241 lines
10 KiB
Python
241 lines
10 KiB
Python
# coding: utf-8
|
|
|
|
from unittest.mock import patch
|
|
|
|
from odoo.addons.base.tests.common import TransactionCaseWithUserPortal
|
|
from odoo.addons.website_sale.controllers.main import WebsiteSale, PaymentPortal
|
|
from odoo.addons.website.tools import MockRequest
|
|
from odoo.addons.website_sale.models.product_template import ProductTemplate
|
|
from odoo.exceptions import UserError, ValidationError
|
|
from odoo.tests.common import tagged
|
|
from odoo.fields import Command
|
|
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class WebsiteSaleCart(TransactionCaseWithUserPortal):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(WebsiteSaleCart, cls).setUpClass()
|
|
cls.website = cls.env['website'].browse(1)
|
|
cls.WebsiteSaleController = WebsiteSale()
|
|
cls.public_user = cls.env.ref('base.public_user')
|
|
cls.product = cls.env['product.product'].create({
|
|
'name': 'Test Product',
|
|
'sale_ok': True,
|
|
'website_published': True,
|
|
'lst_price': 1000.0,
|
|
'standard_price': 800.0,
|
|
})
|
|
|
|
def test_add_cart_deleted_product(self):
|
|
# Create a published product then unlink it
|
|
product = self.env['product.product'].create({
|
|
'name': 'Test Product',
|
|
'sale_ok': True,
|
|
'website_published': True,
|
|
})
|
|
product_id = product.id
|
|
product.unlink()
|
|
|
|
with self.assertRaises(UserError):
|
|
with MockRequest(product.with_user(self.public_user).env, website=self.website.with_user(self.public_user)):
|
|
self.WebsiteSaleController.cart_update_json(product_id=product_id, add_qty=1)
|
|
|
|
def test_add_cart_unpublished_product(self):
|
|
# Try to add an unpublished product
|
|
product = self.env['product.product'].create({
|
|
'name': 'Test Product',
|
|
'sale_ok': True,
|
|
})
|
|
|
|
with self.assertRaises(UserError):
|
|
with MockRequest(product.with_user(self.public_user).env, website=self.website.with_user(self.public_user)):
|
|
self.WebsiteSaleController.cart_update_json(product_id=product.id, add_qty=1)
|
|
|
|
# public but remove sale_ok
|
|
product.sale_ok = False
|
|
product.website_published = True
|
|
|
|
with self.assertRaises(UserError):
|
|
with MockRequest(product.with_user(self.public_user).env, website=self.website.with_user(self.public_user)):
|
|
self.WebsiteSaleController.cart_update_json(product_id=product.id, add_qty=1)
|
|
|
|
def test_add_cart_archived_product(self):
|
|
# Try to add an archived product
|
|
product = self.env['product.product'].create({
|
|
'name': 'Test Product',
|
|
'sale_ok': True,
|
|
})
|
|
product.active = False
|
|
|
|
with self.assertRaises(UserError):
|
|
with MockRequest(product.with_user(self.public_user).env, website=self.website.with_user(self.public_user)):
|
|
self.WebsiteSaleController.cart_update_json(product_id=product.id, add_qty=1)
|
|
|
|
def test_zero_price_product_rule(self):
|
|
"""
|
|
With the `prevent_zero_price_sale` that we have on website, we can't add free products
|
|
to our cart.
|
|
There is an exception for certain product types specified by the
|
|
`_get_product_types_allow_zero_price` method, so this test ensures that it works
|
|
by mocking that function to return the "service" product type.
|
|
"""
|
|
website_prevent_zero_price = self.env['website'].create({
|
|
'name': 'Prevent zero price sale',
|
|
'prevent_zero_price_sale': True,
|
|
})
|
|
product_consu = self.env['product.product'].create({
|
|
'name': 'Cannot be zero price',
|
|
'detailed_type': 'consu',
|
|
'list_price': 0,
|
|
'website_published': True,
|
|
})
|
|
product_service = self.env['product.product'].create({
|
|
'name': 'Can be zero price',
|
|
'detailed_type': 'service',
|
|
'list_price': 0,
|
|
'website_published': True,
|
|
})
|
|
|
|
with patch.object(ProductTemplate, '_get_product_types_allow_zero_price', lambda pt: ['service']):
|
|
with self.assertRaises(UserError, msg="'consu' product type is not allowed to have a 0 price sale"), \
|
|
MockRequest(self.env, website=website_prevent_zero_price):
|
|
self.WebsiteSaleController.cart_update_json(product_id=product_consu.id, add_qty=1)
|
|
|
|
# service types should not raise a UserError
|
|
with MockRequest(self.env, website=website_prevent_zero_price):
|
|
self.WebsiteSaleController.cart_update_json(product_id=product_service.id, add_qty=1)
|
|
|
|
def test_update_cart_before_payment(self):
|
|
website = self.website.with_user(self.public_user)
|
|
with MockRequest(self.product.with_user(self.public_user).env, website=website):
|
|
self.WebsiteSaleController.cart_update_json(product_id=self.product.id, add_qty=1)
|
|
sale_order = website.sale_get_order()
|
|
sale_order.access_token = 'test_token'
|
|
old_amount = sale_order.amount_total
|
|
self.WebsiteSaleController.cart_update_json(product_id=self.product.id, add_qty=1)
|
|
# Try processing payment with the old amount
|
|
with self.assertRaises(UserError):
|
|
PaymentPortal().shop_payment_transaction(sale_order.id, sale_order.access_token, amount=old_amount)
|
|
|
|
def test_check_order_delivery_before_payment(self):
|
|
website = self.website.with_user(self.public_user)
|
|
with MockRequest(self.product.with_user(self.public_user).env, website=website):
|
|
sale_order = self.env['sale.order'].create({
|
|
'partner_id': self.public_user.id,
|
|
'order_line': [Command.create({'product_id': self.product.id})],
|
|
'access_token': 'test_token',
|
|
})
|
|
# Try processing payment with a storable product and no carrier_id
|
|
with self.assertRaises(ValidationError):
|
|
PaymentPortal().shop_payment_transaction(sale_order.id, sale_order.access_token)
|
|
|
|
def test_update_cart_zero_qty(self):
|
|
# Try to remove a product that has already been removed
|
|
product = self.env['product.product'].create({
|
|
'name': 'Test Product',
|
|
'sale_ok': True,
|
|
'website_published': True,
|
|
'lst_price': 1000.0,
|
|
'standard_price': 800.0,
|
|
})
|
|
portal_user = self.user_portal
|
|
website = self.website.with_user(portal_user)
|
|
|
|
SaleOrderLine = self.env['sale.order.line']
|
|
|
|
with MockRequest(product.with_user(portal_user).env, website=website):
|
|
# add the product to the cart
|
|
self.WebsiteSaleController.cart_update_json(product_id=product.id, add_qty=1)
|
|
sale_order = website.sale_get_order()
|
|
self.assertEqual(sale_order.amount_untaxed, 1000.0)
|
|
|
|
# remove the product from the cart
|
|
self.WebsiteSaleController.cart_update_json(product_id=product.id, line_id=sale_order.order_line.id, set_qty=0)
|
|
self.assertEqual(sale_order.amount_total, 0.0)
|
|
self.assertEqual(sale_order.order_line, SaleOrderLine)
|
|
|
|
# removing the product again doesn't add a line with zero quantity
|
|
self.WebsiteSaleController.cart_update_json(product_id=product.id, set_qty=0)
|
|
self.assertEqual(sale_order.order_line, SaleOrderLine)
|
|
|
|
self.WebsiteSaleController.cart_update_json(product_id=product.id, add_qty=0)
|
|
self.assertEqual(sale_order.order_line, SaleOrderLine)
|
|
|
|
def test_unpublished_accessory_product_visibility(self):
|
|
# Check if unpublished product is shown to public user
|
|
accessory_product = self.env['product.product'].create({
|
|
'name': 'Access Product',
|
|
'is_published': False,
|
|
})
|
|
|
|
product = self.env['product.product'].create({
|
|
'name': 'Test Product',
|
|
'sale_ok': True,
|
|
'website_published': True,
|
|
'accessory_product_ids': [Command.link(accessory_product.id)]
|
|
})
|
|
|
|
website = self.website.with_user(self.public_user)
|
|
with MockRequest(product.with_user(self.public_user).env, website=self.website.with_user(self.public_user)):
|
|
self.WebsiteSaleController.cart_update_json(product_id=product.id, add_qty=1)
|
|
sale_order = website.sale_get_order()
|
|
self.assertEqual(len(sale_order._cart_accessories()), 0)
|
|
|
|
def test_remove_archived_product_line(self):
|
|
"""If an order has a line containing an archived product,
|
|
it is removed when opening the order in the cart."""
|
|
# Arrange
|
|
user = self.public_user
|
|
website = self.website.with_user(user)
|
|
product = self.env['product.product'].create({
|
|
'name': 'Product',
|
|
'sale_ok': True,
|
|
'website_published': True,
|
|
})
|
|
with MockRequest(self.env(user=user), website=website):
|
|
self.WebsiteSaleController.cart_update_json(product_id=product.id, add_qty=1)
|
|
order = website.sale_get_order()
|
|
|
|
# pre-condition: the order contains an active product
|
|
self.assertRecordValues(order.order_line, [{
|
|
"product_id": product.id,
|
|
}])
|
|
self.assertTrue(product.active)
|
|
|
|
# Act: archive the product and open the cart
|
|
product.active = False
|
|
self.WebsiteSaleController.cart()
|
|
|
|
# Assert: the line has been removed
|
|
self.assertFalse(order.order_line)
|
|
|
|
def test_keep_note_line(self):
|
|
"""If an order has a line containing a note,
|
|
it is not removed when opening the order in the cart."""
|
|
# Arrange
|
|
user = self.public_user
|
|
website = self.website.with_user(user)
|
|
with MockRequest(self.env(user=user), website=website):
|
|
order = website.sale_get_order(force_create=True)
|
|
order.order_line = [
|
|
Command.create({
|
|
"name": "Note",
|
|
"display_type": "line_note",
|
|
})
|
|
]
|
|
|
|
# pre-condition: the order contains only a note line
|
|
self.assertRecordValues(order.order_line, [{
|
|
"display_type": "line_note",
|
|
}])
|
|
|
|
# Act: open the cart
|
|
self.WebsiteSaleController.cart()
|
|
|
|
# Assert: the line is still there
|
|
self.assertRecordValues(order.order_line, [{
|
|
"display_type": "line_note",
|
|
}])
|