def test_staff_user_can_filter_all_youth_profiles(rf, staff_user_gql_client): request = rf.post("/graphql") YouthProfileFactory.create_batch(2) youth_profile = YouthProfileFactory() request.user = staff_user_gql_client.user t = Template(""" query { youthProfiles(membershipNumber:"${number}") { totalCount count edges { node { id membershipNumber } } } } """) query = t.substitute(number=youth_profile.membership_number) executed = staff_user_gql_client.execute(query, context=request) assert executed["data"]["youthProfiles"]["totalCount"] == 3 assert executed["data"]["youthProfiles"]["count"] == 1
def test_superuser_can_view_all_youth_profiles(superuser_api_client): a_youth_profile = YouthProfileFactory() other_youth_profile = YouthProfileFactory() # noqa data = get(superuser_api_client, YOUTH_PROFILE_URL) results = data["results"] assert len(results) == YouthProfile.objects.count() get(superuser_api_client, get_youth_profile_url(a_youth_profile), status_code=200)
def test_normal_user_can_add_additional_contact_persons( rf, user_gql_client, phone_data ): profile = ProfileFactory(user=user_gql_client.user) YouthProfileFactory(profile=profile) acpd = AdditionalContactPersonDictFactory() request = rf.post("/graphql") request.user = user_gql_client.user variables = {"input": {"youthProfile": {"addAdditionalContactPersons": [acpd]}}} executed = user_gql_client.execute( UPDATE_MUTATION, context=request, variables=variables ) acp = AdditionalContactPerson.objects.first() expected_data = { "updateMyYouthProfile": { "youthProfile": { "additionalContactPersons": { "edges": [ { "node": { "id": to_global_id( type="AdditionalContactPersonNode", id=acp.pk ), **acpd, } } ] } } } } assert dict(executed["data"]) == expected_data
def test_normal_user_can_remove_additional_contact_persons( rf, user_gql_client, phone_data ): profile = ProfileFactory(user=user_gql_client.user) youth_profile = YouthProfileFactory(profile=profile) acp = AdditionalContactPersonFactory(youth_profile=youth_profile) request = rf.post("/graphql") request.user = user_gql_client.user variables = { "input": { "youthProfile": { "removeAdditionalContactPersons": [ to_global_id(type="AdditionalContactPersonNode", id=acp.pk) ] } } } executed = user_gql_client.execute( UPDATE_MUTATION, context=request, variables=variables ) expected_data = { "updateMyYouthProfile": { "youthProfile": {"additionalContactPersons": {"edges": []}} } } assert dict(executed["data"]) == expected_data
def test_query_extended_profile_nodes(rf, user_gql_client, youth_profile): request = rf.post("/graphql") request.user = user_gql_client.user youth_profile = YouthProfileFactory(user=user_gql_client.user) youth_profile_id = to_global_id("YouthProfileNode", youth_profile.id) profile_id = to_global_id("ProfileNode", youth_profile.id) variables = { "_representations": [{ "id": profile_id, "__typename": "ProfileNode" }] } executed = user_gql_client.execute(FEDERATED_PROFILES_QUERY, variables=variables, context=request) assert executed["data"]["_entities"][0] == { "id": profile_id, "youthProfile": { "id": youth_profile_id, "membershipNumber": youth_profile.membership_number, }, }
def test_normal_user_can_query_additional_contact_persons( rf, user_gql_client, snapshot ): profile = ProfileFactory(user=user_gql_client.user) youth_profile = YouthProfileFactory(profile=profile) acp = AdditionalContactPersonFactory(youth_profile=youth_profile) request = rf.post("/graphql") request.user = user_gql_client.user executed = user_gql_client.execute( ADDITIONAL_CONTACT_PERSONS_QUERY, context=request ) expected_data = { "youthProfile": { "additionalContactPersons": { "edges": [ { "node": { "id": to_global_id( type="AdditionalContactPersonNode", id=acp.pk ), "firstName": acp.first_name, "lastName": acp.last_name, "phone": acp.phone, "email": acp.email, } } ] } } } assert dict(executed["data"]) == expected_data
def test_staff_user_can_query_all_youth_profiles(rf, staff_user_gql_client): request = rf.post("/graphql") request.user = staff_user_gql_client.user YouthProfileFactory.create_batch(2) query = """ query { youthProfiles { totalCount edges { node { id } } } } """ executed = staff_user_gql_client.execute(query, context=request) assert executed["data"]["youthProfiles"]["totalCount"] == 2
def test_user_cannot_delete_other_youth_profiles(user_api_client, youth_profile): other_youth_profile = YouthProfileFactory() assert YouthProfile.objects.count() == 2 # Response status should be 404 as other profiles are hidden from the user delete(user_api_client, get_youth_profile_url(other_youth_profile), status_code=404) assert YouthProfile.objects.count() == 2
def test_user_can_see_only_own_youth_profile(user_api_client, youth_profile): other_youth_profile = YouthProfileFactory() data = get(user_api_client, YOUTH_PROFILE_URL) results = data["results"] assert len(results) == 1 assert YouthProfile.objects.count() > 1 get(user_api_client, get_youth_profile_url(other_youth_profile), status_code=404)
def test_youth_profile_returns_membership_status_and_renewable_flag( rf, user_gql_client): request = rf.post("/graphql") request.user = user_gql_client.user youth_profile = YouthProfileFactory(user=user_gql_client.user) query = """ { myYouthProfile { membershipStatus renewable } } """ expected_data = { "myYouthProfile": { "membershipStatus": "PENDING", "renewable": False } } executed = user_gql_client.execute(query, context=request) assert dict(executed["data"]) == expected_data youth_profile.set_approved() youth_profile.save() expected_data = { "myYouthProfile": { "membershipStatus": "ACTIVE", "renewable": False } } executed = user_gql_client.execute(query, context=request) assert dict(executed["data"]) == expected_data youth_profile.expiration = datetime.date.today() - datetime.timedelta( days=1) youth_profile.save() expected_data = { "myYouthProfile": { "membershipStatus": "EXPIRED", "renewable": True } } executed = user_gql_client.execute(query, context=request) assert dict(executed["data"]) == expected_data
def test_normal_user_cannot_query_all_youth_profiles(rf, gql_client): request = rf.post("/graphql") request.user = gql_client.user YouthProfileFactory.create_batch(2) query = """ query { youthProfiles { edges { node { id } } } } """ executed = gql_client.execute(query, context=request) expected_data = {"youthProfiles": None} assert dict(executed["data"]) == expected_data assert (executed["errors"][0].get("extensions").get("code") == PERMISSION_DENIED_ERROR)
def test_audit_log_create(user, caplog): caplog.clear() youth_profile = YouthProfileFactory() logs = get_log_records(caplog) assert len( logs) == 2 # profile is accessed here as well, thus the 2 log entries log_message = json.loads(logs[1]) assert_common_fields(log_message) assert log_message["audit_event"]["operation"] == "CREATE" assert log_message["audit_event"]["target"] == { "user_id": str(youth_profile.user.uuid), "user_name": youth_profile.user.username, "profile_id": str(youth_profile.pk), "profile_part": "YouthProfile", }
def test_audit_log_read(user, caplog): YouthProfileFactory() caplog.clear() youth_profile = YouthProfile.objects.first() logs = get_log_records(caplog) assert len(logs) == 1 log_message = json.loads(logs[0]) assert_common_fields(log_message) assert log_message["audit_event"]["operation"] == "READ" assert log_message["audit_event"]["target"] == { "user_id": str(youth_profile.user.uuid), "user_name": youth_profile.user.username, "profile_id": str(youth_profile.pk), "profile_part": "YouthProfile", }
def test_normal_user_can_update_additional_contact_persons( rf, user_gql_client): youth_profile = YouthProfileFactory(user=user_gql_client.user) acp = AdditionalContactPersonFactory(youth_profile=youth_profile) new_values = AdditionalContactPersonDictFactory() request = rf.post("/graphql") request.user = user_gql_client.user variables = { "input": { "youthProfile": { "updateAdditionalContactPersons": [{ "id": to_global_id(type="AdditionalContactPersonNode", id=acp.pk), **new_values, }], }, "profileApiToken": "token", } } executed = user_gql_client.execute(UPDATE_MUTATION, context=request, variables=variables) expected_data = { "updateMyYouthProfile": { "youthProfile": { "additionalContactPersons": { "edges": [{ "node": { "id": to_global_id(type="AdditionalContactPersonNode", id=acp.pk), **new_values, } }] } } } } assert dict(executed["data"]) == expected_data
def test_normal_user_cannot_query_someone_elses_youth_profile_by_id( rf, user_gql_client): request = rf.post("/graphql") request.user = user_gql_client.user youth_profile = YouthProfileFactory() profile_id = to_global_id(type="YouthProfileNode", id=youth_profile.pk) t = Template(""" { youthProfile(id: "${id}") { id schoolClass membershipNumber } } """) query = t.substitute(id=profile_id) expected_data = {"youthProfile": None} executed = user_gql_client.execute(query, context=request) assert dict(executed["data"]) == expected_data
def test_normal_user_can_query_my_youth_profile(rf, user_gql_client): request = rf.post("/graphql") request.user = user_gql_client.user youth_profile = YouthProfileFactory(user=user_gql_client.user) query = """ { myYouthProfile { id schoolClass membershipNumber } } """ expected_data = { "myYouthProfile": { "id": to_global_id(type="YouthProfileNode", id=youth_profile.pk), "schoolClass": youth_profile.school_class, "membershipNumber": youth_profile.membership_number, } } executed = user_gql_client.execute(query, context=request) assert dict(executed["data"]) == expected_data
def test_youth_profile_can_be_deleted_when_gdpr_api_disabled( rf, user_gql_client, service_factory, settings): """Deletion is allowed when youth profile is connected, GDPR URL is not set and GDPR API for youth profile is disabled. """ settings.GDPR_API_ENABLED = False youth_profile = YouthProfileFactory(profile__user=user_gql_client.user) profile = youth_profile.profile youth_service = service_factory(service_type=ServiceType.YOUTH_MEMBERSHIP, gdpr_url="") ServiceConnectionFactory(profile=profile, service=youth_service) request = rf.post("/graphql") request.user = user_gql_client.user executed = user_gql_client.execute(DELETE_MY_PROFILE_MUTATION, context=request) expected_data = {"deleteMyProfile": {"clientMutationId": None}} assert dict(executed["data"]) == expected_data with pytest.raises(Profile.DoesNotExist): profile.refresh_from_db() with pytest.raises(User.DoesNotExist): user_gql_client.user.refresh_from_db()
def test_audit_log_read_actor_role(user, role, caplog, staff_user, anon_user): youth_profile = YouthProfileFactory() if role == "SYSTEM": user = None elif role == "OWNER": user = youth_profile.user elif role == "ADMIN": user = staff_user elif role == "ANONYMOUS": user = anon_user caplog.clear() with impersonate(user): YouthProfile.objects.first() logs = get_log_records(caplog) assert len(logs) == 1 log_message = json.loads(logs[0]) assert log_message["audit_event"]["actor"]["role"] == role if user: assert log_message["audit_event"]["actor"]["user_id"] == (str( user.uuid) if user != anon_user else None) assert log_message["audit_event"]["actor"][ "user_name"] == user.username
def test_normal_user_can_query_own_youth_profile_by_id(rf, user_gql_client): request = rf.post("/graphql") request.user = user_gql_client.user youth_profile = YouthProfileFactory(user=user_gql_client.user) profile_id = to_global_id(type="YouthProfileNode", id=youth_profile.pk) t = Template(""" { youthProfile(id: "${id}") { id schoolClass membershipNumber } } """) query = t.substitute(id=profile_id) expected_data = { "youthProfile": { "id": profile_id, "schoolClass": youth_profile.school_class, "membershipNumber": youth_profile.membership_number, } } executed = user_gql_client.execute(query, context=request) assert dict(executed["data"]) == expected_data
def youth_profile(profile): return YouthProfileFactory(profile=profile)
def youth_profile(): return YouthProfileFactory()