# Copyright 2025 Criptomart # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) """ Test suite for HTTP endpoints in website_sale_aplicoop controllers. Coverage: - /eskaera (GET) - View all group orders - /eskaera/ (GET) - View specific group order - /eskaera//add-to-cart (POST) - Add product to cart - /eskaera//checkout (GET) - Checkout page - /eskaera//checkout (POST) - Save cart items - /eskaera/confirm (POST) - Confirm order - /eskaera//confirm/ (POST) - Confirm order from portal - /eskaera//load-from-history/ (POST) - Load draft order - /eskaera/labels (GET) - Get translated labels """ from datetime import datetime, timedelta import json from odoo.tests.common import TransactionCase, HttpCase from odoo.exceptions import ValidationError, AccessError class TestEskaearaListEndpoint(TransactionCase): """Test /eskaera endpoint (list all group orders).""" def setUp(self): super().setUp() self.group = self.env['res.partner'].create({ 'name': 'Test Group', 'is_company': True, 'email': 'group@test.com', }) self.member_partner = self.env['res.partner'].create({ 'name': 'Group Member', 'email': 'member@test.com', }) self.group.member_ids = [(4, self.member_partner.id)] self.user = self.env['res.users'].create({ 'name': 'Test User', 'login': 'testuser@test.com', 'email': 'testuser@test.com', 'partner_id': self.member_partner.id, }) # Create multiple group orders (some open, some closed) start_date = datetime.now().date() self.open_order = self.env['group.order'].create({ 'name': 'Open Order', 'group_ids': [(6, 0, [self.group.id])], 'type': 'regular', 'start_date': start_date, 'end_date': start_date + timedelta(days=7), 'period': 'weekly', 'pickup_day': '3', 'cutoff_day': '0', }) self.open_order.action_open() self.draft_order = self.env['group.order'].create({ 'name': 'Draft Order', 'group_ids': [(6, 0, [self.group.id])], 'type': 'regular', 'start_date': start_date - timedelta(days=14), 'end_date': start_date - timedelta(days=7), 'period': 'weekly', 'pickup_day': '3', 'cutoff_day': '0', }) # Stay in draft self.closed_order = self.env['group.order'].create({ 'name': 'Closed Order', 'group_ids': [(6, 0, [self.group.id])], 'type': 'regular', 'start_date': start_date - timedelta(days=21), 'end_date': start_date - timedelta(days=14), 'period': 'weekly', 'pickup_day': '3', 'cutoff_day': '0', }) self.closed_order.action_open() self.closed_order.action_close() def test_eskaera_list_shows_only_open_and_draft_orders(self): """Test that /eskaera shows only open/draft orders, not closed.""" # In controller context, only open and draft should be visible to members # This is business logic: closed orders are historical visible_orders = self.env['group.order'].search([ ('state', 'in', ['open', 'draft']), ('group_ids', 'in', self.group.id), ]) self.assertIn(self.open_order, visible_orders) self.assertIn(self.draft_order, visible_orders) self.assertNotIn(self.closed_order, visible_orders) def test_eskaera_list_filters_by_user_groups(self): """Test that user only sees orders from their groups.""" other_group = self.env['res.partner'].create({ 'name': 'Other Group', 'is_company': True, 'email': 'other@test.com', }) other_order = self.env['group.order'].create({ 'name': 'Other Group Order', 'group_ids': [(6, 0, [other_group.id])], 'type': 'regular', 'start_date': datetime.now().date(), 'end_date': datetime.now().date() + timedelta(days=7), 'period': 'weekly', 'pickup_day': '3', 'cutoff_day': '0', }) other_order.action_open() # User should not see orders from groups they're not in user_groups = self.member_partner.group_ids visible_orders = self.env['group.order'].search([ ('state', 'in', ['open', 'draft']), ('group_ids', 'in', user_groups.ids), ]) self.assertNotIn(other_order, visible_orders) class TestAddToCartEndpoint(TransactionCase): """Test /eskaera//add-to-cart endpoint.""" def setUp(self): super().setUp() self.group = self.env['res.partner'].create({ 'name': 'Test Group', 'is_company': True, 'email': 'group@test.com', }) self.member_partner = self.env['res.partner'].create({ 'name': 'Group Member', 'email': 'member@test.com', }) self.group.member_ids = [(4, self.member_partner.id)] self.user = self.env['res.users'].create({ 'name': 'Test User', 'login': 'testuser@test.com', 'email': 'testuser@test.com', 'partner_id': self.member_partner.id, }) self.category = self.env['product.category'].create({ 'name': 'Test Category', }) # Published product self.product = self.env['product.product'].create({ 'name': 'Test Product', 'type': 'consu', 'list_price': 10.0, 'categ_id': self.category.id, 'sale_ok': True, 'is_published': True, }) # Unpublished product (should not be available) self.unpublished_product = self.env['product.product'].create({ 'name': 'Unpublished Product', 'type': 'consu', 'list_price': 15.0, 'categ_id': self.category.id, 'sale_ok': False, 'is_published': False, }) start_date = datetime.now().date() self.group_order = self.env['group.order'].create({ 'name': 'Test Order', 'group_ids': [(6, 0, [self.group.id])], 'type': 'regular', 'start_date': start_date, 'end_date': start_date + timedelta(days=7), 'period': 'weekly', 'pickup_day': '3', 'cutoff_day': '0', }) self.group_order.action_open() self.group_order.product_ids = [(4, self.product.id)] def test_add_to_cart_published_product(self): """Test adding published product to cart.""" # Simulate controller logic cart_line = { 'product_id': self.product.id, 'quantity': 2, 'group_order_id': self.group_order.id, 'partner_id': self.member_partner.id, } # Should succeed self.assertTrue(cart_line['product_id']) def test_add_to_cart_zero_quantity(self): """Test that adding zero quantity is rejected.""" # Edge case: quantity = 0 quantity = 0 # Controller should validate: quantity > 0 self.assertFalse(quantity > 0) def test_add_to_cart_negative_quantity(self): """Test that negative quantity is rejected.""" quantity = -5 # Controller should validate: quantity > 0 self.assertFalse(quantity > 0) def test_add_to_cart_unpublished_product(self): """Test that unpublished products cannot be added.""" # Product must be published and sale_ok=True self.assertFalse(self.unpublished_product.is_published) self.assertFalse(self.unpublished_product.sale_ok) def test_add_to_cart_product_not_in_order(self): """Test that products not in the order cannot be added.""" # Create a product NOT associated with group_order other_product = self.env['product.product'].create({ 'name': 'Other Product', 'type': 'consu', 'list_price': 25.0, }) # Controller should check: product in group_order.product_ids self.assertNotIn(other_product, self.group_order.product_ids) def test_add_to_cart_order_closed(self): """Test that adding to closed order is rejected.""" self.group_order.action_close() # Controller should check: order.state == 'open' self.assertEqual(self.group_order.state, 'closed') class TestCheckoutEndpoint(TransactionCase): """Test /eskaera//checkout endpoint.""" def setUp(self): super().setUp() self.group = self.env['res.partner'].create({ 'name': 'Test Group', 'is_company': True, 'email': 'group@test.com', }) self.member_partner = self.env['res.partner'].create({ 'name': 'Group Member', 'email': 'member@test.com', }) self.group.member_ids = [(4, self.member_partner.id)] self.user = self.env['res.users'].create({ 'name': 'Test User', 'login': 'testuser@test.com', 'email': 'testuser@test.com', 'partner_id': self.member_partner.id, }) start_date = datetime.now().date() self.group_order = self.env['group.order'].create({ 'name': 'Test Order', 'group_ids': [(6, 0, [self.group.id])], 'type': 'regular', 'start_date': start_date, 'end_date': start_date + timedelta(days=7), 'period': 'weekly', 'pickup_day': '3', 'pickup_date': start_date + timedelta(days=3), 'cutoff_day': '0', }) self.group_order.action_open() def test_checkout_page_loads(self): """Test that checkout page renders correctly.""" # Controller should render template with group_order context self.assertTrue(self.group_order.exists()) def test_checkout_displays_pickup_date(self): """Test that checkout shows correct pickup date.""" # Controller should calculate pickup_date from pickup_day self.assertTrue(self.group_order.pickup_date) def test_checkout_displays_home_delivery_option(self): """Test that checkout shows home delivery option.""" # Controller should pass home_delivery flag to template self.assertIsNotNone(self.group_order.home_delivery) def test_checkout_order_without_products(self): """Test checkout when no products available.""" # Order with empty product_ids empty_order = self.env['group.order'].create({ 'name': 'Empty Order', 'group_ids': [(6, 0, [self.group.id])], 'type': 'regular', 'start_date': datetime.now().date(), 'end_date': datetime.now().date() + timedelta(days=7), 'period': 'weekly', 'pickup_day': '3', 'cutoff_day': '0', }) empty_order.action_open() # Should handle gracefully self.assertEqual(len(empty_order.product_ids), 0) class TestConfirmOrderEndpoint(TransactionCase): """Test /eskaera/confirm endpoint (confirm final order).""" def setUp(self): super().setUp() self.group = self.env['res.partner'].create({ 'name': 'Test Group', 'is_company': True, 'email': 'group@test.com', }) self.member_partner = self.env['res.partner'].create({ 'name': 'Group Member', 'email': 'member@test.com', }) self.group.member_ids = [(4, self.member_partner.id)] self.user = self.env['res.users'].create({ 'name': 'Test User', 'login': 'testuser@test.com', 'email': 'testuser@test.com', 'partner_id': self.member_partner.id, }) self.category = self.env['product.category'].create({ 'name': 'Test Category', }) self.product = self.env['product.product'].create({ 'name': 'Test Product', 'type': 'consu', 'list_price': 10.0, 'categ_id': self.category.id, }) start_date = datetime.now().date() self.group_order = self.env['group.order'].create({ 'name': 'Test Order', 'group_ids': [(6, 0, [self.group.id])], 'type': 'regular', 'start_date': start_date, 'end_date': start_date + timedelta(days=7), 'period': 'weekly', 'pickup_day': '3', 'pickup_date': start_date + timedelta(days=3), 'cutoff_day': '0', }) self.group_order.action_open() self.group_order.product_ids = [(4, self.product.id)] # Create a draft sale order self.draft_sale = self.env['sale.order'].create({ 'partner_id': self.member_partner.id, 'group_order_id': self.group_order.id, 'pickup_date': self.group_order.pickup_date, 'state': 'draft', }) def test_confirm_order_creates_sale_order(self): """Test that confirming creates a confirmed sale.order.""" # Controller should change state from draft to sale self.draft_sale.action_confirm() self.assertEqual(self.draft_sale.state, 'sale') def test_confirm_empty_order(self): """Test confirming order without items fails.""" # Order with no order_lines should fail empty_sale = self.env['sale.order'].create({ 'partner_id': self.member_partner.id, 'group_order_id': self.group_order.id, 'state': 'draft', }) # Should validate: must have at least one line self.assertEqual(len(empty_sale.order_line), 0) def test_confirm_order_wrong_group(self): """Test that user cannot confirm order from different group.""" other_group = self.env['res.partner'].create({ 'name': 'Other Group', 'is_company': True, }) other_order = self.env['group.order'].create({ 'name': 'Other Order', 'group_ids': [(6, 0, [other_group.id])], 'type': 'regular', 'start_date': datetime.now().date(), 'end_date': datetime.now().date() + timedelta(days=7), 'period': 'weekly', 'pickup_day': '3', 'cutoff_day': '0', }) # User should not be in other_group self.assertNotIn(self.member_partner, other_group.member_ids) class TestLoadDraftEndpoint(TransactionCase): """Test /eskaera//load-from-history/ endpoint.""" def setUp(self): super().setUp() self.group = self.env['res.partner'].create({ 'name': 'Test Group', 'is_company': True, 'email': 'group@test.com', }) self.member_partner = self.env['res.partner'].create({ 'name': 'Group Member', 'email': 'member@test.com', }) self.group.member_ids = [(4, self.member_partner.id)] self.user = self.env['res.users'].create({ 'name': 'Test User', 'login': 'testuser@test.com', 'email': 'testuser@test.com', 'partner_id': self.member_partner.id, }) self.category = self.env['product.category'].create({ 'name': 'Test Category', }) self.product = self.env['product.product'].create({ 'name': 'Test Product', 'type': 'consu', 'list_price': 10.0, 'categ_id': self.category.id, }) start_date = datetime.now().date() self.group_order = self.env['group.order'].create({ 'name': 'Test Order', 'group_ids': [(6, 0, [self.group.id])], 'type': 'regular', 'start_date': start_date, 'end_date': start_date + timedelta(days=7), 'period': 'weekly', 'pickup_day': '3', 'pickup_date': start_date + timedelta(days=3), 'cutoff_day': '0', }) self.group_order.action_open() self.group_order.product_ids = [(4, self.product.id)] def test_load_draft_from_history(self): """Test loading a previous draft order.""" # Create old draft sale old_sale = self.env['sale.order'].create({ 'partner_id': self.member_partner.id, 'group_order_id': self.group_order.id, 'state': 'draft', }) # Should be able to load self.assertTrue(old_sale.exists()) def test_load_draft_not_owned_by_user(self): """Test that user cannot load draft from other user.""" other_partner = self.env['res.partner'].create({ 'name': 'Other Member', 'email': 'other@test.com', }) other_sale = self.env['sale.order'].create({ 'partner_id': other_partner.id, 'group_order_id': self.group_order.id, 'state': 'draft', }) # User should not be able to load other's draft self.assertNotEqual(other_sale.partner_id, self.member_partner) def test_load_draft_expired_order(self): """Test loading draft from expired group order.""" old_start = datetime.now().date() - timedelta(days=30) old_end = datetime.now().date() - timedelta(days=23) expired_order = self.env['group.order'].create({ 'name': 'Expired Order', 'group_ids': [(6, 0, [self.group.id])], 'type': 'regular', 'start_date': old_start, 'end_date': old_end, 'period': 'weekly', 'pickup_day': '3', 'cutoff_day': '0', }) expired_order.action_open() expired_order.action_close() old_sale = self.env['sale.order'].create({ 'partner_id': self.member_partner.id, 'group_order_id': expired_order.id, 'state': 'draft', }) # Should warn: order expired self.assertEqual(expired_order.state, 'closed')