Skip to content

Commit 321b25d

Browse files
authored
GitHub Issue 73: Field editor Advanced Settings to allow for non-unique single-field index (#2827)
- Selenium test updates to check non-unique index for fields via the schema browser table viewer
1 parent a53bee6 commit 321b25d

File tree

4 files changed

+112
-40
lines changed

4 files changed

+112
-40
lines changed

src/org/labkey/test/components/domain/AdvancedSettingsDialog.java

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,10 @@ public AdvancedSettingsDialog setRecommendedVariable(boolean checked)
170170
return this;
171171
}
172172

173-
public boolean isUniqueConstraint()
173+
public AdvancedSettingsDialog setSingleFieldIndex(SingleFieldIndexType type)
174174
{
175-
return elementCache().uniqueConstraint.get();
176-
}
177-
178-
public AdvancedSettingsDialog setUniqueConstraint(boolean checked)
179-
{
180-
elementCache().uniqueConstraint.set(checked);
181-
getWrapper().waitFor(()-> elementCache().uniqueConstraint.get().equals(checked),
182-
"uniqueConstraint checkbox was not set as expected", 1000);
175+
if (type == null) type = SingleFieldIndexType.NO_INDEX;
176+
elementCache().indexSelect.selectByVisibleText(type.getText());
183177
return this;
184178
}
185179

@@ -214,6 +208,25 @@ public DomainFieldRow cancel()
214208
return _row;
215209
}
216210

211+
public enum SingleFieldIndexType
212+
{
213+
NO_INDEX("No Index"),
214+
INDEX("Index"),
215+
UNIQUE_INDEX("Index and require unique values");
216+
217+
private final String _text;
218+
219+
SingleFieldIndexType(String text)
220+
{
221+
_text = text;
222+
}
223+
224+
public String getText()
225+
{
226+
return _text;
227+
}
228+
}
229+
217230
@Override
218231
protected ElementCache newElementCache()
219232
{
@@ -256,8 +269,8 @@ protected class ElementCache extends ModalDialog.ElementCache
256269
Locator.input("domainpropertiesrow-recommendedVariable").findWhenNeeded(this));
257270
public Checkbox enableMissingValues = new Checkbox(
258271
Locator.input("domainpropertiesrow-mvEnabled").findWhenNeeded(this));
259-
public Checkbox uniqueConstraint = new Checkbox(
260-
Locator.input("domainpropertiesrow-uniqueConstraint").findWhenNeeded(this));
272+
public Select indexSelect = SelectWrapper.Select(Locator.tagWithAttribute("select", "name", "domainpropertiesrow-singleFieldConstraint"))
273+
.findWhenNeeded(this);
261274
}
262275

263276
}

src/org/labkey/test/tests/DataClassTest.java

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.labkey.test.TestFileUtils;
2525
import org.labkey.test.WebTestHelper;
2626
import org.labkey.test.categories.Daily;
27+
import org.labkey.test.components.domain.AdvancedSettingsDialog;
2728
import org.labkey.test.components.domain.BaseDomainDesigner;
2829
import org.labkey.test.components.domain.DomainFormPanel;
2930
import org.labkey.test.pages.core.admin.BaseSettingsPage.DATE_FORMAT;
@@ -49,6 +50,7 @@
4950
public class DataClassTest extends BaseWebDriverTest
5051
{
5152
private static final String PROJECT_NAME = "DataClassTestProject";
53+
boolean IS_POSTGRES = WebTestHelper.getDatabaseType() == WebTestHelper.DatabaseType.PostgreSQL;
5254

5355
@Override
5456
public List<String> getAssociatedModules()
@@ -262,35 +264,40 @@ public void testFieldUniqueConstraint()
262264
DomainFormPanel domainFormPanel = createPage.getDomainEditor();
263265
domainFormPanel.manuallyDefineFields(fieldName1)
264266
.setType(FieldDefinition.ColumnType.Integer)
265-
.expand().clickAdvancedSettings().setUniqueConstraint(true).apply();
266-
log("Add another field with a unique constraint");
267+
.expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX).apply();
268+
log("Add another field with a non-unique constraint");
267269
String fieldName2 = "fieldName_2";
268270
domainFormPanel.addField(fieldName2)
269271
.setType(FieldDefinition.ColumnType.DateAndTime)
270-
.expand().clickAdvancedSettings().setUniqueConstraint(true).apply();
272+
.expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.INDEX).apply();
271273
log("Add another field which does not have a unique constraint");
272274
String fieldName3 = "FieldName@3";
273275
domainFormPanel.addField(fieldName3)
274276
.setType(FieldDefinition.ColumnType.Boolean);
275277
createPage.clickSave();
276278

