Esempio n. 1
0
    def test_findSize(self):
        # Given
        sut = Product()
        sizeA = Size(sizeEU="41.25")
        sizeB = Size(sizeEU="38 2/3")
        sizeC = Size(sizeEU="39")
        sut.addSize(sizeA)
        sut.addSize(sizeB)
        sut.addSize(sizeC)

        # When given size not exists
        foundSize = sut.findSize(sizeStr="45")
        # Then
        self.assertIsNone(foundSize, f"Expected that size was not found and "
                                     f"returned value is None, but got '{foundSize}'")

        # When
        foundSize = sut.findSize(sizeStr=sizeA.sizeEU)
        # Then
        self.assertEqual(sizeA, foundSize)

        # When
        foundSize = sut.findSize(sizeStr=sizeB.sizeEU)
        # Then
        self.assertEqual(sizeB, foundSize)

        # When
        foundSize = sut.findSize(sizeStr=sizeC.sizeEU)
        # Then
        self.assertEqual(sizeC, foundSize)
Esempio n. 2
0
 def _decodeProducts(cls, productItems: list) -> List[Product]:
     decodedProducts: List[Product] = list()
     for productItem in productItems:
         product = Product(**productItem)
         product.sizes = cls._decodeSizes(product.sizes)
         decodedProducts.append(product)
     return decodedProducts
    async def _setProductPrice(self, soup: BeautifulSoup,
                               product: Product) -> ProductChanged:
        isProductChanged = False

        try:
            thisProductInfo = soup.find("div",
                                        class_="b-pdp-product-info-section")
            priceElem = thisProductInfo.find(
                "span", class_="b-product-tile-price-item")
            priceAndCurrencyStr = priceElem.text.strip()  # like '98,55 €'
            # Split price and currency
            match = re.search(r"(([0-9.,]+)\s+([^0-9]+))", priceAndCurrencyStr)
            priceStr, currencyStr = match.group(2), match.group(3)
            priceFloat = float(priceStr.replace(",", "."))

        except Exception as e:
            logger.warning("Failed finding product price or currency. %s. %s",
                           e, product.url)
            self._failCount += 1

        else:
            logger.debug(
                "Extracted product price & currency from HTML code. %s",
                product.url)
            if not product.basePrice or product.basePrice != priceFloat:
                product.basePrice = priceFloat
                product.currency = currencyStr
                isProductChanged = True  # note that we never switch back to False

        finally:
            return isProductChanged
Esempio n. 4
0
def run_homework():

    cookie = Product(name="Ciastko", category_name="Jedzenie", unit_price=4)
    # other_cookie = Product(name="Inne ciastko", category_name="Jedzenie", unit_price=4)
    juice = Product(name="Sok", category_name="Napoje", unit_price=3)
    first_order_elements = [
        OrderElement(product=cookie, quantity=3),
        # OrderElement(product=other_cookie, quantity=3),
        OrderElement(product=juice, quantity=4),
    ]
    # first_order_elements.append(OrderElement(product=juice, quantity=4))
    # first_order_elements[0].quantity = 10

    second_order_elements = [
        OrderElement(product=juice, quantity=4),
        OrderElement(product=cookie, quantity=3),
    ]

    first_order = Order(client_first_name="Kuba",
                        client_last_name="Kowalski",
                        order_elements=first_order_elements)
    second_order = Order(client_first_name="Kuba",
                         client_last_name="Kowalski",
                         order_elements=second_order_elements)
    # second_order.client_last_name = "Lewandowski"

    if first_order == second_order:
        print("Te zamówienia są takie same!")
    else:
        print("Te zamówienia są różne!")
