bemade-addons/fsm_visit_confirmation/tests/test_fsm_visit_confirmation.py
2025-02-26 10:12:33 -05:00

232 lines
7.8 KiB
Python

# -*- coding: utf-8 -*-
import logging
from datetime import datetime, timedelta
from odoo import http
from odoo.tests import HttpCase, tagged
from odoo.addons.rating.models import rating_data
_logger = logging.getLogger(__name__)
@tagged("post_install", "-at_install")
class TestFSMVisitConfirmation(HttpCase):
def setUp(self):
super().setUp()
# Configure test company
self.env.company.write(
{
"email": "company@test.example.com",
"name": "Test Company",
}
)
# Create test users and partners
self.fsm_user = self.env["res.users"].create(
{
"name": "FSM User",
"login": "fsm_user",
"email": "fsm@example.com",
"groups_id": [
(
6,
0,
[
self.env.ref("industry_fsm.group_fsm_user").id,
self.env.ref("project.group_project_rating").id,
],
)
],
}
)
# Set email on user's partner
self.fsm_user.partner_id.email = "fsm@example.com"
self.customer = self.env["res.partner"].create(
{
"name": "Customer",
"email": "customer@example.com",
}
)
# Create a project
self.project = self.env["project.project"].create(
{
"name": "Test FSM Project",
"is_fsm": True,
"rating_active": True,
"rating_status": "stage", # Rating requests will be sent when tasks reach stages with rating templates
"company_id": self.env.user.company_id.id,
}
)
# Create stages for the project
self.stage_new = self.env["project.task.type"].create(
{
"name": "New",
"sequence": 0,
"project_ids": [(4, self.project.id)],
}
)
self.stage_needs_confirmation = self.env["project.task.type"].create(
{
"name": "Need Confirmation",
"sequence": 1,
"project_ids": [(4, self.project.id)],
"rating_template_id": self.env.ref(
"fsm_visit_confirmation.rating_project_request_email_template"
).id,
"auto_validation_state": True,
}
)
# Create a task
self.task = self.env["project.task"].create(
{
"name": "Test Task",
"project_id": self.project.id,
"partner_id": self.customer.id,
"work_order_contacts": [(4, self.customer.id)],
"user_ids": [(4, self.fsm_user.id)],
"planned_date_begin": datetime.now() + timedelta(days=1),
"stage_id": self.stage_new.id,
}
)
self.assertEqual(
self.task.stage_id, self.stage_new, "Task should start in New stage"
)
def test_01_task_rating_flow(self):
"""Test the complete task rating flow"""
# Move task to confirmation stage
_logger.info("Project rating_active: %s", self.project.rating_active)
_logger.info(
"Stage rating_template_id: %s",
self.stage_needs_confirmation.rating_template_id,
)
# Verify project rating settings
self.assertTrue(self.project.rating_active, "Project rating should be active")
self.assertEqual(
self.project.rating_status,
"stage",
"Project rating status should be 'stage'",
)
self.assertTrue(
self.stage_needs_confirmation.rating_template_id,
"Stage should have a rating template",
)
# Move task to confirmation stage
self.task.write({"stage_id": self.stage_needs_confirmation.id})
# # Force a small delay to allow email processing
# import time
# time.sleep(1)
# Get the token directly from the task, passing the customer partner
rating = self.env["rating.rating"].search(
[
("res_id", "=", self.task.id),
("res_model", "=", "project.task"),
]
)
self.assertTrue(rating, "Rating should be created")
self.assertEqual(
rating.partner_id, self.customer, "Rating should be for the customer"
)
token = rating.access_token
self.assertTrue(token, "Rating token should exist")
_logger.info("Rating token: %s", token)
# Simulate customer confirming the visit (rating = 5)
self.authenticate(None, None)
# First open the rating page
url = f"/rate/{rating.access_token}/5"
response = self.url_open(url)
self.assertEqual(
response.status_code, 200, "Opening rating page should succeed"
)
# Then submit the feedback
url = f"/rate/{rating.access_token}/submit_feedback"
response = self.url_open(
url,
data={
"rate": "5",
"feedback": "Great service!",
"csrf_token": http.Request.csrf_token(self),
},
)
self.assertEqual(response.status_code, 200, "Rating submission should succeed")
# Now check that the rating was created and consumed
rating.invalidate_recordset()
self.assertTrue(rating.consumed, "Rating should be consumed")
self.assertEqual(
rating.partner_id,
self.customer,
"Rating should be from work order contact",
)
self.assertEqual(rating.rating, 5, "Rating should be 5")
self.assertEqual(rating.feedback, "Great service!", "Feedback should be saved")
self.assertEqual(self.task.state, "03_approved", "Task should be approved")
def test_02_task_rating_flow_request_changes(self):
"""Test the complete task rating flow in the second test case."""
# Move task to confirmation stage
self.task.write({"stage_id": self.stage_needs_confirmation.id})
# Check that a rating request was created
rating = self.env["rating.rating"].search(
[("res_id", "=", self.task.id), ("res_model", "=", "project.task")]
)
self.assertTrue(rating, "Rating request should be created")
self.assertEqual(
rating.partner_id,
self.customer,
"Rating should be requested from work order contact",
)
# Simulate customer refusing the visit (rating = 1)
self.authenticate(None, None)
# First open the rating page
url = f"/rate/{rating.access_token}/1"
response = self.url_open(url)
self.assertEqual(
response.status_code, 200, "Rating page should load successfully"
)
# Then submit the feedback
url = f"/rate/{rating.access_token}/submit_feedback"
response = self.url_open(
url,
data={
"rate": "1",
"feedback": "Need some changes",
"csrf_token": http.Request.csrf_token(self),
},
)
self.assertEqual(
response.status_code, 200, "Feedback submission should succeed"
)
# Refresh the rating record
rating.invalidate_recordset()
self.assertTrue(rating.consumed, "Rating should be consumed")
self.assertEqual(rating.rating, 1, "Rating should be updated to 1")
self.assertEqual(
rating.feedback,
"Need some changes",
"Feedback should be saved",
)
self.assertEqual(
self.task.state,
"02_changes_requested",
"Task should be in changes requested state",
)