mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2026-04-30 23:00:30 +00:00
e9e8c8d218
Build and push containers / metadata (push) Has been cancelled
Build and push containers / build-push-containers (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/amd64 (alpine) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm64 (alpine) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/amd64 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm/v7 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm/v8 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm64 (main) (push) Has been cancelled
ChangeDetection.io App Test / lint-code (push) Has been cancelled
ChangeDetection.io App Test / lint-translations (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Test the built package works basically. (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-10 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-11 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-12 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-13 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-14 (push) Has been cancelled
107 lines
3.9 KiB
Python
107 lines
3.9 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Tests for the /diff/<uuid>/download-patch endpoint.
|
|
|
|
The route should accept from_version and to_version query parameters,
|
|
read those two snapshots from the watch history, generate a unified diff
|
|
patch, and return it as a downloadable text/plain file.
|
|
"""
|
|
|
|
from flask import url_for
|
|
|
|
from changedetectionio.tests.util import live_server_setup, delete_all_watches, wait_for_all_checks
|
|
|
|
|
|
def _add_watch_with_history(app, url, v1_text, v2_text):
|
|
"""
|
|
Add a watch and inject two synthetic snapshots into its history so we
|
|
can test the download-patch route without hitting a live fetch cycle.
|
|
"""
|
|
datastore = app.config['DATASTORE']
|
|
uuid = datastore.add_watch(url=url, extras={})
|
|
watch = datastore.data['watching'][uuid]
|
|
|
|
# Write the two snapshots directly via save_history_blob
|
|
# Args: contents (str), timestamp (str), snapshot_id (str)
|
|
watch.save_history_blob(v1_text, '1000000000', 'snap-v1')
|
|
watch.save_history_blob(v2_text, '1000000001', 'snap-v2')
|
|
|
|
return uuid
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Tests
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def test_download_patch_returns_unified_diff(client, live_server, measure_memory_usage, datastore_path):
|
|
"""
|
|
The endpoint should return a .patch file whose content is a valid unified
|
|
diff between the two requested snapshots.
|
|
"""
|
|
live_server_setup(live_server)
|
|
delete_all_watches(client)
|
|
|
|
app = client.application
|
|
test_url = url_for('test_endpoint', content_type='text/html', content='hello', _external=True)
|
|
|
|
v1 = 'line one\nline two\nline three\n'
|
|
v2 = 'line one\nline two modified\nline three\nline four\n'
|
|
|
|
uuid = _add_watch_with_history(app, test_url, v1, v2)
|
|
|
|
res = client.get(
|
|
url_for('ui.ui_diff.download_patch', uuid=uuid,
|
|
from_version='1000000000', to_version='1000000001'),
|
|
follow_redirects=True,
|
|
)
|
|
|
|
assert res.status_code == 200, f"Expected 200, got {res.status_code}: {res.data[:200]}"
|
|
assert 'text/plain' in res.headers.get('Content-Type', '')
|
|
# No forced download — should open inline in the browser
|
|
assert 'attachment' not in res.headers.get('Content-Disposition', '')
|
|
|
|
patch = res.data.decode('utf-8')
|
|
assert '---' in patch or '+' in patch, "Response should contain unified diff markers"
|
|
assert 'line two modified' in patch or '+line two modified' in patch
|
|
assert '-line two' in patch
|
|
|
|
|
|
def test_download_patch_link_present_in_diff_page(client, live_server, measure_memory_usage, datastore_path):
|
|
"""
|
|
The diff history page HTML should contain a 'Download difference patch' link
|
|
pointing to the download-patch route when from_version and to_version are set.
|
|
"""
|
|
live_server_setup(live_server)
|
|
delete_all_watches(client)
|
|
|
|
app = client.application
|
|
test_url = url_for('test_endpoint', content_type='text/html', content='initial content', _external=True)
|
|
|
|
uuid = _add_watch_with_history(app, test_url, 'initial content\n', 'updated content\n')
|
|
|
|
# Load the diff page without explicit versions — should default to last two
|
|
res = client.get(
|
|
url_for('ui.ui_diff.diff_history_page', uuid=uuid),
|
|
follow_redirects=True,
|
|
)
|
|
|
|
assert res.status_code == 200
|
|
html = res.data.decode('utf-8')
|
|
assert 'Download difference patch' in html
|
|
assert 'download-patch' in html
|
|
|
|
|
|
def test_download_patch_unknown_uuid_returns_404(client, live_server, measure_memory_usage, datastore_path):
|
|
"""
|
|
Requesting a patch for a non-existent watch should return 404.
|
|
"""
|
|
live_server_setup(live_server)
|
|
delete_all_watches(client)
|
|
|
|
res = client.get(
|
|
url_for('ui.ui_diff.download_patch', uuid='00000000-0000-0000-0000-000000000000',
|
|
from_version='1000000000', to_version='1000000001'),
|
|
)
|
|
|
|
assert res.status_code == 404
|