Fix family publishing, concurrent edits and session consistency
This commit is contained in:
+52
-1
@@ -146,7 +146,7 @@ class WebTests(unittest.TestCase):
|
||||
for path in ['/api/users','/api/audit','/media/live/cam_'+'a'*16+'_hd/index.m3u8',
|
||||
'/api/recordings?camera='+'a'*16]:
|
||||
self.assertEqual(request(path),403)
|
||||
for path in ['/api/storage','/api/users','/api/family/person']:
|
||||
for path in ['/api/storage','/api/users','/api/family/person','/api/family/event']:
|
||||
self.assertEqual(request(path,{}),403)
|
||||
self.assertEqual(request('/api/family'),200)
|
||||
app.ACCOUNTS.save(dict(member,disabled=True),self.admin)
|
||||
@@ -275,6 +275,57 @@ class WebTests(unittest.TestCase):
|
||||
event=app.FAMILY.event(dict(good,sourceUrl='https://example.org/report'),None)
|
||||
self.assertEqual(event['sourceUrl'],'https://example.org/report')
|
||||
|
||||
def test_event_accepts_full_chinese_body_and_multiline_summary(self):
|
||||
payload={'title':'中文长文','eventDate':'2026-10-03','body':'家'*12000,'summary':'第一段\n第二段',
|
||||
'status':'published','revision':app.setting('familyRevision',0)}
|
||||
self.assertGreater(len(json.dumps(payload).encode()),16384)
|
||||
code,_,body=self.request('/api/family/event',data=payload)
|
||||
self.assertEqual(code,200)
|
||||
saved=json.loads(body)['item']
|
||||
self.assertEqual(saved['body'],payload['body'])
|
||||
self.assertEqual(saved['summary'],payload['summary'])
|
||||
for changes in [{'body':'家'*12001},{'summary':'家'*401},{'summary':'bad\x00text'}]:
|
||||
invalid=dict(payload,**changes,revision=app.setting('familyRevision',0))
|
||||
self.assertEqual(self.request('/api/family/event',data=invalid)[0],400)
|
||||
|
||||
def test_event_keeps_publication_history_and_omitted_status(self):
|
||||
def save(data):return app.FAMILY.save('event',dict(data,revision=app.setting('familyRevision',0)),self.admin)['item']
|
||||
event=save({'title':'记事','eventDate':'2026-10-03','body':'正文','status':'published'})
|
||||
published=event['publishedAt'];created=event['createdAt']
|
||||
edited=dict(event,title='更新标题');edited.pop('status');edited.pop('publishedAt')
|
||||
event=save(edited)
|
||||
self.assertEqual(event['status'],'published');self.assertEqual(event['publishedAt'],published)
|
||||
event=save(dict(event,status='draft'))
|
||||
self.assertEqual(event['publishedAt'],published)
|
||||
reader={'role':'member','familyAccess':'read'}
|
||||
self.assertNotIn(event['id'],[e['id'] for e in app.FAMILY.snapshot(reader)['events']])
|
||||
event=save(dict(event,status='published'))
|
||||
self.assertEqual(event['publishedAt'],published);self.assertEqual(event['createdAt'],created)
|
||||
|
||||
def test_biological_birth_order_checked_on_link_and_person_changes(self):
|
||||
def save(kind,data):return app.FAMILY.save(kind,dict(data,revision=app.setting('familyRevision',0)),self.admin)['item']
|
||||
parent=save('person',{'name':'Parent','birthDate':'1980-01-01'})
|
||||
child=save('person',{'name':'Child','birthDate':'2000-01-01'})
|
||||
relation=save('link',{'fromId':parent['id'],'toId':child['id'],'kind':'parent','lineage':'biological'})
|
||||
for person,date in [(parent,'2000-01-01'),(parent,'2001-01-01'),(child,'1979-01-01')]:
|
||||
revision=app.setting('familyRevision',0)
|
||||
with self.assertRaises(app.Problem):save('person',dict(person,birthDate=date))
|
||||
self.assertEqual(app.setting('familyRevision',0),revision)
|
||||
self.assertEqual(app.get_object('people',person['id'])['birthDate'],person['birthDate'])
|
||||
save('link',dict(relation,active=False))
|
||||
save('person',dict(parent,birthDate='2001-01-01'))
|
||||
with self.assertRaises(app.Problem):save('link',dict(relation,active=True))
|
||||
save('link',dict(relation,active=True,lineage='adoptive'))
|
||||
|
||||
def test_request_body_limit_is_bounded_and_invalid_length_is_400(self):
|
||||
from email.message import Message
|
||||
from types import SimpleNamespace
|
||||
for length in ['invalid','-1','0','131073']:
|
||||
headers=Message();headers['Content-Type']='application/json';headers['Content-Length']=length
|
||||
fake=SimpleNamespace(headers=headers,rfile=io.BytesIO(b'{}'))
|
||||
with self.assertRaises(app.Problem) as caught:app.Handler.body(fake,131072)
|
||||
self.assertEqual(caught.exception.status,400)
|
||||
|
||||
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)}
|
||||
|
||||
Reference in New Issue
Block a user