Example #1
0
 def test_delete_report(self):
     victim = PriceReport.fetch(self.report1_key, self.keeper)
     product = victim.product
     victim.delete_from(self.keeper)
     transaction.commit()
     self.assertNotIn(victim, product)
     self.assertNotIn(victim, PriceReport.fetch_all(self.keeper))
Example #2
0
    def test_report_assembly_new_product(self):
        from uuid import uuid4
        product_title = u'Молоко Great Milk TWO 1L'
        reporter_name = 'Jill'
        merchant_title = "Scotty's grocery"
        raw_data1 = {
            'product_title': product_title,
            'price_value': 42.6,
            'url': 'http://scottys.com/products/milk/1',
            'merchant_title': merchant_title,
            'date_time': None,
            'reporter_name': reporter_name
        }
        uuid_ = uuid4()
        report, stats = PriceReport.assemble(storage_manager=self.keeper,
                                             uuid=uuid_,
                                             **raw_data1)
        transaction.commit()
        self.keeper.close()

        self.keeper = open_storage()
        stored_report = PriceReport.fetch(report.key, self.keeper)
        self.assertEqual(report.key, stored_report.key)
        self.assertEqual(report.key, str(uuid_))

        product = Product.fetch(product_title, self.keeper)
        self.assertEqual(product_title, product.title)
        self.assertIn(report, product.reports)

        category = ProductCategory.fetch('milk', self.keeper)
        self.assertIn(product, category.products)

        merchant = Merchant.fetch(merchant_title, self.keeper)
        self.assertEqual(merchant_title, merchant.title)
        self.assertIn(product, merchant)
Example #3
0
    def test_price_report_lifetime(self):
        milk = ProductCategory.fetch("milk", self.keeper)

        # add an outdated report
        PriceReport.assemble(
            price_value=15.40,
            product_title=u"Молоко Минувших дней 1л",
            reporter_name="John",
            merchant_title="Howie's grocery",
            url="http://someshop.com/item/345",
            date_time=MONTH_AGO,
            storage_manager=self.keeper,
        )
        transaction.commit()
        self.assertEqual(50.75, milk.get_price())

        # add a valid report
        PriceReport.assemble(
            price_value=10.22,
            product_title=u"Молоко Минувших дней 1л",
            reporter_name="John",
            merchant_title="Howie's grocery",
            url="http://someshop.com/item/349",
            date_time=HOUR_AGO,
            storage_manager=self.keeper,
        )
        transaction.commit()
        self.assertEqual(45.9, milk.get_price())
        self.assertEqual(15.40, milk.get_price(datetime.datetime.now() - datetime.timedelta(days=25)))
        self.assertIsNone(milk.get_price(datetime.datetime.now() - datetime.timedelta(days=45)))
Example #4
0
    def test_report_assembly_new_product(self):
        from uuid import uuid4

        product_title = u"Молоко Great Milk TWO 1L"
        reporter_name = "Jill"
        merchant_title = "Scotty's grocery"
        raw_data1 = {
            "product_title": product_title,
            "price_value": 42.6,
            "url": "http://scottys.com/products/milk/1",
            "merchant_title": merchant_title,
            "date_time": None,
            "reporter_name": reporter_name,
        }
        uuid_ = uuid4()
        report, stats = PriceReport.assemble(storage_manager=self.keeper, uuid=uuid_, **raw_data1)
        transaction.commit()
        self.keeper.close()

        self.keeper = open_storage()
        stored_report = PriceReport.fetch(report.key, self.keeper)
        self.assertEqual(report.key, stored_report.key)
        self.assertEqual(report.key, str(uuid_))

        product = Product.fetch(product_title, self.keeper)
        self.assertEqual(product_title, product.title)
        self.assertIn(report, product.reports)

        category = ProductCategory.fetch("milk", self.keeper)
        self.assertIn(product, category.products)

        merchant = Merchant.fetch(merchant_title, self.keeper)
        self.assertEqual(merchant_title, merchant.title)
        self.assertIn(product, merchant)
