Exemplo n.º 1
0
def test_prevent_quota_definition_deletion(
    unapproved_transaction,
    date_ranges,
    date_range,
    update_type,
    error_expected,
):
    """
    QAM does not like handling deletions of active Quota Definitions.

    Ensure an active Quota Definition cannot be deleted.
    """
    quota_definition = factories.QuotaDefinitionFactory.create(
        valid_between=getattr(date_ranges, date_range), )

    deleted = quota_definition.new_version(
        workbasket=unapproved_transaction.workbasket,
        transaction=unapproved_transaction,
        update_type=update_type,
    )

    error_expected = error_expected and (update_type == UpdateType.DELETE)
    with raises_if(BusinessRuleViolation, error_expected):
        business_rules.PreventQuotaDefinitionDeletion(
            deleted.transaction).validate(deleted, )
Exemplo n.º 2
0
def test_GA13(area_code, expect_error):
    """The referenced geographical area id (member) can only be linked to a
    country or region."""
    membership = factories.GeographicalMembershipFactory.create(
        member__area_code=area_code, )

    with raises_if(BusinessRuleViolation, expect_error):
        business_rules.GA13(membership.transaction).validate(membership)
Exemplo n.º 3
0
def test_ACN2_allowed_application_codes(app_code, expect_error):
    """The referenced additional code type must have as application code "non-
    Meursing" or "Export Refund for Processed Agricultural Goods”."""
    additional_code = factories.AdditionalCodeFactory.create(
        type__application_code=app_code, )
    with raises_if(BusinessRuleViolation, expect_error):
        business_rules.ACN2(
            additional_code.transaction).validate(additional_code)
Exemplo n.º 4
0
def test_blocking_of_fcfs_quotas_only(mechanism, error_expected):
    """Blocking periods are only applicable to FCFS quotas."""
    blocking = factories.QuotaBlockingFactory.create(
        quota_definition__order_number__mechanism=mechanism, )

    with raises_if(BusinessRuleViolation, error_expected):
        business_rules.BlockingOnlyOfFCFSQuotas(
            blocking.transaction).validate(blocking)
Exemplo n.º 5
0
 def do_assert(
     factory: Type[factories.TrackedModelMixin],
     business_rule: Type[BusinessRule],
     identifying_fields: Optional[Dict[str, Any]] = None,
 ):
     make_record, error_expected = request.param
     duplicate = make_record(factory, identifying_fields)
     with raises_if(BusinessRuleViolation, error_expected):
         business_rule(duplicate.transaction).validate(duplicate)
Exemplo n.º 6
0
def test_suspension_of_fcfs_quotas_only(mechanism, error_expected):
    """Quota suspensions are only applicable to First Come First Served
    quotas."""
    suspension = factories.QuotaSuspensionFactory.create(
        quota_definition__order_number__mechanism=mechanism, )

    with raises_if(BusinessRuleViolation, error_expected):
        business_rules.SuspensionsOnlyToFCFSQuotas(
            suspension.transaction).validate(suspension, )
Exemplo n.º 7
0
def test_GA16(date_ranges, group_validity, membership_validity, expect_error):
    """The validity period of the geographical area group must span all
    membership periods of its members."""

    membership = factories.GeographicalMembershipFactory.create(
        geo_group__valid_between=getattr(date_ranges, group_validity),
        valid_between=getattr(date_ranges, membership_validity),
    )
    with raises_if(BusinessRuleViolation, expect_error):
        business_rules.GA16(membership.transaction).validate(membership)
Exemplo n.º 8
0
def test_duties_validator(
    duties,
    error_expected,
    date_ranges,
    duty_sentence_parser,
):
    # duty_sentence_parser populates data needed by the DutySentenceParser
    # removing it will cause the test to fail.
    with raises_if(ValidationError, error_expected):
        validate_duties(duties, date_ranges.normal)
Exemplo n.º 9
0
    def check(factory):
        first_instance = factory.create()
        instance = factory.create(
            update_type=update_type,
            version_group=first_instance.version_group,
        )

        with raises_if(UpdateValidity.Violation, expected_error):
            UpdateValidity(instance.transaction).validate(instance)

        return True
