[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) <yti@odoo.com>
This commit is contained in:
+2
-2
@@ -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')"
|
||||
}, {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
@@ -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")
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
+15
-17
@@ -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',
|
||||
});
|
||||
}]);
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_customize
|
||||
@@ -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")
|
||||
Reference in New Issue
Block a user