def test_remove_products_from_collection( staff_api_client, collection, product_list, permission_manage_products): query = """ mutation collectionRemoveProducts( $id: ID!, $products: [ID]!) { collectionRemoveProducts(collectionId: $id, products: $products) { collection { products { totalCount } } } } """ collection.products.add(*product_list) collection_id = to_global_id('Collection', collection.id) product_ids = [ to_global_id('Product', product.pk) for product in product_list] no_products_before = collection.products.count() variables = {'id': collection_id, 'products': product_ids} response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products]) content = get_graphql_content(response) data = content['data']['collectionRemoveProducts']['collection'] assert data[ 'products']['totalCount'] == no_products_before - len(product_ids)
def test_get_nodes(product_list): global_ids = [ to_global_id('Product', product.pk) for product in product_list] # Make sure function works even if duplicated ids are provided global_ids.append(to_global_id('Product', product_list[0].pk)) # Return products corresponding to global ids products = get_nodes(global_ids, Product) assert products == product_list # Raise an error if requested id has no related database object nonexistent_item = Mock(type='Product', pk=123) nonexistent_item_global_id = to_global_id( nonexistent_item.type, nonexistent_item.pk) global_ids.append(nonexistent_item_global_id) msg = 'There is no node of type {} with pk {}'.format( nonexistent_item.type, nonexistent_item.pk) with pytest.raises(AssertionError, message=msg): get_nodes(global_ids, Product) global_ids.pop() # Raise an error if one of the node is of wrong type invalid_item = Mock(type='test', pk=123) invalid_item_global_id = to_global_id(invalid_item.type, invalid_item.pk) global_ids.append(invalid_item_global_id) with pytest.raises(AssertionError, message='Must receive an Product id.'): get_nodes(global_ids, Product) # Raise an error if no nodes were found global_ids = [] msg = 'Could not resolve to a nodes with the global id list of {}.'.format( global_ids) with pytest.raises(Exception, message=msg): get_nodes(global_ids, Product)
def test_remove_products_from_collection( admin_api_client, collection, product_list): query = """ mutation collectionRemoveProducts( $id: ID!, $products: [ID]!) { collectionRemoveProducts(collectionId: $id, products: $products) { collection { products { totalCount } } } } """ collection.products.add(*product_list) collection_id = to_global_id('Collection', collection.id) product_ids = [ to_global_id('Product', product.pk) for product in product_list] no_products_before = collection.products.count() variables = json.dumps( {'id': collection_id, 'products': product_ids}) response = admin_api_client.post( reverse('api'), {'query': query, 'variables': variables}) content = get_graphql_content(response) assert 'errors' not in content data = content['data']['collectionRemoveProducts']['collection'] assert data[ 'products']['totalCount'] == no_products_before - len(product_ids)
def test_latest_comments_query(self, db, comment): query = ''' query { latestComments { edges { node { id content user { id username } post { id title } } } } } ''' result = schema.execute(query) assert not result.errors assert result.data['latestComments']['edges'][0]['node']['id'] == to_global_id('CommentType', comment.id) assert result.data['latestComments']['edges'][0]['node']['user']['id'] == to_global_id('UserType', comment.user.id) assert result.data['latestComments']['edges'][0]['node']['post']['id'] == to_global_id('PostType', comment.post.id)
def test_all_posts_query(self, db, comment): query = ''' query { allPosts (orderBy: {field: CREATED_AT, direction: DESC}, offset: 0){ edges { node { id title user { id username } comments (orderBy: {field: CREATED_AT, direction: DESC}, offset: 0) { edges { node { id content } } } } } } } ''' result = schema.execute(query) assert not result.errors post = comment.post assert result.data['allPosts']['edges'][0]['node']['id'] == to_global_id('PostType', post.id) assert result.data['allPosts']['edges'][0]['node']['user']['id'] == to_global_id('UserType', post.user.id) assert result.data['allPosts']['edges'][0]['node']['comments']['edges'][0]['node']['id'] == to_global_id('CommentType', comment.id)
def test_remove_products_from_collection( staff_api_client, collection, product_list, permission_manage_products ): query = """ mutation collectionRemoveProducts( $id: ID!, $products: [ID]!) { collectionRemoveProducts(collectionId: $id, products: $products) { collection { products { totalCount } } } } """ collection.products.add(*product_list) collection_id = to_global_id("Collection", collection.id) product_ids = [to_global_id("Product", product.pk) for product in product_list] no_products_before = collection.products.count() variables = {"id": collection_id, "products": product_ids} response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products] ) content = get_graphql_content(response) data = content["data"]["collectionRemoveProducts"]["collection"] assert data["products"]["totalCount"] == no_products_before - len(product_ids)
def testQuery_repeatedKeyProperty(self): tk1 = Tag(name="t1").put() tk2 = Tag(name="t2").put() tk3 = Tag(name="t3").put() tk4 = Tag(name="t4").put() Article(headline="h1", summary="s1", tags=[tk1, tk2, tk3, tk4]).put() result = schema.execute(''' query ArticleWithAuthorID { articles { headline authorId tagIds tags { name } } } ''') self.assertEmpty(result.errors) article = dict(result.data['articles'][0]) self.assertListEqual(map(lambda k: to_global_id('TagType', k.urlsafe()), [tk1, tk2, tk3, tk4]), article['tagIds']) self.assertLength(article['tags'], 4) for i in range(0, 3): self.assertEqual(article['tags'][i]['name'], 't%s' % (i + 1))
def test_update_collection_mutation_remove_background_image( staff_api_client, collection_with_image, permission_manage_products): query = """ mutation updateCollection($id: ID!, $backgroundImage: Upload) { collectionUpdate( id: $id, input: { backgroundImage: $backgroundImage } ) { collection { backgroundImage{ url } } errors { field message } } } """ assert collection_with_image.background_image variables = { 'id': to_global_id('Collection', collection_with_image.id), 'backgroundImage': None} response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products]) content = get_graphql_content(response) data = content['data']['collectionUpdate']['collection'] assert not data['backgroundImage'] collection_with_image.refresh_from_db() assert not collection_with_image.background_image
def test_update_collection_with_background_image( monkeypatch, staff_api_client, collection, permission_manage_products): mock_create_thumbnails = Mock(return_value=None) monkeypatch.setattr( ('saleor.dashboard.collection.forms.' 'create_collection_background_image_thumbnails.delay'), mock_create_thumbnails) image_file, image_name = create_image() image_alt = 'Alt text for an image.' variables = { 'name': 'new-name', 'slug': 'new-slug', 'id': to_global_id('Collection', collection.id), 'backgroundImage': image_name, 'backgroundImageAlt': image_alt, 'isPublished': True} body = get_multipart_request_body( MUTATION_UPDATE_COLLECTION_WITH_BACKGROUND_IMAGE, variables, image_file, image_name) response = staff_api_client.post_multipart( body, permissions=[permission_manage_products]) content = get_graphql_content(response) data = content['data']['collectionUpdate'] assert not data['errors'] slug = data['collection']['slug'] collection = Collection.objects.get(slug=slug) assert collection.background_image mock_create_thumbnails.assert_called_once_with(collection.pk) assert data['collection']['backgroundImage']['alt'] == image_alt
def test_create_collection(admin_api_client, product_list): query = """ mutation createCollection( $name: String!, $slug: String!, $products: [ID], $backgroundImage: Upload!, $isPublished: Boolean!) { collectionCreate( input: {name: $name, slug: $slug, products: $products, backgroundImage: $backgroundImage, isPublished: $isPublished}) { collection { name slug products { totalCount } } } } """ product_ids = [ to_global_id('Product', product.pk) for product in product_list] image_file, image_name = create_image() name = 'test-name' slug = 'test-slug' variables = { 'name': name, 'slug': slug, 'products': product_ids, 'backgroundImage': image_name, 'isPublished': True} body = get_multipart_request_body(query, variables, image_file, image_name) response = admin_api_client.post_multipart(reverse('api'), body) content = get_graphql_content(response) assert 'errors' not in content data = content['data']['collectionCreate']['collection'] assert data['name'] == name assert data['slug'] == slug assert data['products']['totalCount'] == len(product_ids) collection = Collection.objects.get(slug=slug) assert collection.background_image.file
def test_update_collection(admin_api_client, collection): query = """ mutation updateCollection( $name: String!, $slug: String!, $id: ID!, $isPublished: Boolean!) { collectionUpdate( id: $id, input: {name: $name, slug: $slug, isPublished: $isPublished}) { collection { name slug } } } """ collection_id = to_global_id('Collection', collection.id) name = 'new-name' slug = 'new-slug' variables = json.dumps( {'name': name, 'slug': slug, 'id': collection_id, 'isPublished': True}) response = admin_api_client.post( reverse('api'), {'query': query, 'variables': variables}) content = get_graphql_content(response) assert 'errors' not in content data = content['data']['collectionUpdate']['collection'] assert data['name'] == name assert data['slug'] == slug
def test_update_category_mutation_remove_background_image( staff_api_client, category_with_image, permission_manage_products ): query = """ mutation updateCategory($id: ID!, $backgroundImage: Upload) { categoryUpdate( id: $id, input: { backgroundImage: $backgroundImage } ) { category { backgroundImage{ url } } errors { field message } } } """ assert category_with_image.background_image variables = { "id": to_global_id("Category", category_with_image.id), "backgroundImage": None, } response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products] ) content = get_graphql_content(response) data = content["data"]["categoryUpdate"]["category"] assert not data["backgroundImage"] category_with_image.refresh_from_db() assert not category_with_image.background_image
def test_update_collection_invalid_background_image( staff_api_client, collection, permission_manage_products ): image_file, image_name = create_pdf_file_with_image_ext() image_alt = "Alt text for an image." variables = { "name": "new-name", "slug": "new-slug", "id": to_global_id("Collection", collection.id), "backgroundImage": image_name, "backgroundImageAlt": image_alt, "isPublished": True, } body = get_multipart_request_body( MUTATION_UPDATE_COLLECTION_WITH_BACKGROUND_IMAGE, variables, image_file, image_name, ) response = staff_api_client.post_multipart( body, permissions=[permission_manage_products] ) content = get_graphql_content(response) data = content["data"]["collectionUpdate"] assert data["errors"][0]["field"] == "backgroundImage" assert data["errors"][0]["message"] == "Invalid file type"
def testQuery_keyProperty(self): author_key = Author(name="john dow", email="*****@*****.**").put() article_key = Article(headline="h1", summary="s1", author_key=author_key).put() result = schema.execute(''' query ArticleWithAuthorID { articles { ndbId headline authorId authorNdbId: authorId(ndb: true) author { name, email } } } ''') self.assertEmpty(result.errors) article = dict(result.data['articles'][0]) self.assertEqual(article['ndbId'], str(article_key.id())) self.assertEqual(article['authorNdbId'], str(author_key.id())) author = dict(article['author']) self.assertDictEqual(author, {'name': u'john dow', 'email': u'*****@*****.**'}) self.assertEqual('h1', article['headline']) self.assertEqual(to_global_id('AuthorType', author_key.urlsafe()), article['authorId'])
def test_subclassed_node_query(): executed = schema.execute( '{ node(id:"%s") { ... on MyOtherNode { shared, extraField, somethingElse } } }' % to_global_id("MyOtherNode", 1)) assert not executed.errors assert executed.data == OrderedDict({'node': OrderedDict( [('shared', '1'), ('extraField', 'extra field info.'), ('somethingElse', '----')])})
def test_assign_variant_image( admin_api_client, user_api_client, product_with_image): query = """ mutation assignVariantImageMutation($variantId: ID!, $imageId: ID!) { variantImageAssign(variantId: $variantId, imageId: $imageId) { errors { field message } productVariant { id } } } """ variant = product_with_image.variants.first() image = product_with_image.images.first() variables = json.dumps({ 'variantId': to_global_id('ProductVariant', variant.pk), 'imageId': to_global_id('ProductImage', image.pk)}) response = admin_api_client.post( reverse('api'), {'query': query, 'variables': variables}) content = get_graphql_content(response) assert 'errors' not in content variant.refresh_from_db() assert variant.images.first() == image # check that assigning an image from a different product is not allowed product_with_image.pk = None product_with_image.save() image_2 = ProductImage.objects.create(product=product_with_image) variables = json.dumps({ 'variantId': to_global_id('ProductVariant', variant.pk), 'imageId': to_global_id('ProductImage', image_2.pk)}) response = admin_api_client.post( reverse('api'), {'query': query, 'variables': variables}) content = get_graphql_content(response) assert content['data']['variantImageAssign']['errors'][0]['field'] == 'imageId' # check permissions response = user_api_client.post( reverse('api'), {'query': query, 'variables': variables}) assert_no_permission(response)
def test_update_collection( monkeypatch, staff_api_client, collection, permission_manage_products ): query = """ mutation updateCollection( $name: String!, $slug: String!, $description: String, $id: ID!, $isPublished: Boolean!, $publicationDate: Date) { collectionUpdate( id: $id, input: {name: $name, slug: $slug, description: $description, isPublished: $isPublished, publicationDate: $publicationDate}) { collection { name slug description publicationDate } } } """ mock_create_thumbnails = Mock(return_value=None) monkeypatch.setattr( ( "saleor.dashboard.collection.forms." "create_collection_background_image_thumbnails.delay" ), mock_create_thumbnails, ) name = "new-name" slug = "new-slug" description = "new-description" publication_date = date.today() variables = { "name": name, "slug": slug, "description": description, "id": to_global_id("Collection", collection.id), "isPublished": True, "publicationDate": publication_date, } response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products] ) content = get_graphql_content(response) data = content["data"]["collectionUpdate"]["collection"] assert data["name"] == name assert data["slug"] == slug assert data["publicationDate"] == publication_date.isoformat() assert mock_create_thumbnails.call_count == 0
def test_post_query(self, db, post): g_id = to_global_id('PostType', post.id) query = ''' query { post (id: "%s") { id title } } ''' % g_id result = schema.execute(query) assert not result.errors assert result.data['post']['id'] == g_id
def test_user_query(self, db, user): g_id = to_global_id('UserType', user.id) query = ''' query { user (id: "%s") { id username } } ''' % g_id result = schema.execute(query) assert not result.errors assert result.data['user']['id'] == g_id
def test_correctly_fetches_id_name_rebels(self): query = ''' query RebelsQuery { rebels { id, name } } ''' expected = { 'rebels': { 'id': to_global_id('Faction', ndb.Key('Faction', 'rebels').urlsafe()), 'name': 'Alliance to Restore the Republic' } } result = schema.execute(query) self.assertFalse(result.errors, msg=str(result.errors)) self.assertDictEqual(result.data, expected)
def test_correctly_fetches_id_name_empire(self): empire_key = to_global_id('Faction', ndb.Key('Faction', 'empire').urlsafe()) query = ''' query EmpireQuery { empire { id name } } ''' expected = { 'empire': { 'id': empire_key, 'name': 'Galactic Empire' } } result = schema.execute(query) self.assertFalse(result.errors, msg=str(result.errors)) self.assertDictEqual(result.data, expected)
def test_update_collection_invalid_background_image( staff_api_client, collection, permission_manage_products): image_file, image_name = create_pdf_file_with_image_ext() image_alt = 'Alt text for an image.' variables = { 'name': 'new-name', 'slug': 'new-slug', 'id': to_global_id('Collection', collection.id), 'backgroundImage': image_name, 'backgroundImageAlt': image_alt, 'isPublished': True} body = get_multipart_request_body( MUTATION_UPDATE_COLLECTION_WITH_BACKGROUND_IMAGE, variables, image_file, image_name) response = staff_api_client.post_multipart( body, permissions=[permission_manage_products]) content = get_graphql_content(response) data = content['data']['collectionUpdate'] assert data['errors'][0]['field'] == 'backgroundImage' assert data['errors'][0]['message'] == 'Invalid file type'
def test_delete_collection(admin_api_client, collection): query = """ mutation deleteCollection($id: ID!) { collectionDelete(id: $id) { collection { name } } } """ collection_id = to_global_id('Collection', collection.id) variables = json.dumps({'id': collection_id}) response = admin_api_client.post( reverse('api'), {'query': query, 'variables': variables}) content = get_graphql_content(response) assert 'errors' not in content data = content['data']['collectionDelete']['collection'] assert data['name'] == collection.name with pytest.raises(collection._meta.model.DoesNotExist): collection.refresh_from_db()
def test_delete_collection(staff_api_client, collection, permission_manage_products): query = """ mutation deleteCollection($id: ID!) { collectionDelete(id: $id) { collection { name } } } """ collection_id = to_global_id("Collection", collection.id) variables = {"id": collection_id} response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products] ) content = get_graphql_content(response) data = content["data"]["collectionDelete"]["collection"] assert data["name"] == collection.name with pytest.raises(collection._meta.model.DoesNotExist): collection.refresh_from_db()
def test_correctly_refetches_rebels(self): rebels_key = to_global_id('Faction', ndb.Key('Faction', 'rebels').urlsafe()) query = ''' query RebelsRefetchQuery { node(id: "%s") { id ... on Faction { name } } } ''' % rebels_key expected = { 'node': { 'id': rebels_key, 'name': 'Alliance to Restore the Republic' } } result = schema.execute(query) self.assertFalse(result.errors, msg=str(result.errors)) self.assertDictEqual(result.data, expected)
def test_update_collection_with_background_image( monkeypatch, staff_api_client, collection, permission_manage_products, media_root ): mock_create_thumbnails = Mock(return_value=None) monkeypatch.setattr( ( "saleor.dashboard.collection.forms." "create_collection_background_image_thumbnails.delay" ), mock_create_thumbnails, ) image_file, image_name = create_image() image_alt = "Alt text for an image." variables = { "name": "new-name", "slug": "new-slug", "id": to_global_id("Collection", collection.id), "backgroundImage": image_name, "backgroundImageAlt": image_alt, "isPublished": True, } body = get_multipart_request_body( MUTATION_UPDATE_COLLECTION_WITH_BACKGROUND_IMAGE, variables, image_file, image_name, ) response = staff_api_client.post_multipart( body, permissions=[permission_manage_products] ) content = get_graphql_content(response) data = content["data"]["collectionUpdate"] assert not data["errors"] slug = data["collection"]["slug"] collection = Collection.objects.get(slug=slug) assert collection.background_image mock_create_thumbnails.assert_called_once_with(collection.pk) assert data["collection"]["backgroundImage"]["alt"] == image_alt
def resolve_suggested_action(self, info): user = info.context.user today = timezone.localtime(timezone.now()).date() if user.is_authenticated: # Is the user onboarded? if user.quest_statuses.count() <= 1: return ActionType(type=Actions.STARTING_JOURNEY.value) # Suggesting next untracked habit next_habit = user.habits.active().untracked().first() if next_habit: if next_habit.is_controlled: if next_habit.name == ControlledHabit.FOCUS_HABIT.value: return ActionType(type=Actions.SETTING_FOCUS.value) if next_habit.name == ControlledHabit.JOURNAL_HABIT.value: return ActionType(type=Actions.WRITING_JOURNAL.value) if next_habit.name == ControlledHabit.STATS_HABIT.value: return ActionType(type=Actions.TRACKING_STATS.value) else: id = to_global_id(HabitNode._meta.name, next_habit.id) payload = {'id': id, 'name': next_habit.name, 'icon': next_habit.icon or '🔄'} return ActionType(type=Actions.TRACKING_HABIT.value, payload=payload) return None
def test_update_collection( monkeypatch, staff_api_client, collection, permission_manage_products): query = """ mutation updateCollection( $name: String!, $slug: String!, $description: String, $id: ID!, $isPublished: Boolean!, $publicationDate: Date) { collectionUpdate( id: $id, input: {name: $name, slug: $slug, description: $description, isPublished: $isPublished, publicationDate: $publicationDate}) { collection { name slug description publicationDate } } } """ mock_create_thumbnails = Mock(return_value=None) monkeypatch.setattr( ('saleor.dashboard.collection.forms.' 'create_collection_background_image_thumbnails.delay'), mock_create_thumbnails) name = 'new-name' slug = 'new-slug' description = 'new-description' publication_date = date.today() variables = { 'name': name, 'slug': slug, 'description': description, 'id': to_global_id('Collection', collection.id), 'isPublished': True, 'publicationDate': publication_date} response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products]) content = get_graphql_content(response) data = content['data']['collectionUpdate']['collection'] assert data['name'] == name assert data['slug'] == slug assert data['publicationDate'] == publication_date.isoformat() assert mock_create_thumbnails.call_count == 0
def test_relay_mutation_update_permission_classes_with_permission( user_factory, graphql_client ): user = user_factory(is_staff=True) graphql_client.force_authenticate(user) response = graphql_client.execute( UPDATE_MUTATION, {"input": {"id": to_global_id("BookType", 1), "title": "new title"}}, ) assert response.status_code == 200 assert json.loads(response.content) == { "data": {"updateRelayBookAdmin": None}, "errors": [ { "locations": [{"column": 5, "line": 3}], "message": "No Book matches the given query.", "path": ["updateRelayBookAdmin"], } ], }
def test_update_scheduleclass_permission_granted(self): """ Allow updating scheduleclasses for users with permissions """ query = self.scheduleclass_update_mutation scheduleclass = f.SchedulePublicWeeklyClassFactory.create() variables = self.variables_update variables['input']['id'] = to_global_id('ScheduleItemNode', scheduleclass.pk) # Create regular user user = f.RegularUserFactory.create() permission = Permission.objects.get(codename=self.permission_change) user.user_permissions.add(permission) user.save() executed = execute_test_client_api_query(query, user, variables=variables) data = executed.get('data') self.assertEqual(data['updateScheduleClass']['scheduleItem']['id'], variables['input']['id']) self.assertEqual( data['updateScheduleClass']['scheduleItem']['frequencyType'], variables['input']['frequencyType'])
def test_update_schedule_item_attendance(self): """ Update a class attendance status """ query = self.schedule_item_attendance_update_mutation schedule_item_attendance = f.ScheduleItemAttendanceClasspassFactory.create() variables = self.variables_update_classpass variables['input']['id'] = to_global_id('ScheduleItemAttendanceNode', schedule_item_attendance.id) executed = execute_test_client_api_query( query, self.admin_user, variables=variables ) data = executed.get('data') self.assertEqual( data['updateScheduleItemAttendance']['scheduleItemAttendance']['id'], variables['input']['id'] ) self.assertEqual( data['updateScheduleItemAttendance']['scheduleItemAttendance']['bookingStatus'], variables['input']['bookingStatus'] )
def test_update_collection_invalid_background_image( staff_api_client, collection, permission_manage_products): image_file, image_name = create_pdf_file_with_image_ext() image_alt = "Alt text for an image." variables = { "name": "new-name", "slug": "new-slug", "id": to_global_id("Collection", collection.id), "backgroundImage": image_name, "backgroundImageAlt": image_alt, } body = get_multipart_request_body( MUTATION_UPDATE_COLLECTION_WITH_BACKGROUND_IMAGE, variables, image_file, image_name, ) response = staff_api_client.post_multipart( body, permissions=[permission_manage_products]) content = get_graphql_content(response) data = content["data"]["collectionUpdate"] assert data["errors"][0]["field"] == "backgroundImage" assert data["errors"][0]["message"] == "Invalid file type."
def test_delete_account_finance_payment_batch_category_item_permission_granted( self): """ Allow deleting account finance payment batch category items for users with permissions """ query = self.account_finance_payment_batch_category_item_delete_mutation account_finance_payment_batch_category_item = f.AccountFinancePaymentBatchCategoryItemFactory.create( ) variables = self.variables_delete variables['input']['id'] = to_global_id( "AccountFinancePaymentBatchCategoryItemNode", account_finance_payment_batch_category_item.pk) # Create regular user user = f.TeacherFactory.create() permission = Permission.objects.get(codename=self.permission_delete) user.user_permissions.add(permission) user.save() executed = execute_test_client_api_query(query, user, variables=variables) data = executed.get('data') self.assertEqual( data['deleteAccountFinancePaymentBatchCategoryItem']['ok'], True)
def test_mutate_yaml_file(log_dir): from ml_dash.config import Args Args.logdir = log_dir client = Client(schema) query = """ mutation AppMutation ($id: ID!) { updateYaml (input: { id: $id, data: {text: "hey", key: 10, charts: [0, 1]}, clientMutationId: "10", }) { file { id name text yaml } } } """ path = "/episodeyang/cpc-belief/README.md" r = client.execute(query, variables=dict(id=to_global_id("File", path))) if 'errors' in r: raise RuntimeError("\n" + shows(r['errors'])) else: print(">>") show(r['data'])
def test_query_one_booking_status_cancelled(self): """ Query one schedule_item as admin - booking status cancelled """ schedule_class = f.SchedulePublicWeeklyClassFactory.create() schedule_class.status = 'CANCELLED' schedule_class.save() today = datetime.date.today() next_monday = next_weekday(today, 1) variables = { "scheduleItemId": to_global_id('ScheduleItemNode', schedule_class.id), "date": str(next_monday) } # Now query single schedule item and check executed = execute_test_client_api_query(self.scheduleclass_query, self.admin_user, variables=variables) data = executed.get('data') self.assertEqual(data['scheduleClass']['scheduleItemId'], variables['scheduleItemId']) self.assertEqual(data['scheduleClass']['bookingStatus'], "CANCELLED")
def test_category_update_mutation_invalid_background_image( staff_api_client, category, permission_manage_products ): image_file, image_name = create_pdf_file_with_image_ext() image_alt = "Alt text for an image." variables = { "name": "new-name", "slug": "new-slug", "id": to_global_id("Category", category.id), "backgroundImage": image_name, "backgroundImageAlt": image_alt, "isPublished": True, } body = get_multipart_request_body( MUTATION_CATEGORY_UPDATE_MUTATION, variables, image_file, image_name ) response = staff_api_client.post_multipart( body, permissions=[permission_manage_products] ) content = get_graphql_content(response) data = content["data"]["categoryUpdate"] assert data["errors"][0]["field"] == "backgroundImage" assert data["errors"][0]["message"] == "Invalid file type."
def test_mutate_text_file(log_dir): from ml_dash.config import Args Args.logdir = log_dir client = Client(schema) query = """ mutation AppMutation ($id: ID!) { updateText (input: { id: $id, text: "new text!!\\n1\\n2\\n3\\n4\\n5\\n6", clientMutationId: "10", }) { file { id name text (stop:5) } } } """ path = "/episodeyang/cpc-belief/README.md" r = client.execute(query, variables=dict(id=to_global_id("File", path))) if 'errors' in r: raise RuntimeError("\n" + shows(r['errors'])) else: print(">>") show(r['data'])
def test_update_schedule_item_attendance_permission_granted(self): """ Allow updating attendances for users with permissions """ query = self.schedule_item_attendance_update_mutation schedule_item_attendance = f.ScheduleItemAttendanceClasspassFactory.create() variables = self.variables_update_classpass variables['input']['id'] = to_global_id('ScheduleItemAttendanceNode', schedule_item_attendance.id) user = schedule_item_attendance.account permission = Permission.objects.get(codename=self.permission_change) user.user_permissions.add(permission) user.save() executed = execute_test_client_api_query( query, user, variables=variables ) data = executed.get('data') self.assertEqual( data['updateScheduleItemAttendance']['scheduleItemAttendance']['bookingStatus'], variables['input']['bookingStatus'] )
def resolve_suggested_action(self, info): user = info.context.user today = timezone.localtime(timezone.now()).date() if user.is_authenticated: if not user.focuses.filter(scope=Scope.DAY.value, start=today).exists(): return ActionType(type=Actions.SETTING_FOCUS.value) if not user.journal_entries.filter(scope=Scope.DAY.value, start=today).exists(): return ActionType(type=Actions.WRITING_JOURNAL.value) # Suggesting next untracked habit next_habit = user.habits.active().untracked().first() if next_habit: id = to_global_id(HabitNode._meta.name, next_habit.id) return ActionType(type=Actions.TRACKING_HABIT.value, payload={ 'id': id, 'name': next_habit.name }) # TODO: Processing Dashboard streak (v1) return None
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_query_permision_granted(self): """ Query list of appointment_category rooms """ query = self.appointments_query appointment = f.OrganizationAppointmentFactory.create() non_public_appointment = f.OrganizationAppointmentFactory.build() non_public_appointment.organization_appointment_category = appointment.organization_appointment_category non_public_appointment.display_public = False non_public_appointment.save() variables = { 'organizationAppointmentCategory': to_global_id('OrganizationAppointmentCategoryNode', appointment.organization_appointment_category.pk), 'archived': False } # Create regular user user = f.RegularUserFactory.create() permission = Permission.objects.get( codename='view_organizationappointment') user.user_permissions.add(permission) user.save() executed = execute_test_client_api_query(query, user, variables=variables) data = executed.get('data') # List all locations, including non public non_public_found = False for item in data['organizationAppointments']['edges']: if not item['node']['displayPublic']: non_public_found = True # Assert non public locations are listed self.assertEqual(non_public_found, True)
def test_update_collection_with_background_image(monkeypatch, staff_api_client, collection, permission_manage_products, media_root): mock_create_thumbnails = Mock(return_value=None) monkeypatch.setattr( ("saleor.product.thumbnails." "create_collection_background_image_thumbnails.delay"), mock_create_thumbnails, ) image_file, image_name = create_image() image_alt = "Alt text for an image." variables = { "name": "new-name", "slug": "new-slug", "id": to_global_id("Collection", collection.id), "backgroundImage": image_name, "backgroundImageAlt": image_alt, "isPublished": True, } body = get_multipart_request_body( MUTATION_UPDATE_COLLECTION_WITH_BACKGROUND_IMAGE, variables, image_file, image_name, ) response = staff_api_client.post_multipart( body, permissions=[permission_manage_products]) content = get_graphql_content(response) data = content["data"]["collectionUpdate"] assert not data["errors"] slug = data["collection"]["slug"] collection = Collection.objects.get(slug=slug) assert collection.background_image mock_create_thumbnails.assert_called_once_with(collection.pk) assert data["collection"]["backgroundImage"]["alt"] == image_alt
def test_product_variant_update_updates_invalid_cost_price( mock_update_product_minimal_variant_price_task, staff_api_client, product, permission_manage_products, ): query = """ mutation ProductVariantUpdate( $id: ID!, $costPrice: PositiveDecimal, ) { productVariantUpdate( id: $id, input: { costPrice: $costPrice, } ) { productVariant { name } productErrors { field message code } } } """ staff_api_client.user.user_permissions.add(permission_manage_products) variant = product.variants.first() variant_id = to_global_id("ProductVariant", variant.pk) cost_price = "-1.99" variables = {"id": variant_id, "costPrice": cost_price} response = staff_api_client.post_graphql(query, variables) assert_negative_positive_decimal_value(response)
def mutate(self, args, context, info): snapshot_id = args.get('snapshot_id') _, snapshot_db_id = from_global_id(snapshot_id) t = args.get('type') if t is not None and t.strip() == '': t = None image = ImageModel(snapshot_id=snapshot_db_id, path=args.get('path'), filename=args.get('filename'), angle=args.get('angle'), image_type=t) try: db.session.add(image) db.session.flush() except IntegrityError as err: print(err.message) db.session.rollback() raise ConflictingDataError("Image already exists") except DBAPIError: logging.getLogger(__name__).exception("An unexpected DB error occured") db.session.rollback() raise UnknownDataError("An unexpected DB error occured") db.session.commit() return AddImage(id=to_global_id('Image', image.id))
def test_update_paymentbatchcategory(self): """ Update a paymentbatchcategory """ query = self.paymentbatchcategory_update_mutation paymentbatchcategory = f.FinancePaymentBatchCategoryCollectionFactory.create( ) variables = self.variables_update variables['input']['id'] = to_global_id( 'FinancePaymentBatchCategoryNode', paymentbatchcategory.pk) executed = execute_test_client_api_query(query, self.admin_user, variables=variables) data = executed.get('data') self.assertEqual( data['updateFinancePaymentBatchCategory'] ['financePaymentBatchCategory']['name'], variables['input']['name']) self.assertEqual( data['updateFinancePaymentBatchCategory'] ['financePaymentBatchCategory']['archived'], False) self.assertEqual( data['updateFinancePaymentBatchCategory'] ['financePaymentBatchCategory']['description'], variables['input']['description'])
def test_remove_field(db, schema_executor, analytics_field): query = """ mutation remove($input: RemoveAnalyticsFieldInput!) { removeAnalyticsField(input: $input) { clientMutationId } } """ input = { "input": { "id": to_global_id(type(analytics_field).__name__, analytics_field.pk) } } result = schema_executor(query, variable_values=input) assert not result.errors # Try to delete a now-nonexistent field result = schema_executor(query, variable_values=input) assert result.errors assert result.errors[0].args == ( "No AnalyticsField matches the given query.", )
def test_repository(snapshot, call_api, repository_factory): repository_factory( id=10, name="james-rivera", owner="sharon54", url="https://gitlab.com/sharon54/jones-rivera", remote_id=2783, ) id = to_global_id("Repository", 10) query = f""" query {{ node (id: "{id}") {{ ... on Repository {{ id owner name url remoteId }} }} }} """ response = call_api(query) snapshot.assert_match(response)
def test_schema_node(db, snapshot, request, node_type): """ Add your model to parametrize for automatic global node testing. Requirement is that node and model have the same name """ node_instance = request.getfixturevalue(node_type) global_id = to_global_id(node_instance.__class__.__name__, node_instance.pk) node_query = """ query %(name)s($id: ID!) { node(id: $id) { ... on %(name)s { id } } } """ % { "name": node_instance.__class__.__name__ } result = schema.execute(node_query, variables={"id": global_id}) assert not result.errors assert result.data["node"]["id"] == global_id
def test_change_todo_status(self): create_test_data() query = ''' mutation ChangeTodoStatusMutation($input: ChangeTodoStatusInput!) { changeTodoStatus(input: $input) { todo { complete } viewer { completedCount } clientMutationId } } ''' variables = { 'input': { 'id': graphql_relay.to_global_id('Todo', 1), 'complete': False, 'clientMutationId': 'give_this_back_to_me', } } expected = { 'changeTodoStatus': { 'todo': { 'complete': False, }, 'viewer': { 'completedCount': 0, }, 'clientMutationId': 'give_this_back_to_me', } } schema = graphene.Schema(query=Query, mutation=Mutation) result = schema.execute(query, variable_values=variables) self.assertIsNone(result.errors, msg=format_graphql_errors(result.errors)) self.assertEqual(result.data, expected, msg='\n' + repr(expected) + '\n' + repr(result.data))
def test_query_status_open(self): """ Query list status open of scheduleclass """ query = self.scheduleclasses_query schedule_class_otc = f.SchedulePublicWeeklyClassOTCFactory.create() schedule_class_otc.status = 'OPEN' schedule_class_otc.save() schedule_class = schedule_class_otc.schedule_item variables = self.variables_query_list_status executed = execute_test_client_api_query(query, self.admin_user, variables=variables) print("##############") print(executed) data = executed.get('data') self.assertEqual(data['scheduleClasses'][0]['date'], variables['dateFrom']) self.assertEqual( data['scheduleClasses'][0]['classes'][0]['scheduleItemId'], to_global_id('ScheduleItemNode', schedule_class.id)) self.assertEqual(data['scheduleClasses'][0]['classes'][0]['status'], schedule_class_otc.status)
def test_query(self): """ Query list of organization documents """ query = self.organization_documents_query executed = execute_test_client_api_query( query, self.admin_user, variables=self.variables_query_list) data = executed.get('data') self.assertEqual( data['organizationDocuments']['edges'][0]['node']['id'], to_global_id('OrganizationDocumentNode', self.organization_document.id)) self.assertEqual( data['organizationDocuments']['edges'][0]['node']['documentType'], self.organization_document.document_type) self.assertEqual( data['organizationDocuments']['edges'][0]['node']['version'], str(self.organization_document.version)) self.assertEqual( data['organizationDocuments']['edges'][0]['node']['dateStart'], str(self.organization_document.date_start)) self.assertEqual( data['organizationDocuments']['edges'][0]['node']['document'], self.organization_document.document)
def mutate_and_get_payload(cls, root, info, id, name, hkid, birthday, confirmed_day, case_num, client_mutation_id): if not info.context.user.is_authenticated(): raise PermissionError("user not logged in") p = Patient.objects.get(pk=from_global_id(id)[1]) if name is not None: p.name = name if hkid is not None: p.hkid = hkid.upper().replace('(', '').replace(')', '') if birthday is not None: p.birthday = birthday if confirmed_day is not None: p.confirmed_day = confirmed_day if case_num is not None: p.case_num = case_num p.save() return UpdatePatientMutation(id=to_global_id(PatientNode.__name__, p.id), name=p.name, hkid=p.hkid, birthday=p.birthday, confirmed_day=p.confirmed_day, case_num=p.case_num)
def test_relay_mutation_update_resolver_permission_classes_without_authentication( graphql_admin_resolver_client, ): response = graphql_admin_resolver_client.execute( UPDATE_MUTATION, {"input": { "id": to_global_id("BookType", 1), "title": "new title" }}, ) assert response.status_code == 200 assert json.loads(response.content) == { "data": { "updateRelayBook": None }, "errors": [{ "locations": [{ "column": 5, "line": 3 }], "message": "You do not have permission to perform this action.", "path": ["updateRelayBook"], }], }
def test_query_permision_granted(self): """ Query list of account teacher_profiles with view permission """ query = self.teacher_profiles_query teacher_profile = f.TeacherProfileFactory.create() variables = { 'id': to_global_id('AccountNode', teacher_profile.account.id) } # Create regular user user = get_user_model().objects.get(pk=teacher_profile.account.id) permission = Permission.objects.get( codename='view_accountteacherprofile') user.user_permissions.add(permission) user.save() executed = execute_test_client_api_query(query, user, variables=variables) data = executed.get('data') # List all teacher_profiles for this account self.assertEqual( data['accountTeacherProfiles']['edges'][0]['node']['account'] ['id'], variables['id'])
def test_update_paymentmethod_permission_granted(self): """ Allow updating paymentmethods for users with permissions """ query = self.paymentmethod_update_mutation paymentmethod = f.FinancePaymentMethodFactory.create() variables = self.variables_update variables['input']['id'] = to_global_id('FinancePaymentMethodNode', paymentmethod.pk) # Create regular user user = f.RegularUserFactory.create() permission = Permission.objects.get(codename=self.permission_change) user.user_permissions.add(permission) user.save() executed = execute_test_client_api_query(query, user, variables=variables) data = executed.get('data') self.assertEqual( data['updateFinancePaymentMethod']['financePaymentMethod']['name'], variables['input']['name']) self.assertEqual( data['updateFinancePaymentMethod']['financePaymentMethod']['code'], variables['input']['code'])
def test_only_companies_with_joblistings_is_in_search(self): """Ensure old joblisting urls are still valid""" name = "name" active_company = Company.objects.create(name=name) inactive_company = Company.objects.create(name=name) Joblisting.objects.create(company=active_company, deadline=timezone.now() + timedelta(days=1)) Joblisting.objects.create(company=inactive_company, deadline=timezone.now() - timedelta(days=1)) global_id = to_global_id("Company", active_company.pk) executed = self.client.execute(self.company_search_query, variable_values={"query": name}) expected = { "data": { "search": [{ "id": global_id, "__typename": "Company" }] } } self.assertIsNone(executed.get("errors")) self.assertEqual(executed, expected)
def test_update_invoice_item(self): """ Update a invoice item """ query = self.invoice_item_update_mutation invoice_item = f.FinanceInvoiceItemFactory.create() variables = self.variables_update variables['input']['id'] = to_global_id('FinanceInvoiceItemNode', invoice_item.id) executed = execute_test_client_api_query(query, self.admin_user, variables=variables) data = executed.get('data') self.assertEqual( data['updateFinanceInvoiceItem']['financeInvoiceItem'] ['productName'], variables['input']['productName']) self.assertEqual( data['updateFinanceInvoiceItem']['financeInvoiceItem'] ['description'], variables['input']['description']) self.assertEqual( data['updateFinanceInvoiceItem']['financeInvoiceItem']['quantity'], variables['input']['quantity']) self.assertEqual( data['updateFinanceInvoiceItem']['financeInvoiceItem']['price'], variables['input']['price']) self.assertEqual( data['updateFinanceInvoiceItem']['financeInvoiceItem'] ['financeTaxRate']['id'], variables['input']['financeTaxRate']) self.assertEqual( data['updateFinanceInvoiceItem']['financeInvoiceItem'] ['financeGlaccount']['id'], variables['input']['financeGlaccount']) self.assertEqual( data['updateFinanceInvoiceItem']['financeInvoiceItem'] ['financeCostcenter']['id'], variables['input']['financeCostcenter'])
def postprocess_analysis(): # TODO document returns """ API endpoint for starting the postprocessing of an analysis The request body must contain the 'analysis_id' and a list 'postprocessing_stack_ids' containing the IDs of the stacks which should be applied to the analysis results. :return: a dict containing a 'msg', a list of 'postprocess_ids' representing the status IDs of the corresponding tasks and a list of postprocessing stack IDs which have already been applied to the given analysis. """ identity = get_jwt_identity() parsed_request = request.get_json() postprocessing_ids = parsed_request['postprocessing_stack_ids'] analysis_id = parsed_request['analysis_id'] note = parsed_request['note'] if 'note' in parsed_request else '' if analysis_id is not None: ql_type, analysis_db_id = from_global_id(analysis_id) analysis = db.session.query(AnalysisModel).get(analysis_db_id) if postprocessing_ids is not None: tasks, postprocesses, finished = submit_postprocesses( analysis, postprocessing_ids, note, identity['username']) # TODO throw error if one postprocess can't be started? return jsonify({ 'msg': 'Started Postprocesses', 'postprocessing_task_ids': [to_global_id('Task', t.key) for t in tasks], 'already_finished': finished }), 202 return jsonify({'msg': 'No postprocessing stack ids given'}), 422 else: return jsonify({'msg': 'No analysis id given'}), 422
def test_global_id_allows_setting_customer_parent_type(): my_id = '1' gid = GlobalID(parent_type=User) id_resolver = gid.get_resolver(lambda *_: my_id) my_global_id = id_resolver(None, None, None, None) assert my_global_id == to_global_id(User._meta.name, my_id)
def test_global_id_defaults_to_info_parent_type(): my_id = '1' gid = GlobalID() id_resolver = gid.get_resolver(lambda *_: my_id) my_global_id = id_resolver(None, None, None, Info(User)) assert my_global_id == to_global_id(User._meta.name, my_id)