From 6dc58fd625279f8ffe1060170418686034db0af4 Mon Sep 17 00:00:00 2001 From: vasraz Date: Wed, 2 Oct 2019 12:08:49 +0100 Subject: Fix name convention issue Rename modules: workflow-designer-init to sdc-workflow-designer-init workflow-designer-be to sdc-workflow-designer-be workflow-designer-ui to sdc-workflow-designer-ui Rename docker images: onap/workflow-init to onap/sdc-workflow-init onap/workflow-backend to onap/sdc-workflow-backend onap/workflow-frontend to onap/sdc-workflow-frontend List of changed files: modified: README.md modified: docker-compose/debug.yml modified: docker-compose/docker-compose.yml modified: pom.xml modified: sdc-workflow-bdd/pom.xml modified: sdc-workflow-designer-be/pom.xml modified: sdc-workflow-designer-init/pom.xml modified: sdc-workflow-designer-ui/pom.xml modified: sdc-workflow-designer-ui/src/main/frontend/yarn.lock modified: version.properties All others changes are relaited to rename/move. Change-Id: Ic989b6347b815f85e77e23fc8d7884c05b650a27 Issue-ID: SDC-2334 Issue-ID: SDC-2335 Signed-off-by: Vasyl Razinkov --- sdc-workflow-bdd/.gitignore | 11 + sdc-workflow-bdd/README.txt | 4 + sdc-workflow-bdd/config.json | 28 ++ sdc-workflow-bdd/cucumber.js | 3 + sdc-workflow-bdd/features/ActivitySpec.feature | 61 ++++ .../features/ActivitySpecStatus.feature | 21 ++ sdc-workflow-bdd/features/ArchiveWorkflow.feature | 68 ++++ sdc-workflow-bdd/features/Version.feature | 101 ++++++ sdc-workflow-bdd/features/VersionState.feature | 55 ++++ sdc-workflow-bdd/features/Workflow.feature | 31 ++ sdc-workflow-bdd/features/WorkflowList.feature | 97 ++++++ .../features/examples/ResponseDataChecks.feature | 50 +++ sdc-workflow-bdd/package.json | 31 ++ sdc-workflow-bdd/plugins/README.md | 23 ++ sdc-workflow-bdd/plugins/jsdoc_config.json | 15 + sdc-workflow-bdd/plugins/reporter.js | 31 ++ sdc-workflow-bdd/plugins/steps.js | 65 ++++ sdc-workflow-bdd/pom.xml | 167 ++++++++++ .../resources/json/createActivitySpec.json | 23 ++ .../resources/json/createWorkflow.json | 4 + .../json/versionWith2Inputs2Outputs1.json | 27 ++ .../json/versionWith2Inputs2Outputs2.json | 27 ++ .../json/versionWithDuplicateInputName.json | 27 ++ .../json/versionWithDuplicateOutputName.json | 27 ++ .../stepDefinitions/ActivitySpec_steps.js | 47 +++ .../stepDefinitions/Collaboration_Steps.js | 113 +++++++ sdc-workflow-bdd/stepDefinitions/General_Steps.js | 354 +++++++++++++++++++++ .../stepDefinitions/InputData_steps.js | 99 ++++++ .../stepDefinitions/InterfaceOperationSteps.js | 118 +++++++ sdc-workflow-bdd/stepDefinitions/Item_steps.js | 91 ++++++ sdc-workflow-bdd/stepDefinitions/REST_Steps.js | 80 +++++ sdc-workflow-bdd/stepDefinitions/Utils.js | 153 +++++++++ sdc-workflow-bdd/stepDefinitions/Workflow_Steps.js | 35 ++ sdc-workflow-bdd/stepDefinitions/world.js | 87 +++++ 34 files changed, 2174 insertions(+) create mode 100644 sdc-workflow-bdd/.gitignore create mode 100644 sdc-workflow-bdd/README.txt create mode 100644 sdc-workflow-bdd/config.json create mode 100644 sdc-workflow-bdd/cucumber.js create mode 100644 sdc-workflow-bdd/features/ActivitySpec.feature create mode 100644 sdc-workflow-bdd/features/ActivitySpecStatus.feature create mode 100644 sdc-workflow-bdd/features/ArchiveWorkflow.feature create mode 100644 sdc-workflow-bdd/features/Version.feature create mode 100644 sdc-workflow-bdd/features/VersionState.feature create mode 100644 sdc-workflow-bdd/features/Workflow.feature create mode 100644 sdc-workflow-bdd/features/WorkflowList.feature create mode 100644 sdc-workflow-bdd/features/examples/ResponseDataChecks.feature create mode 100644 sdc-workflow-bdd/package.json create mode 100644 sdc-workflow-bdd/plugins/README.md create mode 100644 sdc-workflow-bdd/plugins/jsdoc_config.json create mode 100644 sdc-workflow-bdd/plugins/reporter.js create mode 100644 sdc-workflow-bdd/plugins/steps.js create mode 100644 sdc-workflow-bdd/pom.xml create mode 100644 sdc-workflow-bdd/resources/json/createActivitySpec.json create mode 100644 sdc-workflow-bdd/resources/json/createWorkflow.json create mode 100644 sdc-workflow-bdd/resources/json/versionWith2Inputs2Outputs1.json create mode 100644 sdc-workflow-bdd/resources/json/versionWith2Inputs2Outputs2.json create mode 100644 sdc-workflow-bdd/resources/json/versionWithDuplicateInputName.json create mode 100644 sdc-workflow-bdd/resources/json/versionWithDuplicateOutputName.json create mode 100644 sdc-workflow-bdd/stepDefinitions/ActivitySpec_steps.js create mode 100644 sdc-workflow-bdd/stepDefinitions/Collaboration_Steps.js create mode 100644 sdc-workflow-bdd/stepDefinitions/General_Steps.js create mode 100644 sdc-workflow-bdd/stepDefinitions/InputData_steps.js create mode 100644 sdc-workflow-bdd/stepDefinitions/InterfaceOperationSteps.js create mode 100644 sdc-workflow-bdd/stepDefinitions/Item_steps.js create mode 100644 sdc-workflow-bdd/stepDefinitions/REST_Steps.js create mode 100644 sdc-workflow-bdd/stepDefinitions/Utils.js create mode 100644 sdc-workflow-bdd/stepDefinitions/Workflow_Steps.js create mode 100644 sdc-workflow-bdd/stepDefinitions/world.js (limited to 'sdc-workflow-bdd') diff --git a/sdc-workflow-bdd/.gitignore b/sdc-workflow-bdd/.gitignore new file mode 100644 index 00000000..316e3984 --- /dev/null +++ b/sdc-workflow-bdd/.gitignore @@ -0,0 +1,11 @@ +.idea +.vscode +.history +debug.log +dist +docs +node_modules +.npmrc +npm-debug.log +devConfig.json +jenkinsConfig.json diff --git a/sdc-workflow-bdd/README.txt b/sdc-workflow-bdd/README.txt new file mode 100644 index 00000000..35250ed3 --- /dev/null +++ b/sdc-workflow-bdd/README.txt @@ -0,0 +1,4 @@ +In order to setup the project: + +Run "mvn install -DskipTests", this will create the documentation under the "docs". +Open the index.html under the docs directory and continue from there. \ No newline at end of file diff --git a/sdc-workflow-bdd/config.json b/sdc-workflow-bdd/config.json new file mode 100644 index 00000000..5d38d099 --- /dev/null +++ b/sdc-workflow-bdd/config.json @@ -0,0 +1,28 @@ +{ + "protocol" : "http", + + "onboarding" : { + "port" : 8285, + "prefix" : "sdc1/feProxy/onboarding-api/v1.0", + "server" : "onboarding.server", + "user" : "user" + }, + "vf" : { + "port" : 8285, + "prefix" : "sdc1/feProxy/rest/v1", + "server" : "vf.server", + "user" : "user" + }, + "workflow" : { + "port" : 8080, + "prefix" : "wf", + "server": "wf.server", + "user" : "user" + }, + "activity_spec" : { + "port" : 8080, + "prefix": "v1.0", + "server": "wf.server", + "user" : "user" + } +} diff --git a/sdc-workflow-bdd/cucumber.js b/sdc-workflow-bdd/cucumber.js new file mode 100644 index 00000000..4ade9b1c --- /dev/null +++ b/sdc-workflow-bdd/cucumber.js @@ -0,0 +1,3 @@ +module.exports = { + "default" : "--require stepDefinitions -f summary -r ./features -f json:report/report.json" +}; \ No newline at end of file diff --git a/sdc-workflow-bdd/features/ActivitySpec.feature b/sdc-workflow-bdd/features/ActivitySpec.feature new file mode 100644 index 00000000..7d9a754a --- /dev/null +++ b/sdc-workflow-bdd/features/ActivitySpec.feature @@ -0,0 +1,61 @@ +Feature: Activity Spec + + #SDC-6350 + Scenario: Create + When I want to set the input data to file "resources/json/createActivitySpec.json" + Then I want to update the input property "name" with a random value + When I want to create an ActivitySpec + + Then I want to check property "id" exists + And I want to check property "versionId" exists + + And I want to list ActivitySpecs with status "Draft" + And I want to check property "total" exists + + And I want to get the ActivitySpec for the current item + And I want to check property "status" for value "Draft" + + And I want to call action "CERTIFY" on this ActivitySpec item + And I want to get the ActivitySpec for the current item + And I want to check property "status" for value "Certified" + + And I want to call action "DEPRECATE" on this ActivitySpec item + And I want to get the ActivitySpec for the current item + And I want to check property "status" for value "Deprecated" + + And I want to call action "DELETE" on this ActivitySpec item + And I want to get the ActivitySpec for the current item + And I want to check property "status" for value "Deleted" + + Scenario: Get with invalid Id + Then I want to set property "item.id" to value "invalidId" + Then I want the following to fail with error message "No Activity Spec found for the given identifiers" + And I want to get the ActivitySpec for the current item + + #SDC-6353 + Scenario: Create with duplicate name - invalid + Given I want to set property "duplicateName" with a random value + And I want to set the input data to file "resources/json/createActivitySpec.json" + And I want to update the input property "name" with value of property "duplicateName" + And I want to create an ActivitySpec + And I want to check property "id" exists + And I want to check property "versionId" exists + + When I want to set the input data to file "resources/json/createActivitySpec.json" + And I want to update the input property "name" with value of property "duplicateName" + Then I want the following to fail with response status code 422 + And I want to create an ActivitySpec + + #SDC-6354 + Scenario: Create with invalid name - invalid + Given I want to set the input data to file "resources/json/createActivitySpec.json" + And I want to update the input property "name" with value "test!@" + Then I want the following to fail with response status code 400 + When I want to create an ActivitySpec + + #SDC-6355 + Scenario: Create with null/blank name - invalid + Given I want to set the input data to file "resources/json/createActivitySpec.json" + And I want to update the input property "name" with value "" + Then I want the following to fail with response status code 400 + When I want to create an ActivitySpec \ No newline at end of file diff --git a/sdc-workflow-bdd/features/ActivitySpecStatus.feature b/sdc-workflow-bdd/features/ActivitySpecStatus.feature new file mode 100644 index 00000000..c908701b --- /dev/null +++ b/sdc-workflow-bdd/features/ActivitySpecStatus.feature @@ -0,0 +1,21 @@ +Feature: Activity Spec Status + + Scenario: Invalid Status Transition + When I want to set the input data to file "resources/json/createActivitySpec.json" + Then I want to update the input property "name" with a random value + When I want to create an ActivitySpec + Then I want to check property "id" exists + And I want to check property "versionId" exists + + When I want to get the ActivitySpec for the current item + Then I want to check property "status" for value "Draft" + + Then I want the following to fail with response status code 422 + When I want to call action "DEPRECATE" on this ActivitySpec item + + Then I want the following to fail with response status code 422 + When I want to call action "DELETE" on this ActivitySpec item + + When I want to call action "CERTIFY" on this ActivitySpec item + Then I want the following to fail with response status code 422 + When I want to call action "CERTIFY" on this ActivitySpec item \ No newline at end of file diff --git a/sdc-workflow-bdd/features/ArchiveWorkflow.feature b/sdc-workflow-bdd/features/ArchiveWorkflow.feature new file mode 100644 index 00000000..e63227df --- /dev/null +++ b/sdc-workflow-bdd/features/ArchiveWorkflow.feature @@ -0,0 +1,68 @@ +# Copyright © 2018 European Support Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Feature: Archive Workflow + + Scenario: Archive workflow + Given I want to create a Workflow + When I want to create input data + And I want to update the input property "status" with value "ARCHIVED" + And I want to create for path "/workflows/{item.id}/archiving" with the input data from the context + Then I want to get path "/workflows/{item.id}" + And I want to check property "status" for value "ARCHIVED" + When I want to get path "/workflows?limit=2000&statusFilter=ARCHIVED" + Then I want to check in the list "items" property "id" with value "{item.id}" exists + When I want to get path "/workflows?limit=2000&" + Then I want to check in the list "items" property "id" with value "{item.id}" does not exist + + + Scenario: Archive and then Restore workflow + Given I want to create a Workflow + When I want to create input data + And I want to update the input property "status" with value "ARCHIVED" + And I want to create for path "/workflows/{item.id}/archiving" with the input data from the context + Then I want to get path "/workflows/{item.id}" + And I want to check property "status" for value "ARCHIVED" + When I want to get path "/workflows?limit=2000&statusFilter=ARCHIVED" + Then I want to check in the list "items" property "id" with value "{item.id}" exists + When I want to get path "/workflows?limit=2000&" + Then I want to check in the list "items" property "id" with value "{item.id}" does not exist + And I want to update the input property "status" with value "ACTIVE" + And I want to create for path "/workflows/{item.id}/archiving" with the input data from the context + Then I want to get path "/workflows/{item.id}" + And I want to check property "status" for value "ACTIVE" + When I want to get path "/workflows?limit=2000&statusFilter=ARCHIVED" + Then I want to check in the list "items" property "id" with value "{item.id}" does not exist + When I want to get path "/workflows?limit=2000&" + Then I want to check in the list "items" property "id" with value "{item.id}" exists + + Scenario: Archive already archived workflow + Given I want to create a Workflow + When I want to create input data + And I want to update the input property "status" with value "ARCHIVED" + And I want to create for path "/workflows/{item.id}/archiving" with the input data from the context + When I want to create input data + And I want to update the input property "status" with value "ARCHIVED" + Then I want the following to fail with response status code 422 + And I want to create for path "/workflows/{item.id}/archiving" with the input data from the context + + Scenario: Restore already active workflow + Given I want to create a Workflow + When I want to create input data + And I want to update the input property "status" with value "ACTIVE" + Then I want the following to fail with response status code 422 + And I want to create for path "/workflows/{item.id}/archiving" with the input data from the context + + + diff --git a/sdc-workflow-bdd/features/Version.feature b/sdc-workflow-bdd/features/Version.feature new file mode 100644 index 00000000..3ca68c96 --- /dev/null +++ b/sdc-workflow-bdd/features/Version.feature @@ -0,0 +1,101 @@ +# Copyright © 2018 European Support Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Feature: Workflow Versions + + Background: Init - Create workflow + Given I want to create a Workflow + + Scenario: Create first empty version + When I want to update the input property "description" with value "first empty version" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to copy to property "item.versionId" from response data path "id" + + Then I want to get path "/workflows/{item.id}/versions/{item.versionId}" + And I want to check that property "id" in the response equals to value of saved property "item.versionId" + And I want to get path "/workflows/{item.id}/versions" + And I want to check in the list "items" property "id" with value of saved property "item.versionId" exists + + Scenario: Create first version with inputs/outputs + When I want to set the input data to file "resources/json/versionWith2Inputs2Outputs1.json" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + + Then I want to check in the list "inputs" property "name" with value "in1" exists + And I want to check in the list "inputs" property "name" with value "in2" exists + And I want to check in the list "outputs" property "name" with value "out1" exists + And I want to check in the list "outputs" property "name" with value "out2" exists + + Scenario: Create second version + And I want to update the input property "description" with value "first empty version" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to copy to property "item.firstVersionId" from response data path "id" + And I want to update the input property "name" with value "CERTIFIED" + And I want to create for path "/workflows/{item.id}/versions/{item.firstVersionId}/state" with the input data from the context + + When I want to create input data + And I want to update the input property "description" with value "second empty version" + And I want to create for path "/workflows/{item.id}/versions?baseVersionId={item.firstVersionId}" with the input data from the context + And I want to copy to property "item.versionId" from response data path "id" + + Then I want to get path "/workflows/{item.id}/versions/{item.versionId}" + And I want to check that property "id" in the response equals to value of saved property "item.versionId" + And I want to get path "/workflows/{item.id}/versions" + And I want to check in the list "items" property "id" with value of saved property "item.versionId" exists + + Scenario: Update version + And I want to create input data + And I want to update the input property "description" with value "workflow version description" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to copy to property "item.versionId" from response data path "id" + + When I want to update the input property "description" with value "workflow version description updated" + And I want to update for path "/workflows/{item.id}/versions/{item.versionId}" with the input data from the context + + Then I want to get path "/workflows/{item.id}/versions/{item.versionId}" + And I want to check property "description" for value "workflow version description updated" + + Scenario: Update version with duplicate input name - invalid + And I want to update the input property "description" with value "version with with duplicate input name" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to copy to property "item.versionId" from response data path "id" + + And I want to set the input data to file "resources/json/versionWithDuplicateInputName.json" + Then I want the following to fail with response status code 400 + When I want to update for path "/workflows/{item.id}/versions/{item.versionId}" with the input data from the context + + Scenario: Update version with duplicate output name - invalid + And I want to update the input property "description" with value "version with with duplicate output name" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to copy to property "item.versionId" from response data path "id" + + And I want to set the input data to file "resources/json/versionWithDuplicateOutputName.json" + Then I want the following to fail with response status code 400 + When I want to update for path "/workflows/{item.id}/versions/{item.versionId}" with the input data from the context + + Scenario: Update version with inputs/outputs (create/update/delete parameters) + And I want to set the input data to file "resources/json/versionWith2Inputs2Outputs1.json" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to copy to property "item.versionId" from response data path "id" + + When I want to set the input data to file "resources/json/versionWith2Inputs2Outputs2.json" + And I want to update for path "/workflows/{item.id}/versions/{item.versionId}" with the input data from the context + + Then I want to get path "/workflows/{item.id}/versions/{item.versionId}" + And I want to check in the list "inputs" property "name" with value "in1" exists + And I want to check in the list "inputs" property "name" with value "in2" does not exist + And I want to check in the list "inputs" property "name" with value "in3" exists + And I want to check in the list "outputs" property "name" with value "out1" exists + And I want to check in the list "outputs" property "name" with value "out2" does not exist + And I want to check in the list "outputs" property "name" with value "out3" exists + diff --git a/sdc-workflow-bdd/features/VersionState.feature b/sdc-workflow-bdd/features/VersionState.feature new file mode 100644 index 00000000..09e93a75 --- /dev/null +++ b/sdc-workflow-bdd/features/VersionState.feature @@ -0,0 +1,55 @@ +# Copyright © 2018 European Support Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Feature: Workflow Version State + + Background: Create workflow and first version + Given I want to create a Workflow + And I want to update the input property "description" with value "workflow version description" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to copy to property "item.versionId" from response data path "id" + + Scenario: Get state after creation + When I want to get path "/workflows/{item.id}/versions/{item.versionId}/state" + Then I want to check property "name" for value "DRAFT" + And I want to check property "nextStates[0]" for value "CERTIFIED" + + Scenario: Update state to current state - invalid + Then I want the following to fail with response status code 422 + When I want to update the input property "name" with value "DRAFT" + And I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context + + Scenario: Update state - DRAFT to CERTIFIED + When I want to update the input property "name" with value "CERTIFIED" + And I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context + Then I want to get path "/workflows/{item.id}/versions/{item.versionId}/state" + And I want to check property "name" for value "CERTIFIED" + And I want to check property "nextStates" to have length 0 + + Scenario: Update state when CERTIFIED - invalid + When I want to update the input property "name" with value "CERTIFIED" + And I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context + When I want the following to fail with response status code 422 + Then I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context + + Scenario: Update when CERTIFIED - invalid + When I want to update the input property "name" with value "CERTIFIED" + And I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context + And I want to update the input property "description" with value "workflow version description updated" + Then I want the following to fail with response status code 422 + When I want to update for path "/workflows/{item.id}/versions/{item.versionId}" with the input data from the context + + Scenario: Create second version based on non CERTIFIED one - invalid + Then I want the following to fail with response status code 422 + When I want to create for path "/workflows/{item.id}/versions?baseVersionId={item.versionId}" with the input data from the context \ No newline at end of file diff --git a/sdc-workflow-bdd/features/Workflow.feature b/sdc-workflow-bdd/features/Workflow.feature new file mode 100644 index 00000000..80969614 --- /dev/null +++ b/sdc-workflow-bdd/features/Workflow.feature @@ -0,0 +1,31 @@ +# Copyright © 2018 European Support Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Feature: Workflow + +# Scenario: Create invalid - without name +# Given I want to create input data +# When I want the following to fail with response status code 400 +# Then I want to create for path "/workflows" with the input data from the context + + Scenario: Create + When I want to create a Workflow + Then I want to check property "description" for value "Workflow Description" + +# Scenario: Update and Get +# Given I want to create a Workflow +# And I want to update the input property "description" with value "workflow description updated" +# When I want to update for path "/workflows/{item.id}" with the input data from the context +# Then I want to get path "/workflows/{item.id}" +# And I want to check property "description" for value "workflow description updated" diff --git a/sdc-workflow-bdd/features/WorkflowList.feature b/sdc-workflow-bdd/features/WorkflowList.feature new file mode 100644 index 00000000..529f8a5c --- /dev/null +++ b/sdc-workflow-bdd/features/WorkflowList.feature @@ -0,0 +1,97 @@ +# Copyright © 2018 European Support Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Feature: Workflows list + + Background: Init - create various workflows in order to test list filter + Given I want to create a Workflow + And I want to copy to property "noVersionsWorkflowId" from response data path "id" + + Given I want to create a Workflow + And I want to copy to property "draftVersionWorkflowId" from response data path "id" + And I want to update the input property "description" with value "first version" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + + Given I want to create a Workflow + And I want to copy to property "certifiedVersionWorkflowId" from response data path "id" + And I want to update the input property "description" with value "first version" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to update the input property "name" with value "CERTIFIED" + And I want to create for path "/workflows/{item.id}/versions/{responseData.id}/state" with the input data from the context + + Given I want to create a Workflow + And I want to copy to property "draftAndCertifiedVersionWorkflowId" from response data path "id" + And I want to update the input property "description" with value "first version" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to copy to property "item.versionId" from response data path "id" + And I want to update the input property "name" with value "CERTIFIED" + And I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context + And I want to update the input property "description" with value "second version" + And I want to create for path "/workflows/{item.id}/versions?baseVersionId={item.versionId}" with the input data from the context + + Given I want to create a Workflow + And I want to copy to property "rand1" from response data path "name" + And I want to update the input property "name" with value "workflow_ss_1_{rand1}" + And I want to update for path "/workflows/{item.id}" with the input data from the context + + Given I want to create a Workflow + And I want to copy to property "rand2" from response data path "name" + And I want to update the input property "name" with value "workflow_ss_2_{rand2}" + And I want to update for path "/workflows/{item.id}" with the input data from the context + + Given I want to create a Workflow + And I want to copy to property "rand3" from response data path "name" + And I want to update the input property "name" with value "workflow_ss_3_{rand3}" + And I want to update for path "/workflows/{item.id}" with the input data from the context + + Scenario: List all + When I want to get path "/workflows?limit=2000" + Then I want to check in the list "items" property "id" with value of saved property "noVersionsWorkflowId" exists + And I want to check in the list "items" property "id" with value of saved property "draftVersionWorkflowId" exists + And I want to check in the list "items" property "id" with value of saved property "certifiedVersionWorkflowId" exists + And I want to check in the list "items" property "id" with value of saved property "draftAndCertifiedVersionWorkflowId" exists + + Scenario: List ones with DRAFT version(s) + When I want to get path "/workflows?versionState=DRAFT&limit=2000" + Then I want to check in the list "items" property "id" with value of saved property "noVersionsWorkflowId" does not exist + And I want to check in the list "items" property "id" with value of saved property "draftVersionWorkflowId" exists + And I want to check in the list "items" property "id" with value of saved property "certifiedVersionWorkflowId" does not exist + And I want to check in the list "items" property "id" with value of saved property "draftAndCertifiedVersionWorkflowId" exists + + Scenario: List ones with CERTIFIED version(s) + When I want to get path "/workflows?versionState=CERTIFIED&limit=2000" + Then I want to check in the list "items" property "id" with value of saved property "noVersionsWorkflowId" does not exist + And I want to check in the list "items" property "id" with value of saved property "draftVersionWorkflowId" does not exist + And I want to check in the list "items" property "id" with value of saved property "certifiedVersionWorkflowId" exists + And I want to check in the list "items" property "id" with value of saved property "draftAndCertifiedVersionWorkflowId" exists + + Scenario: List ones with DRAFT/CERTIFIED version(s) + When I want to get path "/workflows?versionState=DRAFT,CERTIFIED&limit=2000" + Then I want to check in the list "items" property "id" with value of saved property "noVersionsWorkflowId" does not exist + And I want to check in the list "items" property "id" with value of saved property "draftVersionWorkflowId" exists + And I want to check in the list "items" property "id" with value of saved property "certifiedVersionWorkflowId" exists + And I want to check in the list "items" property "id" with value of saved property "draftAndCertifiedVersionWorkflowId" exists + + Scenario: List ones with gibberish version(s) = none + When I want to get path "/workflows?versionState=gibberish&limit=2000" + Then I want to check in the list "items" property "id" with value of saved property "noVersionsWorkflowId" does not exist + And I want to check in the list "items" property "id" with value of saved property "draftVersionWorkflowId" does not exist + And I want to check in the list "items" property "id" with value of saved property "certifiedVersionWorkflowId" does not exist + And I want to check in the list "items" property "id" with value of saved property "draftAndCertifiedVersionWorkflowId" does not exist + + Scenario: List ones that contain 'workflow_ss' in name + When I want to get path "/workflows?searchNameFilter=workflow_ss&limit=2000" + And I want to check in the list "items" property "name" with value "workflow_ss_1_{rand1}" exists + And I want to check in the list "items" property "name" with value "workflow_ss_2_{rand2}" exists + And I want to check in the list "items" property "name" with value "workflow_ss_3_{rand3}" exists \ No newline at end of file diff --git a/sdc-workflow-bdd/features/examples/ResponseDataChecks.feature b/sdc-workflow-bdd/features/examples/ResponseDataChecks.feature new file mode 100644 index 00000000..7956e651 --- /dev/null +++ b/sdc-workflow-bdd/features/examples/ResponseDataChecks.feature @@ -0,0 +1,50 @@ +Feature: Example for checking response data + Scenario: Example Checks + # setting some data just for testing purposes + Given Response Data: + """ + { + "field1" : "string field", + "field2" : true, + "field3": "5", + "field4" : [{"entry1":"a"},{"entry2":"b"},{"entry3":"c"}], + "inputs": [ + { + "mandatory": true, + "name": "in1", + "type": "STRING" + }, + { + "mandatory": true, + "name": "in2", + "type": "INTEGER" + } + ], + "outputs": [ + { + "mandatory": true, + "name": "workflow", + "type": "TIMESTAMP" + }, + { + "mandatory": true, + "name": "out2", + "type": "BOOLEAN" + } + ] + } + """ + # printing out for test purposes + #Then I want to print the context data + + # running the different options of checking the respone data + Then I want to check property "field1" for value "string field" + Then I want to check property "field2" to be true + Then I want to check property "field3" for value 5 + Then I want to check property "field4" to have length 3 + Then I want to check property "field4[0].entry1" exists + Then I want to check property "field4[0].no_exist" does not exist + Then I want to check property "outputs[0].name" exists + Then I want to check property "outputs[0].name" for value "workflow" + Then I want to check in the list "outputs" property "name" with value "out2" exists + Then I want to check in the list "outputs" property "name" with value "out3" does not exist diff --git a/sdc-workflow-bdd/package.json b/sdc-workflow-bdd/package.json new file mode 100644 index 00000000..8d4bc114 --- /dev/null +++ b/sdc-workflow-bdd/package.json @@ -0,0 +1,31 @@ +{ + "name": "sdctests", + "version": "1.0.0", + "license": "Apache-2.0", + "description": "SDC Cucumber testing", + "main": "reporter.js", + "directories": { + "doc": "docs" + }, + "scripts": { + "test": "cucumber-js", + "test-and-report": "npm-run-all -c -s test cucumber-html-report", + "cucumber-html-report": "node plugins/reporter.js", + "cucumber-docs": "jsdoc ./stepDefinitions -c plugins/jsdoc_config.json --readme plugins/README.md" + }, + "author": "", + "dependencies": { + "assert": "^1.4.1", + "cucumber": "^3.2.1", + "cucumber-html-reporter": "^3.0.4", + "docdash": "^0.4.0", + "jsdoc": "^3.5.5", + "jsdoc-one-page": "0.0.5", + "lodash": "^4.17.4", + "node-zip": "^1.1.1", + "normalize-newline": "^3.0.0", + "npm-run-all": "^4.1.2", + "request": "^2.83.0", + "yamljs": "^0.3.0" + } +} diff --git a/sdc-workflow-bdd/plugins/README.md b/sdc-workflow-bdd/plugins/README.md new file mode 100644 index 00000000..956fe772 --- /dev/null +++ b/sdc-workflow-bdd/plugins/README.md @@ -0,0 +1,23 @@ +
+

