Add complete family graph and private family chronicle

This commit is contained in:
Codex
2026-10-03 20:02:07 +08:00
parent de6eae176d
commit 8d58ad0a2f
14 changed files with 458 additions and 46 deletions
+38
View File
@@ -232,6 +232,44 @@ class WebTests(unittest.TestCase):
with self.assertRaises(app.Problem):app.FAMILY.person({'name':'Example','deathDate':'2020-01-01'},None)
self.assertEqual(app.FAMILY.person({'name':'Example','lifeStatus':'deceased','deathDate':'2020-01-01'},None)['deathDate'],'2020-01-01')
def test_family_event_draft_publish_archive_and_restore(self):
def save(data):
return app.FAMILY.save('event',dict(data,revision=app.setting('familyRevision',0)),self.admin)['item']
p=app.FAMILY.save('person',{'name':'Event person','revision':app.setting('familyRevision',0)},self.admin)['item']
reader={'role':'member','familyAccess':'read','personId':p['id']}
e=save({'title':'First event','eventDate':'2024-02-10','summary':'Summary','body':'Line one\nLine two','personIds':[p['id'],p['id']]})
self.assertEqual(e['status'],'draft');self.assertEqual(e['personIds'],[p['id']])
self.assertNotIn(e['id'],[r['id'] for r in app.FAMILY.snapshot(reader)['events']])
e=save(dict(e,status='published'))
self.assertIn('publishedAt',e)
self.assertIn(e['id'],[r['id'] for r in app.FAMILY.snapshot(reader)['events']])
e=save(dict(e,archived=True))
self.assertNotIn(e['id'],[r['id'] for r in app.FAMILY.snapshot(reader)['events']])
self.assertIn(e['id'],[r['id'] for r in app.FAMILY.snapshot(self.admin)['events']])
e=save(dict(e,archived=False))
self.assertIn(e['id'],[r['id'] for r in app.FAMILY.snapshot(reader)['events']])
with self.assertRaises(app.Problem):app.FAMILY.save('event',dict(e,revision=0),self.admin)
with self.assertRaises(app.Problem):app.FAMILY.save('event',dict(e,revision=app.setting('familyRevision',0)),reader)
with self.assertRaises(app.Problem):app.FAMILY.snapshot({'role':'member','familyAccess':'none'})
def test_family_event_validation(self):
good={'title':'Event','eventDate':'2020-02-29','body':'Text','status':'published'}
for changes in [{'eventDate':'2023-02-29'},{'title':''},{'sourceUrl':'javascript:alert(1)'},
{'sourceUrl':'https://user:secret@example.com'},{'personIds':['missing']},
{'body':'x'*12001},{'status':'public'},{'archived':'false'},{'personIds':'wrong'},
{'body':'','summary':'','sourceUrl':''}]:
with self.subTest(changes=list(changes)):
with self.assertRaises(app.Problem):app.FAMILY.event(dict(good,**changes),None)
event=app.FAMILY.event(dict(good,sourceUrl='https://example.org/report'),None)
self.assertEqual(event['sourceUrl'],'https://example.org/report')
def test_event_endpoint_and_static_modules(self):
self.assertEqual(self.request('/api/family/event',False,{'title':'Denied'})[0],401)
payload={'title':'API event','eventDate':'2026-01-01','body':'Test only','status':'published','revision':app.setting('familyRevision',0)}
self.assertEqual(self.request('/api/family/event',data=payload)[0],200)
for path in ['/family-graph.js','/family-map.js','/family-map.css','/family-events.js']:
self.assertEqual(self.request(path,False)[0],200)
def test_empty_recording_day_is_not_service_failure(self):
error = app.urllib.error.HTTPError('http://localhost/list', 404, 'Not Found', {},
io.BytesIO(b'{"error":"no recording segments found"}'))