From 585ef1dfa1fd9a56ea3f502e7153392450464029 Mon Sep 17 00:00:00 2001 From: Henry Cooksley Date: Tue, 26 Nov 2024 12:16:22 +0000 Subject: [PATCH] Add test for issuing a licence --- api/data_workspace/v2/serializers.py | 8 +- api/data_workspace/v2/tests/bdd/conftest.py | 62 ++++++++++++++++ .../bdd/scenarios/goods_on_licences.feature | 14 ++++ .../v2/tests/bdd/test_applications.py | 74 ------------------- .../v2/tests/bdd/test_goods_on_licences.py | 35 +++++++++ api/data_workspace/v2/urls.py | 3 - api/data_workspace/v2/views.py | 3 +- lite_routing | 2 +- pii-secret-exclude.txt | 1 + 9 files changed, 120 insertions(+), 82 deletions(-) create mode 100644 api/data_workspace/v2/tests/bdd/scenarios/goods_on_licences.feature create mode 100644 api/data_workspace/v2/tests/bdd/test_goods_on_licences.py diff --git a/api/data_workspace/v2/serializers.py b/api/data_workspace/v2/serializers.py index c0a4f4029..944c270de 100644 --- a/api/data_workspace/v2/serializers.py +++ b/api/data_workspace/v2/serializers.py @@ -11,7 +11,6 @@ ) from api.cases.enums import LicenceDecisionType from api.cases.models import LicenceDecision -from api.cases.models import Case from api.licences.models import GoodOnLicence from api.staticdata.countries.models import Country from api.staticdata.report_summaries.models import ReportSummary @@ -96,10 +95,15 @@ class Meta: "description", "good_id", ) + + class GoodOnLicenceSerializer(serializers.ModelSerializer): + good_id = serializers.UUIDField() + licence_id = serializers.UUIDField() + class Meta: model = GoodOnLicence - fields = ("id", "good_id", "licence_id") + fields = ("good_id", "licence_id") class ApplicationSerializer(serializers.ModelSerializer): diff --git a/api/data_workspace/v2/tests/bdd/conftest.py b/api/data_workspace/v2/tests/bdd/conftest.py index 2c1bace8a..ffc4710d7 100644 --- a/api/data_workspace/v2/tests/bdd/conftest.py +++ b/api/data_workspace/v2/tests/bdd/conftest.py @@ -25,6 +25,10 @@ PartyOnApplicationFactory, StandardApplicationFactory, ) +from api.cases.enums import ( + AdviceType, +) +from api.cases.tests.factories import FinalAdviceFactory from api.cases.enums import CaseTypeEnum from api.cases.models import CaseType from api.core.constants import ( @@ -33,6 +37,7 @@ Roles, ) from api.goods.tests.factories import GoodFactory +from api.flags.enums import SystemFlags from api.documents.libraries.s3_operations import init_s3_client from api.letter_templates.models import LetterTemplate from api.parties.tests.factories import PartyDocumentFactory @@ -364,3 +369,60 @@ def check_rows(client, parse_table, unpage_data, table_name, rows): expected_data.append({key: value for key, value in zip(keys, row)}) expected_data = cast_to_types(expected_data, table_metadata["fields"]) assert actual_data == expected_data + + +@pytest.fixture() +def parse_attributes(parse_table): + def _parse_attributes(attributes): + kwargs = {} + table_data = parse_table(attributes) + for key, value in table_data[1:]: + kwargs[key] = value + return kwargs + + return _parse_attributes + + +@pytest.fixture() +def issue_licence(api_client, lu_case_officer, gov_headers, siel_template): + def _issue_licence(application): + data = {"action": AdviceType.APPROVE, "duration": 24} + for good_on_app in application.goods.all(): + good_on_app.quantity = 100 + good_on_app.value = 10000 + good_on_app.save() + data[f"quantity-{good_on_app.id}"] = str(good_on_app.quantity) + data[f"value-{good_on_app.id}"] = str(good_on_app.value) + FinalAdviceFactory(user=lu_case_officer, case=application, good=good_on_app.good) + + issue_date = datetime.datetime.now() + data.update({"year": issue_date.year, "month": issue_date.month, "day": issue_date.day}) + + application.flags.remove(SystemFlags.ENFORCEMENT_CHECK_REQUIRED) + + url = reverse("applications:finalise", kwargs={"pk": application.pk}) + response = api_client.put(url, data=data, **gov_headers) + assert response.status_code == 200, response.content + response = response.json() + + data = { + "template": str(siel_template.id), + "text": "", + "visible_to_exporter": False, + "advice_type": AdviceType.APPROVE, + } + url = reverse( + "cases:generated_documents:generated_documents", + kwargs={"pk": str(application.pk)}, + ) + response = api_client.post(url, data=data, **gov_headers) + assert response.status_code == 201, response.content + + url = reverse( + "cases:finalise", + kwargs={"pk": str(application.pk)}, + ) + response = api_client.put(url, data={}, **gov_headers) + assert response.status_code == 201 + + return _issue_licence diff --git a/api/data_workspace/v2/tests/bdd/scenarios/goods_on_licences.feature b/api/data_workspace/v2/tests/bdd/scenarios/goods_on_licences.feature new file mode 100644 index 000000000..1e78d22ed --- /dev/null +++ b/api/data_workspace/v2/tests/bdd/scenarios/goods_on_licences.feature @@ -0,0 +1,14 @@ +@db +Feature: Goods On Licences + +Scenario: Issue a licence + Given a standard application with the following goods: + | id | name | + | 61d193bd-a4d8-4f7d-8c07-1ac5e03ea2c7 | A controlled good | + And a draft licence with attributes: + | name | value | + | id | 962b4948-b87a-42fe-9c2b-61bdefd9cd21 | + When the licence is issued + Then the `goods_on_licences` table has the following rows: + | good_id | licence_id | + | 61d193bd-a4d8-4f7d-8c07-1ac5e03ea2c7 | 962b4948-b87a-42fe-9c2b-61bdefd9cd21 | diff --git a/api/data_workspace/v2/tests/bdd/test_applications.py b/api/data_workspace/v2/tests/bdd/test_applications.py index 1a2c1ac20..63bce3634 100644 --- a/api/data_workspace/v2/tests/bdd/test_applications.py +++ b/api/data_workspace/v2/tests/bdd/test_applications.py @@ -4,8 +4,6 @@ from freezegun import freeze_time -from moto import mock_aws - from pytest_bdd import ( given, parsers, @@ -13,7 +11,6 @@ when, ) -from django.conf import settings from django.urls import reverse from api.applications.enums import ApplicationExportType @@ -28,7 +25,6 @@ AdviceType, ) from api.cases.tests.factories import FinalAdviceFactory -from api.documents.libraries.s3_operations import init_s3_client from api.flags.enums import SystemFlags from api.licences.enums import LicenceStatus from api.parties.tests.factories import ( @@ -41,18 +37,6 @@ scenarios("./scenarios/applications.feature") -@pytest.fixture() -def parse_attributes(parse_table): - def _parse_attributes(attributes): - kwargs = {} - table_data = parse_table(attributes) - for key, value in table_data[1:]: - kwargs[key] = value - return kwargs - - return _parse_attributes - - def run_processing_time_task(start, up_to): processing_time_task_run_date_time = start.replace(hour=22, minute=30) up_to = pytz.utc.localize(datetime.datetime.fromisoformat(up_to)) @@ -62,19 +46,6 @@ def run_processing_time_task(start, up_to): processing_time_task_run_date_time = processing_time_task_run_date_time + datetime.timedelta(days=1) -@pytest.fixture(autouse=True) -def mock_s3(): - with mock_aws(): - s3 = init_s3_client() - s3.create_bucket( - Bucket=settings.AWS_STORAGE_BUCKET_NAME, - CreateBucketConfiguration={ - "LocationConstraint": settings.AWS_REGION, - }, - ) - yield - - @pytest.fixture def submit_application(api_client, exporter_headers, mocker): def _submit_application(draft_application): @@ -103,51 +74,6 @@ def _submit_application(draft_application): return _submit_application -@pytest.fixture() -def issue_licence(api_client, lu_case_officer, gov_headers, siel_template): - def _issue_licence(application): - data = {"action": AdviceType.APPROVE, "duration": 24} - for good_on_app in application.goods.all(): - good_on_app.quantity = 100 - good_on_app.value = 10000 - good_on_app.save() - data[f"quantity-{good_on_app.id}"] = str(good_on_app.quantity) - data[f"value-{good_on_app.id}"] = str(good_on_app.value) - FinalAdviceFactory(user=lu_case_officer, case=application, good=good_on_app.good) - - issue_date = datetime.datetime.now() - data.update({"year": issue_date.year, "month": issue_date.month, "day": issue_date.day}) - - application.flags.remove(SystemFlags.ENFORCEMENT_CHECK_REQUIRED) - - url = reverse("applications:finalise", kwargs={"pk": application.pk}) - response = api_client.put(url, data=data, **gov_headers) - assert response.status_code == 200, response.content - response = response.json() - - data = { - "template": str(siel_template.id), - "text": "", - "visible_to_exporter": False, - "advice_type": AdviceType.APPROVE, - } - url = reverse( - "cases:generated_documents:generated_documents", - kwargs={"pk": str(application.pk)}, - ) - response = api_client.post(url, data=data, **gov_headers) - assert response.status_code == 201, response.content - - url = reverse( - "cases:finalise", - kwargs={"pk": str(application.pk)}, - ) - response = api_client.put(url, data={}, **gov_headers) - assert response.status_code == 201 - - return _issue_licence - - @pytest.fixture() def caseworker_change_status(api_client, lu_case_officer, lu_case_officer_headers): def _caseworker_change_status(application, status): diff --git a/api/data_workspace/v2/tests/bdd/test_goods_on_licences.py b/api/data_workspace/v2/tests/bdd/test_goods_on_licences.py new file mode 100644 index 000000000..b63dc856b --- /dev/null +++ b/api/data_workspace/v2/tests/bdd/test_goods_on_licences.py @@ -0,0 +1,35 @@ +from pytest_bdd import given, parsers, scenarios, when + +from api.applications.tests.factories import GoodOnApplicationFactory +from api.licences.tests.factories import StandardLicenceFactory +from api.licences.enums import LicenceStatus + +scenarios("./scenarios/goods_on_licences.feature") + + +@given(parsers.parse("a standard application with the following goods:{goods}"), target_fixture="standard_application") +def standard_application_with_following_goods(parse_table, goods, standard_application): + standard_application.goods.all().delete() + good_attributes = parse_table(goods)[1:] + for id, name in good_attributes: + GoodOnApplicationFactory( + application=standard_application, + id=id, + good__name=name, + ) + return standard_application + + +@given(parsers.parse("a draft licence with attributes:{attributes}"), target_fixture="draft_licence") +def draft_licence_with_attributes(parse_attributes, attributes, standard_application): + draft_licence = StandardLicenceFactory( + case=standard_application, status=LicenceStatus.DRAFT, **parse_attributes(attributes) + ) + return draft_licence + + +@when("the licence is issued") +def licence_is_issued(standard_application, issue_licence): + issue_licence(standard_application) + issued_application = standard_application.refresh_from_db() + return issued_application diff --git a/api/data_workspace/v2/urls.py b/api/data_workspace/v2/urls.py index 25304d198..99ad9f58e 100644 --- a/api/data_workspace/v2/urls.py +++ b/api/data_workspace/v2/urls.py @@ -7,9 +7,6 @@ router_v2.register(views.CountryViewSet) router_v2.register(views.DestinationViewSet) router_v2.register(views.GoodViewSet) -<<<<<<< HEAD router_v2.register(views.GoodDescriptionViewSet) -======= router_v2.register(views.GoodOnLicenceViewSet) ->>>>>>> ea66a2a2 (Add goods on licences endpoint initial commit) router_v2.register(views.ApplicationViewSet) diff --git a/api/data_workspace/v2/views.py b/api/data_workspace/v2/views.py index 067154e5e..107e7ac62 100644 --- a/api/data_workspace/v2/views.py +++ b/api/data_workspace/v2/views.py @@ -34,7 +34,6 @@ GoodDescriptionSerializer, GoodSerializer, LicenceDecisionSerializer, - LicenceDecisionType, GoodOnLicenceSerializer, ) from api.licences.enums import LicenceStatus @@ -124,7 +123,7 @@ def get_closed_statuses(): class GoodOnLicenceViewSet(BaseViewSet): serializer_class = GoodOnLicenceSerializer queryset = GoodOnLicence.objects.exclude( - licence__case__status__=CaseStatusEnum.DRAFT, + licence__case__status__status=CaseStatusEnum.DRAFT, licence__status=LicenceStatus.DRAFT, ) diff --git a/lite_routing b/lite_routing index fbad92cd7..514fdb9de 160000 --- a/lite_routing +++ b/lite_routing @@ -1 +1 @@ -Subproject commit fbad92cd75b1195ad3c2262e6a95c6b7e8c925ef +Subproject commit 514fdb9de41b40f812ef9d461bac405cc01405d8 diff --git a/pii-secret-exclude.txt b/pii-secret-exclude.txt index ecf825368..03d87ef58 100644 --- a/pii-secret-exclude.txt +++ b/pii-secret-exclude.txt @@ -117,3 +117,4 @@ api/staticdata/report_summaries/migrations/data/0002_add_report_summaries/report api/cases/generated_documents/tests/data/dummy.pdf api/cases/generated_documents/tests/data/signed.pdf api/data_workspace/v2/tests/bdd/scenarios/applications.feature +api/data_workspace/v2/tests/bdd/scenarios/goods_on_licences.feature