Esempio n. 5
0
def run_homework():
    product_one = Product(name="Cookies", category_name="Food", unit_price=3.5)
    product_two = Product(name="Cheese", category_name="Food", unit_price=3.5)
    product_three = Product(name="Cookies",
                            category_name="Food",
                            unit_price=3.5)
    print(f"Products 1 and 2 are equal? {product_one == product_two}")
    print(f"Products 1 and 3 are equal? {product_one == product_three}")
    print(f"Products 2 and 3 are equal? {product_two == product_three}")

    order_element_1 = OrderElement(product_one, 3)
    order_element_2 = OrderElement(product_one, 3)
    order_element_3 = OrderElement(product_two, 4)
    print(
        f"Order elements 1 and 2 are equal? {order_element_1 == order_element_2}"
    )
    print(
        f"Order elements 1 and 3 are equal? {order_element_1 == order_element_3}"
    )
    print(
        f"Order elements 2 and 3 are equal? {order_element_2 == order_element_3}"
    )

    order_1 = Order(client_first_name="Maciej",
                    client_last_name="Sobieszuk",
                    order_elements=[order_element_1, order_element_2])
    order_2 = Order(client_first_name="Maciej",
                    client_last_name="Sobieszuk",
                    order_elements=[order_element_2, order_element_1])
    order_3 = Order(client_first_name="Maciej",
                    client_last_name="Xyz",
                    order_elements=[order_element_1, order_element_2])
    print(f"Orders 1 and 2 are equal? {order_1 == order_2}")
    print(f"Orders 1 and 3 are equal? {order_1 == order_3}")
    print(f"Orders 2 and 3 are equal? {order_2 == order_3}")
Esempio n. 6
0
    def test_lastScanStamp_shouldGetAndSet(self):
        # Given
        sut = Product()

        # When Setter
        sut.lastScanStamp = 123456789.987654321
        # Then Getter
        self.assertEqual(123456789.987654321, sut.lastScanStamp)
Esempio n. 7
0
    def test_addSize_shouldRaiseTypeErrorOnInvalidType(self):
        # Given
        sut = Product()
        invalidType = mock.Mock(spec=dict)

        # When / Then
        with self.assertRaises(TypeError):
            sut.addSize(invalidType)
Esempio n. 8
0
    def test_url_shouldGetAndSet(self):
        # Given
        sut = Product()

        # When Setter
        sut.url = "https://something-to-test/shop"
        # Then Getter
        self.assertEqual("https://something-to-test/shop", sut.url)
Esempio n. 9
0
    def test_name_shouldGetAndSet(self):
        # Given
        sut = Product()

        # When Setter
        sut.name = "My smart product"
        # Then Getter
        self.assertEqual("My smart product", sut.name)
Esempio n. 10
0
    def test_getReleaseDate_shouldReturnNoneWhenReleaseStampIsNotSet(self):
        # Given
        sut = Product()
        sut.invalidateReleaseDate()

        # When
        result = sut.getReleaseDate(forTimezone="America/Indiana/Petersburg", forType=dtt.datetime)

        # Then
        self.assertEqual(None, result)
Esempio n. 11
0
    def test_sizes_setterShouldRaiseOnInvalidType(self):
        # Given
        sut = Product()
        sizeA = mock.Mock(spec=Size)
        invalidType = mock.Mock()
        invalidList = [sizeA, invalidType]

        # When / Then
        with self.assertRaises(TypeError):
            sut.sizes = invalidList
Esempio n. 12
0
    def test_getReleaseDate_shouldReturnReadableString(self):
        # Given
        sut = Product()

        givenDatetime = dtt.datetime(2023, 11, 28, 13, 30, 12)
        givenTimezoneString = "Europe/Berlin"   # See also: pytz.all_timezones
        expectedString = "28.11.2023, 13:30:12"
        sut.setReleaseDate(givenDatetime, timezone=givenTimezoneString)

        # When
        result = sut.getReleaseDate(forTimezone=givenTimezoneString, forType=str)

        # Then
        self.assertEqual(expectedString, result)
Esempio n. 13
0
def run_homework():
    cookie = Product(name="Ciastko", category_name="Jedzenie", unit_price=4)
    tomato = Product(name="Pomidor", category_name="Owoce i warzywa", unit_price=3)
    something = Product(name="Coś", category_name="Nieznana kategoria", unit_price=50)
    ten_cookies = OrderElement(cookie, quantity=10)
    five_tomatoes = OrderElement(tomato, quantity=5)
    single_something = OrderElement(something, quantity=1)

    cookies_tax = TaxCalculator.tax_for_order_element(ten_cookies)
    tomatoes_tax = TaxCalculator.tax_for_order_element(five_tomatoes)
    something_tax = TaxCalculator.tax_for_order_element(single_something)

    print(f"Cena ciastek: {ten_cookies.calculate_price()} + {cookies_tax:.2f}")
    print(f"Cena pomidorów: {five_tomatoes.calculate_price()} + {tomatoes_tax:.2f}")
    print(f"Cena czegoś: {single_something.calculate_price()} + {something_tax:.2f}")
