Flask + Vue rewrite of the classic-ASP shopdb, built as a plugin framework so sister GE Aerospace sites can adopt it. Product version 0.7.0-pre-0.8.0, plugin contract 0.11.0, 966 backend tests. Key entry points: - docs/INSTALL-WINDOWS-IIS.md - tested Windows + IIS install runbook (own-site and subpath deployment methods) - docs/PILOT-DEPLOY.md - production pilot: stand up + import + verify - docs/IMPORT-API.md - schema-agnostic legacy data import contract - scripts/site_imports/wjf/ - West Jefferson reference import loader - docs/adr/ - twelve accepted architecture decision records
73 lines
2.6 KiB
Python
73 lines
2.6 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'
|