[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) <bon@odoo.com>
This commit is contained in:
Nasreddin Boulif (bon)
2022-09-02 19:13:53 +02:00
parent 156e2f1fc3
commit cb789579d2
3 changed files with 53 additions and 6 deletions
@@ -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:
@@ -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)
@@ -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)