package org.molgenis.data.postgresql;
import org.mockito.ArgumentCaptor;
import org.molgenis.data.DataService;
import org.molgenis.data.MolgenisDataException;
import org.molgenis.data.Query;
import org.molgenis.data.UnknownAttributeException;
import org.molgenis.data.meta.model.Attribute;
import org.molgenis.data.meta.model.EntityType;
import org.springframework.jdbc.core.JdbcTemplate;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import javax.sql.DataSource;
import java.util.stream.Stream;
import static com.google.common.collect.Lists.newArrayList;
import static org.mockito.ArgumentCaptor.forClass;
import static org.mockito.Mockito.*;
import static org.molgenis.data.meta.AttributeType.*;
import static org.molgenis.data.meta.model.EntityTypeMetadata.ENTITY_TYPE_META_DATA;
import static org.molgenis.data.meta.model.EntityTypeMetadata.EXTENDS;
import static org.molgenis.data.postgresql.PostgreSqlRepositoryCollection.POSTGRESQL;
import static org.testng.Assert.assertEquals;
public class PostgreSqlRepositoryCollectionTest
{
private PostgreSqlRepositoryCollection postgreSqlRepoCollection;
private JdbcTemplate jdbcTemplate;
private DataService dataService;
@BeforeMethod
public void setUpBeforeMethod()
{
PostgreSqlEntityFactory postgreSqlEntityFactory = mock(PostgreSqlEntityFactory.class);
DataSource dataSource = mock(DataSource.class);
jdbcTemplate = mock(JdbcTemplate.class);
dataService = mock(DataService.class);
postgreSqlRepoCollection = new PostgreSqlRepositoryCollection(postgreSqlEntityFactory, dataSource, jdbcTemplate,
dataService);
}
@Test
public void updateAttribute()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.getLabel()).thenReturn("label");
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.getLabel()).thenReturn("updated label");
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
verifyZeroInteractions(jdbcTemplate);
}
@Test
public void updateAttributeNillableToNotNillable()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.isNillable()).thenReturn(true);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.isNillable()).thenReturn(false);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
ArgumentCaptor<String> captor = forClass(String.class);
verify(jdbcTemplate).execute(captor.capture());
assertEquals(captor.getValue(), "ALTER TABLE \"entity\" ALTER COLUMN \"attr\" SET NOT NULL");
}
@Test
public void updateAttributeNotNillableToNillable()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.isNillable()).thenReturn(false);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.isNillable()).thenReturn(true);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
ArgumentCaptor<String> captor = forClass(String.class);
verify(jdbcTemplate).execute(captor.capture());
assertEquals(captor.getValue(), "ALTER TABLE \"entity\" ALTER COLUMN \"attr\" DROP NOT NULL");
}
@Test(expectedExceptions = MolgenisDataException.class)
public void updateAttributeNotNillableToNillableIdAttr()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(entityType.getIdAttribute()).thenReturn(attr);
when(attr.isNillable()).thenReturn(false);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.isNillable()).thenReturn(true);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
}
@Test
public void updateAttributeUniqueToNotUnique()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.isUnique()).thenReturn(true);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.isUnique()).thenReturn(false);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
ArgumentCaptor<String> captor = forClass(String.class);
verify(jdbcTemplate).execute(captor.capture());
assertEquals(captor.getValue(), "ALTER TABLE \"entity\" DROP CONSTRAINT \"entity_attr_key\"");
}
@Test(expectedExceptions = MolgenisDataException.class)
public void updateAttributeUniqueToNotUniqueIdAttr()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn("attr").getMock();
when(entityType.getIdAttribute()).thenReturn(attr);
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.isUnique()).thenReturn(true);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.isUnique()).thenReturn(false);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
}
@Test
public void updateAttributeNotUniqueToUnique()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.isUnique()).thenReturn(false);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.isUnique()).thenReturn(true);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
ArgumentCaptor<String> captor = forClass(String.class);
verify(jdbcTemplate).execute(captor.capture());
assertEquals(captor.getValue(), "ALTER TABLE \"entity\" ADD CONSTRAINT \"entity_attr_key\" UNIQUE (\"attr\")");
}
@Test
public void updateAttributeDataTypeToDataType()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.getDataType()).thenReturn(STRING);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.getDataType()).thenReturn(INT);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
ArgumentCaptor<String> captor = forClass(String.class);
verify(jdbcTemplate).execute(captor.capture());
assertEquals(captor.getValue(),
"ALTER TABLE \"entity\" ALTER COLUMN \"attr\" SET DATA TYPE integer USING \"attr\"::integer");
}
@Test
public void updateAttributeSingleRefDataTypeToDataType()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.getDataType()).thenReturn(XREF);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.getDataType()).thenReturn(STRING);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
ArgumentCaptor<String> captor = forClass(String.class);
verify(jdbcTemplate, times(2)).execute(captor.capture());
assertEquals(captor.getAllValues(), newArrayList("ALTER TABLE \"entity\" DROP CONSTRAINT \"entity_attr_fkey\"",
"ALTER TABLE \"entity\" ALTER COLUMN \"attr\" SET DATA TYPE character varying(255) USING \"attr\"::character varying(255)"));
}
@Test
public void updateAttributeSingleRefDataTypeToSingleRefDataType()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.getDataType()).thenReturn(XREF);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.getDataType()).thenReturn(CATEGORICAL);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
verifyZeroInteractions(jdbcTemplate);
}
@Test
public void updateAttributeMultiRefDataTypeToMultiRefDataType()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.getDataType()).thenReturn(MREF);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.getDataType()).thenReturn(CATEGORICAL_MREF);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
verifyZeroInteractions(jdbcTemplate);
}
@Test
public void updateAttributeDataTypeToSingleRefDataType()
{
Attribute refIdAttr = when(mock(Attribute.class).getName()).thenReturn("refIdAttr").getMock();
when(refIdAttr.getDataType()).thenReturn(STRING);
EntityType refEntityType = when(mock(EntityType.class).getName()).thenReturn("refEntity").getMock();
when(refEntityType.getIdAttribute()).thenReturn(refIdAttr);
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.getDataType()).thenReturn(STRING);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.getDataType()).thenReturn(XREF);
when(updatedAttr.getRefEntity()).thenReturn(refEntityType);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
ArgumentCaptor<String> captor = forClass(String.class);
verify(jdbcTemplate, times(2)).execute(captor.capture());
assertEquals(captor.getAllValues(), newArrayList(
"ALTER TABLE \"entity\" ALTER COLUMN \"attr\" SET DATA TYPE character varying(255) USING \"attr\"::character varying(255)",
"ALTER TABLE \"entity\" ADD CONSTRAINT \"entity_attr_fkey\" FOREIGN KEY (\"attr\") REFERENCES \"refEntity\"(\"refIdAttr\")"));
}
@Test(expectedExceptions = MolgenisDataException.class)
public void updateAttributeDataTypeToDataTypeIdAttr()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
Attribute attr = when(mock(Attribute.class).getName()).thenReturn("attr").getMock();
when(entityType.getIdAttribute()).thenReturn(attr);
when(attr.getDataType()).thenReturn(STRING);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn("attr").getMock();
when(updatedAttr.getDataType()).thenReturn(INT);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
}
@Test
public void updateAttributeWithExpressionBefore()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute idAttr = when(mock(Attribute.class).getName()).thenReturn("id").getMock();
when(entityType.getIdAttribute()).thenReturn(idAttr);
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.getExpression()).thenReturn("expression");
when(attr.hasExpression()).thenReturn(true);
when(attr.getDataType()).thenReturn(STRING);
when(attr.isNillable()).thenReturn(false);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.getExpression()).thenReturn(null);
when(updatedAttr.hasExpression()).thenReturn(false);
when(updatedAttr.getDataType()).thenReturn(STRING);
when(updatedAttr.isNillable()).thenReturn(true);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
verify(jdbcTemplate).execute("ALTER TABLE \"entity\" ADD \"attr\" character varying(255)");
}
@Test
public void updateAttributeWithExpressionAfter()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(attr.getDataType()).thenReturn(STRING);
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.hasExpression()).thenReturn(false);
when(attr.isNillable()).thenReturn(false);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.hasExpression()).thenReturn(true);
when(updatedAttr.isNillable()).thenReturn(true);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
verify(jdbcTemplate).execute("ALTER TABLE \"entity\" DROP COLUMN \"attr\"");
}
@Test
public void updateAttributeWithExpressionBeforeAfter()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.hasExpression()).thenReturn(true);
when(attr.isNillable()).thenReturn(false);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.hasExpression()).thenReturn(true);
when(updatedAttr.isNillable()).thenReturn(true);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
verifyZeroInteractions(jdbcTemplate);
}
@Test
public void updateAttributeCompoundBefore()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute idAttr = when(mock(Attribute.class).getName()).thenReturn("id").getMock();
when(entityType.getIdAttribute()).thenReturn(idAttr);
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.getDataType()).thenReturn(COMPOUND);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.getDataType()).thenReturn(STRING);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
verify(jdbcTemplate).execute("ALTER TABLE \"entity\" ADD \"attr\" character varying(255) NOT NULL");
}
@Test
public void updateAttributeCompoundAfter()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.getDataType()).thenReturn(STRING);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.getDataType()).thenReturn(COMPOUND);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
verify(jdbcTemplate).execute("ALTER TABLE \"entity\" DROP COLUMN \"attr\"");
}
@Test
public void updateAttributeCompoundBeforeAfter()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.getDataType()).thenReturn(COMPOUND);
when(attr.isNillable()).thenReturn(false);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.getDataType()).thenReturn(COMPOUND);
when(updatedAttr.isNillable()).thenReturn(true);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
verifyZeroInteractions(jdbcTemplate);
}
@Test(expectedExceptions = {
MolgenisDataException.class }, expectedExceptionsMessageRegExp = "Cannot update attribute \\[attr\\] for abstract entity type \\[root\\]\\.")
public void updateAttributeAbstractEntity()
{
EntityType abstractEntityType = when(mock(EntityType.class).getName()).thenReturn("root").getMock();
when(abstractEntityType.isAbstract()).thenReturn(true);
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(abstractEntityType.getAttribute(attrName)).thenReturn(attr);
when(attr.isNillable()).thenReturn(true);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.isNillable()).thenReturn(false);
EntityType entityType0 = when(mock(EntityType.class).getName()).thenReturn("entity0").getMock();
when(entityType0.getExtends()).thenReturn(abstractEntityType);
when(entityType0.isAbstract()).thenReturn(true);
EntityType entityType0a = when(mock(EntityType.class).getName()).thenReturn("entity0a").getMock();
when(entityType0a.getExtends()).thenReturn(entityType0);
when(entityType0a.isAbstract()).thenReturn(false);
EntityType entityType0b = when(mock(EntityType.class).getName()).thenReturn("entity0b").getMock();
when(entityType0b.getExtends()).thenReturn(entityType0);
when(entityType0b.isAbstract()).thenReturn(false);
EntityType entityType1 = when(mock(EntityType.class).getName()).thenReturn("entity1").getMock();
when(entityType1.getExtends()).thenReturn(abstractEntityType);
when(entityType1.isAbstract()).thenReturn(false);
//noinspection unchecked
Query<EntityType> entityQ = mock(Query.class);
when(dataService.query(ENTITY_TYPE_META_DATA, EntityType.class)).thenReturn(entityQ);
//noinspection unchecked
Query<EntityType> entityQ0 = mock(Query.class);
//noinspection unchecked
Query<EntityType> entityQ1 = mock(Query.class);
when(entityQ.eq(EXTENDS, abstractEntityType)).thenReturn(entityQ0);
when(entityQ.eq(EXTENDS, entityType0)).thenReturn(entityQ1);
when(entityQ0.findAll()).thenReturn(Stream.of(entityType0, entityType1));
when(entityQ1.findAll()).thenReturn(Stream.of(entityType0a, entityType0b));
postgreSqlRepoCollection.updateAttribute(abstractEntityType, attr, updatedAttr);
ArgumentCaptor<String> captor = forClass(String.class);
verify(jdbcTemplate, times(3)).execute(captor.capture());
assertEquals(captor.getAllValues(), newArrayList("ALTER TABLE \"entity0a\" ALTER COLUMN \"attr\" SET NOT NULL",
"ALTER TABLE \"entity0b\" ALTER COLUMN \"attr\" SET NOT NULL",
"ALTER TABLE \"entity1\" ALTER COLUMN \"attr\" SET NOT NULL"));
}
@Test
public void updateAttributeRefEntityXref()
{
Attribute refIdAttr0 = when(mock(Attribute.class).getName()).thenReturn("refIdAttr0").getMock();
when(refIdAttr0.getDataType()).thenReturn(STRING);
EntityType refEntityType0 = when(mock(EntityType.class).getName()).thenReturn("refEntity0").getMock();
when(refEntityType0.getIdAttribute()).thenReturn(refIdAttr0);
Attribute refIdAttr1 = when(mock(Attribute.class).getName()).thenReturn("refIdAttr1").getMock();
when(refIdAttr1.getDataType()).thenReturn(STRING);
EntityType refEntityType1 = when(mock(EntityType.class).getName()).thenReturn("refEntity1").getMock();
when(refEntityType1.getIdAttribute()).thenReturn(refIdAttr1);
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.getDataType()).thenReturn(XREF);
when(attr.getRefEntity()).thenReturn(refEntityType0);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.getDataType()).thenReturn(XREF);
when(updatedAttr.getRefEntity()).thenReturn(refEntityType1);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
ArgumentCaptor<String> captor = forClass(String.class);
verify(jdbcTemplate, times(2)).execute(captor.capture());
assertEquals(captor.getAllValues(), newArrayList("ALTER TABLE \"entity\" DROP CONSTRAINT \"entity_attr_fkey\"",
"ALTER TABLE \"entity\" ADD CONSTRAINT \"entity_attr_fkey\" FOREIGN KEY (\"attr\") REFERENCES \"refEntity1\"(\"refIdAttr1\")"));
}
@Test
public void updateAttributeRefEntityXrefDifferentIdAttrType()
{
Attribute refIdAttr0 = when(mock(Attribute.class).getName()).thenReturn("refIdAttr0").getMock();
when(refIdAttr0.getDataType()).thenReturn(INT);
EntityType refEntityType0 = when(mock(EntityType.class).getName()).thenReturn("refEntity0").getMock();
when(refEntityType0.getIdAttribute()).thenReturn(refIdAttr0);
Attribute refIdAttr1 = when(mock(Attribute.class).getName()).thenReturn("refIdAttr1").getMock();
when(refIdAttr1.getDataType()).thenReturn(STRING);
EntityType refEntityType1 = when(mock(EntityType.class).getName()).thenReturn("refEntity1").getMock();
when(refEntityType1.getIdAttribute()).thenReturn(refIdAttr1);
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.getDataType()).thenReturn(XREF);
when(attr.getRefEntity()).thenReturn(refEntityType0);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.getDataType()).thenReturn(XREF);
when(updatedAttr.getRefEntity()).thenReturn(refEntityType1);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
ArgumentCaptor<String> captor = forClass(String.class);
verify(jdbcTemplate, times(3)).execute(captor.capture());
assertEquals(captor.getAllValues(), newArrayList("ALTER TABLE \"entity\" DROP CONSTRAINT \"entity_attr_fkey\"",
"ALTER TABLE \"entity\" ALTER COLUMN \"attr\" SET DATA TYPE character varying(255) USING \"attr\"::character varying(255)",
"ALTER TABLE \"entity\" ADD CONSTRAINT \"entity_attr_fkey\" FOREIGN KEY (\"attr\") REFERENCES \"refEntity1\"(\"refIdAttr1\")"));
}
@Test(expectedExceptions = MolgenisDataException.class, expectedExceptionsMessageRegExp = "Updating entity \\[entity\\] attribute \\[attr\\] referenced entity from \\[refEntity0\\] to \\[refEntity1\\] not allowed for type \\[MREF\\]")
public void updateAttributeRefEntityMref()
{
Attribute refIdAttr0 = when(mock(Attribute.class).getName()).thenReturn("refIdAttr0").getMock();
when(refIdAttr0.getDataType()).thenReturn(STRING);
EntityType refEntityType0 = when(mock(EntityType.class).getName()).thenReturn("refEntity0").getMock();
when(refEntityType0.getIdAttribute()).thenReturn(refIdAttr0);
Attribute refIdAttr1 = when(mock(Attribute.class).getName()).thenReturn("refIdAttr1").getMock();
when(refIdAttr1.getDataType()).thenReturn(STRING);
EntityType refEntityType1 = when(mock(EntityType.class).getName()).thenReturn("refEntity1").getMock();
when(refEntityType1.getIdAttribute()).thenReturn(refIdAttr1);
Attribute idAttr = when(mock(Attribute.class).getName()).thenReturn("id").getMock();
when(idAttr.getDataType()).thenReturn(STRING);
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
when(entityType.getIdAttribute()).thenReturn(idAttr);
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
when(attr.getDataType()).thenReturn(MREF);
when(attr.getRefEntity()).thenReturn(refEntityType0);
Attribute updatedAttr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(updatedAttr.getDataType()).thenReturn(MREF);
when(updatedAttr.getRefEntity()).thenReturn(refEntityType1);
postgreSqlRepoCollection.updateAttribute(entityType, attr, updatedAttr);
}
@Test
public void addAttribute()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
Attribute idAttr = when(mock(Attribute.class).getName()).thenReturn("id").getMock();
when(entityType.getIdAttribute()).thenReturn(idAttr);
Attribute attr = when(mock(Attribute.class).getName()).thenReturn("attr").getMock();
when(attr.getDataType()).thenReturn(STRING);
postgreSqlRepoCollection.addAttribute(entityType, attr);
verify(jdbcTemplate).execute("ALTER TABLE \"entity\" ADD \"attr\" character varying(255) NOT NULL");
}
@Test
public void addAttributeUnique()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
Attribute idAttr = when(mock(Attribute.class).getName()).thenReturn("id").getMock();
when(entityType.getIdAttribute()).thenReturn(idAttr);
Attribute attr = when(mock(Attribute.class).getName()).thenReturn("attr").getMock();
when(attr.getDataType()).thenReturn(STRING);
when(attr.isUnique()).thenReturn(true);
postgreSqlRepoCollection.addAttribute(entityType, attr);
verify(jdbcTemplate).execute(
"ALTER TABLE \"entity\" ADD \"attr\" character varying(255) NOT NULL,ADD CONSTRAINT \"entity_attr_key\" UNIQUE (\"attr\")");
}
@Test(expectedExceptions = {
MolgenisDataException.class }, expectedExceptionsMessageRegExp = "Cannot add attribute \\[attr\\] to abstract entity type \\[root\\]\\.")
public void addAttributeAbstractEntity()
{
EntityType abstractEntityType = when(mock(EntityType.class).getName()).thenReturn("root").getMock();
when(abstractEntityType.isAbstract()).thenReturn(true);
Attribute attr = when(mock(Attribute.class).getName()).thenReturn("attr").getMock();
when(attr.getDataType()).thenReturn(STRING);
postgreSqlRepoCollection.addAttribute(abstractEntityType, attr);
}
@Test
public void addAttributeCompound()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
Attribute idAttr = when(mock(Attribute.class).getName()).thenReturn("id").getMock();
when(entityType.getIdAttribute()).thenReturn(idAttr);
Attribute attr = when(mock(Attribute.class).getName()).thenReturn("attr").getMock();
when(attr.getDataType()).thenReturn(COMPOUND);
postgreSqlRepoCollection.addAttribute(entityType, attr);
verifyZeroInteractions(jdbcTemplate);
}
@Test
public void addAttributeWithExpression()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
Attribute idAttr = when(mock(Attribute.class).getName()).thenReturn("id").getMock();
when(entityType.getIdAttribute()).thenReturn(idAttr);
Attribute attr = when(mock(Attribute.class).getName()).thenReturn("attr").getMock();
when(attr.hasExpression()).thenReturn(true);
when(attr.getDataType()).thenReturn(STRING);
postgreSqlRepoCollection.addAttribute(entityType, attr);
verifyZeroInteractions(jdbcTemplate);
}
@Test
public void addAttributeOneToManyMappedBy()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
when(entityType.getBackend()).thenReturn(POSTGRESQL);
EntityType refEntityType = when(mock(EntityType.class).getName()).thenReturn("refEntity").getMock();
when(refEntityType.getBackend()).thenReturn(POSTGRESQL);
Attribute idAttr = when(mock(Attribute.class).getName()).thenReturn("id").getMock();
Attribute attr = when(mock(Attribute.class).getName()).thenReturn("attr").getMock();
Attribute refAttr = when(mock(Attribute.class).getName()).thenReturn("refAttr").getMock();
when(refAttr.getDataType()).thenReturn(XREF);
when(refAttr.isInversedBy()).thenReturn(true);
when(refAttr.getInversedBy()).thenReturn(attr);
when(attr.getDataType()).thenReturn(ONE_TO_MANY);
when(attr.getRefEntity()).thenReturn(refEntityType);
when(attr.getMappedBy()).thenReturn(refAttr);
when(attr.isMappedBy()).thenReturn(true);
when(entityType.getIdAttribute()).thenReturn(idAttr);
postgreSqlRepoCollection.addAttribute(entityType, attr);
verifyZeroInteractions(jdbcTemplate);
}
@Test(expectedExceptions = MolgenisDataException.class)
public void addAttributeAlreadyExists()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
postgreSqlRepoCollection.addAttribute(entityType, attr);
}
@Test
public void deleteAttribute()
{
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(attr.getDataType()).thenReturn(STRING);
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
postgreSqlRepoCollection.deleteAttribute(entityType, attr);
verify(jdbcTemplate).execute("ALTER TABLE \"entity\" DROP COLUMN \"attr\"");
}
@Test
public void deleteAttributeMref()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
EntityType refEntityMeta = when(mock(EntityType.class).getName()).thenReturn("refEntity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(attr.getDataType()).thenReturn(MREF);
when(attr.getRefEntity()).thenReturn(refEntityMeta);
when(entityType.getAttribute(attrName)).thenReturn(attr);
postgreSqlRepoCollection.deleteAttribute(entityType, attr);
verify(jdbcTemplate).execute("DROP TABLE \"entity_attr\"");
}
@Test
public void deleteAttributeOneToManyMappedBy()
{
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
EntityType refEntityMeta = when(mock(EntityType.class).getName()).thenReturn("refEntity").getMock();
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
String refAttrName = "refAttr";
Attribute refAttr = when(mock(Attribute.class).getName()).thenReturn(refAttrName).getMock();
when(attr.getDataType()).thenReturn(ONE_TO_MANY);
when(attr.getRefEntity()).thenReturn(refEntityMeta);
when(attr.getMappedBy()).thenReturn(refAttr);
when(attr.isMappedBy()).thenReturn(true);
when(refAttr.getDataType()).thenReturn(XREF);
when(refAttr.getRefEntity()).thenReturn(entityType);
when(refAttr.getInversedBy()).thenReturn(attr);
when(refAttr.isInversedBy()).thenReturn(true);
when(entityType.getAttribute(attrName)).thenReturn(attr);
postgreSqlRepoCollection.deleteAttribute(entityType, attr);
verifyZeroInteractions(jdbcTemplate);
}
@Test(expectedExceptions = {
MolgenisDataException.class }, expectedExceptionsMessageRegExp = "Cannot delete attribute \\[attr\\] from abstract entity type \\[root\\]\\.")
public void deleteAttributeAbstractEntity()
{
EntityType abstractEntityType = when(mock(EntityType.class).getName()).thenReturn("root").getMock();
when(abstractEntityType.isAbstract()).thenReturn(true);
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(attr.getDataType()).thenReturn(STRING);
when(abstractEntityType.getAttribute(attrName)).thenReturn(attr);
postgreSqlRepoCollection.deleteAttribute(abstractEntityType, attr);
}
@Test
public void deleteAttributeWithExpression()
{
String attrName = "attr";
Attribute attr = when(mock(Attribute.class).getName()).thenReturn(attrName).getMock();
when(attr.hasExpression()).thenReturn(true);
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
when(entityType.getAttribute(attrName)).thenReturn(attr);
postgreSqlRepoCollection.deleteAttribute(entityType, attr);
verifyZeroInteractions(jdbcTemplate);
}
@Test(expectedExceptions = UnknownAttributeException.class)
public void deleteAttributeUnknownAttribute()
{
Attribute attr = when(mock(Attribute.class).getName()).thenReturn("attr").getMock();
EntityType entityType = when(mock(EntityType.class).getName()).thenReturn("entity").getMock();
postgreSqlRepoCollection.deleteAttribute(entityType, attr);
}
}