277279
viewRawTableMetadata(dataClassName);
278-
verifyTableIndices("unique_constraint_test_", List.of("field_name1", "fieldname_2"));
280+
verifyTableIndices("unique_constraint_test_", List.of("field_Name1", "fieldName_2"));
281+
assertTextNotPresent("unique_constraint_test_fieldname_3");
282+
verifyTableIndexNonUnique("unique_constraint_test_", "field_Name1", true);
283+
verifyTableIndexNonUnique("unique_constraint_test_", "fieldName_2", false);
279284

280285
log("Remove a field unique constraint and add a new one");
281286
goToProjectHome();
282287
CreateDataClassPage updatePage = goToDataClass(dataClassName);
283288
domainFormPanel = updatePage.getDomainEditor();
284-
domainFormPanel.getField(fieldName2)
285-
.expand().clickAdvancedSettings().setUniqueConstraint(false)
289+
domainFormPanel.getField(fieldName1)
290+
.expand().clickAdvancedSettings().setSingleFieldIndex(null)
286291
.apply();
287292
domainFormPanel.getField(fieldName3)
288-
.expand().clickAdvancedSettings().setUniqueConstraint(true)
293+
.expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX)
289294
.apply();
290295
updatePage.clickSave();
291296
viewRawTableMetadata(dataClassName);
292-
verifyTableIndices("unique_constraint_test_", List.of("field_name1", "fieldname_3"));
293-
assertTextNotPresent("unique_constraint_test_fieldname_2");
297+
verifyTableIndices("unique_constraint_test_", List.of("fieldName_2", "FieldName_3"));
298+
assertTextNotPresent("unique_constraint_test_field_name1");
299+
verifyTableIndexNonUnique("unique_constraint_test_", "fieldName_2", false);
300+
verifyTableIndexNonUnique("unique_constraint_test_", "FieldName_3", true);
294301
}
295302

296303
@Test
@@ -406,6 +413,16 @@ private void verifyTableIndices(String prefix, List<String> indexSuffixes)
406413
assertTextPresentCaseInsensitive(prefix + suffix);
407414
}
408415