Esempio n. 14
0
    async def _setProductThumbUrl(self, soup: BeautifulSoup, product: Product) -> ProductChanged:
        isProductChanged = False

        try:
            urlThumb = soup.find("li", class_="thumbnail-1") \
                .find("div", class_="wrap") \
                .img["src"]

            # Below code possibly superfluous. The above urlThumb is already valid,
            # but for mighty reasons linking to it in Discord seems to get blocked by BSTN. There's
            # a way to shorten the URL, as the last parts of the URL don't seem to be relevant.
            # Anyway, this won't fix the blocked link in Discord.
            # Example
            # https://www.bstn.com/media/140801/w/280/h/280/n/adidas-zx-8000-fv3269-1.jpg
            # is converted to
            # https://www.bstn.com/media/140801/w/280/h/280/n/0.jpg
            # match = re.search(r".*/h/280/n/", urlThumb)
            # urlThumb = f"{match.group()}0.jpg"

            if not urlThumb: raise AttributeError("No matches in HTML tree.")

        except AttributeError as e:
            logger.warning("Failed finding product image url. %s. %s", e, product.url)
            self._failCount += 1

        else:
            logger.debug("Found product image url. %s", product.url)
            if not product.urlThumb or product.urlThumb != urlThumb:
                product.urlThumb = urlThumb
                isProductChanged = True  # note that we never switch back to False

        finally:
            return isProductChanged
Esempio n. 15
0
def test_product_eq():
    parameters = [
        ("Banan", "Owoc", 2, "Ananas", "Owoc", 4, False),
        ("Stek", "Mięso", 50, "Yaris", "Auto", 10000, False),
        ("Yaris", "Auto", 10000, "Yaris", "Auto", 10000, True),
        ("Banan", "Owoc", 2, "Ananas", "Owoc", 4, True)
    ]

    for params in parameters:
        name, category_name, unit_price, other_name, other_category_name, other_unit_price, expected_result = params
        result = Product(name, category_name, unit_price, Product.identifier) == \
                 Product(other_name, other_category_name, other_unit_price, Product.identifier)
        if result == expected_result:
            print("Super!")
        else:
            print(f"Błąd! Dla danych {params} wynik powinen wynosić {expected_result} a wynosi {result}.")
Esempio n. 16
0
    async def _setProductThumbUrl(self, soup: BeautifulSoup, product: Product) -> ProductChanged:
        isProductChanged = False

        try:
            urlThumb = soup.find("div", class_="thumbnail-1") \
                .find("div", class_="wrap") \
                .img["src"]

            if not urlThumb: raise AttributeError("No matches in HTML tree.")

        except AttributeError as e:
            logger.warning("Failed finding product image url. %s. %s", e, product.url)
            self._failCount += 1

        else:
            logger.debug("Found product image url. %s", product.url)

            # Their image URL is relative so we have to concat the shop's base URL with it.
            absoluteImageURL = urllib.parse.urljoin(self.URL, urlThumb)

            if not product.urlThumb or product.urlThumb != absoluteImageURL:
                product.urlThumb = absoluteImageURL
                isProductChanged = True  # note that we never switch back to False

        finally:
            return isProductChanged
    def test_run(self):
        # Given
        shop = Shop(name="Sneak-a-venue Shop unit test",
                    url=str(self.shopHtmlResponsePath))
        product = Product(url=str(self.productHtmlResponsePath))
        shop.addProduct(product)

        # Results will be written to a temp DB file which path is defined in TempShopRepoHelper.
        repoHelper = TempShopRepoHelper(shops=[shop])

        async def runner():
            # Given
            requestMock = RequestMock()
            messengerMock = MessengerMock(request=requestMock)

            sut = SneakAvenueShopScraper(scrapee=shop,
                                         scrapeeRepo=repoHelper.shopRepo,
                                         request=requestMock,
                                         messenger=messengerMock)

            # When / Then
            try:
                await sut.run()

            except Exception as e:
                self.fail(
                    f"Expected test to run without Exception, but raised: {e}")

            else:
                self.assertEqual(
                    0, sut._failCount,
                    f"Expected fail count to be 0, but is {sut._failCount}")

        asyncio.run(runner())
