From 89bd7c894c383e9a3c7c1e2569c638a17d1efac5 Mon Sep 17 00:00:00 2001 From: Ali Zaidi Date: Tue, 23 Nov 2021 14:41:04 +0000 Subject: [PATCH] Revert "LTD-1368 - Page 1 (Exporter)" --- .gitignore | 1 - .pre-commit-config.yaml | 2 +- api/applications/models.py | 24 ++-- api/applications/tests/test_end_user.py | 37 +----- api/conf/settings.py | 19 +-- api/conftest.py | 110 ------------------ .../migrations/0002_add_document_fields.py | 25 ---- api/documents/models.py | 5 - api/parties/models.py | 7 -- api/parties/serializers.py | 34 +++--- api/users/tests/factories.py | 6 - 11 files changed, 40 insertions(+), 230 deletions(-) delete mode 100644 api/documents/migrations/0002_add_document_fields.py diff --git a/.gitignore b/.gitignore index ad424b45e..e76a49f43 100644 --- a/.gitignore +++ b/.gitignore @@ -91,7 +91,6 @@ local_settings.py .env db.sqlite3 -*.sql # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 05104f240..8dde89b34 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,6 +5,6 @@ repos: - id: check-yaml - id: end-of-file-fixer - repo: https://github.com/psf/black - rev: 19.10b0 + rev: 19.3b0 hooks: - id: black diff --git a/api/applications/models.py b/api/applications/models.py index c5eca7403..e7192256d 100644 --- a/api/applications/models.py +++ b/api/applications/models.py @@ -177,17 +177,12 @@ class Meta: ordering = ["created_at"] +# Licence Applications class StandardApplication(BaseApplication): - """ - Application for any of below licences: - - SIEL (Standard Individual Export Licence) - - SITCL (Standard Individual Trade Control Licence) - """ - export_type = models.CharField(choices=ApplicationExportType.choices, default=None, max_length=50) reference_number_on_information_form = models.CharField(blank=True, null=True, max_length=255) have_you_been_informed = models.CharField( - choices=ApplicationExportLicenceOfficialType.choices, blank=True, null=True, default=None, max_length=50 + choices=ApplicationExportLicenceOfficialType.choices, blank=True, null=True, default=None, max_length=50, ) is_shipped_waybill_or_lading = models.BooleanField(blank=True, default=None, null=True) non_waybill_or_lading_route_details = models.TextField(default=None, blank=True, null=True, max_length=2000) @@ -205,13 +200,6 @@ class StandardApplication(BaseApplication): class OpenApplication(BaseApplication): - """ - Application for any of below licences: - - OGEL (Open General Export Licence) - - OIEL (Open Individual Export Licence) - - OITCL (Open Individual Trade Control Licence) - """ - export_type = models.CharField(choices=ApplicationExportType.choices, default=None, max_length=50) is_shipped_waybill_or_lading = models.BooleanField(blank=True, default=None, null=True) non_waybill_or_lading_route_details = models.TextField(default=None, blank=True, null=True, max_length=2000) @@ -290,7 +278,9 @@ class SiteOnApplication(models.Model): class ApplicationDenialReason(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) - application = models.ForeignKey(BaseApplication, related_name="application_denial_reason", on_delete=models.CASCADE) + application = models.ForeignKey( + BaseApplication, related_name="application_denial_reason", on_delete=models.CASCADE, + ) reasons = models.ManyToManyField(DenialReason) reason_details = models.TextField(default=None, blank=True, null=True, max_length=2200) @@ -298,10 +288,10 @@ class ApplicationDenialReason(models.Model): class ExternalLocationOnApplication(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) external_location = models.ForeignKey( - ExternalLocation, related_name="external_locations_on_application", on_delete=models.CASCADE + ExternalLocation, related_name="external_locations_on_application", on_delete=models.CASCADE, ) application = models.ForeignKey( - BaseApplication, related_name="external_application_sites", on_delete=models.CASCADE + BaseApplication, related_name="external_application_sites", on_delete=models.CASCADE, ) diff --git a/api/applications/tests/test_end_user.py b/api/applications/tests/test_end_user.py index df521eace..cc8e86885 100644 --- a/api/applications/tests/test_end_user.py +++ b/api/applications/tests/test_end_user.py @@ -13,37 +13,6 @@ from test_helpers.clients import DataTestClient -class TestEndUserDocument: - @mock.patch("api.documents.tasks.scan_document_for_viruses.now") - def test_requires_extra_fields_for_end_user( - self, scan_document_for_viruses_function, end_user, exporter_client_with_standard_application - ): - """ - For end-user we require to know if the content is in English and - if company letterhead is there (LTD-1368) - """ - client, app = exporter_client_with_standard_application - app.add_party(end_user.party) - url = reverse("applications:party_document", kwargs={"pk": app.id, "party_pk": end_user.party.id}) - - # Missing required fields for end-user - response = client.post(url, {"name": "document_name.pdf", "s3_key": "s3_keykey.pdf", "size": 123456}) - assert response.status_code == status.HTTP_400_BAD_REQUEST - - # With required fields for end-user - response = client.post( - url, - { - "name": "document_name.pdf", - "s3_key": "s3_keykey.pdf", - "size": 123456, - "is_content_english": True, - "includes_company_letterhead": False, - }, - ) - assert response.status_code == status.HTTP_201_CREATED - - class EndUserOnDraftTests(DataTestClient): def setUp(self): super().setUp() @@ -67,8 +36,6 @@ def setUp(self): "name": "document_name.pdf", "s3_key": "s3_keykey.pdf", "size": 123456, - "is_content_english": True, - "includes_company_letterhead": False, } @parameterized.expand([SubType.GOVERNMENT, SubType.COMMERCIAL, SubType.OTHER]) @@ -89,7 +56,7 @@ def test_set_end_user_on_draft_standard_application_successful(self, data_type): response = self.client.post(self.url, data, **self.exporter_headers) party_on_application = PartyOnApplication.objects.get( - application=self.draft, party__type=PartyType.END_USER, deleted_at__isnull=True + application=self.draft, party__type=PartyType.END_USER, deleted_at__isnull=True, ) self.draft.refresh_from_db() @@ -151,7 +118,7 @@ def test_set_end_user_on_draft_standard_application_failure(self, data): self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( PartyOnApplication.objects.filter( - party__type=PartyType.END_USER, application=self.draft, deleted_at__isnull=True + party__type=PartyType.END_USER, application=self.draft, deleted_at__isnull=True, ).count(), 1, ) diff --git a/api/conf/settings.py b/api/conf/settings.py index bc2f72f5a..86fc236ae 100644 --- a/api/conf/settings.py +++ b/api/conf/settings.py @@ -113,11 +113,6 @@ "django_audit_log_middleware", ] - -if DEBUG: - INSTALLED_APPS += ["django_extensions"] - - MIDDLEWARE = [ "allow_cidr.middleware.AllowCIDRMiddleware", "django.middleware.security.SecurityMiddleware", @@ -293,7 +288,9 @@ # Elasticsearch configuration LITE_API_ENABLE_ES = env.bool("LITE_API_ENABLE_ES", False) if LITE_API_ENABLE_ES: - ELASTICSEARCH_DSL = {"default": {"hosts": env.str("ELASTICSEARCH_HOST")}} + ELASTICSEARCH_DSL = { + "default": {"hosts": env.str("ELASTICSEARCH_HOST")}, + } ENABLE_SPIRE_SEARCH = env.bool("ENABLE_SPIRE_SEARCH", False) @@ -306,7 +303,10 @@ ELASTICSEARCH_APPLICATION_INDEXES["SPIRE"] = SPIRE_APPLICATION_INDEX_NAME ELASTICSEARCH_PRODUCT_INDEXES["SPIRE"] = SPIRE_PRODUCT_INDEX_NAME - INSTALLED_APPS += ["django_elasticsearch_dsl", "django_elasticsearch_dsl_drf"] + INSTALLED_APPS += [ + "django_elasticsearch_dsl", + "django_elasticsearch_dsl_drf", + ] if "test" not in sys.argv: @@ -389,7 +389,10 @@ if DEBUG and "django_extensions" in sys.modules: INSTALLED_APPS.append("django_extensions") - GRAPH_MODELS = {"all_applications": False, "group_models": True} + GRAPH_MODELS = { + "all_applications": False, + "group_models": True, + } # SSO config diff --git a/api/conftest.py b/api/conftest.py index 79e48e94a..25bd64852 100644 --- a/api/conftest.py +++ b/api/conftest.py @@ -4,10 +4,6 @@ import pytest # noqa from django.conf import settings -from rest_framework.test import APIClient - -from api.users.models import ExporterUser, GovUser, UserOrganisationRelationship -from api.users.libraries.user_to_token import user_to_token def camelcase_to_underscore(string): @@ -66,109 +62,3 @@ def {fixture_name}(db): if settings.DEBUG: for fixture_name in sorted(fixture_names): print(f"pytest.fixture: {fixture_name}") - - -# -------------------------- Clients ---------------------------- - - -class LiteClient(APIClient): - """ - APIClient from rest_framework with appropriate headers when we login() - """ - - def __init__(self, *args, **kwargs): - self.headers = {} - super().__init__(*args, **kwargs) - - def login(self, user, organisation=None): - """ - Set headers appropriately for exporter and gov user - - If no organisation given for exporter, an existing one will be used - """ - self.user = user # just for easy reference so we can always see who we are logged-in as - if isinstance(user, ExporterUser): - - # Re-use existing organisation if not explicitly given one - if not organisation: - try: - org_relation = UserOrganisationRelationship.objects.get(user=user) - except UserOrganisationRelationship.DoesNotExist: - raise Exception("Exporter user must belong to an organisation to be able and login") - organisation = org_relation.organisation - - # Use given organisation - else: - try: - UserOrganisationRelationship.objects.get(user=user, organisation=organisation) - except UserOrganisationRelationship.DoesNotExist: - raise Exception( - "Missing UserOrganisationRelationship for given exporter_user and organisation. Create the relationship and try again." - ) - - self.headers = { - "HTTP_EXPORTER_USER_TOKEN": user_to_token(user.baseuser_ptr), - "HTTP_ORGANISATION_ID": str(organisation.id), - } - - elif isinstance(user, GovUser): - if organisation: - raise Exception("No organisation required for gov user") - self.headers = {"HTTP_GOV_USER_TOKEN": user_to_token(user)} - else: - raise Exception(f"Unknown user type: {user}") - - def get(self, *args, **kwargs): - return super().get(*args, **kwargs, **self.headers) - - def post(self, *args, **kwargs): - return super().post(*args, **kwargs, **self.headers) - - def put(self, *args, **kwargs): - return super().put(*args, **kwargs, **self.headers) - - def patch(self, *args, **kwargs): - return super().patch(*args, **kwargs, **self.headers) - - def delete(self, *args, **kwargs): - return super().delete(*args, **kwargs, **self.headers) - - def head(self, *args, **kwargs): - return super().head(*args, **kwargs, **self.headers) - - def options(self, *args, **kwargs): - return super().options(*args, **kwargs, **self.headers) - - -@pytest.fixture -def exporter_client_with_standard_application(exporter_user_factory, standard_application_factory): - """ - Return: A client logged-in as exporter and their application - """ - exporter_user = exporter_user_factory() - relation = UserOrganisationRelationship.objects.get(user=exporter_user) - organisation = relation.organisation - standard_application = standard_application_factory(organisation=organisation) - client = LiteClient() - client.login(exporter_user, organisation) - return client, standard_application - - -# -------------------------- Fixtures --------------------------- - - -@pytest.fixture -def end_user(party_factory, party_on_application_factory): - from api.parties.enums import PartyType - - return party_on_application_factory(party=party_factory(type=PartyType.END_USER)) - - -@pytest.fixture -def standard_application(standard_application_factory): - return standard_application_factory() - - -@pytest.fixture -def open_application(open_application_factory): - return open_application_factory() diff --git a/api/documents/migrations/0002_add_document_fields.py b/api/documents/migrations/0002_add_document_fields.py deleted file mode 100644 index e4bdc21d8..000000000 --- a/api/documents/migrations/0002_add_document_fields.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 3.1.13 on 2021-11-22 14:48 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("documents", "0001_initial"), - ] - - operations = [ - migrations.AddField( - model_name="document", - name="includes_company_letterhead", - field=models.BooleanField( - help_text="Does the document include at least one page on company letterhead?", null=True - ), - ), - migrations.AddField( - model_name="document", - name="is_content_english", - field=models.BooleanField(help_text="Is the document in English?", null=True), - ), - ] diff --git a/api/documents/models.py b/api/documents/models.py index c7242e18d..5d81c685d 100644 --- a/api/documents/models.py +++ b/api/documents/models.py @@ -16,11 +16,6 @@ class Document(TimestampableModel): virus_scanned_at = models.DateTimeField(null=True, blank=True) safe = models.NullBooleanField() - is_content_english = models.BooleanField(null=True, help_text="Is the document in English?") - includes_company_letterhead = models.BooleanField( - null=True, help_text="Does the document include at least one page on company letterhead?" - ) - def __str__(self): return self.name diff --git a/api/parties/models.py b/api/parties/models.py index 4c938939c..d10285a9b 100644 --- a/api/parties/models.py +++ b/api/parties/models.py @@ -74,13 +74,6 @@ class Party(TimestampableModel): objects = PartyManager() - def __repr__(self): - return f"<{self.__class__.__name__} ({self.type}): {self.pk}>" - - @property - def is_end_user(self): - return self.type == PartyType.END_USER - class Meta: ordering = ["name"] diff --git a/api/parties/serializers.py b/api/parties/serializers.py index b5ece9cdd..9d2567fce 100644 --- a/api/parties/serializers.py +++ b/api/parties/serializers.py @@ -137,7 +137,14 @@ class PartyDocumentSerializer(serializers.ModelSerializer): class Meta: model = PartyDocument - fields = ("id", "name", "s3_key", "size", "party", "safe", "is_content_english", "includes_company_letterhead") + fields = ( + "id", + "name", + "s3_key", + "size", + "party", + "safe", + ) def create(self, validated_data): document = super(PartyDocumentSerializer, self).create(validated_data) @@ -145,19 +152,6 @@ def create(self, validated_data): process_document(document) return document - def validate(self, attrs): - validated_data = super().validate(attrs) - if attrs["party"].is_end_user: - if "is_content_english" not in attrs: - raise serializers.ValidationError({"is_content_english": "Select if the document is in English"}) - if "includes_company_letterhead" not in attrs: - raise serializers.ValidationError( - { - "includes_company_letterhead": "Select if the document includes at least one page on company letterhead" - } - ) - return validated_data - class AdditionalContactSerializer(serializers.ModelSerializer): name = serializers.CharField(error_messages=PartyErrors.NAME, max_length=100) @@ -171,7 +165,17 @@ class AdditionalContactSerializer(serializers.ModelSerializer): class Meta: model = Party - fields = ("id", "name", "phone_number", "email", "details", "address", "country", "type", "organisation") + fields = ( + "id", + "name", + "phone_number", + "email", + "details", + "address", + "country", + "type", + "organisation", + ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/api/users/tests/factories.py b/api/users/tests/factories.py index 25585c5a9..412730fd1 100644 --- a/api/users/tests/factories.py +++ b/api/users/tests/factories.py @@ -30,12 +30,6 @@ class ExporterUserFactory(factory.django.DjangoModelFactory): class Meta: model = models.ExporterUser - @factory.post_generation - def add_organisation(exporter_user, create, extracted, **kwargs): - if create: - organisation = kwargs.get("organisation", OrganisationFactory()) - UserOrganisationRelationshipFactory(user=exporter_user, organisation=organisation) - class RoleFactory(factory.django.DjangoModelFactory): name = "fake_role"