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_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
|
||||||
|
|||||||
@@ -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