444 lines
17 KiB
Python
444 lines
17 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo.tests.common import TransactionCase
|
|
from hypothesis import given, strategies as st, settings
|
|
from odoo.exceptions import ValidationError
|
|
|
|
|
|
class TestNoRegression(TransactionCase):
|
|
"""Test cases to verify no regression in other Odoo apps using rating system"""
|
|
|
|
def setUp(self):
|
|
super(TestNoRegression, self).setUp()
|
|
self.Rating = self.env['rating.rating']
|
|
self.Partner = self.env['res.partner']
|
|
self.User = self.env['res.users']
|
|
|
|
# Create test data
|
|
self.test_partner = self.Partner.create({
|
|
'name': 'Test Customer Regression',
|
|
'email': 'regression@example.com',
|
|
})
|
|
|
|
self.test_user = self.User.create({
|
|
'name': 'Test User Regression',
|
|
'login': 'testuser_regression',
|
|
'email': 'testuser_regression@example.com',
|
|
})
|
|
|
|
def _create_rating_for_model(self, model_name, res_id, rating_value, **kwargs):
|
|
"""Helper method to create a rating for any model"""
|
|
res_model_id = self.env['ir.model'].search([('model', '=', model_name)], limit=1)
|
|
|
|
if not res_model_id:
|
|
# Model doesn't exist in this installation
|
|
return None
|
|
|
|
vals = {
|
|
'rating': rating_value,
|
|
'partner_id': self.test_partner.id,
|
|
'rated_partner_id': self.test_user.partner_id.id,
|
|
'res_model_id': res_model_id.id,
|
|
'res_id': res_id,
|
|
}
|
|
vals.update(kwargs)
|
|
return self.Rating.create(vals)
|
|
|
|
# Feature: helpdesk-rating-five-stars, Property 15: No regression in other apps
|
|
@given(rating_value=st.floats(min_value=1.0, max_value=5.0, allow_nan=False, allow_infinity=False))
|
|
@settings(max_examples=20, deadline=None)
|
|
def test_property_project_task_rating_works(self, rating_value):
|
|
"""
|
|
Property 15: No regression in other apps
|
|
For any existing Odoo app using the rating system, the functionality
|
|
should continue to work after module installation.
|
|
|
|
This test verifies that project.task ratings still work correctly.
|
|
|
|
Validates: Requirements 6.4
|
|
"""
|
|
# Check if project module is installed
|
|
if 'project.task' not in self.env:
|
|
self.skipTest("Project module not installed")
|
|
|
|
# Create a project and task
|
|
Project = self.env['project.project']
|
|
Task = self.env['project.task']
|
|
|
|
project = Project.create({
|
|
'name': 'Test Project for Regression',
|
|
'rating_active': True,
|
|
})
|
|
|
|
task = Task.create({
|
|
'name': 'Test Task for Regression',
|
|
'project_id': project.id,
|
|
})
|
|
|
|
# Create rating for the task
|
|
rating = self._create_rating_for_model('project.task', task.id, rating_value)
|
|
|
|
if rating is None:
|
|
self.skipTest("Could not create rating for project.task")
|
|
|
|
# Verify rating was created successfully
|
|
self.assertTrue(rating.id, "Rating should be created for project.task")
|
|
self.assertEqual(rating.res_model, 'project.task',
|
|
"Rating res_model should be 'project.task'")
|
|
self.assertEqual(rating.res_id, task.id,
|
|
"Rating res_id should match task ID")
|
|
|
|
# Verify rating value is stored correctly
|
|
self.assertGreaterEqual(rating.rating, 1.0,
|
|
"Rating value should be >= 1.0")
|
|
self.assertLessEqual(rating.rating, 5.0,
|
|
"Rating value should be <= 5.0")
|
|
|
|
# Verify we can read the rating back
|
|
found_rating = self.Rating.search([
|
|
('res_model', '=', 'project.task'),
|
|
('res_id', '=', task.id),
|
|
('id', '=', rating.id)
|
|
])
|
|
|
|
self.assertEqual(found_rating, rating,
|
|
"Should be able to search and find project.task rating")
|
|
|
|
@given(rating_value=st.floats(min_value=1.0, max_value=5.0, allow_nan=False, allow_infinity=False))
|
|
@settings(max_examples=20, deadline=None)
|
|
def test_property_sale_order_rating_works(self, rating_value):
|
|
"""
|
|
Property 15: No regression in other apps
|
|
For any existing Odoo app using the rating system, the functionality
|
|
should continue to work after module installation.
|
|
|
|
This test verifies that sale.order ratings still work correctly.
|
|
|
|
Validates: Requirements 6.4
|
|
"""
|
|
# Check if sale module is installed
|
|
if 'sale.order' not in self.env:
|
|
self.skipTest("Sale module not installed")
|
|
|
|
# Create a sale order
|
|
SaleOrder = self.env['sale.order']
|
|
|
|
sale_order = SaleOrder.create({
|
|
'name': 'Test SO for Regression',
|
|
'partner_id': self.test_partner.id,
|
|
})
|
|
|
|
# Create rating for the sale order
|
|
rating = self._create_rating_for_model('sale.order', sale_order.id, rating_value)
|
|
|
|
if rating is None:
|
|
self.skipTest("Could not create rating for sale.order")
|
|
|
|
# Verify rating was created successfully
|
|
self.assertTrue(rating.id, "Rating should be created for sale.order")
|
|
self.assertEqual(rating.res_model, 'sale.order',
|
|
"Rating res_model should be 'sale.order'")
|
|
self.assertEqual(rating.res_id, sale_order.id,
|
|
"Rating res_id should match sale order ID")
|
|
|
|
# Verify rating value is stored correctly
|
|
self.assertGreaterEqual(rating.rating, 1.0,
|
|
"Rating value should be >= 1.0")
|
|
self.assertLessEqual(rating.rating, 5.0,
|
|
"Rating value should be <= 5.0")
|
|
|
|
# Verify we can update the rating
|
|
new_value = min(5.0, rating_value + 1.0)
|
|
rating.write({'rating': new_value})
|
|
self.assertAlmostEqual(rating.rating, new_value, places=2,
|
|
msg="Should be able to update sale.order rating")
|
|
|
|
@given(rating_value=st.floats(min_value=1.0, max_value=5.0, allow_nan=False, allow_infinity=False))
|
|
@settings(max_examples=20, deadline=None)
|
|
def test_property_generic_model_rating_works(self, rating_value):
|
|
"""
|
|
Property 15: No regression in other apps
|
|
For any existing Odoo app using the rating system, the functionality
|
|
should continue to work after module installation.
|
|
|
|
This test verifies that ratings for generic models (res.partner)
|
|
still work correctly.
|
|
|
|
Validates: Requirements 6.4
|
|
"""
|
|
# Use res.partner as a generic model that always exists
|
|
partner = self.Partner.create({
|
|
'name': 'Test Partner for Rating',
|
|
'email': 'partner_rating@example.com',
|
|
})
|
|
|
|
# Create rating for the partner
|
|
rating = self._create_rating_for_model('res.partner', partner.id, rating_value)
|
|
|
|
# Verify rating was created successfully
|
|
self.assertTrue(rating.id, "Rating should be created for res.partner")
|
|
self.assertEqual(rating.res_model, 'res.partner',
|
|
"Rating res_model should be 'res.partner'")
|
|
self.assertEqual(rating.res_id, partner.id,
|
|
"Rating res_id should match partner ID")
|
|
|
|
# Verify rating value is stored correctly
|
|
self.assertGreaterEqual(rating.rating, 1.0,
|
|
"Rating value should be >= 1.0")
|
|
self.assertLessEqual(rating.rating, 5.0,
|
|
"Rating value should be <= 5.0")
|
|
|
|
# Verify standard rating operations work
|
|
# 1. Search
|
|
found = self.Rating.search([('id', '=', rating.id)])
|
|
self.assertEqual(found, rating, "Should be able to search rating")
|
|
|
|
# 2. Write
|
|
rating.write({'feedback': 'Test feedback'})
|
|
self.assertEqual(rating.feedback, 'Test feedback',
|
|
"Should be able to write to rating")
|
|
|
|
# 3. Unlink
|
|
rating_id = rating.id
|
|
rating.unlink()
|
|
exists = self.Rating.search([('id', '=', rating_id)])
|
|
self.assertFalse(exists, "Should be able to unlink rating")
|
|
|
|
@given(
|
|
rating_value=st.floats(min_value=1.0, max_value=5.0, allow_nan=False, allow_infinity=False),
|
|
feedback_text=st.text(alphabet=st.characters(blacklist_characters='\x00', blacklist_categories=('Cs',)), min_size=0, max_size=100)
|
|
)
|
|
@settings(max_examples=20, deadline=None)
|
|
def test_property_rating_with_feedback_works(self, rating_value, feedback_text):
|
|
"""
|
|
Property 15: No regression in other apps
|
|
For any existing Odoo app using the rating system, the functionality
|
|
should continue to work after module installation.
|
|
|
|
This test verifies that ratings with feedback still work correctly
|
|
for any model.
|
|
|
|
Validates: Requirements 6.4
|
|
"""
|
|
# Use res.partner as a generic model
|
|
partner = self.Partner.create({
|
|
'name': 'Test Partner for Feedback',
|
|
'email': 'feedback@example.com',
|
|
})
|
|
|
|
# Create rating with feedback
|
|
rating = self._create_rating_for_model(
|
|
'res.partner',
|
|
partner.id,
|
|
rating_value,
|
|
feedback=feedback_text
|
|
)
|
|
|
|
# Verify rating was created successfully
|
|
self.assertTrue(rating.id, "Rating with feedback should be created")
|
|
|
|
# Verify feedback is stored correctly
|
|
self.assertEqual(rating.feedback, feedback_text,
|
|
"Feedback should be stored correctly")
|
|
|
|
# Verify rating value is stored correctly
|
|
self.assertGreaterEqual(rating.rating, 1.0,
|
|
"Rating value should be >= 1.0")
|
|
self.assertLessEqual(rating.rating, 5.0,
|
|
"Rating value should be <= 5.0")
|
|
|
|
@given(rating_value=st.floats(min_value=1.0, max_value=5.0, allow_nan=False, allow_infinity=False))
|
|
@settings(max_examples=20, deadline=None)
|
|
def test_property_rating_consumed_flag_works(self, rating_value):
|
|
"""
|
|
Property 15: No regression in other apps
|
|
For any existing Odoo app using the rating system, the functionality
|
|
should continue to work after module installation.
|
|
|
|
This test verifies that the consumed flag still works correctly.
|
|
|
|
Validates: Requirements 6.4
|
|
"""
|
|
# Use res.partner as a generic model
|
|
partner = self.Partner.create({
|
|
'name': 'Test Partner for Consumed',
|
|
'email': 'consumed@example.com',
|
|
})
|
|
|
|
# Create rating
|
|
rating = self._create_rating_for_model('res.partner', partner.id, rating_value)
|
|
|
|
# Initially, consumed should be False
|
|
self.assertFalse(rating.consumed,
|
|
"New rating should not be consumed")
|
|
|
|
# Mark as consumed
|
|
rating.write({'consumed': True})
|
|
self.assertTrue(rating.consumed,
|
|
"Should be able to mark rating as consumed")
|
|
|
|
# Reset should clear consumed flag
|
|
rating.reset()
|
|
self.assertFalse(rating.consumed,
|
|
"reset() should clear consumed flag")
|
|
self.assertEqual(rating.rating, 0.0,
|
|
"reset() should set rating to 0")
|
|
|
|
@given(rating_value=st.floats(min_value=1.0, max_value=5.0, allow_nan=False, allow_infinity=False))
|
|
@settings(max_examples=20, deadline=None)
|
|
def test_property_rating_access_token_works(self, rating_value):
|
|
"""
|
|
Property 15: No regression in other apps
|
|
For any existing Odoo app using the rating system, the functionality
|
|
should continue to work after module installation.
|
|
|
|
This test verifies that access tokens still work correctly.
|
|
|
|
Validates: Requirements 6.4
|
|
"""
|
|
# Use res.partner as a generic model
|
|
partner = self.Partner.create({
|
|
'name': 'Test Partner for Token',
|
|
'email': 'token@example.com',
|
|
})
|
|
|
|
# Create rating
|
|
rating = self._create_rating_for_model('res.partner', partner.id, rating_value)
|
|
|
|
# Verify access token is generated
|
|
self.assertTrue(rating.access_token,
|
|
"Rating should have an access token")
|
|
|
|
# Store original token
|
|
original_token = rating.access_token
|
|
|
|
# Reset should generate new token
|
|
rating.reset()
|
|
self.assertNotEqual(rating.access_token, original_token,
|
|
"reset() should generate new access token")
|
|
|
|
# Verify we can search by token
|
|
found = self.Rating.search([('access_token', '=', rating.access_token)])
|
|
self.assertIn(rating, found,
|
|
"Should be able to search by access_token")
|
|
|
|
def test_property_rating_text_computed_field_works(self):
|
|
"""
|
|
Property 15: No regression in other apps
|
|
For any existing Odoo app using the rating system, the functionality
|
|
should continue to work after module installation.
|
|
|
|
This test verifies that the rating_text computed field still works.
|
|
|
|
Validates: Requirements 6.4
|
|
"""
|
|
# Use res.partner as a generic model
|
|
partner = self.Partner.create({
|
|
'name': 'Test Partner for Rating Text',
|
|
'email': 'ratingtext@example.com',
|
|
})
|
|
|
|
# Test different rating values
|
|
test_values = [1.0, 2.0, 3.0, 4.0, 5.0]
|
|
|
|
for rating_value in test_values:
|
|
rating = self._create_rating_for_model('res.partner', partner.id, rating_value)
|
|
|
|
# Verify rating_text is computed
|
|
self.assertTrue(rating.rating_text,
|
|
f"rating_text should be computed for rating {rating_value}")
|
|
|
|
# Verify it's a string
|
|
self.assertIsInstance(rating.rating_text, str,
|
|
"rating_text should be a string")
|
|
|
|
# Clean up
|
|
rating.unlink()
|
|
|
|
@given(rating_value=st.floats(min_value=1.0, max_value=5.0, allow_nan=False, allow_infinity=False))
|
|
@settings(max_examples=20, deadline=None)
|
|
def test_property_rating_res_name_computed_field_works(self, rating_value):
|
|
"""
|
|
Property 15: No regression in other apps
|
|
For any existing Odoo app using the rating system, the functionality
|
|
should continue to work after module installation.
|
|
|
|
This test verifies that the res_name computed field still works.
|
|
|
|
Validates: Requirements 6.4
|
|
"""
|
|
# Use res.partner as a generic model
|
|
partner = self.Partner.create({
|
|
'name': 'Test Partner for Res Name',
|
|
'email': 'resname@example.com',
|
|
})
|
|
|
|
# Create rating
|
|
rating = self._create_rating_for_model('res.partner', partner.id, rating_value)
|
|
|
|
# Verify res_name is computed
|
|
self.assertTrue(rating.res_name,
|
|
"res_name should be computed")
|
|
|
|
# Verify it matches the partner name
|
|
self.assertEqual(rating.res_name, partner.name,
|
|
"res_name should match the rated object's name")
|
|
|
|
@given(rating_value=st.floats(min_value=1.0, max_value=5.0, allow_nan=False, allow_infinity=False))
|
|
@settings(max_examples=10, deadline=None)
|
|
def test_property_multiple_ratings_same_model_work(self, rating_value):
|
|
"""
|
|
Property 15: No regression in other apps
|
|
For any existing Odoo app using the rating system, the functionality
|
|
should continue to work after module installation.
|
|
|
|
This test verifies that multiple ratings for the same model work correctly.
|
|
|
|
Validates: Requirements 6.4
|
|
"""
|
|
# Create multiple partners
|
|
partner1 = self.Partner.create({
|
|
'name': 'Test Partner 1',
|
|
'email': 'partner1@example.com',
|
|
})
|
|
|
|
partner2 = self.Partner.create({
|
|
'name': 'Test Partner 2',
|
|
'email': 'partner2@example.com',
|
|
})
|
|
|
|
# Create ratings for both partners
|
|
rating1 = self._create_rating_for_model('res.partner', partner1.id, rating_value)
|
|
rating2 = self._create_rating_for_model('res.partner', partner2.id, min(5.0, rating_value + 1.0))
|
|
|
|
# Verify both ratings exist
|
|
self.assertTrue(rating1.id, "First rating should be created")
|
|
self.assertTrue(rating2.id, "Second rating should be created")
|
|
|
|
# Verify they are different records
|
|
self.assertNotEqual(rating1.id, rating2.id,
|
|
"Ratings should be different records")
|
|
|
|
# Verify they point to different partners
|
|
self.assertEqual(rating1.res_id, partner1.id,
|
|
"First rating should point to first partner")
|
|
self.assertEqual(rating2.res_id, partner2.id,
|
|
"Second rating should point to second partner")
|
|
|
|
# Verify we can search for each independently
|
|
found1 = self.Rating.search([
|
|
('res_model', '=', 'res.partner'),
|
|
('res_id', '=', partner1.id),
|
|
('id', '=', rating1.id)
|
|
])
|
|
self.assertEqual(found1, rating1,
|
|
"Should find first rating independently")
|
|
|
|
found2 = self.Rating.search([
|
|
('res_model', '=', 'res.partner'),
|
|
('res_id', '=', partner2.id),
|
|
('id', '=', rating2.id)
|
|
])
|
|
self.assertEqual(found2, rating2,
|
|
"Should find second rating independently")
|