Remediate the 2026-09-03 feature-test findings
This commit is contained in:
@@ -94,9 +94,16 @@ def test_dashboard_machine_count_collapses(client, db, auth_headers):
|
||||
assert counts['counts']['machines'] == 1
|
||||
|
||||
|
||||
def test_map_excludes_secondary_marker(client, db, auth_headers):
|
||||
def test_an_unpositioned_secondary_is_represented_by_the_primary(
|
||||
client, db, auth_headers):
|
||||
"""The common case: the pair sits in one place, so it draws one marker and
|
||||
that marker is labelled with both bays."""
|
||||
invalidate_settings_cache()
|
||||
_seed_dualpath_pair()
|
||||
secondary = Asset.query.filter_by(assetnumber='2008').first()
|
||||
secondary.mapx = None
|
||||
secondary.mapy = None
|
||||
_db.session.commit()
|
||||
|
||||
resp = client.get('/api/assets/map', headers=auth_headers)
|
||||
assert resp.status_code == 200, resp.get_json()
|
||||
@@ -106,7 +113,30 @@ def test_map_excludes_secondary_marker(client, db, auth_headers):
|
||||
assert '2007' in numbers
|
||||
assert '2008' not in numbers
|
||||
primary = next(a for a in assets if a['assetnumber'] == '2007')
|
||||
assert primary['dualpathpartner'] == '2008'
|
||||
assert primary['dualpathpartner'] == '2008', \
|
||||
'the one marker has to say it stands for both bays'
|
||||
|
||||
|
||||
def test_a_positioned_secondary_draws_its_own_marker(client, db, auth_headers):
|
||||
"""A second bay that is physically somewhere else. Positioning it used to
|
||||
be a silent no-op: the form took the pin, stored it, and the map never drew
|
||||
it, because the secondary was excluded from the feed unconditionally."""
|
||||
invalidate_settings_cache()
|
||||
_seed_dualpath_pair() # fixture positions BOTH bays
|
||||
|
||||
resp = client.get('/api/assets/map', headers=auth_headers)
|
||||
assert resp.status_code == 200, resp.get_json()
|
||||
assets = resp.get_json()['data']['assets']
|
||||
numbers = [a['assetnumber'] for a in assets]
|
||||
|
||||
assert '2007' in numbers
|
||||
assert '2008' in numbers, 'a positioned secondary bay draws its own marker'
|
||||
|
||||
# Two pins, two names. Labelling both '2007 / 2008' would say the same
|
||||
# machine is in two places.
|
||||
for assetnumber in ('2007', '2008'):
|
||||
marker = next(a for a in assets if a['assetnumber'] == assetnumber)
|
||||
assert marker['dualpathpartner'] is None, assetnumber
|
||||
|
||||
|
||||
def test_detail_banner_partner_shown_regardless_of_toggle(client, db, auth_headers):
|
||||
@@ -161,3 +191,86 @@ def test_map_shows_both_bays_when_disabled(client, db, auth_headers):
|
||||
numbers = [a['assetnumber'] for a in resp.get_json()['data']['assets']]
|
||||
assert '2007' in numbers
|
||||
assert '2008' in numbers
|
||||
|
||||
|
||||
def _give_both_bays_a_status():
|
||||
"""The pair fixture leaves statusid null, so the bystatus join matches
|
||||
nothing. Give both bays the same status, which is what a real site has and
|
||||
what makes the breakdown meaningful."""
|
||||
from shopdb.core.models import AssetStatus
|
||||
|
||||
status = AssetStatus(status='In Use')
|
||||
_db.session.add(status)
|
||||
_db.session.flush()
|
||||
for assetnumber in ('2007', '2008'):
|
||||
asset = Asset.query.filter_by(assetnumber=assetnumber).first()
|
||||
asset.statusid = status.statusid
|
||||
_db.session.commit()
|
||||
|
||||
|
||||
def test_the_status_breakdown_adds_up_to_the_total(client, db, auth_headers):
|
||||
"""The dualpath exclusion was applied to total and bytype but not to
|
||||
bystatus, so the status bars summed to more than the headline they sit
|
||||
under - by exactly the number of secondary bays. A breakdown that does not
|
||||
add up to its own total is an afternoon of reconciling."""
|
||||
invalidate_settings_cache()
|
||||
_seed_dualpath_pair()
|
||||
_give_both_bays_a_status()
|
||||
|
||||
resp = client.get('/api/machines/dashboard/summary', headers=auth_headers)
|
||||
assert resp.status_code == 200, resp.get_json()
|
||||
summary = resp.get_json()['data']
|
||||
|
||||
assert summary['total'] == 1, 'two bays, one physical machine'
|
||||
assert sum(row['count'] for row in summary['bystatus']) == summary['total']
|
||||
|
||||
|
||||
def test_the_status_breakdown_counts_both_bays_when_collapse_is_off(
|
||||
client, db, auth_headers):
|
||||
"""With the setting off, every bay is its own machine everywhere - the fix
|
||||
must not start hiding rows a site asked to see."""
|
||||
invalidate_settings_cache()
|
||||
_seed_dualpath_pair()
|
||||
_give_both_bays_a_status()
|
||||
_set_toggle('false')
|
||||
|
||||
summary = client.get('/api/machines/dashboard/summary',
|
||||
headers=auth_headers).get_json()['data']
|
||||
assert summary['total'] == 2
|
||||
assert sum(row['count'] for row in summary['bystatus']) == 2
|
||||
|
||||
|
||||
def test_a_maintenance_date_is_served_as_a_plain_date(client, db, auth_headers):
|
||||
"""It was a DATETIME holding midnight, serialised as '...T00:00:00Z', so a
|
||||
browser west of UTC rendered every maintenance date one day early. A date
|
||||
has no time and no timezone."""
|
||||
from plugins.machines.models import Machine
|
||||
|
||||
# The create route resolves the 'machine' AssetType, which this module's
|
||||
# fixture only seeds as part of building a pair.
|
||||
if not AssetType.query.filter_by(assettype='machine').first():
|
||||
_db.session.add(AssetType(assettype='machine'))
|
||||
_db.session.commit()
|
||||
|
||||
created = client.post('/api/machines', headers=auth_headers, json={
|
||||
'assetnumber': 'MAINT-DATE-1',
|
||||
'name': 'Maintenance date probe',
|
||||
'lastmaintenancedate': '2026-01-15',
|
||||
'nextmaintenancedate': '2026-12-15',
|
||||
})
|
||||
assert created.status_code == 201, created.get_json()
|
||||
payload = created.get_json()['data']
|
||||
machineid = payload.get('machineid') or payload['machine']['machineid']
|
||||
|
||||
fetched = client.get('/api/machines/%d' % machineid,
|
||||
headers=auth_headers).get_json()['data']
|
||||
extension = fetched['machine']
|
||||
assert extension['lastmaintenancedate'] == '2026-01-15'
|
||||
assert extension['nextmaintenancedate'] == '2026-12-15'
|
||||
for value in (extension['lastmaintenancedate'],
|
||||
extension['nextmaintenancedate']):
|
||||
assert 'T' not in value and 'Z' not in value, \
|
||||
'a date must not carry a time or a timezone marker'
|
||||
|
||||
stored = db.session.get(Machine, machineid)
|
||||
assert str(stored.lastmaintenancedate) == '2026-01-15'
|
||||
|
||||
Reference in New Issue
Block a user