Esempio n. 18
0
def load_orders(client_first_name, client_last_name, file_name="orders.json"):
    try:
        with open(file_name, "r") as orders_file:
            orders_by_clients_data = json.load(orders_file).get("orders", {})
    except FileNotFoundError:
        orders_by_clients_data = {}

    client_id = f"{client_first_name}-{client_last_name}"
    if client_id not in orders_by_clients_data:
        return []
    orders = orders_by_clients_data[client_id]
    return [
        Order(
            client_first_name=order["client_first_name"],
            client_last_name=order["client_last_name"],
            order_elements=[
                OrderElement(
                    quantity=order_element["quantity"],
                    product=Product(
                        name=order_element["product"]["name"],
                        category=ProductCategory[order_element["product"]
                                                 ["category"]],
                        unit_price=order_element["product"]["unit_price"],
                        identifier=order_element["product"]["identifier"],
                    )) for order_element in order["order_elements"]
            ],
        ) for order in orders
    ]
Esempio n. 19
0
def run_homework():
    first_order = generate_order()
    print(first_order)

    cookies = Product(name="Cookies", category_name="Food", unit_price=5)
    first_order.add_product_to_order(cookies, quantity=10)
    print(first_order)
    async def _setProductThumbUrl(self, soup: BeautifulSoup,
                                  product: Product) -> ProductChanged:
        """
        Search for the following JS code and extract URL:
        <div class="more-views mobilehidden">
           <ul>
            <li>
             <a href="https:// ...
        """
        isProductChanged = False

        try:
            urlThumb = soup.find("div", {"class": "product-img-box"}) \
                .find("div", {"class": "more-views mobilehidden"}) \
                .find_next("a").get("href")

        except AttributeError as e:
            logger.warning("Failed finding product image url. %s. %s", e,
                           product.url)
            self._failCount += 1

        else:
            logger.debug("Found product image url. %s", product.url)
            if not product.urlThumb or product.urlThumb != urlThumb:
                product.urlThumb = urlThumb
                isProductChanged = True  # note that we never switch back to False

        finally:
            return isProductChanged
Esempio n. 21
0
def run_homework():
    first_order = generate_order()
    print(first_order)

    cookie = Product(name="Ciastko", category_name="Jedzenie", unit_price=4)
    first_order.add_product_to_order(cookie, quantity=10)
    print(first_order)
Esempio n. 22
0
def test_product_comparision():
    parameters = [
        ("Ciastka", "Jedzenie", 4, "Ciastka", "Jedzenie", 4, True),
        ("Ciastka", "Jedzenie", 4, "Chleb", "Jedzenie", 4, False),
        ("Ciastka", "Jedzenie", 4, "Ciastka", "Słodycze", 4, False),
        ("Ciastka", "Jedzenie", 4, "Ciastka", "Jedzenie", 8, False),
    ]

    for params in parameters:
        name, category, price, other_name, other_category, other_price, expected_result = params

        result = Product(name, category, price) == Product(other_name, other_category, other_price)
        if result == expected_result:
            print("OK")
        else:
            print(f"Błąd! Dla danych {params} wynik porównania jest {result} a powinien być {expected_result}")
Esempio n. 23
0
    def test_sizes_setterShouldSetCorrectValues(self):
        # Given
        sut = Product()
        sizeA = mock.Mock(spec=Size)
        sizeB = mock.Mock(spec=Size)
        sizeC = mock.Mock(spec=Size)
        sizeA.mockVal = 40
        sizeB.mockVal = 43.5
        sizeC.mockVal = 42.0
        expectedSizes = [sizeA, sizeB, sizeC]

        # When
        sut.sizes = expectedSizes

        # Then
        self.assertListEqual(expectedSizes, sut.sizes)
Esempio n. 24
0
def generate_product(name=None):
    category = ProductCategory.JEDZENIE
    unit_price = random.randint(MIN_UNIT_PRICE, MAX_UNIT_PRICE)
    identifier = random.randint(MIN_IDENTIFIER, MAX_IDENTIFIER)

    if name is None:
        name = f"Product - {identifier}"
    return Product(name, category, unit_price, identifier)
Esempio n. 25
0
    def __init__(self, quantity, name, category, unit_price=None, identifier=None):
        if unit_price is None:
            unit_price = random.randint(1, 100)
        if identifier is None:
            identifier = random.randint(1, 100)

        self.quantity = quantity
        self.product = Product(name=name, category=category, unit_price=unit_price, identifier=identifier)