Exemplo n.º 10
0
def test_ON13(area_code, expect_error):
    """An exclusion can only be entered if the order number origin is a geographical
    area group (area code = 1).
    """

    origin = factories.QuotaOrderNumberOriginFactory.create(
        geographical_area__area_code=area_code, )
    exclusion = factories.QuotaOrderNumberOriginExclusionFactory.create(
        origin=origin)

    with raises_if(BusinessRuleViolation, expect_error):
        business_rules.ON13(exclusion.transaction).validate(exclusion)
Exemplo n.º 11
0
def test_NIG10(date_ranges, valid_between, expect_error):
    """The successor must be applicable the day after the end date of the old
    code."""
    successor = factories.GoodsNomenclatureSuccessorFactory.create(
        absorbed_into_goods_nomenclature__valid_between=date_ranges.normal,
        replaced_goods_nomenclature__valid_between=getattr(
            date_ranges,
            valid_between,
        ),
    )
    with raises_if(BusinessRuleViolation, expect_error):
        business_rules.NIG10(successor.transaction).validate(successor)
Exemplo n.º 12
0
def test_QA6(existing_relation, new_relation, error_expected):
    """Sub-quotas associated with the same main quota must have the same
    relation type."""

    existing = factories.QuotaAssociationFactory.create(
        sub_quota_relation_type=existing_relation, )
    assoc = factories.QuotaAssociationFactory.create(
        main_quota=existing.main_quota,
        sub_quota_relation_type=new_relation,
    )

    with raises_if(BusinessRuleViolation, error_expected):
        business_rules.QA6(assoc.transaction).validate(assoc)
Exemplo n.º 13
0
def test_NIG18_NIG19(application_code, item_id, error_expected):
    """Footnotes with a footnote type for which the application type = "CN
    footnotes" must be linked to CN lines (all codes up to 8 digits). Footnotes
    with a footnote type for which the application type = "TARIC footnotes" can
    be associated at any level."""

    assoc = factories.FootnoteAssociationGoodsNomenclatureFactory.create(
        associated_footnote__footnote_type__application_code=application_code,
        goods_nomenclature__item_id=item_id,
    )

    with raises_if(BusinessRuleViolation, error_expected):
        business_rules.NIG18(assoc.transaction).validate(assoc)
Exemplo n.º 14
0
def test_NIG7(date_ranges, valid_between, expect_error):
    """The origin must be applicable the day before the start date of the new
    code entered."""
    origin = factories.GoodsNomenclatureOriginFactory.create(
        derived_from_goods_nomenclature__valid_between=date_ranges.normal,
        new_goods_nomenclature__valid_between=getattr(
            date_ranges,
            valid_between,
        ),
    )

    with raises_if(BusinessRuleViolation, expect_error):
        business_rules.NIG7(origin.transaction).validate(origin)
Exemplo n.º 15
0
def test_ON2(date_ranges, existing_range, new_range, ranges_overlap):
    """There may be no overlap in time of two quota order numbers with the same
    quota order number id."""

    existing = factories.QuotaOrderNumberFactory.create(valid_between=getattr(
        date_ranges, existing_range), )

    order_number = factories.QuotaOrderNumberFactory.create(
        order_number=existing.order_number,
        valid_between=getattr(date_ranges, new_range),
    )

    with raises_if(BusinessRuleViolation, ranges_overlap):
        business_rules.ON2(order_number.transaction).validate(order_number)
Exemplo n.º 16
0
def test_NIG24(date_ranges, valid_between, expect_error):
    """When the same footnote is associated more than once with the same
    nomenclature then there may be no overlap in their association periods."""

    existing = factories.FootnoteAssociationGoodsNomenclatureFactory.create(
        valid_between=date_ranges.normal,
    )
    association = factories.FootnoteAssociationGoodsNomenclatureFactory.create(
        associated_footnote=existing.associated_footnote,
        goods_nomenclature=existing.goods_nomenclature,
        valid_between=getattr(date_ranges, valid_between),
    )

    with raises_if(BusinessRuleViolation, expect_error):
        business_rules.NIG24(association.transaction).validate(association)
