Initial import: shopdb-flask multi-site asset platform
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
This commit is contained in:
72
tests/test_plugins/test_shopfloor_feed.py
Normal file
72
tests/test_plugins/test_shopfloor_feed.py
Normal file
@@ -0,0 +1,72 @@
|
||||
"""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'
|
||||
Reference in New Issue
Block a user