diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2c01d00..d35f448 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,4 +22,4 @@ jobs: pip install -r test/pip_reqs.txt - name: Execute Tests run: | - python -m unittest discover + python -m unittest discover -v diff --git a/README.md b/README.md index f1f2445..951ef99 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ $ pip install -r test/pip_reqs.txt and then executing the following in the project's root directory: ```bash -$ python -m unittest discover +$ python -m unittest discover -v ``` ## License diff --git a/plugins/minigames.json b/plugins/minigames.json index 4d69b67..6ed54d6 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -16,7 +16,7 @@ "versions": { "1.1.0": { "api_version": 7, - "commit_sha": "cbdb3ead", + "commit_sha": "40b70fe", "released_on": "08-08-2022", "md5sum": "f4f0bb91f5d10cf8f591ecf7d2848182" } diff --git a/plugins/utilities.json b/plugins/utilities.json index 51a7397..928a86d 100644 --- a/plugins/utilities.json +++ b/plugins/utilities.json @@ -30,12 +30,6 @@ "commit_sha": "963a17379", "released_on": "12-08-2022", "md5sum": "41084bfec41119ca9df8e6d899cd3cc0" - }, - "1.1.0": { - "api_version": 7, - "commit_sha": "13a9d128", - "released_on": "03-06-2022", - "md5sum": "4b6bbb99037ebda4664da7c510b3717c" }, "1.0.0": { "api_version": 6, @@ -58,7 +52,7 @@ "versions": { "1.0.0": { "api_version": 7, - "commit_sha": "2aa6df31", + "commit_sha": "63d674cf", "released_on": "06-08-2022", "md5sum": "233dfaa7f0e9394d21454f4ffa7d0205" } diff --git a/test/categories/__init__.py b/test/categories/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/categories/test_minigames_meta.py b/test/categories/test_minigames_meta.py new file mode 100644 index 0000000..de1f98e --- /dev/null +++ b/test/categories/test_minigames_meta.py @@ -0,0 +1,52 @@ +import hashlib +import json +import re + +import asyncio +import aiohttp + +import unittest +from test import helpers + + +class TestMetadata(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + with open("plugins/minigames.json", "rb") as fin: + self.content = json.load(fin) + + async def asyncTearDown(self): + # This helps suppress aiohttp warnings. See: + # https://github.com/aio-libs/aiohttp/issues/1115 + await asyncio.sleep(0.2) + + def test_keys(self): + self.assertEqual(self.content["name"], "Minigames") + self.assertTrue(isinstance(self.content["description"], str)) + self.assertTrue(self.content["plugins_base_url"].startswith("http")) + self.assertTrue(isinstance(self.content["plugins"], dict)) + + async def test_plugins_metadata(self): + asserts_for_versions_metadata = [] + async with aiohttp.ClientSession() as session: + for plugin in self.content["plugins"].items(): + metadata = helpers.AssertPluginMetadata(*plugin) + metadata.assert_keys() + asserts_for_versions_metadata.append( + metadata.assert_for_versions_metadata( + self.content["plugins_base_url"], + session, + ) + ) + await asyncio.gather( + *asserts_for_versions_metadata + ) + + def test_versions_order(self): + for plugin_metadata in self.content["plugins"].values(): + versions = list(plugin_metadata["versions"].items()) + sorted_versions = sorted( + versions, + key=lambda version: version[0], + reverse=True, + ) + self.assertEqual(sorted_versions, versions) diff --git a/test/categories/test_utilities_meta.py b/test/categories/test_utilities_meta.py new file mode 100644 index 0000000..a6d635f --- /dev/null +++ b/test/categories/test_utilities_meta.py @@ -0,0 +1,52 @@ +import hashlib +import json +import re + +import asyncio +import aiohttp + +import unittest +from test import helpers + + +class TestMetadata(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + with open("plugins/utilities.json", "rb") as fin: + self.content = json.load(fin) + + async def asyncTearDown(self): + # This helps suppress aiohttp warnings. See: + # https://github.com/aio-libs/aiohttp/issues/1115 + await asyncio.sleep(0.2) + + def test_keys(self): + self.assertEqual(self.content["name"], "Utilities") + self.assertTrue(isinstance(self.content["description"], str)) + self.assertTrue(self.content["plugins_base_url"].startswith("http")) + self.assertTrue(isinstance(self.content["plugins"], dict)) + + async def test_plugins_metadata(self): + asserts_for_versions_metadata = [] + async with aiohttp.ClientSession() as session: + for plugin in self.content["plugins"].items(): + metadata = helpers.AssertPluginMetadata(*plugin) + metadata.assert_keys() + asserts_for_versions_metadata.append( + metadata.assert_for_versions_metadata( + self.content["plugins_base_url"], + session, + ) + ) + await asyncio.gather( + *asserts_for_versions_metadata + ) + + def test_versions_order(self): + for plugin_metadata in self.content["plugins"].values(): + versions = list(plugin_metadata["versions"].items()) + sorted_versions = sorted( + versions, + key=lambda version: version[0], + reverse=True, + ) + self.assertEqual(sorted_versions, versions) diff --git a/test/helpers.py b/test/helpers.py new file mode 100644 index 0000000..d253338 --- /dev/null +++ b/test/helpers.py @@ -0,0 +1,85 @@ +import hashlib +import os +import re + +import asyncio + + +async def assert_for_network_file(url, md5sum, aiohttp_session, regexp=None, regexp_result=None): + async with aiohttp_session.get(url) as response: + expected_response_status = 200 + assert response.status == expected_response_status, ( + f'Request to "{url}" returned status code {response.status} ' + f'(expected {expected_response_status}).' + ) + content = await response.read() + caclulated_md5sum = hashlib.md5(content).hexdigest() + assert caclulated_md5sum == md5sum, ( + f'"{url}" failed MD5 checksum:\nGot {caclulated_md5sum} ' + f'(expected {md5sum}).' + ) + if regexp and regexp_result: + result = regexp.search(content).group().decode("utf-8") + assert result == regexp_result, ( + f'Regexp failed: Got ({result}) (expected {regexp_result}).' + ) + + +async def assert_for_network_files_from_versions(base_url, versions, aiohttp_session, regexp=None): + tasks = tuple( + assert_for_network_file( + base_url.format( + content_type="raw", + tag=version["commit_sha"], + ), + version["md5sum"], + aiohttp_session, + regexp=regexp, + regexp_result=str(version["api_version"]), + ) for number, version in versions.items() + ) + await asyncio.gather(*tasks) + + +class AssertPluginMetadata: + def __init__(self, name, metadata): + self.name = name + self.metadata = metadata + self.filename = f"{name}.py" + self.api_number_regexp = re.compile(b"(?<=ba_meta require api )(.*)") + + def assert_keys(self): + assert isinstance(self.metadata["description"], str) + assert isinstance(self.metadata["external_url"], str) + assert isinstance(self.metadata["authors"], list) + assert len(self.metadata["authors"]) > 0 + for author in self.metadata["authors"]: + assert isinstance(author["name"], str) + assert isinstance(author["email"], str) + assert isinstance(author["discord"], str) + assert isinstance(self.metadata["versions"], dict) + assert len(self.metadata["versions"]) > 0 + + async def assert_for_versions_metadata(self, base_url, aiohttp_session): + versions = tuple(self.metadata["versions"].items()) + latest_number, latest_version = versions[0] + await asyncio.gather( + assert_for_network_files_from_versions( + f"{base_url}/{self.filename}", + self.metadata["versions"], + aiohttp_session, + regexp=self.api_number_regexp + ), + # Additionally assert for the latest version with tag as "main". + assert_for_network_file( + f"{base_url}/{self.filename}".format( + content_type="raw", + tag="main", + ), + latest_version["md5sum"], + aiohttp_session, + regexp=self.api_number_regexp, + regexp_result=str(latest_version["api_version"]), + ) + ) + # TODO: Regex stuff to get api number from plugin file. diff --git a/test/test_checks.py b/test/test_checks.py deleted file mode 100644 index 900897c..0000000 --- a/test/test_checks.py +++ /dev/null @@ -1,85 +0,0 @@ -import hashlib -import os -import json -import re - -import asyncio -import aiohttp - -import unittest - - -async def assert_for_md5sum(url, md5sum, aiohttp_session): - async with aiohttp_session.get(url) as response: - expected_response_status = 200 - assert response.status == expected_response_status, ( - f'Request to "{url}" returned status code {response.status} ' - f'(expected {expected_response_status}).' - ) - content = await response.read() - caclulated_md5sum = hashlib.md5(content).hexdigest() - assert caclulated_md5sum == md5sum, ( - f'"{url}" failed MD5 checksum:\nGot {caclulated_md5sum} ' - f'(expected {md5sum}).' - ) - - -async def assert_for_commit_sha_and_md5sum_from_versions(base_url, versions, aiohttp_session): - tasks = tuple( - assert_for_md5sum( - base_url.format( - content_type="raw", - tag=version["commit_sha"], - ), - version["md5sum"], - aiohttp_session, - ) for number, version in versions.items() - ) - await asyncio.gather(*tasks) - - -class TestPluginManagerMetadata(unittest.IsolatedAsyncioTestCase): - async def asyncSetUp(self): - with open("index.json", "rb") as fin: - self.content = json.load(fin) - self.version_regexp = re.compile(b"PLUGIN_MANAGER_VERSION = .+") - - async def asyncTearDown(self): - pass - - def test_keys(self): - assert isinstance(self.content["plugin_manager_url"], str) - assert isinstance(self.content["versions"], dict) - assert isinstance(self.content["categories"], list) - assert isinstance(self.content["external_source_url"], str) - - def test_versions_order(self): - versions = list(self.content["versions"].items()) - sorted_versions = sorted(versions, key=lambda version: version[0]) - assert sorted_versions == versions - - async def test_versions_metadata(self): - versions = tuple(self.content["versions"].items()) - latest_number, latest_version = versions[0] - async with aiohttp.ClientSession() as session: - await asyncio.gather( - assert_for_commit_sha_and_md5sum_from_versions( - self.content["plugin_manager_url"], - self.content["versions"], - session, - ), - # Additionally assert for the latest version with tag as "main". - assert_for_md5sum( - self.content["plugin_manager_url"].format( - content_type="raw", - tag="main", - ), - latest_version["md5sum"], - session, - ), - ) - - -# class TestPluginsMetadata(unittest.IsolatedAsyncioTestCase): - -# class TestExternalSourceMetadata(unittest.IsolatedAsyncioTestCase): diff --git a/test/test_plugin_manager_meta.py b/test/test_plugin_manager_meta.py new file mode 100644 index 0000000..71166cc --- /dev/null +++ b/test/test_plugin_manager_meta.py @@ -0,0 +1,55 @@ +import json +import re + +import asyncio +import aiohttp + +import unittest +from test import helpers + + +class TestPluginManagerMetadata(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + with open("index.json", "rb") as fin: + self.content = json.load(fin) + + async def asyncTearDown(self): + pass + + def test_keys(self): + self.assertTrue(self.content["plugin_manager_url"].startswith("http")) + self.assertTrue(isinstance(self.content["versions"], dict)) + self.assertTrue(isinstance(self.content["categories"], list)) + for category in self.content["categories"]: + self.assertTrue(category.startswith("http")) + self.assertTrue(self.content["external_source_url"].startswith("http")) + + def test_versions_order(self): + versions = list(self.content["versions"].items()) + sorted_versions = sorted( + versions, + key=lambda version: version[0], + reverse=True, + ) + self.assertEqual(sorted_versions, versions) + + async def test_versions_metadata(self): + versions = tuple(self.content["versions"].items()) + latest_number, latest_version = versions[0] + async with aiohttp.ClientSession() as session: + await asyncio.gather( + helpers.assert_for_network_files_from_versions( + self.content["plugin_manager_url"], + self.content["versions"], + session, + ), + # Additionally assert for the latest version with tag as "main". + helpers.assert_for_network_file( + self.content["plugin_manager_url"].format( + content_type="raw", + tag="main", + ), + latest_version["md5sum"], + session, + ), + )