Welcome!

+This is the documentation for using the BDD testing framework for SDC.
+The Modules on the left contains all steps for particalar aress and/or explanations of what they do.
+

+

How to set the server configuration

+
  • Copy the config.json to devConfig.json +
  • Replace the server and user values with the correct values +

    How to run with Maven

    +
  • "mvn install" will install npm if needed, download all modules and create the documentation under the "docs" folder +
  • "mvn test-and-report" will run all tests in the features folder and create an HTML report under the "reports" folder +

    How to develop tests

    +You can open the project in IntelliJ and Webstorm to run and develop scenarios.
    +
  • You will need to install the Cucumber.Js plugin In order to install, go to "Settings/Plugins". If cucumber.js in not on the list, go to "Browse repositories.." and install . +
  • First time only: Right click on feature file and try to run. Now go to "Run/edit configurations" and set the "executable path" to the "node_modules\.bin\cucumber-js.cmd" under your current project. +
  • Now you can run the feature files by right clicking on the file and selecting "Run" from IDEA.
    +
  • Add to existing scenarios or create new files under the "features" directory for additional tests +
    +
  • You can also run a specific test from the command line by running "npm run test -- [features/path to file] +

    More Information

    +
  • More on Cucumber +
  • More on Gherkin +
  • More on Cucumber-js diff --git a/sdc-workflow-bdd/plugins/jsdoc_config.json b/sdc-workflow-bdd/plugins/jsdoc_config.json new file mode 100644 index 00000000..a5a608e8 --- /dev/null +++ b/sdc-workflow-bdd/plugins/jsdoc_config.json @@ -0,0 +1,15 @@ +{ + "tags": { + "allowUnknownTags": true + }, + "templates": { + "default": { + "outputSourceFiles": false + } + }, + "plugins": ["plugins/steps"], + "opts": { + "template": "node_modules/jsdoc-one-page", + "destination": "docs/" + } +} \ No newline at end of file diff --git a/sdc-workflow-bdd/plugins/reporter.js b/sdc-workflow-bdd/plugins/reporter.js new file mode 100644 index 00000000..8913789c --- /dev/null +++ b/sdc-workflow-bdd/plugins/reporter.js @@ -0,0 +1,31 @@ +/* + * Copyright © 2016-2017 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var reporter = require('cucumber-html-reporter'); + +var options = { + theme: 'bootstrap', + jsonFile: 'report/report.json', + output: 'report/report.html', + reportSuiteAsScenarios: true, + launchReport: false, + metadata: { + "ONAP" : "Some build", + "Executed": "Local" + } +}; + +reporter.generate(options); + diff --git a/sdc-workflow-bdd/plugins/steps.js b/sdc-workflow-bdd/plugins/steps.js new file mode 100644 index 00000000..2faa7efb --- /dev/null +++ b/sdc-workflow-bdd/plugins/steps.js @@ -0,0 +1,65 @@ +/* + * Copyright © 2016-2017 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @module plugins/steptag + */ +'use strict'; + + +exports.handlers = { + /** + * Support @step tag. + * + * @step description + */ + newDoclet: function(e) { + var tags = e.doclet.tags; + var tag; + var value; + + // any user-defined tags in this doclet? + if (typeof tags !== 'undefined') { + + tags = tags.filter(function($) { + return $.title === 'step' || $.title === 'examplefile'; + }); + + if (tags.length) { + // take the first one + tag = tags[0]; + let step = null; + let exampleFile = null; + for (tag in tags) { + if (tags[tag].title === "step") { + step = "" + tags[tag].value + "
    "; + } + if (tags[tag].title === "examplefile") { + exampleFile = " Example Features File: " + tags[tag].value + "
    "; + } + } + if (exampleFile !== null) { + step += exampleFile; + } + e.doclet.meta = e.doclet.meta || {}; + if (e.doclet.description !== undefined) { + e.doclet.description = step + e.doclet.description; + } else { + e.doclet.description = step; + } + } + } + } +}; \ No newline at end of file diff --git a/sdc-workflow-bdd/pom.xml b/sdc-workflow-bdd/pom.xml new file mode 100644 index 00000000..0216d596 --- /dev/null +++ b/sdc-workflow-bdd/pom.xml @@ -0,0 +1,167 @@ + + 4.0.0 + + org.openecomp.sdc + sdc-workflow-cucumber + cucumber-report + 1.7.0-SNAPSHOT + + + + + maven-clean-plugin + 2.6.1 + + + clean.dist.folder + clean + + clean + + + + + ${basedir}/report + + **/* + + + + ${basedir}/resources/downloads + + **/* + + + + ${basedir}/docs + + **/* + + + + ${basedir} + + jenkinsConfig.json + + + + + + + + + + + + maven-antrun-plugin + + + create-reporting-folders + generate-sources + + + + + + + + + run + + + + + + + + + + com.github.eirslett + frontend-maven-plugin + 1.8.0 + + + ${project.parent.parent.basedir} + + + + + + install node and yarn + + install-node-and-yarn + + + v10.17.0 + v1.19.1 + + + + + yarn run install + + yarn + + + install + + + + yarn run cucumber docs + + yarn + + + false + run cucumber-docs + + + + + yarn run cucumber test + + yarn + + + false + run test-and-report + + test + + + + + + + + maven-resources-plugin + 2.6 + + + copy-config + validate + + copy-resources + + + ${basedir} + + + ${basedir}/resources + + jenkinsConfig.json + + true + + + + + + + + + + + diff --git a/sdc-workflow-bdd/resources/json/createActivitySpec.json b/sdc-workflow-bdd/resources/json/createActivitySpec.json new file mode 100644 index 00000000..bf1b6012 --- /dev/null +++ b/sdc-workflow-bdd/resources/json/createActivitySpec.json @@ -0,0 +1,23 @@ +{ + "name": "RANDOM", + "description": "Start Server", + "categoryList": [ + "Server" + ], + "inputs": [ + { + "name": "host", + "type": "string", + "value": "10.1.2.3" + } + ], + "outputs": [ + { + "name": "status", + "type": "string", + "value": "started" + } + ], + "type": "string", + "content": "test" +} \ No newline at end of file diff --git a/sdc-workflow-bdd/resources/json/createWorkflow.json b/sdc-workflow-bdd/resources/json/createWorkflow.json new file mode 100644 index 00000000..cc200efb --- /dev/null +++ b/sdc-workflow-bdd/resources/json/createWorkflow.json @@ -0,0 +1,4 @@ +{ + "name": "RANDOM", + "description": "Workflow Description" +} \ No newline at end of file diff --git a/sdc-workflow-bdd/resources/json/versionWith2Inputs2Outputs1.json b/sdc-workflow-bdd/resources/json/versionWith2Inputs2Outputs1.json new file mode 100644 index 00000000..cc0a38ef --- /dev/null +++ b/sdc-workflow-bdd/resources/json/versionWith2Inputs2Outputs1.json @@ -0,0 +1,27 @@ +{ + "description": "version with 2 inputs and 2 outputs", + "inputs": [ + { + "mandatory": true, + "name": "in1", + "type": "STRING" + }, + { + "mandatory": true, + "name": "in2", + "type": "INTEGER" + } + ], + "outputs": [ + { + "mandatory": true, + "name": "out1", + "type": "TIMESTAMP" + }, + { + "mandatory": true, + "name": "out2", + "type": "BOOLEAN" + } + ] +} \ No newline at end of file diff --git a/sdc-workflow-bdd/resources/json/versionWith2Inputs2Outputs2.json b/sdc-workflow-bdd/resources/json/versionWith2Inputs2Outputs2.json new file mode 100644 index 00000000..58f9b2b8 --- /dev/null +++ b/sdc-workflow-bdd/resources/json/versionWith2Inputs2Outputs2.json @@ -0,0 +1,27 @@ +{ + "description": "version with 2 inputs and 2 outputs", + "inputs": [ + { + "mandatory": false, + "name": "in1", + "type": "STRING" + }, + { + "mandatory": true, + "name": "in3", + "type": "INTEGER" + } + ], + "outputs": [ + { + "mandatory": false, + "name": "out1", + "type": "TIMESTAMP" + }, + { + "mandatory": true, + "name": "out3", + "type": "BOOLEAN" + } + ] +} \ No newline at end of file diff --git a/sdc-workflow-bdd/resources/json/versionWithDuplicateInputName.json b/sdc-workflow-bdd/resources/json/versionWithDuplicateInputName.json new file mode 100644 index 00000000..978d9c09 --- /dev/null +++ b/sdc-workflow-bdd/resources/json/versionWithDuplicateInputName.json @@ -0,0 +1,27 @@ +{ + "description": "version with with duplicate input name", + "inputs": [ + { + "mandatory": true, + "name": "in1", + "type": "STRING" + }, + { + "mandatory": true, + "name": "in1", + "type": "INTEGER" + } + ], + "outputs": [ + { + "mandatory": true, + "name": "out1", + "type": "TIMESTAMP" + }, + { + "mandatory": true, + "name": "out2", + "type": "BOOLEAN" + } + ] +} \ No newline at end of file diff --git a/sdc-workflow-bdd/resources/json/versionWithDuplicateOutputName.json b/sdc-workflow-bdd/resources/json/versionWithDuplicateOutputName.json new file mode 100644 index 00000000..4810ebe9 --- /dev/null +++ b/sdc-workflow-bdd/resources/json/versionWithDuplicateOutputName.json @@ -0,0 +1,27 @@ +{ + "description": "version with duplicate output name", + "inputs": [ + { + "mandatory": true, + "name": "in1", + "type": "STRING" + }, + { + "mandatory": true, + "name": "in2", + "type": "INTEGER" + } + ], + "outputs": [ + { + "mandatory": true, + "name": "out1", + "type": "TIMESTAMP" + }, + { + "mandatory": true, + "name": "out1", + "type": "BOOLEAN" + } + ] +} \ No newline at end of file diff --git a/sdc-workflow-bdd/stepDefinitions/ActivitySpec_steps.js b/sdc-workflow-bdd/stepDefinitions/ActivitySpec_steps.js new file mode 100644 index 00000000..7fe8ddf2 --- /dev/null +++ b/sdc-workflow-bdd/stepDefinitions/ActivitySpec_steps.js @@ -0,0 +1,47 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const {Then, When} = require('cucumber'); +const assert = require('assert'); +const util = require('./Utils.js'); +const _ = require('lodash'); + +When('I want to create an ActivitySpec', function () { + let path = '/activity-spec'; + return util.request(this.context, 'POST', path, this.context.inputData, false, 'activity_spec').then((result)=> { + this.context.item = {id : result.data.id, versionId: result.data.versionId}; + this.context.activityspec = {id : result.data.id, versionId: result.data.versionId}; + }); +}); + +When('I want to list ActivitySpecs with status {string}', function (string) { + let path = '/activity-spec?status='+string; + return util.request(this.context, 'GET', path, null, false, 'activity_spec').then((result)=> { + this.context.listCount = result.data.listCount; + }); +}); + +When('I want to get the ActivitySpec for the current item', function () { + let path = '/activity-spec/'+ this.context.item.id+'/versions/'+this.context.item.versionId ; + return util.request(this.context, 'GET', path, null, false, 'activity_spec').then((result)=> { + }); +}); + +Then('I want to call action {string} on this ActivitySpec item', function(string) { + let path = '/activity-spec/'+ this.context.item.id+'/versions/'+this.context.item.versionId+'/actions' ; + let inputData = JSON.parse('{"action" : "' +string+ '"}'); + return util.request(this.context, 'PUT', path, inputData, false, 'activity_spec') +}); \ No newline at end of file diff --git a/sdc-workflow-bdd/stepDefinitions/Collaboration_Steps.js b/sdc-workflow-bdd/stepDefinitions/Collaboration_Steps.js new file mode 100644 index 00000000..c4de7583 --- /dev/null +++ b/sdc-workflow-bdd/stepDefinitions/Collaboration_Steps.js @@ -0,0 +1,113 @@ +/* + * Copyright © 2016-2017 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const {Then, When, Given} = require('cucumber'); +const assert = require('assert'); +const util = require('./Utils.js'); + +/** + * @module Collaboration + * @description Adds the user with the given user ID as a contributor on the item + * @exampleFile Example_Collaboration.feature + * @step I want to add user {string} as a contributor to this Item + **/ +When('I want to add user {string} as a contributor to this Item', function(string) { + let path = '/items/' + this.context.item.id + '/permissions/Contributor'; + let inputData = {removedUsersIds:[],addedUsersIds:[string]}; + return util.request(this.context, 'PUT', path, inputData); +}); + +/** + * @module Collaboration + * @description Adds the user with the given user ID as a contributor on the item + * @exampleFile Example_Collaboration.feature + * @step I want to remove user {string} as a contributor to this Item + **/ +When('I want to remove user {string} as a contributor to this Item', function(string) { + let path = '/items/' + this.context.item.id + '/permissions/Contributor'; + let inputData = {removedUsersIds:[string],addedUsersIds:[]}; + return util.request(this.context, 'PUT', path, inputData); +}); + +/** + * @module Collaboration + * @description Changes the owner to the given User ID + * @exampleFile Example_Collaboration.feature + * @step I want to change the owner to user {string} on this Item + **/ +When('I want to change the owner to user {string} on this Item', function(string) { + let path = '/items/' + this.context.item.id + '/permissions/Owner'; + let inputData = {removedUsersIds:[],addedUsersIds:[string]}; + return util.request(this.context, 'PUT', path, inputData); +}); + + +/** + * @module Collaboration + * @description Checks the role for a user on the item by User id and Role can be either: Contributor/Owner + * @exampleFile Example_Collaboration.feature + * @step I want check user {string} has role {string} on this Item + **/ +When('I want to check user {string} has role {string} on this Item', function(string, string2) { + let path = '/items/' + this.context.item.id + '/permissions'; + return util.request(this.context, 'GET', path).then(results => { + for (i in results.data.results) { + if (results.data.results[i].userId === string) { + assert.equal(string2.toLowerCase(), results.data.results[i].permission.toLowerCase()); + return; + } + } + assert.fail('User not found'); + }); +}); + +/** + * @module Collaboration + * @description Checks the user wth this Id has no permissions on this item + * @exampleFile Example_Collaboration.feature + * @step I want check user {string} has rno permissions on this Item + **/ +When('I want to check user {string} has no permissions on this Item', function(string) { + let path = '/items/' + this.context.item.id + '/permissions'; + return util.request(this.context, 'GET', path).then(results => { + for (i in results.data.results) { + if (results.data.results[i].userId === string) { + assert.fail('Found', null, 'User should not have permissions'); + return; + } + } + }); +}); + +/** + * @module Collaboration + * @description Gets the permissions for the Item + * @exampleFile Example_Collaboration.feature + * @step I want to get the permissions for this Item + **/ +When('I want to get the permissions for this Item', function() { + let path = '/items/' + this.context.item.id + '/permissions'; + return util.request(this.context, 'GET', path); +}); + +/** + * @module Collaboration + * @description Changes the user for the Rest calls + * @exampleFile Example_Collaboration.feature + * @step I want to set the user to {string} + **/ +When('I want to set the user to {string}', function(string) { + this.context.headers['onboarding'].USER_ID = string; +}); diff --git a/sdc-workflow-bdd/stepDefinitions/General_Steps.js b/sdc-workflow-bdd/stepDefinitions/General_Steps.js new file mode 100644 index 00000000..1ceea647 --- /dev/null +++ b/sdc-workflow-bdd/stepDefinitions/General_Steps.js @@ -0,0 +1,354 @@ +/* + * Copyright © 2016-2017 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const {Then, When, Given} = require('cucumber'); +const assert = require('assert'); +const _ = require('lodash'); +const normalizeNewline = require('normalize-newline'); +require('node-zip'); +YAML = require('yamljs'); +const fs = require('fs'); +const util = require('./Utils.js'); + +function getPath(path, context) { + let compiled = _.template(path); + return compiled(context); +} + +/** + * @module ContextData + * @description Use with "Given". Use ONLY for local testing when you know the value of the Item you want to use + * instead of creating a new one. + * @step Item {string} and version Id {string} + **/ +Given('Item {string} and version Id {string}', function (string, string2) { + this.context.item.id = string; + this.context.item.versionId = string2; +}); +/** + * @module ContextData + * @exampleFile ResponseDataChecks.feature + * @description Response Data::
    + * """
    + * {jsonObject}
    + * """
    + * @step Use with "Given". Use ONLY for local testing, creates a response data object + **/ +Given('Response Data:', function (docString) { + this.context.responseData = JSON.parse(docString); +}); + +/** + * @module ContextData + * @description Copy a property from the response data to context Item data, example: item.componentId + * @step I want to save on the context for {string} property {string} with value {string} + **/ +Then('I want to save on the context for {string} property {string} with value {string}', function(string, string1, string2) { + assert.equal(_.includes(['Item'], string), true); + let val = _.get(this.context.responseData, string2); + _.set(this.context, string1, val); +}); +/** + * @module ContextData + * @description Copy a property from the response data to saved data on the context. Example: save newly generated IDs. Response data value can be from a path, xample: results[0].id + * @exampleFile Example_Rest_Calls.feature + * @step I want to save to property {string} from response data path {string} + **/ +Then('I want to copy to property {string} from response data path {string}', function(string, string2) { + let val = _.get(this.context.responseData, string2); + _.set(this.context, string, val); +}); +/** + * @module ContextData + * @description This will set the value of a saved property on the context + * @exampleFile Example_Rest_Calls.feature + * @step I want to set property {string} to value {string} + **/ +Then('I want to set property {string} to value {string}', function(string, string2) { + _.set(this.context, string, string2); +}); + +/** + * @module ContextData + * @description sets context property to a random value + * @exampleFile Example_Rest_Calls.feature + * @step I want to update the input property {string} with a random value + **/ +Then('I want to set property {string} with a random value', function (string) { + _.set(this.context, string, util.random()); +}); + +/** + * @module ResponseData + * @description Will check the output data for a property and a value. property can be a path (example: results[0].id) + * @exampleFile ResponseDataChecks.feature + * @step I want to check property {string} for value {string} + **/ +Then('I want to check property {string} for value {string}', function(string, string2) { + assert.equal(_.get(this.context.responseData, string), string2); +}); +/** + * @module ResponseData + * @description Will check the output data for a property and a value. property can be a path + * (example: results[0].id). Supports comparison to a long String by allowing a line break + * @exampleFile VirtualMachineInterfaceValidationHeatResourceMissingProperties.feature + * @step I want to check property {string} for value {string} + **/ + +Then('I want to check property {string} for value:', function(string, docString) { + assert.equal(_.get(this.context.responseData, string), docString.trim()); +}); +/** + * @module ResponseData + * @description Will check the output data for a property and a integer. property can be a path (example: results[0].id) + * @exampleFile ResponseDataChecks.feature + * @step I want to check property {string} for value {int} + **/ +Then('I want to check property {string} for value {int}', function(string, int) { + assert.equal(_.get(this.context.responseData, string), int); +}); + +/** + * @module ResponseData + * @description Will check the output data for a property and a boolean. property can be a path (example: results[0].id) + * @exampleFile ResponseDataChecks.feature + * @step I want to check property {string} to be "True/False" + **/ +Then('I want to check property {string} to be {word}', function(string, string2) { + assert.equal(_.get(this.context.responseData, string), string2.toLowerCase() == "true"); +}); +/** + * @module ResponseData + * @description Will check the output data for a property and a boolean. property can be a path (example: results[0].id) + * @exampleFile ResponseDataChecks.feature + * @step I want to check property {string} to have length {int} + **/ +Then('I want to check property {string} to have length {int}', function(string, intLength) { + let arrayProp = _.get(this.context.responseData, string); + assert.equal(arrayProp.length, intLength); +}); +/** + * @module ResponseData + * @description Will check the output data for a property and make sure it exists + * @exampleFile ResponseDataChecks.feature + * @step I want to check property {string} exists + **/ +Then('I want to check property {string} exists', function(string) { + assert.equal(_.has(this.context.responseData, string), true); +}); +/** + * @module ResponseData + * @description Will check the output data for a property and make sure it does not exist + * @exampleFile ResponseDataChecks.feature + * @step I want to check property {string} does not exist + **/ +Then('I want to check property {string} does not exist', function(string) { + assert.equal(_.has(this.context.responseData, string), false); +}); + +/** + * @module ResponseData + * @description Will check the output data for a property and a value. property can be a path (example: results[0].id) + * @exampleFile ResponseDataChecks.feature + * @step I want to check property {string} for value {string} + **/ +Then('I want to check in the list {string} property {string} with value {string} exists', function(listPath, propertyPath, value) { + var list = _.get(this.context.responseData, listPath); + let valueCheck = getPath(value, this.context); + assert.notEqual(list.find(element => _.get(element, propertyPath) === valueCheck), undefined); +}); + +/** + * @module ResponseData + * @description Will check the output data for a property and a value. property can be a path (example: results[0].id) + * @exampleFile ResponseDataChecks.feature + * @step I want to check property {string} for value {string} + **/ +Then('I want to check in the list {string} property {string} with value {string} does not exist', function(listPath, propertyPath, value) { + var list = _.get(this.context.responseData, listPath); + assert.equal(list.find(element => _.get(element, propertyPath) === value), undefined); +}); + +/** + * @module ResponseData + * @description Will check the output data for a property and a value. property can be a path (example: results[0].id) + * @exampleFile ResponseDataChecks.feature + * @step I want to check property {string} for value {string} + **/ +Then('I want to check in the list {string} property {string} with value of saved property {string} exists', function(listPath, propertyPath, valueProperty) { + var list = _.get(this.context.responseData, listPath); + var value = _.get(this.context, valueProperty); + assert.notEqual(list.find(element => _.get(element, propertyPath) === value), undefined); +}); + +/** + * @module ResponseData + * @description Will check the output data for a property and a value. property can be a path (example: results[0].id) + * @exampleFile ResponseDataChecks.feature + * @step I want to check property {string} for value {string} + **/ +Then('I want to check in the list {string} property {string} with value of saved property {string} does not exist', function(listPath, propertyPath, valueProperty) { + var list = _.get(this.context.responseData, listPath); + var value = _.get(this.context, valueProperty); + assert.equal(list.find(element => _.get(element, propertyPath) === value), undefined); +}); + +/** +* @module ContextData +* @description Use during development to see what is on the context + * @exampleFile ResponseDataChecks.feature +* @step I want to print the context data +**/ +Then('I want to print the context data', function() { + console.log('------------ context ---------------'); + console.log(JSON.stringify(this.context, null, 2)); + console.log('--------------------------------------'); +}); +/** + * @module ContextData + * @description Set this in order to check that the following Rest call will not have response code 200 + * @exampleFile Example_Rest_Calls.feature + * @step I want the following to fail + **/ +Then('I want the following to fail', function() { + this.context.shouldFail = true; +}); + +/** + * @module ContextData + * @description Set this in order to check that the following Rest call will not have response code 200 + * @exampleFile Example_Rest_Calls.feature + * @step I want the following to fail + **/ +Then('I want the following to fail with response status code {int}', function(int) { + this.context.shouldFail = true; + this.context.responseStatusCode = int; +}); + +/** + * @module ContextData + * @description Set this in order to check that the following Rest call will have the error code on the return data + * @exampleFile Example_VSP.feature + * @step I want the following to fail with error code {string} + **/ +Then('I want the following to fail with error code {string}', function(string) { + this.context.shouldFail = true; + this.context.errorCode = string; +}); + + +/** + * @module ContextData + * @description Set this in order to check that the following Rest call will have the error message on the return data + * @exampleFile DeleteVLMCertified.feature + * @step I want the following to fail with error message {string} + **/ +Then('I want the following to fail with error message {string}', function(string) { + this.context.shouldFail = true; + let errorMessage = getPath(string, this.context); + this.context.errorMessage = errorMessage; +}); + +/** + * @module ZipData + * @description Use this in order to extract a file from a zip file and to compare it to a local file (string comparison). + * @exampleFile Example_VSP.feature + * @step I want to compare the content of the entry {string} in the zip {string} with file {string} + **/ +Then ('I want to compare the content of the entry {string} in the zip {string} with file {string}', function (string, string2, string3) { + let zipFile = fs.readFileSync(string2, 'binary'); + let zip = new JSZip(zipFile, {base64: false, checkCRC32: true}); + let fileData = zip.files[string]._data; + let compareFileData = fs.readFileSync(string3, {encoding: 'ascii'}); + assert.equal(normalizeNewline(compareFileData), normalizeNewline(fileData)); +}); + +/** + * @module ZipData + * @description Loads the yaml from zip file onto the context responseData as JSON for running checks on the output + * @exampleFile Example_VSP.feature + * @step I want to load the yaml content of the entry {string} in the zip {string} to context + **/ +Then ('I want to load the yaml content of the entry {string} in the zip {string} to context', function (string, string2, callback) { + let zipFile = fs.readFileSync(string2, 'binary'); + let zip = new JSZip(zipFile, {base64: false, checkCRC32: true}); + let fileData = zip.files[string]._data; + let nativeObject = YAML.parse(fileData); + this.context.responseData = nativeObject; + callback(); +}); + + +/** + * @module ZipData + * @description Loads the json from zip file onto the context responseData for running check son the output + * @exampleFile Example_VSP.feature + * @step I want to load the json content of the entry {string} in the zip {string} to context + **/ +When('I want to load the json content of the entry {string} in the zip {string} to context', function (string, string2, callback) { + let zipFile = fs.readFileSync(string2, 'binary'); + let zip = new JSZip(zipFile, {base64: false, checkCRC32: true}); + let str = zip.files[string]._data; + this.context.responseData = JSON.parse(str); + callback(); +}); + +Then('I want to check that property {string} in the response equals to value of saved property {string}', function(propertyPath, valueProperty) { + const results = this.context.responseData; + assert.equal(results[propertyPath], _.get(this.context, valueProperty)); +}); + +/** + * @module ResponseData + * @description Check that the itemId from context exits in result of responseData + * exampleFile ArchiveItem.feature + * step I want to check that item exits in response + **/ +Then('I want to check that item exits in response', function() { + + const id = this.context.item.id; + const results = this.context.responseData.results; + var testResult = false; + + for(var i=0; i< results.length; i++){ + if ( id == results[i].id){ + testResult = true; + } + } + + assert.equal(testResult,true); +}); + + +/** + * @module ResponseData + * @description Check that the itemId from context does NOT exits in result of responseData + * exampleFile ArchiveItem.feature + * step I want to check that item does not exits in response + **/ +Then('I want to check that item does not exits in response', function() { + + const id = this.context.item.id; + const results = this.context.responseData.results; + var testResult = false; + + for(var i=0; i< results.length; i++){ + if ( id == results[i].id){ + testResult = true; + } + } + + assert.equal(testResult,false); +}); \ No newline at end of file diff --git a/sdc-workflow-bdd/stepDefinitions/InputData_steps.js b/sdc-workflow-bdd/stepDefinitions/InputData_steps.js new file mode 100644 index 00000000..7fee19a2 --- /dev/null +++ b/sdc-workflow-bdd/stepDefinitions/InputData_steps.js @@ -0,0 +1,99 @@ +/* + * Copyright © 2016-2017 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const {Then, When, Given} = require('cucumber'); +const assert = require('assert'); +const _ = require('lodash'); +const fs = require('fs'); +const util = require('./Utils.js'); + +function getPath(path, context) { + let compiled = _.template(path); + return compiled(context); +} + +/** + * @module InputData + * @description creates an ampty input data object + * @exampleFile Example_Rest_Calls.feature, Example_VLM.feature + * @step I want to create input data + **/ +When('I want to create input data', function () { + this.context.inputData = {}; +}); + +/** + * @module InputData + * @exampleFile Example_Heat.feature + * @description I want to set the input data to:
    + * """
    + * {jsonObject}
    + * """
    + * @step creates an input data element with the given json object + **/ +When('I want to set the input data to:', function (docString) { + this.context.inputData = JSON.parse(docString); +}); + +/** + * @module InputData + * @description creates an input data object from the json in the given file + * @exampleFile Example_Rest_Calls.feature + * @step I want to set the input data to file {string} + **/ +When('I want to set the input data to file {string}', function (string) { + this.context.inputData = util.getJSONFromFile(string); +}); + +/** + * @module InputData + * @description sets the property on the input data to the given value + * @exampleFile Example_Rest_Calls.feature, Example_VLM.feature + * @step I want to update the input property {string} with value {string} + **/ +Then('I want to update the input property {string} with value {string}', function(string, string2) { + let value = getPath(string2, this.context); + _.set(this.context.inputData, string, value); +}); + +/** + * @module InputData + * @description sets the property on the input data to the value of the given property + * @exampleFile WorkflowList.feature + * @step I want to update the input property {string} with value of property {string} + **/ +Then('I want to update the input property {string} with value of property {string}', function(string, string2) { + _.set(this.context.inputData, string, _.get(this.context, string2)); +}); + +/** + * @module InputData + * @description removes a property from the input data object + * @exampleFile Example_Rest_Calls.feature + * @step I want to remove {string} from the input data + **/ +Then('I want to remove {string} from the input data', function(string) { + delete this.context.inputData[string]; +}); + +/** + * @module InputData + * @description sets the input data property to a random value + * @exampleFile Example_Rest_Calls.feature + * @step I want to update the input property {string} with a random value + **/ +Then('I want to update the input property {string} with a random value', function(string) { + _.set(this.context.inputData, string, util.random()); +}); diff --git a/sdc-workflow-bdd/stepDefinitions/InterfaceOperationSteps.js b/sdc-workflow-bdd/stepDefinitions/InterfaceOperationSteps.js new file mode 100644 index 00000000..4c00debc --- /dev/null +++ b/sdc-workflow-bdd/stepDefinitions/InterfaceOperationSteps.js @@ -0,0 +1,118 @@ +/* + * Copyright © 2016-2017 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const {Then, When} = require('cucumber'); +const assert = require('assert'); +const util = require('./Utils.js'); + + +When('I want to create a VF', function() { + let inputData = util.getJSONFromFile('resources/json/operation/createVF_From_Catalog.json'); + + inputData.name = util.random(); + inputData.tags[0] = util.random(); + + let path = '/catalog/resources'; + return util.request(this.context, 'POST', path, inputData, false, 'vf').then(result => { + this.context.item = {uniqueId : result.data.uniqueId, id : result.data.inputs[0].uniqueId, name : result.data.inputs[0].name}; + this.context.vf = {uniqueId : result.data.uniqueId, id : result.data.inputs[0].uniqueId, name : result.data.inputs[0].name}; +}); +}); + +function makeType() { + var text = ""; + var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + for (var i = 0; i < 5; i++) + text += possible.charAt(Math.floor(Math.random() * possible.length)); + + return text; +} + +When('I want to create an Operation', function() { + let inputData = util.getJSONFromFile('resources/json/operation/createOperation.json'); + //let path = '/catalog/resources/f3dc81bb-85e9-4dfd-bd1b-37f5dc5e5534/interfaceOperations'; + let path = '/catalog/resources/' + this.context.vf.uniqueId +'/interfaceOperations'; + + inputData.interfaceOperations.create.operationType = makeType(); + inputData.interfaceOperations.create.inputParams.listToscaDataDefinition[0].paramName = util.random(); + inputData.interfaceOperations.create.inputParams.listToscaDataDefinition[0].paramId = this.context.vf.id; + + return util.request(this.context, 'POST', path, inputData, false, 'vf').then(result => { + this.context.item = {uniqueId : result.data.uniqueId, operationType : result.data.operationType}; + this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType}; +}); +}); + + + +When('I want to list Operations', function () { + let path = '/catalog/resources/' + this.context.vf.uniqueId + '/filteredDataByParams?include=interfaces'; + return util.request(this.context, 'GET', path, null, false, 'vf').then((result)=> { +}); +}); + + +When('I want to get an Operation by Id', function () { + let path = '/catalog/resources/' + this.context.vf.uniqueId + '/interfaceOperations/' + this.context.operation.uniqueId; + return util.request(this.context, 'GET', path, null, false, 'vf').then((result)=> { + this.context.item ={uniqueId : result.data.uniqueId, operationType: result.data.operationType}; + this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType}; +}); +}); + + +When('I want to update an Operation', function () { + let inputData = util.getJSONFromFile('resources/json/operation/updateOperation.json'); + let path = '/catalog/resources/' + this.context.vf.uniqueId + '/interfaceOperations/'; + inputData.interfaceOperations.create.uniqueId = this.context.operation.uniqueId; + inputData.interfaceOperations.create.operationType = this.context.operation.operationType; + inputData.interfaceOperations.create.inputParams.listToscaDataDefinition[0].paramName = util.random(); + inputData.interfaceOperations.create.inputParams.listToscaDataDefinition[0].paramId = this.context.vf.id; + return util.request(this.context, 'PUT', path, inputData, false, 'vf').then((result)=> { + this.context.item ={uniqueId : result.data.uniqueId, operationType: result.data.operationType}; + this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType}; +}); +}); + + +When('I want to delete an Operation', function() { + let path = '/catalog/resources/' + this.context.vf.uniqueId + '/interfaceOperations/' + this.context.operation.uniqueId; + return util.request(this.context, 'DELETE', path, null, false, 'vf'); +}); + + +When('I want to checkin this VF', function () { + let path = '/catalog/resources/' + this.context.vf.uniqueId + '/lifecycleState/CHECKIN' ; + let inputData = {userRemarks: 'checkin'}; + return util.request(this.context, 'POST', path, inputData, false, 'vf').then((result)=> { + this.context.item ={uniqueId : result.data.uniqueId}; + this.context.vf = {uniqueId : result.data.uniqueId}; +}); +}); + + +Then('I want to submit this VF', function () { + let path = '/catalog/resources/' + this.context.vf.uniqueId + '/lifecycleState/certificationRequest' ; + let inputData = {userRemarks: 'submit'}; + return util.request(this.context, 'POST', path, inputData, false, 'vf').then((result)=> { + this.context.item ={uniqueId : result.data.uniqueId}; + this.context.vf = {uniqueId : result.data.uniqueId}; +}); +}); + + + + diff --git a/sdc-workflow-bdd/stepDefinitions/Item_steps.js b/sdc-workflow-bdd/stepDefinitions/Item_steps.js new file mode 100644 index 00000000..3ff7f20f --- /dev/null +++ b/sdc-workflow-bdd/stepDefinitions/Item_steps.js @@ -0,0 +1,91 @@ +/* + * Copyright © 2016-2017 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const {Then, When} = require('cucumber'); +const assert = require('assert'); +const util = require('./Utils.js'); +/** + * @module Item + * @description uses item id and version id from context + * @exampleFile Example_VSP.feature, Example_VLM.feature + * @step I want to make sure this Item has status {string} + **/ +Then('I want to make sure this Item has status {string}', function (string) { + let path = '/items/' + this.context.item.id + '/versions'; + return util.request(this.context, 'GET', path).then(result => { + assert.equal(result.data.results[0].id, this.context.item.versionId); + assert.equal(result.data.results[0].status, string); + }); +}); +/** + * @module Item + * @description uses item id and version id from context + * @exampleFile Example_VSP.feature, Example_VLM.feature + * @step I want to commit this Item + **/ +Then('I want to commit this Item', function () { + let path = '/items/' + this.context.item.id + '/versions/' + this.context.item.versionId + '/actions'; + let inputData = {action: 'Commit', commitRequest: {message: '00Behave'}}; + return util.request(this.context, 'PUT', path, inputData); +}); +/** + * @module Item + * @description creates a new major version. item id and version id from context + * @exampleFile Example_VLM.feature + * @step I want to create a new version for this Item + **/ +Then('I want to create a new version for this Item', function () { + let path = '/items/' + this.context.item.id + '/versions/' + this.context.item.versionId; + let inputData = {description: 'Behave Version', creationMethod: 'major'}; + return util.request(this.context, 'POST', path, inputData).then(result => { + assert.equal(result.data.status, 'Draft'); + }); +}); +/** + * @module Item + * @description reverts to a revision with a given saved property. Should be set from the revision list first + * @exampleFile Example_VLM.feature + * @step I want to commit this Item + **/ +Then('I want to revert this Item to the revision with the value from saved property {string}', function (string) { + let path = '/items/' + this.context.item.id + '/versions/' + this.context.item.versionId + '/actions'; + let inputData = {action: 'Revert', revisionRequest: {revisionId: this.context[string]}}; + return util.request(this.context, 'PUT', path, inputData); +}); + + +/** + * @module Item + * @exampleFile ArchiveItem.feature + * @step I want to archive this item + **/ +Then('I want to archive this item', function() { + let path = '/items/' + this.context.item.id + '/actions' + let inputData = {action: 'ARCHIVE'}; + return util.request(this.context, 'PUT', path, inputData); +}); + + +/** + * @module Item + * @exampleFile ArchiveItem.feature + * @step I want to restore this item + **/ +Then('I want to restore this item', function() { + let path = '/items/' + this.context.item.id + '/actions' + let inputData = {action: 'RESTORE'}; + return util.request(this.context, 'PUT', path, inputData); +}); + diff --git a/sdc-workflow-bdd/stepDefinitions/REST_Steps.js b/sdc-workflow-bdd/stepDefinitions/REST_Steps.js new file mode 100644 index 00000000..c3844124 --- /dev/null +++ b/sdc-workflow-bdd/stepDefinitions/REST_Steps.js @@ -0,0 +1,80 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const {When} = require('cucumber'); +const _ = require('lodash'); +const util = require('./Utils.js'); +_.templateSettings.interpolate = /{([\s\S]+?)}/g; + +function getPath(path, context) { + let compiled = _.template(path); + return compiled(context); +} +/** + * @module Rest_Calls + * @description makes a GET request to the given path (path is appended after the "onboarding-api/v1.0" prefix)
    + * @exampleFile Example_Rest_Calls.feature + * @step I want to get path {string} + **/ +When('I want to get path {string}', function(string) { + let path = getPath(string, this.context); + return util.request(this.context, 'GET', path); +}); + +/** + * @module Rest_Calls + * @description makes a DELETE request to the given path and appends the saved property (path is appended after the "onboarding-api/v1.0" prefix)
    + * @exampleFile Example_Rest_Calls.feature + * @step I want to delete for path {string} with the value from saved property {string} + **/ +When('I want to delete for path {string} with the value from saved property {string}', function(string, string2) { + let path = getPath(string, this.context); + path += '/' + this.context[string2]; + return util.request(this.context, 'DELETE', path); +}); + +/** + * @module Rest_Calls + * @description makes a DELETE request to the given path and appends the saved property (path is appended after the "onboarding-api/v1.0" prefix)
    + * @exampleFile Example_Rest_Calls.feature + * @step I want to delete for path {string} with the value from saved property {string} + **/ +When('I want to delete for path {string}', function (string) { + let path = getPath(string, this.context); + //path += '/' + this.context[string2]; + return util.request(this.context, 'DELETE', path); +}); + +/** + * @module Rest_Calls + * @description makes a PUT request to the given path and sends the input data from the context (path is appended after the "onboarding-api/v1.0" prefix)
    + * @exampleFile Example_Rest_Calls.feature + * @step I want to update for path {string} with the input data from the context + **/ +When('I want to update for path {string} with the input data from the context', function(string) { + let path = getPath(string, this.context); + return util.request(this.context, 'PUT', path, this.context.inputData); +}); + +/** + * @module Rest_Calls + * @description makes a POST request to the given path and sends the input data from the context (path is appended after the "onboarding-api/v1.0" prefix)
    + * @exampleFile Example_Rest_Calls.feature + * @step I want to create for path {string} with the input data from the context + **/ +When('I want to create for path {string} with the input data from the context', function(string) { + let path = getPath(string, this.context); + return util.request(this.context, 'POST', path, this.context.inputData); +}); diff --git a/sdc-workflow-bdd/stepDefinitions/Utils.js b/sdc-workflow-bdd/stepDefinitions/Utils.js new file mode 100644 index 00000000..9f398169 --- /dev/null +++ b/sdc-workflow-bdd/stepDefinitions/Utils.js @@ -0,0 +1,153 @@ +/* + * Copyright © 2016-2017 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const request = require('request'); +const fs = require('fs'); +require('node-zip'); + +function _request(context, method, path, data, isBinary=false, type='workflow') { + let server = context.getUrlForType(type); + + let options = { + method: method, + url: server + path, + headers: context.headers[type] + }; + console.log('--> Calling REST ' + options.method +' url: ' + options.url); + + return new Promise(function (resolve, reject) { + if (method === 'POST' || method === 'PUT') { + if (isBinary) { + var formData = { + upload: fs.createReadStream(data), + }; + options.formData = formData; + } else { + options.json = data; + } + } + request(options, function (err, result, data) { + context.inputData = null; + if (err) { + console.error('Request URL: ' + result.request.uri.href); + console.error('Request Method: ' + result.request.method); + console.error('Response Status Code: ' +result.statusCode); + console.log(err); + reject(err); + } else { + let isExpected = (context.shouldFail) ? (result.statusCode != 200 && result.statusCode != 201) : (result.statusCode == 200 || result.statusCode == 201); + if (!isExpected) { + console.error('Request URL: ' + result.request.uri.href); + console.error('Request Method: ' + result.request.method); + console.error('Response Status Code: ' +result.statusCode); + console.error(result.body); + reject('Status Code was ' + result.statusCode); + } + if (context.shouldFail && context.responseStatusCode) { + if (result.statusCode !== context.responseStatusCode) { + reject('Response Status Code was ' + result.statusCode + ' instead of ' + context.responseStatusCode); + } + } + if (context.shouldFail && context.errorCode) { + if (typeof data === 'string' && data) { + data = JSON.parse(data); + } + let errorCode = data.errorCode; + let contextErrorCode = context.errorCode; + context.errorCode = null; + if (errorCode !== contextErrorCode) { + reject('Error Code was ' + errorCode + ' instead of ' + contextErrorCode); + } + } + if (context.shouldFail && context.errorMessage) { + if (typeof data === 'string' && data) { + data = JSON.parse(data); + } + let errorMessage = data.message; + let contextErrorMessage = context.errorMessage; + context.errorMessage = null; + if (errorMessage !== contextErrorMessage) { + reject('Error Message was ' + errorMessage + ' instead of ' + contextErrorMessage); + } + } + if (context.shouldFail) { + context.shouldFail = false; + resolve({statusCode: result.statusCode, data: {}}); + return; + } + if (method === 'GET' && isBinary) { + // downloading (NetworkPackage) files + return ({ + blob: blobUtil.createBlob([data], {type: 'text/plain'}), + headers: result.headers + }); + } else { + if (typeof data === 'string' && data) { + data = JSON.parse(data); + } + context.responseData = data; + context.inputData = data; + resolve({statusCode: result.statusCode, data: data}); + } + } + }); + }); +} + +function download(context, path, filePath, callback, type='workflow') { + let server = context.getUrlForType(type); + let options = { + method: 'GET', + url: server + path, + headers: context.headers[type] + }; + console.log('--> Calling REST download url: ' + options.url); + + var file = fs.createWriteStream(filePath); + var r = request(options).pipe(file); + r.on('error', function (err) { + console.log(err); + callback(err); + }); + r.on('finish', function () { + file.close(); + let zipFile = fs.readFileSync(filePath, 'binary'); + let zip = new JSZip(zipFile, {base64: false, checkCRC32: true}); + if (zip.files['MANIFEST.json']) { + let manifestData = zip.files['MANIFEST.json']._data; + manifestData = manifestData.replace(/\\n/g, ''); + context.responseData = JSON.parse(manifestData); + } + callback(); + }); + +}; + +function _random() { + let d = new Date(); + return d.getTime().toString().split('').reverse().join(''); +} + +function _getJSONFromFile(file) { + return JSON.parse(fs.readFileSync(file, 'utf8')); +} + + +module.exports = { + request: _request, + random : _random, + getJSONFromFile: _getJSONFromFile, + download: download +}; diff --git a/sdc-workflow-bdd/stepDefinitions/Workflow_Steps.js b/sdc-workflow-bdd/stepDefinitions/Workflow_Steps.js new file mode 100644 index 00000000..abeacab2 --- /dev/null +++ b/sdc-workflow-bdd/stepDefinitions/Workflow_Steps.js @@ -0,0 +1,35 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @module WORKFLOW + * @description Creates a new WORKFLOW with a random name and saves the id and versionId on the context item object
    + * Input data will be taken from the 'resources/json/createWorkflow.json' file. + * @step I want to create a Workflow + **/ + +const {Then, When, Given} = require('cucumber'); +const assert = require('assert'); +const util = require('./Utils.js'); + +When('I want to create a Workflow', function() { + let inputData = util.getJSONFromFile('resources/json/createWorkflow.json'); + inputData.name = util.random(); + let path = '/workflows'; + return util.request(this.context, 'POST', path, inputData).then(result => { + this.context.item ={id : result.data.id}; +}); +}); \ No newline at end of file diff --git a/sdc-workflow-bdd/stepDefinitions/world.js b/sdc-workflow-bdd/stepDefinitions/world.js new file mode 100644 index 00000000..4c50b0c9 --- /dev/null +++ b/sdc-workflow-bdd/stepDefinitions/world.js @@ -0,0 +1,87 @@ +/* + * Copyright © 2016-2017 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const { setWorldConstructor } = require('cucumber'); +const _ = require('lodash'); + +let config = require('../config.json'); +let localConfig = {}; +try { + localConfig = require('../devConfig.json'); +} catch (e) { + try { + localConfig = require('../jenkinsConfig.json'); + } catch (e) { + console.error("no env configuration was found!"); + } +} + +config = _.merge(config, localConfig); +var {setDefaultTimeout} = require('cucumber'); + + +/** + * @module Context + * @description Context that is used per feature file and can be accessed as 'this.context' in all steps.
    + *
    + * Contains the following items:
    + *
  • this.context.server
      REST server and onboarding prefix including version. set either in configuration file or from the command line or SERVER environment variable
    + *
  • this.context
      Object with properties that were saved in the steps.
    + *
  • this.context.inputdata
      Automatically updated with the last responseData from the Rest call
      Object with properties that were prepares in the steps.
    + *
  • this.context.responseData
      Response from the last REST call.
    + **/ +class CustomWorld { + constructor(options) { + this.context = {}; + this.context.headers = {}; + let typeName; + for (typeName in config) { + this.context.headers[typeName] = {}; + if (config[typeName].user) { + this.context.headers[typeName]['USER_ID'] = config[typeName].user; + } + } + + this.context.item = {id: null, versionId: null, componentId: null}; + + this.context.shouldFail = false; + this.context.errorCode = null; + this.context.inputData = null; + this.context.responseData = null; + + this.context.defaultServerType = 'workflow'; + + this.config = config; + + let context = this.context; + this.context.getUrlForType = (function(type) { + var _server = context.server; + var _config = config; + return function(type) { + let typeData = _config[type]; + let _url = _config.protocol + '://' + + typeData.server + ':' + + typeData.port + '/' + + typeData.prefix; + return _url; + } + })(); + + setDefaultTimeout(60 * 1000); + } +} + + +setWorldConstructor(CustomWorld); -- cgit 1.2.3-korg