Example #5
0
    def test_price_report_lifetime(self):
        milk = ProductCategory.fetch('milk', self.keeper)

        # add an outdated report
        PriceReport.assemble(price_value=15.40,
                             product_title=u'Молоко Минувших дней 1л',
                             reporter_name='John',
                             merchant_title="Howie's grocery",
                             url='http://someshop.com/item/345',
                             date_time=MONTH_AGO,
                             storage_manager=self.keeper)
        transaction.commit()
        self.assertEqual(50.75, milk.get_price())

        # add a valid report
        PriceReport.assemble(price_value=10.22,
                             product_title=u'Молоко Минувших дней 1л',
                             reporter_name='John',
                             merchant_title="Howie's grocery",
                             url='http://someshop.com/item/349',
                             date_time=HOUR_AGO,
                             storage_manager=self.keeper)
        transaction.commit()
        self.assertEqual(45.9, milk.get_price())
        self.assertEqual(15.40, milk.get_price(datetime.datetime.now() -
                                               datetime.timedelta(days=25)))
        self.assertIsNone(milk.get_price(datetime.datetime.now() -
                                         datetime.timedelta(days=45)))
Example #6
0
 def test_delete_report(self):
     victim = PriceReport.fetch(self.report1_key, self.keeper)
     product = victim.product
     victim.delete_from(self.keeper)
     transaction.commit()
     self.assertNotIn(victim, product)
     self.assertNotIn(victim, PriceReport.fetch_all(self.keeper))
Example #7
0
 def test_product_category_median_ignore_irrelevant(self):
     raw_data1 = {
         'product_title': u'Молоко Great Milk 0,5л',
         'price_value': 32.6,
         'url': 'http://scottys.com/products/milk/10',
         'merchant_title': "Scotty's grocery",
         'date_time': None,
         'reporter_name': 'Jill'
     }
     PriceReport.assemble(storage_manager=self.keeper, **raw_data1)
     transaction.commit()
     milk = ProductCategory.fetch('milk', self.keeper)
     self.assertEqual(50.75, milk.get_price())
Example #8
0
 def test_product_category_median_ignore_irrelevant(self):
     raw_data1 = {
         "product_title": u"Молоко Great Milk 0,5л",
         "price_value": 32.6,
         "url": "http://scottys.com/products/milk/10",
         "merchant_title": "Scotty's grocery",
         "date_time": None,
         "reporter_name": "Jill",
     }
     PriceReport.assemble(storage_manager=self.keeper, **raw_data1)
     transaction.commit()
     milk = ProductCategory.fetch("milk", self.keeper)
     self.assertEqual(50.75, milk.get_price())
Example #9
0
 def test_merchant_added_to_product(self):
     raw_data = {
         "price_value": 50.4,
         "url": "http://eddies.com/products/milk/1",
         "product_title": u"Молоко Красная Цена у/паст. 3.2% 1л",
         "merchant_title": "Eddie's grocery",
         "reporter_name": "Jack",
         "date_time": DAY_AGO,
     }
     PriceReport.assemble(storage_manager=self.keeper, **raw_data)
     transaction.commit()
     product = Product.fetch(u"Молоко Красная Цена у-паст. 3.2% 1л", self.keeper)
     merchants = list(product.merchants)
     self.assertEqual(2, len(merchants))
Example #10
0
 def test_merchant_added_to_product(self):
     raw_data = {
         "price_value": 50.4,
         "url": "http://eddies.com/products/milk/1",
         "product_title": u"Молоко Красная Цена у/паст. 3.2% 1л",
         "merchant_title": "Eddie's grocery",
         "reporter_name": "Jack",
         'date_time': DAY_AGO,
     }
     PriceReport.assemble(storage_manager=self.keeper, **raw_data)
     transaction.commit()
     product = Product.fetch(u'Молоко Красная Цена у-паст. 3.2% 1л',
                             self.keeper)
     merchants = list(product.merchants)
     self.assertEqual(2, len(merchants))
Example #11
0
    def test_qualified_products(self):
        milk = ProductCategory.fetch('milk', self.keeper)
        fancy_milk_title = u'Молоко The Luxury Milk!!! 0,5л'
        PriceReport.assemble(price_value=40,
                             product_title=fancy_milk_title,
                             url='http"//blah',
                             merchant_title="Howie's grocery",
                             reporter_name='John',
                             storage_manager=self.keeper)
        transaction.commit()

        fancy_milk = Product.fetch(fancy_milk_title, self.keeper)
        qual_products = [p for p, pr in milk.get_qualified_products()]
        self.assertNotIn(fancy_milk, qual_products)
        self.assertEqual(4, len(qual_products))
