From e6ee574f5ec3b59f26702c0537dc6504f2041125 Mon Sep 17 00:00:00 2001 From: Lekshmi Date: Thu, 25 Jun 2020 16:02:13 -0700 Subject: [PATCH] Conversion filing - Schema changes (#34) * Conversion schema * More changes * Pylint and Flake8 fixes --- src/registry_schemas/example_data/__init__.py | 6 +- .../example_data/schema_data.py | 179 +++++++++++++++++- src/registry_schemas/schemas/conversion.json | 47 +++++ src/registry_schemas/schemas/filing.json | 6 +- src/registry_schemas/version.py | 2 +- tests/unit/schema_data.py | 3 +- tests/unit/test_conversion.py | 153 +++++++++++++++ tests/unit/test_filings.py | 26 +++ 8 files changed, 417 insertions(+), 5 deletions(-) create mode 100644 src/registry_schemas/schemas/conversion.json create mode 100644 tests/unit/test_conversion.py diff --git a/src/registry_schemas/example_data/__init__.py b/src/registry_schemas/example_data/__init__.py index c43312a..8dd63ad 100644 --- a/src/registry_schemas/example_data/__init__.py +++ b/src/registry_schemas/example_data/__init__.py @@ -26,6 +26,8 @@ CHANGE_OF_NAME, COMMENT_BUSINESS, COMMENT_FILING, + CONVERSION, + CONVERSION_FILING_TEMPLATE, CORP_CHANGE_OF_ADDRESS, CORRECTION_AR, CORRECTION_COA, @@ -63,5 +65,7 @@ 'INCORPORATION_FILING_TEMPLATE', 'SPECIAL_RESOLUTION', 'STUB_FILING', - 'VOLUNTARY_DISSOLUTION' + 'VOLUNTARY_DISSOLUTION', + 'CONVERSION', + 'CONVERSION_FILING_TEMPLATE' ] diff --git a/src/registry_schemas/example_data/schema_data.py b/src/registry_schemas/example_data/schema_data.py index 019f6cf..f1e7895 100644 --- a/src/registry_schemas/example_data/schema_data.py +++ b/src/registry_schemas/example_data/schema_data.py @@ -12,7 +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 import copy @@ -913,6 +913,162 @@ } } + +CONVERSION = { + 'nameRequest': { + 'legalType': 'BC' + }, + 'offices': { + 'registeredOffice': { + 'deliveryAddress': { + 'streetAddress': 'delivery_address - address line one', + 'addressCity': 'delivery_address city', + 'addressCountry': 'CA', + 'postalCode': 'H0H0H0', + 'addressRegion': 'BC' + }, + 'mailingAddress': { + 'streetAddress': 'mailing_address - address line one', + 'addressCity': 'mailing_address city', + 'addressCountry': 'CA', + 'postalCode': 'H0H0H0', + 'addressRegion': 'BC', + } + }, + 'recordsOffice': { + 'deliveryAddress': { + 'streetAddress': 'delivery_address - address line one', + 'addressCity': 'delivery_address city', + 'addressCountry': 'CA', + 'postalCode': 'H0H0H0', + 'addressRegion': 'BC' + }, + 'mailingAddress': { + 'streetAddress': 'mailing_address - address line one', + 'addressCity': 'mailing_address city', + 'addressCountry': 'CA', + 'postalCode': 'H0H0H0', + 'addressRegion': 'BC', + } + } + }, + 'parties': [ + { + 'officer': { + 'id': 1, + 'firstName': 'Joe', + 'lastName': 'Swanson', + 'middleName': 'P', + 'email': 'joe@email.com', + 'orgName': '', + 'partyType': 'person' + }, + 'mailingAddress': { + 'streetAddress': 'mailing_address - address line one', + 'streetAddressAdditional': '', + 'addressCity': 'mailing_address city', + 'addressCountry': 'CA', + 'postalCode': 'H0H0H0', + 'addressRegion': 'BC' + }, + 'deliveryAddress': { + 'streetAddress': 'delivery_address - address line one', + 'streetAddressAdditional': '', + 'addressCity': 'delivery_address city', + 'addressCountry': 'CA', + 'postalCode': 'H0H0H0', + 'addressRegion': 'BC' + }, + 'roles': [ + { + 'roleType': 'Completing Party', + 'appointmentDate': '2018-01-01' + + }, + { + 'roleType': 'Director', + 'appointmentDate': '2018-01-01' + + } + ] + }, + { + 'officer': { + 'id': 2, + 'firstName': '', + 'lastName': '', + 'middleName': '', + 'orgName': 'Xyz Inc.', + 'partyType': 'org' + }, + 'mailingAddress': { + 'streetAddress': 'mailing_address - address line one', + 'streetAddressAdditional': '', + 'addressCity': 'mailing_address city', + 'addressCountry': 'CA', + 'postalCode': 'H0H0H0', + 'addressRegion': 'BC' + }, + 'roles': [ + { + 'roleType': 'Incorporator', + 'appointmentDate': '2018-01-01' + } + ] + } + ], + 'shareClasses': [ + { + 'id': 1, + 'name': 'Share Class 1', + 'priority': 1, + 'hasMaximumShares': True, + 'maxNumberOfShares': 100, + 'hasParValue': True, + 'parValue': 10, + 'currency': 'CAD', + 'hasRightsOrRestrictions': False, + 'series': [ + { + 'id': 1, + 'name': 'Share Series 1', + 'priority': 1, + 'hasMaximumShares': True, + 'maxNumberOfShares': 50, + 'hasRightsOrRestrictions': False, + }, + { + 'id': 2, + 'name': 'Share Series 2', + 'priority': 2, + 'hasMaximumShares': True, + 'maxNumberOfShares': 100, + 'hasRightsOrRestrictions': False, + } + ] + }, + { + 'id': 2, + 'name': 'Share Class 2', + 'priority': 1, + 'hasMaximumShares': False, + 'maxNumberOfShares': None, + 'hasParValue': False, + 'parValue': None, + 'currency': None, + 'hasRightsOrRestrictions': True, + 'series': [] + }, + ], + 'contactPoint': { + 'email': 'no_one@never.get', + 'phone': '123-456-7890' + }, + 'incorporationAgreement': { + 'agreementType': 'sample' + } +} + FILING_TEMPLATE = { 'filing': { 'header': { @@ -953,6 +1109,26 @@ } } +CONVERSION_FILING_TEMPLATE = { + 'filing': { + 'header': { + 'name': 'conversion', + 'date': '2020-06-25', + 'certifiedBy': 'full name', + 'email': 'no_one@never.get', + 'filingId': 1 + }, + 'business': { + 'foundingDate': '2018-01-01T00:00:00+00:00', + 'identifier': 'BC1234567', + 'lastLedgerTimestamp': '2019-04-15T20:05:49.068272+00:00', + 'legalName': 'legal name - BC1234567', + 'legalType': 'BC' + }, + 'conversion': CONVERSION + } +} + STUB_FILING = { } @@ -977,6 +1153,7 @@ ('appointReceiver', STUB_FILING), ('continuedOut', STUB_FILING), ('changeOfDirectors', CHANGE_OF_DIRECTORS_MAILING), # bcorp-specific version of filing + ('conversion', CONVERSION) ] diff --git a/src/registry_schemas/schemas/conversion.json b/src/registry_schemas/schemas/conversion.json new file mode 100644 index 0000000..e3077ef --- /dev/null +++ b/src/registry_schemas/schemas/conversion.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://bcrs.gov.bc.ca/.well_known/schemas/conversion", + "required": [ + "nameRequest", + "offices", + "parties", + "shareClasses", + "contactPoint" + ], + "type": "object", + "title": "Conversion Filing", + "properties": { + "nameRequest": { + "$ref": "https://bcrs.gov.bc.ca/.well_known/schemas/name_request" + }, + "offices": { + "registeredOffice": { + "$ref": "https://bcrs.gov.bc.ca/.well_known/schemas/office" + }, + "recordsOffice": { + "$ref": "https://bcrs.gov.bc.ca/.well_known/schemas/office" + }, + "required": [ + "registeredOffice" + ] + }, + "parties": { + "type": "array", + "items": { + "$ref": "https://bcrs.gov.bc.ca/.well_known/schemas/parties#/definitions/party" + } + }, + "shareClasses": { + "type": "array", + "items": { + "$ref": "https://bcrs.gov.bc.ca/.well_known/schemas/share_class#/definitions/shareClass" + } + }, + "contactPoint" : { + "$ref": "https://bcrs.gov.bc.ca/.well_known/schemas/contactPoint" + }, + "incorporationAgreement": { + "$ref": "https://bcrs.gov.bc.ca/.well_known/schemas/agreementType" + } + } +} diff --git a/src/registry_schemas/schemas/filing.json b/src/registry_schemas/schemas/filing.json index 5fd7d10..688a7d0 100644 --- a/src/registry_schemas/schemas/filing.json +++ b/src/registry_schemas/schemas/filing.json @@ -72,7 +72,8 @@ "voluntaryLiquidation", "appointReceiver", "continuedOut", - "correction" + "correction", + "conversion" ] }, "availableOnPaperOnly": { @@ -227,6 +228,9 @@ { "title": "Placeholder until all filing types are defined.", "$ref": "https://bcrs.gov.bc.ca/.well_known/schemas/stub_filing" + }, + { + "$ref": "https://bcrs.gov.bc.ca/.well_known/schemas/conversion" } ] } diff --git a/src/registry_schemas/version.py b/src/registry_schemas/version.py index e0752fb..b2b7cad 100644 --- a/src/registry_schemas/version.py +++ b/src/registry_schemas/version.py @@ -22,4 +22,4 @@ Development release segment: .devN """ -__version__ = '2.5.13' # pylint: disable=invalid-name +__version__ = '2.5.14' # pylint: disable=invalid-name diff --git a/tests/unit/schema_data.py b/tests/unit/schema_data.py index d3eed0a..1412929 100644 --- a/tests/unit/schema_data.py +++ b/tests/unit/schema_data.py @@ -38,5 +38,6 @@ ('task.json'), ('todo.json'), ('voluntary_dissolution.json'), - ('agreement_type.json') + ('agreement_type.json'), + ('conversion.json') ] diff --git a/tests/unit/test_conversion.py b/tests/unit/test_conversion.py new file mode 100644 index 0000000..8f70049 --- /dev/null +++ b/tests/unit/test_conversion.py @@ -0,0 +1,153 @@ +# Copyright © 2019 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 conversion schemas are valid.""" + +import copy + +from registry_schemas import validate +from registry_schemas.example_data import CONVERSION + + +def test_conversion_schema(): + """Assert that the JSONSchema validator is working.""" + is_valid, errors = validate(CONVERSION, 'conversion') + + if errors: + for err in errors: + print(err.message) + print(errors) + + assert is_valid + + +def test_validate_no_name_request(): + """Assert not valid if name request node is not present.""" + conversion_json = copy.deepcopy(CONVERSION) + del conversion_json['nameRequest'] + + is_valid, errors = validate(conversion_json, 'conversion') + + if errors: + for err in errors: + print(err.message) + print(errors) + + assert not is_valid + + +def test_validate_invalid_name_request_type(): + """Assert not valid if legalType is not an accepted type.""" + conversion_json = copy.deepcopy(CONVERSION) + conversion_json['nameRequest']['legalType'] = 'ZZ' + + is_valid, errors = validate(conversion_json, 'conversion') + + if errors: + for err in errors: + print(err.message) + print(errors) + + assert not is_valid + + +def test_validate_no_offices(): + """Assert not valid if the required offices are not present.""" + conversion_json = copy.deepcopy(CONVERSION) + del conversion_json['offices']['registeredOffice'] + + is_valid, errors = validate(conversion_json, 'conversion') + + if errors: + for err in errors: + print(err.message) + print(errors) + + assert not is_valid + + +def test_validate_no_contact(): + """Assert not valid if the required contact info is not present.""" + conversion_json = copy.deepcopy(CONVERSION) + del conversion_json['contactPoint'] + + is_valid, errors = validate(conversion_json, 'conversion') + + if errors: + for err in errors: + print(err.message) + print(errors) + + assert not is_valid + + +def test_validate_no_parties(): + """Assert not valid if parties are omitted.""" + conversion_json = copy.deepcopy(CONVERSION) + del conversion_json['parties'] + + is_valid, errors = validate(conversion_json, 'conversion') + + if errors: + for err in errors: + print(err.message) + print(errors) + + assert not is_valid + + +def test_validate_party_type(): + """Assert party types are required.""" + conversion_json = copy.deepcopy(CONVERSION) + + del conversion_json['parties'][0]['officer']['partyType'] + + is_valid, errors = validate(conversion_json, 'conversion') + + if errors: + for err in errors: + print(err.message) + + print(errors) + + assert not is_valid + + +def test_validate_no_share_classes(): + """Assert not valid if share classes are not present.""" + conversion_json = copy.deepcopy(CONVERSION) + del conversion_json['shareClasses'] + + is_valid, errors = validate(conversion_json, 'conversion') + + if errors: + for err in errors: + print(err.message) + print(errors) + + assert not is_valid + + +def test_validate_share_classes_no_name(): + """Assert not valid if mandatory fields are not present.""" + conversion_json = copy.deepcopy(CONVERSION) + del conversion_json['shareClasses'][0]['name'] + + is_valid, errors = validate(conversion_json, 'conversion') + + if errors: + for err in errors: + print(err.message) + print(errors) + + assert not is_valid diff --git a/tests/unit/test_filings.py b/tests/unit/test_filings.py index ba937f2..67eec6e 100644 --- a/tests/unit/test_filings.py +++ b/tests/unit/test_filings.py @@ -27,6 +27,7 @@ CHANGE_OF_ADDRESS, CHANGE_OF_DIRECTORS, CHANGE_OF_DIRECTORS_MAILING, + CONVERSION_FILING_TEMPLATE, CORP_CHANGE_OF_ADDRESS, FILING_HEADER, INCORPORATION_FILING_TEMPLATE, @@ -365,3 +366,28 @@ def test_incorporation_filing_schema(): print(errors) assert is_valid + + +def test_conversion_filing_schema(): + """Assert that the JSONSchema validator is working.""" + is_valid, errors = validate(CONVERSION_FILING_TEMPLATE, 'filing') + + if errors: + for err in errors: + print(err.message) + print(errors) + + assert is_valid + + +def test_invalid_conversion_filing_schema_with_no_business(): + """Assert that the JSONSchema validator is working.""" + conversion_json = CONVERSION_FILING_TEMPLATE + del conversion_json['filing']['business'] + is_valid, errors = validate(conversion_json, 'filing') + if errors: + for err in errors: + print(err.message) + print(errors) + + assert not is_valid