def test_get_post(self): """ GETting or POSTing the user_member_router redirects the user, based on who the User is: - if the request.user is an Organization User, the User is redirected to the org dashboard - if the request.user is a member, the User is redirected to the member dashboard - otherwise, the User is redirected to the org dashboard """ subtests = ( # has_org | has_member | member_has_org | expected_redirect # Does the | Does the | Does the request.user's | The url_name that # request.user have | request.user| Member have an association | the user should # an association with | have a | with an Organization? | be redirected to # an Organization? | Member? | | (True, False, False, 'org:dashboard'), (True, True, False, 'org:dashboard'), (True, True, True, 'org:dashboard'), (False, True, False, 'member:dashboard'), (False, True, True, 'member:dashboard'), (False, False, False, 'org:dashboard'), ) for (has_org, has_member, member_has_org, expected_redirect) in subtests: for method_name in ['get', 'post']: with self.subTest( method_name=method_name, has_org=has_org, has_member=has_member, member_has_org=member_has_org, expected_redirect=expected_redirect, ): self.user.refresh_from_db() if has_org: organization = OrganizationFactory() organization.users.add(self.user) else: self.user.organization_set.clear() if has_member: if not hasattr(self.user, 'member'): self.user.member = MemberFactory(user=self.user) if member_has_org: organization = OrganizationFactory() organization.members.add(self.user.member) else: self.user.member.organizations.clear() elif not has_member and hasattr(self.user, 'member'): self.user.member.delete() # Use the relevant method (GET or POST). method = getattr(self.client, method_name) response = method(self.url) self.assertRedirects(response, reverse(expected_redirect))
def test_post_invalid(self): """Invalid post conditions should results HTTP 422 Unprocessable entity * 'member' does not exist * 'organization' does not exist * 'status' is not in ['approve', 'deny', 'revoke'] """ request_url = reverse(self.url_name) with self.subTest( 'post with non-existing member results in error message'): new_user = UserFactory() new_user_pk = new_user.pk new_user.delete() # now we know they don't exist. response = self.client.post( request_url, { 'approve': 'Not gonna work', 'member': new_user_pk, 'organization': self.organizations[0].pk, }, ) self.assertEqual(response.status_code, 422) self.assertIn(b'member', response.content) # error with the member field with self.subTest( 'post with non-existing organization results in error message' ): new_org = OrganizationFactory() new_org_pk = new_org.pk new_org.delete() # now we know they don't exist. response = self.client.post( request_url, { 'approve': 'Not gonna work', 'member': self.user.pk, 'organization': new_org_pk, }, ) self.assertEqual(response.status_code, 422) self.assertIn( b'organization', response.content) # error with the organization field with self.subTest('post with wrong status results in error message'): response = self.client.post( request_url, { 'member': self.user.pk, 'organization': self.organizations[0].pk }, ) self.assertEqual(response.status_code, 422) self.assertIn(b'status', response.content) # error with the status field
def test_get_post(self): """ GETting or POSTing the user_router redirects the user, based on who the User is: - if the request.user is an Organization User, the User is redirected to the org dashboard - if the request.user is a member, the User is redirected to the member dashboard - otherwise, the User is redirected to the org dashboard """ subtests = ( # is_agent | is_member | expected_redirect # --------------------|---------------------|------------------------- # Is the request.user | Is the request.user | url_name that the user # an org agent? | an org member? | should be redirected to # --------------------|---------------------|------------------------- (True, False, 'org:dashboard'), (True, True, 'org:dashboard'), (False, True, 'member:dashboard'), (False, False, 'member:dashboard'), ) for (is_agent, is_member, expected_redirect) in subtests: for method_name in ['get', 'post']: with self.subTest( method_name=method_name, is_agent=is_agent, is_member=is_member, expected_redirect=expected_redirect, ): self.user.refresh_from_db() if is_agent: organization = OrganizationFactory() organization.agents.add(self.user) else: self.user.agent_organizations.clear() if is_member: organization = OrganizationFactory() organization.members.add(self.user) ResourceGrantFactory( organization=organization, member=self.user ) else: self.user.member_organizations.clear() self.user.resource_grants.all().delete() # Use the relevant method (GET or POST). method = getattr(self.client, method_name) response = method(self.url) self.assertRedirects(response, reverse(expected_redirect))
def give_user_access_to_member_token(self, user, member, provider_name): """ Give the user access to the member's access_token, and return access_token. This method creates necessary database objects so that the user is in an Organization that has a ResourceGrant for the member's Resource, so the user can use the member's access_token to get data about the member. """ # The user is a part of an Organization organization = OrganizationFactory() organization.agents.add(user) # The member has received an access_token to get their own data. provider_name = provider_name access_token = 'accessTOKENhere' UserSocialAuthFactory( user=member, provider=provider_name, extra_data={'refresh_token': 'refreshTOKEN', 'access_token': access_token}, ) # The member has approved the Organization's request for the member's data resource_request = ResourceRequestFactory( member=member, organization=organization, resourcegrant=None, status=REQUEST_APPROVED, ) ResourceGrantFactory( member=resource_request.member, organization=resource_request.organization, resource_class_path=resource_request.resource_class_path, resource_request=resource_request, )
def setUp(self): """set up organizations that will be used in the tests.""" super().setUp() # 3 orgs is sufficient self.organizations = [ OrganizationFactory(name="Org %d" % i) for i in range(1, 4) ]
def test_post_org_unauthorized(self): """posting dismissal of an org notification that the user is not an agent of returns 404""" org = OrganizationFactory() notification = Notification.objects.create(notify=org, actor=self.user, message="Notify the Org") response = self.client.post( reverse('notifications:dismiss', kwargs={'pk': notification.pk})) self.assertEqual(response.status_code, 404)
def test_post_org_valid(self): """posting dismissal of a notification to an org that the user is an agent for works""" org = OrganizationFactory() org.users.add(self.user) notification = Notification.objects.create(notify=org, actor=self.user, message="Notify Us") response = self.client.post( reverse('notifications:dismiss', kwargs={'pk': notification.pk})) notification.refresh_from_db() self.assertEqual(response.status_code, 302) self.assertTrue(notification.dismissed)
def test_get_permissions(self): """ A user may see a member's data sources, if: - the request.user is the member, or - the request.user is in an Organization that has an approved ResourceRequest for the member's data """ # Create a member member = UserFactory() # The member has received an access_token to get their own data. provider_name = Resource.name access_token = 'accessTOKENhere' UserSocialAuthFactory( user=member, provider=provider_name, extra_data={ 'refresh_token': 'refreshTOKEN', 'access_token': access_token }, ) # The URLs that will be used in this test member_data_url = reverse(self.url_name, kwargs={'pk': member.pk}) with self.subTest( "A member's data sources without an approved ResourceRequest"): # We mock the use of the requests library, so we don't make real # requests from within the test. with HTTMock(self.response_content_success): response = self.client.get(member_data_url) # The request.user does not have access to the member's data self.assertEqual(response.status_code, 302) with self.subTest( "A member's data sources with an approved ResourceRequest, other Organization" ): # The member has approved some Organization's request for the member's data organization = OrganizationFactory() resource_request = ResourceRequestFactory( member=member, organization=organization, resourcegrant=None, status=REQUEST_APPROVED, ) resource_grant = ResourceGrantFactory( member=resource_request.member, organization=resource_request.organization, resource_class_path=resource_request.resource_class_path, resource_request=resource_request, ) # We mock the use of the requests library, so we don't make real # requests from within the test. with HTTMock(self.response_content_success): response = self.client.get(member_data_url) # The request.user now has access to the member's data self.assertEqual(response.status_code, 302) with self.subTest( "A member's data sources with approved ResourceRequest from request.user's Organization" ): # The request.user is now in the organization organization.agents.add(self.user) # We mock the use of the requests library, so we don't make real # requests from within the test. with HTTMock(self.response_content_success): response = self.client.get(member_data_url) # The request.user does not have access to the member's data, since # the request.user is not in the organization. self.assertEqual(response.status_code, 200) with self.subTest('A member requesting their own data'): self.client.logout() self.client.force_login(member) # We mock the use of the requests library, so we don't make real # requests from within the test. with HTTMock(self.response_content_success): response = self.client.get(member_data_url) # The request.user has access to their own data, regardless of their # Organization. self.assertEqual(response.status_code, 200) # Even if we remove the ResourceRequest and ResourceGrant objects, # the member is allowed to see their own data. resource_request.delete() resource_grant.delete() with HTTMock(self.response_content_success): response = self.client.get(member_data_url) self.assertEqual(response.status_code, 200)