Example #12
0
def fix_normalized_price():
    """
    Walk through all reports and fix normalized price_value
    and product package
    """

    keeper = get_storage()
    reports = PriceReport.fetch_all(keeper)
    for report in reports:
        try:
            correct_package_key = report.product.get_package_key()
            if report.product.package.key != correct_package_key:
                correct_package = ProductPackage.acquire(
                    correct_package_key, keeper)
                product = Product.fetch(report.product.key, keeper)
                print(
                    yellow(u'Fixing package for {}: {}-->{}'.format(
                        report.product, product.package, correct_package)))
                product.package = correct_package
                report.product = product

            old_norm_price = report.normalized_price_value
            new_norm_price = report._get_normalized_price(report.price_value)
            if old_norm_price != new_norm_price:
                print(
                    yellow(u'Fixing normal price {}-->{}'.format(
                        old_norm_price, new_norm_price)))
                report.normalized_price_value = new_norm_price
        except PackageLookupError, e:
            print(e.message)
Example #13
0
def fix_normalized_price():
    """
    Walk through all reports and fix normalized price_value
    and product package
    """

    keeper = get_storage()
    reports = PriceReport.fetch_all(keeper)
    for report in reports:
        try:
            correct_package_key = report.product.get_package_key()
            if report.product.package.key != correct_package_key:
                correct_package = ProductPackage.acquire(correct_package_key,
                                                         keeper)
                product = Product.fetch(report.product.key, keeper)
                print(yellow(u'Fixing package for {}: {}-->{}'.format(
                    report.product, product.package, correct_package)))
                product.package = correct_package
                report.product = product

            old_norm_price = report.normalized_price_value
            new_norm_price = report._get_normalized_price(report.price_value)
            if old_norm_price != new_norm_price:
                print(yellow(u'Fixing normal price {}-->{}'.format(
                      old_norm_price, new_norm_price)))
                report.normalized_price_value = new_norm_price
        except PackageLookupError, e:
            print(e.message)
Example #14
0
    def test_qualified_products(self):
        milk = ProductCategory.fetch("milk", self.keeper)
        fancy_milk_title = u"Молоко The Luxury Milk!!! 0,5л"
        PriceReport.assemble(
            price_value=40,
            product_title=fancy_milk_title,
            url='http"//blah',
            merchant_title="Howie's grocery",
            reporter_name="John",
            storage_manager=self.keeper,
        )
        transaction.commit()

        fancy_milk = Product.fetch(fancy_milk_title, self.keeper)
        qual_products = [p for p, pr in milk.get_qualified_products()]
        self.assertNotIn(fancy_milk, qual_products)
        self.assertEqual(4, len(qual_products))
Example #15
0
    def post(self):
        # TODO Implement validation
        try:
            dict_list = multidict_to_list(self.request.params)
        except MultidictError as e:
            raise HTTPBadRequest(e.message)
        counts = {'product': 0,
                  'category': 0,
                  'package': 0}
        new_report_keys = list()
        error_msgs = list()
        for dict_ in dict_list:
            try:
                report, new_items = PriceReport.assemble(
                    storage_manager=self.root, **dict_)
                new_report_keys.append(report.key)
                prod_is_new, cat_is_new, pack_is_new = new_items
                counts['product'] += int(prod_is_new)
                counts['category'] += int(cat_is_new)
                counts['package'] += int(pack_is_new)
            except (PackageLookupError, CategoryLookupError, ValueError,
                    TypeError) as e:
                error_msgs.append(e.message)
        counts['total'] = len(dict_list)
        counts['report'] = len(new_report_keys)
        counts['error'] = len(error_msgs)
        if len(new_report_keys):
            general_region.invalidate(hard=False)
            reporters = ', '.join(
                set(self.request.params.getall('reporter_name')))
            # send email
            from pyramid_mailer import get_mailer
            from pyramid_mailer.message import Message
            mailer = get_mailer(self.request)
            message = Message(
                subject=u'Price Watch: отчеты от {}'.format(reporters),
                sender='*****@*****.**',
                recipients=["*****@*****.**"],
                html=render('email/post_report_stats.mako',
                            {'counts': counts,
                             'reporters': reporters,
                             'error_msgs': error_msgs}))
            mailer.send(message)

            return {
                'new_report_keys': new_report_keys,
                'counts': counts,
                'errors': error_msgs
            }
        else:
            raise HTTPBadRequest('No new reports\n' +
                                 '\n'.join(error_msgs))
