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:
@@ -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
|
||||
|
||||
@@ -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}')
|
||||
Reference in New Issue
Block a user