Пример #1
0
 def test_widget_from_type(self):
     self.assertEqual(widget_from_type("1"),
                      get_dotted_path(forms.widgets.TextInput))
     self.assertEqual(widget_from_type(1), get_dotted_path(FloatInput))
     self.assertEqual(widget_from_type(True),
                      get_dotted_path(forms.widgets.CheckboxInput))
     self.assertEqual(widget_from_type(datetime.datetime.now()),
                      get_dotted_path(forms.widgets.DateTimeInput))
     self.assertEqual(widget_from_type(1.11), get_dotted_path(FloatInput))
Пример #2
0
    def test_get_processed_unit_and_value(self):
        units: UnitManager = UnitManager()
        with self.subTest("str"):
            self.assertEqual(units.get_processed_unit_and_value("str"),
                             Value(value="str"))

        with self.subTest("valid unit"):
            parsed_value: UnitValue = units.get_processed_unit_and_value("1kg")
            kg_unit: Unit = Unit.objects.get(
                name="kilogram", widget=get_dotted_path(FloatInput))
            self.assertEqual(parsed_value, UnitValue(value=1, unit=kg_unit))

        with self.subTest("undefined unit"):
            parsed_value: UnitValue = units.get_processed_unit_and_value(
                "1lkj")
            self.assertEqual(parsed_value, Value(value="1lkj"))

        with self.subTest("range value"):
            parsed_value: RangeUnitValue = units.get_processed_unit_and_value(
                "200-240v")
            volt_unit: Unit = Unit.objects.get(
                name="volt", widget=get_dotted_path(FloatInput))
            self.assertEqual(
                parsed_value,
                RangeUnitValue(unit=volt_unit, value_low=200, value_high=240))

        with self.subTest("bool value"):
            for value in ["yes", "Y", "true", "True"]:
                parsed_value: UnitValue = units.get_processed_unit_and_value(
                    value)
                unit: Unit = Unit.objects.get(name="bool",
                                              widget=get_dotted_path(
                                                  forms.widgets.CheckboxInput))
                self.assertEqual(parsed_value, UnitValue(unit=unit,
                                                         value=True))

        with self.subTest("irregular string"):
            string = "5 year full warranty and 10 year parts upon registration"
            parsed_value: UnitValue = units.get_processed_unit_and_value(
                string)
            unit: Unit = Unit.objects.get(name="year",
                                          widget=get_dotted_path(FloatInput))
            self.assertEqual(parsed_value, UnitValue(value=5, unit=unit))
