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:
@@ -6,3 +6,4 @@ from . import test_tablet_lock_payload
|
|||||||
from . import test_kiosk_user_acl
|
from . import test_kiosk_user_acl
|
||||||
from . import test_tablet_session_event_model
|
from . import test_tablet_session_event_model
|
||||||
from . import test_tablet_pin_auth_manager
|
from . import test_tablet_pin_auth_manager
|
||||||
|
from . import test_unlock_lock_session_endpoints
|
||||||
|
|||||||
@@ -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)
|
||||||
Reference in New Issue
Block a user