1+ import pytest
2+ from unittest .mock import Mock , MagicMock , patch
3+ from cpk_lib_python_aws .aws_sso_auditor .auditor import AWSSSOAuditor , NullOutputSink
4+ from cpk_lib_python_aws .aws_sso_auditor .config import Config
5+ from cpk_lib_python_aws .aws_sso_auditor .exceptions import AWSSSOAuditorError
6+
7+
8+ class TestNullOutputSink :
9+ """Test the NullOutputSink class."""
10+
11+ def test_null_output_sink_methods (self ):
12+ """Test that all NullOutputSink methods can be called without error."""
13+ sink = NullOutputSink ()
14+
15+ # All methods should return None and not raise exceptions
16+ assert sink .progress ("test message" ) is None
17+ assert sink .debug_info ("test message" ) is None
18+ assert sink .warning ("test message" ) is None
19+ assert sink .info ("test message" ) is None
20+ assert sink .error ("test message" ) is None
21+
22+ """Test the AWSSSOAuditor class."""
23+
24+ @patch ('cpk_lib_python_aws.aws_sso_auditor.auditor.AWSClientManager' )
25+ def test_auditor_initialization_with_default_config (self , mock_aws_manager ):
26+ """Test auditor initialization with default configuration."""
27+ # Mock the AWS client manager
28+ mock_manager_instance = Mock ()
29+ mock_manager_instance .sso_admin_client = Mock ()
30+ mock_manager_instance .identitystore_client = Mock ()
31+ mock_manager_instance .organizations_client = Mock ()
32+ mock_manager_instance .identity_store_id = "d-123456789"
33+ mock_manager_instance .instance_arn = "arn:aws:sso:::instance/ssoins-123456789"
34+ mock_manager_instance .get_client_info .return_value = {"region" : "us-east-1" }
35+ mock_aws_manager .return_value = mock_manager_instance
36+
37+ auditor = AWSSSOAuditor ()
38+
39+ # Verify initialization
40+ assert auditor .config is not None
41+ assert isinstance (auditor .output_sink , NullOutputSink )
42+ assert auditor .identity_store_id == "d-123456789"
43+ assert auditor .instance_arn == "arn:aws:sso:::instance/ssoins-123456789"
44+
45+ @patch ('cpk_lib_python_aws.aws_sso_auditor.auditor.AWSClientManager' )
46+ def test_auditor_initialization_with_custom_config (self , mock_aws_manager ):
47+ """Test auditor initialization with custom configuration."""
48+ mock_manager_instance = Mock ()
49+ mock_manager_instance .sso_admin_client = Mock ()
50+ mock_manager_instance .identitystore_client = Mock ()
51+ mock_manager_instance .organizations_client = Mock ()
52+ mock_manager_instance .identity_store_id = "d-123456789"
53+ mock_manager_instance .instance_arn = "arn:aws:sso:::instance/ssoins-123456789"
54+ mock_manager_instance .get_client_info .return_value = {"region" : "us-west-2" }
55+ mock_aws_manager .return_value = mock_manager_instance
56+
57+ config = Config (aws_region = "us-west-2" , debug = True )
58+ output_sink = Mock ()
59+
60+ auditor = AWSSSOAuditor (config , output_sink )
61+
62+ assert auditor .config .aws_region == "us-west-2"
63+ assert auditor .config .debug is True
64+ assert auditor .output_sink == output_sink
65+
66+ @patch ('cpk_lib_python_aws.aws_sso_auditor.auditor.AWSClientManager' )
67+ def test_get_permission_sets_for_account_success (self , mock_aws_manager ):
68+ """Test successful retrieval of permission sets for account."""
69+ # Setup mocks
70+ mock_manager_instance = Mock ()
71+ mock_sso_client = Mock ()
72+ mock_paginator = Mock ()
73+
74+ mock_sso_client .get_paginator .return_value = mock_paginator
75+ mock_paginator .paginate .return_value = [
76+ {"PermissionSets" : ["arn:aws:sso:::permissionSet/ps-123" , "arn:aws:sso:::permissionSet/ps-456" ]}
77+ ]
78+
79+ mock_manager_instance .sso_admin_client = mock_sso_client
80+ mock_manager_instance .identitystore_client = Mock ()
81+ mock_manager_instance .organizations_client = Mock ()
82+ mock_manager_instance .identity_store_id = "d-123456789"
83+ mock_manager_instance .instance_arn = "arn:aws:sso:::instance/ssoins-123456789"
84+ mock_manager_instance .get_client_info .return_value = {"region" : "us-east-1" }
85+ mock_aws_manager .return_value = mock_manager_instance
86+
87+ auditor = AWSSSOAuditor ()
88+ result = auditor .get_permission_sets_for_account ("123456789012" )
89+
90+ assert len (result ) == 2
91+ assert "arn:aws:sso:::permissionSet/ps-123" in result
92+ assert "arn:aws:sso:::permissionSet/ps-456" in result
93+
94+ @patch ('cpk_lib_python_aws.aws_sso_auditor.auditor.AWSClientManager' )
95+ def test_get_permission_sets_for_account_failure (self , mock_aws_manager ):
96+ """Test handling of errors when retrieving permission sets."""
97+ # Setup mocks to raise exception
98+ mock_manager_instance = Mock ()
99+ mock_sso_client = Mock ()
100+ mock_sso_client .get_paginator .side_effect = Exception ("AWS API Error" )
101+
102+ mock_manager_instance .sso_admin_client = mock_sso_client
103+ mock_manager_instance .identitystore_client = Mock ()
104+ mock_manager_instance .organizations_client = Mock ()
105+ mock_manager_instance .identity_store_id = "d-123456789"
106+ mock_manager_instance .instance_arn = "arn:aws:sso:::instance/ssoins-123456789"
107+ mock_manager_instance .get_client_info .return_value = {"region" : "us-east-1" }
108+ mock_aws_manager .return_value = mock_manager_instance
109+
110+ auditor = AWSSSOAuditor ()
111+ result = auditor .get_permission_sets_for_account ("123456789012" )
112+
113+ # Should return empty list on error
114+ assert result == []
115+
116+ @patch ('cpk_lib_python_aws.aws_sso_auditor.auditor.AWSClientManager' )
117+ def test_get_group_details_success (self , mock_aws_manager ):
118+ """Test successful retrieval of group details."""
119+ mock_manager_instance = Mock ()
120+ mock_identity_client = Mock ()
121+
122+ mock_identity_client .describe_group .return_value = {
123+ "GroupId" : "group-123" ,
124+ "DisplayName" : "Test Group" ,
125+ "Description" : "A test group"
126+ }
127+
128+ mock_manager_instance .sso_admin_client = Mock ()
129+ mock_manager_instance .identitystore_client = mock_identity_client
130+ mock_manager_instance .organizations_client = Mock ()
131+ mock_manager_instance .identity_store_id = "d-123456789"
132+ mock_manager_instance .instance_arn = "arn:aws:sso:::instance/ssoins-123456789"
133+ mock_manager_instance .get_client_info .return_value = {"region" : "us-east-1" }
134+ mock_aws_manager .return_value = mock_manager_instance
135+
136+ auditor = AWSSSOAuditor ()
137+ result = auditor .get_group_details ("group-123" )
138+
139+ assert result ["GroupId" ] == "group-123"
140+ assert result ["DisplayName" ] == "Test Group"
141+ assert result ["Description" ] == "A test group"
142+
143+ @patch ('cpk_lib_python_aws.aws_sso_auditor.auditor.AWSClientManager' )
144+ def test_get_group_details_failure (self , mock_aws_manager ):
145+ """Test handling of errors when retrieving group details."""
146+ mock_manager_instance = Mock ()
147+ mock_identity_client = Mock ()
148+ mock_identity_client .describe_group .side_effect = Exception ("Group not found" )
149+
150+ mock_manager_instance .sso_admin_client = Mock ()
151+ mock_manager_instance .identitystore_client = mock_identity_client
152+ mock_manager_instance .organizations_client = Mock ()
153+ mock_manager_instance .identity_store_id = "d-123456789"
154+ mock_manager_instance .instance_arn = "arn:aws:sso:::instance/ssoins-123456789"
155+ mock_manager_instance .get_client_info .return_value = {"region" : "us-east-1" }
156+ mock_aws_manager .return_value = mock_manager_instance
157+
158+ auditor = AWSSSOAuditor ()
159+ result = auditor .get_group_details ("group-123" )
160+
161+ # Should return default values on error
162+ assert result ["GroupId" ] == "group-123"
163+ assert result ["DisplayName" ] == "Unknown"
164+ assert result ["Description" ] == ""
165+
166+
167+ @patch ('cpk_lib_python_aws.aws_sso_auditor.auditor.AWSClientManager' )
168+ def test_audit_account_basic_flow (self , mock_aws_manager ):
169+ """Test basic audit_account flow with minimal data."""
170+ mock_manager_instance = Mock ()
171+ mock_sso_client = Mock ()
172+ mock_identity_client = Mock ()
173+
174+ # Mock get_all_account_assignments to return empty list
175+ mock_manager_instance .sso_admin_client = mock_sso_client
176+ mock_manager_instance .identitystore_client = mock_identity_client
177+ mock_manager_instance .organizations_client = Mock ()
178+ mock_manager_instance .identity_store_id = "d-123456789"
179+ mock_manager_instance .instance_arn = "arn:aws:sso:::instance/ssoins-123456789"
180+ mock_manager_instance .get_client_info .return_value = {"region" : "us-east-1" }
181+ mock_aws_manager .return_value = mock_manager_instance
182+
183+ auditor = AWSSSOAuditor ()
184+
185+ # Mock the get_permission_sets_for_account to return empty list
186+ auditor .get_permission_sets_for_account = Mock (return_value = [])
187+
188+ result = auditor .audit_account ("123456789012" )
189+
190+ # Verify basic structure
191+ assert "metadata" in result
192+ assert "sso_groups" in result
193+ assert "permission_sets" in result
194+ assert "summary" in result
195+ assert result ["metadata" ]["account_id" ] == "123456789012"
196+ assert result ["summary" ]["total_groups" ] == 0
197+ assert result ["summary" ]["total_permission_sets" ] == 0
198+ assert result ["summary" ]["total_assignments" ] == 0
0 commit comments