test(shopfloor): HTTP tests for unlock_session + lock_session

5 tests covering correct/wrong PIN, audit event writes, manual/idle
lock reasons. Uses HttpCase to actually drive the JSONRPC endpoint
end-to-end with session cookie handling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-24 12:55:19 -04:00
parent 7fab01e5cb
commit 87e924d1d8
2 changed files with 97 additions and 0 deletions

View File

@@ -6,3 +6,4 @@ from . import test_tablet_lock_payload
from . import test_kiosk_user_acl
from . import test_tablet_session_event_model
from . import test_tablet_pin_auth_manager
from . import test_unlock_lock_session_endpoints

View File

@@ -0,0 +1,96 @@
import json
from odoo.tests.common import HttpCase, tagged
@tagged('-at_install', 'post_install', 'fp_tablet')
class TestUnlockLockSessionEndpoints(HttpCase):
def setUp(self):
super().setUp()
Users = self.env['res.users'].with_context(no_reset_password=True)
self.tech = Users.create({
'login': 'http_tech@example.com', 'name': 'HTTP Tech',
'email': 'http_tech@example.com',
'group_ids': [(6, 0, [
self.env.ref('fusion_plating.group_fp_technician').id
])],
})
self.tech.sudo().set_tablet_pin('1234')
# Make sure the kiosk password is set so lock_session can re-auth.
ICP = self.env['ir.config_parameter'].sudo()
if not ICP.get_param('fp.tablet.kiosk_password'):
ICP.set_param('fp.tablet.kiosk_password', 'test_kiosk_pwd')
kiosk = self.env.ref('fusion_plating_shopfloor.user_fp_tablet_kiosk')
kiosk.sudo().password = 'test_kiosk_pwd'
def _jsonrpc(self, route, params):
return self.url_open(
route,
data=json.dumps({'jsonrpc': '2.0', 'params': params}),
headers={'Content-Type': 'application/json'},
).json()
def test_unlock_session_with_correct_pin_returns_ok(self):
self.authenticate('fp_tablet_kiosk@enplating.local', 'test_kiosk_pwd')
resp = self._jsonrpc('/fp/tablet/unlock_session', {
'user_id': self.tech.id, 'pin': '1234',
})
self.assertTrue(resp['result']['ok'])
self.assertEqual(resp['result']['tech_id'], self.tech.id)
def test_unlock_session_writes_audit_event(self):
self.authenticate('fp_tablet_kiosk@enplating.local', 'test_kiosk_pwd')
self._jsonrpc('/fp/tablet/unlock_session', {
'user_id': self.tech.id, 'pin': '1234',
})
events = self.env['fp.tablet.session.event'].sudo().search([
('event_type', '=', 'unlock'),
('user_id', '=', self.tech.id),
])
self.assertGreater(len(events), 0)
e = events[0]
self.assertTrue(e.session_id_hash)
self.assertTrue(e.session_started_at)
def test_unlock_session_with_wrong_pin_writes_failed_event(self):
self.authenticate('fp_tablet_kiosk@enplating.local', 'test_kiosk_pwd')
resp = self._jsonrpc('/fp/tablet/unlock_session', {
'user_id': self.tech.id, 'pin': '0000',
})
self.assertFalse(resp['result']['ok'])
events = self.env['fp.tablet.session.event'].sudo().search([
('event_type', '=', 'failed_unlock'),
('attempted_user_id', '=', self.tech.id),
('failure_reason', '=', 'wrong_pin'),
])
self.assertGreater(len(events), 0)
def test_lock_session_writes_manual_lock_event(self):
self.authenticate('fp_tablet_kiosk@enplating.local', 'test_kiosk_pwd')
# Unlock first
self._jsonrpc('/fp/tablet/unlock_session', {
'user_id': self.tech.id, 'pin': '1234',
})
# Then lock with reason=manual
resp = self._jsonrpc('/fp/tablet/lock_session', {'reason': 'manual'})
self.assertTrue(resp['result']['ok'])
events = self.env['fp.tablet.session.event'].sudo().search([
('event_type', '=', 'manual_lock'),
('user_id', '=', self.tech.id),
])
self.assertGreater(len(events), 0)
self.assertIsNotNone(events[0].session_ended_at)
self.assertGreaterEqual(events[0].duration_seconds, 0)
def test_lock_session_idle_reason_writes_idle_lock(self):
self.authenticate('fp_tablet_kiosk@enplating.local', 'test_kiosk_pwd')
self._jsonrpc('/fp/tablet/unlock_session', {
'user_id': self.tech.id, 'pin': '1234',
})
self._jsonrpc('/fp/tablet/lock_session', {'reason': 'idle'})
events = self.env['fp.tablet.session.event'].sudo().search([
('event_type', '=', 'idle_lock'),
('user_id', '=', self.tech.id),
])
self.assertGreater(len(events), 0)