104 lines
4.4 KiB
Python
104 lines
4.4 KiB
Python
import re
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
from scripts import publish_release
|
|
|
|
|
|
class Response:
|
|
def __init__(self, body=b'{"id": 1}', status=201, headers=None):
|
|
self.body = body
|
|
self.status = status
|
|
self.headers = headers or {}
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, *args):
|
|
return False
|
|
|
|
def read(self, size=-1):
|
|
return self.body if size < 0 else self.body[:size]
|
|
|
|
|
|
class PublishReleaseTest(unittest.TestCase):
|
|
def test_upload_is_multipart_with_attachment_field(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
path = Path(temporary) / "package.crx"
|
|
path.write_bytes(b"Cr24\x03payload")
|
|
with patch("scripts.publish_release.urlopen", return_value=Response()) as request:
|
|
publish_release._upload_asset(
|
|
"https://gitea.example/api/v1", "secret-token", "/repos/o/r", 4, path, "package.crx"
|
|
)
|
|
sent = request.call_args.args[0]
|
|
body = sent.data
|
|
content_type = sent.get_header("Content-type")
|
|
boundary = re.search(r"boundary=([^;]+)", content_type).group(1).encode("ascii")
|
|
self.assertIn(b'name="attachment"', body)
|
|
self.assertIn(b"filename=\"package.crx\"", body)
|
|
self.assertIn(b"Cr24\x03payload", body)
|
|
self.assertTrue(body.endswith(b"--" + boundary + b"--\r\n"))
|
|
|
|
def test_edit_and_delete_use_release_scoped_attachment_path(self):
|
|
with patch("scripts.publish_release.api_call") as call:
|
|
publish_release._edit_asset("base", "token", "/repos/o/r", 9, 12, "new.crx")
|
|
publish_release._delete_asset("base", "token", "/repos/o/r", 9, 12)
|
|
self.assertEqual(call.call_args_list[0].args[3], "/repos/o/r/releases/9/assets/12")
|
|
self.assertEqual(call.call_args_list[1].args[3], "/repos/o/r/releases/9/assets/12")
|
|
|
|
def test_public_crx_check_is_anonymous_and_allows_content_type_parameters(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
updates = Path(temporary) / "updates.xml"
|
|
updates.write_text(
|
|
'<gupdate><app><updatecheck codebase="https://public.example/package.crx" /></app></gupdate>',
|
|
encoding="utf-8",
|
|
)
|
|
with patch(
|
|
"scripts.publish_release.urlopen",
|
|
return_value=Response(
|
|
b"Cr24\x03payload",
|
|
status=200,
|
|
headers={"Content-Type": "application/x-chrome-extension; charset=binary"},
|
|
),
|
|
) as request:
|
|
publish_release.verify_public_crx(updates)
|
|
self.assertIsNone(request.call_args.args[0].get_header("Authorization"))
|
|
|
|
def test_second_replacement_is_single_asset_and_version_downgrades_are_skipped(self):
|
|
assets = []
|
|
next_id = iter(range(1, 10))
|
|
|
|
def upload(*args):
|
|
asset = {"id": next(next_id), "name": args[-1]}
|
|
assets.append(asset)
|
|
return asset
|
|
|
|
def edit(*args):
|
|
attachment_id, name = args[-2:]
|
|
next(asset for asset in assets if asset["id"] == attachment_id)["name"] = name
|
|
|
|
def delete(*args):
|
|
attachment_id = args[-1]
|
|
assets[:] = [asset for asset in assets if asset["id"] != attachment_id]
|
|
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
path = Path(temporary) / "package.crx"
|
|
path.write_bytes(b"data")
|
|
with patch("scripts.publish_release.release_assets", side_effect=lambda *args: assets.copy()), \
|
|
patch("scripts.publish_release._upload_asset", side_effect=upload), \
|
|
patch("scripts.publish_release._edit_asset", side_effect=edit), \
|
|
patch("scripts.publish_release._delete_asset", side_effect=delete):
|
|
publish_release.replace_asset("base", "token", "/repos/o/r", 9, path)
|
|
publish_release.replace_asset("base", "token", "/repos/o/r", 9, path)
|
|
|
|
self.assertEqual(assets, [{"id": 2, "name": "package.crx"}])
|
|
self.assertFalse(publish_release.should_publish_updates("2.4.0", "2.3.9"))
|
|
self.assertFalse(publish_release.should_publish_updates("2.4.0", "2.4.0"))
|
|
self.assertTrue(publish_release.should_publish_updates("2.4.0", "2.4.1"))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|