def test_field_types__specified__overrides_field_type(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateDogMutation(DjangoUpdateMutation): class Meta: model = Dog field_types = {"tag": graphene.Int()} @classmethod def handle_tag(self, value, *args, **kwargs): return f"Dog-{value}" class Mutations(graphene.ObjectType): update_dog = UpdateDogMutation.Field() dog = DogFactory.create() user = UserFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation UpdateDog( $id: ID!, $input: UpdateDogInput! ){ updateDog(id: $id, input: $input){ dog{ id } } } """ # Result with a string in the tag field should fail now result = schema.execute(mutation, variables={ "id": to_global_id("DogNode", dog.id), "input": { "name": "Sparky", "tag": "not-an-int", "breed": "HUSKY", "owner": to_global_id("UserNode", user.id) } }, context=Dict(user=user)) self.assertEqual(len(result.errors), 1) result = schema.execute(mutation, variables={ "id": to_global_id("DogNode", dog.id), "input": { "name": "Sparky", "breed": "HUSKY", "tag": 25, "owner": to_global_id("UserNode", user.id) } }, context=Dict(user=user)) self.assertIsNone(result.errors)
def test__many_to_one_relation_exists__creates_specified_fields(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class CreateDogMutation(DjangoCreateMutation): class Meta: model = Dog class Mutations(graphene.ObjectType): create_dog = CreateDogMutation.Field() user = UserFactory.create() cat = CatFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation CreateDog( $input: CreateDogInput! ){ createDog(input: $input){ dog{ id enemies{ edges{ node{ id } } } } } } """ result = schema.execute( mutation, variables={ "input": { "name": "Sparky", "breed": "HUSKY", "tag": "1234", "owner": to_global_id("UserNode", user.id), "enemies": [to_global_id("CatNode", cat.id)], }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) data = Dict(result.data) self.assertIsNone(result.errors) self.assertEqual(to_global_id("CatNode", cat.id), data.createDog.dog.enemies.edges[0].node.id) new_dog = Dog.objects.get(pk=disambiguate_id(data.createDog.dog.id)) # Load from database cat.refresh_from_db() self.assertEqual(cat, new_dog.enemies.first())
def test_many_to_one_extras__add_by_input__adds_by_input(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class CreateCatMutation(DjangoCreateMutation): class Meta: model = Cat class UpdateUserMutation(DjangoUpdateMutation): class Meta: model = User exclude_fields = ("password", ) many_to_one_extras = {"cats": {"add": {"type": "auto"}}} class Mutations(graphene.ObjectType): create_cat = CreateCatMutation.Field() update_user = UpdateUserMutation.Field() user = UserFactory.create() # Create some cats self.assertEqual(user.cats.all().count(), 0) schema = Schema(mutation=Mutations) mutation = """ mutation UpdateUser( $id: ID!, $input: UpdateUserInput! ){ updateUser(id: $id, input: $input){ user{ id } } } """ result = schema.execute(mutation, variables={ "id": to_global_id("UserNode", user.id), "input": { "username": user.username, "firstName": user.first_name, "lastName": user.last_name, "email": user.email, "catsAdd": [{ "name": "Cat damon" } for _ in range(5)] } }, context=Dict(user=user)) self.assertIsNone(result.errors) user.refresh_from_db() self.assertEqual(user.cats.all().count(), 5)
def test_check_permissions__override__uses_new_check_permissions_to_grant_access( self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateCatMutation(DjangoUpdateMutation): class Meta: model = Cat # This will be overridden permissions = ("tests.change_cat", ) @classmethod def check_permissions(cls, root, info, id, input) -> None: if input["name"] == "Name 2": raise ValueError("Cannot be Name 2") return None class Mutations(graphene.ObjectType): update_cat = UpdateCatMutation.Field() user = UserFactory.create() cat = CatFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation UpdateCat( $id: ID!, $input: UpdateCatInput! ){ updateCat(id: $id, input: $input){ cat{ id } } } """ result = schema.execute(mutation, variables={ "id": to_global_id("UserNode", user.id), "input": { "name": "Name 2", "owner": to_global_id("UserNode", user.id) } }, context=Dict(user=user)) self.assertEqual(len(result.errors), 1) result = schema.execute(mutation, variables={ "id": to_global_id("UserNode", user.id), "input": { "name": "Name 3", "owner": to_global_id("UserNode", user.id) } }, context=Dict(user=user)) self.assertIsNone(result.errors)
def test_many_to_many_extras__add_extra_by_input__adds_by_input(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class CreateCatMutation(DjangoCreateMutation): class Meta: model = Cat class UpdateDogMutation(DjangoUpdateMutation): class Meta: model = Dog many_to_many_extras = {"enemies": {"exact": {"type": "CreateCatInput"}}} class Mutations(graphene.ObjectType): create_cat = CreateCatMutation.Field() update_dog = UpdateDogMutation.Field() dog = DogFactory.create() user = UserFactory.create() # Create some enemies cats = CatFactory.create_batch(5) self.assertEqual(dog.enemies.all().count(), 0) schema = Schema(mutation=Mutations) mutation = """ mutation UpdateDog( $id: ID!, $input: UpdateDogInput! ){ updateDog(id: $id, input: $input){ dog{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("DogNode", dog.id), "input": { "name": "Sparky", "tag": "tag", "breed": "HUSKY", "owner": to_global_id("UserNode", user.id), "enemies": [ {"name": cat.name, "owner": cat.owner.id} for cat in cats ], }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) dog.refresh_from_db() self.assertEqual(dog.enemies.all().count(), 5)
def test_get_permissions__list_with_permissions__requires_returned_permissions( self, ): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateCatMutation(DjangoUpdateMutation): class Meta: model = Cat @classmethod def get_permissions(cls, root, info, *args, **kwargs): return ["tests.change_cat"] class Mutations(graphene.ObjectType): update_cat = UpdateCatMutation.Field() user = UserFactory.create() user_with_permissions = UserWithPermissionsFactory.create( permissions=["tests.change_cat"]) cat = CatFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation UpdateCat( $id: ID!, $input: UpdateCatInput! ){ updateCat(id: $id, input: $input){ cat{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("CatNode", cat.id), "input": { "name": "Name", "owner": to_global_id("UserNode", user.id) }, }, context=Dict(user=user), ) self.assertEqual(len(result.errors), 1) result = schema.execute( mutation, variables={ "id": to_global_id("CatNode", cat.id), "input": { "name": "Name", "owner": to_global_id("UserNode", user.id) }, }, context=Dict(user=user_with_permissions), ) self.assertIsNone(result.errors)
def test_mutate__objects_exists__updates(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class BatchPatchDogMutation(DjangoBatchPatchMutation): class Meta: model = Dog class Mutations(graphene.ObjectType): batch_patch_dog = BatchPatchDogMutation.Field() dog_1 = DogFactory.create() dog_2 = DogFactory.create() user = UserFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation BatchPatchDog( $input: [BatchPatchDogInput]! ){ batchPatchDog(input: $input){ dogs{ id name } } } """ result = schema.execute(mutation, variables={ "input": [ { "id": to_global_id("DogNode", dog_1.id), "name": "New name 1", }, { "id": to_global_id("DogNode", dog_2.id), "name": "New name 2", }, ] }, context=Dict(user=user)) self.assertIsNone(result.errors) dogs = result.data["batchPatchDog"]["dogs"] dog_1_result = dogs[0] dog_2_result = dogs[1] self.assertEqual("New name 1", dog_1_result["name"]) self.assertEqual("New name 2", dog_2_result["name"]) dog_1.refresh_from_db() dog_2.refresh_from_db() self.assertEqual("New name 1", dog_1.name) self.assertEqual("New name 2", dog_2.name)
def test__one_to_one_relation_exists__creates_specified_fields(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class CreateDogMutation(DjangoCreateMutation): class Meta: model = Dog one_to_one_extras = {"registration": {"type": "auto"}} class Mutations(graphene.ObjectType): create_dog = CreateDogMutation.Field() user = UserFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation CreateDog( $input: CreateDogInput! ){ createDog(input: $input){ dog{ id registration{ id registrationNumber } } } } """ result = schema.execute( mutation, variables={ "input": { "name": "Sparky", "breed": "HUSKY", "tag": "1234", "owner": to_global_id("UserNode", user.id), "registration": { "registrationNumber": "12345" }, }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) data = Dict(result.data) self.assertIsNone(result.errors) self.assertEqual("12345", data.createDog.dog.registration.registrationNumber) # Load from database dog = Dog.objects.get(pk=disambiguate_id(data.createDog.dog.id)) registration = getattr(dog, "registration", None) self.assertIsNotNone(registration) self.assertEqual(registration.registration_number, "12345")
def test_validate__validate_field_raises__returns_error(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateCatMutation(DjangoUpdateMutation): class Meta: model = Cat @classmethod def validate_name(cls, root, info, value, input, id, obj): owner = User.objects.get(pk=disambiguate_id(input["owner"])) if value == owner.get_full_name(): raise ValueError("Cat must have different name than owner") class Mutations(graphene.ObjectType): update_cat = UpdateCatMutation.Field() user = UserFactory.create(first_name="John", last_name="Doe") cat = CatFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation UpdateCat( $id: ID!, $input: UpdateCatInput! ){ updateCat(id: $id, input: $input){ cat{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("UserNode", user.id), "input": { "name": "John Doe", "owner": to_global_id("UserNode", user.id), }, }, context=Dict(user=user), ) self.assertEqual(len(result.errors), 1) result = schema.execute( mutation, variables={ "id": to_global_id("UserNode", user.id), "input": { "name": "Kitty", "owner": to_global_id("UserNode", user.id) }, }, context=Dict(user=user), ) self.assertIsNone(result.errors)
def test_many_to_many_extras__type_auto__makes_it_possible_to_add_new_full_objects( self, ): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateDogMutation(DjangoUpdateMutation): class Meta: model = Dog many_to_many_extras = {"enemies": {"add": {"type": "auto"}}} class Mutations(graphene.ObjectType): update_dog = UpdateDogMutation.Field() dog = DogFactory.create() user = UserFactory.create() self.assertEqual(dog.enemies.all().count(), 0) schema = Schema(mutation=Mutations) mutation = """ mutation UpdateDog( $id: ID!, $input: UpdateDogInput! ){ updateDog(id: $id, input: $input){ dog{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("DogNode", dog.id), "input": { "name": "Sparky", "tag": "tag", "breed": "HUSKY", "owner": to_global_id("UserNode", user.id), "enemiesAdd": [{ "name": "Meowington", "owner": to_global_id("UserNode", user.id), }], }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) dog.refresh_from_db() self.assertEqual(dog.enemies.all().count(), 1)
def test_auto_type__with_proper_setup__generates_new_auto_type(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateDogMutation(DjangoUpdateMutation): class Meta: model = Dog foreign_key_extras = { "owner": { "type": "auto", "exclude_fields": ["password"] } } class Mutations(graphene.ObjectType): update_dog = UpdateDogMutation.Field() dog = DogFactory.create() user = UserFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation UpdateDog( $id: ID!, $input: UpdateDogInput! ){ updateDog(id: $id, input: $input){ dog{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("DogNode", dog.id), "input": { "name": "Sparky", "tag": "tag", "breed": "HUSKY", "owner": { "username": "******", "email": "*****@*****.**", "firstName": "Tormod", "lastName": "Haugland", }, }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) dog.refresh_from_db() self.assertEqual("*****@*****.**", dog.owner.email)
def test_many_to_one_extras__add_by_input__adds_by_input(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class CreateCatMutation(DjangoCreateMutation): class Meta: model = Cat class CreateUserMutation(DjangoCreateMutation): class Meta: model = User exclude_fields = ("password", ) many_to_one_extras = {"cats": {"add": {"type": "auto"}}} class Mutations(graphene.ObjectType): create_cat = CreateCatMutation.Field() create_user = CreateUserMutation.Field() user = UserFactory.build() schema = Schema(mutation=Mutations) mutation = """ mutation CreateUser( $input: CreateUserInput! ){ createUser(input: $input){ user{ id } } } """ result = schema.execute(mutation, variables={ "input": { "username": user.username, "firstName": user.first_name, "lastName": user.last_name, "email": user.email, "catsAdd": [{ "name": "Cat Damon" } for _ in range(5)] } }, context=Dict(user=user)) self.assertIsNone(result.errors) data = Dict(result.data) user = User.objects.get(pk=disambiguate_id(data.createUser.user.id)) self.assertEqual(user.cats.all().count(), 5)
def test__filter_update__updates(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class FilterUpdateDogMutation(DjangoFilterUpdateMutation): class Meta: model = Dog filter_fields = ("name", "name__startswith") class Mutations(graphene.ObjectType): filter_update_dogs = FilterUpdateDogMutation.Field() dog = DogFactory.create(name="Simen") user = UserFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation FilterUpdateDog( $filter: FilterUpdateDogFilterInput!, $data: FilterUpdateDogDataInput! ){ filterUpdateDogs(filter: $filter, data: $data){ updatedCount updatedObjects{ id name tag } } } """ result = schema.execute( mutation, variables={ "filter": { "name_Startswith": "Sim" }, "data": { "tag": "New tag" }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) self.assertEqual( 1, len(result.data["filterUpdateDogs"]["updatedObjects"])) dog_result = result.data["filterUpdateDogs"]["updatedObjects"][0] self.assertEqual("New tag", dog_result["tag"]) dog.refresh_from_db() self.assertEqual("New tag", dog.tag)
def test_many_to_many_extras__calling_exact_with_empty_list__resets_relation(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class PatchDogMutation(DjangoPatchMutation): class Meta: model = Dog many_to_many_extras = {"enemies": {"exact": {"type": "ID"}}} class Mutations(graphene.ObjectType): patch_dog = PatchDogMutation.Field() dog = DogFactory.create() user = UserFactory.create() # Create some enemies cats = CatFactory.create_batch(5) dog.enemies.set(cats) self.assertEqual(dog.enemies.all().count(), 5) schema = Schema(mutation=Mutations) mutation = """ mutation PatchDog( $id: ID!, $input: PatchDogInput! ){ patchDog(id: $id, input: $input){ dog{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("DogNode", dog.id), "input": { "name": "Sparky", "tag": "tag", "breed": "HUSKY", "owner": to_global_id("UserNode", user.id), "enemies": [], }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) dog.refresh_from_db() self.assertEqual(dog.enemies.all().count(), 0)
def test_many_to_one_extras__remove_nullable_field__removes_by_id(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateUserMutation(DjangoUpdateMutation): class Meta: model = User exclude_fields = ("password",) many_to_one_extras = {"mice": {"remove": {"type": "ID"}}} class Mutations(graphene.ObjectType): update_user = UpdateUserMutation.Field() user = UserFactory.create() # Create some enemies mice = MouseFactory.create_batch(5, keeper=user) user.mice.set(mice) self.assertEqual(user.mice.all().count(), 5) schema = Schema(mutation=Mutations) mutation = """ mutation UpdateUser( $id: ID!, $input: UpdateUserInput! ){ updateUser(id: $id, input: $input){ user{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("UserNode", user.id), "input": { "username": user.username, "firstName": user.first_name, "lastName": user.last_name, "email": user.email, "miceRemove": [mouse.id for mouse in mice], }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) user.refresh_from_db() self.assertEqual(user.mice.all().count(), 0)
def test_many_to_one_extras__remove_extra_by_id__removes_by_id(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class PatchUserMutation(DjangoPatchMutation): class Meta: model = User exclude_fields = ("password",) many_to_one_extras = {"cats": {"remove": {"type": "ID"}}} class Mutations(graphene.ObjectType): patch_user = PatchUserMutation.Field() user = UserFactory.create() # Create some enemies cats = CatFactory.create_batch(5) user.cats.set(cats) self.assertEqual(user.cats.all().count(), 5) schema = Schema(mutation=Mutations) mutation = """ mutation PatchUser( $id: ID!, $input: PatchUserInput! ){ patchUser(id: $id, input: $input){ user{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("UserNode", user.id), "input": { "username": user.username, "firstName": user.first_name, "lastName": user.last_name, "email": user.email, "catsRemove": [cat.id for cat in cats], }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) user.refresh_from_db() self.assertEqual(user.cats.all().count(), 0)
def test_many_to_many_extras__calling_exact_with_empty_list__resets_relation( self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateCatMutation(DjangoUpdateMutation): class Meta: model = Cat many_to_many_extras = {"enemies": {"exact": {"type": "ID"}}} class Mutations(graphene.ObjectType): update_cat = UpdateCatMutation.Field() cat = CatFactory.create() user = UserFactory.create() # Create some enemies dog = DogFactory.create_batch(5) cat.enemies.set(dog) self.assertEqual(cat.enemies.all().count(), 5) schema = Schema(mutation=Mutations) mutation = """ mutation UpdateCat( $id: ID!, $input: UpdateCatInput! ){ updateCat(id: $id, input: $input){ cat{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("CatNode", cat.id), "input": { "name": "Garfield", "owner": to_global_id("UserNode", user.id), "enemies": [], }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) cat.refresh_from_db() self.assertEqual(cat.enemies.all().count(), 0)
def test_many_to_one_extras__auto_calling_mutation_with_setting_field__does_nothing( self, ): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateUserMutation(DjangoUpdateMutation): class Meta: model = User exclude_fields = ("password",) many_to_one_extras = {"cats": {"exact": {"type": "auto"}}} class Mutations(graphene.ObjectType): update_user = UpdateUserMutation.Field() user = UserFactory.create() self.assertEqual(user.cats.all().count(), 0) schema = Schema(mutation=Mutations) mutation = """ mutation UpdateUser( $id: ID!, $input: UpdateUserInput! ){ updateUser(id: $id, input: $input){ user{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("UserNode", user.id), "input": { "username": user.username, "firstName": user.first_name, "lastName": user.last_name, "email": user.email, }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) user.refresh_from_db() self.assertEqual(user.cats.all().count(), 0)
def test_many_to_many_extras__add_extra_by_id__adds_by_id(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class PatchCatMutation(DjangoPatchMutation): class Meta: model = Cat many_to_many_extras = {"enemies": {"add": {"type": "ID"}}} class Mutations(graphene.ObjectType): patch_cat = PatchCatMutation.Field() cat = CatFactory.create() user = UserFactory.create() # Create some enemies dog = DogFactory.create_batch(5) self.assertEqual(cat.enemies.all().count(), 0) schema = Schema(mutation=Mutations) mutation = """ mutation PatchCat( $id: ID!, $input: PatchCatInput! ){ patchCat(id: $id, input: $input){ cat{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("CatNode", cat.id), "input": { "name": "Garfield", "owner": to_global_id("UserNode", user.id), "enemiesAdd": [dog.id for dog in dog], }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) cat.refresh_from_db() self.assertEqual(cat.enemies.all().count(), 5)
def test_default_setup__adding_resource_by_id__adds_resource(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateCatMutation(DjangoUpdateMutation): class Meta: model = Cat class Mutations(graphene.ObjectType): update_cat = UpdateCatMutation.Field() cat = CatFactory.create() user = UserFactory.create() dog = DogFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation UpdateCat( $id: ID!, $input: UpdateCatInput! ){ updateCat(id: $id, input: $input){ cat{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("CatNode", cat.id), "input": { "name": "Garfield", "owner": to_global_id("UserNode", user.id), "enemies": [to_global_id("DogNode", dog.id)], }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) cat.refresh_from_db() self.assertEqual(cat.enemies.all().count(), 1)
def test__ids_does_not_exist__only_deletes_relevant_objects(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class BatchDeleteUserMutation(DjangoBatchDeleteMutation): class Meta: model = User class Mutations(graphene.ObjectType): batch_delete_user = BatchDeleteUserMutation.Field() users = UserFactory.create_batch(10) selection = random.sample(users, k=5) non_existing_ids = list(range(-1, -5)) ids_to_delete = [user.id for user in selection] + non_existing_ids schema = Schema(mutation=Mutations) mutation = """ mutation BatchDeleteUser( $ids: [ID]!, ){ batchDeleteUser(ids: $ids){ deletedIds missedIds deletionCount } } """ result = schema.execute( mutation, variables={"ids": ids_to_delete}, ) data = Dict(result.data) self.assertEqual(5, data.batchDeleteUser.deletionCount) self.assertListEqual( list(sorted([str(user.id) for user in selection])), list(sorted(disambiguate_ids(data.batchDeleteUser.deletedIds))), ) self.assertListEqual( non_existing_ids, list(sorted(disambiguate_ids(data.batchDeleteUser.missedIds))), )
def test_get_permissions__empty_list__overrides_and_grants_access(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateCatMutation(DjangoUpdateMutation): class Meta: model = Cat # This will be overridden permissions = ("tests.change_cat", ) @classmethod def get_permissions(cls, root, info, *args, **kwargs): return [] class Mutations(graphene.ObjectType): update_cat = UpdateCatMutation.Field() user = UserFactory.create() cat = CatFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation UpdateCat( $id: ID!, $input: UpdateCatInput! ){ updateCat(id: $id, input: $input){ cat{ id } } } """ result = schema.execute(mutation, variables={ "id": to_global_id("UserNode", user.id), "input": { "name": "Name", "owner": to_global_id("UserNode", user.id) } }, context=Dict(user=user)) self.assertIsNone(result.errors)
def test_validate__validate_field_does_nothing__passes(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateCatMutation(DjangoUpdateMutation): class Meta: model = Cat @classmethod def validate_name(cls, root, info, value, input, id, obj): pass class Mutations(graphene.ObjectType): update_cat = UpdateCatMutation.Field() user = UserFactory.create() cat = CatFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation UpdateCat( $id: ID!, $input: UpdateCatInput! ){ updateCat(id: $id, input: $input){ cat{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("UserNode", user.id), "input": { "name": "Name", "owner": to_global_id("UserNode", user.id) }, }, context=Dict(user=user), ) self.assertIsNone(result.errors)
def test_permissions__user_has_no_permission__returns_error(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateCatMutation(DjangoUpdateMutation): class Meta: model = Cat permissions = ("tests.change_cat", ) class Mutations(graphene.ObjectType): update_cat = UpdateCatMutation.Field() user = UserFactory.create() cat = CatFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation UpdateCat( $id: ID!, $input: UpdateCatInput! ){ updateCat(id: $id, input: $input){ cat{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("CatNode", cat.id), "input": { "name": "Name", "owner": to_global_id("UserNode", user.id) }, }, context=Dict(user=user), ) self.assertEqual(len(result.errors), 1)
def test_muate__user_misses_permission__fails(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class DeleteCatMutation(DjangoDeleteMutation): class Meta: model = Cat permissions = ("tests.delete_cat", ) class Mutations(graphene.ObjectType): delete_cat = DeleteCatMutation.Field() user = UserFactory.create() cat = CatFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation DeleteCat( $id: ID! ){ deleteCat(id: $id){ found deletedId } } """ result = schema.execute( mutation, variables={ "id": to_global_id("CatNode", cat.id), # Notably, owner is omitted "input": { "name": "New name" }, }, context=Dict(user=user), ) self.assertIsNotNone(result.errors) self.assertIn("Not permitted", str(result.errors))
def test_get_permissions__conditional_list__requires_returned_permissions(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class PatchCatMutation(DjangoPatchMutation): class Meta: model = Cat @classmethod def get_permissions(cls, root, info, input, id, *args, **kwargs): owner_id = int(disambiguate_id(input["owner"])) if info.context.user.id == owner_id: return [] return ["tests.change_cat"] class Mutations(graphene.ObjectType): patch_cat = PatchCatMutation.Field() user = UserFactory.create() new_cat_owner = UserFactory.create() cat = CatFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation PatchCat( $id: ID!, $input: PatchCatInput! ){ patchCat(id: $id, input: $input){ cat{ id } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("CatNode", cat.id), "input": { "name": "Name", "owner": to_global_id("UserNode", new_cat_owner.id), }, }, context=Dict(user=user), ) self.assertEqual(len(result.errors), 1) result = schema.execute( mutation, variables={ "id": to_global_id("CatNode", cat.id), "input": { "name": "Name", "owner": to_global_id("UserNode", new_cat_owner.id), }, }, context=Dict(user=new_cat_owner), ) self.assertIsNone(result.errors)
def test_custom_field__separate_from_model_fields__adds_new_field_which_can_be_handled( self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class CreateDogMutation(DjangoCreateMutation): class Meta: model = Dog custom_fields = {"bark": graphene.Boolean()} @classmethod def before_save(cls, root, info, input, obj): if input.get("bark"): obj.bark_count += 1 return obj class Mutations(graphene.ObjectType): create_dog = CreateDogMutation.Field() dog = DogFactory.create() user = UserFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation CreateDog( $input: CreateDogInput! ){ createDog(input: $input){ dog{ id barkCount } } } """ self.assertEqual(0, dog.bark_count) result = schema.execute( mutation, variables={ "input": { "name": "Sparky", "tag": "tag", "breed": "HUSKY", "bark": True, "owner": to_global_id("UserNode", user.id) }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) self.assertEqual(1, result.data["createDog"]["dog"]["barkCount"]) result = schema.execute( mutation, variables={ "input": { "name": "Sparky", "tag": "tag-2", "breed": "HUSKY", "owner": to_global_id("UserNode", user.id) }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) self.assertEqual(0, result.data["createDog"]["dog"]["barkCount"])
def test__many_to_one_relation_exists__creates_specified_fields(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class CreateUserMutation(DjangoCreateMutation): class Meta: model = User exclude_fields = ("password", ) class Mutations(graphene.ObjectType): create_user = CreateUserMutation.Field() user = UserFactory.create() cat = CatFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation CreateUser( $input: CreateUserInput! ){ createUser(input: $input){ user{ id cats{ edges{ node{ id } } } } } } """ result = schema.execute( mutation, variables={ "input": { "username": "******", "email": "*****@*****.**", "firstName": "John", "lastName": "Doe", "cats": [to_global_id("CatNode", cat.id)], }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) data = Dict(result.data) self.assertIsNone(result.errors) self.assertEqual(to_global_id("CatNode", cat.id), data.createUser.user.cats.edges[0].node.id) new_user = User.objects.get( pk=disambiguate_id(data.createUser.user.id)) # Load from database cat.refresh_from_db() self.assertEqual(cat, new_user.cats.first())
def test__reverse_one_to_one_exists__updates_specified_fields(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class CreateDogRegistrationMutation(DjangoCreateMutation): class Meta: model = DogRegistration one_to_one_extras = {"dog": {"type": "auto"}} class Mutations(graphene.ObjectType): create_dog_registration = CreateDogRegistrationMutation.Field() user = UserFactory.create() schema = Schema(mutation=Mutations) mutation = """ mutation CreateDogRegistration( $input: CreateDogRegistrationInput! ){ createDogRegistration(input: $input){ dogRegistration{ id registrationNumber dog{ id name tag breed } } } } """ result = schema.execute( mutation, variables={ "input": { "registrationNumber": "12345", "dog": { "name": "Sparky", "breed": "LABRADOR", "tag": "1234", "owner": user.id, }, }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) data = Dict(result.data) dog_registration = data.createDogRegistration.dogRegistration dog = data.createDogRegistration.dogRegistration.dog self.assertEqual("Sparky", dog.name) self.assertEqual("LABRADOR", dog.breed) self.assertEqual("1234", dog.tag) self.assertEqual("12345", dog_registration.registrationNumber) # Load from database dog_registration = DogRegistration.objects.get( pk=disambiguate_id(dog_registration.id)) dog = getattr(dog_registration, "dog", None) self.assertIsNotNone(dog) self.assertEqual(dog.name, "Sparky") self.assertEqual(dog.tag, "1234")
def test__reverse_one_to_one_exists__updates_specified_fields(self): # This registers the UserNode type # noinspection PyUnresolvedReferences from .schema import UserNode class UpdateDogRegistrationMutation(DjangoUpdateMutation): class Meta: model = DogRegistration one_to_one_extras = {"dog": {"type": "auto"}} class Mutations(graphene.ObjectType): update_dog_registration = UpdateDogRegistrationMutation.Field() user = UserFactory.create() dog = DogFactory.create(breed="HUSKY") dog_registration = DogRegistration.objects.create( dog=dog, registration_number="1234") schema = Schema(mutation=Mutations) mutation = """ mutation UpdateDogRegistration( $id: ID!, $input: UpdateDogRegistrationInput! ){ updateDogRegistration(id: $id, input: $input){ dogRegistration{ id registrationNumber dog{ id breed } } } } """ result = schema.execute( mutation, variables={ "id": to_global_id("DogRegistrationNode", dog_registration.id), "input": { "registrationNumber": dog_registration.registration_number, "dog": { "name": dog.name, "breed": "LABRADOR", "tag": dog.tag, "owner": to_global_id("UserNode", dog.owner.id), }, }, }, context=Dict(user=user), ) self.assertIsNone(result.errors) data = Dict(result.data) self.assertEqual("LABRADOR", data.updateDogRegistration.dogRegistration.dog.breed) # Load from database dog_registration.refresh_from_db() dog.refresh_from_db() self.assertEqual(dog.breed, "LABRADOR")