import argparse from unittest.mock import MagicMock from prowler.providers.github.lib.arguments import arguments class Test_GitHubArguments: def setup_method(self): """Setup mock ArgumentParser for testing""" self.mock_parser = MagicMock() self.mock_subparsers = MagicMock() self.mock_github_parser = MagicMock() self.mock_auth_group = MagicMock() self.mock_scoping_group = MagicMock() # Setup the mock chain self.mock_parser.add_subparsers.return_value = self.mock_subparsers self.mock_subparsers.add_parser.return_value = self.mock_github_parser self.mock_github_parser.add_argument_group.side_effect = [ self.mock_auth_group, self.mock_scoping_group, ] def test_init_parser_creates_subparser(self): """Test that init_parser creates the GitHub subparser correctly""" # Create a mock object that has the necessary attributes mock_github_args = MagicMock() mock_github_args.subparsers = self.mock_subparsers mock_github_args.common_providers_parser = MagicMock() # Call init_parser arguments.init_parser(mock_github_args) # Verify subparser was created self.mock_subparsers.add_parser.assert_called_once_with( "github", parents=[mock_github_args.common_providers_parser], help="GitHub Provider", ) def test_init_parser_creates_argument_groups(self): """Test that init_parser creates the correct argument groups""" mock_github_args = MagicMock() mock_github_args.subparsers = self.mock_subparsers mock_github_args.common_providers_parser = MagicMock() arguments.init_parser(mock_github_args) # Verify argument groups were created assert self.mock_github_parser.add_argument_group.call_count == 2 calls = self.mock_github_parser.add_argument_group.call_args_list assert calls[0][0][0] == "Authentication Modes" assert calls[1][0][0] == "Scan Scoping" def test_init_parser_adds_authentication_arguments(self): """Test that init_parser adds all authentication arguments""" mock_github_args = MagicMock() mock_github_args.subparsers = self.mock_subparsers mock_github_args.common_providers_parser = MagicMock() arguments.init_parser(mock_github_args) # Verify authentication arguments were added assert self.mock_auth_group.add_argument.call_count == 4 # Check that all authentication arguments are present calls = self.mock_auth_group.add_argument.call_args_list auth_args = [call[0][0] for call in calls] assert "--personal-access-token" in auth_args assert "--oauth-app-token" in auth_args assert "--github-app-id" in auth_args # Check for either form of the github app key argument assert any("--github-app-key" in arg for arg in auth_args) def test_init_parser_adds_scoping_arguments(self): """Test that init_parser adds all scoping arguments""" mock_github_args = MagicMock() mock_github_args.subparsers = self.mock_subparsers mock_github_args.common_providers_parser = MagicMock() arguments.init_parser(mock_github_args) # Verify scoping arguments were added assert self.mock_scoping_group.add_argument.call_count == 2 # Check that all scoping arguments are present calls = self.mock_scoping_group.add_argument.call_args_list scoping_args = [call[0][0] for call in calls] assert "--repository" in scoping_args assert "--organization" in scoping_args def test_repository_argument_configuration(self): """Test that repository argument is configured correctly""" mock_github_args = MagicMock() mock_github_args.subparsers = self.mock_subparsers mock_github_args.common_providers_parser = MagicMock() arguments.init_parser(mock_github_args) # Find the repository argument call calls = self.mock_scoping_group.add_argument.call_args_list repo_call = None for call in calls: if call[0][0] == "--repository": repo_call = call break assert repo_call is not None # Check argument configuration kwargs = repo_call[1] assert kwargs["nargs"] == "*" assert kwargs["default"] is None assert kwargs["metavar"] == "REPOSITORY" assert "owner/repo-name" in kwargs["help"] def test_organization_argument_configuration(self): """Test that organization argument is configured correctly""" mock_github_args = MagicMock() mock_github_args.subparsers = self.mock_subparsers mock_github_args.common_providers_parser = MagicMock() arguments.init_parser(mock_github_args) # Find the organization argument call calls = self.mock_scoping_group.add_argument.call_args_list org_call = None for call in calls: if call[0][0] == "--organization": org_call = call break assert org_call is not None # Check argument configuration kwargs = org_call[1] assert kwargs["nargs"] == "*" assert kwargs["default"] is None assert kwargs["metavar"] == "ORGANIZATION" assert "Organization or user name" in kwargs["help"] class Test_GitHubArguments_Integration: def test_real_argument_parsing_no_scoping(self): """Test parsing arguments without scoping parameters""" parser = argparse.ArgumentParser() subparsers = parser.add_subparsers() common_parser = argparse.ArgumentParser(add_help=False) # Create a mock object that mimics the structure used by the init_parser function mock_github_args = MagicMock() mock_github_args.subparsers = subparsers mock_github_args.common_providers_parser = common_parser arguments.init_parser(mock_github_args) # Parse arguments without scoping args = parser.parse_args(["github", "--personal-access-token", "test-token"]) assert args.personal_access_token == "test-token" assert args.repository is None assert args.organization is None def test_real_argument_parsing_with_repository(self): """Test parsing arguments with repository scoping""" parser = argparse.ArgumentParser() subparsers = parser.add_subparsers() common_parser = argparse.ArgumentParser(add_help=False) mock_github_args = MagicMock() mock_github_args.subparsers = subparsers mock_github_args.common_providers_parser = common_parser arguments.init_parser(mock_github_args) # Parse arguments with repository scoping args = parser.parse_args( [ "github", "--personal-access-token", "test-token", "--repository", "owner1/repo1", "owner2/repo2", ] ) assert args.personal_access_token == "test-token" assert args.repository == ["owner1/repo1", "owner2/repo2"] assert args.organization is None def test_real_argument_parsing_with_organization(self): """Test parsing arguments with organization scoping""" parser = argparse.ArgumentParser() subparsers = parser.add_subparsers() common_parser = argparse.ArgumentParser(add_help=False) mock_github_args = MagicMock() mock_github_args.subparsers = subparsers mock_github_args.common_providers_parser = common_parser arguments.init_parser(mock_github_args) # Parse arguments with organization scoping args = parser.parse_args( [ "github", "--personal-access-token", "test-token", "--organization", "org1", "org2", ] ) assert args.personal_access_token == "test-token" assert args.repository is None assert args.organization == ["org1", "org2"] def test_real_argument_parsing_with_both_scoping(self): """Test parsing arguments with both repository and organization scoping""" parser = argparse.ArgumentParser() subparsers = parser.add_subparsers() common_parser = argparse.ArgumentParser(add_help=False) mock_github_args = MagicMock() mock_github_args.subparsers = subparsers mock_github_args.common_providers_parser = common_parser arguments.init_parser(mock_github_args) # Parse arguments with both scoping types args = parser.parse_args( [ "github", "--personal-access-token", "test-token", "--repository", "owner1/repo1", "--organization", "org1", ] ) assert args.personal_access_token == "test-token" assert args.repository == ["owner1/repo1"] assert args.organization == ["org1"] def test_real_argument_parsing_single_values(self): """Test parsing arguments with single repository and organization values""" parser = argparse.ArgumentParser() subparsers = parser.add_subparsers() common_parser = argparse.ArgumentParser(add_help=False) mock_github_args = MagicMock() mock_github_args.subparsers = subparsers mock_github_args.common_providers_parser = common_parser arguments.init_parser(mock_github_args) # Parse arguments with single values args = parser.parse_args( [ "github", "--personal-access-token", "test-token", "--repository", "owner1/repo1", "--organization", "org1", ] ) assert args.personal_access_token == "test-token" assert args.repository == ["owner1/repo1"] assert args.organization == ["org1"] def test_real_argument_parsing_empty_scoping(self): """Test parsing arguments with empty scoping values""" parser = argparse.ArgumentParser() subparsers = parser.add_subparsers() common_parser = argparse.ArgumentParser(add_help=False) mock_github_args = MagicMock() mock_github_args.subparsers = subparsers mock_github_args.common_providers_parser = common_parser arguments.init_parser(mock_github_args) # Parse arguments with empty scoping flags args = parser.parse_args( [ "github", "--personal-access-token", "test-token", "--repository", "--organization", ] ) assert args.personal_access_token == "test-token" assert args.repository == [] assert args.organization == []