diff --git a/src/org/labkey/test/components/domain/AdvancedSettingsDialog.java b/src/org/labkey/test/components/domain/AdvancedSettingsDialog.java index 6fc243a399..2aead987ef 100644 --- a/src/org/labkey/test/components/domain/AdvancedSettingsDialog.java +++ b/src/org/labkey/test/components/domain/AdvancedSettingsDialog.java @@ -170,16 +170,10 @@ public AdvancedSettingsDialog setRecommendedVariable(boolean checked) return this; } - public boolean isUniqueConstraint() + public AdvancedSettingsDialog setSingleFieldIndex(SingleFieldIndexType type) { - return elementCache().uniqueConstraint.get(); - } - - public AdvancedSettingsDialog setUniqueConstraint(boolean checked) - { - elementCache().uniqueConstraint.set(checked); - getWrapper().waitFor(()-> elementCache().uniqueConstraint.get().equals(checked), - "uniqueConstraint checkbox was not set as expected", 1000); + if (type == null) type = SingleFieldIndexType.NO_INDEX; + elementCache().indexSelect.selectByVisibleText(type.getText()); return this; } @@ -214,6 +208,25 @@ public DomainFieldRow cancel() return _row; } + public enum SingleFieldIndexType + { + NO_INDEX("No Index"), + INDEX("Index"), + UNIQUE_INDEX("Index and require unique values"); + + private final String _text; + + SingleFieldIndexType(String text) + { + _text = text; + } + + public String getText() + { + return _text; + } + } + @Override protected ElementCache newElementCache() { @@ -256,8 +269,8 @@ protected class ElementCache extends ModalDialog.ElementCache Locator.input("domainpropertiesrow-recommendedVariable").findWhenNeeded(this)); public Checkbox enableMissingValues = new Checkbox( Locator.input("domainpropertiesrow-mvEnabled").findWhenNeeded(this)); - public Checkbox uniqueConstraint = new Checkbox( - Locator.input("domainpropertiesrow-uniqueConstraint").findWhenNeeded(this)); + public Select indexSelect = SelectWrapper.Select(Locator.tagWithAttribute("select", "name", "domainpropertiesrow-singleFieldConstraint")) + .findWhenNeeded(this); } } diff --git a/src/org/labkey/test/tests/DataClassTest.java b/src/org/labkey/test/tests/DataClassTest.java index dd39eb96a4..372d9e11f5 100644 --- a/src/org/labkey/test/tests/DataClassTest.java +++ b/src/org/labkey/test/tests/DataClassTest.java @@ -24,6 +24,7 @@ import org.labkey.test.TestFileUtils; import org.labkey.test.WebTestHelper; import org.labkey.test.categories.Daily; +import org.labkey.test.components.domain.AdvancedSettingsDialog; import org.labkey.test.components.domain.BaseDomainDesigner; import org.labkey.test.components.domain.DomainFormPanel; import org.labkey.test.pages.core.admin.BaseSettingsPage.DATE_FORMAT; @@ -49,6 +50,7 @@ public class DataClassTest extends BaseWebDriverTest { private static final String PROJECT_NAME = "DataClassTestProject"; + boolean IS_POSTGRES = WebTestHelper.getDatabaseType() == WebTestHelper.DatabaseType.PostgreSQL; @Override public List getAssociatedModules() @@ -262,12 +264,12 @@ public void testFieldUniqueConstraint() DomainFormPanel domainFormPanel = createPage.getDomainEditor(); domainFormPanel.manuallyDefineFields(fieldName1) .setType(FieldDefinition.ColumnType.Integer) - .expand().clickAdvancedSettings().setUniqueConstraint(true).apply(); - log("Add another field with a unique constraint"); + .expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX).apply(); + log("Add another field with a non-unique constraint"); String fieldName2 = "fieldName_2"; domainFormPanel.addField(fieldName2) .setType(FieldDefinition.ColumnType.DateAndTime) - .expand().clickAdvancedSettings().setUniqueConstraint(true).apply(); + .expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.INDEX).apply(); log("Add another field which does not have a unique constraint"); String fieldName3 = "FieldName@3"; domainFormPanel.addField(fieldName3) @@ -275,22 +277,27 @@ public void testFieldUniqueConstraint() createPage.clickSave(); viewRawTableMetadata(dataClassName); - verifyTableIndices("unique_constraint_test_", List.of("field_name1", "fieldname_2")); + verifyTableIndices("unique_constraint_test_", List.of("field_Name1", "fieldName_2")); + assertTextNotPresent("unique_constraint_test_fieldname_3"); + verifyTableIndexNonUnique("unique_constraint_test_", "field_Name1", true); + verifyTableIndexNonUnique("unique_constraint_test_", "fieldName_2", false); log("Remove a field unique constraint and add a new one"); goToProjectHome(); CreateDataClassPage updatePage = goToDataClass(dataClassName); domainFormPanel = updatePage.getDomainEditor(); - domainFormPanel.getField(fieldName2) - .expand().clickAdvancedSettings().setUniqueConstraint(false) + domainFormPanel.getField(fieldName1) + .expand().clickAdvancedSettings().setSingleFieldIndex(null) .apply(); domainFormPanel.getField(fieldName3) - .expand().clickAdvancedSettings().setUniqueConstraint(true) + .expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX) .apply(); updatePage.clickSave(); viewRawTableMetadata(dataClassName); - verifyTableIndices("unique_constraint_test_", List.of("field_name1", "fieldname_3")); - assertTextNotPresent("unique_constraint_test_fieldname_2"); + verifyTableIndices("unique_constraint_test_", List.of("fieldName_2", "FieldName_3")); + assertTextNotPresent("unique_constraint_test_field_name1"); + verifyTableIndexNonUnique("unique_constraint_test_", "fieldName_2", false); + verifyTableIndexNonUnique("unique_constraint_test_", "FieldName_3", true); } @Test @@ -406,6 +413,16 @@ private void verifyTableIndices(String prefix, List indexSuffixes) assertTextPresentCaseInsensitive(prefix + suffix); } + private void verifyTableIndexNonUnique(String prefix, String suffix, boolean isUnique) + { + String boolDisplay = isUnique ? "0" : "1"; + if (IS_POSTGRES) boolDisplay = isUnique ? "false" : "true"; + String fieldKey = prefix + suffix; + if (IS_POSTGRES) fieldKey = fieldKey.toLowerCase(); + Locator locator = Locator.xpath("//td[contains(text(), '" + fieldKey + "')]/preceding-sibling::td[2][text()='" + boolDisplay + "']"); + checker().verifyTrue("Non_Unique value not as expected in metadata for locator: " + locator, locator.existsIn(getDriver())); + } + private CreateDataClassPage goToCreateNewDataClass() { DataRegionTable drt = DataRegion(getDriver()).find(); diff --git a/src/org/labkey/test/tests/SampleTypeTest.java b/src/org/labkey/test/tests/SampleTypeTest.java index 3b2a4c8470..4d84069379 100644 --- a/src/org/labkey/test/tests/SampleTypeTest.java +++ b/src/org/labkey/test/tests/SampleTypeTest.java @@ -38,6 +38,7 @@ import org.labkey.test.categories.Daily; import org.labkey.test.components.CustomizeView; import org.labkey.test.components.assay.AssayConstants; +import org.labkey.test.components.domain.AdvancedSettingsDialog; import org.labkey.test.components.domain.BaseDomainDesigner; import org.labkey.test.components.domain.DomainFormPanel; import org.labkey.test.components.ext4.Window; @@ -105,6 +106,7 @@ public class SampleTypeTest extends BaseWebDriverTest private static final String LOWER_CASE_SAMPLE_TYPE = CASE_INSENSITIVE_SAMPLE_TYPE.toLowerCase(); private static final String UPPER_CASE_SAMPLE_TYPE = CASE_INSENSITIVE_SAMPLE_TYPE.toUpperCase(); private static final TestUser USER_FOR_FILTERTEST = new TestUser("filter_user@sampletypetest.test"); + boolean IS_POSTGRES = WebTestHelper.getDatabaseType() == WebTestHelper.DatabaseType.PostgreSQL; @Override public List getAssociatedModules() @@ -1825,17 +1827,17 @@ public void testFieldUniqueConstraint() .goToCreateNewSampleType() .setName(sampleTypeName); - log("Add a field with a unique constraint"); + log("Add a field with a non-unique constraint"); String fieldName1 = "field Name1"; DomainFormPanel domainFormPanel = createPage.getFieldsPanel(); domainFormPanel.manuallyDefineFields(fieldName1) .setType(ColumnType.Integer) - .expand().clickAdvancedSettings().setUniqueConstraint(true).apply(); + .expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.INDEX).apply(); log("Add another field with a unique constraint"); String fieldName2 = "fieldName_2"; domainFormPanel.addField(fieldName2) .setType(ColumnType.DateAndTime) - .expand().clickAdvancedSettings().setUniqueConstraint(true).apply(); + .expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX).apply(); log("Add another field which does not have a unique constraint"); String fieldName3 = "FieldName@3"; domainFormPanel.addField(fieldName3) @@ -1843,22 +1845,27 @@ public void testFieldUniqueConstraint() createPage.clickSave(); viewRawTableMetadata(sampleTypeName); - verifyTableIndices("unique_constraint_test_", List.of("field_name1", "fieldname_2")); + verifyTableIndices("unique_constraint_test_", List.of("field_Name1", "fieldName_2")); + assertTextNotPresent("unique_constraint_test_fieldname_3"); + verifyTableIndexNonUnique("unique_constraint_test_", "field_Name1", false); + verifyTableIndexNonUnique("unique_constraint_test_", "fieldName_2", true); log("Remove a field unique constraint and add a new one"); goToProjectHome(); UpdateSampleTypePage updatePage = sampleHelper.goToEditSampleType(sampleTypeName); domainFormPanel = updatePage.getFieldsPanel(); domainFormPanel.getField(fieldName2) - .expand().clickAdvancedSettings().setUniqueConstraint(false) + .expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.INDEX) .apply(); domainFormPanel.getField(fieldName3) - .expand().clickAdvancedSettings().setUniqueConstraint(true) + .expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX) .apply(); updatePage.clickSave(); viewRawTableMetadata(sampleTypeName); - verifyTableIndices("unique_constraint_test_", List.of("field_name1", "fieldname_3")); - assertTextNotPresent("unique_constraint_test_fieldname_2"); + verifyTableIndices("unique_constraint_test_", List.of("field_name1", "FieldName_3")); + verifyTableIndexNonUnique("unique_constraint_test_", "field_Name1", false); + verifyTableIndexNonUnique("unique_constraint_test_", "fieldName_2", false); + verifyTableIndexNonUnique("unique_constraint_test_", "FieldName_3", true); } @Test @@ -2020,6 +2027,16 @@ private void verifyTableIndices(String prefix, List indexSuffixes) assertTextPresentCaseInsensitive(prefix + suffix); } + private void verifyTableIndexNonUnique(String prefix, String suffix, boolean isUnique) + { + String boolDisplay = isUnique ? "0" : "1"; + if (IS_POSTGRES) boolDisplay = isUnique ? "false" : "true"; + String fieldKey = prefix + suffix; + if (IS_POSTGRES) fieldKey = fieldKey.toLowerCase(); + Locator locator = Locator.xpath("//td[contains(text(), '" + fieldKey + "')]/preceding-sibling::td[2][text()='" + boolDisplay + "']"); + checker().verifyTrue("Non_Unique value not as expected in metadata for locator: " + locator, locator.existsIn(getDriver())); + } + private void setFileAttachment(int index, File attachment) { DataRegionTable drt = DataRegionTable.findDataRegionWithinWebpart(this, "Sample Type Contents"); diff --git a/src/org/labkey/test/tests/list/ListTest.java b/src/org/labkey/test/tests/list/ListTest.java index f320aa3384..41f8992f59 100644 --- a/src/org/labkey/test/tests/list/ListTest.java +++ b/src/org/labkey/test/tests/list/ListTest.java @@ -38,6 +38,7 @@ import org.labkey.test.categories.Data; import org.labkey.test.categories.Hosting; import org.labkey.test.components.CustomizeView; +import org.labkey.test.components.domain.AdvancedSettingsDialog; import org.labkey.test.components.domain.BaseDomainDesigner; import org.labkey.test.components.domain.ConditionalFormatDialog; import org.labkey.test.components.domain.DomainFieldRow; @@ -101,6 +102,7 @@ public class ListTest extends BaseWebDriverTest protected final static String LIST_NAME_HTML_KEY = "A_HtmlKey_" + DOMAIN_TRICKY_CHARACTERS; protected final static ColumnType LIST_KEY_TYPE = ColumnType.String; protected final static String LIST_KEY_NAME = "Key"; + boolean IS_POSTGRES = WebTestHelper.getDatabaseType() == WebTestHelper.DatabaseType.PostgreSQL; protected final static String LIST_KEY_NAME2 = "Color \"`~!@#$%^&*()_-+={}[]|\\:;<>,.?/"; protected final static String LIST_KEY_NAME2_BULK = "\"Color \"\"`~!@#$%^&*()_-+={}[]|\\:;<>,.?/\""; @@ -1589,45 +1591,58 @@ public void testFieldUniqueConstraint() viewRawTableMetadata(listName); verifyTableIndices("unique_constraint_list_", Collections.emptyList()); - // set two fields to have unique constraints + // set fields to have constraints EditListDefinitionPage listDefinitionPage = _listHelper.goToEditDesign(listName); listDefinitionPage.getFieldsPanel() - .getField(fieldName1).expand().clickAdvancedSettings().setUniqueConstraint(true) + .getField(fieldName1).expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX) .apply(); listDefinitionPage.getFieldsPanel() - .getField(fieldName2).expand().clickAdvancedSettings().setUniqueConstraint(true) + .getField(fieldName2).expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX) + .apply(); + // set one field to have non-unique constraint + listDefinitionPage.getFieldsPanel() + .getField(fieldName3).expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.INDEX) .apply(); listDefinitionPage.clickSave(); AuditLogHelper.DetailedAuditEventRow expectedDomainEvent = new AuditLogHelper.DetailedAuditEventRow(null, listName, null, "The descriptor of domain " + listName + " was updated.", - "", null, null, "Indices: > [field Name1, unique: true, fieldName_2, unique: true]"); + "", null, null, "Indices: > [FieldName@3, unique: false, field Name1, unique: true, fieldName_2, unique: true]"); boolean pass = _auditLogHelper.validateLastDomainAuditEvents(listName, getProjectName(), expectedDomainEvent, Collections.emptyMap()); checker().verifyTrue("Domain audit comment not as expected after updating field unique constraint", pass); viewRawTableMetadata(listName); - verifyTableIndices("unique_constraint_list_", List.of("field_name1", "fieldname_2")); - assertTextNotPresent("unique_constraint_list_fieldname_3"); + verifyTableIndices("unique_constraint_list_", List.of("field_Name1", "fieldName_2", "FieldName_3")); + verifyTableIndexNonUnique("unique_constraint_list_", "field_Name1", true); + verifyTableIndexNonUnique("unique_constraint_list_", "fieldName_2", true); + verifyTableIndexNonUnique("unique_constraint_list_", "FieldName_3", false); - // remove a field unique constraint and add a new one + // remove a field unique constraint, change a field from unique -> non-unique, and change one from non-unique -> unique listDefinitionPage = _listHelper.goToEditDesign(listName); listDefinitionPage.getFieldsPanel() - .getField(fieldName2).expand().clickAdvancedSettings().setUniqueConstraint(false) + .getField(fieldName1).expand().clickAdvancedSettings().setSingleFieldIndex(null) + .apply(); + listDefinitionPage.getFieldsPanel() + .getField(fieldName2).expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.INDEX) .apply(); listDefinitionPage.getFieldsPanel() - .getField(fieldName3).expand().clickAdvancedSettings().setUniqueConstraint(true) + .getField(fieldName3).expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX) .apply(); listDefinitionPage.clickSave(); + String expectedDataChanges = "Indices: [field name1, unique: true, fieldname@3, unique: false, fieldname_2, unique: true] > [FieldName@3, unique: true, fieldName_2, unique: false]"; + if (!IS_POSTGRES) expectedDataChanges = "Indices: [FieldName@3, unique: false, field Name1, unique: true, fieldName_2, unique: true] > [FieldName@3, unique: true, fieldName_2, unique: false]"; expectedDomainEvent = new AuditLogHelper.DetailedAuditEventRow(null, listName, null, "The descriptor of domain " + listName + " was updated.", - "", null, null, "Indices: [field name1, unique: true, fieldname_2, unique: true] > [FieldName@3, unique: true, field Name1, unique: true]"); + "", null, null, expectedDataChanges); pass = _auditLogHelper.validateLastDomainAuditEvents(listName, getProjectName(), expectedDomainEvent, Collections.emptyMap()); checker().verifyTrue("Domain audit comment not as expected after updating field unique constraint", pass); viewRawTableMetadata(listName); - verifyTableIndices("unique_constraint_list_", List.of("field_name1", "fieldname_3")); - assertTextNotPresent("unique_constraint_list_fieldname_2"); + verifyTableIndices("unique_constraint_list_", List.of("fieldName_2", "FieldName_3")); + assertTextNotPresent("unique_constraint_list_field_name1"); + verifyTableIndexNonUnique("unique_constraint_list_", "fieldName_2", false); + verifyTableIndexNonUnique("unique_constraint_list_", "FieldName_3", true); } @Test // Issue 52247 @@ -1698,6 +1713,16 @@ private void verifyTableIndices(String prefix, List indexSuffixes) assertTextPresentCaseInsensitive(prefix + suffix); } + private void verifyTableIndexNonUnique(String prefix, String suffix, boolean isUnique) + { + String boolDisplay = isUnique ? "0" : "1"; + if (IS_POSTGRES) boolDisplay = isUnique ? "false" : "true"; + String fieldKey = prefix + suffix; + if (IS_POSTGRES) fieldKey = fieldKey.toLowerCase(); + Locator locator = Locator.xpath("//td[contains(text(), '" + fieldKey + "')]/preceding-sibling::td[2][text()='" + boolDisplay + "']"); + checker().verifyTrue("Non_Unique value not as expected in metadata for locator: " + locator, locator.existsIn(getDriver())); + } + /** * Test "tricky characters" in field names, including key field. This will test CrUD operation for list items in * lists with an auto-key and user defined key. This will also use file import for validation.