def test_flatten_violations(self):
        """Test flattening violations"""
        epas.get_user_emails = mock.MagicMock(return_value=TEST_EMAILS)
        violation1 = Rule.RuleViolation(
            resource_type=resource_mod.ResourceType.PROJECT,
            resource_id='12345',
            rule_name='Only my org',
            rule_index=0,
            rule_data=dict(ancestor_resources=[
                resource_util.create_resource('45678', 'organization')
            ]),
            full_name='projects/12345',
            violation_type='EXTERNAL_PROJECT_ACCESS_VIOLATION',
            member='*****@*****.**',
            resource_data=['projects/12345', 'organizations/67890'])

        scanner = epas.ExternalProjectAccessScanner(
            self.global_configs, self.scanner_configs, self.service_config,
            self.model_name, self.snapshot_timestamp, self.rules)
        flattened_iter = scanner._flatten_violations([violation1])

        flat_violation = flattened_iter.next()
        self.assertEqual(flat_violation['resource_id'], '12345')
        self.assertEqual(flat_violation['resource_type'],
                         resource_mod.ResourceType.PROJECT)
        self.assertEqual(flat_violation['rule_name'], 'Only my org')
        self.assertEqual(flat_violation['full_name'], 'projects/12345')
        self.assertEqual(flat_violation['violation_data']['member'],
                         '*****@*****.**')

        with self.assertRaises(StopIteration):
            flat_violation = flattened_iter.next()
    def test_retrieve(self, mock_crm_client):
        """Test retrieving project ancestry data"""
        list_to_generator = lambda x: (n for n in x)

        epas.get_user_emails = mock.MagicMock(return_value=TEST_EMAILS)

        scanner = epas.ExternalProjectAccessScanner(
            self.global_configs, self.scanner_configs, self.service_config,
            self.model_name, self.snapshot_timestamp, self.rules)

        mock_crm_client.get_projects.return_value = list_to_generator(
            [fake_crm_responses.FAKE_PROJECTS_API_RESPONSE1])
        mock_crm_client.get_project_ancestry.return_value = json.loads(
            fake_crm_responses.GET_PROJECT_ANCESTRY_RESPONSE)['ancestor']

        scanner._get_crm_client = mock.MagicMock()
        scanner._get_crm_client.return_value = mock_crm_client

        scanner.rules_engine.build_rule_book(
            self.service_config.get_inventory_config())

        user_ancestries = scanner._retrieve()

        self.assertIn('*****@*****.**', user_ancestries.keys())
        self.assertTrue(isinstance(user_ancestries['*****@*****.**'], list))
        self.assertTrue(
            isinstance(user_ancestries['*****@*****.**'][0], list))
        self.assertTrue(
            isinstance(user_ancestries['*****@*****.**'][0][0], Project))
    def test_find_violations(self):
        """Test finding violations"""
        epas.get_user_emails = mock.MagicMock(return_value=TEST_EMAILS)
        scanner = epas.ExternalProjectAccessScanner(
            self.global_configs, self.scanner_configs, self.service_config,
            self.model_name, self.snapshot_timestamp, self.rules)

        scanner.rules_engine.build_rule_book(
            self.service_config.get_inventory_config())
        user_ancestries = {
            '*****@*****.**':
            [[Project('1234'), Organization('1234567')],
             [Project('12345'),
              Folder('ABCDEFG'),
              Organization('HIJKLMNOP')]]
        }
        violations = scanner._find_violations(user_ancestries)
        self.assertEqual(len(violations), 2)