def set_up_attributes():
    load_size_unit, _ = Unit.objects.get_or_create(name="kilogram", widget=get_dotted_path(FloatInput))
    litres_unit, _ = Unit.objects.get_or_create(name="litres", widget=get_dotted_path(FloatInput))
    spin_unit, _ = Unit.objects.get_or_create(name="revolutions_per_minute", widget=get_dotted_path(FloatInput))
    energy_unit, _ = Unit.objects.get_or_create(name="kwh", widget=get_dotted_path(FloatInput))
    currency, _ = Unit.objects.get_or_create(name="€", alternate_names=["euro"], widget=get_dotted_path(FloatInput), repeat=HOURLY)

    washers = Category.objects.get(name="washing machines")
    fridges = Category.objects.get(name="fridges")
    AttributeType.objects.get_or_create(name="brand")
    load_size, _ = AttributeType.objects.get_or_create(name="load size", category=washers, unit=load_size_unit)
    capacity, _ = AttributeType.objects.get_or_create(name="capacity", category=fridges, unit=litres_unit)
    spin, _ = AttributeType.objects.get_or_create(name="spin speed", category=washers, unit=spin_unit)
    energy, _ = AttributeType.objects.get_or_create(name="energy usage", category=washers, unit=energy_unit)
    AttributeType.objects.get_or_create(name="price", unit=currency)

    CategoryAttributeConfig.objects.get_or_create(attribute_type=load_size, category=washers, weight=5, order=1, scoring=SCORING_NUMERICAL_HIGHER)
    CategoryAttributeConfig.objects.get_or_create(attribute_type=spin, category=washers, weight=4, order=2, scoring=SCORING_NUMERICAL_HIGHER)
    CategoryAttributeConfig.objects.get_or_create(attribute_type=energy, category=washers, weight=3, order=3, scoring=SCORING_NUMERICAL_LOWER)
 def test_website_create_product_attribute(self):
     website: Website = mommy.make(Website)
     product: Product = mommy.make(Product)
     attribute: AttributeType = mommy.make(AttributeType,
                                           unit__widget=get_dotted_path(
                                               forms.widgets.NumberInput))
     product_attribute: WebsiteProductAttribute = website.create_product_attribute(
         product, attribute, "1")
     self.assertEqual(product_attribute.website, website)
     self.assertEqual(product_attribute.attribute_type, attribute)
     self.assertEqual(product_attribute.data['value'], 1)
    def test_custom_get_or_create__product_attribute(self):
        attribute_type: AttributeType = mommy.make(
            AttributeType, unit__widget=get_dotted_path(FloatInput))
        product: Product = mommy.make(Product)
        created_attribute: ProductAttribute = ProductAttribute.objects.custom_get_or_create(
            product, attribute_type, "299")
        self.assertEqual(created_attribute.attribute_type, attribute_type)
        self.assertEqual(created_attribute.product, product)
        self.assertEqual(created_attribute.data['value'], 299.0)

        retrieved_attribute: ProductAttribute = ProductAttribute.objects.custom_get_or_create(
            product, attribute_type, "299")
        self.assertEqual(retrieved_attribute, created_attribute)
    def test_unit(self):
        with self.subTest("text"):
            unit: Unit = mommy.make(Unit,
                                    widget=get_dotted_path(
                                        forms.widgets.TextInput))
            self.assertEqual(unit.serializer, serializers[forms.CharField])
            self.assertEqual(unit.field_class, forms.CharField)
            self.assertEqual(unit.widget_class, forms.widgets.TextInput)

        with self.subTest("int"):
            unit: Unit = mommy.make(Unit,
                                    widget=get_dotted_path(
                                        forms.widgets.NumberInput))
            self.assertEqual(unit.serializer, serializers[forms.IntegerField])
            self.assertEqual(unit.field_class, forms.IntegerField)
            self.assertEqual(unit.widget_class, forms.widgets.NumberInput)

        with self.subTest("float"):
            unit: Unit = mommy.make(Unit, widget=get_dotted_path(FloatInput))
            self.assertEqual(unit.serializer, serializers[forms.FloatField])
            self.assertEqual(unit.field_class, forms.FloatField)
            self.assertEqual(unit.widget_class, FloatInput)

        with self.subTest("bool"):
            unit: Unit = mommy.make(Unit,
                                    widget=get_dotted_path(
                                        forms.widgets.CheckboxInput))
            self.assertEqual(unit.serializer, serializers[forms.BooleanField])
            self.assertEqual(unit.field_class, forms.BooleanField)
            self.assertEqual(unit.widget_class, forms.widgets.CheckboxInput)

        with self.subTest("datetime"):
            unit: Unit = mommy.make(Unit,
                                    widget=get_dotted_path(
                                        forms.widgets.DateTimeInput))
            self.assertEqual(unit.serializer, serializers[forms.DateTimeField])
            self.assertEqual(unit.field_class, forms.DateTimeField)
            self.assertEqual(unit.widget_class, forms.widgets.DateTimeInput)
 def setUpClass(cls) -> None:
     super().setUpClass()
     cls.website: Website = mommy.make(Website,
                                       name="test_website",
                                       currency__name="€")
     cls.category: Category = mommy.make(Category, name="washing machines")
     cls.product: Product = mommy.make(Product, model="model_number")
     cls.gram: Unit = mommy.make(Unit,
                                 name="gram",
                                 widget=get_dotted_path(FloatInput))
     cls.attribute: AttributeType = mommy.make(AttributeType,
                                               name="test_attr",
                                               unit=cls.gram)
     cls.product_attribute: ProductAttribute = mommy.make(
         ProductAttribute,
         product=cls.product,
         attribute_type=cls.attribute)
