helpdesk_rating_five_stars/tests/test_rating_model.py
2025-11-26 10:39:26 +07:00

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")