diff --git a/legal-api/pyproject.toml b/legal-api/pyproject.toml
index 6a0c91de97..8f30f852c9 100644
--- a/legal-api/pyproject.toml
+++ b/legal-api/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "legal-api"
-version = "3.0.0"
+version = "3.0.1"
description = ""
authors = [
{name = "thor",email = "1042854+thorwolpert@users.noreply.github.com"}
diff --git a/legal-api/report-templates/template-parts/common/businessDetails.html b/legal-api/report-templates/template-parts/common/businessDetails.html
index 288d85ddc6..f981e20481 100644
--- a/legal-api/report-templates/template-parts/common/businessDetails.html
+++ b/legal-api/report-templates/template-parts/common/businessDetails.html
@@ -361,12 +361,7 @@
{% endif %}
-
-{% if reportType == 'summary' %}
-
Information current as of {{report_date_time}}
-{% else %}
- Document retrieved on {{report_date_time}}
-{% endif %}
+
diff --git a/legal-api/src/legal_api/core/filing.py b/legal-api/src/legal_api/core/filing.py
index 3c450e43cc..440f831be1 100644
--- a/legal-api/src/legal_api/core/filing.py
+++ b/legal-api/src/legal_api/core/filing.py
@@ -26,6 +26,7 @@
from legal_api.core.meta import FilingMeta
from legal_api.models import Business, Document, DocumentType, UserRoles
from legal_api.models import Filing as FilingStorage
+from legal_api.reports.document_service import DocumentService
from legal_api.services import VersionedBusinessDetailsService
from legal_api.services.authz import has_roles, is_competent_authority
@@ -402,6 +403,9 @@ def ledger(business_id: int, # noqa: PLR0913
query = query.order_by(desc(FilingStorage.filing_date))
+ drs_service: DocumentService = DocumentService()
+ drs_docs = drs_service.get_documents_by_business_id(business.identifier) if business else []
+
ledger = []
for filing in query.all():
@@ -443,6 +447,10 @@ def ledger(business_id: int, # noqa: PLR0913
if filing.court_order_file_number or filing.order_details:
Filing._add_ledger_order(filing, ledger_filing)
+ core_filing: Filing = Filing() # Filing.get_document_list needs a core Filing.
+ core_filing._storage = filing # pylint: disable=protected-access
+ filing_docs = Filing.get_document_list(business, core_filing, jwt)
+ ledger_filing["documents"] = drs_service.update_filing_documents(drs_docs, filing_docs, filing)
ledger.append(ledger_filing)
return ledger
@@ -480,7 +488,7 @@ def _add_ledger_order(filing: FilingStorage, ledger_filing: dict) -> dict:
ledger_filing["data"]["order"] = court_order_data
@staticmethod
- def get_document_list(business, # noqa: PLR0912
+ def get_document_list(business, # noqa: PLR0912, PLR0915 NOSONAR(S3776)
filing,
jwt: JwtManager) -> dict | None:
"""Return a list of documents for a particular filing."""
@@ -512,7 +520,6 @@ def get_document_list(business, # noqa: PLR0912
identifier = withdrawn_filing.storage.temp_reg
doc_url = url_for("API2.get_documents", identifier=identifier, filing_id=filing.id, legal_filing_name=None)
-
documents = {"documents": {}}
# for paper_only filings return and empty documents list
if filing.storage and filing.storage.paper_only:
@@ -531,6 +538,8 @@ def get_document_list(business, # noqa: PLR0912
Document.type == DocumentType.COURT_ORDER.value).one_or_none()):
documents["documents"]["uploadedCourtOrder"] = f"{base_url}{doc_url}/uploadedCourtOrder"
documents["documents"]["receipt"] = f"{base_url}{doc_url}/receipt"
+ elif filing.storage and filing.storage.source == filing.storage.Source.COLIN.value:
+ documents["documents"]["receipt"] = f"{base_url}{doc_url}/receipt"
no_outputs_except_receipt = filing.filing_type in [
Filing.FilingTypes.CHANGEOFLIQUIDATORS.value,
@@ -568,10 +577,13 @@ def get_document_list(business, # noqa: PLR0912
del documents["documents"]["receipt"]
return documents
+ legal_filings = filing.storage.meta_data.get("legalFilings") if filing.storage.meta_data else None
+ if not legal_filings and filing.storage and filing.storage.source == filing.storage.Source.COLIN.value:
+ legal_filings = [filing.filing_type]
if (
filing.status in (Filing.Status.COMPLETED, Filing.Status.CORRECTED) and
filing.storage.meta_data and
- (legal_filings := filing.storage.meta_data.get("legalFilings"))
+ legal_filings
and not (no_outputs_except_receipt or no_outputs_except_receipt_dissolution)
):
legal_filings_copy = copy.deepcopy(legal_filings)
@@ -612,7 +624,6 @@ def get_document_list(business, # noqa: PLR0912
adds = [FilingMeta.get_all_outputs(business.legal_type, doc) for doc in legal_filings]
additional = {item for sublist in adds for item in sublist}
-
FilingMeta.alter_outputs(filing.storage, business, additional)
for doc in additional:
documents["documents"][doc] = f"{base_url}{doc_url}/{doc}"
diff --git a/legal-api/src/legal_api/reports/document_service.py b/legal-api/src/legal_api/reports/document_service.py
index ffdb6ddcc4..63e07fe22b 100644
--- a/legal-api/src/legal_api/reports/document_service.py
+++ b/legal-api/src/legal_api/reports/document_service.py
@@ -18,8 +18,58 @@
from flask import current_app, jsonify
from legal_api.exceptions import BusinessException
-from legal_api.models import Business, Document
+from legal_api.models import Business, Document, Filing
from legal_api.services import AccountService
+from legal_api.utils.base import BaseEnum
+
+BUSINESS_DOCS_PATH: str = "{url}/application-reports/history/{product}/{business_id}?includeDocuments=true"
+GET_REPORT_PATH: str = "{url}/application-reports/{product}/{drsId}"
+GET_REPORT_CERTIFIED_PATH: str = "{url}/application-reports/{product}/{drsId}?certifiedCopy=true"
+POST_REPORT_PATH: str = "{url}/application-reports/{product}/{bus_id}/{filing_id}/{report_type}"
+POST_REPORT_PARAMS: str = "?consumerFilingDate={filing_date}&consumerFilename={filename}"
+GET_DOCUMENT_PATH: str = "{url}/searches/{document_class}?documentServiceId={drs_id}"
+FILING_DOCS_PATH: str = "{url}/application-reports/events/{product}/{business_id}/{filing_id}?includeDocuments=true"
+DRS_REPORT_PARAMS: str = "?reportType={report_type}&drsId={drs_id}"
+DRS_DOCUMENT_PARAMS: str = "?documentClass={document_class}&drsId={drs_id}"
+# Used for audit trail and db queries.
+BUSINESS_API_ACCOUNT_ID: str = "business-api"
+FILING_DOCUMENTS = {
+ "certifiedRules": {
+ "documentType": "COOP_RULES",
+ "documentClass": "COOP"
+ },
+ "certifiedMemorandum": {
+ "documentType": "COOP_MEMORANDUM",
+ "documentClass": "COOP"
+ },
+ "affidavit": {
+ "documentType": "CORP_AFFIDAVIT", # "COSD",
+ "documentClass": "CORP"
+ },
+ "uploadedCourtOrder": {
+ "documentType": "CRT",
+ "documentClass": "CORP"
+ }
+}
+STATIC_DOCUMENTS = {
+ "Unlimited Liability Corporation Information": {
+ "documentType": "DIRECTOR_AFFIDAVIT",
+ "documentClass": "CORP"
+ }
+}
+APP_JSON = "application/json"
+APP_PDF = "application/pdf"
+DOC_PATH = "/documents"
+BEARER = "Bearer "
+
+
+class ReportTypes(BaseEnum):
+ """Render an Enum of the document service report types."""
+
+ CERT = "CERT"
+ FILING = "FILING"
+ NOA = "NOA"
+ RECEIPT = "RECEIPT"
class DocumentService:
@@ -99,17 +149,13 @@ def create_document(
"""
if self.has_document(business_identifier, filing_identifier, report_type):
raise BusinessException("Document already exists", HTTPStatus.CONFLICT)
-
- token = AccountService.get_bearer_token()
- headers = {
- "Content-Type": "application/json",
- "X-ApiKey": self.api_key,
- "Account-Id": account_id,
- "Authorization": "Bearer " + token
- }
- post_url = (f"{self.url}/application-reports/"
+ headers = self._get_request_headers(account_id)
+ filename: str = f"{business_identifier}_{filing_identifier}_{report_type}.pdf"
+ url: str = self.url.replace(DOC_PATH, "")
+ post_url = (f"{url}/application-reports/"
f"{self.product_code}/{business_identifier}/"
- f"{filing_identifier}/{report_type}")
+ f"{filing_identifier}/{report_type}?consumerFiliename={filename}")
+ # Include filing date if available.
response = requests.post(url=post_url, headers=headers, data=binary_or_url)
content = self.get_content(response)
if response.status_code != HTTPStatus.CREATED:
@@ -117,7 +163,7 @@ def create_document(
self.create_document_record(
Business.find_by_identifier(business_identifier).id,
filing_identifier, report_type, content["identifier"],
- f"{business_identifier}_{filing_identifier}_{report_type}.pdf"
+ filename
)
return content, response.status_code
@@ -138,21 +184,16 @@ def get_document(
account_id: The account id.
return: The document url (or binary).
"""
- token = AccountService.get_bearer_token()
- headers = {
- "X-ApiKey": self.api_key,
- "Account-Id": account_id,
- "Content-Type": "application/pdf",
- "Authorization": "Bearer " + token
- }
+ headers = self._get_request_headers(account_id)
+ url: str = self.url.replace(DOC_PATH, "")
get_url = ""
if file_key is not None:
- get_url = f"{self.url}/application-reports/{self.product_code}/{file_key}"
+ get_url = f"{url}/application-reports/{self.product_code}/{file_key}"
else:
document = self.has_document(business_identifier, filing_identifier, report_type)
if document is False:
raise BusinessException("Document not found", HTTPStatus.NOT_FOUND)
- get_url = f"{self.url}/application-reports/{self.product_code}/{document.file_key}"
+ get_url = f"{url}/application-reports/{self.product_code}/{document.file_key}"
if get_url != "":
response = requests.get(url=get_url, headers=headers)
@@ -161,3 +202,256 @@ def get_document(
return jsonify(message=str(content)), response.status_code
return content, response.status_code
return jsonify(message="Document not found"), HTTPStatus.NOT_FOUND
+
+ def get_documents_by_business_id(self, business_identifier: str) -> list:
+ """
+ Get all available document information from the DRS by business identifier.
+
+ business_identifier: The business identifier.
+ return: The list of available filing reports and documents for the business, or [] if there is a problem.
+ """
+ try:
+ if not business_identifier:
+ return []
+ headers = self._get_request_headers(BUSINESS_API_ACCOUNT_ID)
+ url: str = self.url.replace(DOC_PATH, "")
+ get_url = BUSINESS_DOCS_PATH.format(url=url, product=self.product_code, business_id=business_identifier)
+ response = requests.get(url=get_url, headers=headers)
+ content = self.get_content(response)
+ if response.status_code not in (HTTPStatus.OK, HTTPStatus.NOT_FOUND):
+ current_app.logger.error(f"DRS call {get_url} failed status={response.status_code}: {content}")
+ return content if response.status_code == HTTPStatus.OK else []
+ except Exception:
+ return []
+
+ def get_documents_by_filing_id(self, business_identifier: str, filing_identifier: str) -> list:
+ """
+ Get all available document information from the DRS by filing identifier.
+
+ business_identifier: The business identifier.
+ filing_identifier: The filing identifier.
+ return: The list of available filing reports and documents for the filing, or [] if there is a problem or none.
+ """
+ try:
+ if not business_identifier or not filing_identifier:
+ return []
+ headers = self._get_request_headers(BUSINESS_API_ACCOUNT_ID)
+ url: str = self.url.replace(DOC_PATH, "")
+ get_url = FILING_DOCS_PATH.format(
+ url=url,
+ product=self.product_code,
+ business_id=business_identifier,
+ filing_id=filing_identifier
+ )
+ response = requests.get(url=get_url, headers=headers)
+ content = self.get_content(response)
+ if response.status_code not in (HTTPStatus.OK, HTTPStatus.NOT_FOUND):
+ current_app.logger.error(f"DRS call {get_url} failed status={response.status_code}: {content}")
+ return content if response.status_code == HTTPStatus.OK else []
+ except Exception:
+ return []
+
+ def update_document_list(self, drs_docs: list, document_list: list) -> list:
+ """
+ Update document_list urls with DRS information if a filing document maps to a DRS output or document.
+
+ drs_docs: The DRS reports/documents for the filing identifier.
+ document_list: The business list of reports/documents for the filing.
+ return: The updated list of filing reports and documents for the filing.
+ """
+ if not drs_docs or not document_list or not document_list.get("documents"):
+ return document_list
+ doc_list = document_list.get("documents")
+ for doc in drs_docs:
+ if doc.get("reportType") and doc.get("reportType") == "RECEIPT" and doc_list.get("receipt"):
+ query_params: str = DRS_REPORT_PARAMS.format(report_type="RECEIPT", drs_id=doc.get("identifier"))
+ doc_list["receipt"] = doc_list["receipt"] + query_params
+ elif doc.get("reportType") and doc.get("reportType") == "NOA" and doc_list.get("noticeOfArticles"):
+ query_params: str = DRS_REPORT_PARAMS.format(report_type="NOA", drs_id=doc.get("identifier"))
+ doc_list["noticeOfArticles"] = doc_list["noticeOfArticles"] + query_params
+ elif doc.get("reportType") and doc.get("reportType") == "FILING" and doc_list.get("legalFilings"):
+ query_params: str = DRS_REPORT_PARAMS.format(report_type="FILING", drs_id=doc.get("identifier"))
+ filing = doc_list["legalFilings"][0]
+ filing_key = next(iter(filing.keys()))
+ filing[filing_key] = filing[filing_key] + query_params
+ elif doc.get("reportType") and doc.get("reportType") == "CERT":
+ query_params: str = DRS_REPORT_PARAMS.format(report_type="CERT", drs_id=doc.get("identifier"))
+ for key in doc_list:
+ if str(key).find("certificate") > -1:
+ doc_list[key] = doc_list[key] + query_params
+ break
+ elif doc.get("documentClass"):
+ doc_list = self._update_static_document(doc, doc_list)
+ return document_list
+
+ def update_filing_documents(self, drs_docs: list, filing_docs: list, filing: Filing) -> list: # noqa: PLR0912
+ """
+ Get outputs and documents for a ledger filing, adding DRS information if available by mapping on the filing ID.
+
+ drs_docs: The DRS reports/documents for the business identifier.
+ filing_docs: The filing list of reports/documents.
+ return: The updated list of filing reports and documents for the filing.
+ """
+ doc_list = filing_docs.get("documents") if filing_docs else None
+ if not filing_docs or not doc_list:
+ return []
+ if not drs_docs or not filing or filing.paper_only:
+ return doc_list
+ drs_filing_id: int = filing.id
+ # If DRS reports/documents exist add the DRS download info to the document URLs.
+ if filing and filing.source == filing.Source.COLIN.value:
+ meta_data = filing.meta_data
+ if meta_data and meta_data.get("colinFilingInfo") and meta_data["colinFilingInfo"].get("eventId"):
+ drs_filing_id = meta_data["colinFilingInfo"].get("eventId")
+
+ for doc in drs_docs:
+ if doc.get("eventIdentifier", 0) == drs_filing_id:
+ if doc.get("reportType") and doc.get("reportType") == "RECEIPT" and doc_list.get("receipt"):
+ query_params: str = DRS_REPORT_PARAMS.format(report_type="RECEIPT", drs_id=doc.get("identifier"))
+ doc_list["receipt"] = doc_list["receipt"] + query_params
+ elif doc.get("reportType") and doc.get("reportType") == "NOA" and doc_list.get("noticeOfArticles"):
+ query_params: str = DRS_REPORT_PARAMS.format(report_type="NOA", drs_id=doc.get("identifier"))
+ doc_list["noticeOfArticles"] = doc_list["noticeOfArticles"] + query_params
+ elif doc.get("reportType") and doc.get("reportType") == "FILING" and doc_list.get("legalFilings"):
+ query_params: str = DRS_REPORT_PARAMS.format(report_type="FILING", drs_id=doc.get("identifier"))
+ legal_filing = doc_list["legalFilings"][0]
+ filing_key = next(iter(legal_filing.keys()))
+ legal_filing[filing_key] = legal_filing[filing_key] + query_params
+ elif doc.get("reportType") and doc.get("reportType") == "CERT":
+ query_params: str = DRS_REPORT_PARAMS.format(report_type="CERT", drs_id=doc.get("identifier"))
+ for key in doc_list:
+ if str(key).find("certificate") > -1:
+ doc_list[key] = doc_list[key] + query_params
+ break
+ elif doc.get("documentClass"):
+ doc_list = self._update_static_document(doc, doc_list)
+ return doc_list
+
+ def get_filing_report(self, drs_id: str, report_type: str):
+ """
+ Get a filing report document from the document service by unique DRS identifier.
+
+ drs_id: The unique DRS identifier for the requested document.
+ report_type: The report type: request a certified copy for NOA and FILING report types.
+ return: The document binary data.
+ """
+ headers = self._get_request_headers(BUSINESS_API_ACCOUNT_ID)
+ url: str = self.url.replace(DOC_PATH, "")
+ get_url = GET_REPORT_PATH
+ if report_type in (ReportTypes.FILING.value, ReportTypes.NOA.value):
+ get_url = GET_REPORT_CERTIFIED_PATH
+ get_url = get_url.format(url=url, product=self.product_code, drsId=drs_id)
+ response = requests.get(url=get_url, headers=headers)
+ if response.status_code not in (HTTPStatus.OK, HTTPStatus.NOT_FOUND):
+ current_app.logger.error(f"DRS call {get_url} failed status={response.status_code}: {response.content}")
+ return response
+
+ def get_filing_document(self, drs_id: str, doc_class: str):
+ """
+ Get a filing document from the document service by unique DRS identifier.
+
+ drs_id: The unique DRS identifier for the requested document.
+ document_class: The DRS document class for the business to filter on.
+ return: The document binary data.
+ """
+ headers = self._get_request_headers(BUSINESS_API_ACCOUNT_ID)
+ url: str = self.url.replace(DOC_PATH, "")
+ get_url = GET_DOCUMENT_PATH.format(url=url, document_class=doc_class, drs_id=drs_id)
+ response = requests.get(url=get_url, headers=headers)
+ if response.status_code not in (HTTPStatus.OK, HTTPStatus.NOT_FOUND):
+ current_app.logger.error(f"DRS call {get_url} failed status={response.status_code}: {response.content}")
+ return response
+
+ def create_filing_report(
+ self,
+ business_identifier: str,
+ filing: Filing,
+ report_meta: dict,
+ report_response
+ ):
+ """
+ Create a DRS application report record with a report service report.
+
+ business_identifier: Required - associates the report with the business.
+ filing: Required - contains the filing ID and filing date.
+ report_type: Required - the DRS report type.
+ report_response: Required - contains the report binary data
+ return: The DRS API response.
+ """
+ if not business_identifier or not filing or not report_meta or not report_meta.get("reportType"):
+ return report_response
+ headers = self._get_request_headers(BUSINESS_API_ACCOUNT_ID)
+ url: str = self.url.replace(DOC_PATH, "")
+ report_type: str = report_meta.get("reportType")
+ filename: str = report_meta.get("fileName") + ".pdf"
+ filing_date: str = filing.effective_date.isoformat()[:10]
+ post_url = POST_REPORT_PATH.format(
+ url=url,
+ product=self.product_code,
+ bus_id=business_identifier,
+ filing_id=filing.id,
+ report_type=report_type
+ )
+ post_url += POST_REPORT_PARAMS.format(filing_date=filing_date, filename=filename)
+ response = requests.post(url=post_url, headers=headers, data=report_response.content)
+ if response.status_code not in (HTTPStatus.OK, HTTPStatus.CREATED):
+ current_app.logger.error(f"DRS call {post_url} failed status={response.status_code}: {response.content}")
+ return report_response
+ if report_type == ReportTypes.CERT.value:
+ return report_response
+ # Get the certified copy of the NOA and FILING report types.
+ response_json = json.loads(response.content)
+ if response_json and response_json.get("identifier"):
+ response2 = self.get_filing_report(response_json.get("identifier"), report_type)
+ if response2.status_code == HTTPStatus.OK:
+ return response2
+ return report_response
+
+ def _update_static_document(self, doc: dict, doc_list: list) -> list:
+ """
+ Update static document urls in the document_list if a DRS match is found.
+
+ docs: The DRS document information to match on.
+ doc_list: The business list of reports/documents for the filing.
+ return: The updated list of static documents for the filing.
+ """
+ query_params: str = DRS_DOCUMENT_PARAMS.format(
+ document_class=doc.get("documentClass"),
+ drs_id=doc.get("identifier")
+ )
+ for key in doc_list:
+ if key == "staticDocuments":
+ for static_doc in doc_list.get("staticDocuments"):
+ name: str = static_doc.get("name")
+ if (name and name == doc.get("name")) or (
+ name and STATIC_DOCUMENTS.get(name) and
+ doc.get("documentClass") == STATIC_DOCUMENTS[name].get("documentClass") and
+ doc.get("documentType") == STATIC_DOCUMENTS[name].get("documentType")
+ ):
+ static_doc["url"] = static_doc["url"] + query_params
+ break
+ elif (
+ FILING_DOCUMENTS.get(key) and
+ doc.get("documentClass") == FILING_DOCUMENTS[key].get("documentClass") and
+ doc.get("documentType") == FILING_DOCUMENTS[key].get("documentType")
+ ):
+ doc_list[key] = doc_list[key] + query_params
+ break
+ return doc_list
+
+
+ def _get_request_headers(self, account_id: str) -> dict:
+ """
+ Get request headers for the DRS api call.
+
+ account_id: The account use if not the default.
+ return: The request headers.
+ """
+ token = AccountService.get_bearer_token()
+ headers = {
+ "x-apikey": self.api_key,
+ "Account-Id": account_id if account_id else BUSINESS_API_ACCOUNT_ID,
+ "Content-Type": APP_PDF,
+ "Authorization": BEARER + token
+ }
+ return headers
diff --git a/legal-api/src/legal_api/reports/report.py b/legal-api/src/legal_api/reports/report.py
index 6aa09098ab..9e1d8eafb9 100644
--- a/legal-api/src/legal_api/reports/report.py
+++ b/legal-api/src/legal_api/reports/report.py
@@ -36,7 +36,7 @@
PartyRole,
)
from legal_api.models.business import ASSOCIATION_TYPE_DESC
-from legal_api.reports.document_service import DocumentService
+from legal_api.reports.document_service import DocumentService, ReportTypes
from legal_api.reports.registrar_meta import RegistrarInfo
from legal_api.services import VersionedBusinessDetailsService, flags
from legal_api.utils.auth import jwt
@@ -78,21 +78,20 @@ def _get_static_report(self):
)
def _get_report(self):
- if flags.is_on("enable-document-records"):
- account_id = request.headers.get("Account-Id", None)
- if account_id is not None and self._business is not None:
- document, status = self._document_service.get_document(
- self._business.identifier,
- self._filing.id,
- self._report_key,
- account_id
+ account_id = request.headers.get("Account-Id", None)
+ if account_id is not None and self._business is not None:
+ document, status = self._document_service.get_document(
+ self._business.identifier,
+ self._filing.id,
+ self._report_key,
+ account_id
+ )
+ if status == HTTPStatus.OK:
+ return current_app.response_class(
+ response=document,
+ status=status,
+ mimetype="application/pdf"
)
- if status == HTTPStatus.OK:
- return current_app.response_class(
- response=document,
- status=status,
- mimetype="application/pdf"
- )
if self._filing.business_id:
self._business = Business.find_by_internal_id(self._filing.business_id)
@@ -114,32 +113,15 @@ def _get_report(self):
if response.status_code != HTTPStatus.OK:
return jsonify(message=str(response.content)), response.status_code
- if flags.is_on("enable-document-records"):
- create_document = account_id is not None
- create_filing_types = [
- "incorporationApplication",
- "continuationIn",
- "amalgamation",
- "registration"
- ]
- if self._filing.filing_type in create_filing_types:
- create_document = create_document and self._business and self._business.tax_id
- else:
- create_document = create_document and \
- self._filing.status in (Filing.Status.COMPLETED, Filing.Status.CORRECTED)
-
- if create_document:
- self._document_service.create_document(
- self._business.identifier,
- self._filing.id,
- self._report_key,
- account_id,
- response.content
- )
-
+ response_drs = self._document_service.create_filing_report(
+ self._business.identifier,
+ self._filing,
+ ReportMeta.reports.get(self._report_key),
+ response
+ )
return current_app.response_class(
- response=response.content,
- status=response.status_code,
+ response=response_drs.content,
+ status=response_drs.status_code,
mimetype="application/pdf"
)
@@ -1291,6 +1273,10 @@ def _format_office_data(self, filing, prev_completed_filing: Filing):
def _format_party_data(self, filing, prev_completed_filing: Filing):
filing["parties"] = filing.get("correction").get("parties", [])
+ if relationships := filing.get("correction").get("relationships"):
+ # map relationships to parties for pdf templates
+ filing["parties"].extend([self._map_relationship_to_party(relationship) for relationship in relationships])
+
if filing.get("parties"):
self._format_directors(filing["parties"])
filing["partyChange"] = False
@@ -1491,6 +1477,24 @@ def _get_environment():
return "TEST"
return ""
+ @staticmethod
+ def _map_relationship_to_party(relationship):
+ # FUTURE: update pdf templates to expect relationships schema and remove this
+ organization_name = relationship["entity"].get("businessName")
+ return {
+ "officer": {
+ "id": relationship["entity"].get("identifier"),
+ "firstName": relationship["entity"].get("givenName"),
+ "middleName": relationship["entity"].get("middleInitial"),
+ "lastName": relationship["entity"].get("familyName"),
+ "organizationName": organization_name,
+ "partyType": "organization" if organization_name else "person"
+ },
+ "deliveryAddress": relationship.get("deliveryAddress"),
+ "mailingAddress": relationship.get("mailingAddress"),
+ "roles": relationship.get("roles", [])
+ }
+
class ReportMeta: # pylint: disable=too-few-public-methods
"""Helper class to maintain the report meta information."""
@@ -1498,35 +1502,43 @@ class ReportMeta: # pylint: disable=too-few-public-methods
reports = {
"amalgamationApplication": {
"filingDescription": "Amalgamation Application",
- "fileName": "amalgamationApplication"
+ "fileName": "amalgamationApplication",
+ "reportType": ReportTypes.FILING.value
},
"certificateOfAmalgamation": {
"filingDescription": "Certificate Of Amalgamation",
- "fileName": "certificateOfAmalgamation"
+ "fileName": "certificateOfAmalgamation",
+ "reportType": ReportTypes.CERT.value
},
"certificateOfIncorporation": {
"filingDescription": "Certificate of Incorporation",
- "fileName": "certificateOfIncorporation"
+ "fileName": "certificateOfIncorporation",
+ "reportType": ReportTypes.CERT.value
},
"incorporationApplication": {
"filingDescription": "Incorporation Application",
- "fileName": "incorporationApplication"
+ "fileName": "incorporationApplication",
+ "reportType": ReportTypes.FILING.value
},
"noticeOfArticles": {
"filingDescription": "Notice of Articles",
- "fileName": "noticeOfArticles"
+ "fileName": "noticeOfArticles",
+ "reportType": ReportTypes.NOA.value
},
"alterationNotice": {
"filingDescription": "Alteration Notice",
- "fileName": "alterationNotice"
+ "fileName": "alterationNotice",
+ "reportType": ReportTypes.FILING.value
},
"transition": {
"filingDescription": "Transition Application",
- "fileName": "transitionApplication"
+ "fileName": "transitionApplication",
+ "reportType": ReportTypes.FILING.value
},
"changeOfAddress": {
"hasDifferentTemplates": True,
"filingDescription": "Change of Address",
+ "reportType": ReportTypes.FILING.value,
"default": {
"fileName": "bcAddressChange"
},
@@ -1537,6 +1549,7 @@ class ReportMeta: # pylint: disable=too-few-public-methods
"changeOfDirectors": {
"hasDifferentTemplates": True,
"filingDescription": "Change of Directors",
+ "reportType": ReportTypes.FILING.value,
"default": {
"fileName": "bcDirectorChange"
},
@@ -1547,6 +1560,7 @@ class ReportMeta: # pylint: disable=too-few-public-methods
"annualReport": {
"hasDifferentTemplates": True,
"filingDescription": "Annual Report",
+ "reportType": ReportTypes.FILING.value,
"default": {
"fileName": "bcAnnualReport"
},
@@ -1556,55 +1570,68 @@ class ReportMeta: # pylint: disable=too-few-public-methods
},
"changeOfName": {
"filingDescription": "Change of Name",
- "fileName": "changeOfName"
+ "fileName": "changeOfName",
+ "reportType": ReportTypes.FILING.value
},
"specialResolution": {
"filingDescription": "Special Resolution",
- "fileName": "specialResolution"
+ "fileName": "specialResolution",
+ "reportType": ReportTypes.FILING.value
},
"specialResolutionApplication": {
"filingDescription": "Special Resolution Application",
- "fileName": "specialResolutionApplication"
+ "fileName": "specialResolutionApplication",
+ "reportType": ReportTypes.FILING.value
},
"voluntaryDissolution": {
"filingDescription": "Voluntary Dissolution",
- "fileName": "voluntaryDissolution"
+ "fileName": "voluntaryDissolution",
+ "reportType": ReportTypes.FILING.value
},
"certificateOfNameChange": {
"filingDescription": "Certificate of Name Change",
- "fileName": "certificateOfNameChange"
+ "fileName": "certificateOfNameChange",
+ "reportType": ReportTypes.CERT.value
},
"certificateOfNameCorrection": {
"filingDescription": "Certificate of Name Correction",
- "fileName": "certificateOfNameChange"
+ "fileName": "certificateOfNameChange",
+ "reportType": ReportTypes.CERT.value
},
"certificateOfDissolution": {
"filingDescription": "Certificate of Dissolution",
- "fileName": "certificateOfDissolution"
+ "fileName": "certificateOfDissolution",
+ "reportType": ReportTypes.CERT.value
},
"dissolution": {
"filingDescription": "Dissolution Application",
- "fileName": "dissolution"
+ "fileName": "dissolution",
+ "reportType": ReportTypes.FILING.value
},
"registration": {
"filingDescription": "Statement of Registration",
- "fileName": "registration"
+ "fileName": "registration",
+ "reportType": ReportTypes.FILING.value
},
"amendedRegistrationStatement": {
"filingDescription": "Amended Registration Statement",
- "fileName": "amendedRegistrationStatement"
+ "fileName": "amendedRegistrationStatement",
+ "reportType": ReportTypes.FILING.value
},
"correctedRegistrationStatement": {
"filingDescription": "Corrected Registration Statement",
- "fileName": "amendedRegistrationStatement"
+ "fileName": "amendedRegistrationStatement",
+ "reportType": ReportTypes.FILING.value
},
"changeOfRegistration": {
"filingDescription": "Change of Registration",
- "fileName": "changeOfRegistration"
+ "fileName": "changeOfRegistration",
+ "reportType": ReportTypes.FILING.value
},
"correction": {
"hasDifferentTemplates": True,
"filingDescription": "Correction",
+ "reportType": ReportTypes.FILING.value,
"default": {
"fileName": "correction"
},
@@ -1617,31 +1644,38 @@ class ReportMeta: # pylint: disable=too-few-public-methods
},
"certificateOfRestoration": {
"filingDescription": "Certificate of Restoration",
- "fileName": "certificateOfRestoration"
+ "fileName": "certificateOfRestoration",
+ "reportType": ReportTypes.FILING.value
},
"restoration": {
"filingDescription": "Restoration Application",
- "fileName": "restoration"
+ "fileName": "restoration",
+ "reportType": ReportTypes.FILING.value
},
"letterOfConsent": {
"filingDescription": "Letter Of Consent",
- "fileName": "letterOfConsent"
+ "fileName": "letterOfConsent",
+ "reportType": ReportTypes.FILING.value
},
"letterOfConsentAmalgamationOut": {
"filingDescription": "Letter Of Consent",
- "fileName": "letterOfConsentAmalgamationOut"
+ "fileName": "letterOfConsentAmalgamationOut",
+ "reportType": ReportTypes.FILING.value
},
"letterOfAgmExtension": {
"filingDescription": "Letter Of AGM Extension",
- "fileName": "letterOfAgmExtension"
+ "fileName": "letterOfAgmExtension",
+ "reportType": ReportTypes.FILING.value
},
"letterOfAgmLocationChange": {
"filingDescription": "Letter Of AGM Location Change",
- "fileName": "letterOfAgmLocationChange"
+ "fileName": "letterOfAgmLocationChange",
+ "reportType": ReportTypes.FILING.value
},
"continuationIn": {
"filingDescription": "Continuation Application",
- "fileName": "continuationApplication"
+ "fileName": "continuationApplication",
+ "reportType": ReportTypes.FILING.value
},
"certificateOfContinuation": {
"filingDescription": "Certificate of Continuation",
@@ -1649,15 +1683,18 @@ class ReportMeta: # pylint: disable=too-few-public-methods
},
"noticeOfWithdrawal": {
"filingDescription": "Notice of Withdrawal",
- "fileName": "noticeOfWithdrawal"
+ "fileName": "noticeOfWithdrawal",
+ "reportType": ReportTypes.FILING.value
},
"appointReceiver": {
"filingDescription": "Appoint Receiver",
- "fileName": "appointReceiver"
+ "fileName": "appointReceiver",
+ "reportType": ReportTypes.FILING.value
},
"ceaseReceiver": {
"filingDescription": "Cease Receiver",
- "fileName": "ceaseReceiver"
+ "fileName": "ceaseReceiver",
+ "reportType": ReportTypes.FILING.value
}
}
diff --git a/legal-api/src/legal_api/resources/v2/business/business_filings/business_documents.py b/legal-api/src/legal_api/resources/v2/business/business_filings/business_documents.py
index e89306619d..8ba369352e 100644
--- a/legal-api/src/legal_api/resources/v2/business/business_filings/business_documents.py
+++ b/legal-api/src/legal_api/resources/v2/business/business_filings/business_documents.py
@@ -27,6 +27,7 @@
from legal_api.models import Business, Document
from legal_api.models import Filing as FilingModel
from legal_api.reports import get_pdf
+from legal_api.reports.document_service import DocumentService
from legal_api.resources.v2.business.bp import bp
from legal_api.services import MinioService, authorized
from legal_api.utils.auth import jwt
@@ -37,6 +38,12 @@
DOCUMENTS_BASE_ROUTE: Final = "//filings//documents"
+PARAM_REPORT_TYPE: str = "reportType"
+PARAM_DOC_CLASS = "documentClass"
+PARAM_DRS_ID = "drsId"
+APP_PDF = "application/pdf"
+CONTENT_JSON = {"Content-Type": "application/json"}
+CONTENT_PDF = {"Content-Type": APP_PDF}
@cors_preflight("GET, POST")
@@ -55,7 +62,6 @@ def get_documents(identifier: str, # noqa: PLR0911, PLR0912
return jsonify(
message=get_error_message(ErrorCode.NOT_AUTHORIZED, identifier=identifier)
), HTTPStatus.UNAUTHORIZED
-
if identifier.startswith("T"):
filing_model = FilingModel.get_temp_reg_filing(identifier)
business = Business.find_by_internal_id(filing_model.business_id)
@@ -87,7 +93,7 @@ def get_documents(identifier: str, # noqa: PLR0911, PLR0912
return {"documents": {}}, HTTPStatus.OK
return _get_document_list(business, filing)
- if "application/pdf" in request.accept_mimetypes:
+ if APP_PDF in request.accept_mimetypes:
file_name = (legal_filing_name or file_key)
if not _is_document_available(business, filing, file_name):
return jsonify(
@@ -95,6 +101,9 @@ def get_documents(identifier: str, # noqa: PLR0911, PLR0912
file_name=file_name, filing_id=filing_id, identifier=identifier)
), HTTPStatus.NOT_FOUND
+ if drs_params := _get_drs_params():
+ return _get_drs_documents(drs_params)
+
if legal_filing_name:
if legal_filing_name.lower().startswith("receipt"):
return _get_receipt(business, filing, jwt.get_token_auth_header())
@@ -106,12 +115,38 @@ def get_documents(identifier: str, # noqa: PLR0911, PLR0912
return current_app.response_class(
response=response.data,
status=response.status,
- mimetype="application/pdf"
+ mimetype=APP_PDF
)
return {}, HTTPStatus.NOT_FOUND
+def _get_drs_params() -> dict:
+ """Extract DRS parameters from the request."""
+ params: dict = {}
+ if request.args.get(PARAM_REPORT_TYPE):
+ params["reportType"] = request.args.get(PARAM_REPORT_TYPE)
+ if request.args.get(PARAM_DRS_ID):
+ params["drsId"] = request.args.get(PARAM_DRS_ID)
+ if request.args.get(PARAM_DOC_CLASS):
+ params["documentClass"] = request.args.get(PARAM_DOC_CLASS)
+ return params
+
+
+def _get_drs_documents(drs_params: dict):
+ """Return an indvidual DRS document as binary data, or a DRS JSON error."""
+ doc_service: DocumentService = DocumentService()
+ drs_id: str = drs_params.get(PARAM_DRS_ID)
+ response = None
+ if drs_params.get(PARAM_REPORT_TYPE):
+ response = doc_service.get_filing_report(drs_id, drs_params.get(PARAM_REPORT_TYPE))
+ else:
+ response = doc_service.get_filing_document(drs_id, drs_params.get(PARAM_DOC_CLASS))
+
+ content_type: str = CONTENT_PDF if response.status_code == HTTPStatus.OK else CONTENT_JSON
+ return response.content, response.status_code, content_type
+
+
def _is_document_available(business, filing, file_name):
"""Check if the document is available."""
document_list = Filing.get_document_list(business, filing, jwt)
@@ -128,11 +163,23 @@ def _is_document_available(business, filing, file_name):
return file_name in documents
-def _get_document_list(business, filing):
+def _get_document_list(business: Business, filing: Filing):
"""Get list of document outputs."""
- if not (document_list := Filing.get_document_list(business, filing, jwt)):
+ document_list = Filing.get_document_list(business, filing, jwt)
+ if not (document_list):
return {}, HTTPStatus.NOT_FOUND
-
+ storage: FilingModel = filing.storage
+ # If DRS reports/documents exist add the DRS download info to the document URLs.
+ if storage and not storage.paper_only:
+ drs_filing_id: int = storage.id
+ if storage.source and storage.source == storage.Source.COLIN.value and storage.meta_data:
+ meta_data = storage.meta_data
+ if meta_data and meta_data.get("colinFilingInfo") and meta_data["colinFilingInfo"].get("eventId"):
+ drs_filing_id = meta_data["colinFilingInfo"].get("eventId")
+ identifier = business.identifier if business else storage.temp_reg
+ doc_service: DocumentService = DocumentService()
+ drs_docs: list = doc_service.get_documents_by_filing_id(identifier, drs_filing_id)
+ document_list = doc_service.update_document_list(drs_docs, document_list)
return jsonify(document_list), HTTPStatus.OK
diff --git a/legal-api/tests/conftest.py b/legal-api/tests/conftest.py
index 841884e684..d13c6185bb 100644
--- a/legal-api/tests/conftest.py
+++ b/legal-api/tests/conftest.py
@@ -313,7 +313,7 @@ def _mock_get_side_effect(request, context):
DOCUMENT_API_URL = 'http://document-api.com'
DOCUMENT_API_VERSION = '/api/v1'
-DOCUMENT_SVC_URL = f'{DOCUMENT_API_URL + DOCUMENT_API_VERSION}/documents'
+DOCUMENT_SVC_URL = f'{DOCUMENT_API_URL + DOCUMENT_API_VERSION}'
DOCUMENT_PRODUCT_CODE = 'BUSINESS'
@pytest.fixture()
@@ -331,4 +331,21 @@ def mock_doc_service():
mock.get(re.compile(f"{get_url}.*"),
status_code=HTTPStatus.OK,
text=json.dumps(mock_response))
+ get_url2 = f'{DOCUMENT_SVC_URL}/application-reports/history/{DOCUMENT_PRODUCT_CODE}/'
+ mock.get(re.compile(f"{get_url2}.*"),
+ status_code=HTTPStatus.OK,
+ text=json.dumps(mock_response))
yield mock
+
+
+@pytest.fixture()
+def mock_drs_service():
+ mock_response = []
+ with requests_mock.Mocker(real_http=True) as m:
+ get_url = f'{DOCUMENT_SVC_URL}/application-reports/{DOCUMENT_PRODUCT_CODE}/'
+ get_url2 = f'{DOCUMENT_SVC_URL}/application-reports/history/{DOCUMENT_PRODUCT_CODE}/'
+ get_url3 = f'{DOCUMENT_SVC_URL}/application-reports/events/{DOCUMENT_PRODUCT_CODE}/'
+ m.register_uri('GET', re.compile(f"{get_url}.*"), json=mock_response, status_code=HTTPStatus.OK)
+ m.register_uri('GET', re.compile(f"{get_url2}.*"), json=mock_response, status_code=HTTPStatus.OK)
+ m.register_uri('GET', re.compile(f"{get_url3}.*"), json=mock_response, status_code=HTTPStatus.OK)
+ yield m
diff --git a/legal-api/tests/unit/core/test_filing_ledger.py b/legal-api/tests/unit/core/test_filing_ledger.py
index 06cdebb81a..1a7cb29582 100644
--- a/legal-api/tests/unit/core/test_filing_ledger.py
+++ b/legal-api/tests/unit/core/test_filing_ledger.py
@@ -17,14 +17,16 @@
import datedelta
import pytest
+from flask import current_app
from registry_schemas.example_data import FILING_TEMPLATE
from legal_api.core import Filing as CoreFiling
from legal_api.models import Business, Comment, Filing, UserRoles
from legal_api.models.user import UserRoles
+from legal_api.services.authz import STAFF_ROLE
from legal_api.utils.datetime import datetime
from tests.unit.models import factory_business, factory_completed_filing, factory_user
-from tests.unit.services.utils import helper_create_jwt
+from tests.unit.services.utils import helper_create_jwt, create_header
def load_ledger(business, founding_date):
@@ -65,16 +67,23 @@ def load_ledger(business, founding_date):
return i
-def test_simple_ledger_search(session):
+def test_simple_ledger_search(app, session, client, jwt, monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger returns values for all the expected keys."""
# setup
identifier = 'BC1234567'
founding_date = datetime.utcnow() - datedelta.datedelta(months=len(Filing.FILINGS.keys()))
business = factory_business(identifier=identifier, founding_date=founding_date, last_ar_date=None, entity_type=Business.LegalTypes.BCOMP.value)
num_of_files = load_ledger(business, founding_date)
+ token = helper_create_jwt(jwt, roles=[STAFF_ROLE], username='testuser')
+ headers = {'Authorization': 'Bearer ' + token, 'Account-Id': 1}
- # test
- ledger = CoreFiling.ledger(business.id)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
+
+ # test
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ ledger = CoreFiling.ledger(business.id, jwt)
# Did we get the full set
assert len(ledger) == num_of_files
@@ -83,7 +92,7 @@ def test_simple_ledger_search(session):
alteration = next((f for f in ledger if f.get('name') == 'alteration'), None)
assert alteration
- assert 18 == len(alteration.keys())
+ assert 18 <= len(alteration.keys())
assert 'availableOnPaperOnly' in alteration
assert 'effectiveDate' in alteration
assert 'filingId' in alteration
@@ -100,7 +109,7 @@ def test_simple_ledger_search(session):
# assert alteration['filingLink']
-def test_common_ledger_items(session):
+def test_common_ledger_items(session,):
"""Assert that common ledger items works as expected."""
identifier = 'BC1234567'
founding_date = datetime.utcnow() - datedelta.datedelta(months=len(Filing.FILINGS.keys()))
diff --git a/legal-api/tests/unit/reports/test_document_service.py b/legal-api/tests/unit/reports/test_document_service.py
index c8f982134a..7038a78e3f 100644
--- a/legal-api/tests/unit/reports/test_document_service.py
+++ b/legal-api/tests/unit/reports/test_document_service.py
@@ -17,12 +17,300 @@
from datetime import datetime
from http import HTTPStatus
import datedelta
+import json
+import pytest
+
+from legal_api.models import Filing
from legal_api.reports.document_service import DocumentService
from tests.unit.models import factory_business, factory_completed_filing
from registry_schemas.example_data import FILING_TEMPLATE
+META_COLIN = {
+ "colinFilingInfo": {
+ "eventId": 7678798,
+ "eventType": "FILE",
+ "filingType": "NOCDR"
+ }
+}
+META_MODERN = {}
+DOCS_MODERN = {
+ "documents": {
+ "certificateOfIncorporation": "https://test.com/BC0888490/filings/2405954/documents/certificateOfIncorporation",
+ "legalFilings": [
+ {"incorporationApplication": "https://test.com/BC0888490/filings/2405954/documents/incorporationApplication"}
+ ],
+ "noticeOfArticles": "https://test.com/BC0888490/filings/2405954/documents/noticeOfArticles",
+ "receipt": "https://test.com/BC0888490/filings/2405954/documents/receipt"
+ }
+}
+DOCS_COLIN = {
+ "documents": {
+ "certificateOfIncorporation": "https://test.com/BC0791952/filings/515091/documents/certificateOfIncorporation",
+ "legalFilings": [
+ {"incorporationApplication": "https://test.com/BC0791952/filings/515091/documents/incorporationApplication"}
+ ],
+ "noticeOfArticles": "https://test.com/BC0791952/filings/515091/documents/noticeOfArticles",
+ "receipt": "https://test.com/BC0791952/filings/515091/documents/receipt"
+ }
+}
+DOCS_STATIC1 = {
+ "documents": {
+ "certificateOfIncorporation": "https://test.com/CP1044798/filings/233791/documents/certificateOfIncorporation",
+ "certifiedMemorandum": "https://test.com/CP1044798/filings/233791/documents/certifiedMemorandum",
+ "certifiedRules": "https://test.com/CP1044798/filings/233791/documents/certifiedRules",
+ "legalFilings": [
+ {"incorporationApplication": "https://test.com/CP1044798/filings/233791/documents/incorporationApplication"}
+ ],
+ "receipt": "https://test.com/CP1044798/filings/233791/documents/receipt"
+ }
+}
+DOCS_STATIC2 = {
+ "documents": {
+ "certificateOfContinuation": "https://test.com/C9900863/filings/155753/documents/certificateOfContinuation",
+ "legalFilings": [
+ {"continuationIn": "https://test.com/C9900863/filings/155753/documents/continuationIn"}
+ ],
+ "noticeOfArticles": "https://test.com/C9900863/filings/155753/documents/noticeOfArticles",
+ "receipt": "https://test.com/C9900863/filings/155753/documents/receipt",
+ "staticDocuments": [
+ {
+ "name": "Unlimited Liability Corporation Information",
+ "url": "https://test.com/C9900863/filings/155753/documents/static/DS0000100741"
+ },
+ {
+ "name": "20250107-Authorization1.pdf",
+ "url": "https://test.com/C9900863/filings/155753/documents/static/DS0000100740"
+ }
+ ]
+ }
+}
+DRS_NONE = []
+DRS_MODERN = [
+ {
+ "dateCreated": "2026-03-11T15:45:51+00:00",
+ "datePublished": "2026-03-03T20:00:00+00:00",
+ "entityIdentifier": "BC0888490",
+ "eventIdentifier": 2405954,
+ "identifier": "DSR0000100951",
+ "name": "certificateOfIncorporation.pdf",
+ "productCode": "BUSINESS",
+ "reportType": "CERT",
+ "url": ""
+ },
+ {
+ "dateCreated": "2026-03-11T15:53:19+00:00",
+ "datePublished": "2026-03-03T20:00:00+00:00",
+ "entityIdentifier": "BC0888490",
+ "eventIdentifier": 2405954,
+ "identifier": "DSR0000100952",
+ "name": "noticeOfArticles.pdf",
+ "productCode": "BUSINESS",
+ "reportType": "NOA",
+ "url": ""
+ },
+ {
+ "dateCreated": "2026-03-11T16:09:51+00:00",
+ "datePublished": "2026-03-03T20:00:00+00:00",
+ "entityIdentifier": "BC0888490",
+ "eventIdentifier": 2405954,
+ "identifier": "DSR0000100954",
+ "name": "incorporationApplication.pdf",
+ "productCode": "BUSINESS",
+ "reportType": "FILING",
+ "url": ""
+ }
+]
+DRS_COLIN = [
+ {
+ "dateCreated": "2026-02-24T23:15:35+00:00",
+ "datePublished": "2007-05-23T18:40:59+00:00",
+ "entityIdentifier": "BC0791952",
+ "eventIdentifier": 7678798,
+ "identifier": "DSR0000100896",
+ "name": "BC0791952-ICORP-RECEIPT.pdf",
+ "productCode": "BUSINESS",
+ "reportType": "RECEIPT",
+ "url": ""
+ },
+ {
+ "dateCreated": "2026-02-24T23:15:37+00:00",
+ "datePublished": "2007-05-23T18:40:59+00:00",
+ "entityIdentifier": "BC0791952",
+ "eventIdentifier": 7678798,
+ "identifier": "DSR0000100897",
+ "name": "BC0791952-ICORP-FILING.pdf",
+ "productCode": "BUSINESS",
+ "reportType": "FILING",
+ "url": ""
+ },
+ {
+ "dateCreated": "2026-02-24T23:15:41+00:00",
+ "datePublished": "2007-05-23T18:40:59+00:00",
+ "entityIdentifier": "BC0791952",
+ "eventIdentifier": 7678798,
+ "identifier": "DSR0000100898",
+ "name": "BC0791952-ICORP-NOA.pdf",
+ "productCode": "BUSINESS",
+ "reportType": "NOA",
+ "url": ""
+ },
+ {
+ "dateCreated": "2026-02-24T23:15:45+00:00",
+ "datePublished": "2007-05-23T18:40:59+00:00",
+ "entityIdentifier": "BC0791952",
+ "eventIdentifier": 7678798,
+ "identifier": "DSR0000100899",
+ "name": "BC0791952-ICORP-CERT.pdf",
+ "productCode": "BUSINESS",
+ "reportType": "CERT",
+ "url": ""
+ }
+]
+DRS_STATIC1 = [
+ {
+ "consumerDocumentId": "0100000525",
+ "dateCreated": "2026-03-11T19:19:32+00:00",
+ "datePublished": "2026-01-22T00:00:00+00:00",
+ "documentClass": "COOP",
+ "documentType": "COOP_MEMORANDUM",
+ "documentTypeDescription": "Cooperative Memorandum",
+ "entityIdentifier": "CP1044798",
+ "eventIdentifier": 233791,
+ "identifier": "DS0000101630",
+ "name": "",
+ "url": ""
+ },
+ {
+ "consumerDocumentId": "0100000526",
+ "dateCreated": "2026-03-11T19:19:37+00:00",
+ "datePublished": "2026-01-22T00:00:00+00:00",
+ "documentClass": "COOP",
+ "documentType": "COOP_RULES",
+ "documentTypeDescription": "Cooperative Rules",
+ "entityIdentifier": "CP1044798",
+ "eventIdentifier": 233791,
+ "identifier": "DS0000101631",
+ "name": "",
+ "url": ""
+ }
+]
+DRS_STATIC2 = [
+ {
+ "consumerDocumentId": "0100000193",
+ "dateCreated": "2025-01-07T16:11:59+00:00",
+ "datePublished": "2025-01-07T20:00:00+00:00",
+ "documentClass": "CORP",
+ "documentType": "CNTA",
+ "documentTypeDescription": "Continuation in Authorization",
+ "entityIdentifier": "C9900863",
+ "eventIdentifier": 155753,
+ "identifier": "DS0000100740",
+ "name": "20250107-Authorization1.pdf",
+ "url": ""
+ },
+ {
+ "consumerDocumentId": "0100000193",
+ "dateCreated": "2025-01-07T16:12:05+00:00",
+ "datePublished": "2025-01-07T20:00:00+00:00",
+ "documentClass": "CORP",
+ "documentType": "DIRECTOR_AFFIDAVIT",
+ "documentTypeDescription": "Director Affidavit",
+ "entityIdentifier": "C9900863",
+ "eventIdentifier": 155753,
+ "identifier": "DS0000100741",
+ "name": "20250107-Affidavit.pdf",
+ "url": ""
+ }
+]
+
+# testdata pattern is ({description}, {doc_data}, {drs_data}, {receipt}, {filing}, {noa}, {cert}, {static})
+TEST_FILING_UPDATE_DATA = [
+ ("No docs", DOCS_MODERN, DRS_NONE, None, None, None, None, None),
+ ("Modern docs", DOCS_MODERN, DRS_MODERN, None, "reportType=FILING&drsId=DSR0000100954", "reportType=NOA&drsId=DSR0000100952", "reportType=CERT&drsId=DSR0000100951", None),
+ ("Colin docs", DOCS_COLIN, DRS_COLIN, "reportType=RECEIPT&drsId=DSR0000100896", "reportType=FILING&drsId=DSR0000100897", "reportType=NOA&drsId=DSR0000100898", "reportType=CERT&drsId=DSR0000100899", None),
+ ("Static 1", DOCS_STATIC1, DRS_STATIC1, None, None, None, None, "documentClass=COOP&drsId=DS0000101630"),
+ ("Static 2", DOCS_STATIC2, DRS_STATIC2, None, None, None, None, "documentClass=CORP&drsId=DS0000100741"),
+]
+# testdata pattern is ({description}, {doc_data}, {drs_data}, {receipt}, {filing}, {noa}, {cert}, {static}, {meta}, {filing_id})
+TEST_BUSINESS_UPDATE_DATA = [
+ ("No docs", DOCS_MODERN, DRS_NONE, None, None, None, None, None, META_MODERN, 2405954),
+ ("Modern docs", DOCS_MODERN, DRS_MODERN, None, "reportType=FILING&drsId=DSR0000100954", "reportType=NOA&drsId=DSR0000100952", "reportType=CERT&drsId=DSR0000100951", None, META_MODERN, 2405954),
+ ("Colin docs", DOCS_COLIN, DRS_COLIN, "reportType=RECEIPT&drsId=DSR0000100896", "reportType=FILING&drsId=DSR0000100897", "reportType=NOA&drsId=DSR0000100898", "reportType=CERT&drsId=DSR0000100899", None, META_COLIN, 0),
+ ("Static 1", DOCS_STATIC1, DRS_STATIC1, None, None, None, None, "documentClass=COOP&drsId=DS0000101630", META_MODERN, 233791),
+ ("Static 2", DOCS_STATIC2, DRS_STATIC2, None, None, None, None, "documentClass=CORP&drsId=DS0000100741", META_MODERN, 155753),
+]
+
+
+@pytest.mark.parametrize("desc,doc_data,drs_data,receipt,filing,noa,cert,static", TEST_FILING_UPDATE_DATA)
+def test_update_filing_docs(session, desc, doc_data, drs_data, receipt, filing, noa, cert,static):
+ """Assert that updating filing output url's with DRS info works as expected."""
+ doc_service: DocumentService = DocumentService()
+ filing_docs = copy.deepcopy(doc_data)
+ results = doc_service.update_document_list(drs_data, filing_docs)
+ assert results
+ text_results: str = json.dumps(results)
+ if not receipt:
+ assert text_results.find("reportType=RECEIPT") < 1
+ else:
+ assert text_results.find(receipt) > 0
+ if not filing:
+ assert text_results.find("reportType=FILING") < 1
+ else:
+ assert text_results.find(filing) > 0
+ if not noa:
+ assert text_results.find("reportType=NOA") < 1
+ else:
+ assert text_results.find(noa) > 0
+ if not cert:
+ assert text_results.find("reportType=CERT") < 1
+ else:
+ assert text_results.find(cert) > 0
+ if not static:
+ assert text_results.find("documentClass=") < 1
+ else:
+ assert text_results.find(static) > 0
+
+
+@pytest.mark.parametrize("desc,doc_data,drs_data,receipt,filing,noa,cert,static,meta,filing_id", TEST_BUSINESS_UPDATE_DATA)
+def test_update_ledger_docs(session, desc, doc_data, drs_data, receipt, filing, noa, cert,static, meta, filing_id):
+ """Assert that updating business ledger filing output url's with DRS info works as expected."""
+ doc_service: DocumentService = DocumentService()
+ filing_docs = copy.deepcopy(doc_data)
+ filing1: Filing = Filing()
+ filing1.id = filing_id
+ filing1._meta_data = meta # pylint: disable=protected-access
+ filing1.paper_only = False
+ if filing_id == 0:
+ filing1.source = filing1.Source.COLIN.value
+ else:
+ filing1.source = filing1.Source.LEAR.value
+ results = doc_service.update_filing_documents(drs_data, filing_docs, filing1)
+ assert results
+ text_results: str = json.dumps(results)
+ if not receipt:
+ assert text_results.find("reportType=RECEIPT") < 1
+ else:
+ assert text_results.find(receipt) > 0
+ if not filing:
+ assert text_results.find("reportType=FILING") < 1
+ else:
+ assert text_results.find(filing) > 0
+ if not noa:
+ assert text_results.find("reportType=NOA") < 1
+ else:
+ assert text_results.find(noa) > 0
+ if not cert:
+ assert text_results.find("reportType=CERT") < 1
+ else:
+ assert text_results.find(cert) > 0
+ if not static:
+ assert text_results.find("documentClass=") < 1
+ else:
+ assert text_results.find(static) > 0
+
+
def test_create_document(session, mock_doc_service, mocker):
mocker.patch('legal_api.services.AccountService.get_bearer_token', return_value='')
founding_date = datetime.utcnow()
diff --git a/legal-api/tests/unit/resources/v2/test_business_filings/test_filing_documents.py b/legal-api/tests/unit/resources/v2/test_business_filings/test_filing_documents.py
index 8b002f28ba..73905583a7 100644
--- a/legal-api/tests/unit/resources/v2/test_business_filings/test_filing_documents.py
+++ b/legal-api/tests/unit/resources/v2/test_business_filings/test_filing_documents.py
@@ -21,6 +21,7 @@
import re
from datetime import datetime
from http import HTTPStatus
+import requests_mock
import pytest
from flask import current_app
@@ -1464,7 +1465,7 @@ def test_unpaid_filing(session, client, jwt):
HTTPStatus.OK, '2024-09-26'
)
])
-def test_document_list_for_various_filing_states(session, mocker, client, jwt,
+def test_document_list_for_various_filing_states(app, session, mocker, client, jwt, monkeypatch, mock_drs_service,
test_name,
identifier,
entity_type,
@@ -1516,9 +1517,21 @@ def test_document_list_for_various_filing_states(session, mocker, client, jwt,
'url': f'{base_url}/api/v2/businesses/{identifier}/filings/1/documents/static/{file_key}'
})
- mocker.patch('legal_api.core.filing.has_roles', return_value=True)
- rv = client.get(f'/api/v2/businesses/{business.identifier}/filings/{filing.id}/documents',
- headers=create_header(jwt, [STAFF_ROLE], business.identifier))
+ account_id: str = '1'
+ headers=create_header(jwt, [STAFF_ROLE], identifier, account_id=account_id)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
+
+ # test
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ account_products_mock = []
+ with requests_mock.Mocker() as m:
+ mock_url = f"{app.config['AUTH_SVC_URL']}/orgs/{account_id}/products?include_hidden=true"
+ m.get(mock_url, json=account_products_mock, status_code=HTTPStatus.OK)
+ rv = client.get(f'/api/v2/businesses/{business.identifier}/filings/{filing.id}/documents',
+ headers=headers)
+ m.reset_mock()
# remove the filing ID
rv_data = json.loads(re.sub("/\d+/", "/", rv.data.decode("utf-8")).replace("\n", ""))
@@ -1625,7 +1638,7 @@ def filer_action(filing_name, filing_json, meta_data, business):
{'documents': {}}, HTTPStatus.OK
),
])
-def test_temp_document_list_for_various_filing_states(mocker, session, client, jwt,
+def test_temp_document_list_for_various_filing_states(app, mocker, session, client, jwt, monkeypatch, mock_drs_service,
test_name,
temp_identifier,
identifier,
@@ -1656,10 +1669,21 @@ def test_temp_document_list_for_various_filing_states(mocker, session, client, j
filing._payment_completion_date = '2017-10-01'
filing.temp_reg = temp_identifier
filing.save()
-
- mocker.patch('legal_api.core.filing.has_roles', return_value=True)
- rv = client.get(f'/api/v2/businesses/{temp_identifier}/filings/{filing.id}/documents',
- headers=create_header(jwt, [STAFF_ROLE], temp_identifier))
+ account_id: str = '1'
+ headers=create_header(jwt, [STAFF_ROLE], temp_identifier, account_id=account_id)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
+
+ # test
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ account_products_mock = []
+ with requests_mock.Mocker() as m:
+ mock_url = f"{app.config['AUTH_SVC_URL']}/orgs/{account_id}/products?include_hidden=true"
+ m.get(mock_url, json=account_products_mock, status_code=HTTPStatus.OK)
+ rv = client.get(f'/api/v2/businesses/{temp_identifier}/filings/{filing.id}/documents',
+ headers=headers)
+ m.reset_mock()
# remove the filing ID
rv_data = json.loads(re.sub("/\d+/", "/", rv.data.decode("utf-8")).replace("\n", ""))
@@ -1795,7 +1819,7 @@ def test_get_receipt_no_receipt_ca(session, client, jwt, requests_mock):
HTTPStatus.OK
)
])
-def test_temp_document_list_for_now(mocker, session, client, jwt,
+def test_temp_document_list_for_now(app, mocker, session, client, jwt, monkeypatch, mock_drs_service,
test_name,
temp_identifier,
entity_type,
@@ -1830,10 +1854,20 @@ def test_temp_document_list_for_now(mocker, session, client, jwt,
filing.temp_reg = None
filing.withdrawn_filing_id = withdrawn_filing.id
filing.save()
-
- mocker.patch('legal_api.core.filing.has_roles', return_value=True)
- rv = client.get(f'/api/v2/businesses/{temp_identifier}/filings/{filing.id}/documents',
- headers=create_header(jwt, [STAFF_ROLE], temp_identifier))
+ account_id: str = '1'
+ headers=create_header(jwt, [STAFF_ROLE], temp_identifier, account_id=account_id)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
+
+ # test
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ account_products_mock = []
+ with requests_mock.Mocker() as m:
+ mock_url = f"{app.config['AUTH_SVC_URL']}/orgs/{account_id}/products?include_hidden=true"
+ m.get(mock_url, json=account_products_mock, status_code=HTTPStatus.OK)
+ rv = client.get(f'/api/v2/businesses/{temp_identifier}/filings/{filing.id}/documents', headers=headers)
+ m.reset_mock()
# remove the filing ID
rv_data = json.loads(re.sub("/\d+/", "/", rv.data.decode("utf-8")).replace("\n", ""))
diff --git a/legal-api/tests/unit/resources/v2/test_business_filings/test_filings_ledger.py b/legal-api/tests/unit/resources/v2/test_business_filings/test_filings_ledger.py
index 27e5a8eb56..a5481fef7d 100644
--- a/legal-api/tests/unit/resources/v2/test_business_filings/test_filings_ledger.py
+++ b/legal-api/tests/unit/resources/v2/test_business_filings/test_filings_ledger.py
@@ -59,7 +59,7 @@
from tests.unit.services.utils import create_header
REGISTER_CORRECTION_APPLICATION = 'Register Correction Application'
-def test_get_all_business_filings_only_one_in_ledger(session, client, jwt):
+def test_get_all_business_filings_only_one_in_ledger(app, session, client, jwt, monkeypatch, mock_drs_service, mocker):
"""Assert that the business info can be received in a valid JSONSchema format."""
import copy
identifier = 'CP7654321'
@@ -71,15 +71,21 @@ def test_get_all_business_filings_only_one_in_ledger(session, client, jwt):
ar['filing']['header']['colinIds'] = []
print('test_get_all_business_filings - filing:', filings)
+ headers=create_header(jwt, [STAFF_ROLE], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [STAFF_ROLE], identifier))
+ # test
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
assert rv.status_code == HTTPStatus.OK
assert len(rv.json.get('filings')) == 0 # The endpoint will return only completed filings
-def test_get_all_business_filings_multi_in_ledger(session, client, jwt):
+def test_get_all_business_filings_multi_in_ledger(app, session, client, jwt, monkeypatch, mock_drs_service, mocker):
"""Assert that the business info can be received in a valid JSONSchema format."""
import copy
from tests import add_years
@@ -95,25 +101,36 @@ def test_get_all_business_filings_multi_in_ledger(session, client, jwt):
ar['filing']['annualReport']['annualGeneralMeetingDate'] = \
datetime.date(add_years(datetime(2001, 8, 5, 7, 7, 58, 272362), i)).isoformat()
factory_filing(b, ar)
+ headers=create_header(jwt, [STAFF_ROLE], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [STAFF_ROLE], identifier))
+ # test
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
assert rv.status_code == HTTPStatus.OK
assert len(rv.json.get('filings')) == 0
-def test_ledger_search(session, client, jwt):
+def test_ledger_search(app, session, client, jwt, monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger returns values for all the expected keys."""
# setup
identifier = 'BC1234567'
founding_date = datetime.utcnow() - datedelta.datedelta(months=len(FILINGS.keys()))
business = factory_business(identifier=identifier, founding_date=founding_date, last_ar_date=None, entity_type=Business.LegalTypes.BCOMP.value)
num_of_files = load_ledger(business, founding_date)
+ headers=create_header(jwt, [UserRoles.system], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
# test
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [UserRoles.system], identifier))
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
ledger = rv.json
@@ -124,7 +141,7 @@ def test_ledger_search(session, client, jwt):
alteration = next((f for f in ledger['filings'] if f.get('name') == 'alteration'), None)
assert alteration
- assert 18 == len(alteration.keys())
+ assert 18 <= len(alteration.keys())
assert 'availableOnPaperOnly' in alteration
assert 'effectiveDate' in alteration
assert 'filingId' in alteration
@@ -159,7 +176,7 @@ def ledger_element_setup_filing(business, filing_name, filing_date, filing_dict=
return f
-def test_ledger_comment_count(session, client, jwt):
+def test_ledger_comment_count(app, session, client, jwt, monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger returns the correct number of comments."""
# setup
identifier = 'BC1234567'
@@ -170,10 +187,15 @@ def test_ledger_comment_count(session, client, jwt):
comment.comment = f'this comment {c}'
filing_storage.comments.append(comment)
filing_storage.save()
+ headers=create_header(jwt, [UserRoles.system], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
# test
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [UserRoles.system], identifier))
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
# validate
assert rv.json['filings'][0]['commentsCount'] == number_of_comments
@@ -191,7 +213,8 @@ def test_ledger_comment_count(session, client, jwt):
('filing-status-Withdrawn', Filing.Status.WITHDRAWN.value, 1),
])
-def test_get_all_business_filings_permitted_statuses(session, client, jwt, test_name, filing_status, expected):
+def test_get_all_business_filings_permitted_statuses(app, session, client, jwt, test_name, filing_status, expected,
+ monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger only shows filings with permitted statuses."""
# setup
identifier = 'BC1234567'
@@ -209,10 +232,15 @@ def test_get_all_business_filings_permitted_statuses(session, client, jwt, test_
filing_storage._status = filing_status
filing_storage.skip_status_listener = True
filing_storage.save()
+ headers=create_header(jwt, [UserRoles.system], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
# test
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [UserRoles.system], identifier))
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
# validate
assert len(rv.json.get('filings')) == expected
@@ -233,7 +261,8 @@ def test_get_all_business_filings_permitted_statuses(session, client, jwt, test_
['fileNumber', 'orderDetails']),
])
-def test_ledger_court_order(session, client, jwt, test_name, file_number, order_date, effect_of_order, order_details, expected):
+def test_ledger_court_order(app, session, client, jwt, test_name, file_number, order_date, effect_of_order, order_details, expected,
+ monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger returns court_order values."""
# setup
identifier = 'BC1234567'
@@ -245,10 +274,15 @@ def test_ledger_court_order(session, client, jwt, test_name, file_number, order_
filing_storage.order_details = order_details
filing_storage.save()
+ headers=create_header(jwt, [UserRoles.system], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
# test
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [UserRoles.system], identifier))
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
# validate
assert rv.json['filings'][0]
@@ -260,7 +294,7 @@ def test_ledger_court_order(session, client, jwt, test_name, file_number, order_
assert not filing_json.get('data')
-def test_ledger_display_name_annual_report(session, client, jwt):
+def test_ledger_display_name_annual_report(app, session, client, jwt, monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger returns the correct number of comments."""
# setup
identifier = 'BC1234567'
@@ -275,10 +309,15 @@ def test_ledger_display_name_annual_report(session, client, jwt):
business, filing_storage = ledger_element_setup_help(identifier, 'annualReport')
filing_storage._meta_data = meta_data
filing_storage.save()
+ headers=create_header(jwt, [UserRoles.system], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
# test
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [UserRoles.system], identifier))
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
# validate
assert rv.json['filings'][0]
@@ -287,7 +326,7 @@ def test_ledger_display_name_annual_report(session, client, jwt):
assert filing_json['displayName'] == f'Annual Report ({date.fromisoformat(today).year})'
-def test_ledger_display_unknown_name(session, client, jwt):
+def test_ledger_display_unknown_name(app, session, client, jwt, monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger returns the correct number of comments."""
# setup
identifier = 'BC1234567'
@@ -296,10 +335,15 @@ def test_ledger_display_unknown_name(session, client, jwt):
business, filing_storage = ledger_element_setup_help(identifier, 'someAncientNamedReport')
filing_storage._meta_data = meta_data
filing_storage.save()
+ headers=create_header(jwt, [UserRoles.system], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
# test
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [UserRoles.system], identifier))
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
# validate
assert rv.json['filings'][0]
@@ -308,7 +352,7 @@ def test_ledger_display_unknown_name(session, client, jwt):
assert filing_json['displayName'] == 'Some Ancient Named Report'
-def test_ledger_display_alteration_report(session, client, jwt):
+def test_ledger_display_alteration_report(app, session, client, jwt, monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger returns the correct number of comments."""
# setup
identifier = 'BC1234567'
@@ -322,10 +366,15 @@ def test_ledger_display_alteration_report(session, client, jwt):
business, filing_storage = ledger_element_setup_help(identifier, 'alteration')
filing_storage._meta_data = meta_data
filing_storage.save()
+ headers=create_header(jwt, [UserRoles.system], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
# test
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [UserRoles.system], identifier))
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
# validate
assert rv.json['filings'][0]
@@ -340,7 +389,8 @@ def test_ledger_display_alteration_report(session, client, jwt):
('limitedRestorationExtension', 'Limited Restoration Extension Application'),
('limitedRestorationToFull', 'Conversion to Full Restoration Application'),
])
-def test_ledger_display_restoration(session, client, jwt, restoration_type, expected_display_name):
+def test_ledger_display_restoration(app, session, client, jwt, restoration_type, expected_display_name,
+ monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger returns the correct names of the four restoration types."""
# setup
identifier = 'BC1234567'
@@ -360,10 +410,15 @@ def test_ledger_display_restoration(session, client, jwt, restoration_type, expe
filing['filing']['restoration']['type'] = restoration_type
factory_completed_filing(business, filing, filing_date=filing_date)
+ headers=create_header(jwt, [UserRoles.system], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
# test
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [UserRoles.system], identifier))
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
# validate
assert rv.json['filings']
@@ -378,7 +433,8 @@ def test_ledger_display_restoration(session, client, jwt, restoration_type, expe
('CC', Business.LegalTypes.BC_CCC.value, 'BC Community Contribution Company Incorporation Application'),
('BC', Business.LegalTypes.COMP.value, 'BC Limited Company Incorporation Application'),
])
-def test_ledger_display_incorporation(session, client, jwt, test_name, entity_type, expected_display_name):
+def test_ledger_display_incorporation(app, session, client, jwt, test_name, entity_type, expected_display_name,
+ monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger returns the correct number of comments."""
# setup
identifier = 'BC1234567'
@@ -407,17 +463,22 @@ def test_ledger_display_incorporation(session, client, jwt, test_name, entity_ty
'legalName': business_name}
}
f._meta_data = {**{'applicationDate': today}, **ia_meta}
+ headers=create_header(jwt, [UserRoles.system], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
# test
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [UserRoles.system], identifier))
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
# validate
assert rv.json['filings']
assert rv.json['filings'][0]['displayName'] == expected_display_name
-def test_ledger_display_corrected_incorporation(session, client, jwt):
+def test_ledger_display_corrected_incorporation(app, session, client, jwt, monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger returns the correct number of comments."""
# setup
identifier = 'BC1234567'
@@ -425,10 +486,15 @@ def test_ledger_display_corrected_incorporation(session, client, jwt):
correction = ledger_element_setup_filing(business, 'correction', filing_date=business.founding_date + datedelta.datedelta(months=3))
original.parent_filing_id = correction.id
original.save()
+ headers=create_header(jwt, [UserRoles.system], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
# test
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [UserRoles.system], identifier))
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
# validate
assert rv.json['filings']
@@ -441,7 +507,7 @@ def test_ledger_display_corrected_incorporation(session, client, jwt):
assert False
-def test_ledger_display_corrected_annual_report(session, client, jwt):
+def test_ledger_display_corrected_annual_report(app, session, client, jwt, monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger returns the correct number of comments."""
# setup
identifier = 'BC1234567'
@@ -460,10 +526,15 @@ def test_ledger_display_corrected_annual_report(session, client, jwt):
correction_meta = {'legalFilings': ['annualReport', 'correction']}
correction._meta_data = {**{'applicationDate': today}, **correction_meta}
correction.save()
+ headers=create_header(jwt, [UserRoles.system], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
# test
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [UserRoles.system], identifier))
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
# validate
assert rv.json['filings']
@@ -490,7 +561,8 @@ def test_ledger_display_corrected_annual_report(session, client, jwt):
('unknown-public', None, UserRoles.public_user, 'some-user', '', '', 'some-user'),
]
)
-def test_ledger_redaction(session, client, jwt, test_name, submitter_role, jwt_role, username, firstname, lastname, expected):
+def test_ledger_redaction(app, session, client, jwt, test_name, submitter_role, jwt_role, username, firstname, lastname, expected,
+ monkeypatch, mock_drs_service, mocker):
"""Assert that the core filing is saved to the backing store."""
from legal_api.core.filing import Filing as CoreFiling
try:
@@ -520,9 +592,15 @@ def test_ledger_redaction(session, client, jwt, test_name, submitter_role, jwt_r
new_filing.submitter_roles = submitter_role
setattr(new_filing, 'skip_status_listener', True) # skip status listener
new_filing.save()
-
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [jwt_role], identifier))
+ headers=create_header(jwt, [jwt_role], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
+
+ # test
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
except Exception as err:
print(err)
@@ -530,7 +608,7 @@ def test_ledger_redaction(session, client, jwt, test_name, submitter_role, jwt_r
assert rv.json['filings'][0]['submitter'] == expected
-def test_ledger_display_special_resolution_correction(session, client, jwt):
+def test_ledger_display_special_resolution_correction(app, session, client, jwt, monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger returns the correct number of comments."""
# setup
identifier = 'CP1234567'
@@ -567,10 +645,15 @@ def test_ledger_display_special_resolution_correction(session, client, jwt):
correction_2_meta = {'legalFilings': ['correction']}
correction_2._meta_data = {**{'applicationDate': today}, **correction_2_meta}
correction_2.save()
+ headers=create_header(jwt, [UserRoles.system], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
# test
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [UserRoles.system], identifier))
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
# validate
assert rv.json['filings']
@@ -583,7 +666,7 @@ def test_ledger_display_special_resolution_correction(session, client, jwt):
assert False
-def test_ledger_display_non_special_resolution_correction_name(session, client, jwt):
+def test_ledger_display_non_special_resolution_correction_name(app, session, client, jwt, monkeypatch, mock_drs_service, mocker):
"""Assert that the ledger returns the correct number of comments."""
# setup
identifier = 'CP1234567'
@@ -604,10 +687,15 @@ def test_ledger_display_non_special_resolution_correction_name(session, client,
correction_meta = {'legalFilings': ['correction']}
correction._meta_data = {**{'applicationDate': today}, **correction_meta}
correction.save()
+ headers=create_header(jwt, [UserRoles.system], identifier)
+ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
+ return headers[one]
# test
- rv = client.get(f'/api/v2/businesses/{identifier}/filings',
- headers=create_header(jwt, [UserRoles.system], identifier))
+ with app.test_request_context():
+ monkeypatch.setattr('flask.request.headers.get', mock_auth)
+ rv = client.get(f'/api/v2/businesses/{identifier}/filings',
+ headers=headers)
# validate
assert rv.json['filings']