Пример #8
0
    def test_get_or_create_unit(self):
        units: UnitManager = UnitManager()
        self.assertEqual(units.get_or_create_unit("1"), Value(value=1))

        with self.subTest("unit created"):
            self.assertFalse(Unit.objects.exists())
            parsed_value: UnitValue = units.get_or_create_unit("1kg")
            kg_unit: Unit = Unit.objects.get(
                name="kilogram", widget=get_dotted_path(FloatInput))
            self.assertEqual(parsed_value.unit, kg_unit)
            self.assertEqual(parsed_value.value, 1)

        with self.subTest("existing unit - with conversion"):
            parsed_value: UnitValue = units.get_or_create_unit("2000g",
                                                               unit=kg_unit)
            self.assertEqual(parsed_value.unit, kg_unit)
            self.assertEqual(parsed_value.value, 2)
 def test_product_attributes_serialize(self):
     attribute_type: AttributeType = mommy.make(
         AttributeType,
         name="weight",
         unit=mommy.make(Unit,
                         name="kg",
                         widget=get_dotted_path(FloatInput)))
     attr_1 = mommy.make(ProductAttribute,
                         attribute_type=attribute_type,
                         data={'value': '100'})
     attr_2 = mommy.make(ProductAttribute,
                         attribute_type=attribute_type,
                         data={'value': '200.20'})
     attrs = ProductAttribute.objects.serialize()
     self.assertEqual(attrs.get(pk=attr_1.pk).data['value'], 100.0)
     self.assertEqual(attrs.get(pk=attr_2.pk).data['value'], 200.20)
     mommy.make(ProductAttribute,
                attribute_type=attribute_type,
                data={'value': 'test'})
     with self.assertRaises(UndefinedUnitError) as context:
         ProductAttribute.objects.serialize()
     self.assertEqual(str(context.exception),
                      "'test' is not defined in the unit registry")
    (forms.widgets.CheckboxInput, forms.BooleanField),
    (forms.widgets.DateTimeInput, forms.DateTimeField),
])

# Set of supported field type classes
FIELD_TYPES = set(WIDGETS.values())

WIDGET_NAMES = {
    forms.widgets.TextInput: _("Text"),
    forms.widgets.NumberInput: _("Number (integer)"),
    forms.widgets.CheckboxInput: _("Checkbox"),
    forms.widgets.DateTimeInput: _("Date & Time"),
    FloatInput: _("Number (decimal)"),
}

WIDGET_CHOICES = [(get_dotted_path(cls), WIDGET_NAMES.get(cls, cls.__name__))
                  for cls in WIDGETS.keys()]

OPERATOR_MEAN = 'mean'
OPERATOR_MAX = 'max'
OPERATOR_MIN = 'min'
OPERATOR_SUM = 'sum'

OPERATORS = (OPERATOR_MEAN, OPERATOR_MAX, OPERATOR_MIN, OPERATOR_SUM)

EPREL_API_ROOT_URL = 'https://eprel.ec.europa.eu/api/products/'

