Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
61 changes: 61 additions & 0 deletions examples/openIMIS/createTestCustomParameters.py
Original file line number Diff line number Diff line change
@@ -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()
2 changes: 2 additions & 0 deletions examples/openIMIS/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
128 changes: 125 additions & 3 deletions examples/openIMIS/import_data.py
Original file line number Diff line number Diff line change
@@ -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)}")
7 changes: 6 additions & 1 deletion examples/openIMIS/test_entrypoint.sh
Original file line number Diff line number Diff line change
@@ -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
14 changes: 7 additions & 7 deletions test/openAPI/features/data_create.feature
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -18,16 +18,16 @@ 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: "<ID>" as ID, "<Firstname>" as Firstname, "<LastName>" as LastName, "<BirthCertificateID>" BirthCertificateID
And User provides body with parameters: "<ID>" as ID, "<Firstname>" as Firstname, "<LastName>" as LastName, "<BirthCertificateID>" 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
And The POST /data/{registryname}/{versionnumber}/create endpoint response should have content-type: application/json header
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}
19 changes: 10 additions & 9 deletions test/openAPI/features/support/data_create.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}` };

Expand All @@ -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(
Expand Down
23 changes: 23 additions & 0 deletions test/openAPI/features/support/helpers/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
37 changes: 37 additions & 0 deletions test/openAPI/gherkin_param_manager.sh
Original file line number Diff line number Diff line change
@@ -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
Loading