+ discoverer.setUrls(List.of());
+ assertThat(Cache.getProperty(URLS_PROPERTY_NAME), is(nullValue()));
+ }
+
+ @Test
+ public void testSetUrls_null_propertyReset()
+ {
+ Cache.setProperty(URLS_PROPERTY_NAME, "http://www.example.org");
+ var discoverer = SlivkaWSDiscoverer.getInstance();
+ discoverer.setUrls(null);
+ assertThat(Cache.getProperty(URLS_PROPERTY_NAME), is(nullValue()));
+ }
+
+ @DataProvider
+ public Object[][] urlsList() throws MalformedURLException
+ {
+ return new Object[][] {
+ { List.of(new URL("http://example.org")), "http://example.org" },
+ { List.of(new URL("http://example.org/")), "http://example.org/" },
+ { List.of(new URL("http://example.org/slivka/")),
+ "http://example.org/slivka/" },
+ { List.of(new URL("https://www.compbio.dundee.ac.uk/slivka/"),
+ new URL("http://example.org")),
+ "https://www.compbio.dundee.ac.uk/slivka/,http://example.org" }, };
+ }
+
+ @Test(dataProvider = "urlsList")
+ public void testSetUrls_urlsPropertySet(List<URL> urls, String expected)
+ throws MalformedURLException
+ {
+ var discoverer = SlivkaWSDiscoverer.getInstance();
+ discoverer.setUrls(urls);
+ assertThat(Cache.getProperty(URLS_PROPERTY_NAME), equalTo(expected));
+ }
+
+ @Test
+ public void testFetchServices_oneService_basicDataMatches()
+ throws IOException
+ {
+ var service = new SlivkaService(
+ URI.create("http://example.org/api/services/example"),
+ "example", "Example name", "Example service description",
+ "John Smith", "1.0", "MIT License",
+ List.of("operation::analysis::multiple sequence alignment"),
+ List.of(), List.of(), null);
+ when(clientMock.getServices()).thenReturn(List.of(service));
+ when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
+ var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
+ var webServices = discoverer
+ .fetchServices(new URL("http://example.org/"));
+ assertThat(webServices, hasSize(1));
+ var webService = webServices.get(0);
+ assertThat(webService.getUrl(),
+ equalTo(new URL("http://example.org/")));
+ assertThat(webService.getClientName(), equalTo("slivka"));
+ assertThat(webService.getName(), equalTo("Example name"));
+ assertThat(webService.getDescription(),
+ equalTo("Example service description"));
+ }
+
+ @DataProvider
+ public String[] validMultipleSequenceAlignmentClassifiers()
+ {
+ return new String[] {
+ "Operation :: Analysis :: Multiple sequence alignment",
+ "operation :: analysis :: multiple sequence alignment",
+ "Operation\t::\tAnalysis\t::\tMultiple sequence alignment",
+ "Operation::Analysis::Multiple sequence alignment",
+ "Operation :: Analysis :: Multiple Sequence Alignment",
+ "OPERATION :: ANALYSIS :: MULTIPLE SEQUENCE ALIGNMENT",
+ "Operation :: Analysis :: Sequence alignment :: Multiple sequence alignment",
+ "Operation :: Analysis :: Sequence analysis :: Sequence alignment :: Multiple sequence alignment",
+ "Operation :: Alignment :: Multiple sequence alignment",
+ "Operation :: Alignment :: Sequence alignment :: Multiple sequence alignment",
+ "Operation :: Comparison :: Multiple sequence alignment",
+ "Operation :: Comparison :: Sequence comparison :: Sequence alignment :: Multiple sequence alignment" };
+
+ }
+
+ @Test(dataProvider = "validMultipleSequenceAlignmentClassifiers")
+ public void testFetchServices_multipleSequenceAlignmentClassifier_serviceTypeIsMSA(
+ String classifier) throws IOException
+ {
+ var service = new SlivkaService(URI.create("http://example.org/"),
+ "example", "name", "description", "author", "1.0", "MIT",
+ List.of(classifier), List.of(), List.of(), null);
+ when(clientMock.getServices()).thenReturn(List.of(service));
+ when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
+ var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
+ var webServices = discoverer
+ .fetchServices(new URL("http://example.org/"));
+ assertThat(webServices, hasSize(1));
+ assertThat(webServices.get(0).getCategory(), equalTo("Alignment"));
+ assertThat(webServices.get(0).getActionClass(),
+ typeCompatibleWith(AlignmentAction.class));
+ }
+
+ @DataProvider
+ public SlivkaService[] multipleSequenceAlignmentService()
+ {
+ return new SlivkaService[] { new SlivkaService(
+ URI.create("http://example.org/"), "example", "Examaple name",
+ "Example description", "John Smith", "1.0", "MIT",
+ List.of("Operation :: Analysis :: Multiple sequence alignment"),
+ List.of(), List.of(), null),
+ new SlivkaService(
+ URI.create("http://example.org/api/services/muscle"),
+ "muscle", "MUSCLE",
+ "MUltiple Sequence Comparison by Log- Expectation",
+ "Robert C. Edgar", "3.8.31", "Public domain",
+ List.of("Topic :: Computational biology :: Sequence analysis",
+ "Operation :: Analysis :: Sequence analysis :: Sequence alignment :: Multiple sequence alignment"),
+ List.of(), List.of(), null),
+ new SlivkaService(
+ URI.create("http://example.org/api/services/tcoffee"),
+ "tcoffee", "TCoffee",
+ "Tree-based Consistency Objective Function for Alignment Evaluation",
+ "Cedric Notredame", "13.41.0", "GNU GPL",
+ List.of("Topic :: Computational biology :: Sequence analysis",
+ "Operation :: Analysis :: Sequence analysis :: Sequence alignment :: Multiple sequence alignment"),
+ List.of(), List.of(), null) };
+ }
+
+ @Test(dataProvider = "multipleSequenceAlignmentService")
+ public void testFetchServices_multipleSequenceAlignmentService_actionTypeIsAlignment(
+ SlivkaService service) throws IOException
+ {
+ when(clientMock.getServices()).thenReturn(List.of(service));
+ when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
+ var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
+ var webServices = discoverer
+ .fetchServices(new URL("http://example.org/"));
+ assertThat(webServices.get(0).getCategory(), equalTo("Alignment"));
+ assertThat(webServices.get(0).getActionClass(),
+ typeCompatibleWith(AlignmentAction.class));
+ }
+
+ @Test(dataProvider = "multipleSequenceAlignmentService")
+ public void testFetchServices_multipleSequenceAlignmentService_serviceIsNonInteractive(
+ SlivkaService service) throws IOException
+ {
+ when(clientMock.getServices()).thenReturn(List.of(service));
+ when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
+ var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
+ var webServices = discoverer
+ .fetchServices(new URL("http://example.org/"));
+ assertThat(webServices.get(0).isInteractive(), is(false));
+ }
+
+ @DataProvider
+ public SlivkaService[] clustalFamilyService()
+ {
+ return new SlivkaService[] { new SlivkaService(
+ URI.create("http://example.org/api/services/clustalo"),
+ "clustalo", "ClustalO",
+ "Clustal Omega is the latest addition to the Clustal family.",
+ "Fabian Sievers, et al.", "1.2.4", "GNU GPL ver. 2",
+ List.of("Topic :: Computational biology :: Sequence analysis",
+ "Operation :: Analysis :: Sequence analysis :: Sequence alignment :: Multiple sequence alignment"),
+ List.of(), List.of(), null),
+ new SlivkaService(
+ URI.create("http://example.org/api/services/clustalw"),
+ "clustalw", "ClustalW",
+ "ClustalW is a general purpose multiple alignment program.",
+ "Larkin MA, et al.", "2.1", "GNU GPL ver. 3",
+ List.of("Topic :: Computation biology :: Sequence analysis",
+ "Operation :: Analysis :: Multiple sequence alignment"),
+ List.of(), List.of(), null),
+ new SlivkaService(
+ URI.create("http://example.org/api/services/clustalw2"),
+ "clustalw2", "ClustalW2",
+ "ClustalW is a general purpose multiple alignment program.",
+ "Larkin MA, et al.", "2.1", "GNU GPL ver. 3",
+ List.of("Topic :: Computation biology :: Sequence analysis",
+ "Operation :: Analysis :: Multiple sequence alignment"),
+ List.of(), List.of(), null), };
+ }
+
+ @Test(dataProvider = "clustalFamilyService")
+ public void testFetchService_clustalFamilyService_containsTwoActions(
+ SlivkaService service) throws IOException
+ {
+ when(clientMock.getServices()).thenReturn(List.of(service));
+ when(clientMock.getUrl()).thenReturn(URI.create("http://example.org"));
+ var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
+ var webServices = discoverer
+ .fetchServices(new URL("http://example.org"));
+ var actions = webServices.get(0).getActions();
+ assertThat(actions, hasSize(2));
+ assertThat(actions.get(0), allOf(hasProperty("name", is("Alignment")),
+ hasProperty("subcategory", is("Align"))));
+ assertThat(actions.get(1),
+ allOf(hasProperty("name", is("Re-alignment")),
+ hasProperty("subcategory", is("Realign"))));
+ }
+
+ @DataProvider
+ public String[] validRNASecondaryStructurePredictionClassifiers()
+ {
+ return new String[] {
+ "Operation :: Analysis :: RNA secondary structure prediction",
+ "operation :: analysis :: rna secondary structure prediction",
+ "OPERATION :: ANALYSIS :: RNA SECONDARY STRUCTURE PREDICTION",
+ "Operation\t::\tAnalysis\t::\tRNA secondary structure prediction",
+ "Operation::Analysis::RNA secondary structure prediction",
+ "Operation :: Analysis :: Structure analysis :: RNA secondary structure prediction",
+ "Operation :: Analysis :: Structure analysis :: Nucleic acid structure analysis :: RNA secondary structure analysis :: RNA secondary structure prediction",
+ "Operation :: Analysis :: Structure analysis :: Nucleic acid structure analysis :: Nucleic acid structure prediction :: RNA secondary structure prediction",
+ "Operation :: Analysis :: Sequence analysis :: Nucleic acid sequence analysis :: Nucleic acid feature detection :: RNA secondary structure prediction",
+ "Operation :: Prediction and recognition :: RNA secondary structure prediction",
+ "Operation :: Prediction and recognition :: Nucleic acid feature detection :: RNA secondary structure prediction",
+ "Operation :: Prediction and recignition :: Nucleic acid structure prediction :: RNA secondary structure prediction", };
+ }
+
+ @DataProvider
+ public Iterator<Object> RNASecondaryStructurePredictionService()
+ {
+ var services = new ArrayList<>();
+ for (var classifier : validRNASecondaryStructurePredictionClassifiers())