From cb789579d25e1549b348ed16e4cf08ddaf0c9fbf Mon Sep 17 00:00:00 2001 From: "Nasreddin Boulif (bon)" Date: Tue, 23 Aug 2022 15:16:13 +0000 Subject: [PATCH] [FIX] website[_sale]: add company to domain of snippet filters Steps to reproduce: - Install website_sale module - Create a new company X - Create a new product Y and set company to X - Create a website Z and ensure it's linked to a company but NOT X - Go to website Z homepage and edit it - Add a `Products` block then save (should be by default on filter `Newest`) - Select product Y in the block Issue: The product should not be displayed and when clicking on it, we have an access right error. Cause: Not taking into account the company of the website when preparing values to render in the snippet therefore the product is displayed while it should not. Solution: Update `_prepare_values` to add the website company to the domain if the filter's model has a company_id field. Same issue occure with latest_sold filter (for ex.) so must apply same fix to `_get_products` for filters that use a server action. opw-2956186 closes odoo/odoo#99181 X-original-commit: dab7fed0c396d3dd6e2e2ad8560c706d5c2e89fb Signed-off-by: Nasreddin Boulif (bon) --- .../website/models/website_snippet_filter.py | 3 ++ .../models/website_snippet_filter.py | 3 +- .../tests/test_website_sale_visitor.py | 53 +++++++++++++++++-- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/addons/website/models/website_snippet_filter.py b/addons/website/models/website_snippet_filter.py index c11aacb4005..db418c11058 100644 --- a/addons/website/models/website_snippet_filter.py +++ b/addons/website/models/website_snippet_filter.py @@ -87,6 +87,9 @@ class WebsiteSnippetFilter(models.Model): domain = filter_sudo._get_eval_domain() if 'website_id' in self.env[filter_sudo.model_id]: domain = expression.AND([domain, self.env['website'].get_current_website().website_domain()]) + if 'company_id' in self.env[filter_sudo.model_id]: + website = self.env['website'].get_current_website() + domain = expression.AND([domain, [('company_id', 'in', [False, website.company_id.id])]]) if 'is_published' in self.env[filter_sudo.model_id]: domain = expression.AND([domain, [('is_published', '=', True)]]) if search_domain: diff --git a/addons/website_sale/models/website_snippet_filter.py b/addons/website_sale/models/website_snippet_filter.py index ce6ec975893..f7b6e200972 100644 --- a/addons/website_sale/models/website_snippet_filter.py +++ b/addons/website_sale/models/website_snippet_filter.py @@ -72,7 +72,8 @@ class WebsiteSnippetFilter(models.Model): limit = context.get('limit') domain = expression.AND([ [('website_published', '=', True)], - website.get_current_website().website_domain(), + website.website_domain(), + [('company_id', 'in', [False, website.company_id.id])], search_domain or [], ]) products = handler(website, limit, domain, context) diff --git a/addons/website_sale/tests/test_website_sale_visitor.py b/addons/website_sale/tests/test_website_sale_visitor.py index 50d828917ec..a4147e3358f 100644 --- a/addons/website_sale/tests/test_website_sale_visitor.py +++ b/addons/website_sale/tests/test_website_sale_visitor.py @@ -52,8 +52,9 @@ class WebsiteSaleVisitorTests(TransactionCase): self.assertEqual(len(new_visitors), 1, "No visitor should be created after visiting another tracked product") self.assertEqual(len(new_tracks), 2, "A track should be created after visiting another tracked product") - def test_recently_viewed_company_changed(self): - # Test that, by changing the company of a tracked product, the recently viewed product do not crash + def test_dynamic_filter_newest_products(self): + """Test that a product is not displayed anymore after + changing it company.""" new_company = self.env['res.company'].create({ 'name': 'Test Company', }) @@ -66,11 +67,53 @@ class WebsiteSaleVisitorTests(TransactionCase): }) self.website = self.website.with_user(public_user).with_context(website_id=self.website.id) + snippet_filter = self.env.ref('website_sale.dynamic_filter_newest_products') + + res = snippet_filter._prepare_values(16, []) + res_products = [res_product['_record'] for res_product in res] + self.assertIn(product, res_products) + + product.product_tmpl_id.company_id = new_company + product.product_tmpl_id.flush_recordset(['company_id']) + + res = snippet_filter._prepare_values(16, []) + res_products = [res_product['_record'] for res_product in res] + self.assertNotIn(product, res_products) + + def test_recently_viewed_company_changed(self): + """Test that a product is : + - displayed after visiting it + - not displayed after changing it company.""" + new_company = self.env['res.company'].create({ + 'name': 'Test Company', + }) + public_user = self.env.ref('base.public_user') + + product = self.env['product.product'].create({ + 'name': 'Test Product', + 'website_published': True, + 'sale_ok': True, + }) + + self.website = self.website.with_user(public_user).with_context(website_id=self.website.id) + + snippet_filter = self.env.ref('website_sale.dynamic_filter_latest_viewed_products') + + # BEFORE VISITING THE PRODUCT + res = snippet_filter._prepare_values(16, []) + self.assertFalse(res) + + # AFTER VISITING THE PRODUCT with MockRequest(self.website.env, website=self.website): self.cookies = self.WebsiteSaleController.products_recently_viewed_update(product.id) + with MockRequest(self.website.env, website=self.website, cookies=self.cookies): + res = snippet_filter._prepare_values(16, []) + res_products = [res_product['_record'] for res_product in res] + self.assertIn(product, res_products) + + # AFTER CHANGING PRODUCT COMPANY product.product_tmpl_id.company_id = new_company product.product_tmpl_id.flush_recordset(['company_id']) with MockRequest(self.website.env, website=self.website, cookies=self.cookies): - # Should not raise an error - res = self.website.env['website.snippet.filter']._get_products_latest_viewed(self.website, 16, [], {}) - self.assertFalse(res) + res = snippet_filter._prepare_values(16, []) + self.assertFalse(res)