diff --git a/src/registry_schemas/example_data/mhr/__init__.py b/src/registry_schemas/example_data/mhr/__init__.py index afa9acf..dcf9638 100644 --- a/src/registry_schemas/example_data/mhr/__init__.py +++ b/src/registry_schemas/example_data/mhr/__init__.py @@ -17,6 +17,7 @@ """ from .schema_data import ( ADDRESS, + ADMIN_REGISTRATION, BASE_INFORMATION, DESCRIPTION, DRAFT_SUMMARY, @@ -44,6 +45,7 @@ __all__ = [ 'ADDRESS', + 'ADMIN_REGISTRATION', 'BASE_INFORMATION', 'DESCRIPTION', 'DRAFT_SUMMARY', diff --git a/src/registry_schemas/example_data/mhr/schema_data.py b/src/registry_schemas/example_data/mhr/schema_data.py index c4e196e..3313ea7 100644 --- a/src/registry_schemas/example_data/mhr/schema_data.py +++ b/src/registry_schemas/example_data/mhr/schema_data.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """Sample data used across many tests.""" +# pylint: disable=too-many-lines ADDRESS = { 'street': 'delivery_address - address line one', @@ -21,6 +22,33 @@ 'country': 'CA' } +ADMIN_REGISTRATION = { + 'mhrNumber': '004816', + 'registrationType': 'REG_STAFF_ADMIN', + 'clientReferenceId': 'EX-NRED-001', + 'attentionReference': 'JOHN SMITH', + 'createDateTime': '2022-10-21T18:56:00+00:00', + 'submittingParty': { + 'businessName': 'BOB PATERSON HOMES INC.', + 'address': { + 'street': '1200 S. MACKENZIE AVE.', + 'city': 'WILLIAMS LAKE', + 'region': 'BC', + 'country': 'CA', + 'postalCode': 'V2G 3Y1' + }, + 'phoneNumber': '6044620279', + 'emailAddress': 'bphomes@bphomes.com' + }, + 'documentType': 'NRED', + 'updateDocumentId': '62754188', + 'payment': { + 'receipt': '/pay/api/v1/payment-requests/2198744/receipts', + 'invoiceId': '2198744' + } +} + + BASE_INFORMATION = { 'year': 2018, 'make': 'WATSON IND. (ALTA)', @@ -583,7 +611,6 @@ } } - REGISTRATION_SUMMARY = [ { 'mhrNumber': '002000', diff --git a/src/registry_schemas/schemas/mhr/adminRegistration.json b/src/registry_schemas/schemas/mhr/adminRegistration.json new file mode 100644 index 0000000..0c9a526 --- /dev/null +++ b/src/registry_schemas/schemas/mhr/adminRegistration.json @@ -0,0 +1,54 @@ +{ + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://bcrs.gov.bc.ca/.well_known/schemas/mhr/adminRegistration", + "type": "object", + "title": "The MHR staff administration registration Schema", + "properties": { + "mhrNumber": { + "type": [ "string", "null" ], + "maxLength": 6, + "description": "Unique manufactured home registration number assigned by the Manufactured Home Registry when a registration is created." + }, + "registrationType": { + "type": "string", + "maxLength": 20, + "enum": ["DECAL_REPLACE", "EXEMPTION_RES", "EXEMPTION_NON_RES", "MHREG", "MHREG_CONVERSION", "PERMIT", "PERMIT_EXTENSION", "TRANS", "TRAND", "TRANS_AFFIDAVIT", "TRANS_ADMIN", "TRANS_WILL", "REG_STAFF_ADMIN"] + }, + "clientReferenceId": { + "type": [ "string", "null" ], + "maxLength": 50, + "description": "An optional client reference identifier associated with a change. Provided to facilitate client tracking of MHR activity." + }, + "attentionReference": { + "type": [ "string", "null" ], + "maxLength": 50, + "description": "The registration document attention or reference information." + }, + "submittingParty": { + "$ref": "https://bcrs.gov.bc.ca/.well_known/schemas/common/party" + }, + "createDateTime": { + "type": [ "string", "null" ], + "format": "date-time", + "description": "Generated by the MHR system and included in a response, the date and time a record is created in the system in the ISO 8601 format YYYY-MM-DDThh:mm:ssTZD." + }, + "documentType": { + "type": "string", + "maxLength": 20, + "enum": ["COU", "COUR", "EXRE", "FZE", "NREG", "THAW", "ABAN", "ATTA", "ADDI", "BANK", "COMP", "CONF", "DNCH", "FORE", "GENT", "MAID", "MAIL", "MARR", "MEAM", "NAMV", "PUBA", "REBU", "REIV", "REPV", "SZL", "TAXS", "VEST", "WHAL"] + }, + "updateDocumentId": { + "type": [ "string", "null" ], + "maxLength": 8, + "description": "Only required with NRED and COUR document type requests. It is the document ID of a previously created registration that is being cancelled or updated." + }, + "payment": { + "$ref": "https://bcrs.gov.bc.ca/.well_known/schemas/common/paymentReference" + } + }, + "required": [ + "submittingParty", + "documentType" + ] +} \ No newline at end of file diff --git a/src/registry_schemas/schemas/mhr/note.json b/src/registry_schemas/schemas/mhr/note.json index 26fa715..2866dc7 100644 --- a/src/registry_schemas/schemas/mhr/note.json +++ b/src/registry_schemas/schemas/mhr/note.json @@ -20,6 +20,11 @@ "maxLength": 8, "description": "The unique document registration number for the registration associated with the note." }, + "documentDescription": { + "type": "string", + "maxLength": 100, + "description": "The description of the document type." + }, "createDateTime": { "type": "string", "format": "date-time", @@ -52,6 +57,22 @@ "destroyed": { "type": "boolean", "description": "True if the unit note has been destroyed. Set by the system and included in API responses." + }, + "cancelledDocumentType": { + "type": "string", + "minLength": 1, + "maxLength": 10, + "description": "Conditionally included with the NCAN document type as the document type for the unit note registration that has been cancelled." + }, + "cancelledDocumentDescription": { + "type": "string", + "maxLength": 100, + "description": "Conditionally included with the NCAN document type as the document type description for the unit note registration that has been cancelled." + }, + "cancelledDocumentRegistrationNumber": { + "type": [ "string", "null" ], + "maxLength": 8, + "description": "Conditionally included with the NCAN document type as the unique document registration number for the unit note registration that has been cancelled." } }, "required": [ diff --git a/src/registry_schemas/schemas/mhr/noteRegistration.json b/src/registry_schemas/schemas/mhr/noteRegistration.json index 33f8352..73901cb 100644 --- a/src/registry_schemas/schemas/mhr/noteRegistration.json +++ b/src/registry_schemas/schemas/mhr/noteRegistration.json @@ -36,6 +36,11 @@ "note": { "$ref": "https://bcrs.gov.bc.ca/.well_known/schemas/mhr/note" }, + "cancelDocumentId": { + "type": [ "string", "null" ], + "maxLength": 8, + "description": "Only included in requests for the NCAN document type, the document ID of the previously created unit note registration that is being cancelled." + }, "payment": { "$ref": "https://bcrs.gov.bc.ca/.well_known/schemas/common/paymentReference" } diff --git a/src/registry_schemas/schemas/mhr/registrationSummary.json b/src/registry_schemas/schemas/mhr/registrationSummary.json index 7e5d9c1..4626103 100644 --- a/src/registry_schemas/schemas/mhr/registrationSummary.json +++ b/src/registry_schemas/schemas/mhr/registrationSummary.json @@ -83,6 +83,17 @@ "expireDays": { "type": "integer", "description": "Conditionally included for the CAU, CAUC, and CAUE caution document types. The value may be negative, and represents the number of days from the current timestamp before a caution unit note registration expires. For CAUC regisrations that have no expiry date, the unreachable value of -9999 is returned." + }, + "cancelledDocumentType": { + "type": "string", + "minLength": 1, + "maxLength": 10, + "description": "Conditionally included with the NCAN document type registration as the document type for the unit note registration that has been cancelled." + }, + "cancelledDocumentDescription": { + "type": "string", + "maxLength": 100, + "description": "Conditionally included with the NCAN document type registration as the document type description for the unit note registration that has been cancelled." } }, "required": [ diff --git a/src/registry_schemas/version.py b/src/registry_schemas/version.py index 2420d2d..df31ef1 100644 --- a/src/registry_schemas/version.py +++ b/src/registry_schemas/version.py @@ -22,4 +22,4 @@ Development release segment: .devN """ -__version__ = '1.7.7' # pylint: disable=invalid-name +__version__ = '1.7.8' # pylint: disable=invalid-name diff --git a/tests/unit/mhr/test_admin_registration.py b/tests/unit/mhr/test_admin_registration.py new file mode 100644 index 0000000..1d36d1a --- /dev/null +++ b/tests/unit/mhr/test_admin_registration.py @@ -0,0 +1,71 @@ +# Copyright © 2020 Province of British Columbia +# +# 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. +"""Test Suite to ensure the MHR transport permit registration schema is valid.""" +import copy + +import pytest + +from registry_schemas import validate +from registry_schemas.example_data.mhr import ADMIN_REGISTRATION + + +LONG_CLIENT_REF = '012345678901234567890123456789012345678901234567890' +# testdata pattern is ({desc},{valid},{doc_type},{has_submitting},{is_request},{client_ref}, {attention}) +TEST_DATA = [ + ('Valid request', True, 'COUR', True, True, None, None), + ('Valid response', True, 'THAW', True, False, '1234', 'JOHN SMITH'), + ('Invalid client ref', False, 'NRED', True, True, LONG_CLIENT_REF, None), + ('Invalid attention', False, 'EXRE', True, True, None, LONG_CLIENT_REF), + ('Invalid missing doc type', False, None, True, True, None, None), + ('Invalid doc type', False, 'TAXN', True, True, None, None), + ('Invalid missing sub party', False, 'NRED', False, True, None, None), + ('Invalid update doc id', False, 'NRED', True, True, None, None) +] + + +@pytest.mark.parametrize('desc,valid,doc_type,has_sub,is_request,client_ref,attention', TEST_DATA) +def test_note_registration(desc, valid, doc_type, has_sub, is_request, client_ref, attention): + """Assert that the staff admin registration schema is performing as expected.""" + data = copy.deepcopy(ADMIN_REGISTRATION) + if not doc_type: + del data['documentType'] + else: + data['documentType'] = doc_type + if not has_sub: + del data['submittingParty'] + if client_ref: + data['clientReferenceId'] = client_ref + else: + del data['clientReferenceId'] + if attention: + data['attentionReference'] = attention + else: + del data['attentionReference'] + if is_request: + del data['mhrNumber'] + del data['createDateTime'] + del data['payment'] + del data['registrationType'] + if desc == 'Invalid update doc id': + data['updateDocumentId'] = '123456789' + is_valid, errors = validate(data, 'adminRegistration', 'mhr') + + if errors: + for err in errors: + print(err.message) + + if valid: + assert is_valid + else: + assert not is_valid diff --git a/tests/unit/mhr/test_note_registration.py b/tests/unit/mhr/test_note_registration.py index f004afb..cb62263 100644 --- a/tests/unit/mhr/test_note_registration.py +++ b/tests/unit/mhr/test_note_registration.py @@ -30,6 +30,12 @@ ('Invalid missing note', False, False, True, True, None, None), ('Invalid missing sub party', False, True, False, True, None, None) ] +# testdata pattern is ({desc},{valid},{cancel_doc_id},{is_request},{doc_type}, {doc_reg_num}, {doc_desc}) +TEST_DATA_CANCEL = [ + ('Valid request', True, '12345678', True, None, None, None), + ('Valid response', True, None, False, 'CAU', '00545678', 'NOTICE OF CAUTION'), + ('Invalid request doc id', False, '123456789', True, None, None, None) +] @pytest.mark.parametrize('desc,valid,has_note,has_sub,is_request,client_ref,attention', TEST_DATA) @@ -69,3 +75,32 @@ def test_note_registration(desc, valid, has_note, has_sub, is_request, client_re assert is_valid else: assert not is_valid + + +@pytest.mark.parametrize('desc,valid,cancel_doc_id,is_request,doc_type,doc_reg_num,doc_desc', TEST_DATA_CANCEL) +def test_ncan_registration(desc, valid, cancel_doc_id, is_request, doc_type, doc_reg_num, doc_desc): + """Assert that the unit note registration schema is performing as expected.""" + data = copy.deepcopy(NOTE_REGISTRATION) + if cancel_doc_id: + data['cancelDocumentId'] = cancel_doc_id + if doc_type: + data['note']['cancelledDocumentType'] = doc_type + if doc_reg_num: + data['note']['cancelledDocumentRegistrationNumber'] = doc_reg_num + if doc_desc: + data['note']['cancelledDocumentDescription'] = doc_desc + if is_request: + del data['mhrNumber'] + del data['createDateTime'] + del data['payment'] + del data['registrationType'] + is_valid, errors = validate(data, 'noteRegistration', 'mhr') + + if errors: + for err in errors: + print(err.message) + + if valid: + assert is_valid + else: + assert not is_valid