201 lines
7.6 KiB
Python
201 lines
7.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo.tests.common import TransactionCase
|
|
from hypothesis import given, strategies as st, settings
|
|
|
|
|
|
class TestHelpdeskTicket(TransactionCase):
|
|
"""Test cases for the extended helpdesk ticket model"""
|
|
|
|
def setUp(self):
|
|
super(TestHelpdeskTicket, self).setUp()
|
|
self.HelpdeskTicket = self.env['helpdesk.ticket']
|
|
self.Rating = self.env['rating.rating']
|
|
self.Partner = self.env['res.partner']
|
|
self.User = self.env['res.users']
|
|
self.HelpdeskTeam = self.env['helpdesk.team']
|
|
|
|
# Create test partner
|
|
self.test_partner = self.Partner.create({
|
|
'name': 'Test Customer',
|
|
'email': 'test@example.com',
|
|
})
|
|
|
|
# Create test user
|
|
self.test_user = self.User.create({
|
|
'name': 'Test User',
|
|
'login': 'testuser',
|
|
'email': 'testuser@example.com',
|
|
})
|
|
|
|
# Create helpdesk team
|
|
self.helpdesk_team = self.HelpdeskTeam.create({
|
|
'name': 'Test Support Team',
|
|
})
|
|
|
|
def _create_ticket_with_rating(self, rating_value):
|
|
"""Helper method to create a ticket with a rating"""
|
|
# Create ticket
|
|
ticket = self.HelpdeskTicket.create({
|
|
'name': 'Test Ticket',
|
|
'partner_id': self.test_partner.id,
|
|
'team_id': self.helpdesk_team.id,
|
|
})
|
|
|
|
# Create rating for the ticket
|
|
if rating_value is not None:
|
|
rating = self.Rating.create({
|
|
'rating': rating_value,
|
|
'partner_id': self.test_partner.id,
|
|
'rated_partner_id': self.test_user.partner_id.id,
|
|
'res_model': 'helpdesk.ticket',
|
|
'res_id': ticket.id,
|
|
})
|
|
|
|
# No need to invalidate - computed fields will compute on access
|
|
|
|
return ticket
|
|
|
|
# Feature: helpdesk-rating-five-stars, Property 10: Backend displays correct star count
|
|
@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_backend_displays_correct_star_count(self, rating_value):
|
|
"""
|
|
Property 10: Backend displays correct star count
|
|
For any rating value, the backend view should display the number
|
|
of filled stars equal to the rating value (rounded).
|
|
|
|
Validates: Requirements 4.3
|
|
"""
|
|
# Create ticket with rating
|
|
ticket = self._create_ticket_with_rating(rating_value)
|
|
|
|
# Get the HTML representation
|
|
html = ticket.rating_stars_html
|
|
|
|
# Verify HTML is generated
|
|
self.assertTrue(html, "HTML should be generated for rated ticket")
|
|
|
|
# Count filled and empty stars in HTML
|
|
filled_count = html.count('★')
|
|
empty_count = html.count('☆')
|
|
|
|
# Expected filled stars (rounded rating value)
|
|
expected_filled = round(rating_value)
|
|
expected_empty = 5 - expected_filled
|
|
|
|
# Verify star counts match
|
|
self.assertEqual(filled_count, expected_filled,
|
|
f"For rating {rating_value}, should display {expected_filled} filled stars, got {filled_count}")
|
|
self.assertEqual(empty_count, expected_empty,
|
|
f"For rating {rating_value}, should display {expected_empty} empty stars, got {empty_count}")
|
|
|
|
# Verify total is always 5 stars
|
|
self.assertEqual(filled_count + empty_count, 5,
|
|
"Total stars should always be 5")
|
|
|
|
# Feature: helpdesk-rating-five-stars, Property 13: Ticket view displays rating stars
|
|
@given(rating_value=st.one_of(
|
|
st.just(0.0), # No rating
|
|
st.floats(min_value=1.0, max_value=5.0, allow_nan=False, allow_infinity=False) # Valid ratings
|
|
))
|
|
@settings(max_examples=100, deadline=None)
|
|
def test_property_ticket_view_displays_rating_stars(self, rating_value):
|
|
"""
|
|
Property 13: Ticket view displays rating stars
|
|
For any ticket with a rating, the backend view should display
|
|
the rating as filled star icons.
|
|
|
|
Validates: Requirements 5.1
|
|
"""
|
|
# Create ticket with rating
|
|
ticket = self._create_ticket_with_rating(rating_value)
|
|
|
|
# Get the HTML representation
|
|
html = ticket.rating_stars_html
|
|
|
|
# Verify HTML is generated
|
|
self.assertTrue(html, "HTML should be generated for ticket")
|
|
|
|
# Verify HTML contains star structure
|
|
self.assertIn('o_rating_stars', html,
|
|
"HTML should contain rating stars class")
|
|
|
|
# Verify stars are present
|
|
has_filled_stars = '★' in html
|
|
has_empty_stars = '☆' in html
|
|
|
|
self.assertTrue(has_filled_stars or has_empty_stars,
|
|
"HTML should contain star characters")
|
|
|
|
# For non-zero ratings, verify filled stars match rating
|
|
if rating_value > 0:
|
|
filled_count = html.count('★')
|
|
expected_filled = round(rating_value)
|
|
self.assertEqual(filled_count, expected_filled,
|
|
f"For rating {rating_value}, should display {expected_filled} filled stars")
|
|
else:
|
|
# For zero rating, should display 5 empty stars
|
|
empty_count = html.count('☆')
|
|
self.assertEqual(empty_count, 5,
|
|
"For zero rating, should display 5 empty stars")
|
|
|
|
def test_ticket_without_rating_displays_empty_stars(self):
|
|
"""Test that tickets without ratings display empty stars or 'Not Rated'"""
|
|
# Create ticket without rating
|
|
ticket = self._create_ticket_with_rating(None)
|
|
|
|
# Get the HTML representation
|
|
html = ticket.rating_stars_html
|
|
|
|
# Verify HTML is generated
|
|
self.assertTrue(html, "HTML should be generated even without rating")
|
|
|
|
# Should display 5 empty stars
|
|
empty_count = html.count('☆')
|
|
self.assertEqual(empty_count, 5,
|
|
"Ticket without rating should display 5 empty stars")
|
|
|
|
# Should not have filled stars
|
|
filled_count = html.count('★')
|
|
self.assertEqual(filled_count, 0,
|
|
"Ticket without rating should have no filled stars")
|
|
|
|
def test_ticket_with_multiple_ratings_uses_most_recent(self):
|
|
"""Test that when a ticket has multiple ratings, the most recent is displayed"""
|
|
# Create ticket
|
|
ticket = self.HelpdeskTicket.create({
|
|
'name': 'Test Ticket',
|
|
'partner_id': self.test_partner.id,
|
|
'team_id': self.helpdesk_team.id,
|
|
})
|
|
|
|
# Create first rating
|
|
rating1 = self.Rating.create({
|
|
'rating': 2.0,
|
|
'partner_id': self.test_partner.id,
|
|
'rated_partner_id': self.test_user.partner_id.id,
|
|
'res_model': 'helpdesk.ticket',
|
|
'res_id': ticket.id,
|
|
})
|
|
|
|
# Create second rating (more recent)
|
|
rating2 = self.Rating.create({
|
|
'rating': 5.0,
|
|
'partner_id': self.test_partner.id,
|
|
'rated_partner_id': self.test_user.partner_id.id,
|
|
'res_model': 'helpdesk.ticket',
|
|
'res_id': ticket.id,
|
|
})
|
|
|
|
# Don't invalidate - just access the computed field directly
|
|
# The ORM will handle the relationship correctly
|
|
|
|
# Get the HTML representation
|
|
html = ticket.rating_stars_html
|
|
|
|
# Should display 5 filled stars (from most recent rating)
|
|
filled_count = html.count('★')
|
|
self.assertEqual(filled_count, 5,
|
|
"Should display stars from most recent rating (5 stars)")
|