# -*- coding: utf-8 -*- from odoo.tests.common import TransactionCase from odoo.exceptions import AccessError, ValidationError class TestRatingSecurity(TransactionCase): """Test security and access control for rating system""" def setUp(self): super(TestRatingSecurity, self).setUp() # Create test users self.helpdesk_user = self.env['res.users'].create({ 'name': 'Helpdesk User', 'login': 'helpdesk_user', 'email': 'helpdesk_user@test.com', 'groups_id': [(6, 0, [ self.env.ref('helpdesk.group_helpdesk_user').id, self.env.ref('base.group_user').id ])] }) self.helpdesk_manager = self.env['res.users'].create({ 'name': 'Helpdesk Manager', 'login': 'helpdesk_manager', 'email': 'helpdesk_manager@test.com', 'groups_id': [(6, 0, [ self.env.ref('helpdesk.group_helpdesk_manager').id, self.env.ref('base.group_user').id ])] }) # Create test team self.team = self.env['helpdesk.team'].create({ 'name': 'Test Team', 'use_rating': True, }) # Create test ticket self.ticket = self.env['helpdesk.ticket'].create({ 'name': 'Test Ticket', 'team_id': self.team.id, 'partner_id': self.env.user.partner_id.id, }) # Create test rating self.rating = self.env['rating.rating'].create({ 'res_model': 'helpdesk.ticket', 'res_id': self.ticket.id, 'rating': 4.0, 'consumed': True, }) def test_helpdesk_user_can_read_ratings(self): """Test that helpdesk users can read ratings""" # Switch to helpdesk user rating_as_user = self.rating.with_user(self.helpdesk_user) # Should be able to read self.assertEqual(rating_as_user.rating, 4.0) self.assertEqual(rating_as_user.res_model, 'helpdesk.ticket') def test_helpdesk_user_can_write_ratings(self): """Test that helpdesk users can modify ratings""" # Switch to helpdesk user rating_as_user = self.rating.with_user(self.helpdesk_user) # Should be able to write rating_as_user.write({'rating': 5.0}) self.assertEqual(rating_as_user.rating, 5.0) def test_helpdesk_user_cannot_delete_ratings(self): """Test that helpdesk users cannot delete ratings""" # Switch to helpdesk user rating_as_user = self.rating.with_user(self.helpdesk_user) # Should not be able to delete with self.assertRaises(AccessError): rating_as_user.unlink() def test_helpdesk_manager_can_delete_ratings(self): """Test that helpdesk managers can delete ratings""" # Switch to helpdesk manager rating_as_manager = self.rating.with_user(self.helpdesk_manager) # Should be able to delete rating_as_manager.unlink() self.assertFalse(rating_as_manager.exists()) def test_rating_validation_enforced(self): """Test that rating validation is enforced regardless of user""" # Try to create invalid rating as manager with self.assertRaises(ValidationError): self.env['rating.rating'].with_user(self.helpdesk_manager).create({ 'res_model': 'helpdesk.ticket', 'res_id': self.ticket.id, 'rating': 6.0, # Invalid: > 5 'consumed': True, }) # Try to create invalid rating as user with self.assertRaises(ValidationError): self.env['rating.rating'].with_user(self.helpdesk_user).create({ 'res_model': 'helpdesk.ticket', 'res_id': self.ticket.id, 'rating': -1.0, # Invalid: < 0 'consumed': True, }) def test_audit_logging_on_create(self): """Test that rating creation is logged""" # Create a new rating new_rating = self.env['rating.rating'].create({ 'res_model': 'helpdesk.ticket', 'res_id': self.ticket.id, 'rating': 3.0, 'consumed': True, }) # Verify rating was created self.assertEqual(new_rating.rating, 3.0) self.assertTrue(new_rating.consumed) def test_audit_logging_on_write(self): """Test that rating modifications are logged""" # Modify the rating old_value = self.rating.rating self.rating.write({'rating': 5.0}) # Verify rating was modified self.assertEqual(self.rating.rating, 5.0) self.assertNotEqual(self.rating.rating, old_value) def test_tracking_fields(self): """Test that tracking is enabled on key fields""" # Check that rating field has tracking rating_field = self.env['rating.rating']._fields['rating'] self.assertTrue(hasattr(rating_field, 'tracking')) # Check that feedback field has tracking feedback_field = self.env['rating.rating']._fields['feedback'] self.assertTrue(hasattr(feedback_field, 'tracking')) # Check that consumed field has tracking consumed_field = self.env['rating.rating']._fields['consumed'] self.assertTrue(hasattr(consumed_field, 'tracking')) def test_public_access_via_controller(self): """Test that public users can submit ratings via token (controller handles this)""" # This is tested in the controller tests # Public access is granted through sudo() in the controller with token validation # No direct model access is needed for public users pass def test_rating_modification_restricted(self): """Test that only authorized users can modify ratings""" # Create a portal user (not authorized) portal_user = self.env['res.users'].create({ 'name': 'Portal User', 'login': 'portal_user', 'email': 'portal@test.com', 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])] }) # Portal user should not be able to modify ratings directly rating_as_portal = self.rating.with_user(portal_user) # Should not have access with self.assertRaises(AccessError): rating_as_portal.write({'rating': 2.0})