Merge origin/main into wilm: dashboard/fleet console, vuln upgrades, colours
This commit is contained in:
@@ -104,3 +104,50 @@ def test_relationships_row_carries_isdirectional(client, db, auth_headers):
|
||||
ctrl_rows = [r for r in data['outgoing']
|
||||
if r['relationshiptypename'] == 'controls']
|
||||
assert ctrl_rows and all(r['isdirectional'] is True for r in ctrl_rows)
|
||||
|
||||
def test_the_controlled_asset_sees_the_link_from_its_own_page(client, db, auth_headers):
|
||||
"""The target of a directional edge must receive it in `incoming`.
|
||||
|
||||
A PC controls a machine, and the row is stored once, source=PC. The PC's
|
||||
page reads it from `outgoing`; the machine's page can only ever see it in
|
||||
`incoming`. Nothing asserted that second half, and a UI was shipped that
|
||||
rendered the link on the PC page and showed the machine page nothing - the
|
||||
reciprocal-links defect. The endpoint was correct all along, which is
|
||||
exactly why this assertion is worth having: it pins the contract the
|
||||
frontend depends on, so the next such bug cannot be blamed on the API.
|
||||
"""
|
||||
atype_machine = AssetType(assettype='machine')
|
||||
atype_computer = AssetType(assettype='computer')
|
||||
db.session.add_all([atype_machine, atype_computer])
|
||||
db.session.flush()
|
||||
|
||||
controls = RelationshipType(relationshiptype='controls', isdirectional=True)
|
||||
db.session.add(controls)
|
||||
db.session.flush()
|
||||
|
||||
pc = _make_asset('PC-1', atype_computer.assettypeid)
|
||||
machine = _make_asset('M-1', atype_machine.assettypeid)
|
||||
|
||||
# Stored ONCE, in the canonical direction only.
|
||||
db.session.add(AssetRelationship(sourceassetid=pc.assetid,
|
||||
targetassetid=machine.assetid,
|
||||
relationshiptypeid=controls.relationshiptypeid))
|
||||
db.session.commit()
|
||||
|
||||
resp = client.get(f'/api/assets/{machine.assetid}/relationships',
|
||||
headers=auth_headers)
|
||||
assert resp.status_code == 200
|
||||
data = resp.get_json()['data']
|
||||
|
||||
assert data['outgoing'] == [], 'the machine controls nothing'
|
||||
assert len(data['incoming']) == 1, 'the machine must see the PC that controls it'
|
||||
|
||||
row = data['incoming'][0]
|
||||
assert row['relationshiptypename'] == 'controls'
|
||||
# The peer has to arrive with the fields the UI routes on. assetid alone
|
||||
# is not enough: the detail routes key on pluginid, and the type name
|
||||
# chooses the route base.
|
||||
peer = row['sourceasset']
|
||||
assert peer is not None
|
||||
assert peer['assetid'] == pc.assetid
|
||||
assert peer['assettypename'] == 'computer'
|
||||
|
||||
Reference in New Issue
Block a user