135 lines
5.7 KiB
Python
135 lines
5.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo.tests.common import TransactionCase
|
|
from odoo.exceptions import ValidationError
|
|
from hypothesis import given, strategies as st, settings
|
|
|
|
|
|
class TestRatingModel(TransactionCase):
|
|
"""Test cases for the extended rating model"""
|
|
|
|
def setUp(self):
|
|
super(TestRatingModel, self).setUp()
|
|
self.Rating = self.env['rating.rating']
|
|
self.Partner = self.env['res.partner']
|
|
self.User = self.env['res.users']
|
|
|
|
# Create test partner and user for rating context
|
|
self.test_partner = self.Partner.create({
|
|
'name': 'Test Customer',
|
|
'email': 'test@example.com',
|
|
})
|
|
|
|
self.test_user = self.User.create({
|
|
'name': 'Test User',
|
|
'login': 'testuser',
|
|
'email': 'testuser@example.com',
|
|
})
|
|
|
|
def _create_rating(self, rating_value):
|
|
"""Helper method to create a rating with given value"""
|
|
return self.Rating.create({
|
|
'rating': rating_value,
|
|
'partner_id': self.test_partner.id,
|
|
'rated_partner_id': self.test_user.partner_id.id,
|
|
'res_model': 'res.partner',
|
|
'res_id': self.test_partner.id,
|
|
})
|
|
|
|
# Feature: helpdesk-rating-five-stars, Property 4: Rating persistence within valid range
|
|
@given(rating_value=st.floats(min_value=1.0, max_value=5.0, allow_nan=False, allow_infinity=False))
|
|
@settings(max_examples=100, deadline=None)
|
|
def test_property_valid_rating_persistence(self, rating_value):
|
|
"""
|
|
Property 4: Rating persistence within valid range
|
|
For any submitted rating between 1-5, the stored Rating_Value
|
|
in the database should be between 1 and 5.
|
|
|
|
Validates: Requirements 1.5
|
|
"""
|
|
# Create rating with valid value
|
|
rating = self._create_rating(rating_value)
|
|
|
|
# Verify the rating was stored
|
|
self.assertTrue(rating.id, "Rating should be created")
|
|
|
|
# Verify the stored value is within valid range
|
|
self.assertGreaterEqual(rating.rating, 1.0,
|
|
f"Rating value {rating.rating} should be >= 1.0")
|
|
self.assertLessEqual(rating.rating, 5.0,
|
|
f"Rating value {rating.rating} should be <= 5.0")
|
|
|
|
# Verify the value matches what we set
|
|
self.assertAlmostEqual(rating.rating, rating_value, places=2,
|
|
msg=f"Stored rating {rating.rating} should match input {rating_value}")
|
|
|
|
def test_property_zero_rating_allowed(self):
|
|
"""
|
|
Property 4 (edge case): Zero rating is allowed
|
|
A rating value of 0 (no rating) should be allowed and stored correctly.
|
|
|
|
Validates: Requirements 1.5
|
|
"""
|
|
rating = self._create_rating(0.0)
|
|
|
|
self.assertTrue(rating.id, "Rating with value 0 should be created")
|
|
self.assertEqual(rating.rating, 0.0, "Rating value should be exactly 0")
|
|
|
|
# Feature: helpdesk-rating-five-stars, Property 16: Invalid rating values rejected
|
|
@given(rating_value=st.one_of(
|
|
st.floats(min_value=-1000.0, max_value=-0.01, allow_nan=False, allow_infinity=False), # Negative values
|
|
st.floats(min_value=0.01, max_value=0.99, allow_nan=False, allow_infinity=False), # Between 0 and 1
|
|
st.floats(min_value=5.01, max_value=1000.0, allow_nan=False, allow_infinity=False) # Above 5
|
|
))
|
|
@settings(max_examples=100, deadline=None)
|
|
def test_property_invalid_rating_rejection(self, rating_value):
|
|
"""
|
|
Property 16: Invalid rating values rejected
|
|
For any rating value outside the 1-5 range (or 0), the system
|
|
should reject the submission and raise a ValidationError or database error.
|
|
|
|
Validates: Requirements 7.1
|
|
"""
|
|
# Attempt to create rating with invalid value should raise an exception
|
|
# This can be either ValidationError (from Python) or database constraint error
|
|
with self.assertRaises(Exception,
|
|
msg=f"Rating value {rating_value} should be rejected"):
|
|
self._create_rating(rating_value)
|
|
|
|
def test_rating_stars_computation(self):
|
|
"""Test that star computation works correctly for various ratings"""
|
|
test_cases = [
|
|
(0, 0, 5),
|
|
(1, 1, 4),
|
|
(2, 2, 3),
|
|
(3, 3, 2),
|
|
(4, 4, 1),
|
|
(5, 5, 0),
|
|
(1.4, 1, 4), # rounds down
|
|
(1.5, 2, 3), # rounds up
|
|
(2.6, 3, 2), # rounds up
|
|
]
|
|
|
|
for rating_value, expected_filled, expected_empty in test_cases:
|
|
rating = self._create_rating(rating_value)
|
|
self.assertEqual(rating.rating_stars_filled, expected_filled,
|
|
f"Rating {rating_value} should have {expected_filled} filled stars")
|
|
self.assertEqual(rating.rating_stars_empty, expected_empty,
|
|
f"Rating {rating_value} should have {expected_empty} empty stars")
|
|
|
|
def test_rating_stars_html_generation(self):
|
|
"""Test that HTML generation works correctly"""
|
|
rating = self._create_rating(3.0)
|
|
html = rating._get_rating_stars_html()
|
|
|
|
# Check that HTML contains the expected structure
|
|
self.assertIn('o_rating_stars', html, "HTML should contain rating stars class")
|
|
self.assertIn('★', html, "HTML should contain filled star character")
|
|
self.assertIn('☆', html, "HTML should contain empty star character")
|
|
|
|
# Check that we have 3 filled and 2 empty stars
|
|
filled_count = html.count('★')
|
|
empty_count = html.count('☆')
|
|
self.assertEqual(filled_count, 3, "Should have 3 filled stars")
|
|
self.assertEqual(empty_count, 2, "Should have 2 empty stars")
|