Skip to content

Commit a3a4c92

Browse files
committed
Selenium tests
1 parent b0e42cd commit a3a4c92

2 files changed

Lines changed: 215 additions & 34 deletions

File tree

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

Lines changed: 160 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import org.labkey.test.util.DataRegionTable;
5656
import org.labkey.test.util.EscapeUtil;
5757
import org.labkey.test.util.ExcelHelper;
58+
import org.labkey.test.util.FileBrowserHelper;
5859
import org.labkey.test.util.PortalHelper;
5960
import org.labkey.test.util.SampleTypeHelper;
6061
import org.labkey.test.util.TestDataGenerator;
@@ -1582,58 +1583,183 @@ public void testFileAttachment()
15821583
@Test // Issue 49830
15831584
public void testFilePathOnBulkImport() throws IOException
15841585
{
1585-
projectMenu().navigateToFolder(PROJECT_NAME, FOLDER_NAME);
1586+
goToProjectHome();
15861587

1587-
String sampleTypeName = "FilePathValidation";
15881588
String fileFieldName = "FileField";
15891589
SampleTypeHelper sampleHelper = new SampleTypeHelper(this);
1590-
sampleHelper.createSampleType(new SampleTypeDefinition(sampleTypeName).setFields(
1590+
String sampleTypeNameHome = "FilePathValidationHome";
1591+
sampleHelper.createSampleType(new SampleTypeDefinition(sampleTypeNameHome).setFields(
1592+
List.of(new FieldDefinition(fileFieldName, ColumnType.File))
1593+
));
1594+
1595+
projectMenu().navigateToFolder(PROJECT_NAME, FOLDER_NAME);
1596+
1597+
String sampleTypeNameSub = "FilePathValidationSub";
1598+
sampleHelper.createSampleType(new SampleTypeDefinition(sampleTypeNameSub).setFields(
15911599
List.of(new FieldDefinition(fileFieldName, ColumnType.File))
15921600
));
15931601

15941602
// add a file system file that isn't under the current container dir, i.e. in the parent dir
15951603
goToProjectHome();
15961604
goToModule("FileContent");
1597-
_fileBrowserHelper.uploadFile(TestFileUtils.getSampleData("sampleType.xlsx"));
15981605

1599-
// go back to subfolder and import data with relative path that shouldn't resolve
1600-
DataRegionTable drt = importSampleTypeFilePathData(sampleTypeName, fileFieldName, "Test1", "../sampleType.xlsx");
1601-
checker().verifyEquals("Sample name in data row not as expected", "Test1", drt.getDataAsText(0, "Name"));
1602-
checker().verifyEquals("File field should be empty as path was invalid", " ", drt.getDataAsText(0, fileFieldName));
1603-
1604-
// add a file system file in current container dir and import data with relative path that should resolve
1606+
String testFileHomeName = "Update_Lineage_A.tsv";
1607+
String testFileHomeNameB = "Update_Lineage_B.tsv";
1608+
String homeFileDirectory = "homeDir1";
1609+
_fileBrowserHelper.uploadFile(TestFileUtils.getSampleData(testFileHomeName));
1610+
_fileBrowserHelper.uploadFile(TestFileUtils.getSampleData(testFileHomeNameB));
1611+
_fileBrowserHelper.createFolder(homeFileDirectory);
1612+
FileBrowserHelper.FileDetailInfo homeFileInfo = _fileBrowserHelper.getFileDetailInfo(PROJECT_NAME, testFileHomeName);
1613+
FileBrowserHelper.FileDetailInfo homeFileBInfo = _fileBrowserHelper.getFileDetailInfo(PROJECT_NAME, testFileHomeNameB);
1614+
FileBrowserHelper.FileDetailInfo homeDirInfo = _fileBrowserHelper.getFileDetailInfo(PROJECT_NAME, homeFileDirectory);
1615+
1616+
String folderContainerPath = PROJECT_NAME + "/" + FOLDER_NAME;
1617+
String testFileSubName = "sampleType.tsv";
1618+
String subFileDirectory = "subDir1";
1619+
goToProjectFolder(PROJECT_NAME, FOLDER_NAME);
16051620
goToModule("FileContent");
1606-
_fileBrowserHelper.uploadFile(TestFileUtils.getSampleData("sampleType.xlsx"));
1607-
drt = importSampleTypeFilePathData(sampleTypeName, fileFieldName, "Test2", "sampleType.xlsx");
1608-
checker().verifyEquals("Sample name in data row not as expected", "Test2", drt.getDataAsText(0, "Name"));
1609-
checker().verifyEquals("File field should contain file name", " sampleType.xlsx", drt.getDataAsText(0, fileFieldName));
1610-
1611-
// try an import with a valid file that isn't accessible from this container
1612-
File propFile = new File(TestFileUtils.getTestRoot(), "test.properties");
1613-
drt = importSampleTypeFilePathData(sampleTypeName, fileFieldName, "Test3", propFile.getAbsolutePath());
1614-
checker().verifyEquals("Sample name in data row not as expected", "Test3", drt.getDataAsText(0, "Name"));
1615-
String actualValue = drt.getDataAsText(0, fileFieldName);
1616-
checker().verifyTrue("File field should not be valid", " ".equals(actualValue) || actualValue.contains("properties (unavailable)"));
1617-
1618-
// try an import with an invalid file path
1619-
drt = importSampleTypeFilePathData(sampleTypeName, fileFieldName, "Test4", "invalid/path/to/file");
1620-
checker().verifyEquals("Sample name in data row not as expected", "Test4", drt.getDataAsText(0, "Name"));
1621-
checker().verifyTrue("File field should not be valid", drt.getDataAsText(0, fileFieldName).contains("file (unavailable)"));
1621+
_fileBrowserHelper.uploadFile(TestFileUtils.getSampleData(testFileSubName));
1622+
_fileBrowserHelper.createFolder(subFileDirectory);
1623+
FileBrowserHelper.FileDetailInfo subFileInfo = _fileBrowserHelper.getFileDetailInfo(folderContainerPath, testFileSubName);
1624+
FileBrowserHelper.FileDetailInfo subDirInfo = _fileBrowserHelper.getFileDetailInfo(folderContainerPath, subFileDirectory);
1625+
1626+
goToProjectHome();
1627+
clickAndWait(Locator.linkWithText(sampleTypeNameHome));
1628+
DataRegionTable drt = DataRegionTable.findDataRegionWithinWebpart(this, "Sample Type Contents");
1629+
ImportDataPage importDataPage = drt.clickImportBulkData();
1630+
1631+
// error cases for home sample type:
1632+
// importing directory that does exist under current project root into project
1633+
importSampleTypeFilePathDataError("Fail", homeDirInfo.absoluteFilePath());
1634+
importSampleTypeFilePathDataError("Fail", homeDirInfo.webDavUrl());
1635+
importSampleTypeFilePathDataError("Fail", homeDirInfo.dataFileUrl());
1636+
importSampleTypeFilePathDataError("Fail", homeDirInfo.webDavUrlRelative());
1637+
importSampleTypeFilePathDataError("Fail", homeDirInfo.fileName());
1638+
// importing directory that's not under current project root
1639+
importSampleTypeFilePathDataError("Fail", "/");
1640+
importSampleTypeFilePathDataError("Fail", "../");
1641+
importSampleTypeFilePathDataError("Fail", "../@files");
1642+
importSampleTypeFilePathDataError("Fail", subDirInfo.absoluteFilePath());
1643+
importSampleTypeFilePathDataError("Fail", subDirInfo.webDavUrl());
1644+
importSampleTypeFilePathDataError("Fail", subDirInfo.dataFileUrl());
1645+
importSampleTypeFilePathDataError("Fail", subDirInfo.webDavUrlRelative());
1646+
// importing file that does exist, but not under current root
1647+
importSampleTypeFilePathDataError("Fail", subFileInfo.absoluteFilePath());
1648+
importSampleTypeFilePathDataError("Fail", subFileInfo.webDavUrl());
1649+
importSampleTypeFilePathDataError("Fail", subFileInfo.dataFileUrl());
1650+
importSampleTypeFilePathDataError("Fail", "../" + FOLDER_NAME + "/@files/" + subDirInfo.webDavUrlRelative());
1651+
// importing file that does not exist
1652+
importSampleTypeFilePathDataError("Fail", homeFileInfo.absoluteFilePath() + "bad");
1653+
importSampleTypeFilePathDataError("Fail", homeFileInfo.webDavUrl() + "bad");
1654+
importSampleTypeFilePathDataError("Fail", homeFileInfo.dataFileUrl() + "bad");
1655+
importSampleTypeFilePathDataError("Fail", homeFileInfo.webDavUrlRelative() + "bad");
1656+
importSampleTypeFilePathDataError("Fail", homeFileInfo.fileName() + "bad");
1657+
// happy cases: create new records using valid relative or absolute file in Project/Child
1658+
String header = "Name\t" + fileFieldName + "\n";
1659+
String homeSampleContent = "S-home-fullPath\t" + homeFileInfo.absoluteFilePath() + "\n"
1660+
+ "S-home-relativeDav\t" + homeFileInfo.webDavUrlRelative() + "\n"
1661+
+ "S-home-dataUrl\t" + homeFileInfo.dataFileUrl() + "\n"
1662+
+ "S-home-davUrl\t" + homeFileInfo.webDavUrl() + "\n"
1663+
+ "S-home-relative\t" + "../@files/" + homeFileInfo.fileName();
1664+
setFormElement(Locator.name("text"), header + homeSampleContent);
1665+
clickButton("Submit");
1666+
drt = DataRegionTable.findDataRegionWithinWebpart(this, "Sample Type Contents");
1667+
String fName = " " + homeFileInfo.fileName();
1668+
checker().verifyEqualsSorted("File field not imported as expected", List.of(fName, fName, fName, fName, fName), drt.getColumnDataAsText(fileFieldName));
1669+
// error case for update
1670+
importDataPage = drt.clickImportBulkData();
1671+
importDataPage.setCopyPasteMerge(false, true);
1672+
importSampleTypeFilePathDataError("S-home-fullPath", homeDirInfo.absoluteFilePath());
1673+
importSampleTypeFilePathDataError("S-home-fullPath", homeDirInfo.fileName());
1674+
importSampleTypeFilePathDataError("S-home-fullPath", "../");
1675+
importSampleTypeFilePathDataError("S-home-fullPath", subDirInfo.webDavUrl());
1676+
importSampleTypeFilePathDataError("S-home-fullPath", subDirInfo.dataFileUrl());
1677+
importSampleTypeFilePathDataError("S-home-fullPath", homeFileInfo.absoluteFilePath() + "bad");
1678+
// happy cases for update
1679+
setFormElement(Locator.name("text"), header + homeSampleContent); // no change
1680+
clickButton("Submit");
1681+
drt = DataRegionTable.findDataRegionWithinWebpart(this, "Sample Type Contents");
1682+
checker().verifyEqualsSorted("File field not imported as expected", List.of(fName, fName, fName, fName, fName), drt.getColumnDataAsText(fileFieldName));
1683+
importDataPage = drt.clickImportBulkData();
1684+
importDataPage.setCopyPasteMerge(false, true);
1685+
String homeSampleUpdateContent = "S-home-fullPath\t" + homeFileBInfo.absoluteFilePath() + "\n"
1686+
+ "S-home-relativeDav\t\n"
1687+
+ "S-home-dataUrl\t" + homeFileBInfo.dataFileUrl() + "\n"
1688+
+ "S-home-davUrl\t" + homeFileBInfo.webDavUrl() + "\n"
1689+
+ "S-home-relative\t" + "../@files/" + homeFileBInfo.fileName();
1690+
setFormElement(Locator.name("text"), header + homeSampleUpdateContent);
1691+
clickButton("Submit");
1692+
String fNameUpdated = " " + homeFileBInfo.fileName();
1693+
drt = DataRegionTable.findDataRegionWithinWebpart(this, "Sample Type Contents");
1694+
checker().verifyEqualsSorted("File field not imported as expected", List.of(fNameUpdated, fNameUpdated, fNameUpdated, " "/*removed*/, fNameUpdated), drt.getColumnDataAsText(fileFieldName));
1695+
// error case for merge
1696+
importDataPage = drt.clickImportBulkData();
1697+
importDataPage.setCopyPasteMerge(true, true);
1698+
importSampleTypeFilePathDataError("S-home-fullPath", homeDirInfo.absoluteFilePath());
1699+
importSampleTypeFilePathDataError("S-home-fullPath", subDirInfo.webDavUrl());
1700+
importSampleTypeFilePathDataError("Bad", subDirInfo.webDavUrlRelative());
1701+
// happy case for merge
1702+
String homeSampleMergeContent = homeSampleContent
1703+
+ "\nS-home-merge1\t" + "../@files/" + homeFileBInfo.fileName();
1704+
setFormElement(Locator.name("text"), header + homeSampleMergeContent);
1705+
clickButton("Submit");
1706+
drt = DataRegionTable.findDataRegionWithinWebpart(this, "Sample Type Contents");
1707+
checker().verifyEqualsSorted("File field not imported as expected", List.of(fNameUpdated, fName, fName, fName, fName, fName), drt.getColumnDataAsText(fileFieldName));
1708+
1709+
// error cases for child sample type
1710+
goToProjectFolder(PROJECT_NAME, FOLDER_NAME);
1711+
clickAndWait(Locator.linkWithText(sampleTypeNameSub));
1712+
drt = DataRegionTable.findDataRegionWithinWebpart(this, "Sample Type Contents");
1713+
importDataPage = drt.clickImportBulkData();
1714+
// import data in subfolder with home folder file absolute path, or invalid relative path, or directory
1715+
importSampleTypeFilePathDataError("Fail", homeFileInfo.absoluteFilePath());
1716+
importSampleTypeFilePathDataError("Fail", homeFileInfo.webDavUrl());
1717+
importSampleTypeFilePathDataError("Fail", homeFileInfo.dataFileUrl());
1718+
importSampleTypeFilePathDataError("Fail", "../" + testFileHomeName);
1719+
importSampleTypeFilePathDataError("Fail", "../../" + testFileHomeName);
1720+
importSampleTypeFilePathDataError("Fail", "../");
1721+
importSampleTypeFilePathDataError("Fail", "../../@files");
1722+
importSampleTypeFilePathDataError("Fail", "../../@files/" + homeFileDirectory);
1723+
importSampleTypeFilePathDataError("Fail", homeDirInfo.absoluteFilePath());
1724+
importSampleTypeFilePathDataError("Fail", homeDirInfo.webDavUrl());
1725+
importSampleTypeFilePathDataError("Fail", homeDirInfo.dataFileUrl());
1726+
// import data in subfolder with directory that's under current root
1727+
importSampleTypeFilePathDataError("Fail", subDirInfo.absoluteFilePath());
1728+
importSampleTypeFilePathDataError("Fail", subDirInfo.webDavUrl());
1729+
importSampleTypeFilePathDataError("Fail", subDirInfo.dataFileUrl());
1730+
importSampleTypeFilePathDataError("Fail", subDirInfo.webDavUrlRelative());
1731+
importSampleTypeFilePathDataError("Fail", subDirInfo.fileName());
1732+
// happy case for creating child sample
1733+
String childSampleContent = "S-child-fullPath\t" + subFileInfo.absoluteFilePath() + "\n"
1734+
+ "S-child-relativeDav\t" + subFileInfo.webDavUrlRelative() + "\n"
1735+
+ "S-child-dataUrl\t" + subFileInfo.dataFileUrl() + "\n"
1736+
+ "S-child-davUrl\t" + subFileInfo.webDavUrl() + "\n"
1737+
+ "S-child-relative\t" + "../@files/" + subFileInfo.fileName();
1738+
setFormElement(Locator.name("text"), header + childSampleContent);
1739+
clickButton("Submit");
1740+
drt = DataRegionTable.findDataRegionWithinWebpart(this, "Sample Type Contents");
1741+
fName = " " + subFileInfo.fileName();
1742+
checker().verifyEqualsSorted("File field not imported as expected", List.of(fName, fName, fName, fName, fName), drt.getColumnDataAsText(fileFieldName));
16221743
}
16231744

1624-
private DataRegionTable importSampleTypeFilePathData(String sampleTypeName, String fileFieldName, String sampleName, String filePath)
1745+
1746+
private void importSampleTypeFilePathDataError(String sampleName, String filePath)
16251747
{
1626-
projectMenu().navigateToFolder(PROJECT_NAME, FOLDER_NAME);
1627-
clickAndWait(Locator.linkWithText(sampleTypeName));
1628-
DataRegionTable drt = DataRegionTable.findDataRegionWithinWebpart(this, "Sample Type Contents");
1629-
drt.clickImportBulkData();
1748+
final String fileFieldName = "FileField";
16301749
String header = "Name\t" + fileFieldName + "\n";
16311750
String data = sampleName + "\t" + filePath + "\n";
16321751
setFormElement(Locator.name("text"), header + data);
1633-
clickButton("Submit");
1634-
return DataRegionTable.findDataRegionWithinWebpart(this, "Sample Type Contents");
1752+
new ImportDataPage(getDriver()).submitExpectingError();
1753+
try
1754+
{
1755+
waitForElementToBeVisible(Locator.xpath("//div[contains(@class, 'labkey-error')][contains(text(),'Invalid file path: " + filePath + "')]"));
1756+
}
1757+
catch(NoSuchElementException nse)
1758+
{
1759+
checker().fatal().error("Invalid file path error not present.");
1760+
}
16351761
}
1636-
1762+
16371763
@Test
16381764
public void testCreateViaScript()
16391765
{

src/org/labkey/test/util/FileBrowserHelper.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,17 @@
2020
import org.apache.commons.lang3.mutable.MutableObject;
2121
import org.jetbrains.annotations.Nullable;
2222
import org.junit.Assert;
23+
import org.labkey.remoteapi.CommandException;
24+
import org.labkey.remoteapi.Connection;
25+
import org.labkey.remoteapi.query.Filter;
26+
import org.labkey.remoteapi.query.SelectRowsCommand;
27+
import org.labkey.remoteapi.query.SelectRowsResponse;
2328
import org.labkey.test.BaseWebDriverTest;
2429
import org.labkey.test.Locator;
2530
import org.labkey.test.SortDirection;
2631
import org.labkey.test.TestProperties;
2732
import org.labkey.test.WebDriverWrapper;
33+
import org.labkey.test.WebTestHelper;
2834
import org.labkey.test.components.DomainDesignerPage;
2935
import org.labkey.test.components.ext4.Checkbox;
3036
import org.labkey.test.components.ext4.RadioButton;
@@ -40,6 +46,7 @@
4046
import org.openqa.selenium.support.ui.WebDriverWait;
4147

4248
import java.io.File;
49+
import java.io.IOException;
4350
import java.net.URLEncoder;
4451
import java.nio.charset.StandardCharsets;
4552
import java.time.Duration;
@@ -873,6 +880,54 @@ public void openFolderTree()
873880
}
874881
}
875882

883+
private String stringOrNull(Object value)
884+
{
885+
if (value == null)
886+
return null;
887+
return (String) value;
888+
}
889+
890+
public record FileDetailInfo(String fileName, String absoluteFilePath, String dataFileUrl, String webDavUrl, String webDavUrlRelative)
891+
{
892+
893+
}
894+
895+
public FileDetailInfo getFileDetailInfo(String containerPath, String fileName)
896+
{
897+
List<String> filePathColumns = List.of("AbsoluteFilePath", "DataFileUrl", "WebDavUrl", "WebDavUrlRelative");
898+
try
899+
{
900+
Connection cn = WebTestHelper.getRemoteApiConnection();
901+
SelectRowsCommand cmd = new SelectRowsCommand("exp", "files");
902+
cmd.addFilter("Name", fileName, Filter.Operator.EQUAL);
903+
cmd.setColumns(filePathColumns);
904+
SelectRowsResponse response = cmd.execute(cn, "/" + containerPath);
905+
906+
Map<String, Object> row = response.getRows().get(0);
907+
Object absoluteFilePath = row.get("AbsoluteFilePath");
908+
Object dataFileUrl = row.get("DataFileUrl");
909+
Object webDavUrl = row.get("WebDavUrl");
910+
Object webDavUrlRelative = row.get("WebDavUrlRelative");
911+
return new FileDetailInfo(fileName, stringOrNull(absoluteFilePath), stringOrNull(dataFileUrl), stringOrNull(webDavUrl), stringOrNull(webDavUrlRelative));
912+
}
913+
catch (CommandException ce)
914+
{
915+
if (ce.getStatusCode() == 404)
916+
{
917+
return null;
918+
}
919+
else
920+
{
921+
throw new RuntimeException(ce);
922+
}
923+
}
924+
catch (IOException ioe)
925+
{
926+
throw new RuntimeException(ioe);
927+
}
928+
929+
}
930+
876931
// See PageFlowUtil.encodeURIComponent()
877932
private static final Map<String, String> DECODE_UNRESERVED_MARKS = Map.of(
878933
"!", "%21",

0 commit comments

Comments
 (0)