test(shopfloor): fp_tablet_pin auth manager handles all cases

8 tests: correct/wrong/missing PIN, missing/unknown login, inactive
user, no shop-branch role, and pass-through of other credential types.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-24 12:30:56 -04:00
parent dd0dc26232
commit 358b90516b
2 changed files with 81 additions and 0 deletions

View File

@@ -5,3 +5,4 @@ from . import test_tablet_pin
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

View File

@@ -0,0 +1,80 @@
from odoo.tests.common import TransactionCase, tagged
from odoo.exceptions import AccessDenied
@tagged('-at_install', 'post_install', 'fp_tablet')
class TestTabletPinAuthManager(TransactionCase):
def setUp(self):
super().setUp()
Users = self.env['res.users'].with_context(no_reset_password=True)
self.tech = Users.create({
'login': 'authmgr_tech@example.com', 'name': 'AuthMgr Tech',
'email': 'authmgr_tech@example.com',
'group_ids': [(6, 0, [
self.env.ref('fusion_plating.group_fp_technician').id
])],
})
self.tech.sudo().set_tablet_pin('1234')
self.no_role_user = Users.create({
'login': 'authmgr_norole@example.com', 'name': 'NoRole',
'email': 'authmgr_norole@example.com',
})
# Set a PIN but no shop-branch role
# (set_tablet_pin doesn't care about roles)
self.no_role_user.sudo().set_tablet_pin('5555')
def _check(self, login, pin):
return self.env['res.users'].sudo()._check_credentials(
{'type': 'fp_tablet_pin', 'login': login, 'pin': pin},
self.env,
)
def test_correct_pin_succeeds(self):
result = self._check('authmgr_tech@example.com', '1234')
self.assertEqual(result['uid'], self.tech.id)
self.assertEqual(result['auth_method'], 'fp_tablet_pin')
def test_wrong_pin_raises_access_denied(self):
with self.assertRaises(AccessDenied):
self._check('authmgr_tech@example.com', '0000')
def test_missing_pin_raises_access_denied(self):
with self.assertRaises(AccessDenied):
self._check('authmgr_tech@example.com', '')
def test_missing_login_raises_access_denied(self):
with self.assertRaises(AccessDenied):
self._check('', '1234')
def test_unknown_login_raises_access_denied(self):
with self.assertRaises(AccessDenied):
self._check('nobody@example.com', '1234')
def test_inactive_user_raises_access_denied(self):
self.tech.sudo().active = False
with self.assertRaises(AccessDenied):
self._check('authmgr_tech@example.com', '1234')
def test_no_shop_branch_role_raises_access_denied(self):
with self.assertRaises(AccessDenied):
self._check('authmgr_norole@example.com', '5555')
def test_other_credential_types_pass_through_to_super(self):
# Standard password credential should still work normally.
# We don't test the exact result here — just that our override
# doesn't intercept it.
# AccessDenied is expected because we provide no password.
# Key check: it's not OUR AccessDenied (which fires when type
# is fp_tablet_pin), so the super() chain handles it.
try:
self.env['res.users'].sudo()._check_credentials(
{'type': 'password', 'login': 'authmgr_tech@example.com',
'password': 'wrong'},
self.env,
)
except AccessDenied:
pass # expected — wrong password
except Exception as e:
self.fail(f'Standard password path broken: {e}')