diff --git a/.circleci/config.yml b/.circleci/config.yml index a1e1889..bb8d894 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,18 +2,17 @@ version: 2.1 setup: true orbs: - test-harness: govstack-working-group/testutils@1.0.3 + testutils: govstack-working-group/testutils@dev:alpha workflows: test_everything: jobs: - - test-harness/create-config: + - testutils/create-config: post-steps: # Persist to workspace has to be defined in main workflow - persist_to_workspace: root: workspace paths: - generated.yml - - test-harness/execute-tests: + - testutils/execute-tests: requires: - - test-harness/create-config - + - testutils/create-config \ No newline at end of file diff --git a/examples/openIMIS/createTestCustomParameters.py b/examples/openIMIS/createTestCustomParameters.py new file mode 100644 index 0000000..2a08f2a --- /dev/null +++ b/examples/openIMIS/createTestCustomParameters.py @@ -0,0 +1,61 @@ +import requests +import json + +class CustomParamManager: + def __init__(self): + self.params = {} + + def fetch_tokens(self): + response = requests.post("http://localhost:3333/login/") + response_data = response.json() + self.params["csrf_token"] = response_data["csrf_token"] + self.params["jwt_token"] = response_data["jwt_token"] + + def add_params(self, new_params_list): + for new_params in new_params_list: + self.params.update(new_params) + + def save_to_file(self): + with open("testCustomParameters.json", "w") as json_file: + json.dump(self.params, json_file) + + def show_params(self): + print("Params:", self.params) + + +if __name__ == "__main__": + print("Creating custom parameters for test suite") + param_manager = CustomParamManager() + # param_manager.fetch_tokens() + + id_parameters = [{"ID_" + str(i): str(2000 + i - 1)} for i in range(1, 35)] + + first_name_parameters = [ + {"FirstName_0": "Anna"}, + {"FirstName_1": "Zofia"}, + {"FirstName_2": "Elsa"}, + {"FirstName_3": "Nick"}, + {"FirstName_4": "Thomas"}, + ] + + last_name_parameters = [ + {"LastName_0": "Stock"}, + {"LastName_1": "Don"}, + {"LastName_2": "Smith"}, + {"LastName_3": "Evans"}, + {"LastName_4": "Johnson"}, + ] + + birth_certificate_id = [ + {"BirthCertificateID_0": "RR-1234567999"}, + {"BirthCertificateID_1": "RR-5465679229"}, + {"BirthCertificateID_2": "RR-1234537999"}, + {"BirthCertificateID_3": "RR-7898797999"}, + {"BirthCertificateID_4": "RR-8534567781"}, + ] + + param_manager.add_params(id_parameters) + param_manager.add_params(first_name_parameters) + param_manager.add_params(last_name_parameters) + param_manager.add_params(birth_certificate_id) + param_manager.save_to_file() diff --git a/examples/openIMIS/docker-compose.yml b/examples/openIMIS/docker-compose.yml index 7ffa5a6..bd105f4 100644 --- a/examples/openIMIS/docker-compose.yml +++ b/examples/openIMIS/docker-compose.yml @@ -28,7 +28,9 @@ services: context: https://github.com/openimis/openimis-be_py.git#govstack-testing-setup volumes: - ./import_data.py:/import_data.py + - ./createTestCustomParameters.py:/createTestCustomParameters.py - ./check_service_availability.sh:/check_service_availability.sh + - ../../test/openAPI/test-data.json:/test-data.json environment: &backend-env - DB_HOST=${DB_HOST} - DB_PORT=5432 diff --git a/examples/openIMIS/import_data.py b/examples/openIMIS/import_data.py index 6838326..7b1cb14 100755 --- a/examples/openIMIS/import_data.py +++ b/examples/openIMIS/import_data.py @@ -1,3 +1,125 @@ -# Note: This file will be used to hold a script -# that will be inserted into a Docker container with openIMIS. -# The script will take seed data and convert it into records in openIMIS. +import os +import django +import json + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "openimis-be.openIMIS.openIMIS.settings") +django.setup() + +from insuree.gql_mutations import update_or_create_gender +from govstack_api.models import Registry +from insuree.models import Insuree, Family, Gender +from django.db import IntegrityError + + +def load_json_data(file_path): + with open(file_path, 'r') as file: + return json.load(file) + + +def load_parameter_from_custom_parameters(file_path, parameter: str = ""): + with open(file_path, 'r') as file: + data = json.load(file) + return {k: v for k, v in data.items() if k.startswith(f'{parameter}_')} + + +def create_test_insuree( + with_family=True, is_head=False, custom_props=None, family_custom_props=None, + last_name=None, other_names=None, insuree_id=None, insuree_uuid=None, json_ext=None): + # insuree has a mandatory reference to family and family has a mandatory reference to insuree + # So we first insert the family with a dummy id and then update it + print(insuree_uuid) + if with_family: + family = Family.objects.create( + validity_from="2019-01-01", + head_insuree_id=1, # dummy + audit_user_id=-1, + **(family_custom_props if family_custom_props else {}) + ) + else: + family = None + + insuree = Insuree.objects.create( + **{ + "last_name": last_name, + "id": insuree_id, + "uuid": insuree_uuid, + "other_names": other_names, + "chf_id": str(insuree_id), + "family": Family.objects.get(id=1), + "gender": Gender.objects.get(code='M'), + "dob": "1920-04-02", + "head": is_head, + "card_issued": False, + "validity_from": "2019-01-01", + "audit_user_id": -1, + "json_ext": json_ext, + **(custom_props if custom_props else {}) + } + ) + if with_family: + family.head_insuree_id = insuree.id + if family_custom_props: + for k, v in family_custom_props.items(): + setattr(family, k, v) + family.save() + + insuree.save() + return insuree + + +def create_gender(user, data): + update_or_create_gender(data, user) + + +def create_default_registry(registry_name=None, version=None, class_name=None, model=None, + fields_mapping=None, special_fields=None, default_values=None, + mutations=None, queries=None): + default_args = { + "registry_name": 'registryname', + "version": '111', + "class_name": 'InsureeRegistry', + "model": 'Insuree', + "fields_mapping": {"ID": "id", "uuid": "uuid", "LastName": "lastName", "FirstName": "otherNames"}, + "special_fields": ["BirthCertificateID", "PersonalData"], + "default_values": { + "dob": 'dob: "1920-04-02"', + "head": "head: false", + "family_id": "familyId: 1", + "gender_id": "genderId: \"M\"", + "card_issued": "cardIssued: false" + }, + "mutations": {"create": "createInsuree", "delete": "deleteInsurees", "update": "updateInsuree"}, + "queries": {"get": "insurees"} + } + + registry = Registry.objects.create( + registry_name=registry_name if registry_name is not None else default_args["registry_name"], + version=version if version is not None else default_args["version"], + class_name=class_name if class_name is not None else default_args["class_name"], + model=model if model is not None else default_args["model"], + fields_mapping=fields_mapping if fields_mapping is not None else default_args["fields_mapping"], + special_fields=special_fields if special_fields is not None else default_args["special_fields"], + default_values=default_values if default_values is not None else default_args["default_values"], + mutations=mutations if mutations is not None else default_args["mutations"], + queries=queries if queries is not None else default_args["queries"] + ) + registry.save() + print("Registry has been successfully saved to the database") + + +if __name__ == "__main__": + test_data = load_json_data("../../test-data.json") + create_default_registry() + id_data = load_parameter_from_custom_parameters(file_path="testCustomParameters.json", parameter="ID") + for index, record in enumerate(test_data["registries"]["records"]): + insuree_id = id_data.get(f"ID_{index + 1}", record.pop("id")) + try: + insuree = create_test_insuree( + insuree_id=insuree_id, + last_name=record.pop('LastName'), + other_names=record.pop('FirstName'), + insuree_uuid=record.pop('uuid'), + json_ext=record + ) + except IntegrityError as e: + print(f"Error while creating insuree for ID {insuree_id}. Error: {str(e)}") diff --git a/examples/openIMIS/test_entrypoint.sh b/examples/openIMIS/test_entrypoint.sh index 0dae5f1..a81a09c 100755 --- a/examples/openIMIS/test_entrypoint.sh +++ b/examples/openIMIS/test_entrypoint.sh @@ -1,7 +1,12 @@ #!/bin/bash -docker-compose build db backend +docker-compose build --no-cache db backend docker-compose up -d db backend docker-compose exec backend chmod +x /check_service_availability.sh docker-compose exec backend bash /check_service_availability.sh + +docker-compose exec backend python /createTestCustomParameters.py +container_id=$(docker-compose ps -q backend) +docker cp $container_id:/openimis-be/openIMIS/testCustomParameters.json ./testCustomParameters.json + docker-compose exec backend python /import_data.py diff --git a/test/openAPI/features/data_create.feature b/test/openAPI/features/data_create.feature index 3b9ac3b..2f64b13 100644 --- a/test/openAPI/features/data_create.feature +++ b/test/openAPI/features/data_create.feature @@ -6,7 +6,7 @@ Feature: API endpoint that allows users to create a new record in the database. Given The user wants to create a new record in the database When User sends POST request with given Information-Mediator-Client header, body, "registryname" as registryname and "111" as versionnumber - And User provides body with parameters: "EE378627342345" as ID, "Anna" as Firstname, "Stock" as LastName, "RR-1234567999" BirthCertificateID + And User provides body with parameters: "${ID_0}" as ID, "${FirstName_0}" as Firstname, "${LastName_0}" as LastName, "${BirthCertificateID_0}" as BirthCertificateID Then User receives a response from the POST /data/{registryname}/{versionnumber}/create endpoint And The POST /data/{registryname}/{versionnumber}/create endpoint response should be returned in a timely manner 15000ms And The POST /data/{registryname}/{versionnumber}/create endpoint response should have status 200 @@ -18,7 +18,7 @@ Feature: API endpoint that allows users to create a new record in the database. Given The user wants to create a new record in the database When User sends POST request with given Information-Mediator-Client header, body, "registryname" as registryname and "111" as versionnumber - And User provides body with parameters: "" as ID, "" as Firstname, "" as LastName, "" BirthCertificateID + And User provides body with parameters: "" as ID, "" as Firstname, "" as LastName, "" as BirthCertificateID Then User receives a response from the POST /data/{registryname}/{versionnumber}/create endpoint And The POST /data/{registryname}/{versionnumber}/create endpoint response should be returned in a timely manner 15000ms And The POST /data/{registryname}/{versionnumber}/create endpoint response should have status 200 @@ -26,8 +26,8 @@ Feature: API endpoint that allows users to create a new record in the database. And The POST /data/{registryname}/{versionnumber}/create endpoint response should match json schema Examples: Valid data - | ID |Firstname | LastName | BirthCertificateID - | EE34534123 | Zofia | Don | RR-5465679229 - | EE38778473 | Elsa | Smith | RR-1234537999 - | RR87483474 | Nick | Evans | RR-7898797999 - | PP84848484 | Thomas | Johnson | RR-8534567781 + | ID |Firstname | LastName | BirthCertificateID + | ${ID_1} | ${FirstName_1} | ${LastName_1} | ${BirthCertificateID_1} + | ${ID_2} | ${FirstName_2} | ${LastName_2} | ${BirthCertificateID_2} + | ${ID_3} | ${FirstName_3} | ${LastName_3} | ${BirthCertificateID_3} + | ${ID_4} | ${FirstName_4} | ${LastName_4} | ${BirthCertificateID_4} diff --git a/test/openAPI/features/support/data_create.js b/test/openAPI/features/support/data_create.js index 1014502..2a6bfe4 100644 --- a/test/openAPI/features/support/data_create.js +++ b/test/openAPI/features/support/data_create.js @@ -9,12 +9,12 @@ const { defaultExpectedResponseTime, contentTypeHeader, dataCreateResponseSchema, + replaceKeyWithValueFromJson, } = require('./helpers/helpers'); chai.use(require('chai-json-schema')); let specDataCreate; - const baseUrl = localhost + dataCreateEndpoint; const endpointTag = { tags: `@endpoint=/${dataCreateEndpoint}` }; @@ -41,14 +41,15 @@ When( ); When( - 'User provides body with parameters: {string} as ID, {string} as Firstname, {string} as LastName, {string} BirthCertificateID', - (ID, Firstname, LastName, BirthCertificateID) => - specDataCreate.withBody({ - ID: ID, - Firstname: Firstname, - LastName: LastName, - BirthCertificateID: BirthCertificateID, - }) + 'User provides body with parameters: {string} as ID, {string} as Firstname, {string} as LastName, {string} as BirthCertificateID', + function (ID, Firstname, LastName, BirthCertificateID) { + return specDataCreate.withBody({ + ID: replaceKeyWithValueFromJson(ID), + Firstname: replaceKeyWithValueFromJson(Firstname), + LastName: replaceKeyWithValueFromJson(LastName), + BirthCertificateID: replaceKeyWithValueFromJson(BirthCertificateID), + }); + } ); Then( diff --git a/test/openAPI/features/support/helpers/helpers.js b/test/openAPI/features/support/helpers/helpers.js index 443a0a3..830fb89 100644 --- a/test/openAPI/features/support/helpers/helpers.js +++ b/test/openAPI/features/support/helpers/helpers.js @@ -369,4 +369,27 @@ module.exports = { }, required: ['ID', 'FirstName', 'LastName', 'BirthCertificateID'], }, + replaceKeyWithValueFromJson, + readJsonFile, }; + +const fs = require('fs'); +let jsonData = readJsonFile('testCustomParameters.json') || readJsonFile('testDefaultParameters.json'); + +function replaceKeyWithValueFromJson(key) { + let processedKey = key.replace('${', '').replace('}', ''); + if (!jsonData.hasOwnProperty(processedKey)) { + throw new Error(`Key ${processedKey} not found in jsonData`); + } + return jsonData[processedKey]; +} + +function readJsonFile(fileName) { + try { + let rawData = fs.readFileSync(fileName); + return JSON.parse(rawData); + } catch (error) { + console.log(`Failed to read ${fileName}, returning null.`); + return null; + } +} diff --git a/test/openAPI/gherkin_param_manager.sh b/test/openAPI/gherkin_param_manager.sh new file mode 100755 index 0000000..835ea1c --- /dev/null +++ b/test/openAPI/gherkin_param_manager.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Define paths to custom and default parameters files +CUSTOM_JSON_PATH="testCustomParameters.json" +DEFAULT_JSON_PATH="testDefaultParameters.json" +REPORT_PATH=$1 + +if [ -f $CUSTOM_JSON_PATH ] && [ -f $DEFAULT_JSON_PATH ]; then + # Both files exist, compare their keys + CUSTOM_KEYS=$(jq -r 'keys[]' $CUSTOM_JSON_PATH | sort) + DEFAULT_KEYS=$(jq -r 'keys[]' $DEFAULT_JSON_PATH | sort) + + # Check if keys in custom and default json file match + if [ "$CUSTOM_KEYS" != "$DEFAULT_KEYS" ]; then + echo "Keys in $CUSTOM_JSON_PATH and $DEFAULT_JSON_PATH do not match. Exiting." + exit 1 + fi + + # If keys match then use custom json file + PARAMETERS_PATH="$CUSTOM_JSON_PATH" +elif [ -f $DEFAULT_JSON_PATH ]; then + # Only default parameters file exists, use it for substitution + PARAMETERS_PATH="$DEFAULT_JSON_PATH" +else + echo "No parameters file found. Continuing without parameter substitution." + PARAMETERS_PATH="" +fi + +# Replcae ${key} with values from selected json file in generated report file +if [ ! -z $PARAMETERS_PATH ]; then + echo "Replacing placeholders in $REPORT_PATH using $PARAMETERS_PATH." + export TMPDIR=/tmp + while IFS="=" read -r key value + do + sed "s/\${$key}/$value/g" "$REPORT_PATH" > temp.txt && mv temp.txt "$REPORT_PATH" + done < <(jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' $PARAMETERS_PATH) +fi diff --git a/test/openAPI/test-data.json b/test/openAPI/test-data.json index 8c72a07..3c79243 100644 --- a/test/openAPI/test-data.json +++ b/test/openAPI/test-data.json @@ -57,7 +57,7 @@ "PersonalData": [] }, { - "uuid": "80bcc268-fa17-11ed-be56-0242ac1200022", + "uuid": "80bcc268-fa17-11ed-be56-0242ac120002", "id": "EE6546273487865", "FirstName": "Tobias", "LastName": "Smith", @@ -134,7 +134,7 @@ ] }, { - "uuid": "80bcb084-fa17-11ed-be56-0242ac120002", + "uuid": "80bcb084-fa17-11ed-be56-0242ac120003", "id": "EE378129277266", "FirstName": "John", "LastName": "Bon", @@ -204,7 +204,7 @@ "PersonalData": [] }, { - "uuid": "4784f9c5-c5d7-40ce-9e19-88c1a1a8a8908", + "uuid": "4784f9c5-c5d7-40ce-9e19-88c1a1a8a890", "id": "EE65346467865", "FirstName": "Alina", "LastName": "Soft", @@ -235,7 +235,6 @@ "BirthCertificateID": "RR-1112223331", "PersonalData": [] }, - "//records below have to be deleted in the test - don't use it to update etc.", { "uuid": "80bcb804-fa17-11ed-be56-0242ac120002", "id": "EE378627348834", diff --git a/test/openAPI/testDefaultParameters.json b/test/openAPI/testDefaultParameters.json new file mode 100644 index 0000000..1580fed --- /dev/null +++ b/test/openAPI/testDefaultParameters.json @@ -0,0 +1,54 @@ +{ + "csrf_token": "D2222", + "jwt_token": "D2223", + "ID_0": "1999", + "ID_1": "2000", + "ID_2": "2001", + "ID_3": "2002", + "ID_4": "2003", + "ID_5": "2004", + "ID_6": "2005", + "ID_7": "2006", + "ID_8": "2007", + "ID_9": "2008", + "ID_10": "2009", + "ID_11": "2010", + "ID_12": "2011", + "ID_13": "2012", + "ID_14": "2013", + "ID_15": "2014", + "ID_16": "2015", + "ID_17": "2016", + "ID_18": "2017", + "ID_19": "2018", + "ID_20": "2019", + "ID_21": "2020", + "ID_22": "2021", + "ID_23": "2022", + "ID_24": "2023", + "ID_25": "2024", + "ID_26": "2025", + "ID_27": "2026", + "ID_28": "2027", + "ID_29": "2028", + "ID_30": "2029", + "ID_31": "2030", + "ID_32": "2031", + "ID_33": "2032", + "ID_34": "2033", + "FirstName_0": "Anna", + "FirstName_1": "Zofia", + "FirstName_2": "Elsa", + "FirstName_3": "Nick", + "FirstName_4": "Thomas", + "LastName_0": "Stock", + "LastName_1": "Don", + "LastName_2": "Smith", + "LastName_3": "Evans", + "LastName_4": "Johnson", + "BirthCertificateID_0": "RR-1234567999", + "BirthCertificateID_1": "RR-5465679229", + "BirthCertificateID_2": "RR-1234537999", + "BirthCertificateID_3": "RR-7898797999", + "BirthCertificateID_4": "RR-8534567781" +} \ No newline at end of file