416+
private void verifyTableIndexNonUnique(String prefix, String suffix, boolean isUnique)
417+
{
418+
String boolDisplay = isUnique ? "0" : "1";
419+
if (IS_POSTGRES) boolDisplay = isUnique ? "false" : "true";
420+
String fieldKey = prefix + suffix;
421+
if (IS_POSTGRES) fieldKey = fieldKey.toLowerCase();
422+
Locator locator = Locator.xpath("//td[contains(text(), '" + fieldKey + "')]/preceding-sibling::td[2][text()='" + boolDisplay + "']");
423+
checker().verifyTrue("Non_Unique value not as expected in metadata for locator: " + locator, locator.existsIn(getDriver()));
424+
}
425+
409426
private CreateDataClassPage goToCreateNewDataClass()
410427
{
411428
DataRegionTable drt = DataRegion(getDriver()).find();

src/org/labkey/test/tests/SampleTypeTest.java

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.labkey.test.categories.Daily;
3939
import org.labkey.test.components.CustomizeView;
4040
import org.labkey.test.components.assay.AssayConstants;
41+
import org.labkey.test.components.domain.AdvancedSettingsDialog;
4142
import org.labkey.test.components.domain.BaseDomainDesigner;
4243
import org.labkey.test.components.domain.DomainFormPanel;
4344
import org.labkey.test.components.ext4.Window;
@@ -105,6 +106,7 @@ public class SampleTypeTest extends BaseWebDriverTest
105106
private static final String LOWER_CASE_SAMPLE_TYPE = CASE_INSENSITIVE_SAMPLE_TYPE.toLowerCase();
106107
private static final String UPPER_CASE_SAMPLE_TYPE = CASE_INSENSITIVE_SAMPLE_TYPE.toUpperCase();
107108
private static final TestUser USER_FOR_FILTERTEST = new TestUser("[email protected]");
109+
boolean IS_POSTGRES = WebTestHelper.getDatabaseType() == WebTestHelper.DatabaseType.PostgreSQL;
108110

109111
@Override
110112
public List<String> getAssociatedModules()
@@ -1825,40 +1827,45 @@ public void testFieldUniqueConstraint()
18251827
.goToCreateNewSampleType()
18261828
.setName(sampleTypeName);
18271829

1828-
log("Add a field with a unique constraint");
1830+
log("Add a field with a non-unique constraint");
18291831
String fieldName1 = "field Name1";
18301832
DomainFormPanel domainFormPanel = createPage.getFieldsPanel();
18311833
domainFormPanel.manuallyDefineFields(fieldName1)
18321834
.setType(ColumnType.Integer)
1833-
.expand().clickAdvancedSettings().setUniqueConstraint(true).apply();
1835+
.expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.INDEX).apply();
18341836
log("Add another field with a unique constraint");
18351837
String fieldName2 = "fieldName_2";
18361838
domainFormPanel.addField(fieldName2)
18371839
.setType(ColumnType.DateAndTime)
1838-
.expand().clickAdvancedSettings().setUniqueConstraint(true).apply();
1840+
.expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX).apply();
18391841
log("Add another field which does not have a unique constraint");
18401842
String fieldName3 = "FieldName@3";
18411843
domainFormPanel.addField(fieldName3)
18421844
.setType(ColumnType.Boolean);
18431845
createPage.clickSave();
18441846

18451847
viewRawTableMetadata(sampleTypeName);
1846-
verifyTableIndices("unique_constraint_test_", List.of("field_name1", "fieldname_2"));
1848+
verifyTableIndices("unique_constraint_test_", List.of("field_Name1", "fieldName_2"));
1849+
assertTextNotPresent("unique_constraint_test_fieldname_3");
1850+
verifyTableIndexNonUnique("unique_constraint_test_", "field_Name1", false);
1851+
verifyTableIndexNonUnique("unique_constraint_test_", "fieldName_2", true);
18471852

18481853
log("Remove a field unique constraint and add a new one");
18491854
goToProjectHome();
18501855
UpdateSampleTypePage updatePage = sampleHelper.goToEditSampleType(sampleTypeName);
18511856
domainFormPanel = updatePage.getFieldsPanel();
18521857
domainFormPanel.getField(fieldName2)
1853-
.expand().clickAdvancedSettings().setUniqueConstraint(false)
1858+
.expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.INDEX)
18541859
.apply();
18551860
domainFormPanel.getField(fieldName3)
1856-
.expand().clickAdvancedSettings().setUniqueConstraint(true)
1861+
.expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX)
18571862
.apply();
18581863
updatePage.clickSave();
18591864
viewRawTableMetadata(sampleTypeName);
1860-
verifyTableIndices("unique_constraint_test_", List.of("field_name1", "fieldname_3"));
1861-
assertTextNotPresent("unique_constraint_test_fieldname_2");
1865+
verifyTableIndices("unique_constraint_test_", List.of("field_name1", "FieldName_3"));
1866+
verifyTableIndexNonUnique("unique_constraint_test_", "field_Name1", false);
1867+
verifyTableIndexNonUnique("unique_constraint_test_", "fieldName_2", false);
1868+
verifyTableIndexNonUnique("unique_constraint_test_", "FieldName_3", true);
18621869
}
18631870

18641871
@Test
@@ -2020,6 +2027,16 @@ private void verifyTableIndices(String prefix, List<String> indexSuffixes)
20202027
assertTextPresentCaseInsensitive(prefix + suffix);
20212028
}
20222029

