From d1ed30044b534977c9a7476e7cd6b226d54e3847 Mon Sep 17 00:00:00 2001 From: Josh Adam Date: Tue, 25 Oct 2022 10:37:37 -0500 Subject: [PATCH 01/37] docs: Added missing images --- .../ncbi-export-default-sample-settings.png | Bin 0 -> 27374 bytes .../ncbi-export-sample-validation.png | Bin 0 -> 36649 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/images/tutorials/common/ncbi-export/ncbi-export-default-sample-settings.png create mode 100644 doc/images/tutorials/common/ncbi-export/ncbi-export-sample-validation.png diff --git a/doc/images/tutorials/common/ncbi-export/ncbi-export-default-sample-settings.png b/doc/images/tutorials/common/ncbi-export/ncbi-export-default-sample-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..2714c5002801d33c602cabbd37a3a9d305965764 GIT binary patch literal 27374 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 z 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 literal 0 HcmV?d00001 From 59981b54045b92106142cb4cf77e35dce788e2f4 Mon Sep 17 00:00:00 2001 From: Josh Adam Date: Tue, 25 Oct 2022 11:54:05 -0500 Subject: [PATCH 02/37] docs: Updated alternate text for sample validation image --- doc/_includes/tutorials/common/ncbi-export.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_includes/tutorials/common/ncbi-export.md b/doc/_includes/tutorials/common/ncbi-export.md index 4fd904b8038..b916c0a2a7a 100644 --- a/doc/_includes/tutorials/common/ncbi-export.md +++ b/doc/_includes/tutorials/common/ncbi-export.md @@ -29,7 +29,7 @@ Default values for all samples can be set by clicking on the "Default Sample Set Once all fields and files are selected for a sample, the label will change from "MISSING DATA" to "VALID" indicating that the sample is ready for submission. All samples must be valid before submitting. -![Default Sample Settings]({{ site.baseurl}}/images/tutorials/common/ncbi-export/ncbi-export-sample-validation.png) +![Sample Validation]({{ site.baseurl}}/images/tutorials/common/ncbi-export/ncbi-export-sample-validation.png) After entering this metadata you can select which files should be uploaded from each sample. Only files selected with checkboxes will be uploaded to NCBI. From 874ca2bd56bd06be12fd8e2f819c3f7025a4d880 Mon Sep 17 00:00:00 2001 From: Josh Adam Date: Mon, 31 Oct 2022 07:52:59 -0500 Subject: [PATCH 03/37] test: Working on failing test case --- .../irida/ria/integration/CartPageIT.java | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/CartPageIT.java b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/CartPageIT.java index 823dde92e1c..9a002ba7357 100644 --- a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/CartPageIT.java +++ b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/CartPageIT.java @@ -1,31 +1,28 @@ package ca.corefacility.bioinformatics.irida.ria.integration; -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.openqa.selenium.JavascriptExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; - import ca.corefacility.bioinformatics.irida.ria.integration.components.FastQCModal; import ca.corefacility.bioinformatics.irida.ria.integration.components.SampleDetailsViewer; import ca.corefacility.bioinformatics.irida.ria.integration.pages.LoginPage; import ca.corefacility.bioinformatics.irida.ria.integration.pages.cart.CartPage; import ca.corefacility.bioinformatics.irida.ria.integration.pages.projects.ProjectSamplesPage; +import ca.corefacility.bioinformatics.irida.ria.integration.pages.projects.TableSummary; import ca.corefacility.bioinformatics.irida.ria.integration.utilities.FileUtilities; - import com.github.springtestdbunit.annotation.DatabaseSetup; import com.google.common.collect.ImmutableList; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.JavascriptExecutor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.*; @DatabaseSetup("/ca/corefacility/bioinformatics/irida/ria/web/CartView.xml") public class CartPageIT extends AbstractIridaUIITChromeDriver { @@ -397,4 +394,15 @@ private void detailsTabInfo(FastQCModal fastQCModal) { assertEquals(FILE_GC_CONTENT, fastQCModal.getGCContent(), "Displays the gc content"); } + @Test + void addAndRemoveAssociatedProjectSamplesToCart() { + LoginPage.loginAsUser(driver()); + driver().manage().window().maximize(); + + ProjectSamplesPage samplesPage = ProjectSamplesPage.goToPage(driver(), 1); + samplesPage.toggleAssociatedProject("project6"); + TableSummary summary = samplesPage.getTableSummary(); + assertEquals(25, summary.getTotal(), + "Should have more samples visible with another project selected"); + } } \ No newline at end of file From 9dce278c9936c371a9fe1942b0567f46809291cf Mon Sep 17 00:00:00 2001 From: Josh Adam Date: Mon, 31 Oct 2022 09:03:44 -0500 Subject: [PATCH 04/37] test: Working on test database --- .../ca/corefacility/bioinformatics/irida/ria/web/CartView.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/resources/ca/corefacility/bioinformatics/irida/ria/web/CartView.xml b/src/test/resources/ca/corefacility/bioinformatics/irida/ria/web/CartView.xml index 5af5b2df9bc..ddcf8512b13 100644 --- a/src/test/resources/ca/corefacility/bioinformatics/irida/ria/web/CartView.xml +++ b/src/test/resources/ca/corefacility/bioinformatics/irida/ria/web/CartView.xml @@ -36,6 +36,8 @@ + + Date: Mon, 31 Oct 2022 14:33:32 -0500 Subject: [PATCH 05/37] test: Working failing test --- .../irida/ria/integration/CartPageIT.java | 16 +++++++++++++--- .../bioinformatics/irida/ria/web/CartView.xml | 2 -- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/CartPageIT.java b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/CartPageIT.java index 9a002ba7357..45fbeed21aa 100644 --- a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/CartPageIT.java +++ b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/CartPageIT.java @@ -396,13 +396,23 @@ private void detailsTabInfo(FastQCModal fastQCModal) { @Test void addAndRemoveAssociatedProjectSamplesToCart() { - LoginPage.loginAsUser(driver()); + LoginPage.loginAsAdmin(driver()); driver().manage().window().maximize(); ProjectSamplesPage samplesPage = ProjectSamplesPage.goToPage(driver(), 1); - samplesPage.toggleAssociatedProject("project6"); + samplesPage.toggleAssociatedProject("project5"); TableSummary summary = samplesPage.getTableSummary(); - assertEquals(25, summary.getTotal(), + assertEquals(22, summary.getTotal(), "Should have more samples visible with another project selected"); + String SAMPLE_NAME = "sample5fg44"; + samplesPage.selectSampleByName(SAMPLE_NAME); + samplesPage.addSelectedSamplesToCart(); + + CartPage cartPage = CartPage.goToCart(driver()); + assertEquals(1, cartPage.getNumberOfSamplesInCart(), "Should only be 1 sample in the cart"); + cartPage.viewSampleDetailsFor(SAMPLE_NAME); + SampleDetailsViewer viewer = SampleDetailsViewer.getSampleDetails(driver()); + assertEquals("project5", viewer.getProjectName(), "Should have the correct project name"); + String foo = "bar"; } } \ No newline at end of file diff --git a/src/test/resources/ca/corefacility/bioinformatics/irida/ria/web/CartView.xml b/src/test/resources/ca/corefacility/bioinformatics/irida/ria/web/CartView.xml index ddcf8512b13..5af5b2df9bc 100644 --- a/src/test/resources/ca/corefacility/bioinformatics/irida/ria/web/CartView.xml +++ b/src/test/resources/ca/corefacility/bioinformatics/irida/ria/web/CartView.xml @@ -36,8 +36,6 @@ - - Date: Mon, 31 Oct 2022 21:00:28 -0500 Subject: [PATCH 06/37] test: Added test for adding and removing associated project sample --- .../js/pages/projects/redux/samplesSlice.js | 18 +++++++++++++---- .../irida/ria/integration/CartPageIT.java | 20 ++++++++++++++----- .../components/SampleDetailsViewer.java | 11 +++++----- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/main/webapp/resources/js/pages/projects/redux/samplesSlice.js b/src/main/webapp/resources/js/pages/projects/redux/samplesSlice.js index e4dcf4d31da..a419f2858b2 100644 --- a/src/main/webapp/resources/js/pages/projects/redux/samplesSlice.js +++ b/src/main/webapp/resources/js/pages/projects/redux/samplesSlice.js @@ -72,10 +72,20 @@ const addToCart = createAsyncThunk( "/samples/table/selected/cart", async (_, { getState }) => { const { samples } = getState(); - return await putSampleInCart( - samples.projectId, - Object.values(samples.selected) - ); + // Sort by project id + const samplesList = Object.values(samples.selected); + const projects = samplesList.reduce((prev, current) => { + if (!prev[current.projectId]) prev[current.projectId] = []; + prev[current.projectId].push(current); + return prev; + }, {}); + + const promises = []; + for (const projectId in projects) { + promises.push(putSampleInCart(projectId, projects[projectId])); + } + + return Promise.all(promises).then((responses) => responses.pop()); } ); diff --git a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/CartPageIT.java b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/CartPageIT.java index 45fbeed21aa..27ce2118ae3 100644 --- a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/CartPageIT.java +++ b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/CartPageIT.java @@ -396,23 +396,33 @@ private void detailsTabInfo(FastQCModal fastQCModal) { @Test void addAndRemoveAssociatedProjectSamplesToCart() { + final String PROJECT_NAME = "project5"; + final String ASSOCIATED_PROJECT_NAME = "project"; + final String SAMPLE_NAME = "sample5fdgr"; + final String ASSOCIATED_SAMPLE_NAME = "sample5fg44"; + LoginPage.loginAsAdmin(driver()); driver().manage().window().maximize(); ProjectSamplesPage samplesPage = ProjectSamplesPage.goToPage(driver(), 1); - samplesPage.toggleAssociatedProject("project5"); + samplesPage.toggleAssociatedProject(PROJECT_NAME); TableSummary summary = samplesPage.getTableSummary(); assertEquals(22, summary.getTotal(), "Should have more samples visible with another project selected"); - String SAMPLE_NAME = "sample5fg44"; + samplesPage.selectSampleByName(ASSOCIATED_SAMPLE_NAME); samplesPage.selectSampleByName(SAMPLE_NAME); samplesPage.addSelectedSamplesToCart(); CartPage cartPage = CartPage.goToCart(driver()); - assertEquals(1, cartPage.getNumberOfSamplesInCart(), "Should only be 1 sample in the cart"); + assertEquals(2, cartPage.getNumberOfSamplesInCart(), "Should only be 2 samples in the cart"); cartPage.viewSampleDetailsFor(SAMPLE_NAME); SampleDetailsViewer viewer = SampleDetailsViewer.getSampleDetails(driver()); - assertEquals("project5", viewer.getProjectName(), "Should have the correct project name"); - String foo = "bar"; + assertEquals(ASSOCIATED_PROJECT_NAME, viewer.getProjectName(), "Should have the correct project name"); + + viewer.clickRemoveSampleFromCartButton(); + + assertFalse(viewer.sampleDetailsViewerVisible(), "The sample details viewer should not be displayed as the sample was removed from the cart"); + + assertEquals(1, cartPage.getNumberOfSamplesInCart(), "Should only be 1 sample in the cart"); } } \ No newline at end of file diff --git a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/components/SampleDetailsViewer.java b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/components/SampleDetailsViewer.java index 8ee7525cbe7..783191b16aa 100644 --- a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/components/SampleDetailsViewer.java +++ b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/components/SampleDetailsViewer.java @@ -1,9 +1,6 @@ package ca.corefacility.bioinformatics.irida.ria.integration.components; -import java.io.IOException; -import java.time.Duration; -import java.util.List; - +import ca.corefacility.bioinformatics.irida.ria.integration.pages.AbstractPage; import org.openqa.selenium.By; import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; @@ -13,7 +10,8 @@ import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; -import ca.corefacility.bioinformatics.irida.ria.integration.pages.AbstractPage; +import java.time.Duration; +import java.util.List; public class SampleDetailsViewer extends AbstractPage { @FindBy(className = "t-sample-details-modal") @@ -361,7 +359,8 @@ public void clickAddSampleToCartButton() { public void clickRemoveSampleFromCartButton() { removeSampleFromCartBtn.click(); - waitForTime(500); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5)); + wait.until(ExpectedConditions.invisibilityOf(modal)); } public int numberOfSequencingObjectsSetAsDefault() { From fdea8e630a85374a80eb1e4f04ea2b51c34d1c3e Mon Sep 17 00:00:00 2001 From: Josh Adam Date: Mon, 31 Oct 2022 21:05:12 -0500 Subject: [PATCH 07/37] docs: Updated version number and CHANGELOG --- CHANGELOG.md | 3 +++ build.gradle.kts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9a5aec73c4..c80cf16a93e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Changelog +## [22.09.2] +* [UI] Fixed bug causing associated project samples to be added to the cart with the wrong project identifier. See [PR 1395](https://github.com/phac-nml/irida/pull/1395) + ## [22.09.1] - 2022/10/21 * [UI]: Fixed when sharing or exporting sample on the project sample page, and other minor bugs. See [PR 1382](https://github.com/phac-nml/irida/pull/1382) diff --git a/build.gradle.kts b/build.gradle.kts index cdcb39feebe..4c1b43cecb0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ plugins { } group = "ca.corefacility.bioinformatics" -version = "22.09.1" +version = "22.09.2" description = "irida" java { From 445a4522a794a47ccc33b142dcecb59924ff733a Mon Sep 17 00:00:00 2001 From: Josh Adam Date: Tue, 1 Nov 2022 12:10:38 -0500 Subject: [PATCH 08/37] docs: Fixed CHANGELOG.mdlog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c80cf16a93e..52af82abd15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # Changelog ## [22.09.2] -* [UI] Fixed bug causing associated project samples to be added to the cart with the wrong project identifier. See [PR 1395](https://github.com/phac-nml/irida/pull/1395) +* [UI]: Fixed bug causing associated project samples to be added to the cart with the wrong project identifier. See [PR 1395](https://github.com/phac-nml/irida/pull/1395) ## [22.09.1] - 2022/10/21 * [UI]: Fixed when sharing or exporting sample on the project sample page, and other minor bugs. See [PR 1382](https://github.com/phac-nml/irida/pull/1382) From 5e56f5928cacfe0b969a35e07ee549cf232d233b Mon Sep 17 00:00:00 2001 From: Josh Adam Date: Tue, 1 Nov 2022 12:03:30 -0500 Subject: [PATCH 09/37] fix: Fixed removing locked samples --- .../ProjectSamplesAjaxController.java | 26 ++-- .../ria/web/services/UISampleService.java | 115 +++++++----------- .../samples/services/sample.utilities.js | 4 +- .../pages/projects/ShareSamplesPage.java | 6 +- .../projects/ProjectSamplesPageIT.java | 39 +++++- 5 files changed, 94 insertions(+), 96 deletions(-) diff --git a/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/ajax/projects/ProjectSamplesAjaxController.java b/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/ajax/projects/ProjectSamplesAjaxController.java index 569b39fac6c..838e5f85f6c 100644 --- a/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/ajax/projects/ProjectSamplesAjaxController.java +++ b/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/ajax/projects/ProjectSamplesAjaxController.java @@ -1,17 +1,5 @@ package ca.corefacility.bioinformatics.irida.ria.web.ajax.projects; -import java.io.IOException; -import java.util.List; -import java.util.Locale; - -import javax.servlet.http.HttpServletResponse; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; - import ca.corefacility.bioinformatics.irida.ria.web.ajax.dto.CreateSampleRequest; import ca.corefacility.bioinformatics.irida.ria.web.ajax.dto.SampleFilesResponse; import ca.corefacility.bioinformatics.irida.ria.web.ajax.dto.SampleNameValidationResponse; @@ -32,6 +20,16 @@ import ca.corefacility.bioinformatics.irida.ria.web.samples.dto.ShareSamplesRequest; import ca.corefacility.bioinformatics.irida.ria.web.services.UIProjectSampleService; import ca.corefacility.bioinformatics.irida.ria.web.services.UISampleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Locale; /** * AJAX Controller for handling asynchronous requests for project samples. @@ -148,8 +146,8 @@ public ResponseEntity mergeSamples(@PathVariable Long projectId, @ @DeleteMapping("/remove") public ResponseEntity removeSamplesFromProject(@PathVariable long projectId, @RequestBody RemoveSamplesRequest request) { - String result = uiSampleService.removeSamplesFromProject(projectId, request.getSampleIds()); - return ResponseEntity.ok(new AjaxSuccessResponse(result)); + uiSampleService.removeSamplesFromProject(projectId, request.getSampleIds()); + return ResponseEntity.ok(new AjaxSuccessResponse("")); } /** diff --git a/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/services/UISampleService.java b/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/services/UISampleService.java index 94d740755da..8a6a2cab5da 100644 --- a/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/services/UISampleService.java +++ b/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/services/UISampleService.java @@ -1,80 +1,22 @@ package ca.corefacility.bioinformatics.irida.ria.web.services; -import java.io.IOException; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.text.SimpleDateFormat; -import java.time.Instant; - -import java.io.OutputStreamWriter; -import java.nio.file.attribute.BasicFileAttributes; - -import java.util.*; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import javax.servlet.http.HttpServletResponse; -import javax.validation.ConstraintViolationException; - import ca.corefacility.bioinformatics.irida.exceptions.ConcatenateException; import ca.corefacility.bioinformatics.irida.exceptions.EntityNotFoundException; +import ca.corefacility.bioinformatics.irida.model.assembly.GenomeAssembly; import ca.corefacility.bioinformatics.irida.model.assembly.UploadedAssembly; import ca.corefacility.bioinformatics.irida.model.enums.ProjectMetadataRole; -import ca.corefacility.bioinformatics.irida.model.sample.MetadataTemplateField; -import ca.corefacility.bioinformatics.irida.model.sample.metadata.MetadataRestriction; -import ca.corefacility.bioinformatics.irida.model.sequenceFile.*; -import ca.corefacility.bioinformatics.irida.repositories.sample.MetadataEntryRepository; -import ca.corefacility.bioinformatics.irida.repositories.sample.MetadataRestrictionRepository; -import ca.corefacility.bioinformatics.irida.ria.web.samples.SamplePairer; -import ca.corefacility.bioinformatics.irida.ria.web.samples.dto.*; -import ca.corefacility.bioinformatics.irida.service.sample.MetadataTemplateService; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.MessageSource; - -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Component; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.MultipartHttpServletRequest; - -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVPrinter; - -import org.apache.commons.lang3.StringUtils; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.util.DateFormatConverter; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.springframework.data.domain.Page; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; - -import ca.corefacility.bioinformatics.irida.model.assembly.GenomeAssembly; - import ca.corefacility.bioinformatics.irida.model.joins.impl.ProjectSampleJoin; import ca.corefacility.bioinformatics.irida.model.joins.impl.SampleGenomeAssemblyJoin; import ca.corefacility.bioinformatics.irida.model.project.Project; +import ca.corefacility.bioinformatics.irida.model.sample.MetadataTemplateField; import ca.corefacility.bioinformatics.irida.model.sample.QCEntry; import ca.corefacility.bioinformatics.irida.model.sample.Sample; import ca.corefacility.bioinformatics.irida.model.sample.SampleSequencingObjectJoin; import ca.corefacility.bioinformatics.irida.model.sample.metadata.MetadataEntry; -import ca.corefacility.bioinformatics.irida.ria.web.samples.dto.SampleGenomeAssemblyFileModel; -import ca.corefacility.bioinformatics.irida.ria.web.samples.dto.SampleSequencingObjectFileModel; -import ca.corefacility.bioinformatics.irida.model.sequenceFile.Fast5Object; -import ca.corefacility.bioinformatics.irida.model.sequenceFile.SequenceFilePair; -import ca.corefacility.bioinformatics.irida.model.sequenceFile.SequencingObject; -import ca.corefacility.bioinformatics.irida.model.sequenceFile.SingleEndSequenceFile; -import ca.corefacility.bioinformatics.irida.ria.web.samples.dto.SampleDetails; -import ca.corefacility.bioinformatics.irida.ria.web.samples.dto.SampleFiles; -import ca.corefacility.bioinformatics.irida.ria.web.samples.dto.ShareMetadataRestriction; -import ca.corefacility.bioinformatics.irida.ria.web.samples.dto.ShareSamplesRequest; - +import ca.corefacility.bioinformatics.irida.model.sample.metadata.MetadataRestriction; +import ca.corefacility.bioinformatics.irida.model.sequenceFile.*; +import ca.corefacility.bioinformatics.irida.repositories.sample.MetadataEntryRepository; +import ca.corefacility.bioinformatics.irida.repositories.sample.MetadataRestrictionRepository; import ca.corefacility.bioinformatics.irida.repositories.specification.ProjectSampleJoinSpecification; import ca.corefacility.bioinformatics.irida.repositories.specification.SearchCriteria; import ca.corefacility.bioinformatics.irida.repositories.specification.SearchOperation; @@ -92,19 +34,51 @@ import ca.corefacility.bioinformatics.irida.ria.web.projects.dto.samples.ProjectSamplesFilter; import ca.corefacility.bioinformatics.irida.ria.web.projects.dto.samples.SampleObject; import ca.corefacility.bioinformatics.irida.ria.web.projects.error.SampleMergeException; - +import ca.corefacility.bioinformatics.irida.ria.web.samples.SamplePairer; +import ca.corefacility.bioinformatics.irida.ria.web.samples.dto.*; import ca.corefacility.bioinformatics.irida.security.permissions.sample.UpdateSamplePermission; import ca.corefacility.bioinformatics.irida.service.GenomeAssemblyService; import ca.corefacility.bioinformatics.irida.service.ProjectService; import ca.corefacility.bioinformatics.irida.service.SequencingObjectService; - +import ca.corefacility.bioinformatics.irida.service.sample.MetadataTemplateService; import ca.corefacility.bioinformatics.irida.service.sample.SampleService; - import com.google.common.base.Strings; - +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CreationHelper; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.util.DateFormatConverter; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; +import org.springframework.data.domain.Page; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; -import com.google.common.collect.ImmutableList; +import javax.servlet.http.HttpServletResponse; +import javax.validation.ConstraintViolationException; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.util.*; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** * UI Service for samples @@ -1217,10 +1191,9 @@ private SequenceFile createSequenceFile(MultipartFile file) throws IOException { * @param sampleIds list of sampleIds to remove * @return result of the removal of samples */ - public String removeSamplesFromProject(Long projectId, List sampleIds) { + public void removeSamplesFromProject(Long projectId, List sampleIds) { Project project = projectService.read(projectId); projectService.removeSamplesFromProject(project, sampleService.readMultiple(sampleIds)); - return "FOOBAR"; } /** diff --git a/src/main/webapp/resources/js/pages/projects/samples/services/sample.utilities.js b/src/main/webapp/resources/js/pages/projects/samples/services/sample.utilities.js index 325c437c94c..8c91cdf5ff9 100644 --- a/src/main/webapp/resources/js/pages/projects/samples/services/sample.utilities.js +++ b/src/main/webapp/resources/js/pages/projects/samples/services/sample.utilities.js @@ -34,10 +34,8 @@ export function validateSamplesForRemove(samples, projectId) { values?.forEach((sample) => { if (!isSampleFromCurrentProject(sample.projectId, projectId)) { associated.push(sample); - } else if (sample.owner) { - valid.push(sample); } else { - locked.push(sample); + valid.push(sample); } }); return { valid, locked, associated }; diff --git a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/pages/projects/ShareSamplesPage.java b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/pages/projects/ShareSamplesPage.java index 61c3aba4c98..6a26d122b88 100644 --- a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/pages/projects/ShareSamplesPage.java +++ b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/pages/projects/ShareSamplesPage.java @@ -1,13 +1,13 @@ package ca.corefacility.bioinformatics.irida.ria.integration.pages.projects; -import java.util.List; - import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; +import java.util.List; + import static ca.corefacility.bioinformatics.irida.ria.integration.pages.AbstractPage.waitForTime; public class ShareSamplesPage { @@ -47,7 +47,7 @@ public class ShareSamplesPage { @FindBy(className = "t-move-checkbox") private WebElement moveCheckbox; - @FindBy(className = "t-lock-chekcbox") + @FindBy(className = "t-lock-checkbox") private WebElement lockCheckbox; @FindBy(className = "t-move-multiple") diff --git a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectSamplesPageIT.java b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectSamplesPageIT.java index a7df60c973a..1421b73b0dd 100644 --- a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectSamplesPageIT.java +++ b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectSamplesPageIT.java @@ -1,16 +1,18 @@ package ca.corefacility.bioinformatics.irida.ria.integration.projects; -import java.util.List; - -import org.junit.jupiter.api.Test; - import ca.corefacility.bioinformatics.irida.ria.integration.AbstractIridaUIITChromeDriver; import ca.corefacility.bioinformatics.irida.ria.integration.pages.LoginPage; import ca.corefacility.bioinformatics.irida.ria.integration.pages.projects.ProjectSamplesPage; +import ca.corefacility.bioinformatics.irida.ria.integration.pages.projects.ShareSamplesPage; import ca.corefacility.bioinformatics.irida.ria.integration.pages.projects.TableSummary; - import com.github.springtestdbunit.annotation.DatabaseSetup; import com.google.common.collect.ImmutableList; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +import java.time.Duration; +import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -411,5 +413,32 @@ public void testCoverageColumnWithoutProjectCoverageSettings() { assertNull(page.getCoverageForSampleByName(SAMPLE_WITH_COVERAGE_QC_ENTRY), SAMPLE_WITH_COVERAGE_QC_ENTRY + " should have a value"); } + + @Test + void testRemoveLockedSample() { + LoginPage.loginAsManager(driver()); + ProjectSamplesPage page = ProjectSamplesPage.goToPage(driver(), 1); + page.selectSampleByName(FIRST_SAMPLE_NAME); + page.openToolsDropDown(); + page.shareSamples(); + WebDriverWait wait = new WebDriverWait(driver(), Duration.ofSeconds(2)); + wait.until(ExpectedConditions.urlContains("/share")); + + ShareSamplesPage shareSamplesPage = ShareSamplesPage.initPage(driver()); + shareSamplesPage.searchForProject("project2"); + shareSamplesPage.gotToNextStep(); + shareSamplesPage.selectLockCheckbox(); + shareSamplesPage.gotToNextStep(); + shareSamplesPage.submitShareRequest(); + + page = ProjectSamplesPage.goToPage(driver(), 2); + TableSummary summary = page.getTableSummary(); + assertEquals(1, summary.getTotal(), "Should have 1 sample"); + page.selectSampleByName(FIRST_SAMPLE_NAME); + page.openToolsDropDown(); + page.removeSamples(); + summary = page.getTableSummary(); + assertEquals(0, summary.getTotal(), "There should be no samples left in this project"); + } } From 60fd01adb3896256a9fc2d74b1eab56b98a349df Mon Sep 17 00:00:00 2001 From: Josh Adam Date: Tue, 1 Nov 2022 12:08:54 -0500 Subject: [PATCH 10/37] docs: Updated changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c80cf16a93e..3272fa2e03a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ # Changelog ## [22.09.2] -* [UI] Fixed bug causing associated project samples to be added to the cart with the wrong project identifier. See [PR 1395](https://github.com/phac-nml/irida/pull/1395) +* [UI]: Fixed bug causing associated project samples to be added to the cart with the wrong project identifier. See [PR 1395](https://github.com/phac-nml/irida/pull/1395) +* [UI]: Fixed bug preventing the removal of locked samples within a project. See [PR 1396](https://github.com/phac-nml/irida/pull/1396) ## [22.09.1] - 2022/10/21 * [UI]: Fixed when sharing or exporting sample on the project sample page, and other minor bugs. See [PR 1382](https://github.com/phac-nml/irida/pull/1382) From 3744ff4499ddd2094dc65e8873aa572d9bd608fa Mon Sep 17 00:00:00 2001 From: Josh Adam Date: Tue, 1 Nov 2022 14:11:33 -0500 Subject: [PATCH 11/37] docs: Fixed JavaDoc for UISampleService --- .../bioinformatics/irida/ria/web/services/UISampleService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/services/UISampleService.java b/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/services/UISampleService.java index 8a6a2cab5da..dab0308c68a 100644 --- a/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/services/UISampleService.java +++ b/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/services/UISampleService.java @@ -1189,7 +1189,6 @@ private SequenceFile createSequenceFile(MultipartFile file) throws IOException { * * @param projectId identifier for the project * @param sampleIds list of sampleIds to remove - * @return result of the removal of samples */ public void removeSamplesFromProject(Long projectId, List sampleIds) { Project project = projectService.read(projectId); From 5578f235dfde2feef90f4ec3fd80d8376887be26 Mon Sep 17 00:00:00 2001 From: Deep Sidhu Date: Tue, 1 Nov 2022 14:39:16 -0500 Subject: [PATCH 12/37] Fixed bug if a sample was added to the cart from the sample details viewer, then closed, reopened, it would still have an add to cart button until the page was refreshed. Updated previous refetch to refetchCart --- .../js/components/samples/SampleDetailViewer.tsx | 6 +++--- .../samples/components/SampleDetailsModal.tsx | 13 +++++++++---- .../samples/components/SampleDetailsWrapper.tsx | 6 +++--- .../components/samples/components/ViewerHeader.tsx | 12 ++++++++---- .../js/pages/cart/components/SampleRenderer.jsx | 2 +- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/main/webapp/resources/js/components/samples/SampleDetailViewer.tsx b/src/main/webapp/resources/js/components/samples/SampleDetailViewer.tsx index 4d53dd87b6d..7f9b618931f 100644 --- a/src/main/webapp/resources/js/components/samples/SampleDetailViewer.tsx +++ b/src/main/webapp/resources/js/components/samples/SampleDetailViewer.tsx @@ -9,7 +9,7 @@ export interface SampleDetailViewerProps { projectId: number; displayActions?: boolean; children: React.ReactElement; - refetch?: () => void; + refetchCart?: () => void; } /** @@ -26,7 +26,7 @@ export function SampleDetailViewer({ projectId, displayActions = true, children, - refetch, + refetchCart, }: SampleDetailViewerProps): JSX.Element { const [visible, setVisible] = useState(false); @@ -41,7 +41,7 @@ export function SampleDetailViewer({ sampleId={sampleId} projectId={projectId} displayActions={displayActions} - refetchSample={refetch} + refetchCart={refetchCart} setVisible={setVisible} visible={visible} /> diff --git a/src/main/webapp/resources/js/components/samples/components/SampleDetailsModal.tsx b/src/main/webapp/resources/js/components/samples/components/SampleDetailsModal.tsx index 6114280efbe..2c3bde06f5b 100644 --- a/src/main/webapp/resources/js/components/samples/components/SampleDetailsModal.tsx +++ b/src/main/webapp/resources/js/components/samples/components/SampleDetailsModal.tsx @@ -10,7 +10,7 @@ export interface DisplaySampleDetailsProps { sampleId: number; projectId: number; displayActions?: boolean; - refetch?: () => void; + refetchCart?: () => void; visible: boolean; setVisible: Dispatch>; } @@ -21,7 +21,7 @@ export default function SampleDetailsModal({ sampleId, projectId, displayActions, - refetch, + refetchCart, visible, setVisible, }: DisplaySampleDetailsProps) { @@ -29,7 +29,11 @@ export default function SampleDetailsModal({ const [component, setComponent] = React.useState("details"); // Get the sample ready to display - const { data: details = {}, isLoading } = useGetSampleDetailsQuery({ + const { + data: details = {}, + isLoading, + refetch: refetchSample, + } = useGetSampleDetailsQuery({ sampleId, projectId, }); @@ -85,7 +89,8 @@ export default function SampleDetailsModal({ tab={component} onMenuChange={setComponent} displayActions={!!displayActions} - refetch={refetch} + refetchCart={refetchCart} + refetchSample={refetchSample} />
void; + refetchCart?: () => void; visible: boolean; setVisible: Dispatch>; } @@ -16,7 +16,7 @@ export default function SampleDetailsWrapper({ sampleId, projectId, displayActions, - refetchSample, + refetchCart, visible, setVisible, }: SampleDetailsWrapperProps) { @@ -26,7 +26,7 @@ export default function SampleDetailsWrapper({ sampleId={sampleId} projectId={projectId} displayActions={displayActions} - refetch={refetchSample} + refetchCart={refetchCart} visible={visible} setVisible={setVisible} /> diff --git a/src/main/webapp/resources/js/components/samples/components/ViewerHeader.tsx b/src/main/webapp/resources/js/components/samples/components/ViewerHeader.tsx index e224afbe24d..0053603bce0 100644 --- a/src/main/webapp/resources/js/components/samples/components/ViewerHeader.tsx +++ b/src/main/webapp/resources/js/components/samples/components/ViewerHeader.tsx @@ -15,14 +15,16 @@ export const HEADER_HEIGHT_WITH_PADDING = 97; export default function ViewerHeader({ displayActions, projectId, - refetch, + refetchCart, + refetchSample, tab, onMenuChange, }: { displayActions: boolean; projectId: number; sampleId: number; - refetch: undefined | (() => void); + refetchCart: undefined | (() => void); + refetchSample: () => void; tab: ViewerTab; onMenuChange: Dispatch>; }): JSX.Element { @@ -84,7 +86,8 @@ export default function ViewerHeader({ danger onClick={() => { dispatch(removeSampleFromCartThunk()); - if (typeof refetch !== "undefined") refetch(); + if (typeof refetchCart !== "undefined") refetchCart(); + refetchSample(); }} > {i18n("SampleDetailsViewer.removeFromCart")} @@ -96,7 +99,8 @@ export default function ViewerHeader({ className="t-add-sample-to-cart" onClick={() => { dispatch(addSampleToCartThunk()); - if (typeof refetch !== "undefined") refetch(); + if (typeof refetchCart !== "undefined") refetchCart(); + refetchSample(); }} > {i18n("SampleDetailsViewer.addToCart")} diff --git a/src/main/webapp/resources/js/pages/cart/components/SampleRenderer.jsx b/src/main/webapp/resources/js/pages/cart/components/SampleRenderer.jsx index b6e239c1386..345d2d95877 100644 --- a/src/main/webapp/resources/js/pages/cart/components/SampleRenderer.jsx +++ b/src/main/webapp/resources/js/pages/cart/components/SampleRenderer.jsx @@ -41,7 +41,7 @@ export class SampleRenderer extends React.Component { + + } /> )} diff --git a/src/main/webapp/resources/js/pages/projects/share/ShareSampleListItem.jsx b/src/main/webapp/resources/js/pages/projects/share/ShareSampleListItem.jsx index 37d46909fc2..3d869c38afa 100644 --- a/src/main/webapp/resources/js/pages/projects/share/ShareSampleListItem.jsx +++ b/src/main/webapp/resources/js/pages/projects/share/ShareSampleListItem.jsx @@ -5,7 +5,7 @@ import { IconLocked, IconUnlocked } from "../../../components/icons/Icons"; import { SampleDetailViewer } from "../../../components/samples/SampleDetailViewer"; import { green6 } from "../../../styles/colors"; import { removeSample } from "./shareSlice"; - +import { UnlockTwoTone } from "@ant-design/icons"; /** * Render a list item for the samples to be shared with another project. @@ -40,28 +40,11 @@ export default function ShareSamplesListItem({ > - } - /> - - ) : ( - - } - /> - - ) + } + /> } title={ state.shareReducer); return ( - - {i18n("ShareSamplesList.title")} - + {i18n("ShareSamplesList.title")} {associated.length > 0 && } {samples.length > 0 && ( <> @@ -113,6 +113,14 @@ export function ShareSamples({ )} + {lockedSamples.length > 0 && ( + + + {"The follow samples are locked and cannot be shared"} + + + + )} ); } diff --git a/src/main/webapp/resources/js/pages/projects/share/shareSlice.js b/src/main/webapp/resources/js/pages/projects/share/shareSlice.js index 85ac8072f73..d059c7de179 100644 --- a/src/main/webapp/resources/js/pages/projects/share/shareSlice.js +++ b/src/main/webapp/resources/js/pages/projects/share/shareSlice.js @@ -90,11 +90,16 @@ const initialState = (() => { const { samples: allSamples, projectId: currentProject } = JSON.parse(stringData); - const samples = []; - const associated = []; + const samples = [], + lockedSamples = [], + associated = []; allSamples.forEach((sample) => { if (Number(sample.projectId) === Number(currentProject)) { - samples.push(sample); + if (sample.owner) { + samples.push(sample); + } else { + lockedSamples.push(sample); + } } else { associated.push(sample); } @@ -102,6 +107,7 @@ const initialState = (() => { return { samples, + lockedSamples, associated, currentProject, locked: false, From ce15f3b8c804dce7f721a934daa0f10d9c687492 Mon Sep 17 00:00:00 2001 From: Josh Adam Date: Fri, 4 Nov 2022 12:40:45 -0500 Subject: [PATCH 34/37] test: Updated testing for sharing with locked samples --- .../samples/components/LockedSamplesList.jsx | 4 ++- .../pages/projects/ProjectSamplesPage.java | 22 +----------- .../pages/projects/ShareSamplesPage.java | 13 +++++-- .../projects/ProjectSamplesPageIT.java | 11 ------ .../projects/ProjectShareSamplesIT.java | 35 +++++++++++++++++-- 5 files changed, 46 insertions(+), 39 deletions(-) diff --git a/src/main/webapp/resources/js/pages/projects/samples/components/LockedSamplesList.jsx b/src/main/webapp/resources/js/pages/projects/samples/components/LockedSamplesList.jsx index 8e6f5b83093..8820d31e98c 100644 --- a/src/main/webapp/resources/js/pages/projects/samples/components/LockedSamplesList.jsx +++ b/src/main/webapp/resources/js/pages/projects/samples/components/LockedSamplesList.jsx @@ -32,7 +32,9 @@ export default function LockedSamplesList({ locked }) { sampleId={sample.id} projectId={sample.projectId} > - + } /> diff --git a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/pages/projects/ProjectSamplesPage.java b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/pages/projects/ProjectSamplesPage.java index 6ee9c7db755..dad7ab10fb4 100644 --- a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/pages/projects/ProjectSamplesPage.java +++ b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/pages/projects/ProjectSamplesPage.java @@ -621,27 +621,7 @@ public void gotToPreviousTablePage() { public boolean isMessageDisplayed(String message) { WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(4)); - WebElement notification = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".ant-message-custom-content.ant-message-error span:nth-child(2)"))); + WebElement notification = wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("ant-notification-notice-message"))); return wait.until(ExpectedConditions.textToBePresentInElement(notification, message)); } - - public boolean isShareWithLockedSamplesWarningDisplayed(int numSamples) { - WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(4)); - WebElement notification = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".ant-modal.ant-modal-confirm .ant-modal-confirm-title"))); - return wait.until(ExpectedConditions.textToBePresentInElement(notification, numSamples + " samples are locked and cannot be shared:")); - } - - public void closeShareWithLockedSamplesWarning() { - WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(4)); - WebElement notification = driver.findElement(By.cssSelector(".ant-modal.ant-modal-confirm")); - notification.findElement(By.className("ant-btn-default")).click(); - wait.until(ExpectedConditions.invisibilityOf(notification)); - } - - public void shareSamplesFromLockedWarning() { - WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(4)); - WebElement notification = driver.findElement(By.cssSelector(".ant-modal.ant-modal-confirm")); - notification.findElement(By.className("ant-btn-primary")).click(); - wait.until(ExpectedConditions.urlContains("/share")); - } } diff --git a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/pages/projects/ShareSamplesPage.java b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/pages/projects/ShareSamplesPage.java index 6a26d122b88..180621baf49 100644 --- a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/pages/projects/ShareSamplesPage.java +++ b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/pages/projects/ShareSamplesPage.java @@ -1,5 +1,6 @@ package ca.corefacility.bioinformatics.irida.ria.integration.pages.projects; +import ca.corefacility.bioinformatics.irida.ria.integration.pages.AbstractPage; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; @@ -8,9 +9,7 @@ import java.util.List; -import static ca.corefacility.bioinformatics.irida.ria.integration.pages.AbstractPage.waitForTime; - -public class ShareSamplesPage { +public class ShareSamplesPage extends AbstractPage { @FindBy(css = ".t-project-select .ant-select-selection-search-input") private WebElement shareProjectSelectSearch; @@ -74,6 +73,10 @@ public class ShareSamplesPage { @FindBy(className = "t-field-label") private List metadataFieldLabels; + public ShareSamplesPage(WebDriver driver) { + super(driver); + } + public static ShareSamplesPage initPage(WebDriver driver) { return PageFactory.initElements(driver, ShareSamplesPage.class); } @@ -91,6 +94,10 @@ public int getNumberOfSamplesDisplayed() { return shareSampleListItem.size(); } + public int getNumberOfLockedSamplesDisplayed() { + return driver.findElements(By.className("t-locked-name")).size(); + } + public int getNumberOfUnlockedSamples() { return unlockedSamples.size(); } diff --git a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectSamplesPageIT.java b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectSamplesPageIT.java index 6d8655f1da5..19080dde050 100644 --- a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectSamplesPageIT.java +++ b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectSamplesPageIT.java @@ -450,17 +450,6 @@ void testSharingWithLockedSamplesAsManager() { page.openToolsDropDown(); page.shareSamples(); assertTrue(page.isMessageDisplayed("All samples are locked and cannot be shared.")); - - page.selectSampleByName(FIRST_SAMPLE_NAME); - page.openToolsDropDown(); - page.shareSamples(); - assertTrue(page.isShareWithLockedSamplesWarningDisplayed(1)); - - page.closeShareWithLockedSamplesWarning(); - page.openToolsDropDown(); - page.shareSamples(); - page.shareSamplesFromLockedWarning(); - assertTrue(driver().getCurrentUrl().contains("/share")); } } diff --git a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectShareSamplesIT.java b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectShareSamplesIT.java index 723e12eb1bc..d7aafeba6d3 100644 --- a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectShareSamplesIT.java +++ b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectShareSamplesIT.java @@ -1,13 +1,11 @@ package ca.corefacility.bioinformatics.irida.ria.integration.projects; -import org.junit.jupiter.api.Test; - import ca.corefacility.bioinformatics.irida.ria.integration.AbstractIridaUIITChromeDriver; import ca.corefacility.bioinformatics.irida.ria.integration.pages.LoginPage; import ca.corefacility.bioinformatics.irida.ria.integration.pages.projects.ProjectSamplesPage; import ca.corefacility.bioinformatics.irida.ria.integration.pages.projects.ShareSamplesPage; - import com.github.springtestdbunit.annotation.DatabaseSetup; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; @@ -119,4 +117,35 @@ public void testShareSamplesAsManager() { assertEquals(1, shareSamplesPage.numberOfSamplesWithSameNames(), "There should be one sample listed which exists in the target project with the same name and different identifier"); } + + @Test + void testSharingWithALockedSample() { + final String LOCKED_SAMPLE_NAME = "sample5fdgr"; + + LoginPage.loginAsManager(driver()); + + // SHARING SINGLE SAMPLE + ProjectSamplesPage samplesPage = ProjectSamplesPage.goToPage(driver(), 1); + samplesPage.selectSampleByName("sample5fg44"); + samplesPage.selectSampleByName(LOCKED_SAMPLE_NAME); + samplesPage.shareSamples(); + + assertFalse(shareSamplesPage.isNextButtonEnabled(), ""); + shareSamplesPage.searchForProject("3"); + assertThat(shareSamplesPage.getProjectSelectText()).contains("ID: 3"); + assertTrue(shareSamplesPage.isNextButtonEnabled(), "Next button should be enabled"); + shareSamplesPage.searchForProject("project2"); + assertTrue(shareSamplesPage.isNextButtonEnabled(), "Next button should be enabled"); + shareSamplesPage.gotToNextStep(); + + assertEquals(1, shareSamplesPage.getNumberOfSamplesDisplayed(), "Should display the one sample"); + assertEquals(1, shareSamplesPage.getNumberOfLockedSamplesDisplayed(), "Should have 1 locked sample"); + assertTrue(shareSamplesPage.isPreviousButtonEnabled(), + "Since on the second step, the previous button should be enabled"); + shareSamplesPage.gotToNextStep(); + assertEquals(0, shareSamplesPage.getNumberOfSharedMetadataEntries(), "Should have no fields to share"); + shareSamplesPage.submitShareRequest(); + assertTrue(shareSamplesPage.isShareSingleSuccessDisplayed(), "Success message should be displayed"); + + } } From fabffa85aee95491140a9c9417bc5e69cc75d996 Mon Sep 17 00:00:00 2001 From: Josh Adam Date: Fri, 4 Nov 2022 12:59:12 -0500 Subject: [PATCH 35/37] test: Added missing message for if next button is not disabled --- .../irida/ria/integration/projects/ProjectShareSamplesIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectShareSamplesIT.java b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectShareSamplesIT.java index d7aafeba6d3..70e5f5e4155 100644 --- a/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectShareSamplesIT.java +++ b/src/test/java/ca/corefacility/bioinformatics/irida/ria/integration/projects/ProjectShareSamplesIT.java @@ -24,7 +24,7 @@ public void testShareSamplesAsManager() { samplesPage.selectSampleByName("sample5fg44"); samplesPage.shareSamples(); - assertFalse(shareSamplesPage.isNextButtonEnabled(), ""); + assertFalse(shareSamplesPage.isNextButtonEnabled(), "The next button should not be enabled when going to the page"); shareSamplesPage.searchForProject("3"); assertThat(shareSamplesPage.getProjectSelectText()).contains("ID: 3"); assertTrue(shareSamplesPage.isNextButtonEnabled(), "Next button should be enabled"); @@ -130,7 +130,7 @@ void testSharingWithALockedSample() { samplesPage.selectSampleByName(LOCKED_SAMPLE_NAME); samplesPage.shareSamples(); - assertFalse(shareSamplesPage.isNextButtonEnabled(), ""); + assertFalse(shareSamplesPage.isNextButtonEnabled(), "The next button should not be enabled when going to the page"); shareSamplesPage.searchForProject("3"); assertThat(shareSamplesPage.getProjectSelectText()).contains("ID: 3"); assertTrue(shareSamplesPage.isNextButtonEnabled(), "Next button should be enabled"); From ab8ca1e83ffacf0c9538ce095d8dca724a4268de Mon Sep 17 00:00:00 2001 From: Josh Adam Date: Fri, 4 Nov 2022 13:00:03 -0500 Subject: [PATCH 36/37] chore: Added missing i18n string --- src/main/resources/i18n/messages.properties | 1 + .../webapp/resources/js/pages/projects/share/ShareSamples.jsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/i18n/messages.properties b/src/main/resources/i18n/messages.properties index 64418e585f9..5386fe8b778 100644 --- a/src/main/resources/i18n/messages.properties +++ b/src/main/resources/i18n/messages.properties @@ -365,6 +365,7 @@ ShareSamples.projects=Select a project to share samples with ShareSamples.ready=These samples are ready to copy ShareSamples.exists=Samples that exist in the target project and will not be copied ShareSamples.remove=Remove +ShareSamples.locked=The follow samples are locked and cannot be shared ShareSamplesList.title=Review samples to share ShareSamples.no-samples.message=All samples exist in the target project ShareSamples.no-samples.description=Since these samples exists, there is no reason to re-share them. diff --git a/src/main/webapp/resources/js/pages/projects/share/ShareSamples.jsx b/src/main/webapp/resources/js/pages/projects/share/ShareSamples.jsx index 1b44b51e077..de276ee89e7 100644 --- a/src/main/webapp/resources/js/pages/projects/share/ShareSamples.jsx +++ b/src/main/webapp/resources/js/pages/projects/share/ShareSamples.jsx @@ -116,7 +116,7 @@ export function ShareSamples({ {lockedSamples.length > 0 && ( - {"The follow samples are locked and cannot be shared"} + {i18n("ShareSamples.locked")} From b8ada8bca900ca33abcabbb691f7492ac87d2524 Mon Sep 17 00:00:00 2001 From: Eric Enns Date: Fri, 4 Nov 2022 13:40:01 -0500 Subject: [PATCH 37/37] chore: add in link to compare 22.09.2 release to 22.09.1 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 468bab535f5..70cd336e6f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog -## [22.09.2] +## [22.09.2] - 2022/11/04 * [UI]: Fixed bug causing associated project samples to be added to the cart with the wrong project identifier. See [PR 1395](https://github.com/phac-nml/irida/pull/1395) * [UI]: Fixed bug preventing the removal of locked samples within a project. See [PR 1396](https://github.com/phac-nml/irida/pull/1396) * [Developer/UI]: Fixed bug preventing managers from sharing project samples. See [PR 1398](https://github.com/phac-nml/irida/pull/1398) @@ -141,6 +141,7 @@ ## [...previous](https://github.com/phac-nml/irida/blob/21.09.2/CHANGELOG.md) +[22.09.2]: https://github.com/phac-nml/irida/compare/22.09.1...22.09.2 [22.09.1]: https://github.com/phac-nml/irida/compare/22.09...22.09.1 [22.09]: https://github.com/phac-nml/irida/compare/22.05.5...22.09 [22.05.5]: https://github.com/phac-nml/irida/compare/22.05.4...22.05.5