diff --git a/.gitignore b/.gitignore index 3aeb7b4cfdd3c03331af284813bfa9ac1dd5ad91..e4510e26f8a8144c334a2482ce947d5619da9ec5 100755 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ classes/ *.iml /.idea/ .vscode/settings.json +selenium/.pytest_cache +selenium/.venv +selenium/tests/__pycache__ diff --git a/Dockerfile b/Dockerfile index 48c2c4e70cca1c5b90523c6f5d84e02cf379e621..9c7a35ff737b36c51ac70f1be1835a267f76d7f4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ # the first stage of our build will use a maven 3.6 parent image -FROM maven:3.6-openjdk-11 AS MAVEN_BUILD +FROM maven:3.8-openjdk-11 AS MAVEN_BUILD # We need VIPSCommon too, so the source code must be available in the parent folder COPY ./VIPSCommon ./VIPSCommon diff --git a/pom.xml b/pom.xml index 481a18f4c0a0909aac1f29afc41afb1d4138f062..c7d009dc54fe4258a51dbea6f6ceba2844483759 100755 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,6 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> - <geotools.version>20.2</geotools.version> </properties> <name>VIPSLogic</name> <url>http://maven.apache.org</url> @@ -60,30 +59,15 @@ <version>2.3.1</version> <scope>compile</scope> </dependency> - <dependency> - <groupId>edu.ucar</groupId> - <artifactId>cdm</artifactId> - <version>4.6.10</version> - </dependency> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> - <version>8.3.0</version> + <version>10.4.1</version> </dependency> <dependency> - <groupId>org.hibernate</groupId> - <artifactId>hibernate-spatial</artifactId> - <version>5.6.3.Final</version> - <exclusions> - <exclusion> - <artifactId>postgresql</artifactId> - <groupId>postgresql</groupId> - </exclusion> - <exclusion> - <groupId>org.dom4j</groupId> - <artifactId>dom4j</artifactId> - </exclusion> - </exclusions> + <groupId>org.flywaydb</groupId> + <artifactId>flyway-database-postgresql</artifactId> + <version>10.4.1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> @@ -94,19 +78,19 @@ <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-client</artifactId> - <version>4.7.2.Final</version> + <version>4.7.9.Final</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-core</artifactId> - <version>4.7.2.Final</version> + <version>4.7.9.Final</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jackson2-provider</artifactId> - <version>4.7.2.Final</version> + <version>4.7.9.Final</version> <scope>provided</scope> </dependency> <dependency> @@ -118,14 +102,14 @@ <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> - <version>4.5.13</version> + <version>4.5.14</version> <type>jar</type> <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> - <version>4.10</version> + <version>4.13.2</version> <scope>test</scope> </dependency> <dependency> @@ -139,39 +123,32 @@ <artifactId>JavaAPIforKml</artifactId> <version>2.2.1</version> </dependency> - <!-- https://mvnrepository.com/artifact/net.postgis/postgis-jdbc --> - <dependency> - <groupId>net.postgis</groupId> - <artifactId>postgis-jdbc</artifactId> - <version>2.5.1</version> - </dependency> - <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> - <version>2.13.1</version> + <version>2.16.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> - <version>2.13.1</version> + <version>2.16.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> - <version>2.13.1</version> + <version>2.16.1</version> </dependency> <dependency> <groupId>org.passay</groupId> <artifactId>passay</artifactId> - <version>1.6.1</version> + <version>1.6.4</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> - <version>5.6.3.Final</version> + <version>5.6.15.Final</version> <exclusions> <exclusion> <groupId>org.dom4j</groupId> @@ -179,39 +156,49 @@ </exclusion> </exclusions> </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-spatial</artifactId> + <version>5.6.15.Final</version> + <exclusions> + <exclusion> + <artifactId>postgresql</artifactId> + <groupId>postgresql</groupId> + </exclusion> + <exclusion> + <groupId>org.dom4j</groupId> + <artifactId>dom4j</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> - <version>42.3.1</version> + <version>42.7.1</version> <scope>provided</scope> </dependency> - <dependency> - <groupId>com.fasterxml.jackson.dataformat</groupId> - <artifactId>jackson-dataformat-csv</artifactId> - <version>2.13.1</version> - <type>jar</type> - </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> - <version>2.13.1</version> + <version>2.16.1</version> <type>jar</type> </dependency> <dependency> <groupId>org.locationtech.jts</groupId> <artifactId>jts-core</artifactId> - <version>1.18.2</version> + <version>1.19.0</version> <type>jar</type> </dependency> <dependency> <groupId>org.wololo</groupId> <artifactId>jts2geojson</artifactId> - <version>0.16.1</version> + <version>0.18.1</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-csv</artifactId> - <version>1.2</version> + <version>1.10.0</version> <type>jar</type> </dependency> <dependency> @@ -236,75 +223,32 @@ <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> - <version>2.3.31</version> + <version>2.3.32</version> </dependency> <dependency> <groupId>it.sauronsoftware.cron4j</groupId> <artifactId>cron4j</artifactId> <version>2.2.5</version> </dependency> - <!--dependency> - <groupId>org.openid4java</groupId> - <artifactId>openid4java</artifactId> - <version>0.9.8</version> - </dependency--> - <dependency> - <groupId>com.google.api-client</groupId> - <artifactId>google-api-client</artifactId> - <version>1.19.1</version> - </dependency> - <!--dependency> - <groupId>edu.vt.middleware</groupId> - <artifactId>vt-password</artifactId> - <version>3.1.2</version> - </dependency--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> - <version>1.4</version> + <version>1.5</version> </dependency> <dependency> <groupId>com.ibm.icu</groupId> <artifactId>icu4j</artifactId> - <version>70.1</version> - </dependency> - - <!--dependency> - <groupId>org.postgresql</groupId> - <artifactId>postgresql</artifactId> - <version>9.4-1211</version> - <scope>provided</scope> - </dependency--> - <dependency> - <groupId>org.openjdk.jol</groupId> - <artifactId>jol-core</artifactId> - <version>0.16</version> - </dependency> - <dependency> - <groupId>org.geotools</groupId> - <artifactId>gt-api</artifactId> - <version>20.5</version> - </dependency> - <dependency> - <groupId>org.geotools</groupId> - <artifactId>gt-epsg-hsql</artifactId> - <version>20.5</version> + <version>74.2</version> </dependency> <dependency> <groupId>javax.measure</groupId> <artifactId>unit-api</artifactId> - <version>1.0</version> + <version>2.2</version> </dependency> <dependency> <groupId>com.webcohesion.enunciate</groupId> <artifactId>enunciate-core-annotations</artifactId> - <version>2.13.3</version> - </dependency> - - <dependency> - <groupId>com.webcohesion.enunciate</groupId> - <artifactId>enunciate-rt-util</artifactId> - <version>2.13.3</version> + <version>2.17.1</version> </dependency> <dependency> <groupId>com.bedatadriven</groupId> @@ -314,26 +258,30 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.36</version> + <version>2.0.10</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <version>3.6.1</version> + </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> - <version>3.8.1</version> + <version>3.12.1</version> <configuration> - <source>11</source> - <target>11</target> + <source>17</source> + <target>17</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> - <version>3.3.2</version> + <version>3.4.0</version> <configuration> <webResources> <resource> @@ -358,7 +306,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> - <version>2.22.2</version> + <version>3.2.3</version> <configuration> <argLine>-Xmx6048m</argLine> </configuration> @@ -366,7 +314,7 @@ <plugin> <groupId>com.webcohesion.enunciate</groupId> <artifactId>enunciate-maven-plugin</artifactId> - <version>2.13.3</version> + <version>2.17.1</version> <executions> <execution> <goals> diff --git a/postman_tests/VIPSLogic tests.postman_collection.json b/postman_tests/VIPSLogic tests.postman_collection.json index 50c25b51b3357d68033d5796327584748f35deeb..5cba588d2439ebebabbef738ee719b711ee7da38 100644 --- a/postman_tests/VIPSLogic tests.postman_collection.json +++ b/postman_tests/VIPSLogic tests.postman_collection.json @@ -56,6 +56,54 @@ }, "response": [] }, + { + "name": "Get all observations of Delia radicum for NIBIO", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{vipslogic_url}}/rest/observation/list/filter/1?pestId=129&from=2010-01-01&to=2024-01-01", + "host": [ + "{{vipslogic_url}}" + ], + "path": [ + "rest", + "observation", + "list", + "filter", + "1" + ], + "query": [ + { + "key": "pestId", + "value": "129" + }, + { + "key": "from", + "value": "2010-01-01" + }, + { + "key": "to", + "value": "2024-01-01" + } + ] + } + }, + "response": [] + }, { "name": "Get all observations from an organization as GeoJson", "event": [ @@ -232,6 +280,44 @@ }, "response": [] }, + { + "name": "Get model information", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "eeb6ee57-3540-40a4-9a07-0d9366d6b1e9" + } + ], + "url": { + "raw": "{{vipslogic_url}}/rest/model/PSILARTEMP", + "host": [ + "{{vipslogic_url}}" + ], + "path": [ + "rest", + "model", + "PSILARTEMP" + ] + } + }, + "response": [] + }, { "name": "List weather stations for one organization as KML", "event": [ @@ -386,6 +472,170 @@ }, "response": [] }, + { + "name": "List pests for crop", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "eeb6ee57-3540-40a4-9a07-0d9366d6b1e9" + } + ], + "url": { + "raw": "{{vipslogic_url}}/rest/organism/croppest/15", + "host": [ + "{{vipslogic_url}}" + ], + "path": [ + "rest", + "organism", + "croppest", + "15" + ] + } + }, + "response": [] + }, + { + "name": "List crop categories for an organization", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "eeb6ee57-3540-40a4-9a07-0d9366d6b1e9" + } + ], + "url": { + "raw": "{{vipslogic_url}}/rest/organism/cropcategory/1", + "host": [ + "{{vipslogic_url}}" + ], + "path": [ + "rest", + "organism", + "cropcategory", + "1" + ] + } + }, + "response": [] + }, + { + "name": "List organizations", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "eeb6ee57-3540-40a4-9a07-0d9366d6b1e9" + } + ], + "url": { + "raw": "{{vipslogic_url}}/rest/organization", + "host": [ + "{{vipslogic_url}}" + ], + "path": [ + "rest", + "organization" + ] + } + }, + "response": [] + }, + { + "name": "List all messages for an organization", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "eeb6ee57-3540-40a4-9a07-0d9366d6b1e9" + } + ], + "url": { + "raw": "{{vipslogic_url}}/rest/message/list/1?publishedFrom=2022-01-01&publishedTo=2022-12-31", + "host": [ + "{{vipslogic_url}}" + ], + "path": [ + "rest", + "message", + "list", + "1" + ], + "query": [ + { + "key": "publishedFrom", + "value": "2022-01-01" + }, + { + "key": "publishedTo", + "value": "2022-12-31" + } + ] + } + }, + "response": [] + }, { "name": "Get all results for one forecast", "event": [ @@ -578,6 +828,137 @@ }, "response": [] }, + { + "name": "Get forecast results aggregate as KML", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200 or 204\", function () {", + " console.info(pm.response.code)", + " pm.expect(pm.response.code == 200 || pm.response.code == 204).to.eql(true)", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "eeb6ee57-3540-40a4-9a07-0d9366d6b1e9" + } + ], + "url": { + "raw": "{{vipslogic_url}}/rest/forecastresults/aggregate/1", + "host": [ + "{{vipslogic_url}}" + ], + "path": [ + "rest", + "forecastresults", + "aggregate", + "1" + ] + } + }, + "response": [] + }, + { + "name": "Get the forecast results from a POI", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200 or 204\", function () {", + " console.info(pm.response.code)", + " pm.expect(pm.response.code == 200 || pm.response.code == 204).to.eql(true)", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "eeb6ee57-3540-40a4-9a07-0d9366d6b1e9" + } + ], + "url": { + "raw": "{{vipslogic_url}}/rest/forecastresults/latest/poi/10", + "host": [ + "{{vipslogic_url}}" + ], + "path": [ + "rest", + "forecastresults", + "latest", + "poi", + "10" + ] + } + }, + "response": [] + }, + { + "name": "Get forecast configurations for one org", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "eeb6ee57-3540-40a4-9a07-0d9366d6b1e9" + } + ], + "url": { + "raw": "{{vipslogic_url}}/rest/forecastconfigurationsincludeorgs/1?from=2021-01-01&to=2021-12-31", + "host": [ + "{{vipslogic_url}}" + ], + "path": [ + "rest", + "forecastconfigurationsincludeorgs", + "1" + ], + "query": [ + { + "key": "from", + "value": "2021-01-01" + }, + { + "key": "to", + "value": "2021-12-31" + } + ] + } + }, + "response": [] + }, { "name": "Get forecast configurations for given model and season", "event": [ @@ -656,6 +1037,45 @@ }, "response": [] }, + { + "name": "Get KML list of POIs for a given organization", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "eeb6ee57-3540-40a4-9a07-0d9366d6b1e9" + } + ], + "url": { + "raw": "{{vipslogic_url}}/rest/pois/kml/1", + "host": [ + "{{vipslogic_url}}" + ], + "path": [ + "rest", + "pois", + "kml", + "1" + ] + } + }, + "response": [] + }, { "name": "Evaluate password (requirements configured with Passay)", "event": [ @@ -736,6 +1156,39 @@ } }, "response": [] + }, + { + "name": "Get POI(s) by name", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{vipslogic_url}}/rest/poi/name/Sandefjord", + "host": [ + "{{vipslogic_url}}" + ], + "path": [ + "rest", + "poi", + "name", + "Sandefjord" + ] + } + }, + "response": [] } ] }, @@ -935,6 +1388,115 @@ "response": [] } ] + }, + { + "name": "ModelFormService", + "item": [ + { + "name": "Run SeptoriaHumidityModel", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{vipslogic_url}}/rest/modelform/SEPTORIAHU/runmodel/?organizationId_countryCode=1_NO&weatherStationId=91&dateSpraying1=&dateSpraying2=&dateGs31=2023-05-01&date3rdUpperLeafEmerging=2023-05-11&date2ndUpperLeafEmerging=2023-05-21&dateUpperLeafEmerging=2023-05-31&dateGs75=2023-06-30&thresholdRelativeHumidity=85&thresholdLeafWetness=30&thresholdPrecipitation=0.2&slidingHoursPast=36&slidingHoursAhead=36&thresholdHumidPeriodHours=20&sprayingProtectionDays=10&leafLifeTime=75", + "host": [ + "{{vipslogic_url}}" + ], + "path": [ + "rest", + "modelform", + "SEPTORIAHU", + "runmodel", + "" + ], + "query": [ + { + "key": "organizationId_countryCode", + "value": "1_NO" + }, + { + "key": "weatherStationId", + "value": "91" + }, + { + "key": "dateSpraying1", + "value": "" + }, + { + "key": "dateSpraying2", + "value": "" + }, + { + "key": "dateGs31", + "value": "2023-05-01" + }, + { + "key": "date3rdUpperLeafEmerging", + "value": "2023-05-11" + }, + { + "key": "date2ndUpperLeafEmerging", + "value": "2023-05-21" + }, + { + "key": "dateUpperLeafEmerging", + "value": "2023-05-31" + }, + { + "key": "dateGs75", + "value": "2023-06-30" + }, + { + "key": "thresholdRelativeHumidity", + "value": "85" + }, + { + "key": "thresholdLeafWetness", + "value": "30" + }, + { + "key": "thresholdPrecipitation", + "value": "0.2" + }, + { + "key": "slidingHoursPast", + "value": "36" + }, + { + "key": "slidingHoursAhead", + "value": "36" + }, + { + "key": "thresholdHumidPeriodHours", + "value": "20" + }, + { + "key": "sprayingProtectionDays", + "value": "10" + }, + { + "key": "leafLifeTime", + "value": "75" + } + ] + } + }, + "response": [] + } + ] } ] } \ No newline at end of file diff --git a/selenium/Makefile b/selenium/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..265c51021c31907065b1ee0ba9aaae60774c454d --- /dev/null +++ b/selenium/Makefile @@ -0,0 +1,12 @@ +venv: venv/touchfile + +venv/touchfile: requirements.txt + python3 -m venv .venv + . .venv/bin/activate; python3 -m pip install --upgrade -q pip; pip install -Ur requirements.txt + touch .venv/touchfile + +test: venv + @echo 'Run selenium tests' + . .venv/bin/activate \ + && pytest + diff --git a/selenium/README.md b/selenium/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e3a646c5a199283eefa529315b82f58733ae580e --- /dev/null +++ b/selenium/README.md @@ -0,0 +1,7 @@ +# Selenium tests + +Ensure application is running locally. Tests expect login form to be available on http://vipslogic/index.html. Run tests like this: + +``` +$ make test +``` diff --git a/selenium/requirements.txt b/selenium/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..4b18905fbc889d7ed4c301541ec06b763ed0911d --- /dev/null +++ b/selenium/requirements.txt @@ -0,0 +1,5 @@ +selenium==4.16.0 +pytest +trio +pytest-trio +flake8 \ No newline at end of file diff --git a/selenium/tests/test_selenium.py b/selenium/tests/test_selenium.py new file mode 100644 index 0000000000000000000000000000000000000000..45d44fdffd11f0106ad1a5edec3744ae763560da --- /dev/null +++ b/selenium/tests/test_selenium.py @@ -0,0 +1,111 @@ +from selenium import webdriver +import pytest +from selenium.webdriver.common.by import By +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC + +# https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk/examples/python/README.md + +# BROWSER = 'chrome' +BROWSER = "firefox" + + +@pytest.fixture +def browser(): + if BROWSER == "chrome": + chrome_options = webdriver.ChromeOptions() + chrome_options.add_argument("--headless") + driver = webdriver.Chrome(options=chrome_options) + elif BROWSER == "firefox": + firefox_options = webdriver.FirefoxOptions() + firefox_options.headless = False + driver = webdriver.Firefox(options=firefox_options) + else: + raise Exception("Browser must be set to either chrome or firefox") + + driver.get("http://vipslogic/index.html") + + assert driver.title == "Please log in" + driver.implicitly_wait(0.5) + driver.find_element(by=By.NAME, value="username").send_keys("seleniumtest") + driver.find_element(by=By.NAME, value="password").send_keys("seleniumTEST") + driver.find_element(by=By.CSS_SELECTOR, value="button").click() + assert driver.title == "Welcome to VIPSLogic" + yield driver + driver.quit() + + +def test_name_of_logged_in_user(browser): + link = browser.find_element(By.XPATH, '//a[text()="Selenium Testbruker"]') + assert link is not None + + +def test_admin_organisms(browser): + browser.find_element(By.XPATH, '//a[text()="Admin"]').click() + link = WebDriverWait(browser, 15).until( + EC.element_to_be_clickable((By.XPATH, '//a[text()="Organisms"]')) + ) + assert link.get_attribute("href") == "http://vipslogic/organism" + link.click() + assert browser.title == "Organisms" + link = WebDriverWait(browser, 15).until( + EC.element_to_be_clickable((By.XPATH, '//a[text()="List all pests"]')) + ) + link.click() + assert browser.title == "All pests" + + +def test_admin_scheduling(browser): + browser.find_element(By.XPATH, '//a[text()="Admin"]').click() + link = WebDriverWait(browser, 10).until( + EC.element_to_be_clickable((By.XPATH, '//a[text()="Scheduling"]')) + ) + assert link.get_attribute("href") == "http://vipslogic/scheduling" + link.click() + assert browser.title == "Scheduling overview" + + +def test_admin_organization_group(browser): + browser.find_element(By.XPATH, '//a[text()="Admin"]').click() + link = WebDriverWait(browser, 10).until( + EC.element_to_be_clickable((By.XPATH, '//a[text()="Organization groups"]')) + ) + assert link.get_attribute("href") == "http://vipslogic/organizationgroup" + link.click() + assert browser.title == "Organization groups" + + +def test_admin_apple_fruit_moth(browser): + browser.find_element(By.XPATH, '//a[text()="Admin"]').click() + link = WebDriverWait(browser, 10).until( + EC.element_to_be_clickable((By.XPATH, '//a[text()="Apple fruit moth"]')) + ) + assert link.get_attribute("href") == "http://vipslogic/applefruitmoth" + link.click() + assert browser.title == "Rognebærmøllstasjoner" + + +def test_admin_users(browser): + browser.find_element(By.XPATH, '//a[text()="Admin"]').click() + link = WebDriverWait(browser, 20).until( + EC.element_to_be_clickable((By.XPATH, '//a[text()="Users"]')) + ) + assert link.get_attribute("href") == "http://vipslogic/user" + link.click() + WebDriverWait(browser, 20).until( + EC.visibility_of_element_located((By.XPATH, "//h1[text()='Users']")) + ) + assert browser.title == "Users" + + +def test_admin_forecasts(browser): + browser.find_element(By.XPATH, '//a[text()="Admin"]').click() + link = WebDriverWait(browser, 20).until( + EC.element_to_be_clickable((By.XPATH, '//a[text()="Forecasts"]')) + ) + assert link.get_attribute("href") == "http://vipslogic/forecastConfiguration" + link.click() + WebDriverWait(browser, 20).until( + EC.visibility_of_element_located((By.XPATH, "//h1[text()='Forecasts']")) + ) + assert browser.title == "Forecasts" diff --git a/src/main/java/no/nibio/vips/logic/controller/servlet/LoginController.java b/src/main/java/no/nibio/vips/logic/controller/servlet/LoginController.java index f1a606829d626c648e961c3e5bd5836148ff89dc..ba830e6cc3ad88ba3f49b845648b4cdbf4a91898 100755 --- a/src/main/java/no/nibio/vips/logic/controller/servlet/LoginController.java +++ b/src/main/java/no/nibio/vips/logic/controller/servlet/LoginController.java @@ -19,13 +19,6 @@ package no.nibio.vips.logic.controller.servlet; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl; -import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest; -import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; -import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload; -import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse; -import com.google.api.client.http.javanet.NetHttpTransport; -import com.google.api.client.json.jackson2.JacksonFactory; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; @@ -88,70 +81,9 @@ public class LoginController extends HttpServlet { // We remove the session attribute, so it doesn't stick request.getSession().removeAttribute(LoginController.RETURN_UUID_PARAMETER_NAME); - // This means that an OpenId authentication has returned the user to this URL - // See code below - if(request.getServletPath().contains("oauth2callback")) - { - // Is it an authorization response? - if(request.getParameter("code") != null) - { - String authorizationCode = request.getParameter("code"); - // Verify state - String storedState = (String) request.getSession().getAttribute("state"); - String receivedState = request.getParameter("state"); - if(receivedState == null || storedState == null || ! storedState.equals(receivedState)) - { - request.setAttribute("errorMessageKey", "invalidcredentials"); - request.getRequestDispatcher("/login.ftl").forward(request, response); - return; - } - - // Use code, make request to Google for getting token with user information - GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest( - new NetHttpTransport(), - new JacksonFactory(), - System.getProperty("no.nibio.vips.logic.GOOGLE_OPENID_CLIENT_ID"), - System.getProperty("no.nibio.vips.logic.GOOGLE_OPENID_CLIENT_SECRET"), - authorizationCode, - Globals.PROTOCOL + "://" + ServletUtil.getServerName(request) + "/oauth2callback" - ).execute(); - GoogleIdToken idToken = GoogleIdToken.parse(new JacksonFactory(), tokenResponse.getIdToken()); - Payload payload = idToken.getPayload(); - - // Try to find the user - VipsLogicUser user = userBean.getUser(payload.getSubject(), UserAuthenticationType.TYPE_OPENID_GOOGLE); - if(user != null) - { - request.getSession().setAttribute("user", user); - UUID uUUID = this.handleRememberUser(request, response, user, returnUUID); - if(returnUUID) - { - nextPage += (nextPage.contains("?") ? "&": "?") + "returnUUID=" + uUUID.toString(); - } - if(nextPage.indexOf(Globals.PROTOCOL) == 0) - { - System.out.println("nextPage=" + nextPage); - response.sendRedirect(nextPage); - } - else - { - response.sendRedirect(new StringBuilder(Globals.PROTOCOL + "://").append(ServletUtil.getServerName(request)).append(nextPage).toString()); - } - } - else - { - // This might be - // * a new user - // * an existing user logging in with OpenId/Google for the first time. - // Sending user to form asking this question - request.setAttribute("userAuthenticationTypeId", UserAuthenticationType.TYPE_OPENID_GOOGLE); - request.getSession().setAttribute("openId", payload.getSubject()); - request.getRequestDispatcher("/registerOpenIdForm.ftl").forward(request, response); - } - } - } + // A log out request - else if(request.getServletPath().contains("logout")) + if(request.getServletPath().contains("logout")) { request.getSession().removeAttribute("user"); Cookie rememberedUser = ServletUtil.getCookie(request, "rememberedUser"); @@ -230,39 +162,6 @@ public class LoginController extends HttpServlet { } } - /* Login with Google OpenConnect/OAuth2 - For documentation about how this is done, see: - https://developers.google.com/accounts/docs/OAuth2WebServer - and https://developers.google.com/accounts/docs/OpenIDConnect - ClientID, ClientSecret, callbacks etc. has been created by logging - in to https://console.developers.google.com as tor-einar.skog@nibio.no - */ - else if(userAuthenticationTypeId.equals(UserAuthenticationType.TYPE_OPENID_GOOGLE)) - { - // configure the return_to URL where your application will receive - // the authentication responses from the OpenID Connect provider - String serverName = ServletUtil.getServerName(request); - String callbackUrl = Globals.PROTOCOL + "://" + serverName + "/oauth2callback" ; - // We store the information about the next page in a session - // as Google does not accept to forward it - request.getSession().setAttribute("nextPage", URLEncoder.encode(nextPage, "UTF-8")); - request.getSession().setAttribute(LoginController.RETURN_UUID_PARAMETER_NAME, returnUUID); - request.getSession().setAttribute("rememberUser", request.getParameter("rememberUser")); - // Token to check for security (avoid man-in-the-middle) - String state = new BigInteger(130, new SecureRandom()).toString(32); - request.getSession().setAttribute("state", state); - String url = - new GoogleAuthorizationCodeRequestUrl( - System.getProperty("no.nibio.vips.logic.GOOGLE_OPENID_CLIENT_ID"), - callbackUrl, - Arrays.asList( - "https://www.googleapis.com/auth/userinfo.email") - ) - .setState(state).build(); - - // Redirect to Google for authentication - response.sendRedirect(url); - } // Authentication method not recognized, redirect to standard form else { diff --git a/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleBean.java b/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleBean.java index 94616429a87b91531c992a68b174273bb7d03e12..06e7363b938c4d32745695a4e713c60ad3e33ce7 100644 --- a/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleBean.java +++ b/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleBean.java @@ -55,7 +55,6 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.TransformException; -import no.nibio.vips.logic.controller.session.SchedulingBean; import no.nibio.vips.logic.controller.session.SessionControllerGetter; import no.nibio.vips.logic.controller.session.UserBean; import no.nibio.vips.logic.entity.Organization; diff --git a/src/main/java/no/nibio/vips/logic/service/LogicService.java b/src/main/java/no/nibio/vips/logic/service/LogicService.java index f6802571fb0edd4b9471c3b55e211935922e8be1..e4d7b5d0f7fe06aed8b1b0e81de170acda3a840d 100755 --- a/src/main/java/no/nibio/vips/logic/service/LogicService.java +++ b/src/main/java/no/nibio/vips/logic/service/LogicService.java @@ -1259,8 +1259,8 @@ public class LogicService { /** * - * @param cropOrganismId - * @return + * @param cropOrganismId ID of the crop + * @return list of pests associated with the given crop */ @GET @Path("organism/croppest/{cropOrganismId}") @@ -1283,7 +1283,7 @@ public class LogicService { /** * * @param organizationId - * @return + * @return List of crop categories for a given organization */ @GET @Path("organism/cropcategory/{organizationId}") diff --git a/src/main/java/no/nibio/vips/logic/service/ModelFormService.java b/src/main/java/no/nibio/vips/logic/service/ModelFormService.java index c4726bdb2604e0a585d443614029e6fe17c60307..c1c739baa829e0672830c473feb08357555712f5 100644 --- a/src/main/java/no/nibio/vips/logic/service/ModelFormService.java +++ b/src/main/java/no/nibio/vips/logic/service/ModelFormService.java @@ -195,7 +195,6 @@ public class ModelFormService { ModelConfiguration mConf = new SeptoriaHumidityModelPreprocessor().getModelConfiguration(fConf); Integer VIPSCoreUserId = organization.getDefaultVipsCoreUserId(); - System.out.println("defaultVIPScoreUserId = " + VIPSCoreUserId); List<Result>results = forecastBean.runForecast(mConf, VIPSCoreUserId); diff --git a/src/main/webapp/templates/login.ftl b/src/main/webapp/templates/login.ftl index f25f1444044893dc65d987002b902411ee0b8347..e0a5e522c0483945bd4bed81dbde6167f169fdd4 100755 --- a/src/main/webapp/templates/login.ftl +++ b/src/main/webapp/templates/login.ftl @@ -49,14 +49,6 @@ <a href="/user?action=registerNewUserForm&userAuthenticationTypeId=1">${i18nBundle.registerNewUser}</a><br/> <a href="/user?action=resetPasswordRequestForm">${i18nBundle.forgottenPassword}</a> </form> - <form class="form-signin" action="/loginsubmit" method="POST"> - <input type="hidden" name="userAuthenticationTypeId" value="3"/> - <input type="hidden" name="nextPage" value="${nextPage!"/"}"/> - <input type="hidden" name="returnUUID" value="<#if returnUUID?has_content>${returnUUID?c!""}</#if>"/> - <h2 class="form-signin-heading">${i18nBundle.or}</h2> - <input type="image" src="/images/btn_sign_in_with_google.png" alt="${i18nBundle.signInWith} Google"/><br/> - <input type="checkbox" name="rememberUser"<#if checkRemember?has_content && checkRemember> checked="checked"</#if>/> ${i18nBundle.rememberLogin} - </form> </div> </#macro> <@page_html/>