Aug 19 - Update test files

This commit is contained in:
2026-08-19 16:34:42 -04:00
parent a4a8d84801
commit 8b2582705d
2 changed files with 95 additions and 17 deletions
+62 -15
View File
@@ -15,10 +15,13 @@ Runs on the in-memory SQLite app fixture (multi-tenancy inert). Covers:
* facility / inspection / issue list routes stay scoped for the new role
* the notification matrix exposes an External Inspector column whose defaults
mirror the Inspector column
* creating an external inspector sends an invitation instead of setting a
password: password_set is False and a set-password token is minted
* an invited Customer Inspector is created with password_set False and a
set-password token, and cannot log in until they use it
* creating any other role still requires a password
* the assign-contracts page accepts an external inspector (it 404'd before)
* creating a Customer Inspector goes through Customer Management, and
User Management no longer offers the role (phase51)
* the staff assign-contracts page redirects a customer-side account to
the page that owns it, and still serves our own inspectors
The regression guard that matters most is
test_external_inspector_scope_is_not_unrestricted: if a future edit reverts a
@@ -224,23 +227,27 @@ def test_matrix_defaults_mirror_the_inspector_column(client):
# ── Invitation flow ──────────────────────────────────────────────────────────
def test_creating_external_inspector_invites_instead_of_setting_password(client):
"""phase51 moved this account type to Customer Management.
The invariant is unchanged and is what this test guards: a Customer
Inspector is INVITED, never given a password we chose. Only the door
changed — /customers/new instead of /auth/users/new — because both
customer-side roles are now owned by /customers.
"""
from app.models.user import User
env = _seed()
_login(client, env['admin'])
resp = client.post('/auth/users/new', data={
'username': 'newxan',
resp = client.post('/customers/new', data={
'full_name': 'New Xan',
'email': 'newxan@example.com',
'role': 'external_inspector',
'password': '',
'confirm_password': '',
}, follow_redirects=True)
assert resp.status_code == 200
created = User.query.filter_by(username='newxan').first()
assert created is not None, 'external inspector was not created'
created = User.query.filter_by(email='newxan@example.com').first()
assert created is not None, 'customer inspector was not created'
assert created.role == 'external_inspector'
# Invited, not password-set: login is blocked until they use the link.
assert created.password_set is False
@@ -248,22 +255,42 @@ def test_creating_external_inspector_invites_instead_of_setting_password(client)
assert created.set_password_token_expires is not None
def test_user_management_no_longer_creates_customer_side_accounts(client):
"""The other half of the move: User Management must not mint one.
UserForm stopped offering 'external_inspector', so a crafted POST hits
SelectField validation and nothing is created. Without this, a second
creation path could quietly reappear and skip the invitation flow.
"""
from app.models.user import User
env = _seed()
_login(client, env['admin'])
client.post('/auth/users/new', data={
'username': 'sneaky',
'full_name': 'Sneaky Xan',
'email': 'sneaky@example.com',
'role': 'external_inspector',
'password': '',
'confirm_password': '',
}, follow_redirects=True)
assert User.query.filter_by(username='sneaky').first() is None
def test_invited_external_inspector_cannot_log_in_until_setup(client):
from app.models.user import User
env = _seed()
_login(client, env['admin'])
client.post('/auth/users/new', data={
'username': 'newxan',
client.post('/customers/new', data={
'full_name': 'New Xan',
'email': 'newxan@example.com',
'role': 'external_inspector',
'password': '',
'confirm_password': '',
}, follow_redirects=True)
client.get('/auth/logout', follow_redirects=True)
created = User.query.filter_by(username='newxan').first()
created = User.query.filter_by(email='newxan@example.com').first()
# The placeholder hash is random, so no password can work; assert the
# account is in the blocked state rather than guessing a credential.
assert created.password_set is False
@@ -289,11 +316,31 @@ def test_creating_a_normal_role_still_requires_a_password(client):
# ── Assign-contracts page ────────────────────────────────────────────────────
def test_assign_contracts_page_accepts_external_inspector(client):
def test_assign_contracts_page_redirects_customer_side_to_customer_management(client):
"""phase51: one editor per account, not two.
The staff assign-contracts URL still exists for our own inspectors, but a
customer-side account is redirected to the page that now owns it. Editing
one through UserForm would fail anyway — 'external_inspector' is no longer
an offered role choice, so SelectField would reject the stored value.
"""
env = _seed()
_login(client, env['admin'])
resp = client.get(f"/auth/users/{env['external'].id}/assign-contracts")
assert resp.status_code == 302
assert f"/customers/{env['external'].id}" in resp.headers['Location']
# …and the page it redirects to is the real editor.
assert client.get(f"/customers/{env['external'].id}").status_code == 200
def test_assign_contracts_page_still_accepts_our_own_inspector(client):
"""The staff path must not have been broken by the redirect guard."""
env = _seed()
_login(client, env['admin'])
resp = client.get(f"/auth/users/{env['internal'].id}/assign-contracts")
assert resp.status_code == 200