Exemplo n.º 17
0
    def check(factory):
        instance = factory.create(update_type=update_type)

        # Create a future instance – the business rule should ignore this
        # but the test for CREATE will fail if it does not.
        factory.create(
            update_type=UpdateType.UPDATE,
            transaction__workbasket=instance.transaction.workbasket,
            transaction__order=instance.transaction.order + 1,
        )

        with raises_if(UpdateValidity.Violation, expected_error):
            UpdateValidity(instance.transaction).validate(instance)

        return True
Exemplo n.º 18
0
    def check(
        factory: Type[DjangoModelFactory],
        business_rule: Type[ValidityPeriodContained],
        **factory_kwargs,
    ):
        container_validity, contained_validity, fully_spanned = spanning_dates

        contained = getattr(business_rule, "contained_field_name") or ""
        container = getattr(business_rule, "container_field_name") or ""

        # If the test is checking an UPDATE or a DELETE, set the dates to be
        # valid on the original version so that we can tell if it is
        # successfully checking the later version.
        validity_on_contained = (container_validity
                                 if update_type != UpdateType.CREATE else
                                 contained_validity)

        object = factory.create(
            **factory_kwargs,
            **{
                f"{contained}{'__' if contained else ''}valid_between":
                validity_on_contained,
                f"{contained}{'__' if contained else ''}update_type":
                UpdateType.CREATE,
                f"{container}{'__' if container else ''}valid_between":
                container_validity,
            },
        )
        workbasket = object.transaction.workbasket

        if update_type != UpdateType.CREATE:
            # Make a new version of the contained model with the actual dates we
            # are testing, first finding the correct contained model to use.
            contained_obj = object
            if contained:
                with override_current_transaction(
                        workbasket.current_transaction):
                    contained_obj = (object.get_versions().current().
                                     follow_path(contained).get())
            contained_obj.new_version(
                workbasket,
                valid_between=contained_validity,
                update_type=update_type,
            )

        error_expected = update_type != UpdateType.DELETE and not fully_spanned
        with raises_if(business_rule.Violation, error_expected):
            business_rule(workbasket.current_transaction).validate(object)
Exemplo n.º 19
0
def test_QA4(coefficient, expect_error):
    """
    Whenever a sub-quota receives a coefficient, this has to be a strictly
    positive decimal number.

    When it is not specified a value of 1 is always assumed
    """

    kwargs = {}
    if coefficient is not None:
        kwargs["coefficient"] = coefficient

    assoc = factories.QuotaAssociationFactory.create(**kwargs)

    with raises_if(BusinessRuleViolation, expect_error):
        business_rules.QA4(assoc.transaction).validate(assoc)
Exemplo n.º 20
0
def test_QA3(main_volume, main_unit, sub_volume, sub_unit, expect_error):
    """When converted to the measurement unit of the main quota, the volume of a
    sub-quota must always be lower than or equal to the volume of the main
    quota."""

    units = defaultdict(factories.MeasurementUnitFactory)

    assoc = factories.QuotaAssociationFactory(
        main_quota__volume=main_volume,
        main_quota__measurement_unit=units[main_unit],
        sub_quota__volume=sub_volume,
        sub_quota__measurement_unit=units[sub_unit],
    )

    with raises_if(BusinessRuleViolation, expect_error):
        business_rules.QA3(assoc.transaction).validate(assoc)
Exemplo n.º 21
0
def test_footnote_update(new_data, expected_valid, use_update_form):
    """
    Tests that footnote update view allows an empty dict and that it is possible
    to update the end date day, month, and year to an earlier date.

    We expect a later end date to fail because the validity period extends
    beyond that of the footnote type. We test end date, rather than start_date
    because it is not possible to edit the start date through the view without
    separately updating the description start date beforehand.
    """
    with raises_if(ValidationError, not expected_valid):
        use_update_form(
            factories.FootnoteFactory(
                valid_between=factories.date_ranges("big"),
                footnote_type__valid_between=factories.date_ranges("big"),
            ),
            new_data,
        )