Example #16
0
    def post(self):
        # TODO Implement validation
        try:
            dict_list = multidict_to_list(self.request.params)
        except MultidictError as e:
            raise HTTPBadRequest(e.message)
        counts = {'product': 0, 'category': 0, 'package': 0}
        new_report_keys = list()
        error_msgs = list()
        for dict_ in dict_list:
            try:
                report, new_items = PriceReport.assemble(
                    storage_manager=self.root, **dict_)
                new_report_keys.append(report.key)
                prod_is_new, cat_is_new, pack_is_new = new_items
                counts['product'] += int(prod_is_new)
                counts['category'] += int(cat_is_new)
                counts['package'] += int(pack_is_new)
            except (PackageLookupError, CategoryLookupError, ValueError,
                    TypeError) as e:
                error_msgs.append(e.message)
        counts['total'] = len(dict_list)
        counts['report'] = len(new_report_keys)
        counts['error'] = len(error_msgs)
        if len(new_report_keys):
            general_region.invalidate(hard=False)
            reporters = ', '.join(
                set(self.request.params.getall('reporter_name')))
            # send email
            from pyramid_mailer import get_mailer
            from pyramid_mailer.message import Message
            mailer = get_mailer(self.request)
            message = Message(
                subject=u'Price Watch: отчеты от {}'.format(reporters),
                sender='*****@*****.**',
                recipients=["*****@*****.**"],
                html=render(
                    'email/post_report_stats.mako', {
                        'counts': counts,
                        'reporters': reporters,
                        'error_msgs': error_msgs
                    }))
            mailer.send(message)

            return {
                'new_report_keys': new_report_keys,
                'counts': counts,
                'errors': error_msgs
            }
        else:
            raise HTTPBadRequest('No new reports\n' + '\n'.join(error_msgs))
Example #17
0
    def test_presense_in_references(self):
        milk = ProductCategory.fetch("milk", self.keeper)
        diary = Category.fetch("diary", self.keeper)
        self.assertEqual("diary", diary.title)
        self.assertEqual(4, len(milk.products))
        self.assertIn(64.3, milk.get_prices())

        report1 = PriceReport.fetch(self.report1_key, self.keeper)
        self.assertEqual(55.6, report1.normalized_price_value)
        self.assertIs(milk, report1.product.category)
        self.assertEqual(u"Московский магазин", report1.merchant.title)
        self.assertEqual("Jack", report1.reporter.name)
        self.assertIs(diary, milk.category)
        self.assertIn(milk, diary.categories)
Example #18
0
def recreate():
    """Recreate storage from reports"""
    keeper = get_storage()
    new_keeper = get_storage('storage/new.fs')

    reports = PriceReport.fetch_all(keeper)
    print(cyan('Recreating storage from {} reports...'.format(len(reports))))
    for report in reports:
        try:
            PriceReport.assemble(storage_manager=new_keeper,
                                 uuid=report.uuid,
                                 price_value=report.price_value,
                                 product_title=report.product.title,
                                 merchant_title=report.merchant.title,
                                 reporter_name=report.reporter.name,
                                 url=report.url,
                                 date_time=report.date_time)
        except CategoryLookupError:
            print(yellow(u'Dropping `{}`: '
                         u'no category...'.format(report.product)))
    transaction.commit()
    keeper.close()
    new_keeper.close()
Example #19
0
    def test_presense_in_references(self):
        milk = ProductCategory.fetch('milk', self.keeper)
        diary = Category.fetch('diary', self.keeper)
        self.assertEqual('diary', diary.title)
        self.assertEqual(4, len(milk.products))
        self.assertIn(64.3, milk.get_prices())

        report1 = PriceReport.fetch(self.report1_key, self.keeper)
        self.assertEqual(55.6, report1.normalized_price_value)
        self.assertIs(milk, report1.product.category)
        self.assertEqual(u'Московский магазин', report1.merchant.title)
        self.assertEqual('Jack', report1.reporter.name)
        self.assertIs(diary, milk.category)
        self.assertIn(milk, diary.categories)
