def test_menu_query(user_api_client, menu): query = """ query menu($id: ID, $menu_name: String){ menu(id: $id, name: $menu_name) { name } } """ # test query by name variables = {"menu_name": menu.name} response = user_api_client.post_graphql(query, variables) content = get_graphql_content(response) assert content["data"]["menu"]["name"] == menu.name # test query by id menu_id = graphene.Node.to_global_id("Menu", menu.id) variables = {"id": menu_id} response = user_api_client.post_graphql(query, variables) content = get_graphql_content(response) assert content["data"]["menu"]["name"] == menu.name # test query by invalid name returns null variables = {"menu_name": "not-a-menu"} response = user_api_client.post_graphql(query, variables) content = get_graphql_content(response) assert not content["data"]["menu"]
def test_digital_content_create_mutation_default_settings( monkeypatch, staff_api_client, variant, permission_manage_products): query = """ mutation digitalCreate($variant: ID!, $input: DigitalContentUploadInput!) { digitalContentCreate(variantId: $variant, input: $input) { variant { id } } } """ image_file, image_name = create_image() variables = { 'variant': graphene.Node.to_global_id('ProductVariant', variant.id), 'input': { 'useDefaultSettings': True, 'contentFile': image_name } } body = get_multipart_request_body(query, variables, image_file, image_name) response = staff_api_client.post_multipart( body, permissions=[permission_manage_products]) get_graphql_content(response) variant.refresh_from_db() assert variant.digital_content.content_file assert variant.digital_content.use_default_settings
def test_menu_query(user_api_client, menu): query = """ query menu($id: ID, $menu_name: String){ menu(id: $id, name: $menu_name) { name } } """ # test query by name variables = {'menu_name': menu.name} response = user_api_client.post_graphql(query, variables) content = get_graphql_content(response) assert content['data']['menu']['name'] == menu.name # test query by id menu_id = graphene.Node.to_global_id('Menu', menu.id) variables = {'id': menu_id} response = user_api_client.post_graphql(query, variables) content = get_graphql_content(response) assert content['data']['menu']['name'] == menu.name # test query by invalid name returns null variables = {'menu_name': 'not-a-menu'} response = user_api_client.post_graphql(query, variables) content = get_graphql_content(response) assert not content['data']['menu']
def test_digital_content_delete_mutation( monkeypatch, staff_api_client, variant, digital_content, permission_manage_products): query = """ mutation digitalDelete($variant: ID!){ digitalContentDelete(variantId:$variant){ variant{ id } } } """ variant.digital_content = digital_content variant.digital_content.save() assert hasattr(variant, 'digital_content') variables = { 'variant': graphene.Node.to_global_id('ProductVariant', variant.id) } response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products]) get_graphql_content(response) variant = ProductVariant.objects.get(id=variant.id) assert not hasattr(variant, 'digital_content')
def test_digital_content_url_create( monkeypatch, staff_api_client, variant, permission_manage_products, digital_content): query = """ mutation digitalContentUrlCreate($input: DigitalContentUrlCreateInput!) { digitalContentUrlCreate(input: $input) { digitalContentUrl { id url } errors { field message } } } """ variables = { 'input': { 'content': graphene.Node.to_global_id( 'DigitalContent', digital_content.id), } } assert digital_content.urls.count() == 0 response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products]) get_graphql_content(response) digital_content.refresh_from_db() assert digital_content.urls.count() == 1
def test_use_checkout_billing_address_as_payment_billing( user_api_client, cart_with_item, address): cart = cart_with_item checkout_id = graphene.Node.to_global_id('Checkout', cart.pk) variables = { 'checkoutId': checkout_id, 'input': { 'gateway': 'DUMMY', 'token': 'sample-token', 'amount': str(cart.get_total().gross.amount)}} response = user_api_client.post_graphql(CREATE_QUERY, variables) content = get_graphql_content(response) data = content['data']['checkoutPaymentCreate'] # check if proper error is returned if address is missing assert data['errors'][0]['field'] == 'billingAddress' # assign the address and try again address.street_address_1 = 'spanish-inqusition' address.save() cart.billing_address = address cart.save() response = user_api_client.post_graphql(CREATE_QUERY, variables) content = get_graphql_content(response) data = content['data']['checkoutPaymentCreate'] cart.refresh_from_db() assert cart.payments.count() == 1 payment = cart.payments.first() assert payment.billing_address_1 == address.street_address_1
def test_use_checkout_billing_address_as_payment_billing( user_api_client, checkout_with_item, address ): checkout = checkout_with_item checkout_id = graphene.Node.to_global_id("Checkout", checkout.pk) variables = { "checkoutId": checkout_id, "input": { "gateway": "DUMMY", "token": "sample-token", "amount": str(checkout.get_total().gross.amount), }, } response = user_api_client.post_graphql(CREATE_QUERY, variables) content = get_graphql_content(response) data = content["data"]["checkoutPaymentCreate"] # check if proper error is returned if address is missing assert data["errors"][0]["field"] == "billingAddress" # assign the address and try again address.street_address_1 = "spanish-inqusition" address.save() checkout.billing_address = address checkout.save() response = user_api_client.post_graphql(CREATE_QUERY, variables) content = get_graphql_content(response) data = content["data"]["checkoutPaymentCreate"] checkout.refresh_from_db() assert checkout.payments.count() == 1 payment = checkout.payments.first() assert payment.billing_address_1 == address.street_address_1
def test_staff_query_unpublished_page(staff_api_client, page, permission_manage_pages): page.is_published = False page.save() # query by ID variables = {"id": graphene.Node.to_global_id("Page", page.id)} response = staff_api_client.post_graphql(PAGE_QUERY, variables) content = get_graphql_content(response) assert content["data"]["page"] is None # query by slug variables = {"slug": page.slug} response = staff_api_client.post_graphql(PAGE_QUERY, variables) content = get_graphql_content(response) assert content["data"]["page"] is None # query by ID with page permissions variables = {"id": graphene.Node.to_global_id("Page", page.id)} response = staff_api_client.post_graphql( PAGE_QUERY, variables, permissions=[permission_manage_pages], check_no_permissions=False, ) content = get_graphql_content(response) assert content["data"]["page"] is not None # query by slug with page permissions variables = {"slug": page.slug} response = staff_api_client.post_graphql( PAGE_QUERY, variables, permissions=[permission_manage_pages], check_no_permissions=False, ) content = get_graphql_content(response) assert content["data"]["page"] is not None
def test_shop_fetch_tax_rates( mock_call_command, staff_api_client, permission_manage_settings, settings): settings.VATLAYER_ACCESS_KEY = 'KEY' staff_api_client.user.user_permissions.add(permission_manage_settings) response = staff_api_client.post_graphql( MUTATION_SHOP_FETCH_TAX_RATES) get_graphql_content(response) mock_call_command.assert_called_once_with('get_vat_rates')
def test_assign_menu( staff_api_client, menu, permission_manage_menus, permission_manage_settings, site_settings, ): query = """ mutation AssignMenu($menu: ID, $navigationType: NavigationType!) { assignNavigation(menu: $menu, navigationType: $navigationType) { errors { field message } menu { name } } } """ # test mutations fails without proper permissions menu_id = graphene.Node.to_global_id("Menu", menu.pk) variables = {"menu": menu_id, "navigationType": NavigationType.MAIN.name} response = staff_api_client.post_graphql(query, variables) assert_no_permission(response) staff_api_client.user.user_permissions.add(permission_manage_menus) staff_api_client.user.user_permissions.add(permission_manage_settings) # test assigning main menu response = staff_api_client.post_graphql(query, variables) content = get_graphql_content(response) assert content["data"]["assignNavigation"]["menu"]["name"] == menu.name site_settings.refresh_from_db() assert site_settings.top_menu.name == menu.name # test assigning secondary menu variables = {"menu": menu_id, "navigationType": NavigationType.SECONDARY.name} response = staff_api_client.post_graphql(query, variables) content = get_graphql_content(response) assert content["data"]["assignNavigation"]["menu"]["name"] == menu.name site_settings.refresh_from_db() assert site_settings.bottom_menu.name == menu.name # test unasigning menu variables = {"id": None, "navigationType": NavigationType.MAIN.name} response = staff_api_client.post_graphql(query, variables) content = get_graphql_content(response) assert not content["data"]["assignNavigation"]["menu"] site_settings.refresh_from_db() assert site_settings.top_menu is None
def test_customer_query_unpublished_page(user_api_client, page): page.is_published = False page.save() # query by ID variables = {"id": graphene.Node.to_global_id("Page", page.id)} response = user_api_client.post_graphql(PAGE_QUERY, variables) content = get_graphql_content(response) assert content["data"]["page"] is None # query by slug variables = {"slug": page.slug} response = user_api_client.post_graphql(PAGE_QUERY, variables) content = get_graphql_content(response) assert content["data"]["page"] is None
def test_customer_query_unpublished_page(user_api_client, page): page.is_published = False page.save() # query by ID variables = {'id': graphene.Node.to_global_id('Page', page.id)} response = user_api_client.post_graphql(PAGE_QUERY, variables) content = get_graphql_content(response) assert content['data']['page'] is None # query by slug variables = {'slug': page.slug} response = user_api_client.post_graphql(PAGE_QUERY, variables) content = get_graphql_content(response) assert content['data']['page'] is None
def test_attribute_value_create_translation( staff_api_client, pink_attribute_value, permission_manage_translations): query = """ mutation attributeValueTranslate($attributeValueId: ID!) { attributeValueTranslate( id: $attributeValueId, languageCode: PL, input: {name: "Róż PL"}) { attributeValue { translation(languageCode: PL) { name language { code } } } } } """ attribute_value_id = graphene.Node.to_global_id( 'AttributeValue', pink_attribute_value.id) response = staff_api_client.post_graphql( query, {'attributeValueId': attribute_value_id}, permissions=[permission_manage_translations]) data = get_graphql_content(response)['data']['attributeValueTranslate'] assert data['attributeValue']['translation']['name'] == 'Róż PL' assert data['attributeValue']['translation']['language']['code'] == 'pl'
def test_collection_update_translation( staff_api_client, collection, permission_manage_translations): collection.translations.create(language_code='pl', name='Kolekcja') query = """ mutation collectionTranslate($collectionId: ID!) { collectionTranslate( id: $collectionId, languageCode: PL, input: {name: "Kolekcja PL"}) { collection { translation(languageCode: PL) { name language { code } } } } } """ collection_id = graphene.Node.to_global_id('Collection', collection.id) response = staff_api_client.post_graphql( query, {'collectionId': collection_id}, permissions=[permission_manage_translations]) data = get_graphql_content(response)['data']['collectionTranslate'] assert data['collection']['translation']['name'] == 'Kolekcja PL' assert data['collection']['translation']['language']['code'] == 'pl'
def test_voucher_update_translation( staff_api_client, voucher, permission_manage_translations): voucher.translations.create(language_code='pl', name='Kategoria') query = """ mutation voucherTranslate($voucherId: ID!) { voucherTranslate( id: $voucherId, languageCode: PL, input: {name: "Bon PL"}) { voucher { translation(languageCode: PL) { name language { code } } } } } """ voucher_id = graphene.Node.to_global_id('Voucher', voucher.id) response = staff_api_client.post_graphql( query, {'voucherId': voucher_id}, permissions=[permission_manage_translations]) data = get_graphql_content(response)['data']['voucherTranslate'] assert data['voucher']['translation']['name'] == 'Bon PL' assert data['voucher']['translation']['language']['code'] == 'pl'
def test_category_update_translation( staff_api_client, category, permission_manage_translations): category.translations.create(language_code='pl', name='Kategoria') query = """ mutation categoryTranslate($categoryId: ID!) { categoryTranslate( id: $categoryId, languageCode: PL, input: {name: "Kategoria PL"}) { category { translation(languageCode: PL) { name language { code } } } } } """ category_id = graphene.Node.to_global_id('Category', category.id) response = staff_api_client.post_graphql( query, {'categoryId': category_id}, permissions=[permission_manage_translations]) data = get_graphql_content(response)['data']['categoryTranslate'] assert data['category']['translation']['name'] == 'Kategoria PL' assert data['category']['translation']['language']['code'] == 'pl'
def test_shipping_method_no_translation( staff_api_client, shipping_method, permission_manage_shipping): query = """ query shippingZoneById($shippingZoneId: ID!) { shippingZone(id: $shippingZoneId) { shippingMethods { translation(languageCode: PL) { name language { code } } } } } """ shipping_zone_id = graphene.Node.to_global_id( 'ShippingZone', shipping_method.shipping_zone.id) response = staff_api_client.post_graphql( query, {'shippingZoneId': shipping_zone_id}, permissions=[permission_manage_shipping]) data = get_graphql_content(response)['data'] shipping_method = data['shippingZone']['shippingMethods'][0] assert shipping_method['translation'] is None
def test_product_variant_update_translation( staff_api_client, variant, permission_manage_translations): variant.translations.create(language_code='pl', name='Wariant') query = """ mutation productVariantTranslate($productVariantId: ID!) { productVariantTranslate( id: $productVariantId, languageCode: PL, input: {name: "Wariant PL"}) { productVariant { translation(languageCode: PL) { name language { code } } } } } """ product_variant_id = graphene.Node.to_global_id( 'ProductVariant', variant.id) response = staff_api_client.post_graphql( query, {'productVariantId': product_variant_id}, permissions=[permission_manage_translations]) data = get_graphql_content(response)['data']['productVariantTranslate'] assert data['productVariant']['translation']['name'] == 'Wariant PL' assert data['productVariant']['translation']['language']['code'] == 'pl'
def test_attribute_translation(user_api_client, color_attribute): color_attribute.translations.create(language_code='pl', name='Kolor') query = """ query { attributes(first: 1) { edges { node { translation(languageCode: PL) { name language { code } } } } } } """ response = user_api_client.post_graphql(query) data = get_graphql_content(response)['data'] attribute = data['attributes']['edges'][0]['node'] assert attribute['translation']['name'] == 'Kolor' assert attribute['translation']['language']['code'] == 'pl'
def test_attribute_value_no_translation(user_api_client, pink_attribute_value): query = """ query { attributes(first: 1) { edges { node { values { translation(languageCode: PL) { name language { code } } } } } } } """ attribute_value_id = graphene.Node.to_global_id( 'AttributeValue', pink_attribute_value.id) response = user_api_client.post_graphql( query, {'attributeValueId': attribute_value_id}) data = get_graphql_content(response)['data'] attribute_value = data['attributes']['edges'][0]['node']['values'][-1] assert attribute_value['translation'] is None
def test_shop_update_translation( staff_api_client, site_settings, permission_manage_translations): site_settings.translations.create( language_code='pl', header_text='Nagłówek') query = """ mutation shopSettingsTranslate { shopSettingsTranslate( languageCode: PL, input: {headerText: "Nagłówek PL"}) { shop { translation(languageCode: PL) { headerText language { code } } } } } """ response = staff_api_client.post_graphql( query, permissions=[permission_manage_translations]) data = get_graphql_content(response)['data']['shopSettingsTranslate'] assert data['shop']['translation']['headerText'] == 'Nagłówek PL' assert data['shop']['translation']['language']['code'] == 'pl'
def test_translations_query_inline_fragment(user_api_client, product): product.translations.create(language_code='pl', name='Produkt testowy') query = """ { translations(kind: PRODUCT, first: 1) { edges { node { ... on Product { name translation(languageCode: PL) { name } } } } } } """ response = user_api_client.post_graphql(query) data = get_graphql_content(response)['data']['translations']['edges'][0] assert data['node']['name'] == 'Test product' assert data['node']['translation']['name'] == 'Produkt testowy'
def test_shipping_method_update_translation( staff_api_client, shipping_method, permission_manage_translations): shipping_method.translations.create(language_code='pl', name='DHL') query = """ mutation shippingPriceTranslate($shippingMethodId: ID!) { shippingPriceTranslate( id: $shippingMethodId, languageCode: PL, input: {name: "DHL PL"}) { shippingMethod { translation(languageCode: PL) { name language { code } } } } } """ shipping_method_id = graphene.Node.to_global_id( 'ShippingMethod', shipping_method.id) response = staff_api_client.post_graphql( query, {'shippingMethodId': shipping_method_id}, permissions=[permission_manage_translations]) data = get_graphql_content(response)['data']['shippingPriceTranslate'] assert data['shippingMethod']['translation']['name'] == 'DHL PL' assert data['shippingMethod']['translation']['language']['code'] == 'pl'
def test_menu_item_update_translation( staff_api_client, menu_item, permission_manage_translations): menu_item.translations.create(language_code='pl', name='Odnośnik') query = """ mutation menuItemTranslate($menuItemId: ID!) { menuItemTranslate( id: $menuItemId, languageCode: PL, input: {name: "Odnośnik PL"}) { menuItem { translation(languageCode: PL) { name language { code } } } } } """ menu_item_id = graphene.Node.to_global_id('MenuItem', menu_item.id) response = staff_api_client.post_graphql( query, {'menuItemId': menu_item_id}, permissions=[permission_manage_translations]) data = get_graphql_content(response)['data']['menuItemTranslate'] assert data['menuItem']['translation']['name'] == 'Odnośnik PL' assert data['menuItem']['translation']['language']['code'] == 'pl'
def test_attribute_create_translation( staff_api_client, color_attribute, permission_manage_translations ): query = """ mutation attributeTranslate($attributeId: ID!) { attributeTranslate( id: $attributeId, languageCode: PL, input: {name: "Kolor PL"}) { attribute { translation(languageCode: PL) { name language { code } } } } } """ attribute_id = graphene.Node.to_global_id("Attribute", color_attribute.id) response = staff_api_client.post_graphql( query, {"attributeId": attribute_id}, permissions=[permission_manage_translations], ) data = get_graphql_content(response)["data"]["attributeTranslate"] assert data["attribute"]["translation"]["name"] == "Kolor PL" assert data["attribute"]["translation"]["language"]["code"] == "PL"
def test_voucher_translation( staff_api_client, voucher, permission_manage_discounts): voucher.translations.create(language_code='pl', name='Bon') query = """ query voucherById($voucherId: ID!) { voucher(id: $voucherId) { translation(languageCode: PL) { name language { code } } } } """ voucher_id = graphene.Node.to_global_id('Voucher', voucher.id) response = staff_api_client.post_graphql( query, {'voucherId': voucher_id}, permissions=[permission_manage_discounts]) data = get_graphql_content(response)['data'] assert data['voucher']['translation']['name'] == 'Bon' assert data['voucher']['translation']['language']['code'] == 'pl'
def test_sale_create_translation( staff_api_client, sale, permission_manage_translations ): query = """ mutation saleTranslate($saleId: ID!) { saleTranslate( id: $saleId, languageCode: PL, input: {name: "Wyprz PL"}) { sale { translation(languageCode: PL) { name language { code } } } } } """ sale_id = graphene.Node.to_global_id("Sale", sale.id) response = staff_api_client.post_graphql( query, {"saleId": sale_id}, permissions=[permission_manage_translations] ) data = get_graphql_content(response)["data"]["saleTranslate"] assert data["sale"]["translation"]["name"] == "Wyprz PL" assert data["sale"]["translation"]["language"]["code"] == "PL"
def test_page_update_translation( staff_api_client, page, permission_manage_translations ): page.translations.create(language_code="pl", title="Strona") query = """ mutation pageTranslate($pageId: ID!) { pageTranslate( id: $pageId, languageCode: PL, input: {title: "Strona PL"}) { page { translation(languageCode: PL) { title language { code } } } } } """ page_id = graphene.Node.to_global_id("Page", page.id) response = staff_api_client.post_graphql( query, {"pageId": page_id}, permissions=[permission_manage_translations] ) data = get_graphql_content(response)["data"]["pageTranslate"] assert data["page"]["translation"]["title"] == "Strona PL" assert data["page"]["translation"]["language"]["code"] == "PL"
def test_voucher_update_translation( staff_api_client, voucher, permission_manage_translations ): voucher.translations.create(language_code="pl", name="Kategoria") query = """ mutation voucherTranslate($voucherId: ID!) { voucherTranslate( id: $voucherId, languageCode: PL, input: {name: "Bon PL"}) { voucher { translation(languageCode: PL) { name language { code } } } } } """ voucher_id = graphene.Node.to_global_id("Voucher", voucher.id) response = staff_api_client.post_graphql( query, {"voucherId": voucher_id}, permissions=[permission_manage_translations] ) data = get_graphql_content(response)["data"]["voucherTranslate"] assert data["voucher"]["translation"]["name"] == "Bon PL" assert data["voucher"]["translation"]["language"]["code"] == "PL"
def test_page_update_translation( staff_api_client, page, permission_manage_translations): page.translations.create(language_code='pl', title='Strona') query = """ mutation pageTranslate($pageId: ID!) { pageTranslate( id: $pageId, languageCode: PL, input: {title: "Strona PL"}) { page { translation(languageCode: PL) { title language { code } } } } } """ page_id = graphene.Node.to_global_id('Page', page.id) response = staff_api_client.post_graphql( query, {'pageId': page_id}, permissions=[permission_manage_translations]) data = get_graphql_content(response)['data']['pageTranslate'] assert data['page']['translation']['title'] == 'Strona PL' assert data['page']['translation']['language']['code'] == 'pl'
def test_create_product(staff_api_client, product_type, category, size_attribute, permission_manage_products): query = """ mutation createProduct( $productTypeId: ID!, $categoryId: ID! $name: String!, $description: String!, $isPublished: Boolean!, $chargeTaxes: Boolean!, $taxRate: TaxRateType!, $price: Decimal!, $attributes: [AttributeValueInput!]) { productCreate( input: { category: $categoryId, productType: $productTypeId, name: $name, description: $description, isPublished: $isPublished, chargeTaxes: $chargeTaxes, taxRate: $taxRate, price: $price, attributes: $attributes }) { product { category { name } description isPublished chargeTaxes taxRate name price { amount } productType { name } attributes { attribute { slug } value { slug } } } errors { message field } } } """ product_type_id = graphene.Node.to_global_id('ProductType', product_type.pk) category_id = graphene.Node.to_global_id('Category', category.pk) product_description = 'test description' product_name = 'test name' product_isPublished = True product_chargeTaxes = True product_taxRate = 'STANDARD' product_price = 22.33 # Default attribute defined in product_type fixture color_attr = product_type.product_attributes.get(name='Color') color_value_slug = color_attr.values.first().slug color_attr_slug = color_attr.slug # Add second attribute product_type.product_attributes.add(size_attribute) size_attr_slug = product_type.product_attributes.get(name='Size').slug non_existent_attr_value = 'The cake is a lie' # test creating root product variables = { 'productTypeId': product_type_id, 'categoryId': category_id, 'name': product_name, 'description': product_description, 'isPublished': product_isPublished, 'chargeTaxes': product_chargeTaxes, 'taxRate': product_taxRate, 'price': product_price, 'attributes': [{ 'slug': color_attr_slug, 'value': color_value_slug }, { 'slug': size_attr_slug, 'value': non_existent_attr_value }] } response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products]) content = get_graphql_content(response) data = content['data']['productCreate'] assert data['errors'] == [] assert data['product']['name'] == product_name assert data['product']['description'] == product_description assert data['product']['isPublished'] == product_isPublished assert data['product']['chargeTaxes'] == product_chargeTaxes assert data['product']['taxRate'] == product_taxRate.lower() assert data['product']['productType']['name'] == product_type.name assert data['product']['category']['name'] == category.name values = (data['product']['attributes'][0]['value']['slug'], data['product']['attributes'][1]['value']['slug']) assert slugify(non_existent_attr_value) in values assert color_value_slug in values
def test_real_query(user_api_client, product): product_attr = product.product_type.product_attributes.first() category = product.category attr_value = product_attr.values.first() filter_by = "%s:%s" % (product_attr.slug, attr_value.slug) query = """ query Root($categoryId: ID!, $sortBy: ProductOrder, $first: Int, $attributesFilter: [AttributeScalar], $minPrice: Float, $maxPrice: Float) { category(id: $categoryId) { ...CategoryPageFragmentQuery __typename } products(first: $first, sortBy: $sortBy, categories:[$categoryId], attributes: $attributesFilter, priceGte: $minPrice, priceLte: $maxPrice) { ...ProductListFragmentQuery __typename } attributes(inCategory: $categoryId, first: 20) { edges { node { ...ProductFiltersFragmentQuery __typename } } } } fragment CategoryPageFragmentQuery on Category { id name url ancestors(last: 20) { edges { node { name id url __typename } } } children(first: 20) { edges { node { name id url slug __typename } } } __typename } fragment ProductListFragmentQuery on ProductCountableConnection { edges { node { ...ProductFragmentQuery __typename } __typename } pageInfo { hasNextPage __typename } __typename } fragment ProductFragmentQuery on Product { id name pricing { ...ProductPriceFragmentQuery __typename } thumbnailUrl1x: thumbnailUrl(size: 255) thumbnailUrl2x: thumbnailUrl(size: 510) url __typename } fragment ProductPriceFragmentQuery on ProductPricingInfo { available discount { gross { amount currency __typename } __typename } priceRange { stop { gross { amount currency localized __typename } currency __typename } start { gross { amount currency localized __typename } currency __typename } __typename } __typename } fragment ProductFiltersFragmentQuery on Attribute { id name slug values { id name slug __typename } __typename } """ variables = { "categoryId": graphene.Node.to_global_id("Category", category.id), "sortBy": { "field": "NAME", "direction": "ASC" }, "first": 1, "attributesFilter": [filter_by], } response = user_api_client.post_graphql(query, variables) get_graphql_content(response)
def test_order_query(staff_api_client, permission_manage_orders, fulfilled_order, shipping_zone): order = fulfilled_order query = """ query OrdersQuery { orders(first: 1) { edges { node { number status statusDisplay paymentStatus paymentStatusDisplay userEmail isPaid shippingPrice { gross { amount } } lines { id } fulfillments { fulfillmentOrder } payments{ id } subtotal { net { amount } } total { net { amount } } availableShippingMethods { id price { amount } minimumOrderPrice { amount currency } type } } } } } """ staff_api_client.user.user_permissions.add(permission_manage_orders) response = staff_api_client.post_graphql(query) content = get_graphql_content(response) order_data = content['data']['orders']['edges'][0]['node'] assert order_data['number'] == str(order.pk) assert order_data['status'] == order.status.upper() assert order_data['statusDisplay'] == order.get_status_display() assert order_data['paymentStatus'] == order.get_last_payment_status() payment_status_display = order.get_last_payment_status_display() assert order_data['paymentStatusDisplay'] == payment_status_display assert order_data['isPaid'] == order.is_fully_paid() assert order_data['userEmail'] == order.user_email expected_price = order_data['shippingPrice']['gross']['amount'] assert expected_price == order.shipping_price.gross.amount assert len(order_data['lines']) == order.lines.count() fulfillment = order.fulfillments.first().fulfillment_order fulfillment_order = order_data['fulfillments'][0]['fulfillmentOrder'] assert fulfillment_order == fulfillment assert len(order_data['payments']) == order.payments.count() expected_methods = ShippingMethod.objects.applicable_shipping_methods( price=order.get_subtotal().gross.amount, weight=order.get_total_weight(), country_code=order.shipping_address.country.code) assert len( order_data['availableShippingMethods']) == (expected_methods.count()) method = order_data['availableShippingMethods'][0] expected_method = expected_methods.first() assert float(expected_method.price.amount) == method['price']['amount'] assert float(expected_method.minimum_order_price.amount) == ( method['minimumOrderPrice']['amount']) assert expected_method.type.upper() == method['type']
def test_draft_order_create(staff_api_client, permission_manage_orders, customer_user, product_without_shipping, shipping_method, variant, voucher, graphql_address_data): variant_0 = variant query = """ mutation draftCreate( $user: ID, $discount: Decimal, $lines: [OrderLineCreateInput], $shippingAddress: AddressInput, $shippingMethod: ID, $voucher: ID) { draftOrderCreate( input: {user: $user, discount: $discount, lines: $lines, shippingAddress: $shippingAddress, shippingMethod: $shippingMethod, voucher: $voucher}) { errors { field message } order { discountAmount { amount } discountName lines { productName productSku quantity } status voucher { code } } } } """ user_id = graphene.Node.to_global_id('User', customer_user.id) variant_0_id = graphene.Node.to_global_id('ProductVariant', variant_0.id) variant_1 = product_without_shipping.variants.first() variant_1.quantity = 2 variant_1.save() variant_1_id = graphene.Node.to_global_id('ProductVariant', variant_1.id) discount = '10' variant_list = [{ 'variantId': variant_0_id, 'quantity': 2 }, { 'variantId': variant_1_id, 'quantity': 1 }] shipping_address = graphql_address_data shipping_id = graphene.Node.to_global_id('ShippingMethod', shipping_method.id) voucher_id = graphene.Node.to_global_id('Voucher', voucher.id) variables = { 'user': user_id, 'discount': discount, 'lines': variant_list, 'shippingAddress': shipping_address, 'shippingMethod': shipping_id, 'voucher': voucher_id } response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_orders]) content = get_graphql_content(response) assert not content['data']['draftOrderCreate']['errors'] data = content['data']['draftOrderCreate']['order'] assert data['status'] == OrderStatus.DRAFT.upper() assert data['voucher']['code'] == voucher.code order = Order.objects.first() assert order.user == customer_user assert order.billing_address == customer_user.default_billing_address assert order.shipping_method == shipping_method assert order.shipping_address.first_name == graphql_address_data[ 'firstName']
def test_category_create_mutation(monkeypatch, staff_api_client, permission_manage_products): query = """ mutation( $name: String, $slug: String, $description: String, $descriptionJson: JSONString, $backgroundImage: Upload, $backgroundImageAlt: String, $parentId: ID) { categoryCreate( input: { name: $name slug: $slug description: $description descriptionJson: $descriptionJson backgroundImage: $backgroundImage backgroundImageAlt: $backgroundImageAlt }, parent: $parentId ) { category { id name slug description descriptionJson parent { name id } backgroundImage{ alt } } errors { field message } } } """ mock_create_thumbnails = Mock(return_value=None) monkeypatch.setattr(('remote_works.dashboard.category.forms.' 'create_category_background_image_thumbnails.delay'), mock_create_thumbnails) category_name = 'Test category' category_slug = slugify(category_name) category_description = 'Test description' category_description_json = json.dumps({'content': 'description'}) image_file, image_name = create_image() image_alt = 'Alt text for an image.' # test creating root category variables = { 'name': category_name, 'description': category_description, 'descriptionJson': category_description_json, 'backgroundImage': image_name, 'backgroundImageAlt': image_alt, 'slug': category_slug } body = get_multipart_request_body(query, variables, image_file, image_name) response = staff_api_client.post_multipart( body, permissions=[permission_manage_products]) content = get_graphql_content(response) data = content['data']['categoryCreate'] assert data['errors'] == [] assert data['category']['name'] == category_name assert data['category']['description'] == category_description assert data['category']['descriptionJson'] == category_description_json assert not data['category']['parent'] category = Category.objects.get(name=category_name) assert category.background_image.file mock_create_thumbnails.assert_called_once_with(category.pk) assert data['category']['backgroundImage']['alt'] == image_alt # test creating subcategory parent_id = data['category']['id'] variables = { 'name': category_name, 'description': category_description, 'parentId': parent_id, 'slug': category_slug } response = staff_api_client.post_graphql(query, variables) content = get_graphql_content(response) data = content['data']['categoryCreate'] assert data['errors'] == [] assert data['category']['parent']['id'] == parent_id
def step_impl(context): query = get_query_from_file('logout.graphql') variables = {'token': context.token} response = context.test.client.post_graphql(query, variables) context.response = get_graphql_content(response)
def test_customer_create( send_password_reset_mock, staff_api_client, user_api_client, address, permission_manage_users): query = """ mutation CreateCustomer( $email: String, $firstName: String, $lastName: String, $note: String, $billing: AddressInput, $shipping: AddressInput, $send_mail: Boolean) { customerCreate(input: { email: $email, firstName: $firstName, lastName: $lastName, note: $note, defaultShippingAddress: $shipping, defaultBillingAddress: $billing sendPasswordEmail: $send_mail }) { errors { field message } user { id defaultBillingAddress { id } defaultShippingAddress { id } email firstName lastName isActive isStaff note } } } """ email = '*****@*****.**' first_name = "api_first_name" last_name = "api_last_name" note = 'Test user' address_data = convert_dict_keys_to_camel_case(address.as_data()) variables = { 'email': email, 'firstName': first_name, 'lastName': last_name, 'note': note, 'shipping': address_data, 'billing': address_data, 'send_mail': True} response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_users]) content = get_graphql_content(response) User = get_user_model() customer = User.objects.get(email=email) assert customer.default_billing_address == address assert customer.default_shipping_address == address assert customer.default_shipping_address.pk != customer.default_billing_address.pk data = content['data']['customerCreate'] assert data['errors'] == [] assert data['user']['email'] == email assert data['user']['firstName'] == first_name assert data['user']['lastName'] == last_name assert data['user']['note'] == note assert data['user']['isStaff'] == False assert data['user']['isActive'] == True assert send_password_reset_mock.call_count == 1 args, kwargs = send_password_reset_mock.call_args call_context = args[0] call_email = args[1] assert call_email == email assert 'token' in call_context
def test_create_checkout(api_client, graphql_address_data, variant, count_queries): query = """ fragment Price on TaxedMoney { gross { amount localized } currency } fragment ProductVariant on ProductVariant { id name pricing { discountLocalCurrency { currency gross { amount localized } } price { currency gross { amount localized } } priceUndiscounted { currency gross { amount localized } } priceLocalCurrency { currency gross { amount localized } } } product { id name thumbnail { url alt } thumbnail2x: thumbnail(size: 510) { url } } } fragment CheckoutLine on CheckoutLine { id quantity totalPrice { ...Price } variant { ...ProductVariant } quantity } fragment Address on Address { id firstName lastName companyName streetAddress1 streetAddress2 city postalCode country { code country } countryArea phone } fragment ShippingMethod on ShippingMethod { id name price { currency amount localized } } fragment Checkout on Checkout { token id user { email } totalPrice { ...Price } subtotalPrice { ...Price } billingAddress { ...Address } shippingAddress { ...Address } email availableShippingMethods { ...ShippingMethod } shippingMethod { ...ShippingMethod } shippingPrice { ...Price } lines { ...CheckoutLine } } mutation createCheckout($checkoutInput: CheckoutCreateInput!) { checkoutCreate(input: $checkoutInput) { errors { field message } checkout { ...Checkout } } } """ variables = { "checkoutInput": { "email": "*****@*****.**", "shippingAddress": graphql_address_data, "lines": [{ "quantity": 1, "variantId": Node.to_global_id("ProductVariant", variant.pk), }], } } get_graphql_content(api_client.post_graphql(query, variables))
def test_add_billing_address_to_checkout(api_client, graphql_address_data, checkout_with_shipping_method, count_queries): query = """ fragment Price on TaxedMoney { gross { amount localized } currency } fragment ProductVariant on ProductVariant { id name pricing { discountLocalCurrency { currency gross { amount localized } } price { currency gross { amount localized } } priceUndiscounted { currency gross { amount localized } } priceLocalCurrency { currency gross { amount localized } } } product { id name thumbnail { url alt } thumbnail2x: thumbnail(size: 510) { url } } } fragment CheckoutLine on CheckoutLine { id quantity totalPrice { ...Price } variant { ...ProductVariant } quantity } fragment Address on Address { id firstName lastName companyName streetAddress1 streetAddress2 city postalCode country { code country } countryArea phone } fragment ShippingMethod on ShippingMethod { id name price { currency amount localized } } fragment Checkout on Checkout { token id user { email } totalPrice { ...Price } subtotalPrice { ...Price } billingAddress { ...Address } shippingAddress { ...Address } email availableShippingMethods { ...ShippingMethod } shippingMethod { ...ShippingMethod } shippingPrice { ...Price } lines { ...CheckoutLine } } mutation updateCheckoutBillingAddress( $checkoutId: ID! $billingAddress: AddressInput! ) { checkoutBillingAddressUpdate( checkoutId: $checkoutId billingAddress: $billingAddress ) { errors { field message } checkout { ...Checkout } } } """ variables = { "checkoutId": Node.to_global_id("Checkout", checkout_with_shipping_method.pk), "billingAddress": graphql_address_data, } get_graphql_content(api_client.post_graphql(query, variables))
def test_category_create_mutation( monkeypatch, staff_api_client, permission_manage_products, media_root ): query = """ mutation( $name: String, $slug: String, $description: String, $descriptionJson: JSONString, $backgroundImage: Upload, $backgroundImageAlt: String, $parentId: ID) { categoryCreate( input: { name: $name slug: $slug description: $description descriptionJson: $descriptionJson backgroundImage: $backgroundImage backgroundImageAlt: $backgroundImageAlt }, parent: $parentId ) { category { id name slug description descriptionJson parent { name id } backgroundImage{ alt } } errors { field message } } } """ mock_create_thumbnails = Mock(return_value=None) monkeypatch.setattr( ( "saleor.dashboard.category.forms." "create_category_background_image_thumbnails.delay" ), mock_create_thumbnails, ) category_name = "Test category" category_slug = slugify(category_name) category_description = "Test description" category_description_json = json.dumps({"content": "description"}) image_file, image_name = create_image() image_alt = "Alt text for an image." # test creating root category variables = { "name": category_name, "description": category_description, "descriptionJson": category_description_json, "backgroundImage": image_name, "backgroundImageAlt": image_alt, "slug": category_slug, } body = get_multipart_request_body(query, variables, image_file, image_name) response = staff_api_client.post_multipart( body, permissions=[permission_manage_products] ) content = get_graphql_content(response) data = content["data"]["categoryCreate"] assert data["errors"] == [] assert data["category"]["name"] == category_name assert data["category"]["description"] == category_description assert data["category"]["descriptionJson"] == category_description_json assert not data["category"]["parent"] category = Category.objects.get(name=category_name) assert category.background_image.file mock_create_thumbnails.assert_called_once_with(category.pk) assert data["category"]["backgroundImage"]["alt"] == image_alt # test creating subcategory parent_id = data["category"]["id"] variables = { "name": category_name, "description": category_description, "parentId": parent_id, "slug": category_slug, } response = staff_api_client.post_graphql(query, variables) content = get_graphql_content(response) data = content["data"]["categoryCreate"] assert data["errors"] == [] assert data["category"]["parent"]["id"] == parent_id
def test_real_query(user_api_client, product): product_attr = product.product_type.product_attributes.first() category = product.category attr_value = product_attr.values.first() filter_by = '%s:%s' % (product_attr.slug, attr_value.slug) query = """ query Root($categoryId: ID!, $sortBy: String, $first: Int, $attributesFilter: [AttributeScalar], $minPrice: Float, $maxPrice: Float) { category(id: $categoryId) { ...CategoryPageFragmentQuery __typename } products(first: $first, sortBy: $sortBy, categories:[$categoryId], attributes: $attributesFilter, priceGte: $minPrice, priceLte: $maxPrice) { ...ProductListFragmentQuery __typename } attributes(inCategory: $categoryId) { edges { node { ...ProductFiltersFragmentQuery __typename } } } } fragment CategoryPageFragmentQuery on Category { id name url ancestors { edges { node { name id url __typename } } } children { edges { node { name id url slug __typename } } } __typename } fragment ProductListFragmentQuery on ProductCountableConnection { edges { node { ...ProductFragmentQuery __typename } __typename } pageInfo { hasNextPage __typename } __typename } fragment ProductFragmentQuery on Product { id name price { amount currency localized __typename } availability { ...ProductPriceFragmentQuery __typename } thumbnailUrl1x: thumbnailUrl(size: 255) thumbnailUrl2x: thumbnailUrl(size: 510) url __typename } fragment ProductPriceFragmentQuery on ProductAvailability { available discount { gross { amount currency __typename } __typename } priceRange { stop { gross { amount currency localized __typename } currency __typename } start { gross { amount currency localized __typename } currency __typename } __typename } __typename } fragment ProductFiltersFragmentQuery on Attribute { id name slug values { id name slug __typename } __typename } """ variables = { 'categoryId': graphene.Node.to_global_id( 'Category', category.id), 'sortBy': 'name', 'first': 1, 'attributesFilter': [filter_by]} response = user_api_client.post_graphql(query, variables) get_graphql_content(response)
def test_customer_update( staff_api_client, customer_user, address, permission_manage_users): query = """ mutation UpdateCustomer($id: ID!, $firstName: String, $lastName: String, $isActive: Boolean, $note: String, $billing: AddressInput, $shipping: AddressInput) { customerUpdate(id: $id, input: { isActive: $isActive, firstName: $firstName, lastName: $lastName, note: $note, defaultBillingAddress: $billing defaultShippingAddress: $shipping }) { errors { field message } user { id firstName lastName defaultBillingAddress { id } defaultShippingAddress { id } isActive note } } } """ # this test requires addresses to be set and checks whether new address # instances weren't created, but the existing ones got updated assert customer_user.default_billing_address assert customer_user.default_shipping_address billing_address_pk = customer_user.default_billing_address.pk shipping_address_pk = customer_user.default_shipping_address.pk id = graphene.Node.to_global_id('User', customer_user.id) first_name = 'new_first_name' last_name = 'new_last_name' note = 'Test update note' address_data = convert_dict_keys_to_camel_case(address.as_data()) new_street_address = 'Updated street address' address_data['streetAddress1'] = new_street_address variables = { 'id': id, 'firstName': first_name, 'lastName': last_name, 'isActive': False, 'note': note, 'billing': address_data, 'shipping': address_data} response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_users]) content = get_graphql_content(response) User = get_user_model() customer = User.objects.get(email=customer_user.email) # check that existing instances are updated assert customer.default_billing_address.pk == billing_address_pk assert customer.default_shipping_address.pk == shipping_address_pk assert customer.default_billing_address.street_address_1 == new_street_address assert customer.default_shipping_address.street_address_1 == new_street_address data = content['data']['customerUpdate'] assert data['errors'] == [] assert data['user']['firstName'] == first_name assert data['user']['lastName'] == last_name assert data['user']['note'] == note assert not data['user']['isActive']
def test_update_checkout_lines( api_client, checkout_with_variant, stock, product_with_default_variant, product_with_single_variant, product_with_two_variants, count_queries, ): query = (FRAGMENT_CHECKOUT_LINE + """ mutation updateCheckoutLine($checkoutId: ID!, $lines: [CheckoutLineInput]!){ checkoutLinesUpdate(checkoutId: $checkoutId, lines: $lines) { checkout { id lines { ...CheckoutLine } totalPrice { ...Price } subtotalPrice { ...Price } isShippingRequired } errors { field message } } } """) variables = { "checkoutId": Node.to_global_id("Checkout", checkout_with_variant.pk), "lines": [ { "quantity": 1, "variantId": Node.to_global_id("ProductVariant", stock.product_variant.pk), }, { "quantity": 2, "variantId": Node.to_global_id( "ProductVariant", product_with_default_variant.variants.first().pk, ), }, { "quantity": 10, "variantId": Node.to_global_id( "ProductVariant", product_with_single_variant.variants.first().pk, ), }, { "quantity": 3, "variantId": Node.to_global_id( "ProductVariant", product_with_two_variants.variants.first().pk, ), }, { "quantity": 2, "variantId": Node.to_global_id( "ProductVariant", product_with_two_variants.variants.last().pk, ), }, ], } response = get_graphql_content(api_client.post_graphql(query, variables)) assert not response["data"]["checkoutLinesUpdate"]["errors"]
def test_me_query(user_api_client): response = user_api_client.post_graphql(ME_QUERY) content = get_graphql_content(response) data = content['data']['me'] assert data['email'] == user_api_client.user.email
def test_product_query(staff_api_client, product, permission_manage_products): category = Category.objects.first() product = category.products.first() query = """ query { category(id: "%(category_id)s") { products { edges { node { id name url thumbnailUrl images { url } variants { name stockQuantity } availability { available, priceRange { start { gross { amount currency localized } net { amount currency localized } currency } } } purchaseCost { start { amount } stop { amount } } margin { start stop } } } } } } """ % { 'category_id': graphene.Node.to_global_id('Category', category.id) } staff_api_client.user.user_permissions.add(permission_manage_products) response = staff_api_client.post_graphql(query) content = get_graphql_content(response) assert content['data']['category'] is not None product_edges_data = content['data']['category']['products']['edges'] assert len(product_edges_data) == category.products.count() product_data = product_edges_data[0]['node'] assert product_data['name'] == product.name assert product_data['url'] == product.get_absolute_url() gross = product_data['availability']['priceRange']['start']['gross'] assert float(gross['amount']) == float(product.price.amount) from saleor.product.utils.costs import get_product_costs_data purchase_cost, margin = get_product_costs_data(product) assert purchase_cost.start.amount == product_data['purchaseCost']['start'][ 'amount'] assert purchase_cost.stop.amount == product_data['purchaseCost']['stop'][ 'amount'] assert margin[0] == product_data['margin']['start'] assert margin[1] == product_data['margin']['stop']
def test_create_checkout( api_client, graphql_address_data, stock, product_with_default_variant, product_with_single_variant, product_with_two_variants, count_queries, ): query = (FRAGMENT_CHECKOUT + """ mutation CreateCheckout($checkoutInput: CheckoutCreateInput!) { checkoutCreate(input: $checkoutInput) { errors { field message } checkout { ...Checkout } } } """) checkout_counts = Checkout.objects.count() variables = { "checkoutInput": { "email": "*****@*****.**", "shippingAddress": graphql_address_data, "lines": [ { "quantity": 1, "variantId": Node.to_global_id("ProductVariant", stock.product_variant.pk), }, { "quantity": 2, "variantId": Node.to_global_id( "ProductVariant", product_with_default_variant.variants.first().pk, ), }, { "quantity": 10, "variantId": Node.to_global_id( "ProductVariant", product_with_single_variant.variants.first().pk, ), }, { "quantity": 3, "variantId": Node.to_global_id( "ProductVariant", product_with_two_variants.variants.first().pk, ), }, { "quantity": 2, "variantId": Node.to_global_id( "ProductVariant", product_with_two_variants.variants.last().pk, ), }, ], } } get_graphql_content(api_client.post_graphql(query, variables)) assert checkout_counts + 1 == Checkout.objects.count()
def test_product_type_create_mutation(staff_api_client, product_type, permission_manage_products): query = """ mutation createProductType( $name: String!, $taxRate: TaxRateType!, $hasVariants: Boolean!, $isShippingRequired: Boolean!, $productAttributes: [ID], $variantAttributes: [ID]) { productTypeCreate( input: { name: $name, taxRate: $taxRate, hasVariants: $hasVariants, isShippingRequired: $isShippingRequired, productAttributes: $productAttributes, variantAttributes: $variantAttributes}) { productType { name taxRate isShippingRequired hasVariants variantAttributes { name values { name } } productAttributes { name values { name } } } } } """ product_type_name = 'test type' has_variants = True require_shipping = True product_attributes = product_type.product_attributes.all() product_attributes_ids = [ graphene.Node.to_global_id('Attribute', att.id) for att in product_attributes ] variant_attributes = product_type.variant_attributes.all() variant_attributes_ids = [ graphene.Node.to_global_id('Attribute', att.id) for att in variant_attributes ] variables = { 'name': product_type_name, 'hasVariants': has_variants, 'taxRate': 'STANDARD', 'isShippingRequired': require_shipping, 'productAttributes': product_attributes_ids, 'variantAttributes': variant_attributes_ids } initial_count = ProductType.objects.count() response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products]) content = get_graphql_content(response) assert ProductType.objects.count() == initial_count + 1 data = content['data']['productTypeCreate']['productType'] assert data['name'] == product_type_name assert data['hasVariants'] == has_variants assert data['isShippingRequired'] == require_shipping pa = product_attributes[0] assert data['productAttributes'][0]['name'] == pa.name pa_values = data['productAttributes'][0]['values'] assert sorted([value['name'] for value in pa_values ]) == sorted([value.name for value in pa.values.all()]) va = variant_attributes[0] assert data['variantAttributes'][0]['name'] == va.name va_values = data['variantAttributes'][0]['values'] assert sorted([value['name'] for value in va_values ]) == sorted([value.name for value in va.values.all()]) new_instance = ProductType.objects.latest('pk') assert new_instance.tax_rate == 'standard'
def test_product_type_update_mutation(staff_api_client, product_type, permission_manage_products): query = """ mutation updateProductType( $id: ID!, $name: String!, $hasVariants: Boolean!, $isShippingRequired: Boolean!, $productAttributes: [ID], ) { productTypeUpdate( id: $id, input: { name: $name, hasVariants: $hasVariants, isShippingRequired: $isShippingRequired, productAttributes: $productAttributes }) { productType { name isShippingRequired hasVariants variantAttributes { id } productAttributes { id } } } } """ product_type_name = 'test type updated' has_variants = True require_shipping = False product_type_id = graphene.Node.to_global_id('ProductType', product_type.id) # Test scenario: remove all product attributes using [] as input # but do not change variant attributes product_attributes = [] product_attributes_ids = [ graphene.Node.to_global_id('Attribute', att.id) for att in product_attributes ] variant_attributes = product_type.variant_attributes.all() variables = { 'id': product_type_id, 'name': product_type_name, 'hasVariants': has_variants, 'isShippingRequired': require_shipping, 'productAttributes': product_attributes_ids } response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products]) content = get_graphql_content(response) data = content['data']['productTypeUpdate']['productType'] assert data['name'] == product_type_name assert data['hasVariants'] == has_variants assert data['isShippingRequired'] == require_shipping assert len(data['productAttributes']) == 0 assert len(data['variantAttributes']) == (variant_attributes.count())
def test_menu_reorder_assign_parent_to_top_level(staff_api_client, permission_manage_menus, menu_item_list): """Set the parent of an item to None, to put it as to the root level.""" menu_item_list = list(menu_item_list) menu_global_id = graphene.Node.to_global_id("Menu", menu_item_list[0].menu_id) unchanged_item_global_id = graphene.Node.to_global_id( "MenuItem", menu_item_list[2].pk) root_candidate = menu_item_list[0] root_candidate_global_id = graphene.Node.to_global_id( "MenuItem", root_candidate.pk) # Give to the item menu a parent previous_parent = menu_item_list[1] previous_parent_global_id = graphene.Node.to_global_id( "MenuItem", previous_parent.pk) root_candidate.move_to(previous_parent) root_candidate.save() assert root_candidate.parent moves_input = [{ "itemId": root_candidate_global_id, "parentId": None, "sortOrder": None }] expected_data = { "id": menu_global_id, "items": [ { "id": previous_parent_global_id, "sortOrder": 1, "parent": None, "children": [], }, { "id": unchanged_item_global_id, "sortOrder": 2, "parent": None, "children": [], }, { "id": root_candidate_global_id, "sortOrder": 3, "parent": None, "children": [], }, ], } response = get_graphql_content( staff_api_client.post_graphql( QUERY_REORDER_MENU, { "moves": moves_input, "menu": menu_global_id }, [permission_manage_menus], ))["data"]["menuItemMove"] menu_data = response["menu"] assert not response["errors"] assert menu_data # Ensure the the item was successfully placed at the root # and is now at the bottom of the list (default) assert menu_data == expected_data
def test_update_product(staff_api_client, category, non_default_category, product, permission_manage_products): query = """ mutation updateProduct( $productId: ID!, $categoryId: ID!, $name: String!, $description: String!, $isPublished: Boolean!, $chargeTaxes: Boolean!, $taxRate: TaxRateType!, $price: Decimal!, $attributes: [AttributeValueInput!]) { productUpdate( id: $productId, input: { category: $categoryId, name: $name, description: $description, isPublished: $isPublished, chargeTaxes: $chargeTaxes, taxRate: $taxRate, price: $price, attributes: $attributes }) { product { category { name } description isPublished chargeTaxes taxRate name price { amount } productType { name } attributes { attribute { name } value { name } } } errors { message field } } } """ product_id = graphene.Node.to_global_id('Product', product.pk) category_id = graphene.Node.to_global_id('Category', non_default_category.pk) product_description = 'updated description' product_name = 'updated name' product_isPublished = True product_chargeTaxes = True product_taxRate = 'STANDARD' product_price = "33.12" variables = { 'productId': product_id, 'categoryId': category_id, 'name': product_name, 'description': product_description, 'isPublished': product_isPublished, 'chargeTaxes': product_chargeTaxes, 'taxRate': product_taxRate, 'price': product_price } response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products]) content = get_graphql_content(response) data = content['data']['productUpdate'] assert data['errors'] == [] assert data['product']['name'] == product_name assert data['product']['description'] == product_description assert data['product']['isPublished'] == product_isPublished assert data['product']['chargeTaxes'] == product_chargeTaxes assert data['product']['taxRate'] == product_taxRate.lower() assert not data['product']['category']['name'] == category.name
def test_menu_reorder(staff_api_client, permission_manage_menus, menu_item_list): menu_item_list = list(menu_item_list) menu_global_id = graphene.Node.to_global_id("Menu", menu_item_list[0].menu_id) assert len(menu_item_list) == 3 items_global_ids = [ graphene.Node.to_global_id("MenuItem", item.pk) for item in menu_item_list ] moves_input = [ { "itemId": items_global_ids[0], "parentId": None, "sortOrder": 0 }, { "itemId": items_global_ids[1], "parentId": None, "sortOrder": -1 }, { "itemId": items_global_ids[2], "parentId": None, "sortOrder": None }, ] expected_data = { "id": menu_global_id, "items": [ { "id": items_global_ids[1], "sortOrder": 0, "parent": None, "children": [] }, { "id": items_global_ids[0], "sortOrder": 1, "parent": None, "children": [] }, { "id": items_global_ids[2], "sortOrder": 2, "parent": None, "children": [] }, ], } response = get_graphql_content( staff_api_client.post_graphql( QUERY_REORDER_MENU, { "moves": moves_input, "menu": menu_global_id }, [permission_manage_menus], ))["data"]["menuItemMove"] menu_data = response["menu"] assert not response["errors"] assert menu_data # Ensure the order is right assert menu_data == expected_data
def test_menu_reorder_assign_parent(staff_api_client, permission_manage_menus, menu_item_list): """Assign a menu item as parent of given menu items. Ensure the menu items are properly pushed at the bottom of the item's children. """ menu_item_list = list(menu_item_list) assert len(menu_item_list) == 3 menu_id = graphene.Node.to_global_id("Menu", menu_item_list[1].menu_id) root = menu_item_list[0] item0 = MenuItem.objects.create(menu=root.menu, parent=root, name="Default Link") menu_item_list.insert(0, item0) parent_global_id = graphene.Node.to_global_id("MenuItem", root.pk) items_global_ids = [ graphene.Node.to_global_id("MenuItem", item.pk) for item in menu_item_list ] moves_input = [ { "itemId": items_global_ids[2], "parentId": parent_global_id, "sortOrder": None, }, { "itemId": items_global_ids[3], "parentId": parent_global_id, "sortOrder": None, }, ] expected_data = { "id": menu_id, "items": [{ "id": items_global_ids[1], "sortOrder": 0, "parent": None, "children": [ { "id": items_global_ids[0], "sortOrder": 0, "parent": { "id": parent_global_id }, "children": [], }, { "id": items_global_ids[2], "sortOrder": 1, "parent": { "id": parent_global_id }, "children": [], }, { "id": items_global_ids[3], "sortOrder": 2, "parent": { "id": parent_global_id }, "children": [], }, ], }], } response = get_graphql_content( staff_api_client.post_graphql( QUERY_REORDER_MENU, { "moves": moves_input, "menu": menu_id }, [permission_manage_menus], ))["data"]["menuItemMove"] menu_data = response["menu"] assert not response["errors"] assert menu_data # Ensure the parent and sort orders were assigned correctly assert menu_data == expected_data
def test_permission_group_update( permission_group_manage_users, staff_user, permission_manage_staff, staff_api_client, permission_manage_apps, permission_manage_users, count_queries, ): query = """ mutation PermissionGroupUpdate( $id: ID!, $input: PermissionGroupUpdateInput!) { permissionGroupUpdate( id: $id, input: $input) { group{ id name permissions { name code } } permissionGroupErrors{ field code permissions users message } } } """ group_count = Group.objects.count() staff_user.user_permissions.add(permission_manage_apps, permission_manage_users) group = permission_group_manage_users group.permissions.add(permission_manage_staff) variables = { "id": graphene.Node.to_global_id("Group", group.id), "input": { "name": "New permission group", "addPermissions": [AccountPermissions.MANAGE_SERVICE_ACCOUNTS.name], "removePermissions": [AccountPermissions.MANAGE_USERS.name], "addUsers": [graphene.Node.to_global_id("User", staff_user.pk)], "removeUsers": [graphene.Node.to_global_id("User", group.user_set.first().pk)], }, } response = staff_api_client.post_graphql( query, variables, permissions=(permission_manage_staff, )) content = get_graphql_content(response) data = content["data"]["permissionGroupUpdate"] groups = Group.objects.all() assert data["permissionGroupErrors"] == [] assert len(groups) == group_count
def test_payments_query( payment_txn_captured, permission_manage_orders, staff_api_client ): query = """ { payments(first: 20) { edges { node { id gateway capturedAmount { amount currency } total { amount currency } actions chargeStatus billingAddress { country { code country } firstName lastName cityArea countryArea city companyName streetAddress1 streetAddress2 postalCode } transactions { amount { currency amount } } creditCard { expMonth expYear brand firstDigits lastDigits } } } } } """ response = staff_api_client.post_graphql( query, permissions=[permission_manage_orders] ) content = get_graphql_content(response) data = content["data"]["payments"]["edges"][0]["node"] pay = payment_txn_captured assert data["gateway"] == pay.gateway amount = str(data["capturedAmount"]["amount"]) assert Decimal(amount) == pay.captured_amount assert data["capturedAmount"]["currency"] == pay.currency total = str(data["total"]["amount"]) assert Decimal(total) == pay.total assert data["total"]["currency"] == pay.currency assert data["chargeStatus"] == PaymentChargeStatusEnum.FULLY_CHARGED.name assert data["billingAddress"] == { "firstName": pay.billing_first_name, "lastName": pay.billing_last_name, "city": pay.billing_city, "cityArea": pay.billing_city_area, "countryArea": pay.billing_country_area, "companyName": pay.billing_company_name, "streetAddress1": pay.billing_address_1, "streetAddress2": pay.billing_address_2, "postalCode": pay.billing_postal_code, "country": { "code": pay.billing_country_code, "country": get_country_name_by_code(pay.billing_country_code), }, } assert data["actions"] == [OrderAction.REFUND.name] txn = pay.transactions.get() assert data["transactions"] == [ {"amount": {"currency": pay.currency, "amount": float(str(txn.amount))}} ] assert data["creditCard"] == { "expMonth": pay.cc_exp_month, "expYear": pay.cc_exp_year, "brand": pay.cc_brand, "firstDigits": pay.cc_first_digits, "lastDigits": pay.cc_last_digits, }
def test_verify_token(api_client, customer_user): variables = {"token": get_token(customer_user)} response = api_client.post_graphql(MUTATION_TOKEN_VERIFY, variables) content = get_graphql_content(response) user_email = content["data"]["tokenVerify"]["user"]["email"] assert customer_user.email == user_email
def test_permission_group_update_remove_users_with_manage_staff( permission_group_manage_users, staff_users, permission_manage_staff, staff_api_client, permission_manage_apps, permission_manage_users, permission_manage_orders, count_queries, ): query = """ mutation PermissionGroupUpdate( $id: ID!, $input: PermissionGroupUpdateInput!) { permissionGroupUpdate( id: $id, input: $input) { group{ id name permissions { name code } users { email } } permissionGroupErrors{ field code permissions users message } } } """ staff_user, staff_user1, staff_user2 = staff_users groups = Group.objects.bulk_create([ Group(name="manage users"), Group(name="manage staff, order and users") ]) group1, group2 = groups group1.permissions.add(permission_manage_staff, permission_manage_users) group2.permissions.add(permission_manage_staff, permission_manage_orders, permission_manage_users) group1.user_set.add(staff_user1, staff_user2) group2.user_set.add(staff_user2) staff_user.user_permissions.add(permission_manage_users, permission_manage_orders) variables = { "id": graphene.Node.to_global_id("Group", group1.id), "input": { "removeUsers": [ graphene.Node.to_global_id("User", user.id) for user in [staff_user1, staff_user2] ], }, } response = staff_api_client.post_graphql( query, variables, permissions=(permission_manage_staff, )) content = get_graphql_content(response) data = content["data"]["permissionGroupUpdate"] assert len(data["group"]["users"]) == 0
def test_verify_token_incorrect_token(api_client): variables = {"token": "incorrect_token"} response = api_client.post_graphql(MUTATION_TOKEN_VERIFY, variables) content = get_graphql_content(response) assert not content["data"]["tokenVerify"]
def test_payments_query(payment_txn_captured, permission_manage_orders, staff_api_client): query = """ { payments(first: 20) { edges { node { id gateway capturedAmount { amount currency } total { amount currency } actions chargeStatus billingAddress { country { code country } firstName lastName cityArea countryArea city companyName streetAddress1 streetAddress2 postalCode } transactions { amount { currency amount } } creditCard { expMonth expYear brand firstDigits lastDigits } } } } } """ response = staff_api_client.post_graphql( query, permissions=[permission_manage_orders]) content = get_graphql_content(response) data = content['data']['payments']['edges'][0]['node'] pay = payment_txn_captured assert data['gateway'] == pay.gateway assert data['capturedAmount'] == { 'amount': pay.captured_amount, 'currency': pay.currency } assert data['total'] == {'amount': pay.total, 'currency': pay.currency} assert data['chargeStatus'] == PaymentChargeStatusEnum.FULLY_CHARGED.name assert data['billingAddress'] == { 'firstName': pay.billing_first_name, 'lastName': pay.billing_last_name, 'city': pay.billing_city, 'cityArea': pay.billing_city_area, 'countryArea': pay.billing_country_area, 'companyName': pay.billing_company_name, 'streetAddress1': pay.billing_address_1, 'streetAddress2': pay.billing_address_2, 'postalCode': pay.billing_postal_code, 'country': { 'code': pay.billing_country_code, 'country': get_country_name_by_code(pay.billing_country_code) } } assert data['actions'] == [OrderAction.REFUND.name] txn = pay.transactions.get() assert data['transactions'] == [{ 'amount': { 'currency': pay.currency, 'amount': float(str(txn.amount)) } }] assert data['creditCard'] == { 'expMonth': pay.cc_exp_month, 'expYear': pay.cc_exp_year, 'brand': pay.cc_brand, 'firstDigits': pay.cc_first_digits, 'lastDigits': pay.cc_last_digits }
def test_query_user(staff_api_client, customer_user, permission_manage_users): user = customer_user query = """ query User($id: ID!) { user(id: $id) { email firstName lastName isStaff isActive addresses { id } orders { totalCount } dateJoined lastLogin defaultShippingAddress { firstName lastName companyName streetAddress1 streetAddress2 city cityArea postalCode countryArea phone country { code } } } } """ ID = graphene.Node.to_global_id('User', customer_user.id) variables = {'id': ID} staff_api_client.user.user_permissions.add(permission_manage_users) response = staff_api_client.post_graphql(query, variables) content = get_graphql_content(response) data = content['data']['user'] assert data['email'] == user.email assert data['firstName'] == user.first_name assert data['lastName'] == user.last_name assert data['isStaff'] == user.is_staff assert data['isActive'] == user.is_active assert len(data['addresses']) == user.addresses.count() assert data['orders']['totalCount'] == user.orders.count() address = data['defaultShippingAddress'] user_address = user.default_shipping_address assert address['firstName'] == user_address.first_name assert address['lastName'] == user_address.last_name assert address['companyName'] == user_address.company_name assert address['streetAddress1'] == user_address.street_address_1 assert address['streetAddress2'] == user_address.street_address_2 assert address['city'] == user_address.city assert address['cityArea'] == user_address.city_area assert address['postalCode'] == user_address.postal_code assert address['country']['code'] == user_address.country.code assert address['countryArea'] == user_address.country_area assert address['phone'] == user_address.phone.as_e164
def test_query_countries(user_api_client): response = user_api_client.post_graphql(COUNTRIES_QUERY % {"attributes": ""}) content = get_graphql_content(response) data = content["data"]["shop"] assert len(data["countries"]) == len(countries)