Squash-merge of feat/helpdesk-customer-followup. The billing and fusion_login_audit work from that branch is already on main (landed separately); this lands only the helpdesk feature. - Identity keystone: submit() forwards partner_email/partner_name/ x_fc_client_label so the central Helpdesk find-or-creates the customer partner and subscribes them as a follower (enables reply emails + magic link). - Embedded in-app 'My Tickets' inbox: server-side scoped read/reply RPC endpoints, per-user seen tracking (fusion.helpdesk.ticket.seen), systray unread badge. Defense-in-depth scope domain + _norm_email normalisation (wildcard emails cannot widen scope). - fusion_helpdesk_central: x_fc_client_label field + list/search views + branded acknowledgement email template. - Deployed and smoke-tested live: nexa central 19.0.1.1.0, entech client 19.0.1.4.1 (requires Contact Creation on the central service account). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
28 lines
1.1 KiB
Python
28 lines
1.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright 2026 Nexa Systems Inc.
|
|
# License OPL-1
|
|
"""Tests for fusion.helpdesk.ticket.seen read-tracking."""
|
|
from odoo.tests import TransactionCase, tagged
|
|
|
|
|
|
@tagged('post_install', '-at_install', 'fusion_helpdesk')
|
|
class TestSeen(TransactionCase):
|
|
|
|
def test_mark_seen_upserts_and_is_monotonic(self):
|
|
Seen = self.env['fusion.helpdesk.ticket.seen']
|
|
Seen._mark_seen(central_ticket_id=42, last_message_id=100)
|
|
Seen._mark_seen(central_ticket_id=42, last_message_id=120)
|
|
Seen._mark_seen(central_ticket_id=42, last_message_id=90) # stale, ignored
|
|
rec = Seen.search([
|
|
('user_id', '=', self.env.uid),
|
|
('central_ticket_id', '=', 42),
|
|
])
|
|
self.assertEqual(len(rec), 1, "should upsert, not duplicate")
|
|
self.assertEqual(rec.last_seen_message_id, 120, "monotonic — never moves back")
|
|
|
|
def test_seen_map(self):
|
|
Seen = self.env['fusion.helpdesk.ticket.seen']
|
|
Seen._mark_seen(1, 10)
|
|
Seen._mark_seen(2, 20)
|
|
self.assertEqual(Seen._seen_map([1, 2, 3]), {1: 10, 2: 20})
|