RepoAuditor 0.2.34__tar.gz → 0.2.37__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/workflows/CICD_impl.yml +1 -1
- {repoauditor-0.2.34 → repoauditor-0.2.37}/PKG-INFO +2 -2
- {repoauditor-0.2.34 → repoauditor-0.2.37}/pyproject.toml +1 -1
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/EntryPoint.py +35 -24
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/ExecuteModules.py +2 -2
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Impl/ParallelSequentialProcessor.py +5 -5
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals.py +1 -1
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush.py +1 -1
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovals.py +1 -1
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireCodeOwnerReview.py +1 -1
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireUpToDateBranches.py +1 -1
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Description.py +2 -3
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashCommitMerge.py +2 -1
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/__init__.py +1 -1
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/EntryPoint_UnitTest.py +39 -1
- repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionQuery_UnitTest.py +98 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals_UnitTest.py +75 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/EnsureStatusChecks_UnitTest.py +89 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush_UnitTest.py +77 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireApprovals_UnitTest.py +88 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireCodeOwnerReview_UnitTest.py +90 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireUpToDateBranches_UnitTest.py +76 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicValueRequirementImpl_UnitTest.py +37 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/DefaultBranchQueryRequirements/Protected_UnitTest.py +64 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/DefaultBranchQuery_UnitTest.py +61 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/GitHubModule_UnitTest.py +35 -0
- repoauditor-0.2.34/tests/Plugins/GitHubModule_UnitTest.py → repoauditor-0.2.37/tests/Plugins/GitHubModule/GitHubSession_UnitTest.py +1 -23
- repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/DependabotSecurityUpdates_UnitTest.py +81 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/Description_UnitTest.py +66 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/License_UnitTest.py +63 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/MergeCommitMessage_UnitTest.py +74 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/Private_UnitTest.py +80 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/SecretScanningPushProtection_UnitTest.py +78 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/SecretScanning_UnitTest.py +76 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/SquashMergeCommitMessage_UnitTest.py +72 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQuery_UnitTest.py +61 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/ValueRequrementImpl_UnitTest.py +105 -0
- repoauditor-0.2.37/tests/Plugins/GitHubModule/conftest.py +22 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/uv.lock +35 -9
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.copier-answers.yml +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/CODEOWNERS +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/ISSUE_TEMPLATE/custom.md +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/actions/release_impl/action.yml +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/pull_request_template.md +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/release_sources.yaml +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/workflows/CICD.yml +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/workflows/EndToEnd.yml +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/workflows/codeql.yml +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.gitignore +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.pre-commit-config.yaml +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/.python-version +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/CODE_OF_CONDUCT.md +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/CONTRIBUTING.md +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/DEVELOPMENT.md +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/GOVERNANCE.md +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/LICENSE +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/MAINTAINERS.md +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/README.md +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/SECURITY.md +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/minisign_key.pub +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/AutoGitSemVer.yaml +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/CommandLineProcessor.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Display.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Impl/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Module.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugin.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionQuery.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowDeletions.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowForcePushes.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DoNotAllowBypassSettings.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/EnsureStatusChecks.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicEnableRequirementImpl.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicValueRequirementImpl.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireConversationResolution.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireLinearHistory.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequirePullRequests.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireSignedCommits.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireStatusChecksToPass.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQuery.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/Protected.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/Impl/Common.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/Impl/EnableRequirementImpl.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/Impl/ValueRequirementImpl.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/Impl/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/Module.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQuery.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/AutoMerge.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DefaultBranch.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DeleteHeadBranches.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DependabotSecurityUpdates.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardEnableRequirementImpl.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardValueRequirementImpl.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/License.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommit.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommitMessage.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Private.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/RebaseMergeCommit.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanning.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanningPushProtection.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashMergeCommitMessage.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SuggestUpdatingPullRequestBranches.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportDiscussions.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportIssues.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportProjects.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportWikis.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/TemplateRepository.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/WebCommitSignoff.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubBase/Module.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubBase/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/CustomizationQuery.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Impl/ExistsRequirementImpl.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Impl/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Module.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/CodeOwners.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/Contributing.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/IssueTemplates.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/PullRequestTemplates.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/SecurityPolicy.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomizationPlugin.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubPlugin.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Impl/EnableRulesetRequirementImpl.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Impl/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Module.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequirePullRequests.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequireSignedCommits.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequireStatusChecks.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/RulesetQuery.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesetsPlugin.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Query.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Requirement.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/py.typed +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/src/github_auditor/__init__.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/CommandLineProcessor_UnitTest.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/ExecuteModules_UnitTest.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Module_UnitTest.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugin_UnitTest.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/GitHubCustomization_EndToEndTest.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/GitHubCustomization_UnitTest.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/GitHubRuleset_EndToEndTest.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/GitHubRuleset_UnitTest.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/GitHub_EndToEndTest.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/__snapshots__/GitHubCustomization_EndToEndTest.ambr +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/__snapshots__/GitHubRuleset_EndToEndTest.ambr +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/__snapshots__/GitHub_EndToEndTest.ambr +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/utilities.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Query_UnitTest.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Requirement_UnitTest.py +0 -0
- {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/__snapshots__/ExecuteModules_UnitTest.ambr +0 -0
|
@@ -70,7 +70,7 @@ jobs:
|
|
|
70
70
|
run: uv run pre-commit run --verbose
|
|
71
71
|
|
|
72
72
|
- name: Validate Tests
|
|
73
|
-
run: uv run pytest -k 'not EndToEndTest' --cov-fail-under=
|
|
73
|
+
run: uv run pytest -k 'not EndToEndTest' --cov-fail-under=95.0
|
|
74
74
|
env:
|
|
75
75
|
COVERAGE_FILE: .coverage.${{ matrix.os }}.${{ matrix.python_version }}
|
|
76
76
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: RepoAuditor
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.37
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Project-URL: Homepage, https://github.com/gt-sse-center/RepoAuditor
|
|
6
6
|
Project-URL: Documentation, https://github.com/gt-sse-center/RepoAuditor
|
|
@@ -17,7 +17,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
|
-
Requires-Dist: dbrownell-common>=0.14.
|
|
20
|
+
Requires-Dist: dbrownell-common>=0.14.10
|
|
21
21
|
Requires-Dist: pluggy>=1.5.0
|
|
22
22
|
Requires-Dist: requests>=2.32.3
|
|
23
23
|
Requires-Dist: typer>=0.15.3
|
|
@@ -35,9 +35,9 @@ class NaturalOrderGrouper(TyperGroup):
|
|
|
35
35
|
"""Group commands in natural order."""
|
|
36
36
|
|
|
37
37
|
# ----------------------------------------------------------------------
|
|
38
|
-
def list_commands(self, *args, **kwargs) -> list[str]: # noqa: ARG002
|
|
38
|
+
def list_commands(self, *args, **kwargs) -> list[str]: # noqa: ARG002 # pragma: no cover
|
|
39
39
|
"""Return a list of all the commands, to be sorted in a natural ordering."""
|
|
40
|
-
return self.commands.keys()
|
|
40
|
+
return list(self.commands.keys())
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
# ----------------------------------------------------------------------
|
|
@@ -64,31 +64,42 @@ _all_modules = _GetModules()
|
|
|
64
64
|
del _GetModules
|
|
65
65
|
|
|
66
66
|
|
|
67
|
+
# ----------------------------------------------------------------------
|
|
68
|
+
def TypeInfoToString(
|
|
69
|
+
arg_name: str,
|
|
70
|
+
type_info: TyperEx.TypeDefinitionItemType,
|
|
71
|
+
) -> str:
|
|
72
|
+
"""Convert type information from command line arguments to a string representation.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
arg_name (str): The name of the command line argument.
|
|
76
|
+
type_info (TyperEx.TypeDefinitionItemType): Type information for the accepted value.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
str: String description of the command line argument.
|
|
80
|
+
|
|
81
|
+
"""
|
|
82
|
+
if isinstance(type_info, TyperEx.TypeDefinitionItem):
|
|
83
|
+
python_type = type_info.python_type
|
|
84
|
+
parameter_info = type_info.parameter_info
|
|
85
|
+
elif isinstance(type_info, tuple):
|
|
86
|
+
python_type = type_info[0]
|
|
87
|
+
parameter_info = type_info[1]
|
|
88
|
+
else:
|
|
89
|
+
python_type = type_info
|
|
90
|
+
parameter_info = None
|
|
91
|
+
|
|
92
|
+
return " {arg_name:<50} {type_description:<7} {help}".format(
|
|
93
|
+
arg_name=arg_name,
|
|
94
|
+
type_description=python_type.__name__,
|
|
95
|
+
help="" if parameter_info is None else parameter_info.help,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
67
99
|
# ----------------------------------------------------------------------
|
|
68
100
|
def _HelpEpilog() -> str:
|
|
69
101
|
content: list[str] = []
|
|
70
102
|
|
|
71
|
-
# ----------------------------------------------------------------------
|
|
72
|
-
def TypeInfoToString(
|
|
73
|
-
arg_name: str,
|
|
74
|
-
type_info: TyperEx.TypeDefinitionItemType,
|
|
75
|
-
) -> str:
|
|
76
|
-
if isinstance(type_info, TyperEx.TypeDefinitionItem):
|
|
77
|
-
python_type = type_info.python_type
|
|
78
|
-
parameter_info = type_info.parameter_info
|
|
79
|
-
elif isinstance(type_info, tuple):
|
|
80
|
-
python_type = type_info[0]
|
|
81
|
-
parameter_info = type_info[1]
|
|
82
|
-
else:
|
|
83
|
-
python_type = type_info
|
|
84
|
-
parameter_info = None
|
|
85
|
-
|
|
86
|
-
return " {arg_name:<50} {type_description:<7} {help}".format(
|
|
87
|
-
arg_name=arg_name,
|
|
88
|
-
type_description=python_type.__name__,
|
|
89
|
-
help="" if parameter_info is None else parameter_info.help,
|
|
90
|
-
)
|
|
91
|
-
|
|
92
103
|
# ----------------------------------------------------------------------
|
|
93
104
|
|
|
94
105
|
for module in _all_modules:
|
|
@@ -181,7 +192,7 @@ def _VersionCallback(value: bool) -> None: # noqa: FBT001
|
|
|
181
192
|
epilog=_HelpEpilog(),
|
|
182
193
|
no_args_is_help=False,
|
|
183
194
|
)
|
|
184
|
-
def EntryPoint( # noqa: PLR0913
|
|
195
|
+
def EntryPoint( # noqa: PLR0913 # pragma: no cover
|
|
185
196
|
ctx: typer.Context,
|
|
186
197
|
version: Annotated[ # noqa: ARG001, FBT002
|
|
187
198
|
bool,
|
|
@@ -151,7 +151,7 @@ def Execute(
|
|
|
151
151
|
# ----------------------------------------------------------------------
|
|
152
152
|
def Transform(
|
|
153
153
|
status: ExecuteTasks.Status,
|
|
154
|
-
) -> ExecuteTasks.
|
|
154
|
+
) -> ExecuteTasks.CompleteTransformResult:
|
|
155
155
|
# ----------------------------------------------------------------------
|
|
156
156
|
def OnStatus(num_completed: int, *args, **kwargs) -> None:
|
|
157
157
|
status.OnProgress(
|
|
@@ -169,7 +169,7 @@ def Execute(
|
|
|
169
169
|
ignore_warnings_module_names=ignore_warnings_module_names,
|
|
170
170
|
)
|
|
171
171
|
|
|
172
|
-
return ExecuteTasks.
|
|
172
|
+
return ExecuteTasks.CompleteTransformResult(evaluate_results, result_code, result_status)
|
|
173
173
|
|
|
174
174
|
# ----------------------------------------------------------------------
|
|
175
175
|
|
{repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Impl/ParallelSequentialProcessor.py
RENAMED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
from collections.abc import Callable
|
|
10
10
|
from enum import Enum, auto
|
|
11
|
-
from typing import Optional, TypeVar, cast
|
|
11
|
+
from typing import Optional, TypeVar, Union, cast
|
|
12
12
|
|
|
13
13
|
from dbrownell_Common import ExecuteTasks # type: ignore[import-untyped]
|
|
14
14
|
from dbrownell_Common.Streams.DoneManager import DoneManager # type: ignore[import-untyped]
|
|
@@ -87,18 +87,18 @@ def _Impl(
|
|
|
87
87
|
def Execute(
|
|
88
88
|
results_index: int,
|
|
89
89
|
item: ItemType,
|
|
90
|
-
) -> ExecuteTasks.
|
|
90
|
+
) -> ExecuteTasks.CompleteTransformResult:
|
|
91
91
|
return_code, result = calculate_result_func(item)
|
|
92
92
|
|
|
93
93
|
assert results[results_index] is None
|
|
94
94
|
results[results_index] = result
|
|
95
95
|
|
|
96
|
-
return ExecuteTasks.
|
|
96
|
+
return ExecuteTasks.CompleteTransformResult(None, return_code)
|
|
97
97
|
|
|
98
98
|
# ----------------------------------------------------------------------
|
|
99
99
|
|
|
100
100
|
if parallel:
|
|
101
|
-
transform_results: list[
|
|
101
|
+
transform_results: list[Union[None, object, Exception]] = ExecuteTasks.TransformTasks(
|
|
102
102
|
dm,
|
|
103
103
|
"Processing",
|
|
104
104
|
[
|
|
@@ -111,7 +111,7 @@ def _Impl(
|
|
|
111
111
|
)
|
|
112
112
|
|
|
113
113
|
for transform_result in transform_results:
|
|
114
|
-
if transform_result is not None:
|
|
114
|
+
if transform_result is not None and isinstance(transform_result, Exception):
|
|
115
115
|
raise transform_result
|
|
116
116
|
|
|
117
117
|
for sequential_index, (results_index, item) in enumerate(sequential):
|
|
@@ -73,11 +73,10 @@ class Description(Requirement):
|
|
|
73
73
|
) -> Requirement.EvaluateImplResult:
|
|
74
74
|
standard_data = query_data["standard"]
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
result = standard_data.get("description", None)
|
|
77
|
+
if result is None:
|
|
77
78
|
return CreateIncompleteDataResult()
|
|
78
79
|
|
|
79
|
-
result = standard_data["description"]
|
|
80
|
-
|
|
81
80
|
expect_description = not requirement_args["allow-empty"]
|
|
82
81
|
|
|
83
82
|
if expect_description and not result:
|
|
@@ -33,7 +33,8 @@ class SquashCommitMerge(StandardEnableRequirementImpl):
|
|
|
33
33
|
|
|
34
34
|
Reasons for this Default
|
|
35
35
|
------------------------
|
|
36
|
-
-
|
|
36
|
+
- When performing a Squash & Merge, GitHub creates a new merge commit with its key.
|
|
37
|
+
This makes it difficult to verify author signatures when looking at the commit history.
|
|
37
38
|
|
|
38
39
|
Reasons to Override this Default
|
|
39
40
|
--------------------------------
|
|
@@ -7,12 +7,14 @@
|
|
|
7
7
|
"""Unit tests for EntryPoint.py"""
|
|
8
8
|
|
|
9
9
|
import pytest
|
|
10
|
+
import typer
|
|
10
11
|
|
|
11
12
|
from dbrownell_Common.TestHelpers.StreamTestHelpers import InitializeStreamCapabilities
|
|
13
|
+
from dbrownell_Common.TyperEx import TypeDefinitionItem # type: ignore [import-untyped]
|
|
12
14
|
from typer.testing import CliRunner
|
|
13
15
|
|
|
14
16
|
from RepoAuditor import __version__
|
|
15
|
-
from RepoAuditor.EntryPoint import app
|
|
17
|
+
from RepoAuditor.EntryPoint import app, TypeInfoToString
|
|
16
18
|
|
|
17
19
|
from Plugins.utilities import GetGithubUrl
|
|
18
20
|
|
|
@@ -58,3 +60,39 @@ def test_Help() -> None:
|
|
|
58
60
|
|
|
59
61
|
assert result.exit_code == 0
|
|
60
62
|
assert "Module Information" in result.output
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test_TypeInfoToString() -> None:
|
|
66
|
+
"""Test the TypeInfoToString function to ensure valid command line output."""
|
|
67
|
+
result = TypeInfoToString(
|
|
68
|
+
"test_arg",
|
|
69
|
+
(
|
|
70
|
+
bool,
|
|
71
|
+
typer.Option(
|
|
72
|
+
False,
|
|
73
|
+
help="Help text.",
|
|
74
|
+
),
|
|
75
|
+
),
|
|
76
|
+
)
|
|
77
|
+
expected_string = " test_arg bool Help text."
|
|
78
|
+
assert expected_string == result
|
|
79
|
+
|
|
80
|
+
result = TypeInfoToString(
|
|
81
|
+
"test_arg",
|
|
82
|
+
TypeDefinitionItem(
|
|
83
|
+
bool,
|
|
84
|
+
typer.models.ParameterInfo(
|
|
85
|
+
default=False,
|
|
86
|
+
help="TypeDefinitionItem",
|
|
87
|
+
),
|
|
88
|
+
),
|
|
89
|
+
)
|
|
90
|
+
expected_string = " test_arg bool TypeDefinitionItem"
|
|
91
|
+
assert expected_string == result
|
|
92
|
+
|
|
93
|
+
result = TypeInfoToString(
|
|
94
|
+
"test_none",
|
|
95
|
+
bool,
|
|
96
|
+
)
|
|
97
|
+
expected_string = " test_none bool "
|
|
98
|
+
assert expected_string == result
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------------
|
|
2
|
+
# |
|
|
3
|
+
# | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
|
|
4
|
+
# | Distributed under the MIT License.
|
|
5
|
+
# |
|
|
6
|
+
# -------------------------------------------------------------------------------
|
|
7
|
+
"""Unit tests for ClassicBranchProtectionQuery.py"""
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
from RepoAuditor.Plugins.GitHub.ClassicBranchProtectionQuery import ClassicBranchProtectionQuery
|
|
12
|
+
from RepoAuditor.Plugins.GitHubBase.Module import _GitHubSession
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.fixture
|
|
16
|
+
def module_data():
|
|
17
|
+
return {
|
|
18
|
+
"session": _GitHubSession("https://github.com/gt-sse-center/RepoAuditor", "pat"),
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_mock_request(
|
|
23
|
+
status_code: int = 200,
|
|
24
|
+
protected_branch: bool = True,
|
|
25
|
+
rulesets_exist: bool = True,
|
|
26
|
+
):
|
|
27
|
+
"""A function which creates and returns a `mock_request` function."""
|
|
28
|
+
|
|
29
|
+
class MockedResponse:
|
|
30
|
+
def __init__(self, data, status_code):
|
|
31
|
+
self._data = data
|
|
32
|
+
self.status_code = status_code
|
|
33
|
+
|
|
34
|
+
def json(self):
|
|
35
|
+
return self._data
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def raise_for_status():
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
def mock_request(method, url, *args, **kwargs):
|
|
42
|
+
"""The function to use for monkeypatching"""
|
|
43
|
+
# remove leading /
|
|
44
|
+
if len(url) > 0 and url[0] == "/":
|
|
45
|
+
url = url[1:]
|
|
46
|
+
|
|
47
|
+
if method.lower() == "get":
|
|
48
|
+
if url == "":
|
|
49
|
+
return MockedResponse({"default_branch": "main"}, status_code)
|
|
50
|
+
elif url == "branches/main":
|
|
51
|
+
return MockedResponse({"protected": protected_branch}, status_code)
|
|
52
|
+
elif url == "branches/main/protection":
|
|
53
|
+
return MockedResponse("valid-test-data", status_code)
|
|
54
|
+
elif url == "rules/branches/main":
|
|
55
|
+
if rulesets_exist:
|
|
56
|
+
return MockedResponse("valid-rules", status_code=200)
|
|
57
|
+
else:
|
|
58
|
+
return MockedResponse("", status_code=200)
|
|
59
|
+
|
|
60
|
+
return mock_request
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class TestClassicBranchProtectionQuery:
|
|
64
|
+
def test_GetData(self, module_data, monkeypatch):
|
|
65
|
+
"""Test successful GetData"""
|
|
66
|
+
monkeypatch.setattr(module_data["session"], "request", get_mock_request())
|
|
67
|
+
query = ClassicBranchProtectionQuery()
|
|
68
|
+
query_data = query.GetData(module_data)
|
|
69
|
+
|
|
70
|
+
assert query_data["branch_protection_data"] == "valid-test-data"
|
|
71
|
+
|
|
72
|
+
def test_NotProtected(self, module_data, monkeypatch):
|
|
73
|
+
"""Test where branch is not protected."""
|
|
74
|
+
monkeypatch.setattr(module_data["session"], "request", get_mock_request(protected_branch=False))
|
|
75
|
+
query = ClassicBranchProtectionQuery()
|
|
76
|
+
query_data = query.GetData(module_data)
|
|
77
|
+
|
|
78
|
+
assert query_data is None
|
|
79
|
+
|
|
80
|
+
def test_RulesetProtected(self, module_data, monkeypatch):
|
|
81
|
+
"""Test when the branch is protected by rulesets."""
|
|
82
|
+
monkeypatch.setattr(module_data["session"], "request", get_mock_request(status_code=404))
|
|
83
|
+
query = ClassicBranchProtectionQuery()
|
|
84
|
+
query_data = query.GetData(module_data)
|
|
85
|
+
|
|
86
|
+
assert query_data is None
|
|
87
|
+
|
|
88
|
+
def test_RulesetProtectedNoRules(self, module_data, monkeypatch):
|
|
89
|
+
"""Test when the branch is protected by rulesets, but no rules exist."""
|
|
90
|
+
monkeypatch.setattr(
|
|
91
|
+
module_data["session"], "request", get_mock_request(status_code=404, rulesets_exist=False)
|
|
92
|
+
)
|
|
93
|
+
# Set github_pat to None to test a pathway
|
|
94
|
+
module_data["session"].github_pat = None
|
|
95
|
+
query = ClassicBranchProtectionQuery()
|
|
96
|
+
query_data = query.GetData(module_data)
|
|
97
|
+
|
|
98
|
+
assert query_data is None
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------------
|
|
2
|
+
# |
|
|
3
|
+
# | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
|
|
4
|
+
# | Distributed under the MIT License.
|
|
5
|
+
# |
|
|
6
|
+
# -------------------------------------------------------------------------------
|
|
7
|
+
"""Unit tests for DismissStalePullRequestApprovals.py"""
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
from RepoAuditor.Plugins.GitHub.ClassicBranchProtectionRequirements.DismissStalePullRequestApprovals import (
|
|
12
|
+
DismissStalePullRequestApprovals,
|
|
13
|
+
)
|
|
14
|
+
from RepoAuditor.Requirement import EvaluateResult
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@pytest.fixture
|
|
18
|
+
def query_data(session):
|
|
19
|
+
return {
|
|
20
|
+
"session": session,
|
|
21
|
+
"branch": "main",
|
|
22
|
+
"branch_protection_data": {
|
|
23
|
+
"required_pull_request_reviews": {
|
|
24
|
+
"dismiss_stale_reviews": True,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@pytest.fixture
|
|
31
|
+
def requirement():
|
|
32
|
+
return DismissStalePullRequestApprovals()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class TestDismissStalePullRequestApprovals:
|
|
36
|
+
def test_required_pull_request_reviews_missing(self, requirement, query_data):
|
|
37
|
+
"""Test when `required_pull_request_reviews` is missing."""
|
|
38
|
+
query_data["branch_protection_data"] = {}
|
|
39
|
+
requirement_args = {}
|
|
40
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
41
|
+
assert result.result == EvaluateResult.DoesNotApply
|
|
42
|
+
assert result.context is None
|
|
43
|
+
|
|
44
|
+
def test_required_pull_request_reviews_none(self, requirement, query_data):
|
|
45
|
+
"""Test when `required_pull_request_reviews` is None"""
|
|
46
|
+
query_data["branch_protection_data"]["required_pull_request_reviews"] = None
|
|
47
|
+
requirement_args = {}
|
|
48
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
49
|
+
assert result.result == EvaluateResult.DoesNotApply
|
|
50
|
+
assert result.context is None
|
|
51
|
+
|
|
52
|
+
def test_dismiss_stale_reviews_missing(self, requirement, query_data):
|
|
53
|
+
"""Test when `dismiss_stale_reviews` is missing"""
|
|
54
|
+
query_data["branch_protection_data"]["required_pull_request_reviews"] = {}
|
|
55
|
+
requirement_args = {}
|
|
56
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
57
|
+
assert result.result == EvaluateResult.DoesNotApply
|
|
58
|
+
assert result.context is None
|
|
59
|
+
|
|
60
|
+
def test_dismiss_stale_reviews_none(self, requirement, query_data):
|
|
61
|
+
"""Test when `dismiss_stale_reviews` is None"""
|
|
62
|
+
query_data["branch_protection_data"]["required_pull_request_reviews"] = {
|
|
63
|
+
"dismiss_stale_reviews": None
|
|
64
|
+
}
|
|
65
|
+
requirement_args = {}
|
|
66
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
67
|
+
assert result.result == EvaluateResult.DoesNotApply
|
|
68
|
+
assert result.context is None
|
|
69
|
+
|
|
70
|
+
def test_successful(self, requirement, query_data):
|
|
71
|
+
"""Test successful"""
|
|
72
|
+
query_data["branch_protection_data"]["required_pull_request_reviews"]["dismiss_stale_reviews"] = True
|
|
73
|
+
requirement_args = {"false": False}
|
|
74
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
75
|
+
assert result.result == EvaluateResult.Success
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------------
|
|
2
|
+
# |
|
|
3
|
+
# | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
|
|
4
|
+
# | Distributed under the MIT License.
|
|
5
|
+
# |
|
|
6
|
+
# -------------------------------------------------------------------------------
|
|
7
|
+
"""Unit tests for EnsureStatusChecks.py"""
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
from RepoAuditor.Plugins.GitHub.ClassicBranchProtectionRequirements.EnsureStatusChecks import (
|
|
12
|
+
EnsureStatusChecks,
|
|
13
|
+
)
|
|
14
|
+
from RepoAuditor.Requirement import EvaluateResult
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@pytest.fixture
|
|
18
|
+
def query_data(session):
|
|
19
|
+
return {
|
|
20
|
+
"session": session,
|
|
21
|
+
"branch": "main",
|
|
22
|
+
"branch_protection_data": {
|
|
23
|
+
"required_status_checks": {
|
|
24
|
+
"checks": ["check1", "check2"],
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@pytest.fixture
|
|
31
|
+
def requirement():
|
|
32
|
+
return EnsureStatusChecks()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class TestEnsureStatusChecks:
|
|
36
|
+
def test_disabled(self, requirement, query_data):
|
|
37
|
+
"""Test disabled requirement"""
|
|
38
|
+
requirement_args = {"disable": True}
|
|
39
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
40
|
+
assert result.result == EvaluateResult.DoesNotApply
|
|
41
|
+
assert "The status check requirement has been explicitly disabled." in result.context
|
|
42
|
+
|
|
43
|
+
def test_required_status_checks_missing(self, requirement, query_data):
|
|
44
|
+
"""Test when `required_status_checks` is missing"""
|
|
45
|
+
query_data["branch_protection_data"] = {}
|
|
46
|
+
requirement_args = {"disable": False}
|
|
47
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
48
|
+
assert result.result == EvaluateResult.DoesNotApply
|
|
49
|
+
assert result.context is None
|
|
50
|
+
|
|
51
|
+
def test_required_status_checks_none(self, requirement, query_data):
|
|
52
|
+
"""Test when `required_status_checks` is None"""
|
|
53
|
+
query_data["branch_protection_data"] = {"required_status_checks": None}
|
|
54
|
+
requirement_args = {"disable": False}
|
|
55
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
56
|
+
assert result.result == EvaluateResult.DoesNotApply
|
|
57
|
+
assert result.context is None
|
|
58
|
+
|
|
59
|
+
def test_checks_missing(self, requirement, query_data):
|
|
60
|
+
"""Test when `checks` is missing"""
|
|
61
|
+
query_data["branch_protection_data"]["required_status_checks"] = {}
|
|
62
|
+
requirement_args = {"disable": False}
|
|
63
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
64
|
+
assert result.result == EvaluateResult.Error
|
|
65
|
+
assert "No status checks are configured." in result.context
|
|
66
|
+
|
|
67
|
+
def test_checks_none(self, requirement, query_data):
|
|
68
|
+
"""Test when `checks` is None"""
|
|
69
|
+
query_data["branch_protection_data"]["required_status_checks"] = {"checks": None}
|
|
70
|
+
requirement_args = {"disable": False}
|
|
71
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
72
|
+
assert result.result == EvaluateResult.Error
|
|
73
|
+
assert "No status checks are configured." in result.context
|
|
74
|
+
|
|
75
|
+
def test_Successful(self, requirement, query_data):
|
|
76
|
+
"""Test successful"""
|
|
77
|
+
query_data["branch_protection_data"]["required_status_checks"]["checks"] = ["check1", "check2"]
|
|
78
|
+
requirement_args = {"disable": False}
|
|
79
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
80
|
+
assert result.result == EvaluateResult.Success
|
|
81
|
+
|
|
82
|
+
def test_SuccessfulGetDynamicArgDefinitions(self, requirement, query_data):
|
|
83
|
+
"""Test with GetDynamicArgDefinitions"""
|
|
84
|
+
query_data["branch_protection_data"]["required_status_checks"]["checks"] = ["check1", "check2"]
|
|
85
|
+
requirement_args = {}
|
|
86
|
+
for key, value in requirement.GetDynamicArgDefinitions().items():
|
|
87
|
+
requirement_args[key] = value[1].default
|
|
88
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
89
|
+
assert result.result == EvaluateResult.Success
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------------
|
|
2
|
+
# |
|
|
3
|
+
# | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
|
|
4
|
+
# | Distributed under the MIT License.
|
|
5
|
+
# |
|
|
6
|
+
# -------------------------------------------------------------------------------
|
|
7
|
+
"""Unit tests for RequireApprovalMostRecentPush.py"""
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
from RepoAuditor.Plugins.GitHub.ClassicBranchProtectionRequirements.RequireApprovalMostRecentPush import (
|
|
12
|
+
RequireApprovalMostRecentPush,
|
|
13
|
+
)
|
|
14
|
+
from RepoAuditor.Requirement import EvaluateResult
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@pytest.fixture
|
|
18
|
+
def query_data(session):
|
|
19
|
+
return {
|
|
20
|
+
"session": session,
|
|
21
|
+
"branch": "main",
|
|
22
|
+
"branch_protection_data": {
|
|
23
|
+
"required_pull_request_reviews": {
|
|
24
|
+
"require_last_push_approval": True,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@pytest.fixture
|
|
31
|
+
def requirement():
|
|
32
|
+
return RequireApprovalMostRecentPush()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class TestRequireApprovalMostRecentPush:
|
|
36
|
+
def test_required_pull_request_reviews_missing(self, requirement, query_data):
|
|
37
|
+
"""Test when `required_pull_request_reviews` is missing"""
|
|
38
|
+
query_data["branch_protection_data"] = {}
|
|
39
|
+
requirement_args = {}
|
|
40
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
41
|
+
assert result.result == EvaluateResult.DoesNotApply
|
|
42
|
+
assert result.context is None
|
|
43
|
+
|
|
44
|
+
def test_required_pull_request_reviews_none(self, requirement, query_data):
|
|
45
|
+
"""Test when `required_pull_request_reviews` is None"""
|
|
46
|
+
query_data["branch_protection_data"]["required_pull_request_reviews"] = None
|
|
47
|
+
requirement_args = {}
|
|
48
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
49
|
+
assert result.result == EvaluateResult.DoesNotApply
|
|
50
|
+
assert result.context is None
|
|
51
|
+
|
|
52
|
+
def test_require_last_push_approval_missing(self, requirement, query_data):
|
|
53
|
+
"""Test when `require_last_push_approval` is missing"""
|
|
54
|
+
query_data["branch_protection_data"]["required_pull_request_reviews"] = {}
|
|
55
|
+
requirement_args = {}
|
|
56
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
57
|
+
assert result.result == EvaluateResult.DoesNotApply
|
|
58
|
+
assert result.context is None
|
|
59
|
+
|
|
60
|
+
def test_require_last_push_approval_none(self, requirement, query_data):
|
|
61
|
+
"""Test when `require_last_push_approval` is None"""
|
|
62
|
+
requirement_args = {}
|
|
63
|
+
query_data["branch_protection_data"]["required_pull_request_reviews"][
|
|
64
|
+
"require_last_push_approval"
|
|
65
|
+
] = None
|
|
66
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
67
|
+
assert result.result == EvaluateResult.DoesNotApply
|
|
68
|
+
assert result.context is None
|
|
69
|
+
|
|
70
|
+
def test_Successful(self, requirement, query_data):
|
|
71
|
+
"""Test successful"""
|
|
72
|
+
query_data["branch_protection_data"]["required_pull_request_reviews"][
|
|
73
|
+
"require_last_push_approval"
|
|
74
|
+
] = True
|
|
75
|
+
requirement_args = {"false": False}
|
|
76
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
77
|
+
assert result.result == EvaluateResult.Success
|