Example #20
0
    def test_report_assembly_stored_product(self):
        product_title = u"Молоко Great Milk three 1L"
        product = Product(product_title, self.category)
        self.keeper.register(product)
        transaction.commit()
        self.keeper.close()

        self.keeper = open_storage()
        reporter_name = "Jill"
        merchant_title = "Scotty's grocery 2"
        raw_data1 = {
            "product_title": product_title,
            "price_value": 42.6,
            "url": "http://scottys2.com/products/milk/1",
            "merchant_title": merchant_title,
            "date_time": None,
            "reporter_name": reporter_name,
        }
        report, stats = PriceReport.assemble(self.keeper, **raw_data1)
        transaction.commit()
        self.keeper.close()

        self.keeper = open_storage()
        stored_report = PriceReport.fetch(report.key, self.keeper)
        self.assertEqual(report.key, stored_report.key)

        product = Product.fetch(product_title, self.keeper)
        self.assertEqual(product_title, product.title)
        self.assertIn(report, product)

        category = ProductCategory.fetch("milk", self.keeper)
        self.assertIn(product, category)

        merchant = Merchant.fetch(merchant_title, self.keeper)
        self.assertEqual(merchant_title, merchant.title)
        self.assertIn(product, merchant)
        self.assertIn(merchant, product.merchants)
Example #21
0
    def test_report_assembly_stored_product(self):
        product_title = u'Молоко Great Milk three 1L'
        product = Product(product_title, self.category)
        self.keeper.register(product)
        transaction.commit()
        self.keeper.close()

        self.keeper = open_storage()
        reporter_name = 'Jill'
        merchant_title = "Scotty's grocery 2"
        raw_data1 = {
            'product_title': product_title,
            'price_value': 42.6,
            'url': 'http://scottys2.com/products/milk/1',
            'merchant_title': merchant_title,
            'date_time': None,
            'reporter_name': reporter_name
        }
        report, stats = PriceReport.assemble(self.keeper, **raw_data1)
        transaction.commit()
        self.keeper.close()

        self.keeper = open_storage()
        stored_report = PriceReport.fetch(report.key, self.keeper)
        self.assertEqual(report.key, stored_report.key)

        product = Product.fetch(product_title, self.keeper)
        self.assertEqual(product_title, product.title)
        self.assertIn(report, product)

        category = ProductCategory.fetch('milk', self.keeper)
        self.assertIn(product, category)

        merchant = Merchant.fetch(merchant_title, self.keeper)
        self.assertEqual(merchant_title, merchant.title)
        self.assertIn(product, merchant)
        self.assertIn(merchant, product.merchants)
Example #22
0
def recreate():
    """Recreate storage from reports"""
    keeper = get_storage()
    new_keeper = get_storage('storage/new.fs')

    reports = PriceReport.fetch_all(keeper)
    print(cyan('Recreating storage from {} reports...'.format(len(reports))))
    for report in reports:
        try:
            PriceReport.assemble(storage_manager=new_keeper,
                                 uuid=report.uuid,
                                 price_value=report.price_value,
                                 product_title=report.product.title,
                                 merchant_title=report.merchant.title,
                                 reporter_name=report.reporter.name,
                                 url=report.url,
                                 date_time=report.date_time)
        except CategoryLookupError:
            print(
                yellow(u'Dropping `{}`: '
                       u'no category...'.format(report.product)))
    transaction.commit()
    keeper.close()
    new_keeper.close()
Example #23
0
def display_report(report_key):
    """Display a report by key"""
    keeper = get_storage()
    report = PriceReport.fetch(report_key, keeper)
    if not report:
        print(yellow('No report with key ' + report_key))
        exit()
    print('Key: ' + report.key)
    print('Product: ' + report.product.title)
    print('Package: ' + report.product.get_package_key())
    if report.product.category is None:
        if confirm(yellow('The report is not valid, remove?'), default=False):
            report.delete_from(keeper)
            transaction.commit()
    else:
        print('Product category: ' + report.product.category.title)
    keeper.close()
Example #24
0
def display_report(report_key):
    """Display a report by key"""
    keeper = get_storage()
    report = PriceReport.fetch(report_key, keeper)
    if not report:
        print(yellow('No report with key ' + report_key))
        exit()
    print('Key: ' + report.key)
    print('Product: ' + report.product.title)
    print('Package: ' + report.product.get_package_key())
    if report.product.category is None:
        if confirm(yellow('The report is not valid, remove?'), default=False):
            report.delete_from(keeper)
            transaction.commit()
    else:
        print('Product category: ' + report.product.category.title)
    keeper.close()
