diff --git a/README.md b/README.md index 03c7eb6..02d6de8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -MKS API -========= +# MKS API ### Deze api levert de volgende data: @@ -9,41 +8,46 @@ MKS API - Overzicht ID kaarten en Paspoorten ### Local env -``` -python -m venv venv -source venv/bin/activate -pip install -r requirements-root.txt + +// Initialize + +- `python -m venv venv` +- Mac: `source venv/bin/activate` Windows: `.\venv\Scripts\Activate.ps1` (in case of UnauthorizedAccess run `Set-ExecutionPolicy Unrestricted -Scope Process` beforehand) +- `pip install -r requirements-root.txt` // unittest -python -m unittest +`python -m unittest` // requirements.txt maken -make requirements +`make requirements` // dev server -sh scripts/run-dev.sh -``` +`sh scripts/run-dev.sh` ### Kenmerken + - Het bronsysteem is een soap/stuf api MKS, deze haalt gegevens uit de brp. - Het bronsysteem wordt bevraagd op basis van een BSN of KVK nummer. - De output van de api is JSON formaat. ### Dependencies + - Voeg de naam van de library/dependency toe aan requirements-root.txt - Voer volgende commando uit: `make requirements` - ### Development & testen + - Er is geen uitgebreide lokale set-up waarbij ontwikkeld kan worden op basis van een "draaiende" api. Dit zou gemaakt / geïmplementeerd moeten worden. - Alle tests worden dichtbij de geteste functionaliteit opgeslagen. B.v `some_service.py` en wordt getest in `test_some_service.py`. ### CI/CD + - De applicatie wordt verpakt in een Docker container. - Bouwen en deployen van de applicatie gebeurt in Github en Azure DevOps. ### Release to production + ``` ~ cd scripts ~ sh release.sh --minor [--major [--patch]] -``` \ No newline at end of file +``` diff --git a/app/config.py b/app/config.py index d9931ad..ec22594 100644 --- a/app/config.py +++ b/app/config.py @@ -25,6 +25,10 @@ IS_OT = IS_DEV or IS_TEST IS_AZ = os.getenv("IS_AZ", False) +IS_SHOW_BSN_ENABLED = ( + os.getenv("MKS_IS_SHOW_BSN_ENABLED", "false" if IS_PRODUCTION else "true") == "true" +) + # App constants VERIFY_JWT_SIGNATURE = os.getenv("VERIFY_JWT_SIGNATURE", IS_AP) REQUEST_TIMEOUT = 20 if IS_PRODUCTION else 30 # seconds diff --git a/app/helpers.py b/app/helpers.py index 24804ee..6fd34e5 100644 --- a/app/helpers.py +++ b/app/helpers.py @@ -44,3 +44,15 @@ def get_request_template(name): filename = os.path.join(SERVICES_DIR, f"{name}.jinja2") with open(filename) as fp: return Template(fp.read()) + + +def remove_attr(input, attr): + if isinstance(input, dict): + for key in list(input.keys()): + if key == attr: + input.pop(key) + else: + remove_attr(input[key], attr) + if isinstance(input, list): + for list_item in input: + remove_attr(list_item, attr) diff --git a/app/model/gba.py b/app/model/gba.py index 8b3874c..ea7638e 100644 --- a/app/model/gba.py +++ b/app/model/gba.py @@ -13,7 +13,7 @@ "M": "Man", "V": "Vrouw", } -lookup_prsidb_soort_code = { +lookup_persoonidb_soort_code = { 1: "paspoort", 2: "europese identiteitskaart", 3: "toeristenkaart", diff --git a/app/model/stuf_02_04.py b/app/model/stuf_02_04.py index ec41a16..ef46710 100644 --- a/app/model/stuf_02_04.py +++ b/app/model/stuf_02_04.py @@ -2,13 +2,15 @@ from collections import defaultdict from datetime import date from hashlib import sha256 +from app.config import IS_PRODUCTION +# from config import IS_PRODUCTION from bs4 import Tag, ResultSet from dateutil.relativedelta import relativedelta from app.helpers import encrypt from app.model.gba import ( - lookup_prsidb_soort_code, + lookup_persoonidb_soort_code, lookup_geslacht, lookup_gemeenten, lookup_landen, @@ -32,7 +34,7 @@ is_nil, to_string_4x0, set_indicatie_geboortedatum, - set_fields_with_attributes + set_fields_with_attributes, ) @@ -77,7 +79,7 @@ def get_nationaliteiten(nationaliteiten: ResultSet): def extract_persoon_data(persoon_tree: Tag): result = {} - prs_fields = [ + persoon_fields = [ {"name": "bsn-nummer", "parser": as_bsn, "save_as": "bsn"}, {"name": "geslachtsnaam", "parser": to_string}, {"name": "voornamen", "parser": to_string}, @@ -102,7 +104,7 @@ def extract_persoon_data(persoon_tree: Tag): {"name": "aanduidingNaamgebruik", "parser": to_string}, ] - prs_extra_fields = [ + persoon_extra_fields = [ {"name": "aanduidingNaamgebruikOmschrijving", "parser": to_string}, {"name": "geboortelandnaam", "parser": to_string}, {"name": "geboorteplaatsnaam", "parser": to_string}, @@ -119,13 +121,17 @@ def extract_persoon_data(persoon_tree: Tag): }, ] - prs_fields_with_attrs = [ - {"name": "geboortedatum", "parser": set_indicatie_geboortedatum, "save_as": "indicatieGeboortedatum"}, + persoon_fields_with_attrs = [ + { + "name": "geboortedatum", + "parser": set_indicatie_geboortedatum, + "save_as": "indicatieGeboortedatum", + }, ] - set_fields(persoon_tree, prs_fields, result) - set_extra_fields(persoon_tree.extraElementen, prs_extra_fields, result) - set_fields_with_attributes(persoon_tree, prs_fields_with_attrs, result) + set_fields(persoon_tree, persoon_fields, result) + set_extra_fields(persoon_tree.extraElementen, persoon_extra_fields, result) + set_fields_with_attributes(persoon_tree, persoon_fields_with_attrs, result) # vertrokken onbekend waarheen result["vertrokkenOnbekendWaarheen"] = False @@ -135,14 +141,13 @@ def extract_persoon_data(persoon_tree: Tag): set_omschrijving_geslachtsaanduiding(result) set_geboorteLandnaam(result) set_geboorteplaatsNaam(result) - return result def extract_kinderen_data(persoon_tree: Tag): result = [] - knd_fields = [ + kind_fields = [ {"name": "bsn-nummer", "parser": as_bsn, "save_as": "bsn"}, {"name": "voornamen", "parser": to_string}, {"name": "voorvoegselGeslachtsnaam", "parser": to_string}, @@ -163,7 +168,7 @@ def extract_kinderen_data(persoon_tree: Tag): {"name": "adellijkeTitelPredikaat", "parser": to_string}, ] - knd_extra_fields = [ + kind_extra_fields = [ {"name": "omschrijvingAdellijkeTitel", "parser": to_string}, {"name": "geboortelandnaam", "parser": to_string}, {"name": "geboorteplaatsnaam", "parser": to_string}, @@ -171,8 +176,12 @@ def extract_kinderen_data(persoon_tree: Tag): {"name": "opgemaakteNaam", "parser": to_string}, ] - knd_fields_with_attrs = [ - {"name": "geboortedatum", "parser": set_indicatie_geboortedatum, "save_as": "indicatieGeboortedatum"}, + kind_fields_with_attrs = [ + { + "name": "geboortedatum", + "parser": set_indicatie_geboortedatum, + "save_as": "indicatieGeboortedatum", + }, ] kinderen = persoon_tree.find_all("PRSPRSKND") @@ -181,9 +190,9 @@ def extract_kinderen_data(persoon_tree: Tag): for kind in kinderen: result_kind = {} - set_fields(kind.PRS, knd_fields, result_kind) - set_extra_fields(kind.PRS, knd_extra_fields, result_kind) - set_fields_with_attributes(kind.PRS, knd_fields_with_attrs, result_kind) + set_fields(kind.PRS, kind_fields, result_kind) + set_extra_fields(kind.PRS, kind_extra_fields, result_kind) + set_fields_with_attributes(kind.PRS, kind_fields_with_attrs, result_kind) set_omschrijving_geslachtsaanduiding(result_kind) set_geboorteLandnaam(result_kind) @@ -196,10 +205,10 @@ def extract_kinderen_data(persoon_tree: Tag): return result -def extract_parents_data(persoon_tree: Tag): +def extract_ouders_data(persoon_tree: Tag): result = [] - parent_fields = [ + ouder_fields = [ {"name": "bsn-nummer", "parser": as_bsn, "save_as": "bsn"}, {"name": "voornamen", "parser": to_string}, {"name": "voorvoegselGeslachtsnaam", "parser": to_string}, @@ -220,7 +229,7 @@ def extract_parents_data(persoon_tree: Tag): {"name": "adellijkeTitelPredikaat", "parser": to_string}, ] - parent_extra_fields = [ + ouder_extra_fields = [ {"name": "omschrijvingAdellijkeTitel", "parser": to_string}, {"name": "geboortelandnaam", "parser": to_string}, {"name": "geboorteplaatsnaam", "parser": to_string}, @@ -228,25 +237,29 @@ def extract_parents_data(persoon_tree: Tag): {"name": "opgemaakteNaam", "parser": to_string}, ] - parent_fields_with_attrs = [ - {"name": "geboortedatum", "parser": set_indicatie_geboortedatum, "save_as": "indicatieGeboortedatum"}, + ouder_fields_with_attrs = [ + { + "name": "geboortedatum", + "parser": set_indicatie_geboortedatum, + "save_as": "indicatieGeboortedatum", + }, ] - parents = persoon_tree.find_all("PRSPRSOUD") - if is_nil(parents): + ouders = persoon_tree.find_all("PRSPRSOUD") + if is_nil(ouders): return [] - for ouder in parents: - result_parent = {} - set_fields(ouder.PRS, parent_fields, result_parent) - set_extra_fields(ouder.PRS, parent_extra_fields, result_parent) - set_fields_with_attributes(ouder.PRS, parent_fields_with_attrs, result_parent) + for ouder in ouders: + result_ouder = {} + set_fields(ouder.PRS, ouder_fields, result_ouder) + set_extra_fields(ouder.PRS, ouder_extra_fields, result_ouder) + set_fields_with_attributes(ouder.PRS, ouder_fields_with_attrs, result_ouder) - set_omschrijving_geslachtsaanduiding(result_parent) - set_geboorteLandnaam(result_parent) - set_geboorteplaatsNaam(result_parent) + set_omschrijving_geslachtsaanduiding(result_ouder) + set_geboorteLandnaam(result_ouder) + set_geboorteplaatsNaam(result_ouder) - result.append(result_parent) + result.append(result_ouder) result.sort(key=lambda x: x["geboortedatum"] or date.min) @@ -292,7 +305,11 @@ def extract_verbintenis_data(persoon_tree: Tag): ] partner_fields_with_attrs = [ - {"name": "geboortedatum", "parser": set_indicatie_geboortedatum, "save_as": "indicatieGeboortedatum"}, + { + "name": "geboortedatum", + "parser": set_indicatie_geboortedatum, + "save_as": "indicatieGeboortedatum", + }, ] verbintenissen = persoon_tree.find_all("PRSPRSHUW") @@ -311,14 +328,16 @@ def extract_verbintenis_data(persoon_tree: Tag): set_fields(verb.PRS, partner_fields, result_verbintenis["persoon"]) set_extra_fields(verb.PRS, partner_extra_fields, result_verbintenis["persoon"]) - set_fields_with_attributes(verb.PRS, partner_fields_with_attrs, result_verbintenis["persoon"]) + set_fields_with_attributes( + verb.PRS, partner_fields_with_attrs, result_verbintenis["persoon"] + ) set_omschrijving_geslachtsaanduiding(result_verbintenis["persoon"]) einde_verbintenis_code = verb.find("redenOntbinding").string - result_verbintenis[ - "redenOntbindingOmschrijving" - ] = lookup_reden_ontbinding_partner.get(einde_verbintenis_code, None) + result_verbintenis["redenOntbindingOmschrijving"] = ( + lookup_reden_ontbinding_partner.get(einde_verbintenis_code, None) + ) result.append(result_verbintenis) @@ -499,12 +518,12 @@ def extract_identiteitsbewijzen(persoon_tree: Tag): continue try: - result_id["documentType"] = lookup_prsidb_soort_code[type_number] + result_id["documentType"] = lookup_persoonidb_soort_code[type_number] except Exception as e: logging.info(f"unknown document type {type_number} {type(e)} {e}") - result_id[ - "documentType" - ] = f"onbekend type ({type_number})" # unknown doc type + result_id["documentType"] = ( + f"onbekend type ({type_number})" # unknown doc type + ) hash = sha256() hash.update(result_id["documentNummer"].encode()) @@ -559,7 +578,7 @@ def extract_data(persoon_tree: Tag): if isAmsterdammer: kinderen = extract_kinderen_data(persoon_tree) - ouders = extract_parents_data(persoon_tree) + ouders = extract_ouders_data(persoon_tree) verbintenis = verbintenissen["verbintenis"] verbintenis_historisch = verbintenissen["verbintenisHistorisch"] identiteitsbewijzen = extract_identiteitsbewijzen(persoon_tree) diff --git a/app/server.py b/app/server.py index a5e9587..91f4377 100644 --- a/app/server.py +++ b/app/server.py @@ -11,10 +11,11 @@ from app import auth from app.config import ( IS_DEV, + IS_SHOW_BSN_ENABLED, UpdatedJSONProvider, get_application_insights_connection_string, ) -from app.helpers import decrypt, error_response_json, success_response_json +from app.helpers import decrypt, error_response_json, remove_attr, success_response_json from app.service import mks_client_02_04, mks_client_hr from app.service.adr_mks_client_02_04 import get_resident_count @@ -27,6 +28,7 @@ app = Flask(__name__) app.json = UpdatedJSONProvider(app) + FlaskInstrumentor.instrument_app(app) @@ -36,6 +38,10 @@ def get_brp(): with tracer.start_as_current_span("/brp"): user = auth.get_current_user() brp = mks_client_02_04.get_0204(user["id"]) + + if not IS_SHOW_BSN_ENABLED: + remove_attr(brp, "bsn") + return success_response_json(brp) diff --git a/app/test_02_04_model.py b/app/test_02_04_model.py index 40cc282..0299da6 100644 --- a/app/test_02_04_model.py +++ b/app/test_02_04_model.py @@ -37,194 +37,196 @@ ONTBINDING_RESPOSNE_PATH = os.path.join(FIXTURE_PATH, "response_0204_ontbinding.xml") - -class Model0204Tests(TestCase): - def get_result(self): - self.maxDiff = None - return { - "adres": { - # '_adresSleutel': # changes each time! - "begindatumVerblijf": date(2012, 1, 1), - "einddatumVerblijf": None, - "huisletter": None, - "huisnummer": "1", - "huisnummertoevoeging": "I", - "postcode": "1011 PN", - "landnaam": "Nederland", - "straatnaam": "Amstel", - "woonplaatsNaam": "Amsterdam", - "landcode": "6030", - }, - "adresHistorisch": [ - { - "begindatumVerblijf": date(2005, 1, 1), - "einddatumVerblijf": date(2012, 1, 1), - "huisletter": None, - "huisnummer": "2", - "huisnummertoevoeging": "H", - "postcode": "1011 PN", - "straatnaam": "Amstel", - "woonplaatsNaam": "Amsterdam", - "landcode": "6030", - "landnaam": "Nederland", - }, - { - "begindatumVerblijf": date(1990, 1, 1), - "einddatumVerblijf": date(2005, 1, 1), - "huisletter": None, - "huisnummer": "3", - "huisnummertoevoeging": "3", - "postcode": "1011 PB", - "straatnaam": "Amstel", - "woonplaatsNaam": "Amsterdam", - "landcode": "6030", - "landnaam": "Nederland", - }, - { - "begindatumVerblijf": date(1970, 1, 1), - "einddatumVerblijf": None, - "huisletter": None, - "huisnummer": "3333", - "huisnummertoevoeging": "3", - "postcode": "1011 PB", - "straatnaam": "Amstel", - "woonplaatsNaam": "Amsterdam", - "landcode": "6030", - "landnaam": "Nederland", - }, - ], - "identiteitsbewijzen": [ - { - "datumAfloop": date(2025, 1, 1), - "datumUitgifte": date(2014, 1, 1), - "documentNummer": "PP01XYZ35", - "documentType": "paspoort", - "id": "25ee19ff7a9ecb909e2bf5ca044f1f05d2998c98888893c2075240c25a2ff0f7", - }, - { - "datumAfloop": date(2025, 1, 1), - "datumUitgifte": date(2014, 1, 1), - "documentNummer": "PP12XYZ456", - "documentType": "paspoort", - "id": "52882470c67c063666cedc1e01779db71d186c2cffd818af2dd5d8ec021677f0", - }, - ], - "kinderen": [ - { - "adellijkeTitelPredikaat": None, - "bsn": "567890123", - "geboorteLand": "6030", - "geboortedatum": date(2011, 1, 1), - "indicatieGeboortedatum": None, - "geboortelandnaam": "Nederland", - "geboorteplaats": "947", - "geboorteplaatsnaam": "Neer", - "geslachtsaanduiding": "V", - "geslachtsnaam": "Bakker", - "omschrijvingAdellijkeTitel": None, - "omschrijvingGeslachtsaanduiding": "Vrouw", - "opgemaakteNaam": None, - "overlijdensdatum": None, - "voornamen": "Anne", - "voorvoegselGeslachtsnaam": "van", - } - ], - "ouders": [ - { - "adellijkeTitelPredikaat": None, - "bsn": "456789012", - "geboorteLand": "7035", - "geboortedatum": date(1951, 1, 1), - "indicatieGeboortedatum": None, - "geboortelandnaam": "Japan", - "geboorteplaats": "Tokio", - "geboorteplaatsnaam": "Osaka", - "geslachtsaanduiding": "M", - "geslachtsnaam": "Jansen", - "omschrijvingAdellijkeTitel": None, - "omschrijvingGeslachtsaanduiding": "Man", - "opgemaakteNaam": None, - "overlijdensdatum": None, - "voornamen": "Thomas", - "voorvoegselGeslachtsnaam": None, - }, - { - "adellijkeTitelPredikaat": None, - "bsn": "345678901", - "geboorteLand": "5012", - "geboortedatum": date(1961, 1, 1), - "indicatieGeboortedatum": None, - "geboortelandnaam": "Iran", - "geboorteplaats": "Teheran", - "geboorteplaatsnaam": "Teheran", - "geslachtsaanduiding": "V", - "geslachtsnaam": "Visser", - "omschrijvingAdellijkeTitel": None, - "omschrijvingGeslachtsaanduiding": "Vrouw", - "opgemaakteNaam": None, - "overlijdensdatum": None, - "voornamen": "Iep", - "voorvoegselGeslachtsnaam": None, - }, - ], +BRP_RESPONSE = { + "adres": { + # '_adresSleutel': # changes each time! + "begindatumVerblijf": date(2012, 1, 1), + "einddatumVerblijf": None, + "huisletter": None, + "huisnummer": "1", + "huisnummertoevoeging": "I", + "postcode": "1011 PN", + "landnaam": "Nederland", + "straatnaam": "Amstel", + "woonplaatsNaam": "Amsterdam", + "landcode": "6030", + }, + "adresHistorisch": [ + { + "begindatumVerblijf": date(2005, 1, 1), + "einddatumVerblijf": date(2012, 1, 1), + "huisletter": None, + "huisnummer": "2", + "huisnummertoevoeging": "H", + "postcode": "1011 PN", + "straatnaam": "Amstel", + "woonplaatsNaam": "Amsterdam", + "landcode": "6030", + "landnaam": "Nederland", + }, + { + "begindatumVerblijf": date(1990, 1, 1), + "einddatumVerblijf": date(2005, 1, 1), + "huisletter": None, + "huisnummer": "3", + "huisnummertoevoeging": "3", + "postcode": "1011 PB", + "straatnaam": "Amstel", + "woonplaatsNaam": "Amsterdam", + "landcode": "6030", + "landnaam": "Nederland", + }, + { + "begindatumVerblijf": date(1970, 1, 1), + "einddatumVerblijf": None, + "huisletter": None, + "huisnummer": "3333", + "huisnummertoevoeging": "3", + "postcode": "1011 PB", + "straatnaam": "Amstel", + "woonplaatsNaam": "Amsterdam", + "landcode": "6030", + "landnaam": "Nederland", + }, + ], + "identiteitsbewijzen": [ + { + "datumAfloop": date(2025, 1, 1), + "datumUitgifte": date(2014, 1, 1), + "documentNummer": "PP01XYZ35", + "documentType": "paspoort", + "id": "25ee19ff7a9ecb909e2bf5ca044f1f05d2998c98888893c2075240c25a2ff0f7", + }, + { + "datumAfloop": date(2025, 1, 1), + "datumUitgifte": date(2014, 1, 1), + "documentNummer": "PP12XYZ456", + "documentType": "paspoort", + "id": "52882470c67c063666cedc1e01779db71d186c2cffd818af2dd5d8ec021677f0", + }, + ], + "kinderen": [ + { + "adellijkeTitelPredikaat": None, + "bsn": "567890123", + "geboorteLand": "6030", + "geboortedatum": date(2011, 1, 1), + "indicatieGeboortedatum": None, + "geboortelandnaam": "Nederland", + "geboorteplaats": "947", + "geboorteplaatsnaam": "Neer", + "geslachtsaanduiding": "V", + "geslachtsnaam": "Bakker", + "omschrijvingAdellijkeTitel": None, + "omschrijvingGeslachtsaanduiding": "Vrouw", + "opgemaakteNaam": None, + "overlijdensdatum": None, + "voornamen": "Anne", + "voorvoegselGeslachtsnaam": "van", + } + ], + "ouders": [ + { + "adellijkeTitelPredikaat": None, + "bsn": "456789012", + "geboorteLand": "7035", + "geboortedatum": date(1951, 1, 1), + "indicatieGeboortedatum": None, + "geboortelandnaam": "Japan", + "geboorteplaats": "Tokio", + "geboorteplaatsnaam": "Osaka", + "geslachtsaanduiding": "M", + "geslachtsnaam": "Jansen", + "omschrijvingAdellijkeTitel": None, + "omschrijvingGeslachtsaanduiding": "Man", + "opgemaakteNaam": None, + "overlijdensdatum": None, + "voornamen": "Thomas", + "voorvoegselGeslachtsnaam": None, + }, + { + "adellijkeTitelPredikaat": None, + "bsn": "345678901", + "geboorteLand": "5012", + "geboortedatum": date(1961, 1, 1), + "indicatieGeboortedatum": None, + "geboortelandnaam": "Iran", + "geboorteplaats": "Teheran", + "geboorteplaatsnaam": "Teheran", + "geslachtsaanduiding": "V", + "geslachtsnaam": "Visser", + "omschrijvingAdellijkeTitel": None, + "omschrijvingGeslachtsaanduiding": "Vrouw", + "opgemaakteNaam": None, + "overlijdensdatum": None, + "voornamen": "Iep", + "voorvoegselGeslachtsnaam": None, + }, + ], + "persoon": { + "aanduidingNaamgebruik": "E", + "aanduidingNaamgebruikOmschrijving": "Eigen geslachtsnaam", + "bsn": "000000001", + "codeGemeenteVanInschrijving": 363, + "codeLandEmigratie": None, + "datumVertrekUitNederland": None, + "geboortedatum": date(1968, 1, 1), + "indicatieGeboortedatum": None, + "geboortelandnaam": "Nederland", + "geboorteLand": "6030", + "geboorteplaats": "947", + "geboorteplaatsnaam": "Neer", + "gemeentenaamInschrijving": "Amsterdam", + "geslachtsaanduiding": "M", + "geslachtsnaam": "Boer", + "mokum": True, + "nationaliteiten": [{"code": 1, "omschrijving": "Nederlandse"}], + "omschrijvingAdellijkeTitel": "Ridder", + "omschrijvingBurgerlijkeStaat": "Gehuwd", + "omschrijvingGeslachtsaanduiding": "Man", + "omschrijvingIndicatieGeheim": "Geen beperking", + "indicatieGeheim": False, + "opgemaakteNaam": "J. den Boer", + "vertrokkenOnbekendWaarheen": False, + "voornamen": "Johannes", + "voorvoegselGeslachtsnaam": "den", + "adresInOnderzoek": "080000", # Value provided by adrins.extraelement.aanduidingGegevensInOnderzoek + }, + "verbintenis": {}, + "verbintenisHistorisch": [ + { + "datumOntbinding": None, + "datumSluiting": date(2000, 1, 1), + "landnaamSluiting": "Nederland", "persoon": { - "aanduidingNaamgebruik": "E", - "aanduidingNaamgebruikOmschrijving": "Eigen geslachtsnaam", - "bsn": "000000001", - "codeGemeenteVanInschrijving": 363, - "codeLandEmigratie": None, - "datumVertrekUitNederland": None, - "geboortedatum": date(1968, 1, 1), + "adellijkeTitelPredikaat": None, + "bsn": "234567890", + "geboortedatum": date(1970, 1, 1), "indicatieGeboortedatum": None, "geboortelandnaam": "Nederland", - "geboorteLand": "6030", - "geboorteplaats": "947", "geboorteplaatsnaam": "Neer", - "gemeentenaamInschrijving": "Amsterdam", - "geslachtsaanduiding": "M", - "geslachtsnaam": "Boer", - "mokum": True, - "nationaliteiten": [{"code": 1, "omschrijving": "Nederlandse"}], - "omschrijvingAdellijkeTitel": "Ridder", - "omschrijvingBurgerlijkeStaat": "Gehuwd", - "omschrijvingGeslachtsaanduiding": "Man", - "omschrijvingIndicatieGeheim": "Geen beperking", - "indicatieGeheim": False, - "opgemaakteNaam": "J. den Boer", - "vertrokkenOnbekendWaarheen": False, - "voornamen": "Johannes", - "voorvoegselGeslachtsnaam": "den", - "adresInOnderzoek": "080000", # Value provided by adrins.extraelement.aanduidingGegevensInOnderzoek + "geslachtsaanduiding": "V", + "geslachtsnaam": "Bakker", + "omschrijvingAdellijkeTitel": "Jonkvrouw", + "omschrijvingGeslachtsaanduiding": "Vrouw", + "opgemaakteNaam": None, + "overlijdensdatum": None, + "voornamen": "Wilhelmina", + "voorvoegselGeslachtsnaam": "van", }, - "verbintenis": {}, - "verbintenisHistorisch": [ - { - "datumOntbinding": None, - "datumSluiting": date(2000, 1, 1), - "landnaamSluiting": "Nederland", - "persoon": { - "adellijkeTitelPredikaat": None, - "bsn": "234567890", - "geboortedatum": date(1970, 1, 1), - "indicatieGeboortedatum": None, - "geboortelandnaam": "Nederland", - "geboorteplaatsnaam": "Neer", - "geslachtsaanduiding": "V", - "geslachtsnaam": "Bakker", - "omschrijvingAdellijkeTitel": "Jonkvrouw", - "omschrijvingGeslachtsaanduiding": "Vrouw", - "opgemaakteNaam": None, - "overlijdensdatum": None, - "voornamen": "Wilhelmina", - "voorvoegselGeslachtsnaam": "van", - }, - "plaatsnaamSluitingOmschrijving": "Amsterdam", - "soortVerbintenis": None, - "soortVerbintenisOmschrijving": "Huwelijk", - "redenOntbindingOmschrijving": "Overlijden", - } - ], + "plaatsnaamSluitingOmschrijving": "Amsterdam", + "soortVerbintenis": None, + "soortVerbintenisOmschrijving": "Huwelijk", + "redenOntbindingOmschrijving": "Overlijden", } + ], +} + + +class Model0204Tests(TestCase): + def get_result(self): + self.maxDiff = None + return BRP_RESPONSE def test_response(self): with open(RESPONSE_PATH) as fp: diff --git a/app/test_gba.py b/app/test_gba.py index 9851582..d70494c 100644 --- a/app/test_gba.py +++ b/app/test_gba.py @@ -10,7 +10,7 @@ from app.model.gba import ( lookup_landen, lookup_gemeenten, - lookup_prsidb_soort_code, + lookup_persoonidb_soort_code, lookup_nationaliteiten, ) # noqa: E402 @@ -23,7 +23,7 @@ def test_gemeenten_lookup(self): self.assertEqual(lookup_gemeenten["0363"], "Amsterdam") def test_prsidb_soort_code_lookup(self): - self.assertEqual(lookup_prsidb_soort_code[1], "paspoort") + self.assertEqual(lookup_persoonidb_soort_code[1], "paspoort") def test_nationaliteiten_lookup(self): self.assertEqual(lookup_nationaliteiten["0336"], "Syrische") diff --git a/app/test_server.py b/app/test_server.py index 30fffc3..f274c7a 100644 --- a/app/test_server.py +++ b/app/test_server.py @@ -3,9 +3,10 @@ from unittest.mock import patch from app.auth import PROFILE_TYPE_COMMERCIAL, FlaskServerTestCase +from app.helpers import remove_attr from app.server import app from app.test_mks_client_bsn_hr import get_bsn_xml_response_fixture - +from .test_02_04_model import RESPONSE_PATH, BRP_RESPONSE from .test_mks_client_kvk_mac_hr import ( KVK_HR_MAC_RESPONSE, get_kvk_mac_xml_response_fixture, @@ -17,6 +18,11 @@ from .test_mks_client_nnp_hr import NNP_HR_RESPONSE, get_nnp_xml_response_fixture +def get_bsn_xml_brp_response_fixture(): + with open(RESPONSE_PATH, "rb") as response_file: + return response_file.read().decode("utf-8") + + def wrap_response(response_data, status: str = "OK"): return { "content": json.loads(json.dumps(response_data, default=str)), @@ -43,10 +49,13 @@ def test_status(self): '{"content":{"buildId":"999","gitSha":"abcdefghijk","otapEnv":"unittesting"},"status":"OK"}\n', ) - def _get_expected_private(self): + def _get_expected_private_hr(self): return wrap_response(KVK_HR_EENMANSZAAK_RESPONSE) - def _get_expected_commercial(self): + def _get_expected_private(self): + return wrap_response(BRP_RESPONSE["persoon"]) + + def _get_expected_commercial_hr(self): return wrap_response({**KVK_HR_MAC_RESPONSE, **NNP_HR_RESPONSE}) @patch( @@ -61,7 +70,17 @@ def test_bsn(self): response = self.get_secure("/brp/hr") self.assertEqual(response.status_code, 200) - self.assertEqual(response.json, self._get_expected_private()) + self.assertEqual(response.json, self._get_expected_private_hr()) + + @patch( + "app.service.mks_client_02_04.get_0204_raw", + lambda bsn: get_bsn_xml_brp_response_fixture(), + ) + def test_brp_show_bsn(self): + response = self.get_secure("/brp/brp") + self.assertEqual(response.status_code, 200) + supposed_result = self._get_expected_private()["content"] + self.assertEqual(response.json["content"]["persoon"], supposed_result) @patch( "app.service.mks_client_hr.HR_URL", @@ -78,7 +97,7 @@ def test_bsn(self): def test_get_mac_hr(self): response = self.get_secure("/brp/hr", profile_type=PROFILE_TYPE_COMMERCIAL) self.assertEqual(response.status_code, 200) - self.assertEqual(response.json, self._get_expected_commercial()) + self.assertEqual(response.json, self._get_expected_commercial_hr()) @patch( "app.service.mks_client_hr._get_response_by_kvk_number", @@ -87,3 +106,29 @@ def test_get_mac_hr(self): def test_empty(self): response = self.get_secure("/brp/hr", profile_type=PROFILE_TYPE_COMMERCIAL) self.assertEqual(response.status_code, 200) + + +@patch( + "app.server.IS_SHOW_BSN_ENABLED", + False, +) +class ApiTestsBSNRemoved(FlaskServerTestCase): + + app = app + + @patch( + "app.service.mks_client_02_04.get_0204_raw", + lambda bsn: get_bsn_xml_brp_response_fixture(), + ) + def test_brp_show_bsn(self): + response = self.get_secure("/brp/brp") + self.assertEqual(response.status_code, 200) + + self.assertRaises(KeyError, lambda: response.json["content"]["persoon"]["bsn"]) + + def test_remove_attr(self): + obj = {"bsn": "xxx", "kids": [{"bsn": "xxx", "grandkids": [{"bsn": "xxx"}]}]} + + remove_attr(obj, "bsn") + + self.assertEqual(obj, {"kids": [{"grandkids": [{}]}]})