Skip to content

Commit

Permalink
fix: adjusted iLink document validation
Browse files Browse the repository at this point in the history
- Added validation to invalid document_id
- Added validation with success response without a pdf document
  • Loading branch information
Tiago-Salles authored and igobranco committed Oct 30, 2024
1 parent 02973ab commit c820b4c
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 7 deletions.
107 changes: 107 additions & 0 deletions apps/billing/mocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,113 @@
}


ILINK_RESPONSE_MOCK_NO_DOCUMENT = {
"success": "true",
"response": {
"data": [
{
"attachments": [],
}
]
},
}

ILINK_RESPONSE_MOCK_WRONG_PDF_KEY = {
"success": "true",
"response": {
"data": [
{
"attachments": [
{
"type": "pdF",
"file": "https://ilink.pt/ilink-api/file/lPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
"identifier": "FT 1/1",
"ubl_type": "invoice_representation",
"hash": "pPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
},
{
"type": "pDf",
"file": "https://ilink.pt/ilink-api/file/lPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
"identifier": "FT 1/1",
"ubl_type": "invoice_representation",
"hash": "pPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
},
{
"type": "Pdf",
"file": "https://ilink.pt/ilink-api/file/lPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
"identifier": "FT 1/1",
"ubl_type": "invoice_representation",
"hash": "pPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
},
{
"type": "PDf",
"file": "https://ilink.pt/ilink-api/file/lPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
"identifier": "FT 1/1",
"ubl_type": "invoice_representation",
"hash": "pPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
},
{
"type": "pDF",
"file": "https://ilink.pt/ilink-api/file/lPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
"identifier": "FT 1/1",
"ubl_type": "invoice_representation",
"hash": "pPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
},
{
"type": "PdF",
"file": "https://ilink.pt/ilink-api/file/lPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
"identifier": "FT 1/1",
"ubl_type": "invoice_representation",
"hash": "pPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
},
{
"type": "PD F",
"file": "https://ilink.pt/ilink-api/file/lPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
"identifier": "FT 1/1",
"ubl_type": "invoice_representation",
"hash": "pPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
},
{
"type": "p df",
"file": "https://ilink.pt/ilink-api/file/lPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
"identifier": "FT 1/1",
"ubl_type": "invoice_representation",
"hash": "pPikLsRAJEyjGmHsrAVATZuJgba7xgjf7dgJsJ85eEd8ScQbAEwG8ovh0IeP",
},
],
}
]
},
}


ILINK_RESPONSE_MOCK_NO_PDF_DOCUMENT = {
"success": "true",
"response": {
"data": [
{
"attachments": [
{
"type": "xml",
"file": "https://ilink.acin.pt/ilinktests-api/file/sadad21dsg435fcjdsfjht43uhfdsncoijdsfds",
"identifier": "FT 1/43324",
"ubl_type": "xml_representation",
"hash": "sadad21dsg435fcjdsfjht43uhfdsncoijdsfds",
},
{
"type": "txt",
"file": "https://ilink.acin.pt/ilinktests-api/file/5regedggfdgfdfgfdgfdgfdgfdgfdgfdgdgdf432543t",
"identifier": "ANG JJZH6HPJ-00001",
"ubl_type": "qr_code",
"hash": "5regedggfdgfdfgfdgfdgfdgfdgfdgfdgdgdf432543t",
},
],
}
]
},
}


