From 191b1655bafccb15530f4a64c893d97d17d9dcba Mon Sep 17 00:00:00 2001 From: lmontier-pass Date: Thu, 19 Sep 2024 14:04:57 +0200 Subject: [PATCH] [DE-591] Feat/update integration tests to run on backend (#220) * feat: Add integrations tests on backend api * refactor: Move previous integration tests in postman/internal * feat: Update newman command in github action file --- .../reusable_api_reco_integration_tests.yml | 9 +- ...tion_tests_backend.postman_collection.json | 391 ++++++++++++++++++ .../dev_backend.postman_environment.json | 24 ++ ...roduction_backend.postman_environment.json | 24 ++ .../staging_backend.postman_environment.json | 24 ++ ..._integration_tests.postman_collection.json | 2 +- .../dev.postman_environment.json | 2 +- .../production.postman_environment.json | 2 +- .../staging.postman_environment.json | 2 +- 9 files changed, 471 insertions(+), 9 deletions(-) create mode 100644 apps/recommendation/api/postman/backend/api_integration_tests_backend.postman_collection.json create mode 100644 apps/recommendation/api/postman/backend/dev_backend.postman_environment.json create mode 100644 apps/recommendation/api/postman/backend/production_backend.postman_environment.json create mode 100644 apps/recommendation/api/postman/backend/staging_backend.postman_environment.json rename apps/recommendation/api/postman/{ => internal}/api_integration_tests.postman_collection.json (99%) rename apps/recommendation/api/postman/{ => internal}/dev.postman_environment.json (99%) rename apps/recommendation/api/postman/{ => internal}/production.postman_environment.json (99%) rename apps/recommendation/api/postman/{ => internal}/staging.postman_environment.json (99%) diff --git a/.github/workflows/reusable_api_reco_integration_tests.yml b/.github/workflows/reusable_api_reco_integration_tests.yml index 1b55778f..2a2f68ec 100644 --- a/.github/workflows/reusable_api_reco_integration_tests.yml +++ b/.github/workflows/reusable_api_reco_integration_tests.yml @@ -29,8 +29,8 @@ jobs: id-token: 'write' container: postman/newman:5.3 defaults: - run: - working-directory: "apps/recommendation/api/postman" + run: + working-directory: "apps/recommendation/api/postman/backend" steps: - uses: actions/checkout@v4 - name: "Connect to Secret Manager" @@ -60,9 +60,8 @@ jobs: API_RECO_TOKEN:${{ env.DATA_GCP_PROJECT }}/${{ env.API_RECO_SECRET_NAME }} - name: "Run tests collection" run: | - newman run api_integration_tests.postman_collection.json \ - --environment ${{ inputs.TARGET_ENV }}.postman_environment.json \ - --env-var "api_token=${{ steps.secrets-data.outputs.API_RECO_TOKEN }}" + newman run api_integration_tests_backend.postman_collection.json \ + --environment ${{ inputs.TARGET_ENV }}_backend.postman_environment.json - name: "Post to a Slack channel" if: failure() uses: slackapi/slack-github-action@v1.23.0 diff --git a/apps/recommendation/api/postman/backend/api_integration_tests_backend.postman_collection.json b/apps/recommendation/api/postman/backend/api_integration_tests_backend.postman_collection.json new file mode 100644 index 00000000..21e858ff --- /dev/null +++ b/apps/recommendation/api/postman/backend/api_integration_tests_backend.postman_collection.json @@ -0,0 +1,391 @@ +{ + "info": { + "_postman_id": "df30c550-b119-4e59-9b9d-5c6fb0f9f289", + "name": "API Integration Tests Backend", + "description": "Collection of integration tests for the reco api.\nMade with Postman", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "/similar_offers/offer_id no params", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "pm.test(\"Response time is less than 10s\", function () {\r", + " pm.expect(pm.response.responseTime).to.be.below(10000);\r", + "});\r", + "pm.test(\"Response must be a JSON and have a body\", function () {\r", + " pm.response.to.be.ok;\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "\r", + "pm.test(\"Response must contain an array results\", function () {\r", + " const jsonResponse = pm.response.json();\r", + " pm.expect(jsonResponse).to.be.an(\"object\");\r", + " pm.expect(jsonResponse).to.have.property('results')\r", + " pm.expect(jsonResponse.results).to.be.an(\"array\");\r", + "});\r", + "\r", + "pm.test(\"Response must at least 1 offer\", function () {\r", + " const jsonResponse = pm.response.json();\r", + " pm.expect(jsonResponse.results.length).to.be.above(0);\r", + "});\r", + "\r", + "function checkIfArrayIsUnique(array) {\r", + " return array.length === new Set(array).size;\r", + "}\r", + "\r", + "pm.test('Check if Offer_ids are unique', () => {\r", + " let ids = []\r", + " _.each(pm.response.json().results, (item) => {\r", + " ids.push(item)\r", + " })\r", + "\r", + " pm.expect(checkIfArrayIsUnique(ids), ids).to.be.true\r", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{api_url}}/similar_offers/{{offer_id}}", + "host": [ + "{{api_url}}" + ], + "path": [ + "similar_offers", + "{{offer_id}}" + ] + } + }, + "response": [] + }, + { + "name": "/similar_offers/offer_id geoloc Copy", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "pm.test(\"Response time is less than 10s\", function () {\r", + " pm.expect(pm.response.responseTime).to.be.below(10000);\r", + "});\r", + "pm.test(\"Response must be a JSON and have a body\", function () {\r", + " pm.response.to.be.ok;\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "\r", + "pm.test(\"Response must contain an array results\", function () {\r", + " const jsonResponse = pm.response.json();\r", + " pm.expect(jsonResponse).to.be.an(\"object\");\r", + " pm.expect(jsonResponse).to.have.property('results')\r", + " pm.expect(jsonResponse.results).to.be.an(\"array\");\r", + "});\r", + "\r", + "pm.test(\"Response must at least 1 offer\", function () {\r", + " const jsonResponse = pm.response.json();\r", + " pm.expect(jsonResponse.results.length).to.be.above(0);\r", + "});\r", + "\r", + "function checkIfArrayIsUnique(array) {\r", + " return array.length === new Set(array).size;\r", + "}\r", + "\r", + "pm.test('Check if Offer_ids are unique', () => {\r", + " let ids = []\r", + " _.each(pm.response.json().results, (item) => {\r", + " ids.push(item)\r", + " })\r", + "\r", + " pm.expect(checkIfArrayIsUnique(ids), ids).to.be.true\r", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{api_url}}/similar_offers/{{offer_id}}?longitude=2.3688874&latitude=48.8632553", + "host": [ + "{{api_url}}" + ], + "path": [ + "similar_offers", + "{{offer_id}}" + ], + "query": [ + { + "key": "longitude", + "value": "2.3688874" + }, + { + "key": "latitude", + "value": "48.8632553" + } + ] + } + }, + "response": [] + }, + { + "name": "/similar_offers/offer_id categories", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "pm.test(\"Response time is less than 10s\", function () {\r", + " pm.expect(pm.response.responseTime).to.be.below(10000);\r", + "});\r", + "pm.test(\"Response must be a JSON and have a body\", function () {\r", + " pm.response.to.be.ok;\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "\r", + "pm.test(\"Response must contain an array results\", function () {\r", + " const jsonResponse = pm.response.json();\r", + " pm.expect(jsonResponse).to.be.an(\"object\");\r", + " pm.expect(jsonResponse).to.have.property('results')\r", + " pm.expect(jsonResponse.results).to.be.an(\"array\");\r", + "});\r", + "\r", + "pm.test(\"Response must at least 1 offer\", function () {\r", + " const jsonResponse = pm.response.json();\r", + " pm.expect(jsonResponse.results.length).to.be.above(0);\r", + "});\r", + "\r", + "function checkIfArrayIsUnique(array) {\r", + " return array.length === new Set(array).size;\r", + "}\r", + "\r", + "pm.test('Check if Offer_ids are unique', () => {\r", + " let ids = []\r", + " _.each(pm.response.json().results, (item) => {\r", + " ids.push(item)\r", + " })\r", + "\r", + " pm.expect(checkIfArrayIsUnique(ids), ids).to.be.true\r", + "})\r", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{api_url}}/similar_offers/{{offer_id}}?categories=LIVRES&categories=FILMS_SERIES_CINEMA&categories=SPECTACLES", + "host": [ + "{{api_url}}" + ], + "path": [ + "similar_offers", + "{{offer_id}}" + ], + "query": [ + { + "key": "categories", + "value": "LIVRES" + }, + { + "key": "categories", + "value": "FILMS_SERIES_CINEMA" + }, + { + "key": "categories", + "value": "SPECTACLES" + } + ] + } + }, + "response": [] + }, + { + "name": "/similar_offers/offer_id modelEndpoint default", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "pm.test(\"Response time is less than 10s\", function () {\r", + " pm.expect(pm.response.responseTime).to.be.below(10000);\r", + "});\r", + "pm.test(\"Response must be a JSON and have a body\", function () {\r", + " pm.response.to.be.ok;\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "\r", + "pm.test(\"Response must contain an array results\", function () {\r", + " const jsonResponse = pm.response.json();\r", + " pm.expect(jsonResponse).to.be.an(\"object\");\r", + " pm.expect(jsonResponse).to.have.property('results')\r", + " pm.expect(jsonResponse.results).to.be.an(\"array\");\r", + "});\r", + "\r", + "pm.test(\"Response must at least 1 offer\", function () {\r", + " const jsonResponse = pm.response.json();\r", + " pm.expect(jsonResponse.results.length).to.be.above(0);\r", + "});\r", + "\r", + "function checkIfArrayIsUnique(array) {\r", + " return array.length === new Set(array).size;\r", + "}\r", + "\r", + "pm.test('Check if Offer_ids are unique', () => {\r", + " let ids = []\r", + " _.each(pm.response.json().results, (item) => {\r", + " ids.push(item)\r", + " })\r", + "\r", + " pm.expect(checkIfArrayIsUnique(ids), ids).to.be.true\r", + "})\r", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{api_url}}/similar_offers/{{offer_id}}", + "host": [ + "{{api_url}}" + ], + "path": [ + "similar_offers", + "{{offer_id}}" + ], + "query": [ + { + "key": "modelEndpoint", + "value": "default", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "/similar_offers/offer_id modelEndpoint random", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "pm.test(\"Response time is less than 10s\", function () {\r", + " pm.expect(pm.response.responseTime).to.be.below(10000);\r", + "});\r", + "pm.test(\"Response must be a JSON and have a body\", function () {\r", + " pm.response.to.be.ok;\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "\r", + "pm.test(\"Response must contain an array results\", function () {\r", + " const jsonResponse = pm.response.json();\r", + " pm.expect(jsonResponse).to.be.an(\"object\");\r", + " pm.expect(jsonResponse).to.have.property('results')\r", + " pm.expect(jsonResponse.results).to.be.an(\"array\");\r", + "});\r", + "\r", + "pm.test(\"Response must at least 1 offer\", function () {\r", + " const jsonResponse = pm.response.json();\r", + " pm.expect(jsonResponse.results.length).to.be.above(0);\r", + "});\r", + "\r", + "function checkIfArrayIsUnique(array) {\r", + " return array.length === new Set(array).size;\r", + "}\r", + "\r", + "pm.test('Check if Offer_ids are unique', () => {\r", + " let ids = []\r", + " _.each(pm.response.json().results, (item) => {\r", + " ids.push(item)\r", + " })\r", + "\r", + " pm.expect(checkIfArrayIsUnique(ids), ids).to.be.true\r", + "})\r", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{api_url}}/similar_offers/{{offer_id}}", + "host": [ + "{{api_url}}" + ], + "path": [ + "similar_offers", + "{{offer_id}}" + ], + "query": [ + { + "key": "modelEndpoint", + "value": "random", + "disabled": true + } + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] +} diff --git a/apps/recommendation/api/postman/backend/dev_backend.postman_environment.json b/apps/recommendation/api/postman/backend/dev_backend.postman_environment.json new file mode 100644 index 00000000..69c8e8f7 --- /dev/null +++ b/apps/recommendation/api/postman/backend/dev_backend.postman_environment.json @@ -0,0 +1,24 @@ +{ + "id": "2db9675b-86ff-4434-ac13-255415dd3dcc", + "name": "Dev Backend", + "values": [ + { + "key": "api_url", + "value": "https://backend.testing.passculture.team/native/v1/recommendation/", + "enabled": true + }, + { + "key": "env_name", + "value": "dev", + "enabled": true + }, + { + "key": "offer_id", + "value": "28154", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2024-09-19T09:47:05.096Z", + "_postman_exported_using": "Postman/8.12.7" +} diff --git a/apps/recommendation/api/postman/backend/production_backend.postman_environment.json b/apps/recommendation/api/postman/backend/production_backend.postman_environment.json new file mode 100644 index 00000000..14ffc957 --- /dev/null +++ b/apps/recommendation/api/postman/backend/production_backend.postman_environment.json @@ -0,0 +1,24 @@ +{ + "id": "94fd5658-713c-4f5a-9ad8-49cf05f8d43c", + "name": "Production Backend", + "values": [ + { + "key": "api_url", + "value": "https://backend.passculture.app/native/v1/recommendation/", + "enabled": true + }, + { + "key": "env_name", + "value": "prod", + "enabled": true + }, + { + "key": "offer_id", + "value": "202927", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2024-09-19T09:46:57.086Z", + "_postman_exported_using": "Postman/8.12.7" +} diff --git a/apps/recommendation/api/postman/backend/staging_backend.postman_environment.json b/apps/recommendation/api/postman/backend/staging_backend.postman_environment.json new file mode 100644 index 00000000..108ddbf6 --- /dev/null +++ b/apps/recommendation/api/postman/backend/staging_backend.postman_environment.json @@ -0,0 +1,24 @@ +{ + "id": "e3304672-2263-407f-8ffd-e25ad5b7b155", + "name": "Staging Backend", + "values": [ + { + "key": "api_url", + "value": "https://backend.staging.passculture.team/native/v1/recommendation/", + "enabled": true + }, + { + "key": "env_name", + "value": "stg", + "enabled": true + }, + { + "key": "offer_id", + "value": "64886990", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2024-09-19T09:47:23.198Z", + "_postman_exported_using": "Postman/8.12.7" +} diff --git a/apps/recommendation/api/postman/api_integration_tests.postman_collection.json b/apps/recommendation/api/postman/internal/api_integration_tests.postman_collection.json similarity index 99% rename from apps/recommendation/api/postman/api_integration_tests.postman_collection.json rename to apps/recommendation/api/postman/internal/api_integration_tests.postman_collection.json index 961a6bb0..b8424316 100644 --- a/apps/recommendation/api/postman/api_integration_tests.postman_collection.json +++ b/apps/recommendation/api/postman/internal/api_integration_tests.postman_collection.json @@ -1656,4 +1656,4 @@ } } ] -} \ No newline at end of file +} diff --git a/apps/recommendation/api/postman/dev.postman_environment.json b/apps/recommendation/api/postman/internal/dev.postman_environment.json similarity index 99% rename from apps/recommendation/api/postman/dev.postman_environment.json rename to apps/recommendation/api/postman/internal/dev.postman_environment.json index b5d6fa04..400614d0 100644 --- a/apps/recommendation/api/postman/dev.postman_environment.json +++ b/apps/recommendation/api/postman/internal/dev.postman_environment.json @@ -32,4 +32,4 @@ "_postman_variable_scope": "environment", "_postman_exported_at": "2023-09-14T12:53:54.561Z", "_postman_exported_using": "Postman/10.17.7" -} \ No newline at end of file +} diff --git a/apps/recommendation/api/postman/production.postman_environment.json b/apps/recommendation/api/postman/internal/production.postman_environment.json similarity index 99% rename from apps/recommendation/api/postman/production.postman_environment.json rename to apps/recommendation/api/postman/internal/production.postman_environment.json index b7a76ef8..f12fb544 100644 --- a/apps/recommendation/api/postman/production.postman_environment.json +++ b/apps/recommendation/api/postman/internal/production.postman_environment.json @@ -31,4 +31,4 @@ "_postman_variable_scope": "environment", "_postman_exported_at": "2023-09-14T12:54:32.144Z", "_postman_exported_using": "Postman/10.17.7" -} \ No newline at end of file +} diff --git a/apps/recommendation/api/postman/staging.postman_environment.json b/apps/recommendation/api/postman/internal/staging.postman_environment.json similarity index 99% rename from apps/recommendation/api/postman/staging.postman_environment.json rename to apps/recommendation/api/postman/internal/staging.postman_environment.json index 8be5cf12..e7f1f139 100644 --- a/apps/recommendation/api/postman/staging.postman_environment.json +++ b/apps/recommendation/api/postman/internal/staging.postman_environment.json @@ -31,4 +31,4 @@ "_postman_variable_scope": "environment", "_postman_exported_at": "2023-09-14T12:54:17.316Z", "_postman_exported_using": "Postman/10.17.7" -} \ No newline at end of file +}