2030+
private void verifyTableIndexNonUnique(String prefix, String suffix, boolean isUnique)
2031+
{
2032+
String boolDisplay = isUnique ? "0" : "1";
2033+
if (IS_POSTGRES) boolDisplay = isUnique ? "false" : "true";
2034+
String fieldKey = prefix + suffix;
2035+
if (IS_POSTGRES) fieldKey = fieldKey.toLowerCase();
2036+
Locator locator = Locator.xpath("//td[contains(text(), '" + fieldKey + "')]/preceding-sibling::td[2][text()='" + boolDisplay + "']");
2037+
checker().verifyTrue("Non_Unique value not as expected in metadata for locator: " + locator, locator.existsIn(getDriver()));
2038+
}
2039+
20232040
private void setFileAttachment(int index, File attachment)
20242041
{
20252042
DataRegionTable drt = DataRegionTable.findDataRegionWithinWebpart(this, "Sample Type Contents");

src/org/labkey/test/tests/list/ListTest.java

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.labkey.test.categories.Data;
3939
import org.labkey.test.categories.Hosting;
4040
import org.labkey.test.components.CustomizeView;
41+
import org.labkey.test.components.domain.AdvancedSettingsDialog;
4142
import org.labkey.test.components.domain.BaseDomainDesigner;
4243
import org.labkey.test.components.domain.ConditionalFormatDialog;
4344
import org.labkey.test.components.domain.DomainFieldRow;
@@ -101,6 +102,7 @@ public class ListTest extends BaseWebDriverTest
101102
protected final static String LIST_NAME_HTML_KEY = "A_HtmlKey_" + DOMAIN_TRICKY_CHARACTERS;
102103
protected final static ColumnType LIST_KEY_TYPE = ColumnType.String;
103104
protected final static String LIST_KEY_NAME = "Key";
105+
boolean IS_POSTGRES = WebTestHelper.getDatabaseType() == WebTestHelper.DatabaseType.PostgreSQL;
104106

105107
protected final static String LIST_KEY_NAME2 = "Color \"`~!@#$%^&*()_-+={}[]|\\:;<>,.?/";
106108
protected final static String LIST_KEY_NAME2_BULK = "\"Color \"\"`~!@#$%^&*()_-+={}[]|\\:;<>,.?/\"";
@@ -1589,45 +1591,58 @@ public void testFieldUniqueConstraint()
15891591
viewRawTableMetadata(listName);
15901592
verifyTableIndices("unique_constraint_list_", Collections.emptyList());
15911593

1592-
// set two fields to have unique constraints
1594+
// set fields to have constraints
15931595
EditListDefinitionPage listDefinitionPage = _listHelper.goToEditDesign(listName);
15941596
listDefinitionPage.getFieldsPanel()
1595-
.getField(fieldName1).expand().clickAdvancedSettings().setUniqueConstraint(true)
1597+
.getField(fieldName1).expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX)
15961598
.apply();
15971599
listDefinitionPage.getFieldsPanel()
1598-
.getField(fieldName2).expand().clickAdvancedSettings().setUniqueConstraint(true)
1600+
.getField(fieldName2).expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX)
1601+
.apply();
1602+
// set one field to have non-unique constraint
1603+
listDefinitionPage.getFieldsPanel()
1604+
.getField(fieldName3).expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.INDEX)
15991605
.apply();
16001606
listDefinitionPage.clickSave();
16011607

16021608
AuditLogHelper.DetailedAuditEventRow expectedDomainEvent = new AuditLogHelper.DetailedAuditEventRow(null, listName, null,
16031609
"The descriptor of domain " + listName + " was updated.",
1604-
"", null, null, "Indices: > [field Name1, unique: true, fieldName_2, unique: true]");
1610+
"", null, null, "Indices: > [FieldName@3, unique: false, field Name1, unique: true, fieldName_2, unique: true]");
16051611
boolean pass = _auditLogHelper.validateLastDomainAuditEvents(listName, getProjectName(), expectedDomainEvent, Collections.emptyMap());
16061612
checker().verifyTrue("Domain audit comment not as expected after updating field unique constraint", pass);
16071613

