Raiju/tests/page-backups-smoke.py
2026-10-25 06:05:42 +03:00

59 lines
3.5 KiB
Python

#!/usr/bin/env python3
"""Page-scoped, revision-aware restore through the real API in disposable storage."""
import json
import tempfile
from support import Client, Site, write_json
with tempfile.TemporaryDirectory(prefix='raiju-page-backups-') as folder:
site = Site(folder).start()
try:
client = Client(site).login('editor')
page = site.root / 'content/pages/en_home.json'
initial = client.api('load', page='en_home')[1]
original = initial['data']
original['image'] = {'src': 'assets/images/old.webp', 'alt': 'Original portrait'}
backup = 'en_home_2026-09-16_100000_abcdef.json'
write_json(site.root / 'backups' / backup, original)
write_json(site.root / 'backups/en_home_child_2026-09-16_100001.json', {'title': 'Another page'})
write_json(site.root / 'backups/en_home__child_2026-09-16_100001.json', {'title': 'Nested page'})
status, _, body = client.request('/admin/api.php?action=backups&page=en_home')
assert status == 200
listed = json.loads(body)['data']
assert [item['filename'] for item in listed] == [backup], listed
assert listed[0]['timestamp'] > 0
empty = json.loads(client.request('/admin/api.php?action=backups&page=en_services__test')[2])
assert empty['success'] and empty['data'] == []
current = {**original, 'title': 'Current saved page', 'image': {'src': 'assets/images/new.webp'}}
saved = client.api('save', page='en_home', revision=initial['revision'], content=json.dumps(current))[1]
current_bytes = page.read_bytes()
count = len(list((site.root / 'backups').glob('*.json')))
status, conflict = client.api('restore', page='en_home', backup=backup, revision=initial['revision'])
assert status == 409 and conflict['data']['conflict']
assert page.read_bytes() == current_bytes
assert len(list((site.root / 'backups').glob('*.json'))) == count
assert client.api('restore', page='en_home', backup=backup, revision='')[0] == 428
assert client.api('restore', page='en_other', backup=backup, revision=saved['revision'])[0] == 400
assert client.api('restore', page='en_home', backup=backup, revision=saved['revision'], csrf_token='invalid')[0] == 403
assert page.read_bytes() == current_bytes
# Never replace the current page if its safety backup cannot be written.
backups = site.root / 'backups'
backups.chmod(0o500)
try:
failed = client.api('restore', page='en_home', backup=backup, revision=saved['revision'])[1]
assert not failed['success'] and page.read_bytes() == current_bytes
finally:
backups.chmod(0o700)
status, restored = client.api('restore', page='en_home', backup=backup, revision=saved['revision'])
assert status == 200 and restored['success'], restored
assert json.loads(page.read_text()) == original, 'Restore includes image references'
assert any(path.read_bytes() == current_bytes for path in backups.glob('en_home_*.json'))
assert client.api('restore', backup=backup)[1]['success'], 'Legacy dashboard remains compatible'
status, _, _ = Client(site).request('/admin/api.php?action=backups&page=en_home')
assert status == 401, status
print('PASS page backups: exact page filter, empty list, images, CSRF/auth, stale revision, failed safety backup, current-state backup and legacy restore')
finally:
site.close()