Esempio n. 26
0
    def test_getReleaseDate_shouldReturnDatetime(self):
        # Given
        sut = Product()

        givenTimezoneString = "US/Alaska"  # See also: pytz.all_timezones
        timezone = pytz.timezone(givenTimezoneString)
        givenDatetime = dtt.datetime(2035, 7, 15, 9, 00, 00)
        # Leave datetime itself untouched, just add the timezone-data:
        expectedLocalDatetime = timezone.localize(givenDatetime)

        sut.setReleaseDate(givenDatetime, timezone=givenTimezoneString)

        # When
        result = sut.getReleaseDate(forTimezone=givenTimezoneString, forType=dtt.datetime)

        # Then
        self.assertEqual(expectedLocalDatetime, result)
Esempio n. 27
0
    def test_setReleaseDate_shouldSetCorrectDate(self):
        # Given
        sut = Product()

        berlinZone = pytz.timezone("Pacific/Fiji")  # See also: pytz.all_timezones
        givenDatetime = dtt.datetime(2020, 4, 18, 16, 00, 00)
        # Leave datetime itself untouched, just add the timezone-data:
        berlinDatetime = berlinZone.localize(givenDatetime)
        # Convert to UTC time:
        utcDatetime: dtt.datetime = berlinDatetime.astimezone(pytz.utc)
        # Convert to UNIX epoch float:
        expectedUtcTimestamp = utcDatetime.timestamp()  # 1587218400.0

        # When
        sut.setReleaseDate(givenDatetime, timezone="Pacific/Fiji")

        self.assertEqual(expectedUtcTimestamp, sut.releaseDateStamp)
    async def _setProductPrice(self, soup: BeautifulSoup,
                               product: Product) -> ProductChanged:
        """ We need to find & extract price and currency from the following JS code:
        <script>
            fbq('track', 'ViewContent', {
            value: '64',
            currency: 'EUR',
            content_ids: '245134',
            content_type: 'product_group',
            });
        </script>
        """
        isProductChanged = False

        jsCodeToFind = "fbq\\(\'track\', \'AddToCart\'"
        reCompiled = re.compile(jsCodeToFind)

        try:
            javascriptStr = soup.find("script",
                                      attrs={
                                          "type": "text/javascript"
                                      },
                                      text=reCompiled).string

            priceStr = re.search(r"value:\s+(.*?)[,\n]",
                                 javascriptStr).group(1).strip("\'")
            priceFloat = float(priceStr)
            currency = re.search(r"currency:\s+(.*?)[,\n]",
                                 javascriptStr).group(1).strip("\'")

        except Exception as e:
            logger.warning("Failed finding product price or currency. %s. %s",
                           e, product.url)
            self._failCount += 1

        else:
            logger.debug("Extracted product price & currency from JS code. %s",
                         product.url)
            if not product.basePrice or product.basePrice != priceFloat:
                product.basePrice = priceFloat
                product.currency = currency
                isProductChanged = True  # note that we never switch back to False

        finally:
            return isProductChanged
Esempio n. 29
0
def test_product_eq():
    parameters = [("Ciastka", "Jedzenie", 4, "Ciastka", "Jedzenie", 4, True),
                  ("Ciastka", "Jedzenie", 4, "Ciastka", "Jedzenie", 5, False),
                  ("Ciastka", "Jedzenie", 4, "Ciastka", "Rozrywka", 4, False),
                  ("Ciastka", "Jedzenie", 4, "Piwo", "Jedzenie", 4, False)]

    for params in parameters:
        name, category_name, price, other_name, other_category_name, other_price, expected_result = params

        result = Product(name, category_name,
                         price) == Product(other_name, other_category_name,
                                           other_price)
        if result == expected_result:
            print("OK")
        else:
            print(
                f"Błąc! Dla danych {params} wynik: {result} powinien być: {expected_result}"
            )
Esempio n. 30
0
    def test_setReleaseDate_shouldLogOnError(self):
        # Given
        sut = Product()
        givenDatetime = dtt.datetime(2020, 1, 30, 15, 40, 00)
        invalidTimezone = "very/invalid"

        loggerName = "shop.product"
        loggerUnderTest = clog.getLogger(loggerName)
        expectedLogLevel = "ERROR"
        expectedPartOfLogMessage = "Could not set product release date"

        # When
        with self.assertLogs(loggerUnderTest, level=expectedLogLevel) as tlog:
            sut.setReleaseDate(givenDatetime, timezone=invalidTimezone)

        # Then
        self.assertEqual(1, len(tlog.output))  # expect one single log message in array
        self.assertIn(f"{expectedLogLevel}:{loggerName}:{expectedPartOfLogMessage}", tlog.output[0])