16081614
viewRawTableMetadata(listName);
1609-
verifyTableIndices("unique_constraint_list_", List.of("field_name1", "fieldname_2"));
1610-
assertTextNotPresent("unique_constraint_list_fieldname_3");
1615+
verifyTableIndices("unique_constraint_list_", List.of("field_Name1", "fieldName_2", "FieldName_3"));
1616+
verifyTableIndexNonUnique("unique_constraint_list_", "field_Name1", true);
1617+
verifyTableIndexNonUnique("unique_constraint_list_", "fieldName_2", true);
1618+
verifyTableIndexNonUnique("unique_constraint_list_", "FieldName_3", false);
16111619

1612-
// remove a field unique constraint and add a new one
1620+
// remove a field unique constraint, change a field from unique -> non-unique, and change one from non-unique -> unique
16131621
listDefinitionPage = _listHelper.goToEditDesign(listName);
16141622
listDefinitionPage.getFieldsPanel()
1615-
.getField(fieldName2).expand().clickAdvancedSettings().setUniqueConstraint(false)
1623+
.getField(fieldName1).expand().clickAdvancedSettings().setSingleFieldIndex(null)
1624+
.apply();
1625+
listDefinitionPage.getFieldsPanel()
1626+
.getField(fieldName2).expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.INDEX)
16161627
.apply();
16171628
listDefinitionPage.getFieldsPanel()
1618-
.getField(fieldName3).expand().clickAdvancedSettings().setUniqueConstraint(true)
1629+
.getField(fieldName3).expand().clickAdvancedSettings().setSingleFieldIndex(AdvancedSettingsDialog.SingleFieldIndexType.UNIQUE_INDEX)
16191630
.apply();
16201631
listDefinitionPage.clickSave();
16211632

1633+
String expectedDataChanges = "Indices: [field name1, unique: true, fieldname@3, unique: false, fieldname_2, unique: true] > [FieldName@3, unique: true, fieldName_2, unique: false]";
1634+
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]";
16221635
expectedDomainEvent = new AuditLogHelper.DetailedAuditEventRow(null, listName, null,
16231636
"The descriptor of domain " + listName + " was updated.",
1624-
"", null, null, "Indices: [field name1, unique: true, fieldname_2, unique: true] > [FieldName@3, unique: true, field Name1, unique: true]");
1637+
"", null, null, expectedDataChanges);
16251638
pass = _auditLogHelper.validateLastDomainAuditEvents(listName, getProjectName(), expectedDomainEvent, Collections.emptyMap());
16261639
checker().verifyTrue("Domain audit comment not as expected after updating field unique constraint", pass);
16271640

16281641
viewRawTableMetadata(listName);
1629-
verifyTableIndices("unique_constraint_list_", List.of("field_name1", "fieldname_3"));
1630-
assertTextNotPresent("unique_constraint_list_fieldname_2");
1642+
verifyTableIndices("unique_constraint_list_", List.of("fieldName_2", "FieldName_3"));
1643+
assertTextNotPresent("unique_constraint_list_field_name1");
1644+
verifyTableIndexNonUnique("unique_constraint_list_", "fieldName_2", false);
1645+
verifyTableIndexNonUnique("unique_constraint_list_", "FieldName_3", true);
16311646
}
16321647

16331648
@Test // Issue 52247
@@ -1698,6 +1713,16 @@ private void verifyTableIndices(String prefix, List<String> indexSuffixes)
16981713
assertTextPresentCaseInsensitive(prefix + suffix);
16991714
}
17001715

1716+
private void verifyTableIndexNonUnique(String prefix, String suffix, boolean isUnique)
1717+
{
1718+
String boolDisplay = isUnique ? "0" : "1";
1719+
if (IS_POSTGRES) boolDisplay = isUnique ? "false" : "true";
1720+
String fieldKey = prefix + suffix;
1721+
if (IS_POSTGRES) fieldKey = fieldKey.toLowerCase();
1722+
Locator locator = Locator.xpath("//td[contains(text(), '" + fieldKey + "')]/preceding-sibling::td[2][text()='" + boolDisplay + "']");
1723+
checker().verifyTrue("Non_Unique value not as expected in metadata for locator: " + locator, locator.existsIn(getDriver()));
1724+
}
1725+
17011726
/**
17021727
* Test "tricky characters" in field names, including key field. This will test CrUD operation for list items in
17031728
* lists with an auto-key and user defined key. This will also use file import for validation.

0 commit comments

Comments
 (0)