import pytest from django.core.urlresolvers import reverse @pytest.fixture def organization_resource_creator(organization, user): def rf(users, admins, job_templates, projects, inventories, teams): # Associate one resource of every type with the organization for i in range(users): member_user = user('org-member %s' % i) organization.member_role.members.add(member_user) for i in range(admins): admin_user = user('org-admin %s' % i) organization.admin_role.members.add(admin_user) for i in range(teams): organization.teams.create(name='org-team %s' % i) for i in range(inventories): inventory = organization.inventories.create(name="associated-inv %s" % i) for i in range(projects): organization.projects.create(name="test-proj %s" % i, description="test-proj-desc") # Mix up the inventories and projects used by the job templates i_proj = 0 i_inv = 0 for i in range(job_templates): project = organization.projects.all()[i_proj] inventory = organization.inventories.all()[i_inv] project.jobtemplates.create(name="test-jt %s" % i, description="test-job-template-desc", inventory=inventory, playbook="test_playbook.yml") i_proj += 1 i_inv += 1 if i_proj >= organization.projects.count(): i_proj = 0 if i_inv >= organization.inventories.count(): i_inv = 0 return organization return rf COUNTS_PRIMES = { 'users': 11, 'admins': 5, 'job_templates': 3, 'projects': 3, 'inventories': 7, 'teams': 5 } COUNTS_ZEROS = { 'users': 0, 'admins': 0, 'job_templates': 0, 'projects': 0, 'inventories': 0, 'teams': 0 } @pytest.fixture def resourced_organization(organization_resource_creator): return organization_resource_creator(**COUNTS_PRIMES) @pytest.mark.django_db def test_org_counts_detail_admin(resourced_organization, user, get): # Check that all types of resources are counted by a superuser external_admin = user('admin', True) response = get(reverse('api:organization_detail', args=[resourced_organization.pk]), external_admin) assert response.status_code == 200 counts = response.data['summary_fields']['related_field_counts'] assert counts == COUNTS_PRIMES @pytest.mark.django_db def test_org_counts_detail_member(resourced_organization, user, get): # Check that a non-admin org member can only see users / admin in detail view member_user = resourced_organization.member_role.members.get(username='org-member 1') response = get(reverse('api:organization_detail', args=[resourced_organization.pk]), member_user) assert response.status_code == 200 counts = response.data['summary_fields']['related_field_counts'] assert counts == { 'users': COUNTS_PRIMES['users'], # Policy is that members can see other users and admins 'admins': COUNTS_PRIMES['admins'], 'job_templates': 0, 'projects': 0, 'inventories': 0, 'teams': 0 } @pytest.mark.django_db def test_org_counts_list_admin(resourced_organization, user, get): # Check that all types of resources are counted by a superuser external_admin = user('admin', True) response = get(reverse('api:organization_list', args=[]), external_admin) assert response.status_code == 200 counts = response.data['results'][0]['summary_fields']['related_field_counts'] assert counts == COUNTS_PRIMES @pytest.mark.django_db def test_org_counts_list_member(resourced_organization, user, get): # Check that a non-admin user can only see the full project and # user count, consistent with the RBAC rules member_user = resourced_organization.member_role.members.get(username='org-member 1') response = get(reverse('api:organization_list', args=[]), member_user) assert response.status_code == 200 counts = response.data['results'][0]['summary_fields']['related_field_counts'] assert counts == { 'users': COUNTS_PRIMES['users'], # Policy is that members can see other users and admins 'admins': COUNTS_PRIMES['admins'], 'job_templates': 0, 'projects': 0, 'inventories': 0, 'teams': 0 } @pytest.mark.django_db def test_new_org_zero_counts(user, post): # Check that a POST to the organization list endpoint returns # correct counts, including the new record org_list_url = reverse('api:organization_list', args=[]) post_response = post(url=org_list_url, data={'name': 'test organization', 'description': ''}, user=user('admin', True)) assert post_response.status_code == 201 new_org_list = post_response.render().data counts_dict = new_org_list['summary_fields']['related_field_counts'] assert counts_dict == COUNTS_ZEROS @pytest.mark.django_db def test_two_organizations(resourced_organization, organizations, user, get): # Check correct results for two organizations are returned external_admin = user('admin', True) organization_zero = organizations(1)[0] response = get(reverse('api:organization_list', args=[]), external_admin) assert response.status_code == 200 org_id_full = resourced_organization.id org_id_zero = organization_zero.id counts = {} for i in range(2): org_id = response.data['results'][i]['id'] counts[org_id] = response.data['results'][i]['summary_fields']['related_field_counts'] assert counts[org_id_full] == COUNTS_PRIMES assert counts[org_id_zero] == COUNTS_ZEROS @pytest.mark.django_db def test_scan_JT_counted(resourced_organization, user, get): admin_user = user('admin', True) # Add a scan job template to the org resourced_organization.projects.all()[0].jobtemplates.create( job_type='scan', inventory=resourced_organization.inventories.all()[0], name='scan-job-template') counts_dict = COUNTS_PRIMES counts_dict['job_templates'] += 1 # Test list view list_response = get(reverse('api:organization_list', args=[]), admin_user) assert list_response.status_code == 200 assert list_response.data['results'][0]['summary_fields']['related_field_counts'] == counts_dict # Test detail view detail_response = get(reverse('api:organization_detail', args=[resourced_organization.pk]), admin_user) assert detail_response.status_code == 200 assert detail_response.data['summary_fields']['related_field_counts'] == counts_dict @pytest.mark.django_db def test_JT_associated_with_project(organizations, project, user, get): # Check that adding a project to an organization gets the project's JT # included in the organization's JT count external_admin = user('admin', True) two_orgs = organizations(2) organization = two_orgs[0] other_org = two_orgs[1] unrelated_inv = other_org.inventories.create(name='not-in-organization') organization.projects.add(project) project.jobtemplates.create(name="test-jt", description="test-job-template-desc", inventory=unrelated_inv, playbook="test_playbook.yml") response = get(reverse('api:organization_list', args=[]), external_admin) assert response.status_code == 200 org_id = organization.id counts = {} for org_json in response.data['results']: working_id = org_json['id'] counts[working_id] = org_json['summary_fields']['related_field_counts'] assert counts[org_id] == { 'users': 0, 'admins': 0, 'job_templates': 1, 'projects': 1, 'inventories': 0, 'teams': 0 }