RepoAuditor 0.2.35__tar.gz → 0.2.38__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.35 → repoauditor-0.2.38}/.github/workflows/CICD_impl.yml +1 -1
- {repoauditor-0.2.35 → repoauditor-0.2.38}/PKG-INFO +2 -2
- {repoauditor-0.2.35 → repoauditor-0.2.38}/pyproject.toml +1 -1
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/ExecuteModules.py +2 -2
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Impl/ParallelSequentialProcessor.py +5 -5
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashCommitMerge.py +2 -1
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Impl/ExistsRequirementImpl.py +1 -1
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/__init__.py +1 -1
- repoauditor-0.2.38/tests/Plugins/GitHubCustomization/CutomizationQuery_UnitTest.py +60 -0
- repoauditor-0.2.38/tests/Plugins/GitHubCustomization/ExistsRequirementImpl_UnitTest.py +121 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionQuery_UnitTest.py +88 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals_UnitTest.py +75 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/EnsureStatusChecks_UnitTest.py +89 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush_UnitTest.py +77 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireApprovals_UnitTest.py +88 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireCodeOwnerReview_UnitTest.py +90 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireUpToDateBranches_UnitTest.py +76 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicValueRequirementImpl_UnitTest.py +37 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/DefaultBranchQueryRequirements/Protected_UnitTest.py +64 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/DefaultBranchQuery_UnitTest.py +51 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/GitHubModule_UnitTest.py +33 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/GitHubSession_UnitTest.py +48 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/DependabotSecurityUpdates_UnitTest.py +81 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/Description_UnitTest.py +66 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/License_UnitTest.py +63 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/MergeCommitMessage_UnitTest.py +74 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/Private_UnitTest.py +80 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/SecretScanningPushProtection_UnitTest.py +78 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/SecretScanning_UnitTest.py +76 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/SquashMergeCommitMessage_UnitTest.py +72 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQuery_UnitTest.py +51 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/ValueRequrementImpl_UnitTest.py +105 -0
- repoauditor-0.2.38/tests/Plugins/GitHubModule/fixtures.py +22 -0
- repoauditor-0.2.38/tests/Plugins/GitHubRulesets/RulsesetQuery_UnitTest.py +62 -0
- repoauditor-0.2.38/tests/Plugins/conftest.py +20 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/uv.lock +35 -9
- repoauditor-0.2.35/tests/Plugins/GitHubModule_UnitTest.py +0 -943
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.copier-answers.yml +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/CODEOWNERS +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/ISSUE_TEMPLATE/custom.md +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/actions/release_impl/action.yml +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/pull_request_template.md +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/release_sources.yaml +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/workflows/CICD.yml +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/workflows/EndToEnd.yml +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/workflows/codeql.yml +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.gitignore +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.pre-commit-config.yaml +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/.python-version +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/CODE_OF_CONDUCT.md +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/CONTRIBUTING.md +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/DEVELOPMENT.md +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/GOVERNANCE.md +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/LICENSE +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/MAINTAINERS.md +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/README.md +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/SECURITY.md +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/minisign_key.pub +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/AutoGitSemVer.yaml +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/CommandLineProcessor.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Display.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/EntryPoint.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Impl/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Module.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugin.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionQuery.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowDeletions.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowForcePushes.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DoNotAllowBypassSettings.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/EnsureStatusChecks.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicEnableRequirementImpl.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicValueRequirementImpl.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovals.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireCodeOwnerReview.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireConversationResolution.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireLinearHistory.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequirePullRequests.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireSignedCommits.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireStatusChecksToPass.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireUpToDateBranches.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQuery.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/Protected.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/Impl/Common.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/Impl/EnableRequirementImpl.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/Impl/ValueRequirementImpl.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/Impl/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/Module.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQuery.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/AutoMerge.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DefaultBranch.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DeleteHeadBranches.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DependabotSecurityUpdates.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Description.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardEnableRequirementImpl.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardValueRequirementImpl.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/License.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommit.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommitMessage.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Private.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/RebaseMergeCommit.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanning.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanningPushProtection.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashMergeCommitMessage.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SuggestUpdatingPullRequestBranches.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportDiscussions.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportIssues.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportProjects.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportWikis.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/TemplateRepository.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/WebCommitSignoff.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubBase/Module.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubBase/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/CustomizationQuery.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Impl/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Module.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/CodeOwners.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/Contributing.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/IssueTemplates.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/PullRequestTemplates.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/SecurityPolicy.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomizationPlugin.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubPlugin.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Impl/EnableRulesetRequirementImpl.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Impl/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Module.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequirePullRequests.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequireSignedCommits.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequireStatusChecks.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/RulesetQuery.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesetsPlugin.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Query.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Requirement.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/py.typed +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/src/github_auditor/__init__.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/CommandLineProcessor_UnitTest.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/EntryPoint_UnitTest.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/ExecuteModules_UnitTest.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Module_UnitTest.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugin_UnitTest.py +0 -0
- {repoauditor-0.2.35/tests/Plugins → repoauditor-0.2.38/tests/Plugins/GitHubCustomization}/GitHubCustomization_UnitTest.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/GitHubCustomization_EndToEndTest.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/GitHubRuleset_EndToEndTest.py +0 -0
- {repoauditor-0.2.35/tests/Plugins → repoauditor-0.2.38/tests/Plugins/GitHubRulesets}/GitHubRuleset_UnitTest.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/GitHub_EndToEndTest.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/__snapshots__/GitHubCustomization_EndToEndTest.ambr +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/__snapshots__/GitHubRuleset_EndToEndTest.ambr +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/__snapshots__/GitHub_EndToEndTest.ambr +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/utilities.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Query_UnitTest.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Requirement_UnitTest.py +0 -0
- {repoauditor-0.2.35 → repoauditor-0.2.38}/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.38
|
|
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
|
|
@@ -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.35 → repoauditor-0.2.38}/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):
|
|
@@ -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
|
--------------------------------
|
|
@@ -79,7 +79,7 @@ class ExistsRequirementImpl(Requirement):
|
|
|
79
79
|
if full_file_path.is_dir() and any(full_file_path.iterdir()):
|
|
80
80
|
return Requirement.EvaluateImplResult(
|
|
81
81
|
EvaluateResult.Success,
|
|
82
|
-
f"File found in {
|
|
82
|
+
f"File found in {location} directory of the repository",
|
|
83
83
|
)
|
|
84
84
|
|
|
85
85
|
return Requirement.EvaluateImplResult(
|
|
@@ -0,0 +1,60 @@
|
|
|
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 CustomizationQuery.py"""
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
from git import Repo
|
|
11
|
+
|
|
12
|
+
from RepoAuditor.Plugins.GitHubCustomization.CustomizationQuery import CustomizationQuery, TemporaryDirectory
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def mock_clone_from(github_url, repo_dirname, branch="main"):
|
|
16
|
+
"""A mocked clone_from method for the git.Repo class."""
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class MockTemporaryDirectory:
|
|
21
|
+
"""A mock class to replace tempfile.TemporaryDirectory."""
|
|
22
|
+
|
|
23
|
+
def __init__(self):
|
|
24
|
+
self.name = "test_temp_directory"
|
|
25
|
+
|
|
26
|
+
def cleanup(self):
|
|
27
|
+
"""Mocked cleanup method"""
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@pytest.fixture(autouse=True)
|
|
31
|
+
def patch_temp_directory(monkeypatch):
|
|
32
|
+
monkeypatch.delattr("tempfile.TemporaryDirectory")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class TestCustomizationQuery:
|
|
36
|
+
def test_GetData(self, module_data, monkeypatch):
|
|
37
|
+
"""Test the GetData method."""
|
|
38
|
+
monkeypatch.setattr(
|
|
39
|
+
TemporaryDirectory,
|
|
40
|
+
"__init__",
|
|
41
|
+
MockTemporaryDirectory.__init__,
|
|
42
|
+
)
|
|
43
|
+
monkeypatch.setattr(
|
|
44
|
+
Repo,
|
|
45
|
+
"clone_from",
|
|
46
|
+
mock_clone_from,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
query = CustomizationQuery()
|
|
50
|
+
query_data = query.GetData(module_data)
|
|
51
|
+
|
|
52
|
+
assert query_data["repo_dir"].name == "test_temp_directory"
|
|
53
|
+
|
|
54
|
+
def test_Cleanup(self, module_data):
|
|
55
|
+
"""Test the Cleanup method."""
|
|
56
|
+
query = CustomizationQuery()
|
|
57
|
+
module_data["repo_dir"] = MockTemporaryDirectory()
|
|
58
|
+
result = query.Cleanup(module_data)
|
|
59
|
+
|
|
60
|
+
assert result is None
|
|
@@ -0,0 +1,121 @@
|
|
|
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 GitHub/Impl/ClassicValueRequirementImpl.py"""
|
|
8
|
+
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from tempfile import TemporaryDirectory
|
|
11
|
+
|
|
12
|
+
from RepoAuditor.Plugins.GitHubCustomization.Impl.ExistsRequirementImpl import ExistsRequirementImpl
|
|
13
|
+
from RepoAuditor.Requirement import EvaluateResult
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class MockDirectory:
|
|
17
|
+
def __init__(self):
|
|
18
|
+
self.name = "repository"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TestExistsRequirementImpl:
|
|
22
|
+
def test_Constructor(self):
|
|
23
|
+
"""Test the requirement implementation constructor."""
|
|
24
|
+
requirement = ExistsRequirementImpl(
|
|
25
|
+
name="Exists Some Value",
|
|
26
|
+
dynamic_arg_name="exists",
|
|
27
|
+
github_file="README.md",
|
|
28
|
+
possible_locations=[
|
|
29
|
+
"README.md",
|
|
30
|
+
],
|
|
31
|
+
resolution="Get test to pass",
|
|
32
|
+
rationale="For testing",
|
|
33
|
+
)
|
|
34
|
+
assert requirement.github_file == "README.md"
|
|
35
|
+
|
|
36
|
+
def test_Disabled(self):
|
|
37
|
+
"""Test disabled requirement."""
|
|
38
|
+
requirement = ExistsRequirementImpl(
|
|
39
|
+
name="Exists Some Value",
|
|
40
|
+
dynamic_arg_name="exists",
|
|
41
|
+
github_file="README.md",
|
|
42
|
+
possible_locations=[
|
|
43
|
+
"README.md",
|
|
44
|
+
],
|
|
45
|
+
resolution="Get test to pass",
|
|
46
|
+
rationale="For testing",
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
query_data = {}
|
|
50
|
+
requirement_args = {"exists": False}
|
|
51
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
52
|
+
assert result.result == EvaluateResult.DoesNotApply
|
|
53
|
+
|
|
54
|
+
def test_NotFound(self):
|
|
55
|
+
"""Test for when file is not found."""
|
|
56
|
+
requirement = ExistsRequirementImpl(
|
|
57
|
+
name="Exists Some Value",
|
|
58
|
+
dynamic_arg_name="exists",
|
|
59
|
+
github_file="README.md",
|
|
60
|
+
possible_locations=[
|
|
61
|
+
"MEREAD.md",
|
|
62
|
+
],
|
|
63
|
+
resolution="Get test to pass",
|
|
64
|
+
rationale="For testing",
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
query_data = {"repo_dir": MockDirectory()}
|
|
68
|
+
requirement_args = {"exists": True}
|
|
69
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
70
|
+
assert result.result == EvaluateResult.Error
|
|
71
|
+
assert "No README.md file found" in result.context
|
|
72
|
+
|
|
73
|
+
def test_Found(self):
|
|
74
|
+
"""Test for when file is found as is."""
|
|
75
|
+
requirement = ExistsRequirementImpl(
|
|
76
|
+
name="Exists Some Value",
|
|
77
|
+
dynamic_arg_name="exists",
|
|
78
|
+
github_file="README.md",
|
|
79
|
+
possible_locations=[
|
|
80
|
+
"README.md",
|
|
81
|
+
],
|
|
82
|
+
resolution="Get test to pass",
|
|
83
|
+
rationale="For testing",
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
tempdir = TemporaryDirectory()
|
|
87
|
+
with open(Path(tempdir.name, "README.md"), "w") as f:
|
|
88
|
+
f.write("temp file in temp directory")
|
|
89
|
+
|
|
90
|
+
query_data = {"repo_dir": tempdir}
|
|
91
|
+
requirement_args = {"exists": True}
|
|
92
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
93
|
+
assert result.result == EvaluateResult.Success
|
|
94
|
+
assert "README.md found in repository" in result.context
|
|
95
|
+
|
|
96
|
+
def test_FoundInDirectory(self):
|
|
97
|
+
"""Test if provided path is directory."""
|
|
98
|
+
requirement = ExistsRequirementImpl(
|
|
99
|
+
name="Exists Some Value",
|
|
100
|
+
dynamic_arg_name="exists",
|
|
101
|
+
github_file="README.md",
|
|
102
|
+
possible_locations=[
|
|
103
|
+
"docs",
|
|
104
|
+
],
|
|
105
|
+
resolution="Get test to pass",
|
|
106
|
+
rationale="For testing",
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
tempdir = TemporaryDirectory()
|
|
110
|
+
# Create "docs" directory
|
|
111
|
+
docs_dir = Path(tempdir.name) / "docs"
|
|
112
|
+
docs_dir.mkdir(parents=True)
|
|
113
|
+
|
|
114
|
+
with open(docs_dir / "README.md", "w") as f:
|
|
115
|
+
f.write("temp file in temp directory")
|
|
116
|
+
|
|
117
|
+
query_data = {"repo_dir": tempdir}
|
|
118
|
+
requirement_args = {"exists": True}
|
|
119
|
+
result = requirement.Evaluate(query_data, requirement_args)
|
|
120
|
+
assert result.result == EvaluateResult.Success
|
|
121
|
+
assert "File found in docs directory of the repository" in result.context
|
|
@@ -0,0 +1,88 @@
|
|
|
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
|
+
from RepoAuditor.Plugins.GitHub.ClassicBranchProtectionQuery import ClassicBranchProtectionQuery
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_mock_request(
|
|
13
|
+
status_code: int = 200,
|
|
14
|
+
protected_branch: bool = True,
|
|
15
|
+
rulesets_exist: bool = True,
|
|
16
|
+
):
|
|
17
|
+
"""A function which creates and returns a `mock_request` function."""
|
|
18
|
+
|
|
19
|
+
class MockedResponse:
|
|
20
|
+
def __init__(self, data, status_code):
|
|
21
|
+
self._data = data
|
|
22
|
+
self.status_code = status_code
|
|
23
|
+
|
|
24
|
+
def json(self):
|
|
25
|
+
return self._data
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def raise_for_status():
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
def mock_request(method, url, *args, **kwargs):
|
|
32
|
+
"""The function to use for monkeypatching"""
|
|
33
|
+
# remove leading /
|
|
34
|
+
if len(url) > 0 and url[0] == "/":
|
|
35
|
+
url = url[1:]
|
|
36
|
+
|
|
37
|
+
if method.lower() == "get":
|
|
38
|
+
if url == "":
|
|
39
|
+
return MockedResponse({"default_branch": "main"}, status_code)
|
|
40
|
+
elif url == "branches/main":
|
|
41
|
+
return MockedResponse({"protected": protected_branch}, status_code)
|
|
42
|
+
elif url == "branches/main/protection":
|
|
43
|
+
return MockedResponse("valid-test-data", status_code)
|
|
44
|
+
elif url == "rules/branches/main":
|
|
45
|
+
if rulesets_exist:
|
|
46
|
+
return MockedResponse("valid-rules", status_code=200)
|
|
47
|
+
else:
|
|
48
|
+
return MockedResponse("", status_code=200)
|
|
49
|
+
|
|
50
|
+
return mock_request
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class TestClassicBranchProtectionQuery:
|
|
54
|
+
def test_GetData(self, module_data, monkeypatch):
|
|
55
|
+
"""Test successful GetData"""
|
|
56
|
+
monkeypatch.setattr(module_data["session"], "request", get_mock_request())
|
|
57
|
+
query = ClassicBranchProtectionQuery()
|
|
58
|
+
query_data = query.GetData(module_data)
|
|
59
|
+
|
|
60
|
+
assert query_data["branch_protection_data"] == "valid-test-data"
|
|
61
|
+
|
|
62
|
+
def test_NotProtected(self, module_data, monkeypatch):
|
|
63
|
+
"""Test where branch is not protected."""
|
|
64
|
+
monkeypatch.setattr(module_data["session"], "request", get_mock_request(protected_branch=False))
|
|
65
|
+
query = ClassicBranchProtectionQuery()
|
|
66
|
+
query_data = query.GetData(module_data)
|
|
67
|
+
|
|
68
|
+
assert query_data is None
|
|
69
|
+
|
|
70
|
+
def test_RulesetProtected(self, module_data, monkeypatch):
|
|
71
|
+
"""Test when the branch is protected by rulesets."""
|
|
72
|
+
monkeypatch.setattr(module_data["session"], "request", get_mock_request(status_code=404))
|
|
73
|
+
query = ClassicBranchProtectionQuery()
|
|
74
|
+
query_data = query.GetData(module_data)
|
|
75
|
+
|
|
76
|
+
assert query_data is None
|
|
77
|
+
|
|
78
|
+
def test_RulesetProtectedNoRules(self, module_data, monkeypatch):
|
|
79
|
+
"""Test when the branch is protected by rulesets, but no rules exist."""
|
|
80
|
+
monkeypatch.setattr(
|
|
81
|
+
module_data["session"], "request", get_mock_request(status_code=404, rulesets_exist=False)
|
|
82
|
+
)
|
|
83
|
+
# Set github_pat to None to test a pathway
|
|
84
|
+
module_data["session"].github_pat = None
|
|
85
|
+
query = ClassicBranchProtectionQuery()
|
|
86
|
+
query_data = query.GetData(module_data)
|
|
87
|
+
|
|
88
|
+
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
|