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.
102 lines
4.0 KiB
Python
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'
|