Files
shopdb-flask/tests/test_plugins/test_shopfloor_feed.py
cproudlock ee80d684d4
Some checks failed
CI / backend (push) Successful in 1m45s
CI / naming (push) Successful in 1s
CI / frontend (push) Successful in 8s
CI / migrations-mysql (push) Failing after 8s
Shopfloor feed resolves employee names live when none is stored
Photos already resolved through the directory at read time, but names
only came from the stored employeename column - empty after a
shopdb-only import, so recertification/recognition cards showed bare
SSOs. New resolve_employee_display_name in the employees plugin
(mode-aware: self-hosted table or external HR) backs a fallback in
both the single-card and split-per-employee paths; stored names still
win when present.
2026-07-17 13:29:34 -04:00

102 lines
4.0 KiB
Python

"""Tests for the shopfloor TV feed (/api/notifications/shopfloor).
Since the notification-type display rework, per-employee fan-out is driven by
the type's splitperemployee column (seeded true for Recognition/Training):
a note naming several comma-joined SSOs yields one card per employee; types
without the flag stay a single card.
"""
import pytest
from plugins.notifications.models import Notification, NotificationType
def _make_type(db, typename, typecolor, splitperemployee=False):
t = NotificationType(typename=typename, typecolor=typecolor,
splitperemployee=splitperemployee, isactive=True)
db.session.add(t)
db.session.commit()
return t
def _make_shopfloor_note(db, ntype, employeesso, employeename):
n = Notification(
notificationtypeid=ntype.notificationtypeid,
notification='msg',
businessunitid=None,
isactive=True,
isshopfloor=True,
employeesso=employeesso,
employeename=employeename,
)
db.session.add(n)
db.session.commit()
return n
@pytest.mark.parametrize('typecolor', ['recognition', 'training'])
def test_multi_employee_split_into_one_card_each(client, db, typecolor):
"""A split-flagged note with two SSOs yields two current cards."""
ntype = _make_type(db, typecolor.capitalize(), typecolor, splitperemployee=True)
_make_shopfloor_note(db, ntype, '111,222', 'Alice, Bob')
resp = client.get('/api/notifications/shopfloor')
assert resp.status_code == 200
current = resp.get_json()['data']['current']
assert len(current) == 2
assert {c['employeesso'] for c in current} == {'111', '222'}
assert {c['employeename'] for c in current} == {'Alice', 'Bob'}
def test_non_split_type_stays_single_card(client, db):
"""A type without splitperemployee is not fanned out, even with many SSOs."""
ntype = _make_type(db, 'Awareness', 'info')
_make_shopfloor_note(db, ntype, '111,222', 'Alice, Bob')
resp = client.get('/api/notifications/shopfloor')
assert resp.status_code == 200
current = resp.get_json()['data']['current']
assert len(current) == 1
assert current[0]['employeesso'] == '111,222'
def test_single_employee_recognition_stays_single_card(client, db):
"""One SSO produces one card (no spurious split on a lone employee)."""
ntype = _make_type(db, 'Recognition', 'recognition', splitperemployee=True)
_make_shopfloor_note(db, ntype, '111', 'Alice')
resp = client.get('/api/notifications/shopfloor')
assert resp.status_code == 200
current = resp.get_json()['data']['current']
assert len(current) == 1
assert current[0]['employeesso'] == '111'
def test_shopfloor_names_resolve_live_when_not_stored(client, app, db):
"""A notification imported without employeename shows the directory name,
not the bare SSO - single and split-per-employee paths both."""
from plugins.employees.models import DirectoryEmployee
from plugins.notifications.models import Notification, NotificationType
from shopdb.core.models import Setting
with app.app_context():
Setting.set('employee_directory_mode', 'selfhosted',
valuetype='string', category='employees')
db.session.add(DirectoryEmployee(
sso=502000777, firstname='Recert', lastname='Person'))
ntype = NotificationType(typename='Recertification',
typecolor='recertification',
splitperemployee=True)
db.session.add(ntype)
db.session.flush()
db.session.add(Notification(
notificationtypeid=ntype.notificationtypeid,
notification='Recert due', isshopfloor=True,
employeesso='502000777', employeename=None))
db.session.commit()
feed = client.get('/api/notifications/shopfloor').get_json()['data']
cards = feed['current'] + feed['upcoming']
card = next(c for c in cards if c['notification'] == 'Recert due')
assert card['employeename'] == 'Recert Person'