diff options
Diffstat (limited to 'addons/website_sale_coupon/tests')
3 files changed, 313 insertions, 0 deletions
diff --git a/addons/website_sale_coupon/tests/__init__.py b/addons/website_sale_coupon/tests/__init__.py new file mode 100644 index 00000000..cc015ce4 --- /dev/null +++ b/addons/website_sale_coupon/tests/__init__.py @@ -0,0 +1,2 @@ +from . import test_sale_coupon_multiwebsite +from . import test_shop_sale_coupon diff --git a/addons/website_sale_coupon/tests/test_sale_coupon_multiwebsite.py b/addons/website_sale_coupon/tests/test_sale_coupon_multiwebsite.py new file mode 100644 index 00000000..4c50d5f8 --- /dev/null +++ b/addons/website_sale_coupon/tests/test_sale_coupon_multiwebsite.py @@ -0,0 +1,149 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.addons.sale_coupon.tests.test_program_numbers import TestSaleCouponProgramNumbers +from odoo.addons.website.tools import MockRequest +from odoo.exceptions import UserError +from odoo.tests import tagged + + +@tagged('-at_install', 'post_install') +class TestSaleCouponMultiwebsite(TestSaleCouponProgramNumbers): + + def setUp(self): + super(TestSaleCouponMultiwebsite, self).setUp() + self.website = self.env['website'].browse(1) + self.website2 = self.env['website'].create({'name': 'website 2'}) + + def test_01_multiwebsite_checks(self): + """ Ensure the multi website compliance of programs and coupons, both in + backend and frontend. + """ + order = self.empty_order + self.env['sale.order.line'].create({ + 'product_id': self.largeCabinet.id, + 'name': 'Large Cabinet', + 'product_uom_qty': 2.0, + 'order_id': order.id, + }) + + def _remove_reward(): + order.order_line.filtered('is_reward_line').unlink() + self.assertEqual(len(order.order_line.ids), 1, "Program should have been removed") + + def _apply_code(code, backend=True): + if backend: + self.env['sale.coupon.apply.code'].with_context(active_id=order.id).create({ + 'coupon_code': code + }).process_coupon() + else: + self.env['sale.coupon.apply.code'].sudo().apply_coupon(order, code) + + # ========================================== + # ========== Programs (with code) ========== + # ========================================== + + # 1. Backend - Generic + _apply_code(self.p1.promo_code) + self.assertEqual(len(order.order_line.ids), 2, "Should get the discount line as it is a generic promo program") + _remove_reward() + + # 2. Frontend - Generic + with MockRequest(self.env, website=self.website): + _apply_code(self.p1.promo_code, False) + self.assertEqual(len(order.order_line.ids), 2, "Should get the discount line as it is a generic promo program (2)") + _remove_reward() + + # make program specific + self.p1.website_id = self.website.id + # 3. Backend - Specific + with self.assertRaises(UserError): + _apply_code(self.p1.promo_code) # the order has no website_id so not possible to use a website specific code + + # 4. Frontend - Specific - Correct website + order.website_id = self.website.id + with MockRequest(self.env, website=self.website): + _apply_code(self.p1.promo_code, False) + self.assertEqual(len(order.order_line.ids), 2, "Should get the discount line as it is a specific promo program for the correct website") + _remove_reward() + + # 5. Frontend - Specific - Wrong website + self.p1.website_id = self.website2.id + with MockRequest(self.env, website=self.website): + _apply_code(self.p1.promo_code, False) + self.assertEqual(len(order.order_line.ids), 1, "Should not get the reward as wrong website") + + # ============================== + # =========== Coupons ========== + # ============================== + + order.website_id = False + self.env['coupon.generate.wizard'].with_context(active_id=self.discount_coupon_program.id).create({ + 'nbr_coupons': 4, + }).generate_coupon() + coupons = self.discount_coupon_program.coupon_ids + + # 1. Backend - Generic + _apply_code(coupons[0].code) + self.assertEqual(len(order.order_line.ids), 2, "Should get the discount line as it is a generic coupon program") + _remove_reward() + + # 2. Frontend - Generic + with MockRequest(self.env, website=self.website): + _apply_code(coupons[1].code, False) + self.assertEqual(len(order.order_line.ids), 2, "Should get the discount line as it is a generic coupon program (2)") + _remove_reward() + + # make program specific + self.discount_coupon_program.website_id = self.website.id + # 3. Backend - Specific + with self.assertRaises(UserError): + _apply_code(coupons[2].code) # the order has no website_id so not possible to use a website specific code + + # 4. Frontend - Specific - Correct website + order.website_id = self.website.id + with MockRequest(self.env, website=self.website): + _apply_code(coupons[2].code, False) + self.assertEqual(len(order.order_line.ids), 2, "Should get the discount line as it is a specific coupon program for the correct website") + _remove_reward() + + # 5. Frontend - Specific - Wrong website + self.discount_coupon_program.website_id = self.website2.id + with MockRequest(self.env, website=self.website): + _apply_code(coupons[3].code, False) + self.assertEqual(len(order.order_line.ids), 1, "Should not get the reward as wrong website") + + # ======================================== + # ========== Programs (no code) ========== + # ======================================== + + order.website_id = False + self.p1.website_id = False + self.p1.promo_code = False + self.p1.promo_code_usage = 'no_code_needed' + + # 1. Backend - Generic + order.recompute_coupon_lines() + self.assertEqual(len(order.order_line.ids), 2, "Should get the discount line as it is a generic promo program") + + # 2. Frontend - Generic + with MockRequest(self.env, website=self.website): + order.recompute_coupon_lines() + self.assertEqual(len(order.order_line.ids), 2, "Should get the discount line as it is a generic promo program (2)") + + # make program specific + self.p1.website_id = self.website.id + # 3. Backend - Specific + order.recompute_coupon_lines() + self.assertEqual(len(order.order_line.ids), 1, "The order has no website_id so not possible to use a website specific code") + + # 4. Frontend - Specific - Correct website + order.website_id = self.website.id + with MockRequest(self.env, website=self.website): + order.recompute_coupon_lines() + self.assertEqual(len(order.order_line.ids), 2, "Should get the discount line as it is a specific promo program for the correct website") + + # 5. Frontend - Specific - Wrong website + self.p1.website_id = self.website2.id + with MockRequest(self.env, website=self.website): + order.recompute_coupon_lines() + self.assertEqual(len(order.order_line.ids), 1, "Should not get the reward as wrong website") diff --git a/addons/website_sale_coupon/tests/test_shop_sale_coupon.py b/addons/website_sale_coupon/tests/test_shop_sale_coupon.py new file mode 100644 index 00000000..2bc2e0dd --- /dev/null +++ b/addons/website_sale_coupon/tests/test_shop_sale_coupon.py @@ -0,0 +1,162 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from datetime import timedelta + +from odoo import fields +from odoo.tests import HttpCase, tagged, TransactionCase +from odoo.addons.sale.tests.test_sale_product_attribute_value_config import TestSaleProductAttributeValueCommon + + +@tagged('post_install', '-at_install') +class TestUi(TestSaleProductAttributeValueCommon, HttpCase): + + @classmethod + def setUpClass(cls): + super(TestUi, cls).setUpClass() + # set currency to not rely on demo data and avoid possible race condition + cls.currency_ratio = 1.0 + pricelist = cls.env.ref('product.list0') + new_currency = cls._setup_currency(cls.currency_ratio) + pricelist.currency_id = new_currency + pricelist.flush() + + + def test_01_admin_shop_sale_coupon_tour(self): + # pre enable "Show # found" option to avoid race condition... + public_category = self.env['product.public.category'].create({'name': 'Public Category'}) + + large_cabinet = self.env['product.product'].create({ + 'name': 'Small Cabinet', + 'list_price': 320.0, + 'type': 'consu', + 'is_published': True, + 'sale_ok': True, + 'public_categ_ids': [(4, public_category.id)], + 'taxes_id': False, + }) + + free_large_cabinet = self.env['product.product'].create({ + 'name': 'Free Product - Small Cabinet', + 'type': 'service', + 'taxes_id': False, + 'supplier_taxes_id': False, + 'sale_ok': False, + 'purchase_ok': False, + 'invoice_policy': 'order', + 'default_code': 'FREELARGECABINET', + 'categ_id': self.env.ref('product.product_category_all').id, + 'taxes_id': False, + }) + + ten_percent = self.env['product.product'].create({ + 'name': '10.0% discount on total amount', + 'type': 'service', + 'taxes_id': False, + 'supplier_taxes_id': False, + 'sale_ok': False, + 'purchase_ok': False, + 'invoice_policy': 'order', + 'default_code': '10PERCENTDISC', + 'categ_id': self.env.ref('product.product_category_all').id, + 'taxes_id': False, + }) + + self.env['coupon.program'].create({ + 'name': "Buy 3 Small Cabinets, get one for free", + 'promo_code_usage': 'no_code_needed', + 'discount_apply_on': 'on_order', + 'reward_type': 'product', + 'program_type': 'promotion_program', + 'reward_product_id': large_cabinet.id, + 'rule_min_quantity': 3, + 'rule_products_domain': "[['name', 'ilike', 'Small Cabinet']]", + 'discount_line_product_id': free_large_cabinet.id + }) + + self.env['coupon.program'].create({ + 'name': "Code for 10% on orders", + 'promo_code_usage': 'code_needed', + 'promo_code': 'testcode', + 'discount_apply_on': 'on_order', + 'discount_type': 'percentage', + 'discount_percentage': 10.0, + 'program_type': 'promotion_program', + 'discount_line_product_id': ten_percent.id + }) + + self.env.ref("website_sale.search_count_box").write({"active": True}) + self.start_tour("/", 'shop_sale_coupon', login="admin") + + +@tagged('post_install', '-at_install') +class TestWebsiteSaleCoupon(TransactionCase): + + def setUp(self): + super(TestWebsiteSaleCoupon, self).setUp() + program = self.env['coupon.program'].create({ + 'name': '10% TEST Discount', + 'promo_code_usage': 'code_needed', + 'discount_apply_on': 'on_order', + 'discount_type': 'percentage', + 'discount_percentage': 10.0, + 'program_type': 'coupon_program', + }) + + self.env['coupon.generate.wizard'].with_context(active_id=program.id).create({}).generate_coupon() + self.coupon = program.coupon_ids[0] + + self.steve = self.env['res.partner'].create({ + 'name': 'Steve Bucknor', + 'email': 'steve.bucknor@example.com', + }) + self.empty_order = self.env['sale.order'].create({ + 'partner_id': self.steve.id + }) + + def test_01_gc_coupon(self): + # 1. Simulate a frontend order (website, product) + order = self.empty_order + order.website_id = self.env['website'].browse(1) + self.env['sale.order.line'].create({ + 'product_id': self.env['product.product'].create({ + 'name': 'Product A', + 'list_price': 100, + 'sale_ok': True, + }).id, + 'name': 'Product A', + 'product_uom_qty': 2.0, + 'order_id': order.id, + }) + + # 2. Apply the coupon + self.env['sale.coupon.apply.code'].with_context(active_id=order.id).create({ + 'coupon_code': self.coupon.code + }).process_coupon() + order.recompute_coupon_lines() + + self.assertEqual(len(order.applied_coupon_ids), 1, "The coupon should've been applied on the order") + self.assertEqual(self.coupon, order.applied_coupon_ids) + self.assertEqual(self.coupon.state, 'used') + + # 3. Test recent order -> Should not be removed + order._gc_abandoned_coupons() + + self.assertEqual(len(order.applied_coupon_ids), 1, "The coupon shouldn't have been removed from the order no more than 4 days") + self.assertEqual(self.coupon.state, 'used', "Should not have been changed") + + # 4. Test order not older than ICP validity -> Should not be removed + ICP = self.env['ir.config_parameter'] + icp_validity = ICP.create({'key': 'website_sale_coupon.abandonned_coupon_validity', 'value': 5}) + order.flush() + query = """UPDATE %s SET write_date = %%s WHERE id = %%s""" % (order._table,) + self.env.cr.execute(query, (fields.Datetime.to_string(fields.datetime.now() - timedelta(days=4, hours=2)), order.id)) + order._gc_abandoned_coupons() + + self.assertEqual(len(order.applied_coupon_ids), 1, "The coupon shouldn't have been removed from the order the order is 4 days old but icp validity is 5 days") + self.assertEqual(self.coupon.state, 'used', "Should not have been changed (2)") + + # 5. Test order with no ICP and older then 4 default days -> Should be removed + icp_validity.unlink() + order._gc_abandoned_coupons() + + self.assertEqual(len(order.applied_coupon_ids), 0, "The coupon should've been removed from the order as more than 4 days") + self.assertEqual(self.coupon.state, 'new', "Should have been reset.") |
