diff --git a/CHANGELOG.md b/CHANGELOG.md index cc99efcb..10ccc3f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/lang/zh-CN/ ### Fixed - 修复在评论议题后立即关闭拉取请求,拉取请求会被再次创建的问题 +- 修复插件元数据缺失时不报错的问题 ## [4.2.3] - 2024-12-30 diff --git a/src/providers/validation/models.py b/src/providers/validation/models.py index 98d9b275..d29d9ca8 100644 --- a/src/providers/validation/models.py +++ b/src/providers/validation/models.py @@ -317,7 +317,7 @@ def plugin_test_metadata_validator( if context is None: raise PydanticCustomError("validation_context", "未获取到验证上下文") - if v is None: + if not v: raise PydanticCustomError( "plugin.metadata", "插件无法获取到元数据", @@ -383,7 +383,7 @@ class ValidationDict(BaseModel): @property def valid(self) -> bool: - return not self.errors + return self.info is not None @property def name(self) -> str: diff --git a/tests/plugins/github/publish/process/test_publish_check.py b/tests/plugins/github/publish/process/test_publish_check.py index 1c3b5e48..e0b9e5ce 100644 --- a/tests/plugins/github/publish/process/test_publish_check.py +++ b/tests/plugins/github/publish/process/test_publish_check.py @@ -352,524 +352,6 @@ async def test_adapter_process_publish_check( assert mocked_api["homepage"].called -async def test_plugin_process_publish_check( - app: App, - mocker: MockerFixture, - mocked_api: MockRouter, - tmp_path: Path, - mock_installation, -) -> None: - """测试插件的发布流程""" - from src.plugins.github import plugin_config - from src.providers.docker_test import Metadata - - mock_subprocess_run = mock_subprocess_run_with_side_effect(mocker) - - mock_issue = MockIssue(body=MockBody(type="plugin").generate()).as_mock(mocker) - - mock_event = mocker.MagicMock() - mock_event.issue = mock_issue - - mock_issues_resp = mocker.MagicMock() - mock_issues_resp.parsed_data = mock_issue - - mock_comment = mocker.MagicMock() - mock_comment.body = "Plugin: name" - mock_list_comments_resp = mocker.MagicMock() - mock_list_comments_resp.parsed_data = [mock_comment] - - mock_pull = mocker.MagicMock() - mock_pull.number = 2 - mock_pulls_resp = mocker.MagicMock() - mock_pulls_resp.parsed_data = mock_pull - - mock_test_result = mocker.MagicMock() - mock_test_result.metadata = Metadata( - name="name", - desc="desc", - homepage="https://nonebot.dev", - type="application", - supported_adapters=None, - ) - mock_test_result.load = True - mock_test_result.version = "1.0.0" - mock_test_result.output = "" - mock_docker = mocker.patch("src.providers.docker_test.DockerPluginTest.run") - mock_docker.return_value = mock_test_result - - with open(tmp_path / "plugins.json5", "w") as f: - json.dump([], f) - - check_json_data(plugin_config.input_config.plugin_path, []) - - async with app.test_matcher() as ctx: - adapter, bot = get_github_bot(ctx) - event = get_mock_event(IssuesOpened) - event.payload.issue.labels = get_issue_labels(["Plugin", "Publish"]) - - ctx.should_call_api( - "rest.apps.async_get_repo_installation", - {"owner": "he0119", "repo": "action-test"}, - mock_installation, - ) - ctx.should_call_api( - "rest.issues.async_get", - {"owner": "he0119", "repo": "action-test", "issue_number": 80}, - mock_issues_resp, - ) - ctx.should_call_api( - "rest.issues.async_update", - snapshot( - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 80, - "body": """\ -### PyPI 项目名 - -project_link - -### 插件 import 包名 - -module_name - -### 标签 - -[{"label": "test", "color": "#ffffff"}] - -### 插件配置项 - -```dotenv -log_level=DEBUG -``` - -### 插件测试 - -- [x] 🔥插件测试中,请稍后\ -""", - } - ), - True, - ) - ctx.should_call_api( - "rest.issues.async_list_comments", - {"owner": "he0119", "repo": "action-test", "issue_number": 80}, - mock_list_comments_resp, - ) - ctx.should_call_api( - "rest.issues.async_update", - snapshot( - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 80, - "body": """\ -### PyPI 项目名 - -project_link - -### 插件 import 包名 - -module_name - -### 标签 - -[{"label": "test", "color": "#ffffff"}] - -### 插件配置项 - -```dotenv -log_level=DEBUG -``` - -### 插件测试 - -- [ ] 如需重新运行插件测试,请勾选左侧勾选框\ -""", - } - ), - True, - ) - ctx.should_call_api( - "rest.issues.async_list_comments", - {"owner": "he0119", "repo": "action-test", "issue_number": 80}, - mock_list_comments_resp, - ) - ctx.should_call_api( - "rest.issues.async_create_comment", - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 80, - "body": snapshot( - """\ -# 📃 商店发布检查结果 - -> Plugin: name - -**✅ 所有测试通过,一切准备就绪!** - - -
-详情 -
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 项目 project_link 已发布至 PyPI。
  • ✅ 标签: test-#ffffff。
  • ✅ 插件类型: application。
  • ✅ 插件支持的适配器: 所有。
  • ✅ 插件 加载测试 通过。
  • ✅ 版本号: 1.0.0。
  • ✅ 发布时间:2023-09-01 08:00:00 CST。
  • -
    - ---- - -💡 如需修改信息,请直接修改 issue,机器人会自动更新检查结果。 -💡 当插件加载测试失败时,请发布新版本后勾选插件测试勾选框重新运行插件测试。 - -♻️ 评论已更新至最新检查结果 - -💪 Powered by [NoneFlow](https://github.com/nonebot/noneflow) - -""" - ), - }, - True, - ) - ctx.should_call_api( - "rest.issues.async_update", - snapshot( - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 80, - "title": "Plugin: name", - } - ), - True, - ) - ctx.should_call_api( - "rest.pulls.async_create", - { - "owner": "he0119", - "repo": "action-test", - "title": snapshot("Plugin: name"), - "body": "resolve #80", - "base": "master", - "head": "publish/issue80", - }, - mock_pulls_resp, - ) - ctx.should_call_api( - "rest.issues.async_add_labels", - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 2, - "labels": ["Publish", "Plugin"], - }, - True, - ) - - ctx.receive_event(bot, event) - - # 测试 git 命令 - assert_subprocess_run_calls( - mock_subprocess_run, - [ - ["git", "config", "--global", "safe.directory", "*"], - ["git", "switch", "-C", "publish/issue80"], - ["git", "ls-remote", "--heads", "origin", "publish/issue80"], - ["git", "config", "--global", "user.name", "test"], - [ - "git", - "config", - "--global", - "user.email", - "test@users.noreply.github.com", - ], - ["git", "add", "-A"], - ["git", "commit", "-m", ":beers: publish plugin name (#80)"], - ["git", "fetch", "origin"], - ["git", "diff", "origin/publish/issue80", "publish/issue80"], - ["git", "push", "origin", "publish/issue80", "-f"], - ], - ) - - # 检查文件是否正确 - check_json_data( - plugin_config.input_config.plugin_path, - [ - snapshot( - { - "module_name": "module_name", - "project_link": "project_link", - "author_id": 1, - "tags": [{"label": "test", "color": "#ffffff"}], - "is_official": False, - } - ) - ], - ) - - assert mocked_api["homepage"].called - mock_docker.assert_called_once_with("3.12") - - -async def test_plugin_process_publish_check_re_run( - app: App, - mocker: MockerFixture, - mocked_api: MockRouter, - tmp_path: Path, - mock_installation, -) -> None: - """测试插件的发布流程,重新运行插件测试""" - from src.plugins.github import plugin_config - from src.providers.docker_test import Metadata - - mock_subprocess_run = mock_subprocess_run_with_side_effect(mocker) - - # 这次运行时,议题内容已经包含了插件测试按钮 - mock_issue = MockIssue( - body=MockBody(type="plugin", test_button=True).generate() - ).as_mock(mocker) - - mock_event = mocker.MagicMock() - mock_event.issue = mock_issue - - mock_issues_resp = mocker.MagicMock() - mock_issues_resp.parsed_data = mock_issue - - mock_comment = mocker.MagicMock() - mock_comment.body = "Plugin: name" - mock_list_comments_resp = mocker.MagicMock() - mock_list_comments_resp.parsed_data = [mock_comment] - - mock_pull = mocker.MagicMock() - mock_pull.number = 2 - mock_pulls_resp = mocker.MagicMock() - mock_pulls_resp.parsed_data = mock_pull - - mock_test_result = mocker.MagicMock() - mock_test_result.metadata = Metadata( - name="name", - desc="desc", - homepage="https://nonebot.dev", - type="application", - supported_adapters=None, - ) - mock_test_result.load = True - mock_test_result.version = "1.0.0" - mock_test_result.output = "" - mock_docker = mocker.patch("src.providers.docker_test.DockerPluginTest.run") - mock_docker.return_value = mock_test_result - - with open(tmp_path / "plugins.json5", "w") as f: - json.dump([], f) - - check_json_data(plugin_config.input_config.plugin_path, []) - - async with app.test_matcher() as ctx: - adapter, bot = get_github_bot(ctx) - event = get_mock_event(IssuesOpened) - event.payload.issue.labels = get_issue_labels(["Plugin", "Publish"]) - - ctx.should_call_api( - "rest.apps.async_get_repo_installation", - {"owner": "he0119", "repo": "action-test"}, - mock_installation, - ) - ctx.should_call_api( - "rest.issues.async_get", - {"owner": "he0119", "repo": "action-test", "issue_number": 80}, - mock_issues_resp, - ) - # 测试前,将插件测试状态修改为插件测试中,提示用户 - ctx.should_call_api( - "rest.issues.async_update", - snapshot( - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 80, - "body": """\ -### PyPI 项目名 - -project_link - -### 插件 import 包名 - -module_name - -### 标签 - -[{"label": "test", "color": "#ffffff"}] - -### 插件配置项 - -```dotenv -log_level=DEBUG -``` - -### 插件测试 - -- [x] 🔥插件测试中,请稍后\ -""", - } - ), - True, - ) - ctx.should_call_api( - "rest.issues.async_list_comments", - {"owner": "he0119", "repo": "action-test", "issue_number": 80}, - mock_list_comments_resp, - ) - ctx.should_call_api( - "rest.issues.async_update", - snapshot( - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 80, - "body": """\ -### PyPI 项目名 - -project_link - -### 插件 import 包名 - -module_name - -### 标签 - -[{"label": "test", "color": "#ffffff"}] - -### 插件配置项 - -```dotenv -log_level=DEBUG -``` - -### 插件测试 - -- [ ] 如需重新运行插件测试,请勾选左侧勾选框\ -""", - } - ), - True, - ) - ctx.should_call_api( - "rest.issues.async_list_comments", - {"owner": "he0119", "repo": "action-test", "issue_number": 80}, - mock_list_comments_resp, - ) - ctx.should_call_api( - "rest.issues.async_create_comment", - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 80, - "body": snapshot( - """\ -# 📃 商店发布检查结果 - -> Plugin: name - -**✅ 所有测试通过,一切准备就绪!** - - -
    -详情 -
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 项目 project_link 已发布至 PyPI。
  • ✅ 标签: test-#ffffff。
  • ✅ 插件类型: application。
  • ✅ 插件支持的适配器: 所有。
  • ✅ 插件 加载测试 通过。
  • ✅ 版本号: 1.0.0。
  • ✅ 发布时间:2023-09-01 08:00:00 CST。
  • -
    - ---- - -💡 如需修改信息,请直接修改 issue,机器人会自动更新检查结果。 -💡 当插件加载测试失败时,请发布新版本后勾选插件测试勾选框重新运行插件测试。 - -♻️ 评论已更新至最新检查结果 - -💪 Powered by [NoneFlow](https://github.com/nonebot/noneflow) - -""" - ), - }, - True, - ) - ctx.should_call_api( - "rest.issues.async_update", - snapshot( - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 80, - "title": "Plugin: name", - } - ), - True, - ) - ctx.should_call_api( - "rest.pulls.async_create", - { - "owner": "he0119", - "repo": "action-test", - "title": snapshot("Plugin: name"), - "body": "resolve #80", - "base": "master", - "head": "publish/issue80", - }, - mock_pulls_resp, - ) - ctx.should_call_api( - "rest.issues.async_add_labels", - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 2, - "labels": ["Publish", "Plugin"], - }, - True, - ) - - ctx.receive_event(bot, event) - - # 测试 git 命令 - assert_subprocess_run_calls( - mock_subprocess_run, - [ - ["git", "config", "--global", "safe.directory", "*"], - ["git", "switch", "-C", "publish/issue80"], - ["git", "ls-remote", "--heads", "origin", "publish/issue80"], - ["git", "config", "--global", "user.name", "test"], - [ - "git", - "config", - "--global", - "user.email", - "test@users.noreply.github.com", - ], - ["git", "add", "-A"], - ["git", "commit", "-m", ":beers: publish plugin name (#80)"], - ["git", "fetch", "origin"], - ["git", "diff", "origin/publish/issue80", "publish/issue80"], - ["git", "push", "origin", "publish/issue80", "-f"], - ], - ) - - # 检查文件是否正确 - check_json_data( - plugin_config.input_config.plugin_path, - [ - snapshot( - { - "module_name": "module_name", - "project_link": "project_link", - "author_id": 1, - "tags": [{"label": "test", "color": "#ffffff"}], - "is_official": False, - } - ) - ], - ) - - assert mocked_api["homepage"].called - mock_docker.assert_called_once_with("3.12") - - async def test_edit_title( app: App, mocker: MockerFixture, @@ -1414,266 +896,6 @@ async def test_comment_by_self( mock_subprocess_run.assert_not_called() -async def test_skip_plugin_check( - app: App, - mocker: MockerFixture, - mocked_api: MockRouter, - tmp_path: Path, - mock_installation, -) -> None: - """测试手动跳过插件测试的流程""" - from src.plugins.github import plugin_config - - mock_subprocess_run = mocker.patch( - "subprocess.run", side_effect=lambda *args, **kwargs: mocker.MagicMock() - ) - - mock_issue = MockIssue(number=70, body=MockBody("plugin").generate()).as_mock( - mocker - ) - - mock_event = mocker.MagicMock() - mock_event.issue = mock_issue - - mock_issues_resp = mocker.MagicMock() - mock_issues_resp.parsed_data = mock_issue - - mock_comment = mocker.MagicMock() - mock_comment.body = "/skip" - mock_comment.author_association = "OWNER" - mock_list_comments_resp = mocker.MagicMock() - mock_list_comments_resp.parsed_data = [mock_comment] - - mock_pulls_resp = mocker.MagicMock() - mock_pulls_resp.parsed_data = [] - - with open(tmp_path / "plugins.json5", "w") as f: - json.dump([], f) - - check_json_data(plugin_config.input_config.plugin_path, []) - - async with app.test_matcher() as ctx: - adapter, bot = get_github_bot(ctx) - event = get_mock_event(IssueCommentCreated, "issue-comment-skip") - - ctx.should_call_api( - "rest.apps.async_get_repo_installation", - {"owner": "he0119", "repo": "action-test"}, - mock_installation, - ) - ctx.should_call_api( - "rest.issues.async_get", - {"owner": "he0119", "repo": "action-test", "issue_number": 70}, - mock_issues_resp, - ) - ctx.should_call_api( - "rest.issues.async_update", - snapshot( - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 70, - "body": """\ -### PyPI 项目名 - -project_link - -### 插件 import 包名 - -module_name - -### 标签 - -[{"label": "test", "color": "#ffffff"}] - -### 插件配置项 - -```dotenv -log_level=DEBUG -``` - -### 插件测试 - -- [x] 🔥插件测试中,请稍后\ -""", - } - ), - True, - ) - ctx.should_call_api( - "rest.issues.async_list_comments", - {"owner": "he0119", "repo": "action-test", "issue_number": 70}, - mock_list_comments_resp, - ) - ctx.should_call_api( - "rest.issues.async_update", - snapshot( - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 70, - "body": """\ -### 插件名称 - -### 插件描述 - -### 插件项目仓库/主页链接 - -### 插件类型 - -### 插件支持的适配器 - -### PyPI 项目名 - -project_link - -### 插件 import 包名 - -module_name - -### 标签 - -[{"label": "test", "color": "#ffffff"}] - -### 插件配置项 - -```dotenv -log_level=DEBUG -``` - -### 插件测试 - -- [x] 🔥插件测试中,请稍后\ -""", - } - ), - True, - ) - ctx.should_call_api( - "rest.issues.async_update", - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 70, - "body": snapshot( - """\ -### 插件名称 - -### 插件描述 - -### 插件项目仓库/主页链接 - -### 插件类型 - -### 插件支持的适配器 - -### PyPI 项目名 - -project_link - -### 插件 import 包名 - -module_name - -### 标签 - -[{"label": "test", "color": "#ffffff"}] - -### 插件配置项 - -```dotenv -log_level=DEBUG -``` - -### 插件测试 - -- [ ] 如需重新运行插件测试,请勾选左侧勾选框\ -""" - ), - }, - True, - ) - ctx.should_call_api( - "rest.issues.async_list_comments", - {"owner": "he0119", "repo": "action-test", "issue_number": 70}, - mock_list_comments_resp, - ) - ctx.should_call_api( - "rest.issues.async_create_comment", - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 70, - "body": snapshot( - """\ -# 📃 商店发布检查结果 - -> Plugin: project_link - -**⚠️ 在发布检查过程中,我们发现以下问题:** - -
  • ⚠️ 名称: 无法匹配到数据。
    请确保填写该数据项。
  • ⚠️ 描述: 无法匹配到数据。
    请确保填写该数据项。
  • ⚠️ 项目仓库/主页链接: 无法匹配到数据。
    请确保填写该数据项。
  • ⚠️ 插件类型: 无法匹配到数据。
    请确保填写该数据项。
  • ⚠️ 插件支持的适配器: 无法匹配到数据。
    请确保填写该数据项。
  • - -
    -详情 -
  • ✅ 项目 project_link 已发布至 PyPI。
  • ✅ 标签: test-#ffffff。
  • ✅ 插件 加载测试 已跳过。
  • ✅ 版本号: 0.0.1。
  • ✅ 发布时间:2023-09-01 08:00:00 CST。
  • -
    - ---- - -💡 如需修改信息,请直接修改 issue,机器人会自动更新检查结果。 -💡 当插件加载测试失败时,请发布新版本后勾选插件测试勾选框重新运行插件测试。 - -♻️ 评论已更新至最新检查结果 - -💪 Powered by [NoneFlow](https://github.com/nonebot/noneflow) - -""" - ), - }, - True, - ) - ctx.should_call_api( - "rest.issues.async_update", - snapshot( - { - "owner": "he0119", - "repo": "action-test", - "issue_number": 70, - "title": "Plugin: project_link", - } - ), - True, - ) - ctx.should_call_api( - "rest.pulls.async_list", - { - "owner": "he0119", - "repo": "action-test", - "head": "he0119:publish/issue70", - }, - mock_pulls_resp, - ) - - ctx.receive_event(bot, event) - - # 测试 git 命令 - mock_subprocess_run.assert_has_calls( - [ - mocker.call( - ["git", "config", "--global", "safe.directory", "*"], - check=True, - capture_output=True, - ), # type: ignore - ] - ) - - # 检查文件是否正确 - check_json_data(plugin_config.input_config.plugin_path, []) - - assert mocked_api["pypi_project_link"].called - - async def test_convert_pull_request_to_draft( app: App, mocker: MockerFixture, diff --git a/tests/plugins/github/publish/process/test_publish_check_plugin.py b/tests/plugins/github/publish/process/test_publish_check_plugin.py new file mode 100644 index 00000000..a8fd11ef --- /dev/null +++ b/tests/plugins/github/publish/process/test_publish_check_plugin.py @@ -0,0 +1,998 @@ +import json +from pathlib import Path + +from inline_snapshot import snapshot +from nonebot.adapters.github import IssueCommentCreated, IssuesOpened +from nonebug import App +from pytest_mock import MockerFixture +from respx import MockRouter + +from tests.plugins.github.event import get_mock_event +from tests.plugins.github.utils import ( + MockBody, + MockIssue, + assert_subprocess_run_calls, + check_json_data, + generate_issue_body_plugin, + get_github_bot, + get_issue_labels, + mock_subprocess_run_with_side_effect, + should_call_apis, +) + + +async def test_plugin_process_publish_check( + app: App, + mocker: MockerFixture, + mocked_api: MockRouter, + tmp_path: Path, + mock_installation, +) -> None: + """测试插件的发布流程""" + from src.plugins.github import plugin_config + from src.providers.docker_test import Metadata + + mock_subprocess_run = mock_subprocess_run_with_side_effect(mocker) + + mock_issue = MockIssue(body=MockBody(type="plugin").generate()).as_mock(mocker) + + mock_event = mocker.MagicMock() + mock_event.issue = mock_issue + + mock_issues_resp = mocker.MagicMock() + mock_issues_resp.parsed_data = mock_issue + + mock_comment = mocker.MagicMock() + mock_comment.body = "Plugin: name" + mock_list_comments_resp = mocker.MagicMock() + mock_list_comments_resp.parsed_data = [mock_comment] + + mock_pull = mocker.MagicMock() + mock_pull.number = 2 + mock_pulls_resp = mocker.MagicMock() + mock_pulls_resp.parsed_data = mock_pull + + mock_test_result = mocker.MagicMock() + mock_test_result.metadata = Metadata( + name="name", + desc="desc", + homepage="https://nonebot.dev", + type="application", + supported_adapters=None, + ) + mock_test_result.load = True + mock_test_result.version = "1.0.0" + mock_test_result.output = "" + mock_docker = mocker.patch("src.providers.docker_test.DockerPluginTest.run") + mock_docker.return_value = mock_test_result + + with open(tmp_path / "plugins.json5", "w") as f: + json.dump([], f) + + check_json_data(plugin_config.input_config.plugin_path, []) + + async with app.test_matcher() as ctx: + adapter, bot = get_github_bot(ctx) + event = get_mock_event(IssuesOpened) + event.payload.issue.labels = get_issue_labels(["Plugin", "Publish"]) + + ctx.receive_event(bot, event) + should_call_apis( + ctx, + [ + { + "api": "rest.apps.async_get_repo_installation", + "result": mock_installation, + }, + { + "api": "rest.issues.async_get", + "result": mock_issues_resp, + }, + { + "api": "rest.issues.async_update", + "result": None, + }, + { + "api": "rest.issues.async_list_comments", + "result": mock_list_comments_resp, + }, + { + "api": "rest.issues.async_update", + "result": None, + }, + { + "api": "rest.issues.async_list_comments", + "result": mock_list_comments_resp, + }, + { + "api": "rest.issues.async_create_comment", + "result": None, + }, + { + "api": "rest.issues.async_update", + "result": None, + }, + { + "api": "rest.pulls.async_create", + "result": mock_pulls_resp, + }, + { + "api": "rest.issues.async_add_labels", + "result": None, + }, + ], + snapshot( + { + 0: {"owner": "he0119", "repo": "action-test"}, + 1: {"owner": "he0119", "repo": "action-test", "issue_number": 80}, + 2: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 80, + "body": """\ +### PyPI 项目名 + +project_link + +### 插件 import 包名 + +module_name + +### 标签 + +[{"label": "test", "color": "#ffffff"}] + +### 插件配置项 + +```dotenv +log_level=DEBUG +``` + +### 插件测试 + +- [x] 🔥插件测试中,请稍后\ +""", + }, + 3: {"owner": "he0119", "repo": "action-test", "issue_number": 80}, + 4: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 80, + "body": """\ +### PyPI 项目名 + +project_link + +### 插件 import 包名 + +module_name + +### 标签 + +[{"label": "test", "color": "#ffffff"}] + +### 插件配置项 + +```dotenv +log_level=DEBUG +``` + +### 插件测试 + +- [ ] 如需重新运行插件测试,请勾选左侧勾选框\ +""", + }, + 5: {"owner": "he0119", "repo": "action-test", "issue_number": 80}, + 6: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 80, + "body": """\ +# 📃 商店发布检查结果 + +> Plugin: name + +**✅ 所有测试通过,一切准备就绪!** + + +
    +详情 +
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 项目 project_link 已发布至 PyPI。
  • ✅ 标签: test-#ffffff。
  • ✅ 插件类型: application。
  • ✅ 插件支持的适配器: 所有。
  • ✅ 插件 加载测试 通过。
  • ✅ 版本号: 1.0.0。
  • ✅ 发布时间:2023-09-01 08:00:00 CST。
  • +
    + +--- + +💡 如需修改信息,请直接修改 issue,机器人会自动更新检查结果。 +💡 当插件加载测试失败时,请发布新版本后勾选插件测试勾选框重新运行插件测试。 + +♻️ 评论已更新至最新检查结果 + +💪 Powered by [NoneFlow](https://github.com/nonebot/noneflow) + +""", + }, + 7: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 80, + "title": "Plugin: name", + }, + 8: { + "owner": "he0119", + "repo": "action-test", + "title": "Plugin: name", + "body": "resolve #80", + "base": "master", + "head": "publish/issue80", + }, + 9: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 2, + "labels": ["Publish", "Plugin"], + }, + } + ), + ) + + # 测试 git 命令 + assert_subprocess_run_calls( + mock_subprocess_run, + [ + ["git", "config", "--global", "safe.directory", "*"], + ["git", "switch", "-C", "publish/issue80"], + ["git", "ls-remote", "--heads", "origin", "publish/issue80"], + ["git", "config", "--global", "user.name", "test"], + [ + "git", + "config", + "--global", + "user.email", + "test@users.noreply.github.com", + ], + ["git", "add", "-A"], + ["git", "commit", "-m", ":beers: publish plugin name (#80)"], + ["git", "fetch", "origin"], + ["git", "diff", "origin/publish/issue80", "publish/issue80"], + ["git", "push", "origin", "publish/issue80", "-f"], + ], + ) + + # 检查文件是否正确 + check_json_data( + plugin_config.input_config.plugin_path, + [ + snapshot( + { + "module_name": "module_name", + "project_link": "project_link", + "author_id": 1, + "tags": [{"label": "test", "color": "#ffffff"}], + "is_official": False, + } + ) + ], + ) + + assert mocked_api["homepage"].called + mock_docker.assert_called_once_with("3.12") + + +async def test_plugin_process_publish_check_re_run( + app: App, + mocker: MockerFixture, + mocked_api: MockRouter, + tmp_path: Path, + mock_installation, +) -> None: + """测试插件的发布流程,重新运行插件测试""" + from src.plugins.github import plugin_config + from src.providers.docker_test import Metadata + + mock_subprocess_run = mock_subprocess_run_with_side_effect(mocker) + + # 这次运行时,议题内容已经包含了插件测试按钮 + mock_issue = MockIssue( + body=MockBody(type="plugin", test_button=True).generate() + ).as_mock() + + mock_event = mocker.MagicMock() + mock_event.issue = mock_issue + + mock_issues_resp = mocker.MagicMock() + mock_issues_resp.parsed_data = mock_issue + + mock_comment = mocker.MagicMock() + mock_comment.body = "Plugin: name" + mock_list_comments_resp = mocker.MagicMock() + mock_list_comments_resp.parsed_data = [mock_comment] + + mock_pull = mocker.MagicMock() + mock_pull.number = 2 + mock_pulls_resp = mocker.MagicMock() + mock_pulls_resp.parsed_data = mock_pull + + mock_test_result = mocker.MagicMock() + mock_test_result.metadata = Metadata( + name="name", + desc="desc", + homepage="https://nonebot.dev", + type="application", + supported_adapters=None, + ) + mock_test_result.load = True + mock_test_result.version = "1.0.0" + mock_test_result.output = "" + mock_docker = mocker.patch("src.providers.docker_test.DockerPluginTest.run") + mock_docker.return_value = mock_test_result + + with open(tmp_path / "plugins.json5", "w") as f: + json.dump([], f) + + check_json_data(plugin_config.input_config.plugin_path, []) + + async with app.test_matcher() as ctx: + adapter, bot = get_github_bot(ctx) + event = get_mock_event(IssuesOpened) + event.payload.issue.labels = get_issue_labels(["Plugin", "Publish"]) + + ctx.receive_event(bot, event) + should_call_apis( + ctx, + [ + { + "api": "rest.apps.async_get_repo_installation", + "result": mock_installation, + }, + { + "api": "rest.issues.async_get", + "result": mock_issues_resp, + }, + { + "api": "rest.issues.async_update", + "result": None, + }, + { + "api": "rest.issues.async_list_comments", + "result": mock_list_comments_resp, + }, + { + "api": "rest.issues.async_update", + "result": None, + }, + { + "api": "rest.issues.async_list_comments", + "result": mock_list_comments_resp, + }, + { + "api": "rest.issues.async_create_comment", + "result": None, + }, + { + "api": "rest.issues.async_update", + "result": None, + }, + { + "api": "rest.pulls.async_create", + "result": mock_pulls_resp, + }, + { + "api": "rest.issues.async_add_labels", + "result": None, + }, + ], + snapshot( + { + 0: {"owner": "he0119", "repo": "action-test"}, + 1: {"owner": "he0119", "repo": "action-test", "issue_number": 80}, + 2: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 80, + "body": """\ +### PyPI 项目名 + +project_link + +### 插件 import 包名 + +module_name + +### 标签 + +[{"label": "test", "color": "#ffffff"}] + +### 插件配置项 + +```dotenv +log_level=DEBUG +``` + +### 插件测试 + +- [x] 🔥插件测试中,请稍后\ +""", + }, + 3: {"owner": "he0119", "repo": "action-test", "issue_number": 80}, + 4: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 80, + "body": """\ +### PyPI 项目名 + +project_link + +### 插件 import 包名 + +module_name + +### 标签 + +[{"label": "test", "color": "#ffffff"}] + +### 插件配置项 + +```dotenv +log_level=DEBUG +``` + +### 插件测试 + +- [ ] 如需重新运行插件测试,请勾选左侧勾选框\ +""", + }, + 5: {"owner": "he0119", "repo": "action-test", "issue_number": 80}, + 6: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 80, + "body": """\ +# 📃 商店发布检查结果 + +> Plugin: name + +**✅ 所有测试通过,一切准备就绪!** + + +
    +详情 +
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 项目 project_link 已发布至 PyPI。
  • ✅ 标签: test-#ffffff。
  • ✅ 插件类型: application。
  • ✅ 插件支持的适配器: 所有。
  • ✅ 插件 加载测试 通过。
  • ✅ 版本号: 1.0.0。
  • ✅ 发布时间:2023-09-01 08:00:00 CST。
  • +
    + +--- + +💡 如需修改信息,请直接修改 issue,机器人会自动更新检查结果。 +💡 当插件加载测试失败时,请发布新版本后勾选插件测试勾选框重新运行插件测试。 + +♻️ 评论已更新至最新检查结果 + +💪 Powered by [NoneFlow](https://github.com/nonebot/noneflow) + +""", + }, + 7: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 80, + "title": "Plugin: name", + }, + 8: { + "owner": "he0119", + "repo": "action-test", + "title": "Plugin: name", + "body": "resolve #80", + "base": "master", + "head": "publish/issue80", + }, + 9: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 2, + "labels": ["Publish", "Plugin"], + }, + } + ), + ) + + # 测试 git 命令 + assert_subprocess_run_calls( + mock_subprocess_run, + [ + ["git", "config", "--global", "safe.directory", "*"], + ["git", "switch", "-C", "publish/issue80"], + ["git", "ls-remote", "--heads", "origin", "publish/issue80"], + ["git", "config", "--global", "user.name", "test"], + [ + "git", + "config", + "--global", + "user.email", + "test@users.noreply.github.com", + ], + ["git", "add", "-A"], + ["git", "commit", "-m", ":beers: publish plugin name (#80)"], + ["git", "fetch", "origin"], + ["git", "diff", "origin/publish/issue80", "publish/issue80"], + ["git", "push", "origin", "publish/issue80", "-f"], + ], + ) + + # 检查文件是否正确 + check_json_data( + plugin_config.input_config.plugin_path, + [ + snapshot( + { + "module_name": "module_name", + "project_link": "project_link", + "author_id": 1, + "tags": [{"label": "test", "color": "#ffffff"}], + "is_official": False, + } + ) + ], + ) + + assert mocked_api["homepage"].called + mock_docker.assert_called_once_with("3.12") + + +async def test_plugin_process_publish_check_missing_metadata( + app: App, + mocker: MockerFixture, + mocked_api: MockRouter, + tmp_path: Path, + mock_installation, +) -> None: + """测试发布检查不通过,测试缺少插件元数据""" + from src.plugins.github import plugin_config + + mock_subprocess_run = mock_subprocess_run_with_side_effect(mocker) + + mock_issue = MockIssue( + title="Plugin: test", + body=generate_issue_body_plugin(), + ).as_mock() + + mock_issues_resp = mocker.MagicMock() + mock_issues_resp.parsed_data = mock_issue + + mock_pulls_resp = mocker.MagicMock() + mock_pulls_resp.parsed_data = [] + + mock_comment = mocker.MagicMock() + mock_comment.body = "Plugin: test" + mock_list_comments_resp = mocker.MagicMock() + mock_list_comments_resp.parsed_data = [mock_comment] + + mock_test_result = mocker.MagicMock() + mock_test_result.metadata = None + mock_test_result.load = True + mock_test_result.version = "1.0.0" + mock_test_result.output = "" + mock_docker = mocker.patch("src.providers.docker_test.DockerPluginTest.run") + mock_docker.return_value = mock_test_result + + with open(tmp_path / "plugins.json5", "w") as f: + json.dump([], f) + + check_json_data(plugin_config.input_config.plugin_path, []) + + async with app.test_matcher() as ctx: + adapter, bot = get_github_bot(ctx) + event = get_mock_event(IssuesOpened) + event.payload.issue.labels = get_issue_labels(["Plugin", "Publish"]) + + ctx.receive_event(bot, event) + should_call_apis( + ctx, + [ + { + "api": "rest.apps.async_get_repo_installation", + "result": mock_installation, + }, + { + "api": "rest.issues.async_get", + "result": mock_issues_resp, + }, + { + "api": "rest.issues.async_update", + "result": None, + }, + { + "api": "rest.issues.async_list_comments", + "result": mock_list_comments_resp, + }, + { + "api": "rest.issues.async_update", + "result": None, + }, + { + "api": "rest.issues.async_list_comments", + "result": mock_list_comments_resp, + }, + { + "api": "rest.issues.async_create_comment", + "result": None, + }, + { + "api": "rest.issues.async_update", + "result": None, + }, + { + "api": "rest.pulls.async_list", + "result": mock_pulls_resp, + }, + ], + snapshot( + { + 0: {"owner": "he0119", "repo": "action-test"}, + 1: {"owner": "he0119", "repo": "action-test", "issue_number": 80}, + 2: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 80, + "body": """\ +### PyPI 项目名 + +project_link + +### 插件 import 包名 + +module_name + +### 标签 + +[{"label": "test", "color": "#ffffff"}] + +### 插件配置项 + +```dotenv +log_level=DEBUG +``` + +### 插件测试 + +- [x] 🔥插件测试中,请稍后\ +""", + }, + 3: {"owner": "he0119", "repo": "action-test", "issue_number": 80}, + 4: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 80, + "body": """\ +### PyPI 项目名 + +project_link + +### 插件 import 包名 + +module_name + +### 标签 + +[{"label": "test", "color": "#ffffff"}] + +### 插件配置项 + +```dotenv +log_level=DEBUG +``` + +### 插件测试 + +- [ ] 如需重新运行插件测试,请勾选左侧勾选框\ +""", + }, + 5: {"owner": "he0119", "repo": "action-test", "issue_number": 80}, + 6: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 80, + "body": """\ +# 📃 商店发布检查结果 + +> Plugin: project_link + +**⚠️ 在发布检查过程中,我们发现以下问题:** + +
  • ⚠️ 无法获取到插件元数据。
    请确保插件正常加载。
  • + +
    +详情 +
  • ✅ 项目 project_link 已发布至 PyPI。
  • ✅ 标签: test-#ffffff。
  • ✅ 插件 加载测试 通过。
  • ✅ 版本号: 1.0.0。
  • ✅ 发布时间:2023-09-01 08:00:00 CST。
  • +
    + +--- + +💡 如需修改信息,请直接修改 issue,机器人会自动更新检查结果。 +💡 当插件加载测试失败时,请发布新版本后勾选插件测试勾选框重新运行插件测试。 + +♻️ 评论已更新至最新检查结果 + +💪 Powered by [NoneFlow](https://github.com/nonebot/noneflow) + +""", + }, + 7: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 80, + "title": "Plugin: project_link", + }, + 8: { + "owner": "he0119", + "repo": "action-test", + "head": "he0119:publish/issue80", + }, + } + ), + ) + + # 测试 git 命令 + assert_subprocess_run_calls( + mock_subprocess_run, + [ + ["git", "config", "--global", "safe.directory", "*"], + ], + ) + + # 检查文件是否正确 + check_json_data(plugin_config.input_config.plugin_path, []) + + assert not mocked_api["homepage"].called + + +async def test_skip_plugin_check( + app: App, + mocker: MockerFixture, + mocked_api: MockRouter, + tmp_path: Path, + mock_installation, +) -> None: + """测试手动跳过插件测试的流程""" + from src.plugins.github import plugin_config + + mock_subprocess_run = mock_subprocess_run_with_side_effect(mocker) + + mock_issue = MockIssue(number=70, body=MockBody("plugin").generate()).as_mock() + + mock_event = mocker.MagicMock() + mock_event.issue = mock_issue + + mock_issues_resp = mocker.MagicMock() + mock_issues_resp.parsed_data = mock_issue + + mock_comment = mocker.MagicMock() + mock_comment.body = "/skip" + mock_comment.author_association = "OWNER" + mock_list_comments_resp = mocker.MagicMock() + mock_list_comments_resp.parsed_data = [mock_comment] + + mock_pulls_resp = mocker.MagicMock() + mock_pulls_resp.parsed_data = [] + + with open(tmp_path / "plugins.json5", "w") as f: + json.dump([], f) + + check_json_data(plugin_config.input_config.plugin_path, []) + + async with app.test_matcher() as ctx: + adapter, bot = get_github_bot(ctx) + event = get_mock_event(IssueCommentCreated, "issue-comment-skip") + + ctx.receive_event(bot, event) + should_call_apis( + ctx, + [ + # 获取安装信息 + { + "api": "rest.apps.async_get_repo_installation", + "result": mock_installation, + }, + # 获取议题信息 + { + "api": "rest.issues.async_get", + "result": mock_issues_resp, + }, + { + "api": "rest.issues.async_update", + "result": None, + }, + { + "api": "rest.issues.async_list_comments", + "result": mock_list_comments_resp, + }, + { + "api": "rest.issues.async_update", + "result": None, + }, + { + "api": "rest.issues.async_update", + "result": None, + }, + { + "api": "rest.issues.async_list_comments", + "result": mock_list_comments_resp, + }, + { + "api": "rest.issues.async_create_comment", + "result": None, + }, + { + "api": "rest.issues.async_update", + "result": None, + }, + { + "api": "rest.pulls.async_list", + "result": mock_pulls_resp, + }, + ], + snapshot( + { + 0: {"owner": "he0119", "repo": "action-test"}, + 1: {"owner": "he0119", "repo": "action-test", "issue_number": 70}, + 2: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 70, + "body": """\ +### PyPI 项目名 + +project_link + +### 插件 import 包名 + +module_name + +### 标签 + +[{"label": "test", "color": "#ffffff"}] + +### 插件配置项 + +```dotenv +log_level=DEBUG +``` + +### 插件测试 + +- [x] 🔥插件测试中,请稍后\ +""", + }, + 3: {"owner": "he0119", "repo": "action-test", "issue_number": 70}, + 4: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 70, + "body": """\ +### 插件名称 + +### 插件描述 + +### 插件项目仓库/主页链接 + +### 插件类型 + +### 插件支持的适配器 + +### PyPI 项目名 + +project_link + +### 插件 import 包名 + +module_name + +### 标签 + +[{"label": "test", "color": "#ffffff"}] + +### 插件配置项 + +```dotenv +log_level=DEBUG +``` + +### 插件测试 + +- [x] 🔥插件测试中,请稍后\ +""", + }, + 5: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 70, + "body": """\ +### 插件名称 + +### 插件描述 + +### 插件项目仓库/主页链接 + +### 插件类型 + +### 插件支持的适配器 + +### PyPI 项目名 + +project_link + +### 插件 import 包名 + +module_name + +### 标签 + +[{"label": "test", "color": "#ffffff"}] + +### 插件配置项 + +```dotenv +log_level=DEBUG +``` + +### 插件测试 + +- [ ] 如需重新运行插件测试,请勾选左侧勾选框\ +""", + }, + 6: {"owner": "he0119", "repo": "action-test", "issue_number": 70}, + 7: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 70, + "body": """\ +# 📃 商店发布检查结果 + +> Plugin: project_link + +**⚠️ 在发布检查过程中,我们发现以下问题:** + +
  • ⚠️ 名称: 无法匹配到数据。
    请确保填写该数据项。
  • ⚠️ 描述: 无法匹配到数据。
    请确保填写该数据项。
  • ⚠️ 项目仓库/主页链接: 无法匹配到数据。
    请确保填写该数据项。
  • ⚠️ 插件类型: 无法匹配到数据。
    请确保填写该数据项。
  • ⚠️ 插件支持的适配器: 无法匹配到数据。
    请确保填写该数据项。
  • ⚠️ 无法获取到插件元数据。
    请确保插件正常加载。
  • + +
    +详情 +
  • ✅ 项目 project_link 已发布至 PyPI。
  • ✅ 标签: test-#ffffff。
  • ✅ 插件 加载测试 已跳过。
  • ✅ 版本号: 0.0.1。
  • ✅ 发布时间:2023-09-01 08:00:00 CST。
  • +
    + +--- + +💡 如需修改信息,请直接修改 issue,机器人会自动更新检查结果。 +💡 当插件加载测试失败时,请发布新版本后勾选插件测试勾选框重新运行插件测试。 + +♻️ 评论已更新至最新检查结果 + +💪 Powered by [NoneFlow](https://github.com/nonebot/noneflow) + +""", + }, + 8: { + "owner": "he0119", + "repo": "action-test", + "issue_number": 70, + "title": "Plugin: project_link", + }, + 9: { + "owner": "he0119", + "repo": "action-test", + "head": "he0119:publish/issue70", + }, + } + ), + ) + + # 测试 git 命令 + assert_subprocess_run_calls( + mock_subprocess_run, + [ + ["git", "config", "--global", "safe.directory", "*"], + ], + ) + + # 检查文件是否正确 + check_json_data(plugin_config.input_config.plugin_path, []) + + assert mocked_api["pypi_project_link"].called diff --git a/tests/plugins/github/publish/render/test_publish_render.py b/tests/plugins/github/publish/render/test_publish_render.py index ad9ded06..d2861800 100644 --- a/tests/plugins/github/publish/render/test_publish_render.py +++ b/tests/plugins/github/publish/render/test_publish_render.py @@ -1,15 +1,18 @@ from inline_snapshot import snapshot from nonebug import App +from tests.providers.validation.utils import generate_bot_data + async def test_render_empty(app: App): """测试没有数据和错误时的输出""" from src.plugins.github.plugins.publish.render import render_comment - from src.providers.validation import PublishType, ValidationDict + from src.providers.validation import BotPublishInfo, PublishType, ValidationDict result = ValidationDict( type=PublishType.BOT, raw_data={"name": "name"}, + info=BotPublishInfo.model_construct(**generate_bot_data()), ) comment = await render_comment(result) @@ -38,11 +41,12 @@ async def test_render_empty(app: App): async def test_render_reuse(app: App): """复用评论""" from src.plugins.github.plugins.publish.render import render_comment - from src.providers.validation import PublishType, ValidationDict + from src.providers.validation import BotPublishInfo, PublishType, ValidationDict result = ValidationDict( type=PublishType.BOT, raw_data={"name": "name"}, + info=BotPublishInfo.model_construct(**generate_bot_data()), ) comment = await render_comment(result, True) diff --git a/tests/plugins/github/publish/render/test_publish_render_data.py b/tests/plugins/github/publish/render/test_publish_render_data.py index 2fac3e94..56ea8688 100644 --- a/tests/plugins/github/publish/render/test_publish_render_data.py +++ b/tests/plugins/github/publish/render/test_publish_render_data.py @@ -2,6 +2,8 @@ from nonebug import App from pytest_mock import MockFixture +from tests.providers.validation.utils import generate_plugin_data + async def test_render_data_bot(app: App): """机器人验证数据""" @@ -211,7 +213,7 @@ async def test_render_data_plugin(app: App, mocker: MockFixture): async def test_render_data_plugin_supported_adapters(app: App, mocker: MockFixture): """插件支持的适配器""" from src.plugins.github.plugins.publish.render import render_comment - from src.providers.validation import PublishType, ValidationDict + from src.providers.validation import PluginPublishInfo, PublishType, ValidationDict result = ValidationDict( type=PublishType.PLUGIN, @@ -228,7 +230,7 @@ async def test_render_data_plugin_supported_adapters(app: App, mocker: MockFixtu "load": True, "skip_test": False, }, - info=None, + info=PluginPublishInfo.model_construct(**generate_plugin_data()), errors=[], ) diff --git a/tests/plugins/github/utils.py b/tests/plugins/github/utils.py index 2e77dda2..f6221d4c 100644 --- a/tests/plugins/github/utils.py +++ b/tests/plugins/github/utils.py @@ -204,8 +204,11 @@ class MockIssue: pull_request: Any = None user: MockUser = field(default_factory=MockUser) - def as_mock(self, mocker: MockFixture): - mocker_issue = mocker.MagicMock(spec=Issue) + def as_mock(self, mocker: MockFixture | None = None): + if mocker is None: + mocker_issue = MagicMock(spec=Issue) + else: + mocker_issue = mocker.MagicMock(spec=Issue) mocker_issue.configure_mock(**self.__dict__) return mocker_issue diff --git a/tests/providers/store_test/test_validate_plugin.py b/tests/providers/store_test/test_validate_plugin.py index c3a27e2f..0024fa38 100644 --- a/tests/providers/store_test/test_validate_plugin.py +++ b/tests/providers/store_test/test_validate_plugin.py @@ -324,14 +324,45 @@ async def test_validate_plugin_skip_test_plugin_test_failed( StoreTestResult( config="", outputs={ - "validation": None, + "validation": { + "data": { + "module_name": "nonebot_plugin_treehelp", + "project_link": "nonebot-plugin-treehelp", + "time": "2024-07-13T04:41:40.905441Z", + "version": "0.3.9", + "name": "帮助", + "desc": "获取插件帮助信息", + "author": "he0119", + "author_id": 1, + "homepage": "https://nonebot.dev/", + "tags": [], + "is_official": False, + "type": "application", + "supported_adapters": None, + "load": True, + "skip_test": True, + "test_output": """\ +创建测试目录 plugin_test + For further information visit https://errors.pydantic.dev/2.9/v/model_type\x1b[0m\ +""", + }, + "errors": [ + { + "type": "plugin.metadata", + "loc": ("metadata",), + "msg": "无法获取到插件元数据", + "input": False, + "ctx": {"load": None}, + } + ], + }, "load": """\ 创建测试目录 plugin_test For further information visit https://errors.pydantic.dev/2.9/v/model_type\x1b[0m\ """, "metadata": None, }, - results={"validation": True, "load": False, "metadata": False}, + results={"validation": False, "load": False, "metadata": False}, test_env={"python==3.12.7": True}, version="0.3.9", ) @@ -350,7 +381,7 @@ async def test_validate_plugin_skip_test_plugin_test_failed( tags=[], time="2024-07-13T04:41:40.905441Z", type="application", - valid=True, + valid=False, version="0.3.9", ) ) @@ -424,7 +455,6 @@ async def test_validate_plugin_failed_with_previous( "is_official": True, "type": "application", "supported_adapters": None, - "metadata": False, "skip_test": False, "version": "0.3.9", "test_output": """\ @@ -444,7 +474,14 @@ async def test_validate_plugin_failed_with_previous( For further information visit https://errors.pydantic.dev/2.9/v/model_type\x1b[0m\ """ }, - } + }, + { + "type": "plugin.metadata", + "loc": ("metadata",), + "msg": "无法获取到插件元数据", + "input": False, + "ctx": {"load": None}, + }, ], }, "load": """\ diff --git a/tests/providers/validation/fields/test_missing.py b/tests/providers/validation/fields/test_missing.py index d3b67008..b1c9a314 100644 --- a/tests/providers/validation/fields/test_missing.py +++ b/tests/providers/validation/fields/test_missing.py @@ -33,7 +33,6 @@ async def test_fields_missing_plugin(mocked_api: MockRouter) -> None: "author_id": 1, "tags": [{"label": "test", "color": "#ffffff"}], "supported_adapters": None, - "metadata": False, "skip_test": False, "test_output": "error", } @@ -138,6 +137,13 @@ async def test_fields_missing_plugin(mocked_api: MockRouter) -> None: "input": False, "ctx": {"output": "error"}, }, + { + "type": "plugin.metadata", + "loc": ("metadata",), + "msg": "无法获取到插件元数据", + "input": False, + "ctx": {"load": None}, + }, ] ) diff --git a/tests/providers/validation/test_plugin.py b/tests/providers/validation/test_plugin.py index 35def94a..d3949eaf 100644 --- a/tests/providers/validation/test_plugin.py +++ b/tests/providers/validation/test_plugin.py @@ -155,7 +155,14 @@ async def test_plugin_info_validation_plugin_load_failed( "msg": "插件无法正常加载", "input": False, "ctx": {"output": "test_output"}, - } + }, + { + "type": "plugin.metadata", + "loc": ("metadata",), + "msg": "无法获取到插件元数据", + "input": False, + "ctx": {"load": None}, + }, ], info=None, raw_data={ @@ -189,7 +196,6 @@ async def test_plugin_info_validation_plugin_load_failed( "tags": [{"label": "test", "color": "#ffffff"}], "type": "application", "supported_adapters": None, - "metadata": False, "skip_test": False, "version": "0.0.1", "test_output": "test_output",