WEBSITE_TYPE_RETAILER = 'retailer'
WEBSITE_TYPE_SUPPLIER = 'supplier'
WEBSITE_TYPES = (
    (WEBSITE_TYPE_RETAILER, _('Retailer')),
    def test_attribute_type_convert_unit(self):
        kilogram: Unit = mommy.make(Unit,
                                    name="kilogram",
                                    widget=get_dotted_path(FloatInput))
        attribute_type: AttributeType = mommy.make(AttributeType,
                                                   name="weight",
                                                   unit=kilogram)

        with self.subTest("same unit type"):
            self.assertEqual(
                attribute_type.convert_unit(kilogram).unit, kilogram)

        gram: Unit = mommy.make(Unit,
                                name="gram",
                                widget=get_dotted_path(FloatInput))
        mommy.make(ProductAttribute,
                   attribute_type=attribute_type,
                   data={'value': 7})
        with self.subTest("convert to grams"):
            self.assertEqual(attribute_type.convert_unit(gram).unit, gram)
            self.assertTrue(
                ProductAttribute.objects.filter(attribute_type=attribute_type,
                                                data__value=7000))

        with self.subTest("unit is None"):
            attribute_type_1: AttributeType = mommy.make(AttributeType,
                                                         unit=None)
            attribute_type_2: AttributeType = mommy.make(AttributeType,
                                                         unit=None)
            self.assertIsNone(
                attribute_type_1.convert_unit(attribute_type_2.unit).unit)

        with self.subTest("mismatch units"):
            litre: Unit = mommy.make(Unit,
                                     name="litre",
                                     widget=get_dotted_path(FloatInput))
            mommy.make(ProductAttribute,
                       attribute_type=attribute_type,
                       data={'value': 7})
            with self.assertRaises(Exception) as context:
                attribute_type.convert_unit(litre)
            self.assertEqual(
                str(context.exception),
                "Cannot convert from 'gram' ([mass]) to 'liter' ([length] ** 3)"
            )
            self.assertTrue(
                ProductAttribute.objects.filter(attribute_type=attribute_type,
                                                attribute_type__unit=gram,
                                                data__value=7))

        with self.subTest("text conversion attempt"):
            mg: Unit = mommy.make(Unit,
                                  name="mg",
                                  widget=get_dotted_path(FloatInput))
            mommy.make(ProductAttribute,
                       attribute_type=attribute_type,
                       data={'value': 'test'})
            with self.assertRaises(Exception) as context:
                attribute_type.convert_unit(mg)
            self.assertEqual(str(context.exception),
                             "'test' is not defined in the unit registry")
            self.assertTrue(
                ProductAttribute.objects.filter(attribute_type=attribute_type,
                                                attribute_type__unit=gram,
                                                data__value='test'))

        with self.subTest("adding new unit"):
            kg: Unit = mommy.make(Unit,
                                  name="kg",
                                  widget=get_dotted_path(FloatInput))
            attribute_type: AttributeType = mommy.make(AttributeType,
                                                       unit=None)
            mommy.make(ProductAttribute,
                       attribute_type=attribute_type,
                       data={'value': '700'})
            attribute_type.convert_unit(kg)
            self.assertEqual(
                AttributeType.objects.get(pk=attribute_type.pk).unit, kg)
            self.assertTrue(
                ProductAttribute.objects.filter(attribute_type=attribute_type,
                                                data__value=700.0))
 def setUpClass(cls) -> None:
     super().setUpClass()
     cls.website: Website = mommy.make(Website, name="test_website", currency__name="€", currency__widget=get_dotted_path(FloatInput))
     cls.category: Category = mommy.make(Category, name="washing machines")
     cls.product: Product = mommy.make(Product, model="model_number", category=cls.category)
     cls.energy_label_pdf_url = "https://whirlpool-cdn.thron.com/static/7UO8OG_NEL859991596350_9DDFJI.pdf"
def set_up_websites():
    currency, _ = Unit.objects.get_or_create(name="€", alternate_names=["euro"], widget=get_dotted_path(FloatInput), repeat=HOURLY)
    harvey_norman, _ = Website.objects.get_or_create(name="harvey_norman", domain="harveynorman.ie", currency=currency)
    laundry, _ = Category.objects.get_or_create(name="laundry")
    cooling, _ = Category.objects.get_or_create(name="cooling")
    washing_machines, _ = Category.objects.get_or_create(name="washing machines", parent=laundry, alternate_names=["washers", "front loaders"])
    fridges, _ = Category.objects.get_or_create(name="fridges", parent=cooling)
    EprelCategory.objects.get_or_create(category=washing_machines, name="washingmachines2019")
    EprelCategory.objects.get_or_create(category=washing_machines, name="washingmachines")
    Url.objects.get_or_create(url="https://www.harveynorman.ie/home-appliances/appliances/washing-machines/", url_type=CATEGORY, website=harvey_norman, category=washing_machines)

    table_selector, _ = Selector.objects.get_or_create(selector_type=TABLE, css_selector="#content_features table.table-product-features tr", website=harvey_norman)
    Selector.objects.get_or_create(selector_type=TABLE_LABEL_COLUMN, css_selector="th strong::text", website=harvey_norman, parent=table_selector)
    Selector.objects.get_or_create(selector_type=TABLE_VALUE_COLUMN, css_selector="td::text", website=harvey_norman, parent=table_selector)
    Selector.objects.get_or_create(selector_type=PRICE, css_selector=".price-num:nth-child(2)::text", website=harvey_norman)
    Selector.objects.get_or_create(selector_type=MODEL, css_selector=".product-id.meta::text", website=harvey_norman)
    Selector.objects.get_or_create(selector_type=LINK, css_selector=".product-info a", website=harvey_norman)
    Selector.objects.get_or_create(selector_type=PAGINATION, css_selector="li a.next", website=harvey_norman)
    Selector.objects.get_or_create(selector_type=IMAGE, css_selector='.cm-image-previewer.image-magnifier-image::attr(href)', website=harvey_norman)