Example #25
0
    def test_product_add_report(self):
        product = self.product
        product.category = self.category
        report1 = PriceReport(
            price_value=42.6,
            product=product,
            reporter=Reporter('Jill'),
            merchant=Merchant("Scotty's grocery"),
        )
        product.add_report(report1)
        product.add_report(report1)
        transaction.commit()
        self.keeper.close()

        self.keeper = open_storage()
        product = Product.fetch(u'Молоко Great Milk 1L', self.keeper)
        self.assertIn(report1, product.reports)
        self.assertEqual(1, len(product.reports))
Example #26
0
    def test_price_from_past_date(self):
        milk = ProductCategory.fetch("milk", self.keeper)
        cheapest_milk_title = u"Молоко The Cheapest Milk!!! 1л"
        PriceReport.assemble(
            price_value=30.10,
            product_title=cheapest_milk_title,
            reporter_name="John",
            merchant_title="Howie's grocery",
            url="http://someshop.com/item/344",
            date_time=HOUR_AGO,
            storage_manager=self.keeper,
        )
        PriceReport.assemble(
            price_value=29.10,
            product_title=cheapest_milk_title,
            reporter_name="John",
            merchant_title="Howie's grocery",
            url="http://someshop.com/item/344",
            date_time=WEEK_AGO,
            storage_manager=self.keeper,
        )
        PriceReport.assemble(
            price_value=25.22,
            product_title=cheapest_milk_title,
            reporter_name="John",
            merchant_title="Howie's grocery",
            url="http://someshop.com/item/344",
            date_time=MONTH_AGO,
            storage_manager=self.keeper,
        )

        transaction.commit()
        cheapest_milk = Product.fetch(cheapest_milk_title, self.keeper)

        self.assertEqual(30.10, cheapest_milk.get_price())
        self.assertEqual(1, cheapest_milk.get_price_delta(DAY_AGO, relative=False))
        self.assertEqual(0.034364261168384876, cheapest_milk.get_price_delta(DAY_AGO))
        self.assertEqual(30.10, min(milk.get_prices()))
        self.assertEqual(45.9, milk.get_price())
        self.assertEqual(0.5773195876288658, milk.get_price_delta(DAY_AGO))
Example #27
0
    def test_price_from_past_date(self):
        milk = ProductCategory.fetch('milk', self.keeper)
        cheapest_milk_title = u'Молоко The Cheapest Milk!!! 1л'
        PriceReport.assemble(price_value=30.10,
                             product_title=cheapest_milk_title,
                             reporter_name='John',
                             merchant_title="Howie's grocery",
                             url='http://someshop.com/item/344',
                             date_time=HOUR_AGO,
                             storage_manager=self.keeper)
        PriceReport.assemble(price_value=29.10,
                             product_title=cheapest_milk_title,
                             reporter_name='John',
                             merchant_title="Howie's grocery",
                             url='http://someshop.com/item/344',
                             date_time=WEEK_AGO,
                             storage_manager=self.keeper)
        PriceReport.assemble(price_value=25.22,
                             product_title=cheapest_milk_title,
                             reporter_name='John',
                             merchant_title="Howie's grocery",
                             url='http://someshop.com/item/344',
                             date_time=MONTH_AGO,
                             storage_manager=self.keeper)

        transaction.commit()
        cheapest_milk = Product.fetch(cheapest_milk_title, self.keeper)

        self.assertEqual(30.10, cheapest_milk.get_price())
        self.assertEqual(1, cheapest_milk.get_price_delta(DAY_AGO,
                                                          relative=False))
        self.assertEqual(0.034364261168384876,
                         cheapest_milk.get_price_delta(DAY_AGO))
        self.assertEqual(30.10, min(milk.get_prices()))
        self.assertEqual(45.9, milk.get_price())
        self.assertEqual(0.5773195876288658, milk.get_price_delta(DAY_AGO))
