--- /dev/null
+package jalview.ws2.actions.secstructpred;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.equalTo;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.ArgumentMatchers.any;
+import static jalview.testutils.ScopeFunctions.apply;
+import static jalview.testutils.Matchers.matchesSequenceString;
+
+import jalview.io.DataSourceType;
+import jalview.io.FastaFile;
+import jalview.io.JPredFile;
+
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignViewport;
+import jalview.ws2.actions.ServiceInputInvalidException;
+import jalview.ws2.api.Credentials;
+import jalview.ws2.api.JobStatus;
+import jalview.ws2.api.WebServiceJobHandle;
+import jalview.ws2.client.api.SecStructPredWebServiceClientI;
+import static java.lang.String.format;
+
+public class SecStructPredPDBSearchTaskTest
+{
+ protected SecStructPredWebServiceClientI mockClient;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setupMockClient() throws IOException
+ {
+ mockClient = mock(SecStructPredWebServiceClientI.class);
+ when(mockClient.getUrl()).thenReturn("http://example.org");
+ when(mockClient.getClientName()).thenReturn("mock");
+ when(mockClient.getLog(any())).thenReturn("");
+ when(mockClient.getErrorLog(any())).thenReturn("");
+ }
+
+ @DataProvider
+ public Object[][] viewportAndExpectedInputSeq()
+ {
+ return new Object[][] {
+ { new AlignViewport(createAlignment("AAAAAAAAAAAAAAAAAAAA")),
+ "AAAAAAAAAAAAAAAAAAAA", },
+ { new AlignViewport(createAlignment("--AAGGAGAG-AGGA----MMMMMMMM")),
+ "AAGGAGAGAGGAMMMMMMMM" },
+ { new AlignViewport(createAlignment("AAAANNNCCCCCCCCCCAAAAAA"),
+ apply(new HiddenColumns(), it -> it.hideColumns(4, 6))),
+ "AAAACCCCCCCCCCAAAAAA" },
+ { new AlignViewport(
+ createAlignment("NNNNGGGGVVVVVAAAAAAACCMMMMMMMM"),
+ apply(new HiddenColumns(), it -> {
+ it.hideColumns(4, 7);
+ it.hideColumns(20, 21);
+ })),
+ "NNNNVVVVVAAAAAAAMMMMMMMM" } };
+ }
+
+ public static AlignmentI createAlignment(String... sequences)
+ {
+ var seqArray = new Sequence[sequences.length];
+ for (int i = 0; i < sequences.length; i++)
+ seqArray[i] = new Sequence(format("Seq%d", i), sequences[i]);
+ return new Alignment(seqArray);
+ }
+
+ @Test(
+ groups = { "Functional" },
+ dataProvider = "viewportAndExpectedInputSeq")
+ public void testPrepareJobs_checkInputSequences(AlignViewport viewport,
+ String expectedSeq) throws Exception
+ {
+ var task = new SecStructPredPDBSearchTask(mockClient, List.of(),
+ Credentials.empty(), viewport);
+ var jobs = task.prepareJobs();
+ assertThat(jobs.get(0).getInputSequences(),
+ contains(matchesSequenceString(expectedSeq)));
+ }
+
+ @DataProvider
+ public Object[][] viewportWithTooShortSequence()
+ {
+ return new Object[][] {
+ { new AlignViewport(createAlignment("")) },
+ { new AlignViewport(createAlignment("A")) },
+ { new AlignViewport(createAlignment("AAAAAAAAAAAAAAAAAAA")) },
+ { new AlignViewport(createAlignment("AAAAACCCCCAAAAA-----CC")) },
+ { new AlignViewport(createAlignment("-------------------------")) },
+ { new AlignViewport(createAlignment("AAAAAAAAAAAAAAAAAAAAAAAAA"),
+ apply(new HiddenColumns(), it -> it.hideColumns(0, 24))) },
+ { new AlignViewport(createAlignment("AAAAACCCCCAAAAACCCCCAAAAA"),
+ apply(new HiddenColumns(), it -> it.hideColumns(0, 10))) } };
+ }
+
+ @Test(
+ groups = { "Functional" },
+ dataProvider = "viewportWithTooShortSequence",
+ expectedExceptions = ServiceInputInvalidException.class)
+ public void testPrepareJobs_SequenceTooShort_InputInvalidException(
+ AlignViewport viewport) throws ServiceInputInvalidException
+ {
+ var task = new SecStructPredPDBSearchTask(mockClient, List.of(),
+ Credentials.empty(), viewport);
+ task.prepareJobs();
+ }
+
+ @DataProvider
+ public Object[][] collectResultDataset() throws IOException
+ {
+ return new Object[][] {
+ {
+ new AlignViewport(new Alignment(new FastaFile(
+ "examples/testdata/secstrpred/sequence0_input.fa",
+ DataSourceType.FILE).getSeqsAsArray()
+ )),
+ "examples/testdata/secstrpred/sequence0.align",
+ "examples/testdata/secstrpred/sequence0.concise"
+ },
+ };
+ }
+
+ @Test(groups = { "Functional" }, dataProvider = "collectResultDataset")
+ public void testCollectResult(AlignViewport viewport, String alnFileName,
+ String predFileName) throws Exception
+ {
+ var alnFile = new FastaFile(alnFileName, DataSourceType.FILE);
+ var predFile = new JPredFile(predFileName, DataSourceType.FILE);
+ when(mockClient.getPredictionFile(any())).thenReturn(predFile);
+ when(mockClient.getAlignmentFile(any())).thenReturn(alnFile);
+ when(mockClient.getStatus(any())).thenReturn(JobStatus.COMPLETED);
+ when(mockClient.submit(any(), any(), any()))
+ .thenReturn(new WebServiceJobHandle("mock", "mock",
+ "http://example.org", "0"));
+
+ var task = new SecStructPredPDBSearchTask(mockClient, List.of(),
+ Credentials.empty(), viewport);
+ task.init();
+ task.poll();
+ task.complete();
+ var resultAlignment = task.getResult();
+ var sequences = resultAlignment.getSequences();
+
+ {
+ List<Matcher<? super SequenceI>> matchers = new ArrayList<>();
+ for (var seq : alnFile.getSeqs())
+ matchers.add(matchesSequenceString(seq));
+ assertThat(sequences, Matchers.contains(matchers));
+ }
+
+ {
+ var originalHidden = viewport.getAlignment().getHiddenColumns();
+ var resultHidden = resultAlignment.getHiddenColumns();
+ assertThat(resultHidden, equalTo(originalHidden));
+ }
+ }
+}