def xml_success_response_mock(data):
return f"""
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wss="http://www.adonix.com/WSS">
Expand Down
26 changes: 20 additions & 6 deletions apps/billing/services/receipt_host_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,22 @@ def __check_status_code(self, response: requests.Response):
except Exception:
raise requests.exceptions.RequestException(response=response)

def __raise_document_not_found(self):
not_found_response = requests.Response()
not_found_response.status_code = 404
raise requests.exceptions.RequestException(response=not_found_response)

def get_document(self, document_id: str):
"""
This method gets the file url, it calls the receipt host giving the required parameters.
The `document_id` is a transaction parameter, it is the returned id from the transaction processor.
The `__receipt_bearer_token` is setted in the environment.
The `__receipt_bearer_token` is set in the environment.
"""

if not document_id:
self.__raise_document_not_found()

response = requests.get(
url=f"{self.__receipt_host_url}",
params={"document_number": document_id, "document_type": "issued"},
Expand All @@ -31,11 +40,16 @@ def get_document(self, document_id: str):
)
self.__check_status_code(response=response)
response = response.json()
document_informations = [
response = response["response"]["data"]

document = [
attachment
for data in response["response"]["data"]
for data in response
for attachment in data["attachments"]
if attachment["type"] == "pdf"
][0]
if attachment["type"] and str(attachment["type"]).replace(" ", "").upper() == "PDF"
]

if document:
return document[0]["file"]

return document_informations["file"]
self.__raise_document_not_found()
72 changes: 71 additions & 1 deletion apps/billing/tests/test_receipt_host_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@
from rest_framework.test import APIClient

from apps.billing.factories import TransactionFactory
from apps.billing.mocks import ILINK_RESPONSE_MOCK, UNAUTHORIZED_ILINK_RESPONSE, MockResponse
from apps.billing.mocks import (
ILINK_RESPONSE_MOCK,
ILINK_RESPONSE_MOCK_NO_DOCUMENT,
ILINK_RESPONSE_MOCK_NO_PDF_DOCUMENT,
ILINK_RESPONSE_MOCK_WRONG_PDF_KEY,
UNAUTHORIZED_ILINK_RESPONSE,
MockResponse,
)
from apps.billing.models import Transaction


Expand Down Expand Up @@ -134,3 +141,66 @@ def test_get_document_unauthorized(self, mocked_post):

self.assertEqual(response.status_code, 500)
self.assertEqual(response.data["response"], "Occurred an error getting the document")

@mock.patch("requests.get", lambda *args, **kwargs: MockResponse("File not found", status_code=404))
def test_get_document_file_document_id_not_valid(self):
"""
This test ensures when the `document_id` is not valid, it will return `404`
"""

self.api_client.credentials(HTTP_AUTHORIZATION=f"Token {self.token}")

self.transaction.document_id = None
self.transaction.save()
response = self.api_client.get(f"/api/billing/receipt-link/{self.transaction.transaction_id}/")
self.assertEqual(response.status_code, 404)

self.transaction.document_id = ""
self.transaction.save()
response = self.api_client.get(f"/api/billing/receipt-link/{self.transaction.transaction_id}/")
self.assertEqual(response.status_code, 404)

self.transaction.document_id = " "
self.transaction.save()
response = self.api_client.get(f"/api/billing/receipt-link/{self.transaction.transaction_id}/")
self.assertEqual(response.status_code, 404)

@mock.patch("requests.get", lambda *args, **kwargs: MockResponse(ILINK_RESPONSE_MOCK_NO_DOCUMENT, status_code=200))
def test_get_document_file_without_document(self):
"""
This test ensures when `iLink` return a success response without any document link
it will be returned `404`
"""

self.api_client.credentials(HTTP_AUTHORIZATION=f"Token {self.token}")
response = self.api_client.get(f"/api/billing/receipt-link/{self.transaction.transaction_id}/")

self.assertEqual(response.status_code, 404)

@mock.patch(
"requests.get", lambda *args, **kwargs: MockResponse(ILINK_RESPONSE_MOCK_NO_PDF_DOCUMENT, status_code=200)
)
def test_get_document_file_without_pdf_document(self):
"""
This test ensures when `iLink` return a success response without a PDF document link
it will be returned `404`
"""

self.api_client.credentials(HTTP_AUTHORIZATION=f"Token {self.token}")
response = self.api_client.get(f"/api/billing/receipt-link/{self.transaction.transaction_id}/")

self.assertEqual(response.status_code, 404)

@mock.patch(
"requests.get", lambda *args, **kwargs: MockResponse(ILINK_RESPONSE_MOCK_WRONG_PDF_KEY, status_code=200)
)
def test_get_document_file_wrong_pdf_key_in_response(self):
"""
This test ensures when `iLink` return a success response without a PDF document link
it will be returned `404`
"""

self.api_client.credentials(HTTP_AUTHORIZATION=f"Token {self.token}")
response = self.api_client.get(f"/api/billing/receipt-link/{self.transaction.transaction_id}/")

self.assertEqual(response.status_code, 200)

0 comments on commit c820b4c

Please sign in to comment.