Example #28
0
    def test_report_assembly(self):
        raw_data1 = {
            "product_title": u"Молоко Great Milk 1L",
            "sku": "ART97665",
            "price_value": 42.6,
            "url": "http://scottys.com/products/milk/1",
            "merchant_title": "Scotty's grocery",
            "date_time": None,
            "reporter_name": "Jill",
        }
        raw_data2 = {
            "product_title": u"Молоко Great Milk 0.93 L",
            "price_value": 50,
            "url": "http://scottys.com/products/milk/5",
            "merchant_title": "Scotty's grocery",
            "date_time": None,
            "reporter_name": "Jill",
        }
        raw_data3 = {
            "product_title": u"Сметана Great Sour Cream 450g",
            "price_value": 60.4,
            "url": "http://scottys.com/products/sc/6",
            "merchant_title": "Scotty's grocery",
            "date_time": datetime.datetime(2014, 10, 5),
            "reporter_name": "Jill",
        }
        raw_data4 = {
            "product_title": u"Сметана Great Sour Cream 987987g",
            "price_value": 60.4,
            "url": "http://scottys.com/products/sc/8978",
            "merchant_title": "Scotty's grocery",
            "date_time": datetime.datetime(2014, 10, 5),
            "reporter_name": "Jill",
        }
        raw_data5 = {
            "product_title": u"Картофель Вегетория для варки 3кг",
            "price_value": 80.5,
            "url": "http://scottys.com/products/pot/324",
            "merchant_title": "Scotty's grocery",
            "reporter_name": "Jill",
        }
        report1, stats1 = PriceReport.assemble(storage_manager=self.keeper, **raw_data1)
        report2, stats2 = PriceReport.assemble(storage_manager=self.keeper, **raw_data2)
        report3, stats3 = PriceReport.assemble(storage_manager=self.keeper, **raw_data3)
        report5, stats5 = PriceReport.assemble(storage_manager=self.keeper, **raw_data5)
        try:
            PriceReport.assemble(storage_manager=self.keeper, **raw_data4)
        except PackageLookupError:
            pass
        transaction.commit()

        # check category and products
        milk = ProductCategory.fetch("milk", self.keeper)
        sc = ProductCategory.fetch("sour cream", self.keeper)
        self.assertEqual(6, len(milk.products))
        self.assertIn(42.6, milk.get_prices())
        product1 = Product.fetch(u"Молоко Great Milk 1L", self.keeper)
        product2 = Product.fetch(u"Молоко Great Milk 0.93 L", self.keeper)
        self.assertIs(milk, product1.category)
        self.assertEqual("1 l", product1.package.title)
        self.assertEqual("ART97665", report1.sku)
        self.assertEqual("0.93 l", product2.package.title)
        self.assertEqual(1, product1.package_ratio)
        self.assertEqual(0.93, product2.package_ratio)
        self.assertFalse(hasattr(report2, "sku"))
        self.assertIn(product1, milk.products)
        self.assertEqual("sour cream", report3.product.category.title)
        self.assertIn(u"Сметана Great Sour Cream 450g", [p.title for p in sc.products])
        self.assertNotIn(u"Сметана Great Sour Cream 987987g", [p.title for p in sc.products])

        # check references
        potato = ProductCategory.fetch("potato", self.keeper)
        self.assertIn(report5, PriceReport.fetch_all(self.keeper))
        self.assertIn(report5, potato.products[0].reports)
        self.assertIn(report5, Product.fetch(u"Картофель Вегетория для варки 3кг", self.keeper).reports)

        # check reporter
        jill = Reporter.fetch("Jill", self.keeper)
        self.assertIs(jill, report1.reporter)
        self.assertIs(jill, report2.reporter)
        self.assertIs(jill, report3.reporter)

        # check price calculations
        self.assertEqual(42.60, round(report1.normalized_price_value, 2))
        self.assertEqual(53.76, round(report2.normalized_price_value, 2))
        self.assertEqual(53.69, round(report3.normalized_price_value, 2))

        # check merchant
        merchant = Merchant.fetch("Scotty's grocery", self.keeper)
        self.assertIs(merchant, report1.merchant)
        self.assertIn(merchant, product1.merchants)
        self.assertIn(product1, merchant)

        # check datetime that is not now
        date_in_past = datetime.datetime(2014, 10, 5)
        self.assertEqual(date_in_past, report3.date_time)

        # check if no false product is registered
        false_product = Product.fetch(u"Сметана Great Sour Cream 987987g", self.keeper)
        self.assertIsNone(false_product)
