From 44d43ace64e12d9bb6fad062547f27b26c4ebaaa Mon Sep 17 00:00:00 2001 From: Arnaud Joset Date: Thu, 8 Oct 2020 12:58:26 +0000 Subject: [PATCH] [FIX] sale_product_configurator,website_sale,website_sale_product_configurator: tests were failing Before this commit, * the website_sale tests used the field optional_product_ids on product_template even if it is defined on sale_product_configurator. * the website_sale_product_configurator test added some steps to the website_sale tour. This commit removes the faulty fields in the website_sale test and fix the website_sale_product_configurator tests. After this commit, sale_product_configurator and website_sale_product_configurator have a test classes to setup all the parameters needed during the flow. This prevent duplicated code for similar workflow. closes odoo/odoo#60081 Taskid: 2340918 X-original-commit: f7ca48e9d1ff56ae53ab156114f9dc29534ac3f6 Signed-off-by: Yannick Tivisse (yti) --- .../product_configurator_pricelist_ui.js | 4 +- .../tests/__init__.py | 1 + .../sale_product_configurator/tests/common.py | 114 ++++++++++++++ .../test_sale_product_configurator_ui.py | 142 +++--------------- addons/website_sale/tests/test_customize.py | 2 - .../website_sale/tests/test_sale_process.py | 1 - ...bsite_sale_shop_custom_attributes_value.js | 32 ++-- .../tests/__init__.py | 4 + .../tests/test_customize.py | 15 ++ 9 files changed, 172 insertions(+), 143 deletions(-) create mode 100644 addons/sale_product_configurator/tests/common.py create mode 100644 addons/website_sale_product_configurator/tests/__init__.py create mode 100644 addons/website_sale_product_configurator/tests/test_customize.py diff --git a/addons/sale_product_configurator/static/tests/tours/product_configurator_pricelist_ui.js b/addons/sale_product_configurator/static/tests/tours/product_configurator_pricelist_ui.js index 60fc965b39b..af97bf1f7c7 100644 --- a/addons/sale_product_configurator/static/tests/tours/product_configurator_pricelist_ui.js +++ b/addons/sale_product_configurator/static/tests/tours/product_configurator_pricelist_ui.js @@ -31,10 +31,10 @@ tour.stepUtils.showAppsMenuItem(), }, { content: "search the pricelist", trigger: 'div[name="pricelist_id"] input', - run: 'text Public Pricelist' + run: 'text Custom pricelist (TEST)' }, { content: "select the pricelist", - trigger: 'ul.ui-autocomplete > li > a:contains(Public Pricelist)', + trigger: 'ul.ui-autocomplete > li > a:contains(Custom pricelist (TEST))', }, { trigger: "a:contains('Add a product')" }, { diff --git a/addons/sale_product_configurator/tests/__init__.py b/addons/sale_product_configurator/tests/__init__.py index c1cb786c919..2b67147c409 100644 --- a/addons/sale_product_configurator/tests/__init__.py +++ b/addons/sale_product_configurator/tests/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from . import common from . import test_sale_product_configurator_ui diff --git a/addons/sale_product_configurator/tests/common.py b/addons/sale_product_configurator/tests/common.py new file mode 100644 index 00000000000..252fda2b17a --- /dev/null +++ b/addons/sale_product_configurator/tests/common.py @@ -0,0 +1,114 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +import base64 + +from odoo.tests.common import SavepointCase +from odoo.modules.module import get_module_resource + + +class TestProductConfiguratorCommon(SavepointCase): + + @classmethod + def setUpClass(cls): + super().setUpClass() + # Setup attributes and attributes values + cls.product_attribute_1 = cls.env['product.attribute'].create({ + 'name': 'Legs', + 'sequence': 10, + }) + product_attribute_value_1 = cls.env['product.attribute.value'].create({ + 'name': 'Steel', + 'attribute_id': cls.product_attribute_1.id, + 'sequence': 1, + }) + product_attribute_value_2 = cls.env['product.attribute.value'].create({ + 'name': 'Aluminium', + 'attribute_id': cls.product_attribute_1.id, + 'sequence': 2, + }) + product_attribute_2 = cls.env['product.attribute'].create({ + 'name': 'Color', + 'sequence': 20, + }) + product_attribute_value_3 = cls.env['product.attribute.value'].create({ + 'name': 'White', + 'attribute_id': product_attribute_2.id, + 'sequence': 1, + }) + product_attribute_value_4 = cls.env['product.attribute.value'].create({ + 'name': 'Black', + 'attribute_id': product_attribute_2.id, + 'sequence': 2, + }) + + # Create product template + cls.product_product_custo_desk = cls.env['product.template'].create({ + 'name': 'Customizable Desk (TEST)', + 'standard_price': 500.0, + 'list_price': 750.0, + }) + + # Generate variants + cls.env['product.template.attribute.line'].create([{ + 'product_tmpl_id': cls.product_product_custo_desk.id, + 'attribute_id': cls.product_attribute_1.id, + 'value_ids': [(4, product_attribute_value_1.id), (4, product_attribute_value_2.id)], + }, { + 'product_tmpl_id': cls.product_product_custo_desk.id, + 'attribute_id': product_attribute_2.id, + 'value_ids': [(4, product_attribute_value_3.id), (4, product_attribute_value_4.id)], + + }]) + + # Apply a price_extra for the attribute Aluminium + cls.product_product_custo_desk.attribute_line_ids[0].product_template_value_ids[1].price_extra = 50.40 + + # Add a Custom attribute + product_attribute_value_custom = cls.env['product.attribute.value'].create({ + 'name': 'Custom', + 'attribute_id': cls.product_attribute_1.id, + 'sequence': 3, + 'is_custom': True + }) + cls.product_product_custo_desk.attribute_line_ids[0].write({'value_ids': [(4, product_attribute_value_custom.id)]}) + + # Disable the aluminium + black product + cls.product_product_custo_desk.product_variant_ids[3].active = False + + # Setup a first optional product + img_path = get_module_resource('product', 'static', 'img', 'product_product_11-image.png') + img_content = base64.b64encode(open(img_path, "rb").read()) + cls.product_product_conf_chair = cls.env['product.template'].create({ + 'name': 'Conference Chair (TEST)', + 'image_1920': img_content, + 'list_price': 16.50, + }) + + cls.env['product.template.attribute.line'].create({ + 'product_tmpl_id': cls.product_product_conf_chair.id, + 'attribute_id': cls.product_attribute_1.id, + 'value_ids': [(4, product_attribute_value_1.id), (4, product_attribute_value_2.id)], + }) + cls.product_product_conf_chair.attribute_line_ids[0].product_template_value_ids[1].price_extra = 6.40 + cls.product_product_custo_desk.optional_product_ids = [(4, cls.product_product_conf_chair.id)] + + # Setup a second optional product + cls.product_product_conf_chair_floor_protect = cls.env['product.template'].create({ + 'name': 'Chair floor protection', + 'list_price': 12.0, + }) + cls.product_product_conf_chair.optional_product_ids = [(4, cls.product_product_conf_chair_floor_protect.id)] + + + def _create_pricelist(cls, pricelists): + for pricelist in pricelists: + if not pricelist.item_ids.filtered(lambda i: i.product_tmpl_id == cls.product_product_custo_desk and i.price_discount == 20): + cls.env['product.pricelist.item'].create({ + 'base': 'list_price', + 'applied_on': '1_product', + 'pricelist_id': pricelist.id, + 'product_tmpl_id': cls.product_product_custo_desk.id, + 'price_discount': 20, + 'min_quantity': 2, + 'compute_price': 'formula', + }) + pricelist.discount_policy = 'without_discount' diff --git a/addons/sale_product_configurator/tests/test_sale_product_configurator_ui.py b/addons/sale_product_configurator/tests/test_sale_product_configurator_ui.py index 3b962f52d87..009c2de6e8f 100644 --- a/addons/sale_product_configurator/tests/test_sale_product_configurator_ui.py +++ b/addons/sale_product_configurator/tests/test_sale_product_configurator_ui.py @@ -1,111 +1,30 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -import base64 - import odoo.tests -from odoo.modules.module import get_module_resource +from .common import TestProductConfiguratorCommon @odoo.tests.tagged('post_install', '-at_install') -class TestUi(odoo.tests.HttpCase): +class TestUi(odoo.tests.HttpSavepointCase, TestProductConfiguratorCommon): def setUp(self): super(TestUi, self).setUp() - - # Setup attributes and attributes values - self.product_attribute_1 = self.env['product.attribute'].create({ - 'name': 'Legs', - 'sequence': 10, + self.custom_pricelist = self.env['product.pricelist'].create({ + 'name': 'Custom pricelist (TEST)', + 'item_ids': [(0, 0, { + 'base': 'list_price', + 'applied_on': '1_product', + 'product_tmpl_id': self.product_product_custo_desk.id, + 'price_discount': 20, + 'min_quantity': 2, + 'compute_price': 'formula' + })] }) - product_attribute_value_1 = self.env['product.attribute.value'].create({ - 'name': 'Steel', - 'attribute_id': self.product_attribute_1.id, - 'sequence': 1, - }) - product_attribute_value_2 = self.env['product.attribute.value'].create({ - 'name': 'Aluminium', - 'attribute_id': self.product_attribute_1.id, - 'sequence': 2, - }) - product_attribute_2 = self.env['product.attribute'].create({ - 'name': 'Color', - 'sequence': 20, - }) - product_attribute_value_3 = self.env['product.attribute.value'].create({ - 'name': 'White', - 'attribute_id': product_attribute_2.id, - 'sequence': 1, - }) - product_attribute_value_4 = self.env['product.attribute.value'].create({ - 'name': 'Black', - 'attribute_id': product_attribute_2.id, - 'sequence': 2, - }) - - # Create product template - self.product_product_4_product_template = self.env['product.template'].create({ - 'name': 'Customizable Desk (TEST)', - 'standard_price': 500.0, - 'list_price': 750.0, - }) - - # Generate variants - self.env['product.template.attribute.line'].create([{ - 'product_tmpl_id': self.product_product_4_product_template.id, - 'attribute_id': self.product_attribute_1.id, - 'value_ids': [(4, product_attribute_value_1.id), (4, product_attribute_value_2.id)], - }, { - 'product_tmpl_id': self.product_product_4_product_template.id, - 'attribute_id': product_attribute_2.id, - 'value_ids': [(4, product_attribute_value_3.id), (4, product_attribute_value_4.id)], - - }]) - - # Apply a price_extra for the attribute Aluminium - self.product_product_4_product_template.attribute_line_ids[0].product_template_value_ids[1].price_extra = 50.40 - - - # Add a Custom attribute - product_attribute_value_7 = self.env['product.attribute.value'].create({ - 'name': 'Custom', - 'attribute_id': self.product_attribute_1.id, - 'sequence': 3, - 'is_custom': True - }) - self.product_product_4_product_template.attribute_line_ids[0].write({'value_ids': [(4, product_attribute_value_7.id)]}) - - # Disable the aluminium + black product - self.product_product_4_product_template.product_variant_ids[3].active = False - - # Setup a first optional product - img_path = get_module_resource('product', 'static', 'img', 'product_product_11-image.png') - img_content = base64.b64encode(open(img_path, "rb").read()) - self.product_product_11_product_template = self.env['product.template'].create({ - 'name': 'Conference Chair (TEST)', - 'image_1920': img_content, - 'list_price': 16.50, - }) - - self.env['product.template.attribute.line'].create({ - 'product_tmpl_id': self.product_product_11_product_template.id, - 'attribute_id': self.product_attribute_1.id, - 'value_ids': [(4, product_attribute_value_1.id), (4, product_attribute_value_2.id)], - }) - self.product_product_4_product_template.optional_product_ids = [(4, self.product_product_11_product_template.id)] - - # Setup a second optional product - self.product_product_1_product_template = self.env['product.template'].create({ - 'name': 'Chair floor protection', - 'list_price': 12.0, - }) - self.product_product_11_product_template.optional_product_ids = [(4, self.product_product_1_product_template.id)] - def test_01_product_configurator(self): # To be able to test the product configurator, admin user must have access to "variants" feature, so we give him the right group for that self.env.ref('base.user_admin').write({'groups_id': [(4, self.env.ref('product.group_product_variant').id)]}) - self.start_tour("/web", 'sale_product_configurator_tour', login="admin") def test_02_product_configurator_advanced(self): @@ -159,20 +78,18 @@ class TestUi(odoo.tests.HttpCase): 'attribute_id': product_attribute.id } for i in range(1, 11) for product_attribute in product_attributes]) - product_template = self.product_product_4_product_template + product_template = self.product_product_custo_desk self.env['product.template.attribute.line'].create([{ 'attribute_id': product_attribute.id, 'product_tmpl_id': product_template.id, 'value_ids': [(6, 0, product_attribute.value_ids.ids)], } for product_attribute in product_attributes]) - self.start_tour("/web", 'sale_product_configurator_advanced_tour', login="admin") def test_03_product_configurator_edition(self): # To be able to test the product configurator, admin user must have access to "variants" feature, so we give him the right group for that self.env.ref('base.user_admin').write({'groups_id': [(4, self.env.ref('product.group_product_variant').id)]}) - self.start_tour("/web", 'sale_product_configurator_edition_tour', login="admin") def test_04_product_configurator_single_custom_value(self): @@ -200,14 +117,13 @@ class TestUi(odoo.tests.HttpCase): 'attribute_id': product_attributes[0].id }]) - product_template = self.product_product_4_product_template + product_template = self.product_product_custo_desk self.env['product.template.attribute.line'].create([{ 'attribute_id': product_attributes[0].id, 'product_tmpl_id': product_template.id, 'value_ids': [(6, 0, [product_attribute_values[0].id])] }]) - self.start_tour("/web", 'sale_product_configurator_single_custom_attribute_tour', login="admin") def test_05_product_configurator_pricelist(self): @@ -227,27 +143,11 @@ class TestUi(odoo.tests.HttpCase): # Add a 15% tax on desk tax = self.env['account.tax'].create({'name': "Test tax", 'amount': 15}) - self.product_product_4_product_template.taxes_id = tax + self.product_product_custo_desk.taxes_id = tax # Remove tax from Conference Chair and Chair floor protection - self.product_product_1_product_template.taxes_id = None - self.product_product_11_product_template.taxes_id = None - - # Make sure pricelist rule exist - product_template = self.product_product_4_product_template - pricelist = self.env.ref('product.list0') - - if not pricelist.item_ids.filtered(lambda i: i.product_tmpl_id == product_template and i.applied_on == '1_product' and i.price_discount == 20): - self.env['product.pricelist.item'].create({ - 'base': 'list_price', - 'applied_on': '1_product', - 'pricelist_id': pricelist.id, - 'product_tmpl_id': product_template.id, - 'price_discount': 20, - 'min_quantity': 2, - 'compute_price': 'formula', - }) - + self.product_product_conf_chair.taxes_id = None + self.product_product_conf_chair_floor_protect.taxes_id = None self.start_tour("/web", 'sale_product_configurator_pricelist_tour', login="admin") def test_06_product_configurator_optional_products(self): @@ -255,17 +155,17 @@ class TestUi(odoo.tests.HttpCase): window opens correctly and lets you select optional products even if the main product does not have variants. """ - # add an optional product to the office chair and the custo desk for testing purposes office_chair = self.env['product.product'].create({ 'name': 'Office Chair Black', }) - custo_desk = self.product_product_4_product_template.product_variant_ids[0] + custo_desk = self.product_product_custo_desk.product_variant_ids[0] office_chair.update({ - 'optional_product_ids': [(6, 0, [self.product_product_1_product_template.id])] + 'optional_product_ids': [(6, 0, [self.product_product_conf_chair_floor_protect.id])] }) custo_desk.update({ - 'optional_product_ids': [(6, 0, [office_chair.product_tmpl_id.id, self.product_product_11_product_template.id])] + 'optional_product_ids': [(6, 0, [office_chair.product_tmpl_id.id, self.product_product_conf_chair.id])] }) + self.product_product_custo_desk.optional_product_ids = [(4, self.product_product_conf_chair.id)] self.start_tour("/web", 'sale_product_configurator_optional_products_tour', login="admin") diff --git a/addons/website_sale/tests/test_customize.py b/addons/website_sale/tests/test_customize.py index 08de828ffa0..285a70d66bc 100644 --- a/addons/website_sale/tests/test_customize.py +++ b/addons/website_sale/tests/test_customize.py @@ -133,14 +133,12 @@ class TestUi(HttpCaseWithUserDemo, HttpCaseWithUserPortal): 'value_ids': [(4, product_attribute_value_1.id), (4, product_attribute_value_2.id)], }) self.product_product_11_product_template.attribute_line_ids[0].product_template_value_ids[1].price_extra = 6.40 - self.product_product_4_product_template.optional_product_ids = [(4, self.product_product_11_product_template.id)] # Setup a second optional product self.product_product_1_product_template = self.env['product.template'].create({ 'name': 'Chair floor protection', 'list_price': 12.0, }) - self.product_product_11_product_template.optional_product_ids = [(4, self.product_product_1_product_template.id)] # fix runbot, sometimes one pricelist is chosen, sometimes the other... pricelists = self.env['website'].get_current_website().get_current_pricelist() | self.env.ref('product.list0') diff --git a/addons/website_sale/tests/test_sale_process.py b/addons/website_sale/tests/test_sale_process.py index 259a26e2c4d..558e9965f2c 100644 --- a/addons/website_sale/tests/test_sale_process.py +++ b/addons/website_sale/tests/test_sale_process.py @@ -49,7 +49,6 @@ class TestUi(HttpCaseWithUserDemo): 'name': 'Chair floor protection', 'list_price': 12.0, }) - self.product_product_11_product_template.optional_product_ids = [(6, 0, [self.product_product_1_product_template.id])] cash_journal = self.env['account.journal'].create({'name': 'Cash - Test', 'type': 'cash', 'code': 'CASH - Test'}) self.env.ref('payment.payment_acquirer_transfer').journal_id = cash_journal diff --git a/addons/website_sale_product_configurator/static/tests/tours/website_sale_shop_custom_attributes_value.js b/addons/website_sale_product_configurator/static/tests/tours/website_sale_shop_custom_attributes_value.js index aa3f2122ec2..9872017e6f3 100644 --- a/addons/website_sale_product_configurator/static/tests/tours/website_sale_shop_custom_attributes_value.js +++ b/addons/website_sale_product_configurator/static/tests/tours/website_sale_shop_custom_attributes_value.js @@ -1,30 +1,28 @@ odoo.define("website_sale_product_TESTurator.tour_shop_custom_attribute_value", function (require) { "use strict"; -/** - * Add custom steps to handle the optional products modal introduced - * by the product TESTurator module. - */ + var tour = require('web_tour.tour'); -require('website_sale.tour_shop_custom_attribute_value'); - var optionVariantImage; -var addCartStepIndex = _.findIndex(tour.tours.shop_custom_attribute_value.steps, function (step) { - return (step.id === 'add_cart_step'); -}); -tour.tours.shop_custom_attribute_value.steps.splice(addCartStepIndex + 1, 0, { - trigger: 'div:contains(Custom TEST: Wood)', - extra_trigger: '.js_product.in_cart.main_product', - run: function (){} // checks that Yep, it's wood! +tour.register("a_shop_custom_attribute_value", { + url: "/shop?search=Customizable Desk", + test: true, +}, [{ + content: "click on Customizable Desk", + trigger: '.oe_product_cart a:contains("Customizable Desk (TEST)")', }, { - trigger: 'button.js_add_cart_json:has(i.fa-plus)', + trigger: 'a.js_add_cart_json:has(i.fa-plus)', run: 'click', }, { - trigger: 'div.oe_striked_price span:contains(750)', + trigger: 'span.text-danger span:contains(750)', run: function (){}, // check }, { - trigger: 'span.oe_price span:contains(600)', + trigger: 'b.oe_price span:contains(600)', run: function (){}, // check +}, { + id: 'add_cart_step', + trigger: 'a:contains(Add to Cart)', + run: 'click', }, { trigger: '.oe_optional_products_modal .js_product:eq(1) div:contains("Conference Chair (TEST) (Steel)")', run: function () { @@ -64,6 +62,6 @@ tour.tours.shop_custom_attribute_value.steps.splice(addCartStepIndex + 1, 0, { }, { trigger: 'button:has(span:contains(Proceed to Checkout))', run: 'click', -}); +}]); }); diff --git a/addons/website_sale_product_configurator/tests/__init__.py b/addons/website_sale_product_configurator/tests/__init__.py new file mode 100644 index 00000000000..1d513809ae9 --- /dev/null +++ b/addons/website_sale_product_configurator/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import test_customize diff --git a/addons/website_sale_product_configurator/tests/test_customize.py b/addons/website_sale_product_configurator/tests/test_customize.py new file mode 100644 index 00000000000..bac65e2d96b --- /dev/null +++ b/addons/website_sale_product_configurator/tests/test_customize.py @@ -0,0 +1,15 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.tests.common import HttpSavepointCase +from odoo.addons.sale_product_configurator.tests.common import TestProductConfiguratorCommon +from odoo.tests import tagged + + +@tagged('post_install', '-at_install') +class TestUi(HttpSavepointCase, TestProductConfiguratorCommon): + + def test_01_admin_shop_custom_attribute_value_tour(self): + # fix runbot, sometimes one pricelist is chosen, sometimes the other... + pricelists = self.env['website'].get_current_website().get_current_pricelist() | self.env.ref('product.list0') + self._create_pricelist(pricelists) + self.start_tour("/", 'a_shop_custom_attribute_value', login="admin")