Files
EscapistsReintroduced/tests/test_workshop_changelog.py
T
2026-11-07 01:05:43 +01:00

90 lines
4.7 KiB
Python

"""Version extraction uses the addon asset, not the manifest schema or game version."""
import importlib.util
from pathlib import Path
import unittest
import json
import io
from unittest.mock import patch
ROOT = Path(__file__).resolve().parents[1]
spec = importlib.util.spec_from_file_location('workshop_changelog', ROOT / 'tools/workshop_changelog.py')
tool = importlib.util.module_from_spec(spec)
spec.loader.exec_module(tool)
PROJECT = 'GameProject { GUID "2528466DE220D91C" }'
TEXT = '# Changelog\n\n## Update\n\n- Gameplay fix.\n'
class WorkshopTests(unittest.TestCase):
def test_asset_version(self):
manifest = {'version': 1, 'asset': {'id': '2528466DE220D91C', 'version': '0.0.109', 'gameVersion': '1.8.0.13'}}
self.assertEqual(tool.bundled_version(manifest, PROJECT), '0.0.109')
def test_reject_wrong_addon_and_invalid_manifest(self):
for manifest in (None, [], {}, {'asset': None}, {'asset': {'id': None}},
{'asset': {'id': 'OTHER', 'version': '0.0.109'}},
{'asset': {'id': '2528466DE220D91C', 'version': '99999.0.0'}},
{'version': '0.0.109', 'asset': {'id': '2528466DE220D91C'}}):
with self.subTest(manifest=manifest), self.assertRaises(ValueError):
tool.bundled_version(manifest, PROJECT)
def test_update_preserves_notes_and_is_idempotent(self):
updated = tool.update_changelog(TEXT, '0.0.109')
self.assertIn('Latest published Workshop version: **0.0.109**', updated)
self.assertTrue(updated.endswith('## Update\n\n- Gameplay fix.\n'))
self.assertEqual(updated, tool.update_changelog(updated, '0.0.109'))
next_release = tool.update_changelog(updated, '0.0.110')
self.assertNotIn('0.0.109', next_release)
self.assertEqual(next_release.count('Latest published Workshop version:'), 1)
def test_bad_layout_refused(self):
for text in ('Notes only', TEXT + 'Latest published Workshop version: **0.0.1**\n',
'# Changelog\nLatest published Workshop version: **0.0.1**\nLatest published Workshop version: **0.0.2**\n'):
with self.subTest(text=text), self.assertRaises(ValueError):
tool.update_changelog(text, '0.0.109')
class PublishedLookupTests(unittest.TestCase):
def page(self, **overrides):
asset = dict(id='2528466DE220D91C', currentVersionNumber='0.0.147',
gameVersion='1.9.0.37', versions=[dict(version='0.0.147',
assetId='2528466DE220D91C', published=True, approved=True)])
asset.update(overrides)
return '<script id="__NEXT_DATA__" type="application/json">' + json.dumps(
{'props': {'pageProps': {'asset': asset}}}) + '</script>'
def test_public_version_is_not_game_or_bundle_version(self):
self.assertEqual(tool.online_version(self.page(), '2528466DE220D91C'), '0.0.147')
def test_wrong_asset_unpublished_and_ambiguous_pages_are_rejected(self):
cases = [self.page(id='1111111111111111'), self.page(versions=[]),
self.page(private=True), self.page(blocked=True),
self.page(currentVersionNumber='1.9.0.37'),
self.page(versions=[dict(version='0.0.147', assetId='2528466DE220D91C', published=False, approved=True)]),
self.page(versions=[dict(version='0.0.147', assetId='2528466DE220D91C', published=True, approved=False)]),
self.page() + self.page(), '<html>unavailable</html>']
for page in cases:
with self.subTest(page=page), self.assertRaises(ValueError):
tool.online_version(page, '2528466DE220D91C')
def test_stale_response_is_not_a_downgrade(self):
text = tool.update_changelog(TEXT, '0.0.146')
with self.assertRaises(ValueError):
tool.prevent_downgrade(text, '0.0.142')
tool.prevent_downgrade(text, '0.0.146')
tool.prevent_downgrade(text, '0.0.147')
tool.prevent_downgrade(tool.update_changelog(TEXT, '0.0.9'), '0.0.10')
def test_live_sync_validates_response_and_fails_closed(self):
with patch.object(tool.urllib.request, 'urlopen', return_value=io.BytesIO(self.page().encode())):
self.assertEqual(tool.sync_version(PROJECT, TEXT), '0.0.147')
with patch.object(tool.urllib.request, 'urlopen', side_effect=OSError('offline')):
with self.assertRaises(OSError):
tool.sync_version(PROJECT, TEXT)
with patch.object(tool.urllib.request, 'urlopen', return_value=io.BytesIO(self.page().encode())):
with self.assertRaises(ValueError):
tool.sync_version(PROJECT, tool.update_changelog(TEXT, '0.0.148'))
if __name__ == '__main__':
unittest.main()