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.
Files changed (162) hide show
  1. {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/workflows/CICD_impl.yml +1 -1
  2. {repoauditor-0.2.34 → repoauditor-0.2.37}/PKG-INFO +2 -2
  3. {repoauditor-0.2.34 → repoauditor-0.2.37}/pyproject.toml +1 -1
  4. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/EntryPoint.py +35 -24
  5. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/ExecuteModules.py +2 -2
  6. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Impl/ParallelSequentialProcessor.py +5 -5
  7. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals.py +1 -1
  8. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush.py +1 -1
  9. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovals.py +1 -1
  10. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireCodeOwnerReview.py +1 -1
  11. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireUpToDateBranches.py +1 -1
  12. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Description.py +2 -3
  13. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashCommitMerge.py +2 -1
  14. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/__init__.py +1 -1
  15. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/EntryPoint_UnitTest.py +39 -1
  16. repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionQuery_UnitTest.py +98 -0
  17. repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals_UnitTest.py +75 -0
  18. repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/EnsureStatusChecks_UnitTest.py +89 -0
  19. repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush_UnitTest.py +77 -0
  20. repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireApprovals_UnitTest.py +88 -0
  21. repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireCodeOwnerReview_UnitTest.py +90 -0
  22. repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireUpToDateBranches_UnitTest.py +76 -0
  23. repoauditor-0.2.37/tests/Plugins/GitHubModule/ClassicValueRequirementImpl_UnitTest.py +37 -0
  24. repoauditor-0.2.37/tests/Plugins/GitHubModule/DefaultBranchQueryRequirements/Protected_UnitTest.py +64 -0
  25. repoauditor-0.2.37/tests/Plugins/GitHubModule/DefaultBranchQuery_UnitTest.py +61 -0
  26. repoauditor-0.2.37/tests/Plugins/GitHubModule/GitHubModule_UnitTest.py +35 -0
  27. repoauditor-0.2.34/tests/Plugins/GitHubModule_UnitTest.py → repoauditor-0.2.37/tests/Plugins/GitHubModule/GitHubSession_UnitTest.py +1 -23
  28. repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/DependabotSecurityUpdates_UnitTest.py +81 -0
  29. repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/Description_UnitTest.py +66 -0
  30. repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/License_UnitTest.py +63 -0
  31. repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/MergeCommitMessage_UnitTest.py +74 -0
  32. repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/Private_UnitTest.py +80 -0
  33. repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/SecretScanningPushProtection_UnitTest.py +78 -0
  34. repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/SecretScanning_UnitTest.py +76 -0
  35. repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQueryRequirements/SquashMergeCommitMessage_UnitTest.py +72 -0
  36. repoauditor-0.2.37/tests/Plugins/GitHubModule/StandardQuery_UnitTest.py +61 -0
  37. repoauditor-0.2.37/tests/Plugins/GitHubModule/ValueRequrementImpl_UnitTest.py +105 -0
  38. repoauditor-0.2.37/tests/Plugins/GitHubModule/conftest.py +22 -0
  39. {repoauditor-0.2.34 → repoauditor-0.2.37}/uv.lock +35 -9
  40. {repoauditor-0.2.34 → repoauditor-0.2.37}/.copier-answers.yml +0 -0
  41. {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/CODEOWNERS +0 -0
  42. {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  43. {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  44. {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/ISSUE_TEMPLATE/custom.md +0 -0
  45. {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  46. {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/actions/release_impl/action.yml +0 -0
  47. {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/pull_request_template.md +0 -0
  48. {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/release_sources.yaml +0 -0
  49. {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/workflows/CICD.yml +0 -0
  50. {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/workflows/EndToEnd.yml +0 -0
  51. {repoauditor-0.2.34 → repoauditor-0.2.37}/.github/workflows/codeql.yml +0 -0
  52. {repoauditor-0.2.34 → repoauditor-0.2.37}/.gitignore +0 -0
  53. {repoauditor-0.2.34 → repoauditor-0.2.37}/.pre-commit-config.yaml +0 -0
  54. {repoauditor-0.2.34 → repoauditor-0.2.37}/.python-version +0 -0
  55. {repoauditor-0.2.34 → repoauditor-0.2.37}/CODE_OF_CONDUCT.md +0 -0
  56. {repoauditor-0.2.34 → repoauditor-0.2.37}/CONTRIBUTING.md +0 -0
  57. {repoauditor-0.2.34 → repoauditor-0.2.37}/DEVELOPMENT.md +0 -0
  58. {repoauditor-0.2.34 → repoauditor-0.2.37}/GOVERNANCE.md +0 -0
  59. {repoauditor-0.2.34 → repoauditor-0.2.37}/LICENSE +0 -0
  60. {repoauditor-0.2.34 → repoauditor-0.2.37}/MAINTAINERS.md +0 -0
  61. {repoauditor-0.2.34 → repoauditor-0.2.37}/README.md +0 -0
  62. {repoauditor-0.2.34 → repoauditor-0.2.37}/SECURITY.md +0 -0
  63. {repoauditor-0.2.34 → repoauditor-0.2.37}/minisign_key.pub +0 -0
  64. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/AutoGitSemVer.yaml +0 -0
  65. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/CommandLineProcessor.py +0 -0
  66. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Display.py +0 -0
  67. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Impl/__init__.py +0 -0
  68. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Module.py +0 -0
  69. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugin.py +0 -0
  70. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionQuery.py +0 -0
  71. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowDeletions.py +0 -0
  72. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowForcePushes.py +0 -0
  73. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DoNotAllowBypassSettings.py +0 -0
  74. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/EnsureStatusChecks.py +0 -0
  75. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicEnableRequirementImpl.py +0 -0
  76. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicValueRequirementImpl.py +0 -0
  77. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/__init__.py +0 -0
  78. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireConversationResolution.py +0 -0
  79. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireLinearHistory.py +0 -0
  80. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequirePullRequests.py +0 -0
  81. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireSignedCommits.py +0 -0
  82. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireStatusChecksToPass.py +0 -0
  83. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/__init__.py +0 -0
  84. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQuery.py +0 -0
  85. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/Protected.py +0 -0
  86. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/__init__.py +0 -0
  87. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/Impl/Common.py +0 -0
  88. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/Impl/EnableRequirementImpl.py +0 -0
  89. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/Impl/ValueRequirementImpl.py +0 -0
  90. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/Impl/__init__.py +0 -0
  91. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/Module.py +0 -0
  92. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQuery.py +0 -0
  93. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/AutoMerge.py +0 -0
  94. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DefaultBranch.py +0 -0
  95. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DeleteHeadBranches.py +0 -0
  96. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DependabotSecurityUpdates.py +0 -0
  97. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardEnableRequirementImpl.py +0 -0
  98. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardValueRequirementImpl.py +0 -0
  99. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/__init__.py +0 -0
  100. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/License.py +0 -0
  101. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommit.py +0 -0
  102. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommitMessage.py +0 -0
  103. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Private.py +0 -0
  104. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/RebaseMergeCommit.py +0 -0
  105. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanning.py +0 -0
  106. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanningPushProtection.py +0 -0
  107. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashMergeCommitMessage.py +0 -0
  108. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SuggestUpdatingPullRequestBranches.py +0 -0
  109. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportDiscussions.py +0 -0
  110. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportIssues.py +0 -0
  111. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportProjects.py +0 -0
  112. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportWikis.py +0 -0
  113. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/TemplateRepository.py +0 -0
  114. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/WebCommitSignoff.py +0 -0
  115. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/__init__.py +0 -0
  116. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHub/__init__.py +0 -0
  117. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubBase/Module.py +0 -0
  118. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubBase/__init__.py +0 -0
  119. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/CustomizationQuery.py +0 -0
  120. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Impl/ExistsRequirementImpl.py +0 -0
  121. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Impl/__init__.py +0 -0
  122. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Module.py +0 -0
  123. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/CodeOwners.py +0 -0
  124. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/Contributing.py +0 -0
  125. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/IssueTemplates.py +0 -0
  126. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/PullRequestTemplates.py +0 -0
  127. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/SecurityPolicy.py +0 -0
  128. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/__init__.py +0 -0
  129. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomization/__init__.py +0 -0
  130. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubCustomizationPlugin.py +0 -0
  131. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubPlugin.py +0 -0
  132. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Impl/EnableRulesetRequirementImpl.py +0 -0
  133. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Impl/__init__.py +0 -0
  134. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Module.py +0 -0
  135. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequirePullRequests.py +0 -0
  136. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequireSignedCommits.py +0 -0
  137. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequireStatusChecks.py +0 -0
  138. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/__init__.py +0 -0
  139. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/RulesetQuery.py +0 -0
  140. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesets/__init__.py +0 -0
  141. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/GitHubRulesetsPlugin.py +0 -0
  142. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Plugins/__init__.py +0 -0
  143. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Query.py +0 -0
  144. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/Requirement.py +0 -0
  145. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/RepoAuditor/py.typed +0 -0
  146. {repoauditor-0.2.34 → repoauditor-0.2.37}/src/github_auditor/__init__.py +0 -0
  147. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/CommandLineProcessor_UnitTest.py +0 -0
  148. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/ExecuteModules_UnitTest.py +0 -0
  149. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Module_UnitTest.py +0 -0
  150. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugin_UnitTest.py +0 -0
  151. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/GitHubCustomization_EndToEndTest.py +0 -0
  152. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/GitHubCustomization_UnitTest.py +0 -0
  153. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/GitHubRuleset_EndToEndTest.py +0 -0
  154. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/GitHubRuleset_UnitTest.py +0 -0
  155. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/GitHub_EndToEndTest.py +0 -0
  156. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/__snapshots__/GitHubCustomization_EndToEndTest.ambr +0 -0
  157. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/__snapshots__/GitHubRuleset_EndToEndTest.ambr +0 -0
  158. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/__snapshots__/GitHub_EndToEndTest.ambr +0 -0
  159. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Plugins/utilities.py +0 -0
  160. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Query_UnitTest.py +0 -0
  161. {repoauditor-0.2.34 → repoauditor-0.2.37}/tests/Requirement_UnitTest.py +0 -0
  162. {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=80.0
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.34
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.6
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
@@ -7,7 +7,7 @@ authors = [
7
7
  ]
8
8
  requires-python = ">= 3.10"
9
9
  dependencies = [
10
- "dbrownell-common>=0.14.6",
10
+ "dbrownell-common>=0.14.10",
11
11
  "pluggy>=1.5.0",
12
12
  "requests>=2.32.3",
13
13
  "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.TransformResultComplete:
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.TransformResultComplete(evaluate_results, result_code, result_status)
172
+ return ExecuteTasks.CompleteTransformResult(evaluate_results, result_code, result_status)
173
173
 
174
174
  # ----------------------------------------------------------------------
175
175
 
@@ -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.TransformResultComplete:
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.TransformResultComplete(None, return_code)
96
+ return ExecuteTasks.CompleteTransformResult(None, return_code)
97
97
 
98
98
  # ----------------------------------------------------------------------
99
99
 
100
100
  if parallel:
101
- transform_results: list[Optional[Exception]] = ExecuteTasks.TransformTasks(
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):
@@ -54,4 +54,4 @@ def _GetValue(
54
54
  if settings is None:
55
55
  return None
56
56
 
57
- return settings["dismiss_stale_reviews"]
57
+ return settings.get("dismiss_stale_reviews", None)
@@ -53,4 +53,4 @@ def _GetValue(
53
53
  if settings is None:
54
54
  return None
55
55
 
56
- return settings["require_last_push_approval"]
56
+ return settings.get("require_last_push_approval", None)
@@ -55,4 +55,4 @@ def _GetValue(
55
55
  if settings is None:
56
56
  return None
57
57
 
58
- return settings["required_approving_review_count"]
58
+ return settings.get("required_approving_review_count", None)
@@ -57,4 +57,4 @@ def _GetValue(
57
57
  if settings is None:
58
58
  return None
59
59
 
60
- return settings["require_code_owner_reviews"]
60
+ return settings.get("require_code_owner_reviews", None)
@@ -55,4 +55,4 @@ def _GetValue(
55
55
  if settings is None:
56
56
  return None
57
57
 
58
- return settings["strict"]
58
+ return settings.get("strict", None)
@@ -73,11 +73,10 @@ class Description(Requirement):
73
73
  ) -> Requirement.EvaluateImplResult:
74
74
  standard_data = query_data["standard"]
75
75
 
76
- if "description" not in standard_data:
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
- - Rebase merging is not compatible with signed commits, as GitHub creates a new commit when squashing.
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
  --------------------------------
@@ -2,4 +2,4 @@ APP_NAME = "RepoAuditor"
2
2
 
3
3
  # Note that the default value below will be used until the value
4
4
  # here is explicitly updated by the Continuous Integration system.
5
- __version__ = "0.2.34"
5
+ __version__ = "0.2.37"
@@ -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