Exemplo n.º 22
0
def test_ROIMB46(regulation_id, role_type, expect_error, delete_record):
    """A base regulation cannot be deleted if it is used as a justification
    regulation, except for ‘C’ regulations used only in measures as both
    measure-generating regulation and justification regulation."""
    # We should not be deleting base regulations. Also, we will not be using the
    # justification regulation field, though there will be a lot of EU regulations where
    # the justification regulation field is set.

    regulation = factories.RegulationFactory.create(
        regulation_id=regulation_id,
        role_type=role_type,
    )
    measure = factories.MeasureFactory.create(
        valid_between=factories.date_ranges("normal"),
        generating_regulation=regulation,
        terminating_regulation=regulation,
    )
    assert measure.terminating_regulation == regulation

    deleted = delete_record(regulation)
    with raises_if(BusinessRuleViolation, expect_error):
        business_rules.ROIMB46(deleted.transaction).validate(deleted)
Exemplo n.º 23
0
def test_QA5(existing_volume, new_volume, coeff, type, error_expected):
    """
    Whenever a sub-quota is defined with the ‘equivalent’ type, it must have the
    same volume as the other sub-quotas associated with the parent quota.

    Moreover it must be defined with a coefficient not equal to 1.

    A sub-quota defined with the 'normal' type must have a coefficient of 1.
    """

    existing = factories.QuotaAssociationFactory.create(
        sub_quota__volume=Decimal(existing_volume),
        sub_quota_relation_type=type,
    )
    assoc = factories.QuotaAssociationFactory.create(
        main_quota=existing.main_quota,
        sub_quota__volume=Decimal(new_volume),
        sub_quota_relation_type=type,
        coefficient=Decimal(coeff),
    )

    with raises_if(BusinessRuleViolation, error_expected):
        business_rules.QA5(assoc.transaction).validate(assoc)
Exemplo n.º 24
0
def test_NIG2(
    date_ranges,
    parent_validity,
    self_validity,
    child_validity,
    expect_error,
):
    """
    The validity period of the goods nomenclature must be within the validity
    period of the product line above in the hierarchy.

    Also covers NIG3
    """
    parent = factories.GoodsNomenclatureIndentFactory.create(
        indented_goods_nomenclature__valid_between=getattr(
            date_ranges,
            parent_validity,
        ),
        indented_goods_nomenclature__item_id="2901000000",
        indent=0,
    )
    self = factories.GoodsNomenclatureIndentFactory.create(
        indented_goods_nomenclature__valid_between=getattr(date_ranges, self_validity),
        indented_goods_nomenclature__item_id="2901210000",
        indent=1,
    )
    child = factories.GoodsNomenclatureIndentFactory.create(
        indented_goods_nomenclature__item_id="2901290000",
        indented_goods_nomenclature__valid_between=getattr(date_ranges, child_validity),
        indent=2,
    )

    # Running against a lone code should never error
    business_rules.NIG2(parent.transaction).validate(parent)

    with raises_if(BusinessRuleViolation, expect_error):
        business_rules.NIG2(type(child.transaction).objects.last()).validate(self)
Exemplo n.º 25
0
def test_quota_definition_must_have_one_unit(has_unit, has_currency, error_expected):
    with raises_if(IntegrityError, error_expected):
        factories.QuotaDefinitionFactory.create(
            is_monetary=has_currency,
            is_physical=has_unit,
        )
Exemplo n.º 26
0
def test_regulation_update(new_data, expected_valid, use_update_form):
    with raises_if(ValidationError, not expected_valid):
        use_update_form(factories.UIRegulationFactory(), new_data)
Exemplo n.º 27
0
def test_footnote_create_form(use_create_form, new_data, expected_valid):
    with raises_if(ValidationError, not expected_valid):
        use_create_form(models.Footnote, new_data)
Exemplo n.º 28
0
def test_no_blank_descriptions(description, error_expected):
    description = factories.TestModelDescription1Factory(
        description=description)
    with raises_if(BusinessRuleViolation, error_expected):
        NoBlankDescription(description.transaction).validate(description)
Exemplo n.º 29
0
def test_footnote_description_update(new_data, expected_valid,
                                     use_update_form):
    with raises_if(ValidationError, not expected_valid):
        use_update_form(factories.FootnoteDescriptionFactory(), new_data)
Exemplo n.º 30
0
def test_additional_code_create_form(use_create_form, new_data,
                                     expected_valid):
    with raises_if(ValidationError, not expected_valid):
        use_create_form(AdditionalCode, new_data)