Odoo18-Base/addons/website_sale/tests/test_website_editor.py
2025-03-10 11:12:23 +07:00

267 lines
12 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
from odoo import Command
from odoo.addons.website_sale.controllers.main import WebsiteSale
from odoo.addons.website.tools import MockRequest
from odoo.exceptions import ValidationError
from odoo.tests import HttpCase, tagged
_logger = logging.getLogger(__name__)
ATTACHMENT_DATA = [
b"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAEElEQVR4nGKqf3geEAAA//8EGgIyYKYzzgAAAABJRU5ErkJggg==",
b"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAEElEQVR4nGKqvvQEEAAA//8EBQI0GMlQsAAAAABJRU5ErkJggg==",
b"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAEElEQVR4nGKKLakBBAAA//8ChwFQsvFlAwAAAABJRU5ErkJggg==",
b"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAEElEQVR4nGJqkdoACAAA//8CfAFRzSyOUAAAAABJRU5ErkJggg==",
b"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAEElEQVR4nGLSfxgICAAA//8CrAFkoLBhpQAAAABJRU5ErkJggg==",
]
ATTACHMENT_COUNT = 5
@tagged('post_install', '-at_install')
class TestProductPictureController(HttpCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.website = cls.env['website'].browse(1)
cls.WebsiteSaleController = WebsiteSale()
cls.product = cls.env['product.product'].create({
'name': 'Storage Test Box',
'standard_price': 70.0,
'list_price': 79.0,
'website_published': True,
})
cls.attachments = cls.env['ir.attachment'].create([
{
'datas': ATTACHMENT_DATA[i],
'name': f'image0{i}.gif',
'public': True
}
for i in range(ATTACHMENT_COUNT)])
def _create_product_images(self):
with MockRequest(self.product.env, website=self.website):
self.WebsiteSaleController.add_product_images(
[{'id': attachment.id} for attachment in self.attachments],
self.product.id,
self.product.product_tmpl_id.id,
)
def _get_product_image_data(self):
return [
hasattr(image, 'video_url') and image.video_url or image.image_1920
for image in self.product._get_images()
]
def test_bulk_image_upload(self):
# Turns attachments to product_images
self._create_product_images()
# Check if the media now exists on the product :
for i, image in enumerate(self.product.product_template_image_ids):
# Check if all names are now in the product
self.assertIn(image.name, self.attachments.mapped('name'))
# Check if image datas are the same
self.assertEqual(image.image_1920, ATTACHMENT_DATA[i])
# Check if exactly ATTACHMENT_COUNT images were saved (no dupes/misses?)
self.assertEqual(ATTACHMENT_COUNT, len(self.product.product_template_image_ids))
def test_image_clear(self):
# First create some images
self._create_product_images()
self.assertEqual(ATTACHMENT_COUNT, len(self.product.product_template_image_ids))
# Remove all images
# (Exception raised if error)
with MockRequest(self.product.env, website=self.website):
self.WebsiteSaleController.clear_product_images(
self.product.id,
self.product.product_tmpl_id.id,
)
# According to the product, there are no variants images.
self.assertEqual(0, len(self.product.product_template_image_ids))
def test_extra_images_with_new_variant(self):
# Test that adding images for a variant that is not yet created works
product_attribute = self.env['product.attribute'].create({
"name": "Test attribute",
"create_variant": "dynamic",
})
product_attribute_values = self.env['product.attribute.value'].create([
{
"name" : "Test Dynamic 1",
"attribute_id": product_attribute.id,
"sequence": 1,
},
{
"name" : "Test Dynamic 2",
"attribute_id": product_attribute.id,
"sequence": 2,
}
])
product_template = self.env['product.template'].create({
"name": "test product",
"website_published": True,
})
product_template_attribute_line = self.env['product.template.attribute.line'].create({
"attribute_id": product_attribute.id,
"product_tmpl_id": product_template.id,
"value_ids": product_attribute_values,
})
self.assertEqual(0, len(product_template.product_variant_ids))
with MockRequest(product_template.env, website=self.website):
self.WebsiteSaleController.add_product_images(
[{'id': self.attachments[0].id}],
False,
product_template.id,
[product_template_attribute_line.product_template_value_ids[0].id],
)
self.assertEqual(1, len(product_template.product_variant_ids))
def test_resequence_image_first(self):
self._create_product_images()
with MockRequest(self.product.env, website=self.website):
images = self.product._get_images()
i1, i2, i3, i4, i5, i6 = self._get_product_image_data()
self.WebsiteSaleController.resequence_product_image(
images[2]._name, images[2].id, 'first',
)
# Trigger the reordering of product.image records based on their sequence.
self.env['product.image'].invalidate_model()
self.assertListEqual(self._get_product_image_data(), [i3, i1, i2, i4, i5, i6])
self.assertEqual(self.product.image_1920, i3)
def test_resequence_image_left(self):
self._create_product_images()
with MockRequest(self.product.env, website=self.website):
images = self.product._get_images()
i1, i2, i3, i4, i5, i6 = self._get_product_image_data()
self.WebsiteSaleController.resequence_product_image(
images[2]._name, images[2].id, 'left',
)
self.env['product.image'].invalidate_model()
self.assertListEqual(self._get_product_image_data(), [i1, i3, i2, i4, i5, i6])
def test_resequence_image_right(self):
self._create_product_images()
with MockRequest(self.product.env, website=self.website):
images = self.product._get_images()
i1, i2, i3, i4, i5, i6 = self._get_product_image_data()
self.WebsiteSaleController.resequence_product_image(
images[2]._name, images[2].id, 'right',
)
self.env['product.image'].invalidate_model()
self.assertListEqual(self._get_product_image_data(), [i1, i2, i4, i3, i5, i6])
def test_resequence_image_last(self):
self._create_product_images()
with MockRequest(self.product.env, website=self.website):
images = self.product._get_images()
i1, i2, i3, i4, i5, i6 = self._get_product_image_data()
self.WebsiteSaleController.resequence_product_image(
images[2]._name, images[2].id, 'last',
)
self.env['product.image'].invalidate_model()
self.assertListEqual(self._get_product_image_data(), [i1, i2, i4, i5, i6, i3])
def test_resequence_image_first_to_last(self):
""" Moving an image from first to last position is an edge case in the code. """
self._create_product_images()
with MockRequest(self.product.env, website=self.website):
images = self.product._get_images()
i1, i2, i3, i4, i5, i6 = self._get_product_image_data()
self.WebsiteSaleController.resequence_product_image(
images[0]._name, images[0].id, 'last',
)
self.env['product.image'].invalidate_model()
self.assertListEqual(self._get_product_image_data(), [i2, i3, i4, i5, i6, i1])
self.assertEqual(self.product.image_1920, i2)
def test_resequence_video_left(self):
self._create_product_images()
with MockRequest(self.product.env, website=self.website):
images = self.product._get_images()
images[2].video_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
i1, i2, i3, i4, i5, i6 = self._get_product_image_data()
self.WebsiteSaleController.resequence_product_image(
images[2]._name, images[2].id, 'left',
)
self.env['product.image'].invalidate_model()
self.assertListEqual(self._get_product_image_data(), [i1, i3, i2, i4, i5, i6])
def test_resequence_video_first(self):
""" A video can't be resequenced to first position. """
self._create_product_images()
with MockRequest(self.product.env, website=self.website):
images = self.product._get_images()
images[2].video_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
i1, i2, i3, i4, i5, i6 = self._get_product_image_data()
with self.assertRaises(ValidationError):
self.WebsiteSaleController.resequence_product_image(
images[2]._name, images[2].id, 'first',
)
self.env['product.image'].invalidate_model()
self.assertListEqual(self._get_product_image_data(), [i1, i2, i3, i4, i5, i6])
def test_resequence_video_replace_first(self):
""" A video can't replace an image that was resequenced away from first position. """
self._create_product_images()
with MockRequest(self.product.env, website=self.website):
images = self.product._get_images()
images[1].video_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
i1, i2, i3, i4, i5, i6 = self._get_product_image_data()
with self.assertRaises(ValidationError):
self.WebsiteSaleController.resequence_product_image(
images[0]._name, images[0].id, 'right',
)
self.env['product.image'].invalidate_model()
self.assertListEqual(self._get_product_image_data(), [i1, i2, i3, i4, i5, i6])
@tagged('post_install', '-at_install')
class TestWebsiteSaleEditor(HttpCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env['res.users'].create({
'name': 'Restricted Editor',
'login': 'restricted',
'password': 'restricted',
'groups_id': [Command.set([
cls.env.ref('base.group_user').id,
cls.env.ref('sales_team.group_sale_manager').id,
cls.env.ref('website.group_website_restricted_editor').id
])]
})
def test_category_page_and_products_snippet(self):
category = self.env['product.public.category'].create({
'name': 'Test Category',
})
self.env['product.template'].create({
'name': 'Test Product',
'website_published': True,
'public_categ_ids': [
Command.link(category.id)
]
})
self.env['product.template'].create({
'name': 'Test Product Outside Category',
'website_published': True,
})
self.start_tour(self.env['website'].get_client_action_url('/shop'), 'category_page_and_products_snippet_edition', login='restricted')
self.start_tour('/shop', 'category_page_and_products_snippet_use', login=None)
def test_website_sale_restricted_editor_ui(self):
self.env['product.template'].create({
'name': 'Test Product',
'website_sequence': 0,
'website_published': True,
})
self.start_tour(self.env['website'].get_client_action_url('/shop'), 'website_sale_restricted_editor_ui', login='restricted')