JAL-4199 Set all setup methods to alwaysRun
[jalview.git] / test / jalview / ws2 / client / slivka / SlivkaWSDiscovererTest.java
1 package jalview.ws2.client.slivka;
2
3 import static org.hamcrest.MatcherAssert.assertThat;
4 import static org.hamcrest.Matchers.allOf;
5 import static org.hamcrest.Matchers.contains;
6 import static org.hamcrest.Matchers.equalTo;
7 import static org.hamcrest.Matchers.hasProperty;
8 import static org.hamcrest.Matchers.hasSize;
9 import static org.hamcrest.Matchers.instanceOf;
10 import static org.hamcrest.Matchers.is;
11 import static org.hamcrest.Matchers.nullValue;
12 import static org.hamcrest.Matchers.typeCompatibleWith;
13 import static org.mockito.Mockito.mock;
14 import static org.mockito.Mockito.when;
15
16 import java.io.IOException;
17 import java.net.MalformedURLException;
18 import java.net.URI;
19 import java.net.URL;
20 import java.util.ArrayList;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.function.Function;
25
26 import org.hamcrest.Matcher;
27 import org.testng.annotations.BeforeClass;
28 import org.testng.annotations.BeforeMethod;
29 import org.testng.annotations.DataProvider;
30 import org.testng.annotations.Test;
31
32 import jalview.bin.Cache;
33 import jalview.bin.Console;
34 import jalview.ws.params.ValueConstrainI.ValueType;
35 import jalview.ws.params.simple.BooleanOption;
36 import jalview.ws.params.simple.DoubleParameter;
37 import jalview.ws.params.simple.IntegerParameter;
38 import jalview.ws.params.simple.StringParameter;
39 import jalview.ws2.actions.alignment.AlignmentAction;
40 import jalview.ws2.actions.annotation.AnnotationAction;
41 import jalview.ws2.client.api.WebServiceDiscovererI;
42 import uk.ac.dundee.compbio.slivkaclient.Parameter;
43 import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
44 import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
45
46 public class SlivkaWSDiscovererTest
47 {
48   private static final String URLS_PROPERTY_NAME = "SLIVKAHOSTURLS";
49
50   SlivkaClient clientMock;
51
52   Function<URL, SlivkaClient> factoryMock;
53
54   @BeforeClass(alwaysRun = true)
55   public void setupProperties()
56   {
57     Cache.loadProperties("test/jalview/ws2/client/slivka/default.jvprops");
58     Console.initLogger();
59   }
60
61   @BeforeMethod(alwaysRun = true)
62   public void setupDiscoverer() throws IOException
63   {
64     clientMock = mock(SlivkaClient.class);
65   }
66
67   @Test(groups = { "Functional" })
68   public void getStatusForUrl_servicesReturned_statusIsOK() throws Exception
69   {
70     when(clientMock.getServices())
71         .thenReturn(List.of(mock(SlivkaService.class)));
72     var discoverer = new SlivkaWSDiscoverer(
73         url -> url.toString().equals("http://example.org") ? clientMock
74             : null);
75     assertThat(discoverer.getStatusForUrl(new URL("http://example.org")),
76         is(WebServiceDiscovererI.STATUS_OK));
77   }
78
79   @Test(groups = { "Functional" })
80   public void getStatusForUrl_noServicesReturned_statusIsNoServices()
81       throws Exception
82   {
83     when(clientMock.getServices()).thenReturn(List.of());
84     var discoverer = new SlivkaWSDiscoverer(
85         url -> url.toString().equals("http://example.org") ? clientMock
86             : null);
87     assertThat(discoverer.getStatusForUrl(new URL("http://example.org")),
88         is(WebServiceDiscovererI.STATUS_NO_SERVICES));
89   }
90
91   @Test(groups = { "Functional" })
92   public void getStatusForUrl_exceptionThrown_statusIsInvalid()
93       throws Exception
94   {
95     when(clientMock.getServices()).thenThrow(new IOException());
96     var discoverer = new SlivkaWSDiscoverer(
97         url -> url.toString().equals("http://example.org") ? clientMock
98             : null);
99     assertThat(discoverer.getStatusForUrl(new URL("http://example.org")),
100         is(WebServiceDiscovererI.STATUS_INVALID));
101   }
102
103   @Test(groups = { "Functional" })
104   public void testGetUrls_noPropEntry_defaultUrlReturned()
105       throws MalformedURLException
106   {
107     var discoverer = SlivkaWSDiscoverer.getInstance();
108     assertThat(discoverer.getUrls(),
109         contains(new URL("https://www.compbio.dundee.ac.uk/slivka/")));
110   }
111
112   @DataProvider
113   public Object[][] urlPropertyValues() throws MalformedURLException
114   {
115     return new Object[][] {
116         { "http://example.org/", List.of(new URL("http://example.org/")) },
117         { "https://example.org/slivka/",
118             List.of(new URL("https://example.org/slivka/")) },
119         { "https://www.compbio.dundee.ac.uk/,http://www.example.org/",
120             List.of(new URL("https://www.compbio.dundee.ac.uk/"),
121                 new URL("http://www.example.org/")) },
122         { "http://example.org/,", List.of(new URL("http://example.org/")) },
123         { ",http://example.org", List.of(new URL("http://example.org")) },
124         { "", List.of() },
125         { ",", List.of() },
126         { "example.org", List.of() },
127         { "example.org,http://example.org",
128             List.of(new URL("http://example.org")) } };
129   }
130
131   @Test(groups = { "Functional" }, dataProvider = "urlPropertyValues")
132   public void testGetUrls_urlsProperlyParsed(String propValue,
133       List<URL> expected)
134   {
135     Cache.setProperty(URLS_PROPERTY_NAME, propValue);
136     var discoverer = SlivkaWSDiscoverer.getInstance();
137     assertThat(discoverer.getUrls(), equalTo(expected));
138   }
139
140   @Test(groups = { "Functional" })
141   public void testSetUrls_emptyList_propertyReset()
142   {
143     Cache.setProperty(URLS_PROPERTY_NAME, "http://www.example.org");
144     var discoverer = SlivkaWSDiscoverer.getInstance();
145     discoverer.setUrls(List.of());
146     assertThat(Cache.getProperty(URLS_PROPERTY_NAME), is(nullValue()));
147   }
148
149   @Test(groups = { "Functional" })
150   public void testSetUrls_null_propertyReset()
151   {
152     Cache.setProperty(URLS_PROPERTY_NAME, "http://www.example.org");
153     var discoverer = SlivkaWSDiscoverer.getInstance();
154     discoverer.setUrls(null);
155     assertThat(Cache.getProperty(URLS_PROPERTY_NAME), is(nullValue()));
156   }
157
158   @DataProvider
159   public Object[][] urlsList() throws MalformedURLException
160   {
161     return new Object[][] {
162         { List.of(new URL("http://example.org")), "http://example.org" },
163         { List.of(new URL("http://example.org/")), "http://example.org/" },
164         { List.of(new URL("http://example.org/slivka/")),
165             "http://example.org/slivka/" },
166         { List.of(new URL("https://www.compbio.dundee.ac.uk/slivka/"),
167             new URL("http://example.org")),
168             "https://www.compbio.dundee.ac.uk/slivka/,http://example.org" }, };
169   }
170
171   @Test(groups = { "Functional" }, dataProvider = "urlsList")
172   public void testSetUrls_urlsPropertySet(List<URL> urls, String expected)
173       throws MalformedURLException
174   {
175     var discoverer = SlivkaWSDiscoverer.getInstance();
176     discoverer.setUrls(urls);
177     assertThat(Cache.getProperty(URLS_PROPERTY_NAME), equalTo(expected));
178   }
179
180   @Test(groups = { "Functional" })
181   public void testFetchServices_oneService_basicDataMatches()
182       throws IOException
183   {
184     var service = new SlivkaService(
185         URI.create("http://example.org/api/services/example"),
186         "example", "Example name", "Example service description",
187         "John Smith", "1.0", "MIT License",
188         List.of("operation::analysis::multiple sequence alignment"),
189         List.of(), List.of(), null);
190     when(clientMock.getServices()).thenReturn(List.of(service));
191     when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
192     var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
193     var webServices = discoverer
194         .fetchServices(new URL("http://example.org/"));
195     assertThat(webServices, hasSize(1));
196     var webService = webServices.get(0);
197     assertThat(webService.getUrl(),
198         equalTo(new URL("http://example.org/")));
199     assertThat(webService.getClientName(), equalTo("slivka"));
200     assertThat(webService.getName(), equalTo("Example name"));
201     assertThat(webService.getDescription(),
202         equalTo("Example service description"));
203   }
204
205   @DataProvider
206   public String[] validMultipleSequenceAlignmentClassifiers()
207   {
208     return new String[] {
209         "Operation :: Analysis :: Multiple sequence alignment",
210         "operation :: analysis :: multiple sequence alignment",
211         "Operation\t::\tAnalysis\t::\tMultiple sequence alignment",
212         "Operation::Analysis::Multiple sequence alignment",
213         "Operation :: Analysis :: Multiple Sequence Alignment",
214         "OPERATION :: ANALYSIS :: MULTIPLE SEQUENCE ALIGNMENT",
215         "Operation :: Analysis :: Sequence alignment :: Multiple sequence alignment",
216         "Operation :: Analysis :: Sequence analysis :: Sequence alignment :: Multiple sequence alignment",
217         "Operation :: Alignment :: Multiple sequence alignment",
218         "Operation :: Alignment :: Sequence alignment :: Multiple sequence alignment",
219         "Operation :: Comparison :: Multiple sequence alignment",
220         "Operation :: Comparison :: Sequence comparison :: Sequence alignment :: Multiple sequence alignment" };
221
222   }
223
224   @Test(
225     groups = { "Functional" },
226     dataProvider = "validMultipleSequenceAlignmentClassifiers")
227   public void testFetchServices_multipleSequenceAlignmentClassifier_serviceTypeIsMSA(
228       String classifier) throws IOException
229   {
230     var service = new SlivkaService(URI.create("http://example.org/"),
231         "example", "name", "description", "author", "1.0", "MIT",
232         List.of(classifier), List.of(), List.of(), null);
233     when(clientMock.getServices()).thenReturn(List.of(service));
234     when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
235     var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
236     var webServices = discoverer
237         .fetchServices(new URL("http://example.org/"));
238     assertThat(webServices, hasSize(1));
239     assertThat(webServices.get(0).getCategory(), equalTo("Alignment"));
240     assertThat(webServices.get(0).getActionClass(),
241         typeCompatibleWith(AlignmentAction.class));
242   }
243
244   @DataProvider
245   public SlivkaService[] multipleSequenceAlignmentService()
246   {
247     return new SlivkaService[] {
248         new SlivkaService(
249             URI.create("http://example.org/"), "example", "Examaple name",
250             "Example description", "John Smith", "1.0", "MIT",
251             List.of("Operation :: Analysis :: Multiple sequence alignment"),
252             List.of(), List.of(), null),
253         new SlivkaService(
254             URI.create("http://example.org/api/services/muscle"),
255             "muscle", "MUSCLE",
256             "MUltiple Sequence Comparison by Log- Expectation",
257             "Robert C. Edgar", "3.8.31", "Public domain",
258             List.of("Topic :: Computational biology :: Sequence analysis",
259                 "Operation :: Analysis :: Sequence analysis :: Sequence alignment :: Multiple sequence alignment"),
260             List.of(), List.of(), null),
261         new SlivkaService(
262             URI.create("http://example.org/api/services/tcoffee"),
263             "tcoffee", "TCoffee",
264             "Tree-based Consistency Objective Function for Alignment Evaluation",
265             "Cedric Notredame", "13.41.0", "GNU GPL",
266             List.of("Topic :: Computational biology :: Sequence analysis",
267                 "Operation :: Analysis :: Sequence analysis :: Sequence alignment :: Multiple sequence alignment"),
268             List.of(), List.of(), null) };
269   }
270
271   @Test(
272     groups = { "Functional" },
273     dataProvider = "multipleSequenceAlignmentService")
274   public void testFetchServices_multipleSequenceAlignmentService_actionTypeIsAlignment(
275       SlivkaService service) throws IOException
276   {
277     when(clientMock.getServices()).thenReturn(List.of(service));
278     when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
279     var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
280     var webServices = discoverer
281         .fetchServices(new URL("http://example.org/"));
282     assertThat(webServices.get(0).getCategory(), equalTo("Alignment"));
283     assertThat(webServices.get(0).getActionClass(),
284         typeCompatibleWith(AlignmentAction.class));
285   }
286
287   @Test(
288     groups = { "Functional" },
289     dataProvider = "multipleSequenceAlignmentService")
290   public void testFetchServices_multipleSequenceAlignmentService_serviceIsNonInteractive(
291       SlivkaService service) throws IOException
292   {
293     when(clientMock.getServices()).thenReturn(List.of(service));
294     when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
295     var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
296     var webServices = discoverer
297         .fetchServices(new URL("http://example.org/"));
298     assertThat(webServices.get(0).isInteractive(), is(false));
299   }
300
301   @DataProvider
302   public SlivkaService[] clustalFamilyService()
303   {
304     return new SlivkaService[] {
305         new SlivkaService(
306             URI.create("http://example.org/api/services/clustalo"),
307             "clustalo", "ClustalO",
308             "Clustal Omega is the latest addition to the Clustal family.",
309             "Fabian Sievers, et al.", "1.2.4", "GNU GPL ver. 2",
310             List.of("Topic :: Computational biology :: Sequence analysis",
311                 "Operation :: Analysis :: Sequence analysis :: Sequence alignment :: Multiple sequence alignment"),
312             List.of(), List.of(), null),
313         new SlivkaService(
314             URI.create("http://example.org/api/services/clustalw"),
315             "clustalw", "ClustalW",
316             "ClustalW is a general purpose multiple alignment program.",
317             "Larkin MA, et al.", "2.1", "GNU GPL ver. 3",
318             List.of("Topic :: Computation biology :: Sequence analysis",
319                 "Operation :: Analysis :: Multiple sequence alignment"),
320             List.of(), List.of(), null),
321         new SlivkaService(
322             URI.create("http://example.org/api/services/clustalw2"),
323             "clustalw2", "ClustalW2",
324             "ClustalW is a general purpose multiple alignment program.",
325             "Larkin MA, et al.", "2.1", "GNU GPL ver. 3",
326             List.of("Topic :: Computation biology :: Sequence analysis",
327                 "Operation :: Analysis :: Multiple sequence alignment"),
328             List.of(), List.of(), null), };
329   }
330
331   @Test(groups = { "Functional" }, dataProvider = "clustalFamilyService")
332   public void testFetchService_clustalFamilyService_containsTwoActions(
333       SlivkaService service) throws IOException
334   {
335     when(clientMock.getServices()).thenReturn(List.of(service));
336     when(clientMock.getUrl()).thenReturn(URI.create("http://example.org"));
337     var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
338     var webServices = discoverer
339         .fetchServices(new URL("http://example.org"));
340     var actions = webServices.get(0).getActions();
341     assertThat(actions, hasSize(2));
342     assertThat(actions.get(0), allOf(hasProperty("name", is("Alignment")),
343         hasProperty("subcategory", is("Align"))));
344     assertThat(actions.get(1),
345         allOf(hasProperty("name", is("Re-alignment")),
346             hasProperty("subcategory", is("Realign"))));
347   }
348
349   @DataProvider
350   public String[] validRNASecondaryStructurePredictionClassifiers()
351   {
352     return new String[] {
353         "Operation :: Analysis :: RNA secondary structure prediction",
354         "operation :: analysis :: rna secondary structure prediction",
355         "OPERATION :: ANALYSIS :: RNA SECONDARY STRUCTURE PREDICTION",
356         "Operation\t::\tAnalysis\t::\tRNA secondary structure prediction",
357         "Operation::Analysis::RNA secondary structure prediction",
358         "Operation :: Analysis :: Structure analysis :: RNA secondary structure prediction",
359         "Operation :: Analysis :: Structure analysis :: Nucleic acid structure analysis :: RNA secondary structure analysis :: RNA secondary structure prediction",
360         "Operation :: Analysis :: Structure analysis :: Nucleic acid structure analysis :: Nucleic acid structure prediction :: RNA secondary structure prediction",
361         "Operation :: Analysis :: Sequence analysis :: Nucleic acid sequence analysis :: Nucleic acid feature detection :: RNA secondary structure prediction",
362         "Operation :: Prediction and recognition :: RNA secondary structure prediction",
363         "Operation :: Prediction and recognition :: Nucleic acid feature detection :: RNA secondary structure prediction",
364         "Operation :: Prediction and recignition :: Nucleic acid structure prediction :: RNA secondary structure prediction", };
365   }
366
367   @DataProvider
368   public Iterator<Object> RNASecondaryStructurePredictionService()
369   {
370     var services = new ArrayList<>();
371     for (var classifier : validRNASecondaryStructurePredictionClassifiers())
372     {
373       services.add(new SlivkaService(URI.create("http://example.org/"),
374           "example", "name", "description", "author", "1.0", "MIT",
375           List.of(classifier), List.of(), List.of(), null));
376     }
377     return services.iterator();
378   }
379
380   @Test(
381     groups = { "Functional" },
382     dataProvider = "RNASecondaryStructurePredictionService")
383   public void testFetchServices_RNASecStrPredClassifier_serviceTypeIsRNASecStrPred(
384       SlivkaService service) throws IOException
385   {
386     when(clientMock.getServices()).thenReturn(List.of(service));
387     when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
388     var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
389     var webServices = discoverer
390         .fetchServices(new URL("http://example.org/"));
391     assertThat(webServices, hasSize(1));
392     assertThat(webServices.get(0).getCategory(),
393         equalTo("Secondary Structure Prediction"));
394     assertThat(webServices.get(0).getActionClass(),
395         typeCompatibleWith(AnnotationAction.class));
396   }
397
398   @DataProvider
399   public String[] validConservationAnalysisClassifiers()
400   {
401     return new String[] {
402         "Operation :: Analysis :: Sequence alignment analysis (conservation)",
403         "Operation::Analysis::Sequence alignment analysis (conservation)",
404         "Operation\t::\tAnalysis\t::\tSequence alignment analysis (conservation)",
405         "Operation :: Analysis :: Sequence analysis :: Sequence alignment analysis (conservation)",
406         "Operation :: Analysis :: Sequence analysis :: Sequence alignment analysis :: Sequence alignment analysis (conservation)", };
407   }
408
409   @DataProvider
410   public Iterator<Object> ConservationAnalysisService()
411   {
412     var services = new ArrayList<>();
413     for (var classifier : validConservationAnalysisClassifiers())
414     {
415       services.add(new SlivkaService(URI.create("http://example.org/"),
416           "example", "name", "description", "author", "1.0", "MIT",
417           List.of(classifier), List.of(), List.of(), null));
418     }
419     return services.iterator();
420   }
421
422   @Test(
423     groups = { "Functional" },
424     dataProvider = "validConservationAnalysisClassifiers")
425   public void testFetchServices_conservationAnalysisClassifier_serviceTypeIsConservation(
426       String classifier) throws IOException
427   {
428     var service = new SlivkaService(URI.create("http://example.org/"),
429         "example", "name", "description", "author", "1.0", "MIT",
430         List.of(classifier), List.of(), List.of(), null);
431     when(clientMock.getServices()).thenReturn(List.of(service));
432     when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
433     var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
434     var webServices = discoverer
435         .fetchServices(new URL("http://example.org/"));
436     assertThat(webServices, hasSize(1));
437     assertThat(webServices.get(0).getCategory(), equalTo("Conservation"));
438     assertThat(webServices.get(0).getActionClass(),
439         typeCompatibleWith(AnnotationAction.class));
440   }
441
442   @DataProvider
443   public Object[] validProteinSequenceAnalysisClassifiers()
444   {
445     return new Object[] {
446         "Operation :: Analysis :: Sequence analysis :: Protein sequence analysis", };
447   }
448
449   @Test(
450     groups = { "Functional" },
451     dataProvider = "validProteinSequenceAnalysisClassifiers")
452   public void testFetchServices_proteinSequenceAnalysisClassifier_serviceTypeIsProtSeqAnalysis(
453       String classifier) throws IOException
454   {
455     var service = new SlivkaService(URI.create("http://example.org/"),
456         "example", "name", "description", "author", "1.0", "MIT",
457         List.of(classifier), List.of(), List.of(), null);
458     when(clientMock.getServices()).thenReturn(List.of(service));
459     when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
460     var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
461     var webServices = discoverer
462         .fetchServices(new URL("http://example.org/"));
463     assertThat(webServices, hasSize(1));
464     assertThat(webServices.get(0).getCategory(),
465         equalTo("Protein Disorder"));
466     assertThat(webServices.get(0).getActionClass(),
467         typeCompatibleWith(AnnotationAction.class));
468   }
469
470   @DataProvider
471   public Object[] validProteinSecondaryStructurePredictionClassifiers()
472   {
473     return new Object[] {
474         "Operation ;: Analysis :: Protein secondary structure prediction",
475         "Operation :: Analysis :: Structure analysis :: Protein structure analysis :: Protein secondary structure analysis :: Protein secondary structure prediction",
476         "Operation :: Analysis :: Sequence analysis :: Protein sequence analysis :: Protein feature detection :: Protein secondary structure prediction",
477         "Operation :: Analysis :: Sequence analysis :: Protein sequence analysis :: Protein secondary structure prediction",
478         "Operation :: Prediction and recognition :: Protein secondary structure prediction",
479         "Operation :: Prediction and recognition :: Protein feature detection :: Protein secondary structure prediction", };
480   }
481
482   @Test(
483     enabled = false, // sec. str. pred. not implemented for slivka
484     groups = { "Functional" },
485     dataProvider = "validProteinSecondaryStructurePredictionClassifiers")
486   public void testFetchServices_proteinSecStrPredClassifier_serviceTypeIsProtSecStrPred(
487       String classifier) throws IOException
488   {
489     var service = new SlivkaService(URI.create("http://example.org/"),
490         "example", "name", "description", "author", "1.0", "MIT",
491         List.of(classifier), List.of(), List.of(), null);
492     when(clientMock.getServices()).thenReturn(List.of(service));
493     when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
494     var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
495     var webServices = discoverer
496         .fetchServices(new URL("http://example.org/"));
497     assertThat(webServices, hasSize(1));
498     assertThat(webServices.get(0).getCategory(),
499         equalTo("Protein Disorder"));
500     assertThat(webServices.get(0).getActionClass(),
501         typeCompatibleWith(AnnotationAction.class));
502   }
503
504   @DataProvider
505   public SlivkaService[] unrecognisedService()
506   {
507     return new SlivkaService[] {
508         new SlivkaService(URI.create("http://example.org/"), "example",
509             "Example name", "Example description", "John Smith",
510             "1.0.0", "Apache License, version 2.0",
511             List.of("This :: Classifier :: Does not exist"), List.of(),
512             List.of(), null) };
513   }
514
515   @Test(groups = { "Functional" }, dataProvider = "unrecognisedService")
516   public void testFetchServices_unrecognisedService_noServiceDiscovered(
517       SlivkaService service) throws IOException
518   {
519     when(clientMock.getServices()).thenReturn(List.of(service));
520     when(clientMock.getUrl()).thenReturn(URI.create("http://example.org"));
521     var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
522     var webServices = discoverer
523         .fetchServices(new URL("http://example.org"));
524     assertThat(webServices, hasSize(0));
525   }
526
527   @DataProvider
528   public Object[] serviceParameterAndMappedClass()
529   {
530     return new Object[][] {
531         {
532             new Parameter.IntegerParameter("param", "Parameter", "Description",
533                 true, false, null, Map.of(), null, null),
534             IntegerParameter.class
535         },
536         {
537             new Parameter.DecimalParameter("param", "Parameter",
538                 "Description", true, false, null, Map.of(), null, null,
539                 false, false),
540             DoubleParameter.class
541         },
542         {
543             new Parameter.TextParameter("param", "Parameter", "Description",
544                 true, false, null, Map.of(), 0, null),
545             StringParameter.class
546         },
547         {
548             new Parameter.FlagParameter("param", "Parameter", "Description",
549                 true, false, null, Map.of()),
550             BooleanOption.class
551         },
552         {
553             new Parameter.ChoiceParameter("param", "Parameter", "Description",
554                 true, false, null, Map.of(), List.of()),
555             StringParameter.class
556         },
557     };
558   }
559
560   @Test(
561     groups = { "Functional" },
562     dataProvider = "serviceParameterAndMappedClass")
563   public void testServiceParameter_slivkaParameterMappedToJalviewParameter(
564       Parameter slivkaParameter, Class<?> expectedClass)
565       throws IOException
566   {
567     var service = new SlivkaService(URI.create("http://example.org"),
568         "example", "name", "description", "author", "1.0",
569         "MIT License",
570         List.of("Operation :: Analysis :: Multiple sequence alignment"),
571         List.of(slivkaParameter), List.of(), null);
572     when(clientMock.getServices()).thenReturn(List.of(service));
573     when(clientMock.getUrl()).thenReturn(URI.create("http://example.org"));
574     var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
575     var webServices = discoverer
576         .fetchServices(new URL("http://example.org"));
577     var paramDatastore = webServices.get(0).getParamDatastore();
578     var arguments = paramDatastore.getServiceParameters();
579     assertThat(arguments.get(0), instanceOf(expectedClass));
580   }
581
582   @DataProvider
583   public Object[][] serviceParametersAndPropertyMatcher()
584   {
585     return new Object[][] {
586         {
587             new Parameter.IntegerParameter("param1", "Parameter 1",
588                 "Description of parameter 1", true, false, null, Map.of(),
589                 null, null),
590             allOf(
591                 hasProperty("name", equalTo("param1")),
592                 hasProperty("label", equalTo("Parameter 1")),
593                 hasProperty("description", equalTo("Description of parameter 1")),
594                 hasProperty("required", is(true)),
595                 hasProperty("value", nullValue()))
596         },
597         {
598             new Parameter.IntegerParameter("param2", null, null, true, false,
599                 null, Map.of(), null, null),
600             allOf(
601                 hasProperty("name", equalTo("param2")),
602                 hasProperty("label", equalTo("param2")),
603                 hasProperty("description", nullValue()),
604                 hasProperty("required", is(true)),
605                 hasProperty("value", nullValue()))
606         },
607         {
608             new Parameter.IntegerParameter("param3", "Parameter 3", "", false,
609                 false, 12, Map.of(), null, null),
610             allOf(
611                 hasProperty("name", equalTo("param3")),
612                 hasProperty("label", equalTo("Parameter 3")),
613                 hasProperty("description", equalTo("")),
614                 hasProperty("required", is(false)),
615                 hasProperty("value", equalTo("12")))
616         },
617     };
618   }
619
620   @Test(
621     groups = { "Functional" },
622     dataProvider = "serviceParametersAndPropertyMatcher")
623   public void testServiceParameters_testBasicParameterProperties(
624       Parameter parameter, Matcher<Object> matcher) throws IOException
625   {
626     var service = new SlivkaService(URI.create("http://example.org/"),
627         "example", "Example name", "Example description", "John Smith",
628         "1.0", "MIT",
629         List.of("Operation :: Analysis :: Multiple sequence alignment"),
630         List.of(parameter), List.of(), null);
631     when(clientMock.getServices()).thenReturn(List.of(service));
632     when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
633     var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
634     var webServices = discoverer
635         .fetchServices(new URL("http://example.org/"));
636     var paramDatastore = webServices.get(0).getParamDatastore();
637     var arguments = paramDatastore.getServiceParameters();
638     assertThat(arguments.get(0), matcher);
639   }
640
641   @DataProvider
642   public Object[][] integerParametersAndPropertyMatcher()
643   {
644     return new Object[][] {
645         {
646             new Parameter.IntegerParameter("param", null, null, true, false,
647                 null, Map.of(), null, null),
648             hasProperty("validValue", hasProperty("type", is(ValueType.Integer)))
649         },
650         {
651             new Parameter.IntegerParameter("param", null, null, true, false,
652                 null, Map.of(), null, null),
653             hasProperty("validValue", allOf(
654                 hasProperty("min", nullValue()),
655                 hasProperty("max", nullValue()))),
656         },
657         {
658             new Parameter.IntegerParameter("param", null, null, true, false,
659                 null, Map.of(), -12, 42),
660             hasProperty("validValue", allOf(
661                 hasProperty("min", is(-12)),
662                 hasProperty("max", is(42))))
663         },
664     };
665   }
666
667   @Test(
668     groups = { "Functional" },
669     dataProvider = "integerParametersAndPropertyMatcher")
670   public void testServiceParameters_testIntegerProperties(
671       Parameter parameter, Matcher<Object> matcher) throws IOException
672   {
673     var service = new SlivkaService(URI.create("http://example.org"),
674         "example", "Example name", "Example description", "John Smith",
675         "1.0", "MIT",
676         List.of("Operation :: Analysis :: Multiple Sequence Alignment"),
677         List.of(parameter), List.of(), null);
678     when(clientMock.getServices()).thenReturn(List.of(service));
679     when(clientMock.getUrl()).thenReturn(URI.create("http://example.org/"));
680     var discoverer = new SlivkaWSDiscoverer(url -> clientMock);
681     var webServices = discoverer
682         .fetchServices(new URL("http://example.org/"));
683     var paramDatastore = webServices.get(0).getParamDatastore();
684     var arguments = paramDatastore.getServiceParameters();
685     assertThat(arguments.get(0), matcher);
686   }
687 }