Example #29
0
    def test_report_assembly(self):
        raw_data1 = {
            'product_title': u'Молоко Great Milk 1L',
            'sku': 'ART97665',
            'price_value': 42.6,
            'url': 'http://scottys.com/products/milk/1',
            'merchant_title': "Scotty's grocery",
            'date_time': None,
            'reporter_name': 'Jill'
        }
        raw_data2 = {
            'product_title': u'Молоко Great Milk 0.93 L',
            'price_value': 50,
            'url': 'http://scottys.com/products/milk/5',
            'merchant_title': "Scotty's grocery",
            'date_time': None,
            'reporter_name': 'Jill'
        }
        raw_data3 = {
            'product_title': u'Сметана Great Sour Cream 450g',
            'price_value': 60.4,
            'url': 'http://scottys.com/products/sc/6',
            'merchant_title': "Scotty's grocery",
            'date_time': datetime.datetime(2014, 10, 5),
            'reporter_name': 'Jill'
        }
        raw_data4 = {
            'product_title': u'Сметана Great Sour Cream 987987g',
            'price_value': 60.4,
            'url': 'http://scottys.com/products/sc/8978',
            'merchant_title': "Scotty's grocery",
            'date_time': datetime.datetime(2014, 10, 5),
            'reporter_name': 'Jill'
        }
        raw_data5 = {
            'product_title': u'Картофель Вегетория для варки 3кг',
            'price_value': 80.5,
            'url': 'http://scottys.com/products/pot/324',
            'merchant_title': "Scotty's grocery",
            'reporter_name': 'Jill'
        }
        report1, stats1 = PriceReport.assemble(storage_manager=self.keeper,
                                               **raw_data1)
        report2, stats2 = PriceReport.assemble(storage_manager=self.keeper,
                                               **raw_data2)
        report3, stats3 = PriceReport.assemble(storage_manager=self.keeper,
                                               **raw_data3)
        report5, stats5 = PriceReport.assemble(storage_manager=self.keeper,
                                               **raw_data5)
        try:
            PriceReport.assemble(storage_manager=self.keeper, **raw_data4)
        except PackageLookupError:
            pass
        transaction.commit()

        # check category and products
        milk = ProductCategory.fetch('milk', self.keeper)
        sc = ProductCategory.fetch('sour cream', self.keeper)
        self.assertEqual(6, len(milk.products))
        self.assertIn(42.6, milk.get_prices())
        product1 = Product.fetch(u'Молоко Great Milk 1L', self.keeper)
        product2 = Product.fetch(u'Молоко Great Milk 0.93 L', self.keeper)
        self.assertIs(milk, product1.category)
        self.assertEqual('1 l', product1.package.title)
        self.assertEqual('ART97665', report1.sku)
        self.assertEqual('0.93 l', product2.package.title)
        self.assertEqual(1, product1.package_ratio)
        self.assertEqual(0.93, product2.package_ratio)
        self.assertFalse(hasattr(report2, 'sku'))
        self.assertIn(product1, milk.products)
        self.assertEqual('sour cream', report3.product.category.title)
        self.assertIn(u'Сметана Great Sour Cream 450g',
                      [p.title for p in sc.products])
        self.assertNotIn(u'Сметана Great Sour Cream 987987g',
                         [p.title for p in sc.products])

        # check references
        potato = ProductCategory.fetch('potato', self.keeper)
        self.assertIn(report5, PriceReport.fetch_all(self.keeper))
        self.assertIn(report5, potato.products[0].reports)
        self.assertIn(report5,
                      Product.fetch(u'Картофель Вегетория для варки 3кг',
                                    self.keeper).reports)

        # check reporter
        jill = Reporter.fetch('Jill', self.keeper)
        self.assertIs(jill, report1.reporter)
        self.assertIs(jill, report2.reporter)
        self.assertIs(jill, report3.reporter)

        # check price calculations
        self.assertEqual(42.60, round(report1.normalized_price_value, 2))
        self.assertEqual(53.76, round(report2.normalized_price_value, 2))
        self.assertEqual(53.69, round(report3.normalized_price_value, 2))

        # check merchant
        merchant = Merchant.fetch("Scotty's grocery", self.keeper)
        self.assertIs(merchant, report1.merchant)
        self.assertIn(merchant, product1.merchants)
        self.assertIn(product1, merchant)

        # check datetime that is not now
        date_in_past = datetime.datetime(2014, 10, 5)
        self.assertEqual(date_in_past, report3.date_time)

        # check if no false product is registered
        false_product = Product.fetch(u'Сметана Great Sour Cream 987987g',
                                      self.keeper)
        self.assertIsNone(false_product)