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.
Files changed (167) hide show
  1. {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/workflows/CICD_impl.yml +1 -1
  2. {repoauditor-0.2.35 → repoauditor-0.2.38}/PKG-INFO +2 -2
  3. {repoauditor-0.2.35 → repoauditor-0.2.38}/pyproject.toml +1 -1
  4. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/ExecuteModules.py +2 -2
  5. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Impl/ParallelSequentialProcessor.py +5 -5
  6. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashCommitMerge.py +2 -1
  7. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Impl/ExistsRequirementImpl.py +1 -1
  8. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/__init__.py +1 -1
  9. repoauditor-0.2.38/tests/Plugins/GitHubCustomization/CutomizationQuery_UnitTest.py +60 -0
  10. repoauditor-0.2.38/tests/Plugins/GitHubCustomization/ExistsRequirementImpl_UnitTest.py +121 -0
  11. repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionQuery_UnitTest.py +88 -0
  12. repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals_UnitTest.py +75 -0
  13. repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/EnsureStatusChecks_UnitTest.py +89 -0
  14. repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush_UnitTest.py +77 -0
  15. repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireApprovals_UnitTest.py +88 -0
  16. repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireCodeOwnerReview_UnitTest.py +90 -0
  17. repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireUpToDateBranches_UnitTest.py +76 -0
  18. repoauditor-0.2.38/tests/Plugins/GitHubModule/ClassicValueRequirementImpl_UnitTest.py +37 -0
  19. repoauditor-0.2.38/tests/Plugins/GitHubModule/DefaultBranchQueryRequirements/Protected_UnitTest.py +64 -0
  20. repoauditor-0.2.38/tests/Plugins/GitHubModule/DefaultBranchQuery_UnitTest.py +51 -0
  21. repoauditor-0.2.38/tests/Plugins/GitHubModule/GitHubModule_UnitTest.py +33 -0
  22. repoauditor-0.2.38/tests/Plugins/GitHubModule/GitHubSession_UnitTest.py +48 -0
  23. repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/DependabotSecurityUpdates_UnitTest.py +81 -0
  24. repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/Description_UnitTest.py +66 -0
  25. repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/License_UnitTest.py +63 -0
  26. repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/MergeCommitMessage_UnitTest.py +74 -0
  27. repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/Private_UnitTest.py +80 -0
  28. repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/SecretScanningPushProtection_UnitTest.py +78 -0
  29. repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/SecretScanning_UnitTest.py +76 -0
  30. repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQueryRequirements/SquashMergeCommitMessage_UnitTest.py +72 -0
  31. repoauditor-0.2.38/tests/Plugins/GitHubModule/StandardQuery_UnitTest.py +51 -0
  32. repoauditor-0.2.38/tests/Plugins/GitHubModule/ValueRequrementImpl_UnitTest.py +105 -0
  33. repoauditor-0.2.38/tests/Plugins/GitHubModule/fixtures.py +22 -0
  34. repoauditor-0.2.38/tests/Plugins/GitHubRulesets/RulsesetQuery_UnitTest.py +62 -0
  35. repoauditor-0.2.38/tests/Plugins/conftest.py +20 -0
  36. {repoauditor-0.2.35 → repoauditor-0.2.38}/uv.lock +35 -9
  37. repoauditor-0.2.35/tests/Plugins/GitHubModule_UnitTest.py +0 -943
  38. {repoauditor-0.2.35 → repoauditor-0.2.38}/.copier-answers.yml +0 -0
  39. {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/CODEOWNERS +0 -0
  40. {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  41. {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  42. {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/ISSUE_TEMPLATE/custom.md +0 -0
  43. {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  44. {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/actions/release_impl/action.yml +0 -0
  45. {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/pull_request_template.md +0 -0
  46. {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/release_sources.yaml +0 -0
  47. {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/workflows/CICD.yml +0 -0
  48. {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/workflows/EndToEnd.yml +0 -0
  49. {repoauditor-0.2.35 → repoauditor-0.2.38}/.github/workflows/codeql.yml +0 -0
  50. {repoauditor-0.2.35 → repoauditor-0.2.38}/.gitignore +0 -0
  51. {repoauditor-0.2.35 → repoauditor-0.2.38}/.pre-commit-config.yaml +0 -0
  52. {repoauditor-0.2.35 → repoauditor-0.2.38}/.python-version +0 -0
  53. {repoauditor-0.2.35 → repoauditor-0.2.38}/CODE_OF_CONDUCT.md +0 -0
  54. {repoauditor-0.2.35 → repoauditor-0.2.38}/CONTRIBUTING.md +0 -0
  55. {repoauditor-0.2.35 → repoauditor-0.2.38}/DEVELOPMENT.md +0 -0
  56. {repoauditor-0.2.35 → repoauditor-0.2.38}/GOVERNANCE.md +0 -0
  57. {repoauditor-0.2.35 → repoauditor-0.2.38}/LICENSE +0 -0
  58. {repoauditor-0.2.35 → repoauditor-0.2.38}/MAINTAINERS.md +0 -0
  59. {repoauditor-0.2.35 → repoauditor-0.2.38}/README.md +0 -0
  60. {repoauditor-0.2.35 → repoauditor-0.2.38}/SECURITY.md +0 -0
  61. {repoauditor-0.2.35 → repoauditor-0.2.38}/minisign_key.pub +0 -0
  62. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/AutoGitSemVer.yaml +0 -0
  63. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/CommandLineProcessor.py +0 -0
  64. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Display.py +0 -0
  65. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/EntryPoint.py +0 -0
  66. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Impl/__init__.py +0 -0
  67. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Module.py +0 -0
  68. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugin.py +0 -0
  69. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionQuery.py +0 -0
  70. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowDeletions.py +0 -0
  71. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowForcePushes.py +0 -0
  72. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals.py +0 -0
  73. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DoNotAllowBypassSettings.py +0 -0
  74. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/EnsureStatusChecks.py +0 -0
  75. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicEnableRequirementImpl.py +0 -0
  76. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicValueRequirementImpl.py +0 -0
  77. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/__init__.py +0 -0
  78. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush.py +0 -0
  79. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovals.py +0 -0
  80. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireCodeOwnerReview.py +0 -0
  81. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireConversationResolution.py +0 -0
  82. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireLinearHistory.py +0 -0
  83. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequirePullRequests.py +0 -0
  84. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireSignedCommits.py +0 -0
  85. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireStatusChecksToPass.py +0 -0
  86. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireUpToDateBranches.py +0 -0
  87. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/__init__.py +0 -0
  88. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQuery.py +0 -0
  89. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/Protected.py +0 -0
  90. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQueryRequirements/__init__.py +0 -0
  91. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/Impl/Common.py +0 -0
  92. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/Impl/EnableRequirementImpl.py +0 -0
  93. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/Impl/ValueRequirementImpl.py +0 -0
  94. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/Impl/__init__.py +0 -0
  95. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/Module.py +0 -0
  96. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQuery.py +0 -0
  97. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/AutoMerge.py +0 -0
  98. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DefaultBranch.py +0 -0
  99. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DeleteHeadBranches.py +0 -0
  100. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/DependabotSecurityUpdates.py +0 -0
  101. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Description.py +0 -0
  102. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardEnableRequirementImpl.py +0 -0
  103. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/StandardValueRequirementImpl.py +0 -0
  104. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Impl/__init__.py +0 -0
  105. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/License.py +0 -0
  106. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommit.py +0 -0
  107. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/MergeCommitMessage.py +0 -0
  108. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/Private.py +0 -0
  109. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/RebaseMergeCommit.py +0 -0
  110. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanning.py +0 -0
  111. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SecretScanningPushProtection.py +0 -0
  112. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SquashMergeCommitMessage.py +0 -0
  113. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SuggestUpdatingPullRequestBranches.py +0 -0
  114. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportDiscussions.py +0 -0
  115. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportIssues.py +0 -0
  116. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportProjects.py +0 -0
  117. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/SupportWikis.py +0 -0
  118. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/TemplateRepository.py +0 -0
  119. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/WebCommitSignoff.py +0 -0
  120. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/StandardQueryRequirements/__init__.py +0 -0
  121. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHub/__init__.py +0 -0
  122. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubBase/Module.py +0 -0
  123. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubBase/__init__.py +0 -0
  124. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/CustomizationQuery.py +0 -0
  125. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Impl/__init__.py +0 -0
  126. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Module.py +0 -0
  127. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/CodeOwners.py +0 -0
  128. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/Contributing.py +0 -0
  129. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/IssueTemplates.py +0 -0
  130. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/PullRequestTemplates.py +0 -0
  131. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/SecurityPolicy.py +0 -0
  132. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/Requirements/__init__.py +0 -0
  133. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomization/__init__.py +0 -0
  134. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubCustomizationPlugin.py +0 -0
  135. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubPlugin.py +0 -0
  136. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Impl/EnableRulesetRequirementImpl.py +0 -0
  137. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Impl/__init__.py +0 -0
  138. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Module.py +0 -0
  139. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequirePullRequests.py +0 -0
  140. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequireSignedCommits.py +0 -0
  141. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/RequireStatusChecks.py +0 -0
  142. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/Requirements/__init__.py +0 -0
  143. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/RulesetQuery.py +0 -0
  144. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesets/__init__.py +0 -0
  145. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/GitHubRulesetsPlugin.py +0 -0
  146. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Plugins/__init__.py +0 -0
  147. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Query.py +0 -0
  148. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/Requirement.py +0 -0
  149. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/RepoAuditor/py.typed +0 -0
  150. {repoauditor-0.2.35 → repoauditor-0.2.38}/src/github_auditor/__init__.py +0 -0
  151. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/CommandLineProcessor_UnitTest.py +0 -0
  152. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/EntryPoint_UnitTest.py +0 -0
  153. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/ExecuteModules_UnitTest.py +0 -0
  154. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Module_UnitTest.py +0 -0
  155. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugin_UnitTest.py +0 -0
  156. {repoauditor-0.2.35/tests/Plugins → repoauditor-0.2.38/tests/Plugins/GitHubCustomization}/GitHubCustomization_UnitTest.py +0 -0
  157. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/GitHubCustomization_EndToEndTest.py +0 -0
  158. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/GitHubRuleset_EndToEndTest.py +0 -0
  159. {repoauditor-0.2.35/tests/Plugins → repoauditor-0.2.38/tests/Plugins/GitHubRulesets}/GitHubRuleset_UnitTest.py +0 -0
  160. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/GitHub_EndToEndTest.py +0 -0
  161. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/__snapshots__/GitHubCustomization_EndToEndTest.ambr +0 -0
  162. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/__snapshots__/GitHubRuleset_EndToEndTest.ambr +0 -0
  163. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/__snapshots__/GitHub_EndToEndTest.ambr +0 -0
  164. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Plugins/utilities.py +0 -0
  165. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Query_UnitTest.py +0 -0
  166. {repoauditor-0.2.35 → repoauditor-0.2.38}/tests/Requirement_UnitTest.py +0 -0
  167. {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=90.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.35
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.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",
@@ -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):
@@ -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
  --------------------------------
@@ -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 {self.github_file} directory of the repository",
82
+ f"File found in {location} directory of the repository",
83
83
  )
84
84
 
85
85
  return Requirement.EvaluateImplResult(
@@ -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.35"
5
+ __version__ = "0.2.38"
@@ -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