Beispiel #1
0
def test_non_staff_user_can_only_see_his_order(user_api_client, order):
    # FIXME: Remove client.login() when JWT authentication is re-enabled.
    user_api_client.login(username=order.user.email, password='******')

    query = """
    query OrderQuery($id: ID!) {
        order(id: $id) {
            orderId
        }
    }
    """
    ID = graphene.Node.to_global_id('Order', order.id)
    variables = json.dumps({'id': ID})
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    order_data = content['data']['order']
    assert order_data['orderId'] == order.pk

    order.user = None
    order.save()
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    order_data = content['data']['order']
    assert not order_data
Beispiel #2
0
def test_voucher_permissions(
        staff_api_client, staff_user, permission_manage_discounts):
    query = """
    query vouchers{
        vouchers(first: 1) {
            edges {
                node {
                    name
                }
            }
        }
    }
    """
    # Query to ensure user with no permissions can't see vouchers
    response = staff_api_client.post(reverse('api'), {'query': query})
    content = get_graphql_content(response)
    message = 'You do not have permission to perform this action'
    assert content['errors'][0]['message'] == message

    # Give staff user proper permissions
    staff_user.user_permissions.add(permission_manage_discounts)

    # Query again
    response = staff_api_client.post(reverse('api'), {'query': query})
    content = get_graphql_content(response)
    assert 'errors' not in content
Beispiel #3
0
def test_create_token_mutation(admin_client, staff_user):
    query = '''
    mutation {
        tokenCreate(email: "%(email)s", password: "******") {
            token
            errors {
                field
                message
            }
        }
    }
    '''
    success_query = query % {'email': staff_user.email, 'password': '******'}
    response = admin_client.post(
        reverse('api'), json.dumps({'query': success_query}),
        content_type='application/json')
    content = get_graphql_content(response)
    assert 'errors' not in content
    token_data = content['data']['tokenCreate']
    assert token_data['token']
    assert not token_data['errors']

    error_query = query % {'email': staff_user.email, 'password': '******'}
    response = admin_client.post(
        reverse('api'), json.dumps({'query': error_query}),
        content_type='application/json')
    content = get_graphql_content(response)
    assert 'errors' not in content
    token_data = content['data']['tokenCreate']
    assert not token_data['token']
    errors = token_data['errors']
    assert errors
    assert not errors[0]['field']
Beispiel #4
0
def test_query_users(admin_api_client, user_api_client):
    query = """
    query Users($isStaff: Boolean) {
        users(isStaff: $isStaff) {
            totalCount
            edges {
                node {
                    isStaff
                }
            }
        }
    }
    """
    variables = json.dumps({'isStaff': True})
    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    users = content['data']['users']['edges']
    assert users
    assert all([user['node']['isStaff'] for user in users])

    variables = json.dumps({'isStaff': False})
    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    users = content['data']['users']['edges']
    assert users
    assert all([not user['node']['isStaff'] for user in users])

    # check permissions
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    assert_no_permission(response)
Beispiel #5
0
def test_category_create_mutation(admin_api_client):
    query = """
        mutation($name: String, $slug: String, $description: String, $parentId: ID) {
            categoryCreate(
                input: {
                    name: $name
                    slug: $slug
                    description: $description
                    parent: $parentId
                }
            ) {
                category {
                    id
                    name
                    slug
                    description
                    parent {
                        name
                        id
                    }
                }
                errors {
                    field
                    message
                }
            }
        }
    """

    category_name = 'Test category'
    category_slug = slugify(category_name)
    category_description = 'Test description'

    # test creating root category
    variables = json.dumps({
        'name': category_name, 'description': category_description,
        'slug': category_slug})
    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['categoryCreate']
    assert data['errors'] == []
    assert data['category']['name'] == category_name
    assert data['category']['description'] == category_description
    assert not data['category']['parent']

    # test creating subcategory
    parent_id = data['category']['id']
    variables = json.dumps({
        'name': category_name, 'description': category_description,
        'parentId': parent_id, 'slug': category_slug})
    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['categoryCreate']
    assert data['errors'] == []
    assert data['category']['parent']['id'] == parent_id
Beispiel #6
0
def test_category_level(user_api_client, default_category):
    category = default_category
    query = """
    query leveled_categories($level: Int) {
        categories(level: $level) {
            edges {
                node {
                    name
                    parent {
                        name
                    }
                }
            }
        }
    }
    """
    child = Category.objects.create(
        name='child', slug='chi-ld', parent=category)
    variables = json.dumps({'level': 0})
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    category_data = content['data']['categories']['edges'][0]['node']
    assert category_data['name'] == category.name
    assert category_data['parent'] == None

    query = """
    query leveled_categories($level: Int) {
        categories(level: $level) {
            edges {
                node {
                    name
                    parent {
                        name
                    }
                }
            }
        }
    }
    """
    variables = json.dumps({'level': 1})
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    category_data = content['data']['categories']['edges'][0]['node']
    assert category_data['name'] == child.name
    assert category_data['parent']['name'] == category.name
Beispiel #7
0
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
Beispiel #8
0
def test_voucher_query(
        admin_api_client, voucher):
    query = """
    query vouchers{
        vouchers(first: 1) {
            edges {
                node {
                    type
                    name
                    code
                    usageLimit
                    used
                    startDate
                    discountValueType
                    discountValue
                }
            }
        }
    }
    """
    response = admin_api_client.post(reverse('api'), {'query': query})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['vouchers']['edges'][0]['node']
    assert data['type'] == voucher.type.upper()
    assert data['name'] == voucher.name
    assert data['code'] == voucher.code
    assert data['usageLimit'] == voucher.usage_limit
    assert data['used'] == voucher.used
    assert data['startDate'] == voucher.start_date.isoformat()
    assert data['discountValueType'] == voucher.discount_value_type.upper()
    assert data['discountValue'] == voucher.discount_value
Beispiel #9
0
def test_address_validator_uses_geip_when_country_code_missing(
        user_api_client, monkeypatch):
    query = """
    query getValidator($input: AddressValidationInput!) {
        addressValidator(input: $input) {
            countryCode,
            countryName
        }
    }
    """
    variables = json.dumps({'input': {
        'countryCode': None,
        'countryArea': None,
        'cityArea': None
    }})
    mock_country_by_ip = Mock(return_value=Mock(code='US'))
    monkeypatch.setattr(
        'saleor.graphql.account.resolvers.get_client_ip',
        lambda request: Mock(return_value='127.0.0.1'))
    monkeypatch.setattr(
        'saleor.graphql.account.resolvers.get_country_by_ip',
        mock_country_by_ip)
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert mock_country_by_ip.called
    assert 'errors' not in content
    data = content['data']['addressValidator']
    assert data['countryCode'] == 'US'
    assert data['countryName'] == 'UNITED STATES'
Beispiel #10
0
def test_address_validator(user_api_client):
    query = """
    query getValidator($input: AddressValidationInput!) {
        addressValidator(input: $input) {
            countryCode
            countryName
            addressFormat
            addressLatinFormat
            postalCodeMatchers
        }
    }
    """
    variables = json.dumps({'input': {
        'countryCode': 'PL',
        'countryArea': None,
        'cityArea': None
    }})
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['addressValidator']
    assert data['countryCode'] == 'PL'
    assert data['countryName'] == 'POLAND'
    assert data['addressFormat'] is not None
    assert data['addressLatinFormat'] is not None
    matcher = data['postalCodeMatchers'][0]
    matcher = re.compile(matcher)
    assert matcher.match('00-123')
Beispiel #11
0
def test_validate_voucher(voucher, admin_api_client):
    query = """
    mutation  voucherUpdate(
        $id: ID!, $type: VoucherTypeEnum) {
            voucherUpdate(
            id: $id, input: {type: $type}) {
                errors {
                    field
                    message
                }
            }
        }
    """
    # apparently can't do so via pytest parametrize
    # as it parses VoucherTypeEnum into str format
    fields = (
        (VoucherTypeEnum.CATEGORY, 'categories'),
        (VoucherTypeEnum.PRODUCT, 'products'),
        (VoucherTypeEnum.COLLECTION, 'collections'))
    for voucher_type, field_name in fields:
        variables = json.dumps({
            'type': voucher_type.name,
            'id': graphene.Node.to_global_id('Voucher', voucher.id)})
        response = admin_api_client.post(
            reverse('api'), {'query': query, 'variables': variables})
        content = get_graphql_content(response)
        data = content['data']['voucherUpdate']['errors'][0]
        assert data['field'] == field_name
        assert data['message'] == 'This field is required.'
Beispiel #12
0
def test_create_product_attribute(admin_api_client):
    query = """
    mutation createAttribute($name: String!, $slug: String!) {
        productAttributeCreate(input: {name: $name, slug: $slug}) {
            productAttribute {
                name
                slug
                values {
                    name
                    slug
                }
            }
        }
    }
    """
    name = 'test name'
    slug = 'test-slug'
    variables = json.dumps({'name': name, 'slug': slug})
    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['productAttributeCreate']['productAttribute']
    assert data['name'] == name
    assert data['slug'] == slug
    assert not data['values']
Beispiel #13
0
def test_shop_endpoint(settings, admin_api_client):
    query = """
    query shop {
        shop {
            permissions {
                code
                name
            }
            languages {
                code
                language
            }
            phonePrefixes
        }
    }
    """
    languages = settings.LANGUAGES
    response = admin_api_client.post(reverse('api'), {'query': query})
    content = get_graphql_content(response)

    assert 'errors' not in content
    data = content['data']['shop']
    permissions = data['permissions']
    permissions_codes = {permission.get('code') for permission in permissions}
    assert len(permissions_codes) == len(MODELS_PERMISSIONS)
    for code in permissions_codes:
        assert code in MODELS_PERMISSIONS
    assert len(data['languages']) == len(languages)
    assert len(data['phonePrefixes']) == len(COUNTRY_CODE_TO_REGION_CODE)
Beispiel #14
0
def test_update_sale(user_api_client, admin_api_client, sale):
    query = """
    mutation  saleUpdate($type: DiscountValueTypeEnum, $id: ID!) {
            saleUpdate(id: $id, input: {type: $type}) {
                errors {
                    field
                    message
                }
                sale {
                    type
                }
            }
        }
    """
    # Set discount value type to 'fixed' and change it in mutation
    sale.type = DiscountValueType.FIXED
    sale.save()
    variables = json.dumps({
        'id': graphene.Node.to_global_id('Sale', sale.id),
        'type': DiscountValueTypeEnum.PERCENTAGE.name})

    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})

    assert_no_permission(response)

    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['saleUpdate']['sale']
    assert data['type'] == DiscountValueType.PERCENTAGE.upper()
Beispiel #15
0
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
Beispiel #16
0
def test_reorder_images(admin_api_client, product_with_images):
    query = """
    mutation reorderImages($product_id: ID!, $images_ids: [ID]!) {
        productImageReorder(productId: $product_id, imagesIds: $images_ids) {
            product {
                id
            }
        }
    }
    """
    product = product_with_images
    images = product.images.all()
    image_0 = images[0]
    image_1 = images[1]
    image_0_id = graphene.Node.to_global_id('ProductImage', image_0.id)
    image_1_id = graphene.Node.to_global_id('ProductImage', image_1.id)
    product_id = graphene.Node.to_global_id('Product', product.id)

    variables = {
        'product_id': product_id, 'images_ids': [image_1_id, image_0_id]}
    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content

    # Check if order has been changed
    product.refresh_from_db()
    reordered_images = product.images.all()
    reordered_image_0 = reordered_images[0]
    reordered_image_1 = reordered_images[1]
    assert image_0.id == reordered_image_1.id
    assert image_1.id == reordered_image_0.id
Beispiel #17
0
def test_invalid_product_image_create_mutation(admin_api_client, product):
    query = """
    mutation createProductImage($image: Upload!, $product: ID!) {
        productImageCreate(input: {image: $image, product: $product}) {
            image {
                id
                url
                sortOrder
            }
            errors {
                field
                message
            }
        }
    }
    """
    image_file, image_name = create_pdf_file_with_image_ext()
    variables = {
        'product': graphene.Node.to_global_id('Product', product.id),
        'image': image_name}
    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
    assert content['data']['productImageCreate']['errors'] == [{
        'field': 'image',
        'message': 'Invalid file type'}]
    product.refresh_from_db()
    assert product.images.count() == 0
Beispiel #18
0
def test_product_type(user_api_client, product_type):
    query = """
    query {
        productTypes {
            totalCount
            edges {
                node {
                    id
                    name
                    products(first: 1) {
                        edges {
                            node {
                                id
                            }
                        }
                    }
                }
            }
        }
    }
    """
    response = user_api_client.post(reverse('api'), {'query': query})
    content = get_graphql_content(response)
    no_product_types = ProductType.objects.count()
    assert 'errors' not in content
    assert content['data']['productTypes']['totalCount'] == no_product_types
    assert len(content['data']['productTypes']['edges']) == no_product_types
Beispiel #19
0
def test_update_attribute_choice_value(admin_api_client, pink_choice_value):
    value = pink_choice_value
    query = """
    mutation updateChoice($id: ID!, $name: String!, $slug: String!) {
        attributeChoiceValueUpdate(
        id: $id, input: {name: $name, slug: $slug}) {
            attributeChoiceValue {
                name
                slug
            }
        }
    }
    """
    id = graphene.Node.to_global_id('ProductAttributeValue', value.id)
    name = 'Crimson'
    slug = value.slug
    variables = json.dumps(
        {'name': name, 'slug': slug, 'id': id})
    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    value.refresh_from_db()
    data = content[
        'data']['attributeChoiceValueUpdate']['attributeChoiceValue']
    assert data['name'] == name == value.name
Beispiel #20
0
def test_sale_delete_mutation(user_api_client, admin_api_client, sale):
    query = """
        mutation DeleteSale($id: ID!) {
            saleDelete(id: $id) {
                sale {
                    name
                    id
                }
                errors {
                    field
                    message
                }
              }
            }
    """
    variables = json.dumps({
        'id': graphene.Node.to_global_id('Sale', sale.id)})

    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    assert_no_permission(response)

    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['saleDelete']
    assert data['sale']['name'] == sale.name
    with pytest.raises(sale._meta.model.DoesNotExist):
        sale.refresh_from_db()
Beispiel #21
0
def test_create_attribute_choice_value(admin_api_client, color_attribute):
    attribute = color_attribute
    query = """
    mutation createChoice($attribute: ID!, $name: String!, $slug: String!) {
        attributeChoiceValueCreate(
        input: {attribute: $attribute, name: $name, slug: $slug}) {
            attributeChoiceValue {
                name
                slug
            }
        }
    }
    """
    attribute_id = graphene.Node.to_global_id('ProductAttribute', attribute.id)
    name = 'test name'
    slug = 'test-slug'
    variables = json.dumps(
        {'name': name, 'slug': slug, 'attribute': attribute_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']['attributeChoiceValueCreate']['attributeChoiceValue']
    assert data['name'] == name
    assert data['slug'] == slug
Beispiel #22
0
def test_query_staff(
        admin_api_client, user_api_client, staff_user, customer_user,
        admin_user):
    query = """
    {
        staffUsers {
            edges {
                node {
                    email
                    isStaff
                }
            }
        }
    }
    """
    variables = json.dumps({})
    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    data = content['data']['staffUsers']['edges']
    assert len(data) == 2
    staff_emails = [user['node']['email'] for user in data]
    assert sorted(staff_emails) == [admin_user.email, staff_user.email]
    assert all([user['node']['isStaff'] for user in data])

    # check permissions
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    assert_no_permission(response)
Beispiel #23
0
def test_create_sale(user_api_client, admin_api_client):
    query = """
    mutation  saleCreate(
        $type: DiscountValueTypeEnum, $name: String, $value: Decimal) {
            saleCreate(input: {name: $name, type: $type, value: $value}) {
                errors {
                    field
                    message
                }
                sale {
                    type
                    name
                    value
                }
            }
        }
    """
    variables = json.dumps({
        'name': 'test sale',
        'type': DiscountValueTypeEnum.FIXED.name,
        'value': '10.12'})
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    assert_no_permission(response)

    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['saleCreate']['sale']
    assert data['type'] == DiscountValueType.FIXED.upper()
    assert data['name'] == 'test sale'
    assert data['value'] == 10.12
Beispiel #24
0
def test_password_reset_email(
        send_password_reset_mock, admin_api_client, customer_user):
    query = """
    mutation ResetPassword($email: String!) {
        passwordReset(email: $email) {
            errors {
                field
                message
            }
        }
    }
    """
    email = customer_user.email
    variables = json.dumps({'email': email})
    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['passwordReset']
    assert data is None
    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
Beispiel #25
0
def test_validate_voucher(voucher, admin_api_client, product):
    query = """
    mutation  voucherUpdate(
        $product_id: ID, $id: ID!, $type: VoucherTypeEnum) {
            voucherUpdate(
            id: $id, input: {product: $product_id, type: $type}) {
                errors {
                    field
                    message
                }
                voucher {
                    product {
                        name
                    }
                }
            }
        }
    """

    assert not voucher.product
    variables = json.dumps({
        'type': VoucherTypeEnum.PRODUCT.name,
        'id': graphene.Node.to_global_id('Voucher', voucher.id),
        'product': graphene.Node.to_global_id('Product', product.id)})

    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    data = content['data']['voucherUpdate']['errors'][0]
    assert data['field'] == 'product'
    assert data['message'] == 'This field is required.'
Beispiel #26
0
def test_create_address_mutation(admin_api_client, customer_user):
    query = """
    mutation CreateUserAddress($user: ID!, $city: String!, $country: String!) {
        addressCreate(input: {userId: $user, city: $city, country: $country}) {
         errors {
            field
            message
         }
         address {
            id
            city
            country
         }
        }
    }
    """
    user_id = graphene.Node.to_global_id('User', customer_user.id)
    variables = json.dumps(
        {'user': user_id, 'city': 'Dummy', 'country': 'PL'})
    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert content['data']['addressCreate']['errors'] == []
    address_response = content['data']['addressCreate']['address']
    assert address_response['city'] == 'Dummy'
    assert address_response['country'] == 'PL'
    address_obj = Address.objects.get(city='Dummy')
    assert address_obj.user_addresses.first() == customer_user
Beispiel #27
0
def test_token_create_user_data(
        permission_manage_orders, staff_client, staff_user):
    query = """
    mutation {
        tokenCreate(email: "%(email)s", password: "******") {
            user {
                id
                email
                permissions {
                    code
                    name
                }
            }
        }
    }
    """

    permission = permission_manage_orders
    staff_user.user_permissions.add(permission)
    code = '.'.join([permission.content_type.name, permission.codename])
    name = permission.name
    user_id = graphene.Node.to_global_id('User', staff_user.id)

    query = query % {'email': staff_user.email, 'password': '******'}
    response = staff_client.post(
        reverse('api'), json.dumps({'query': query}),
        content_type='application/json')
    content = get_graphql_content(response)
    assert 'errors' not in content
    token_data = content['data']['tokenCreate']
    assert token_data['user']['id'] == user_id
    assert token_data['user']['email'] == staff_user.email
    assert token_data['user']['permissions'][0]['name'] == name
    assert token_data['user']['permissions'][0]['code'] == code
Beispiel #28
0
def test_staff_update(admin_api_client, staff_user, user_api_client):
    query = """
    mutation UpdateStaff($id: ID!, $permissions: [String]) {
        staffUpdate(id: $id, input: {permissions: $permissions}) {
            errors {
                field
                message
            }
            user {
                permissions {
                    code
                }
            }
        }
    }
    """
    id = graphene.Node.to_global_id('User', staff_user.id)
    variables = json.dumps({'id': id, 'permissions': []})

    # check unauthorized access
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    assert_no_permission(response)

    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['staffUpdate']
    assert data['errors'] == []
    assert data['user']['permissions'] == []
Beispiel #29
0
def test_cancel_fulfillment_restock_items(
        admin_api_client, fulfillment, admin_user):
    query = """
    mutation cancelFulfillment($id: ID!, $restock: Boolean) {
            fulfillmentCancel(id: $id, input: {restock: $restock}) {
                    fulfillment {
                        status
                    }
                }
        }
    """
    fulfillment_id = graphene.Node.to_global_id('Fulfillment', fulfillment.id)
    variables = json.dumps({'id': fulfillment_id, 'restock': 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']['fulfillmentCancel']['fulfillment']
    assert data['status'] == FulfillmentStatus.CANCELED.upper()
    event_restocked_items = fulfillment.order.events.get()
    assert event_restocked_items.type == (
        OrderEvents.FULFILLMENT_RESTOCKED_ITEMS.value)
    assert event_restocked_items.parameters == {
        'quantity': fulfillment.get_total_quantity()}
    assert event_restocked_items.user == admin_user
Beispiel #30
0
def test_customer_update(admin_api_client, customer_user, user_api_client):
    query = """
    mutation UpdateCustomer($id: ID!, $note: String) {
        customerUpdate(id: $id, input: {note: $note}) {
            errors {
                field
                message
            }
            user {
                id
                email
                isStaff
                isActive
                note
            }
        }
    }
    """

    id = graphene.Node.to_global_id('User', customer_user.id)
    note = 'Test update note'
    variables = json.dumps({'id': id, 'note': note})

    # check unauthorized access
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    assert_no_permission(response)

    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['customerUpdate']
    assert data['errors'] == []
    assert data['user']['note'] == note
Beispiel #31
0
def test_customer_create(admin_api_client, user_api_client):
    query = """
    mutation CreateCustomer($email: String, $note: String) {
        customerCreate(input: {email: $email, note: $note}) {
            errors {
                field
                message
            }
            user {
                id
                email
                isStaff
                isActive
                note
            }
        }
    }
    """
    email = '*****@*****.**'
    note = 'Test user'

    variables = json.dumps({'email': email, 'note': note})

    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    assert_no_permission(response)

    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['customerCreate']
    assert data['errors'] == []
    assert data['user']['email'] == email
    assert data['user']['note'] == note
    assert data['user']['isStaff'] == False
    assert data['user']['isActive'] == True
Beispiel #32
0
def test_update_voucher(user_api_client, admin_api_client, voucher):
    query = """
    mutation  voucherUpdate($code: String,
        $discountValueType: DiscountValueTypeEnum, $id: ID!) {
            voucherUpdate(id: $id, input: {
                code: $code, discountValueType: $discountValueType}) {
                errors {
                    field
                    message
                }
                voucher {
                    code
                    discountValueType
                }
            }
        }
    """
    # Set discount value type to 'fixed' and change it in mutation
    voucher.discount_value_type = DiscountValueType.FIXED
    voucher.save()
    assert voucher.code != 'testcode123'
    variables = json.dumps({
        'id': graphene.Node.to_global_id('Voucher', voucher.id),
        'code': 'testcode123',
        'discountValueType': DiscountValueTypeEnum.PERCENTAGE.name})

    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    assert_no_permission(response)

    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['voucherUpdate']['voucher']
    assert data['code'] == 'testcode123'
    assert data['discountValueType'] == DiscountValueType.PERCENTAGE.upper()
Beispiel #33
0
def test_update_sale(user_api_client, admin_api_client, sale):
    query = """
    mutation  saleUpdate($type: DiscountValueTypeEnum, $id: ID!) {
            saleUpdate(id: $id, input: {type: $type}) {
                errors {
                    field
                    message
                }
                sale {
                    type
                }
            }
        }
    """
    # Set discount value type to 'fixed' and change it in mutation
    sale.type = DiscountValueType.FIXED
    sale.save()
    variables = json.dumps({
        'id': graphene.Node.to_global_id('Sale', sale.id),
        'type': DiscountValueTypeEnum.PERCENTAGE.name
    })

    response = user_api_client.post(reverse('api'), {
        'query': query,
        'variables': variables
    })

    assert_no_permission(response)

    response = admin_api_client.post(reverse('api'), {
        'query': query,
        'variables': variables
    })
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['saleUpdate']['sale']
    assert data['type'] == DiscountValueType.PERCENTAGE.upper()
Beispiel #34
0
def test_draft_order_complete(admin_api_client, admin_user, draft_order):
    order = draft_order
    query = """
        mutation draftComplete($id: ID!) {
            draftOrderComplete(id: $id) {
                order {
                    status
                }
            }
        }
        """
    line_1, line_2 = order.lines.order_by('-quantity').all()
    line_1.quantity = 1
    line_1.save(update_fields=['quantity'])
    assert line_1.variant.quantity_available >= line_1.quantity
    assert line_2.variant.quantity_available < line_2.quantity

    order_id = graphene.Node.to_global_id('Order', order.id)
    variables = json.dumps({'id': order_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']['draftOrderComplete']['order']
    order.refresh_from_db()
    assert data['status'] == order.status.upper()
    missing_stock_event, draft_placed_event = OrderEvent.objects.all()

    assert missing_stock_event.user == admin_user
    assert missing_stock_event.type == OrderEvents.OVERSOLD_ITEMS.value
    assert missing_stock_event.parameters == {'oversold_items': [str(line_2)]}

    assert draft_placed_event.user == admin_user
    assert draft_placed_event.type == OrderEvents.PLACED_FROM_DRAFT.value
    assert draft_placed_event.parameters == {}
Beispiel #35
0
def test_create_attribute_choice_value(admin_api_client, color_attribute):
    attribute = color_attribute
    query = """
    mutation createChoice($attribute: ID!, $name: String!, $slug: String!, $value: String!) {
        attributeChoiceValueCreate(
        input: {attribute: $attribute, name: $name, slug: $slug, value: $value}) {
            attributeChoiceValue {
                name
                slug
                type
                value
            }
        }
    }
    """
    attribute_id = graphene.Node.to_global_id('ProductAttribute', attribute.id)
    name = 'test name'
    slug = 'test-slug'
    value = 'test-string'
    variables = json.dumps({
        'name': name,
        'slug': slug,
        'value': value,
        'attribute': attribute_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']['attributeChoiceValueCreate'][
        'attributeChoiceValue']
    assert data['name'] == name
    assert data['slug'] == slug
    assert data['value'] == value
    assert data['type'] == 'STRING'
def test_shipping_zone_query(user_api_client, shipping_zone):
    shipping = shipping_zone
    query = """
    query ShippingQuery($id: ID!) {
        shippingZone(id: $id) {
            name
            shippingMethods {
                price {
                    amount
                }
            }
            priceRange {
                start {
                    amount
                }
                stop {
                    amount
                }
            }
        }
    }
    """
    ID = graphene.Node.to_global_id('ShippingZone', shipping.id)
    variables = json.dumps({'id': ID})
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content

    shipping_data = content['data']['shippingZone']
    assert shipping_data['name'] == shipping.name
    num_of_shipping_methods = shipping_zone.shipping_methods.count()
    assert len(shipping_data['shippingMethods']) == num_of_shipping_methods
    price_range = shipping.price_range
    data_price_range = shipping_data['priceRange']
    assert data_price_range['start']['amount'] == price_range.start.amount
    assert data_price_range['stop']['amount'] == price_range.stop.amount
def test_category_query(user_api_client, product):
    category = Category.objects.first()
    query = '''
    query {
        category(id: "%(category_pk)s") {
            id
            name
            ancestors {
                edges {
                    node {
                        name
                    }
                }
            }
            children {
                edges {
                    node {
                        name
                    }
                }
            }
        }
    }
    ''' % {'category_pk': graphene.Node.to_global_id('Category', category.pk)}
    response = user_api_client.post(reverse('api'), {'query': query})
    content = get_graphql_content(response)
    assert 'errors' not in content
    category_data = content['data']['category']
    assert category_data is not None
    assert category_data['name'] == category.name
    assert (
        len(category_data['ancestors']['edges']) ==
        category.get_ancestors().count())
    assert (
        len(category_data['children']['edges']) ==
        category.get_children().count())
Beispiel #38
0
def test_menu_items_query(user_api_client, menu_item, collection):
    query = """
    query menuitem($id: ID!) {
        menuItem(id: $id) {
            name
            children {
                totalCount
            }
            collection {
                name
            }
            category {
                id
            }
            page {
                id
            }
            url
        }
    }
    """
    menu_item.collection = collection
    menu_item.save()
    variables = json.dumps(
        {'id': graphene.Node.to_global_id('MenuItem', menu_item.pk)})
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['menuItem']
    assert data['name'] == menu_item.name
    assert data['url'] == menu_item.collection.get_absolute_url()
    assert data['children']['totalCount'] == menu_item.children.count()
    assert data['collection']['name'] == collection.name
    assert not data['category']
    assert not data['page']
Beispiel #39
0
def test_staff_update(admin_api_client, staff_user, user_api_client):
    query = """
    mutation UpdateStaff(
            $id: ID!, $permissions: [String], $is_active: Boolean) {
        staffUpdate(
                id: $id,
                input: {permissions: $permissions, isActive: $is_active}) {
            errors {
                field
                message
            }
            user {
                permissions {
                    code
                }
                isActive
            }
        }
    }
    """
    id = graphene.Node.to_global_id('User', staff_user.id)
    variables = json.dumps({'id': id, 'permissions': [], 'is_active': False})

    # check unauthorized access
    response = user_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    assert_no_permission(response)

    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['staffUpdate']
    assert data['errors'] == []
    assert data['user']['permissions'] == []
    assert data['user']['isActive'] == False
Beispiel #40
0
def test_update_menu_item(admin_api_client, menu, menu_item, page):
    query = """
    mutation updateMenuItem($id: ID!, $page: ID) {
        menuItemUpdate(id: $id, input: {page: $page}) {
            menuItem {
                url
            }
        }
    }
    """
    # Menu item before update has url, but no page
    assert menu_item.url
    assert not menu_item.page
    menu_item_id = graphene.Node.to_global_id('MenuItem', menu_item.pk)
    page_id = graphene.Node.to_global_id('Page', page.pk)
    variables = json.dumps({'id': menu_item_id, 'page': page_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']['menuItemUpdate']['menuItem']
    assert data['url'] == page.get_absolute_url()
Beispiel #41
0
def test_collection_image_query(user_api_client, collection):
    image_file, image_name = create_image()
    collection.background_image = image_file
    collection.save()
    collection_id = graphene.Node.to_global_id('Collection', collection.pk)
    query = """
        query fetchCollection($id: ID!){
            collection(id: $id) {
                backgroundImage {
                   url(size: 120)
                }
            }
        }
    """
    variables = json.dumps({'id': collection_id})
    response = user_api_client.post(reverse('api'), {
        'query': query,
        'variables': variables
    })
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['collection']
    thumbnail_url = collection.background_image.thumbnail['120x120'].url
    assert data['backgroundImage']['url'] == thumbnail_url
Beispiel #42
0
def test_product_image_create_mutation(admin_api_client, product):
    query = """
    mutation createProductImage($image: Upload!, $product: ID!) {
        productImageCreate(input: {image: $image, product: $product}) {
            productImage {
                id
                url
                sortOrder
            }
        }
    }
    """
    image_file, image_name = create_image()
    variables = {
        'product': graphene.Node.to_global_id('Product', product.id),
        'image': image_name
    }
    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']['productImageCreate']
    product.refresh_from_db()
    assert product.images.first().image.file
def test_category_delete_mutation(admin_api_client, category):
    query = """
        mutation($id: ID!) {
            categoryDelete(id: $id) {
                category {
                    name
                }
                errors {
                    field
                    message
                }
            }
        }
    """
    variables = json.dumps({
        'id': graphene.Node.to_global_id('Category', category.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']['categoryDelete']
    assert data['category']['name'] == category.name
    with pytest.raises(category._meta.model.DoesNotExist):
        category.refresh_from_db()
def test_create_fulfillment(admin_api_client, order_with_lines):
    order = order_with_lines
    query = """
    mutation fulfillOrder(
        $order: ID, $lines: [FulfillmentLineInput], $tracking: String) {
            fulfillmentCreate(
                input: {lines: $lines, order: $order,
                trackingNumber: $tracking}) {
                    fulfillment {
                        fulfillmentOrder
                        status
                        trackingNumber
                        lines {
                            totalCount
                        }
                    }
                }
        }
    """
    order_id = graphene.Node.to_global_id('Order', order.id)
    order_line = order.lines.first()
    order_line_id = graphene.Node.to_global_id('OrderLine', order_line.id)
    tracking = 'Flames tracking'
    variables = json.dumps(
        {'order': order_id,
         'lines': [{'orderLineId': order_line_id, 'quantity': 1}],
         'tracking': tracking})
    response = admin_api_client.post(
        reverse('api'), {'query': query, 'variables': variables})
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['fulfillmentCreate']['fulfillment']
    assert data['fulfillmentOrder'] == 1
    assert data['status'] == FulfillmentStatus.FULFILLED.upper()
    assert data['trackingNumber'] == tracking
    assert data['lines']['totalCount'] == 1
Beispiel #45
0
def test_update_product_attribute(admin_api_client, color_attribute):
    attribute = color_attribute
    query = """
    mutation updateAttribute($id: ID!, $name: String!, $slug: String!) {
        productAttributeUpdate(id: $id, input: {name: $name, slug: $slug}) {
            productAttribute {
                name
            }
        }
    }
    """
    name = 'Wings name'
    slug = attribute.slug
    id = graphene.Node.to_global_id('ProductAttribute', attribute.id)
    variables = json.dumps({'name': name, 'id': id, 'slug': slug})
    response = admin_api_client.post(reverse('api'), {
        'query': query,
        'variables': variables
    })
    content = get_graphql_content(response)
    attribute.refresh_from_db()
    assert 'errors' not in content
    data = content['data']['productAttributeUpdate']['productAttribute']
    assert data['name'] == name == attribute.name
Beispiel #46
0
def test_delete_attribute_choice_value(admin_api_client, color_attribute,
                                       pink_choice_value):
    value = pink_choice_value
    value = color_attribute.values.get(name='Red')
    query = """
    mutation updateChoice($id: ID!) {
        attributeChoiceValueDelete(id: $id) {
            attributeChoiceValue {
                name
                slug
            }
        }
    }
    """
    id = graphene.Node.to_global_id('ProductAttributeValue', value.id)
    variables = json.dumps({'id': id})
    response = admin_api_client.post(reverse('api'), {
        'query': query,
        'variables': variables
    })
    content = get_graphql_content(response)
    assert 'errors' not in content
    with pytest.raises(value._meta.model.DoesNotExist):
        value.refresh_from_db()
Beispiel #47
0
def test_create_fulfillment_not_sufficient_quantity(admin_api_client,
                                                    order_with_lines,
                                                    admin_user, quantity,
                                                    error_message):
    query = CREATE_FULFILLMENT_QUERY
    order_line = order_with_lines.lines.first()
    order_line_id = graphene.Node.to_global_id('OrderLine', order_line.id)
    variables = json.dumps({
        'order':
        graphene.Node.to_global_id('Order', order_with_lines.id),
        'lines': [{
            'orderLineId': order_line_id,
            'quantity': quantity
        }]
    })
    response = admin_api_client.post(reverse('api'), {
        'query': query,
        'variables': variables
    })
    content = get_graphql_content(response)
    data = content['data']['orderFulfillmentCreate']
    assert 'errors' in data
    assert data['errors'][0]['field'] == str(order_line)
    assert data['errors'][0]['message'] == error_message
Beispiel #48
0
def test_delete_variant(admin_api_client, product):
    query = """
        mutation variantDelete($id: ID!) {
            productVariantDelete(id: $id) {
                productVariant {
                    sku
                    id
                }
              }
            }
    """
    variant = product.variants.first()
    variant_id = graphene.Node.to_global_id('ProductVariant', variant.pk)
    variables = json.dumps({'id': variant_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']['productVariantDelete']
    assert data['productVariant']['sku'] == variant.sku
    with pytest.raises(variant._meta.model.DoesNotExist):
        variant.refresh_from_db()
Beispiel #49
0
def test_draft_order_line_remove(draft_order, permission_manage_orders,
                                 staff_api_client):
    order = draft_order
    line = order.lines.first()
    line_id = graphene.Node.to_global_id('OrderLine', line.id)
    variables = json.dumps({'id': line_id})

    # mutation should fail without proper permissions
    response = staff_api_client.post(reverse('api'), {
        'query': DRAFT_ORDER_LINE_DELETE_MUTATION,
        'variables': variables
    })
    assert_no_permission(response)

    # assign permissions
    staff_api_client.user.user_permissions.add(permission_manage_orders)
    response = staff_api_client.post(reverse('api'), {
        'query': DRAFT_ORDER_LINE_DELETE_MUTATION,
        'variables': variables
    })
    content = get_graphql_content(response)
    data = content['data']['draftOrderLineDelete']
    assert data['orderLine']['id'] == line_id
    assert line not in order.lines.all()
Beispiel #50
0
def test_reorder_images(admin_api_client, product_with_images):
    query = """
    mutation reorderImages($product_id: ID!, $images_ids: [ID]!) {
        productImageReorder(productId: $product_id, imagesIds: $images_ids) {
            product {
                id
            }
        }
    }
    """
    product = product_with_images
    images = product.images.all()
    image_0 = images[0]
    image_1 = images[1]
    image_0_id = graphene.Node.to_global_id('ProductImage', image_0.id)
    image_1_id = graphene.Node.to_global_id('ProductImage', image_1.id)
    product_id = graphene.Node.to_global_id('Product', product.id)

    variables = {
        'product_id': product_id,
        'images_ids': [image_1_id, image_0_id]
    }
    response = admin_api_client.post(reverse('api'), {
        'query': query,
        'variables': variables
    })
    content = get_graphql_content(response)
    assert 'errors' not in content

    # Check if order has been changed
    product.refresh_from_db()
    reordered_images = product.images.all()
    reordered_image_0 = reordered_images[0]
    reordered_image_1 = reordered_images[1]
    assert image_0.id == reordered_image_1.id
    assert image_1.id == reordered_image_0.id
Beispiel #51
0
def test_product_image_delete(admin_api_client, product_with_image):
    product = product_with_image
    query = """
            mutation deleteProductImage($id: ID!) {
                productImageDelete(id: $id) {
                    image {
                        id
                        url
                    }
                }
            }
        """
    image_obj = product.images.first()
    node_id = graphene.Node.to_global_id('ProductImage', image_obj.id)
    variables = {'id': node_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']['productImageDelete']
    assert data['image']['url'] == image_obj.image.url
    with pytest.raises(image_obj._meta.model.DoesNotExist):
        image_obj.refresh_from_db()
    assert node_id == data['image']['id']
Beispiel #52
0
def test_fetch_product_by_id(user_api_client, product):
    query = '''
    query ($productId: ID!) {
        node(id: $productId) {
            ... on Product {
                name
            }
        }
    }
    '''
    response = user_api_client.post(
        reverse('api'), {
            'query':
            query,
            'variables':
            json.dumps({
                'productId':
                graphene.Node.to_global_id('Product', product.id)
            })
        })
    content = get_graphql_content(response)
    assert 'errors' not in content
    product_data = content['data']['node']
    assert product_data['name'] == product.name
Beispiel #53
0
def test_query_product_image_by_id(user_api_client, product_with_image):
    image = product_with_image.images.first()
    query = '''
    query productImageById($imageId: ID!, $productId: ID!) {
        product(id: $productId) {
            imageById(id: $imageId) {
                id
                url
            }
        }
    }
    '''
    variables = json.dumps({
        'productId':
        graphene.Node.to_global_id('Product', product_with_image.pk),
        'imageId':
        graphene.Node.to_global_id('ProductImage', image.pk)
    })
    response = user_api_client.post(reverse('api'), {
        'query': query,
        'variables': variables
    })
    content = get_graphql_content(response)
    assert 'errors' not in content
Beispiel #54
0
def test_product_variants_by_ids(user_api_client, variant):
    query = '''
        query getProduct($ids: [ID!]) {
            productVariants(ids: $ids) {
                edges {
                    node {
                        id
                    }
                }
            }
        }
        '''
    variant_id = graphene.Node.to_global_id('ProductVariant', variant.id)

    variables = json.dumps({'ids': [variant_id]})
    response = user_api_client.post(reverse('api'), {
        'query': query,
        'variables': variables
    })
    content = get_graphql_content(response)
    assert 'errors' not in content
    data = content['data']['productVariants']
    assert data['edges'][0]['node']['id'] == variant_id
    assert len(data['edges']) == 1
Beispiel #55
0
def test_product_type_update_mutation(admin_api_client, product_type):
    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 {
                        totalCount
                    }
                    productAttributes {
                        totalCount
                    }
                }
              }
            }
    """
    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('ProductAttribute', att.id)
        for att in product_attributes
    ]
    variant_attributes = product_type.variant_attributes.all()

    variables = json.dumps({
        'id': product_type_id,
        'name': product_type_name,
        'hasVariants': has_variants,
        'isShippingRequired': require_shipping,
        'productAttributes': product_attributes_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']['productTypeUpdate']
    assert data['productType']['name'] == product_type_name
    assert data['productType']['hasVariants'] == has_variants
    assert data['productType']['isShippingRequired'] == require_shipping
    assert data['productType']['productAttributes']['totalCount'] == 0
    no_va = variant_attributes.count()
    assert data['productType']['variantAttributes']['totalCount'] == no_va
Beispiel #56
0
def test_product_type_create_mutation(admin_api_client, product_type):
    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 {
                edges {
                node {
                    name
                }
                }
            }
            productAttributes {
                edges {
                node {
                    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('ProductAttribute', att.id)
        for att in product_attributes
    ]
    variant_attributes = product_type.variant_attributes.all()
    variant_attributes_ids = [
        graphene.Node.to_global_id('ProductAttribute', att.id)
        for att in variant_attributes
    ]

    variables = json.dumps({
        '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 = admin_api_client.post(reverse('api'), {
        'query': query,
        'variables': variables
    })
    content = get_graphql_content(response)
    assert 'errors' not in content
    assert ProductType.objects.count() == initial_count + 1
    data = content['data']['productTypeCreate']
    assert data['productType']['name'] == product_type_name
    assert data['productType']['hasVariants'] == has_variants
    assert data['productType']['isShippingRequired'] == require_shipping
    no_pa = product_attributes.count()
    assert len(data['productType']['productAttributes']['edges']) == no_pa
    no_va = variant_attributes.count()
    assert len(data['productType']['variantAttributes']['edges']) == no_va
    new_instance = ProductType.objects.latest('pk')
    assert new_instance.tax_rate == 'standard'
Beispiel #57
0
def test_product_query(admin_api_client, product):
    category = Category.objects.first()
    product = category.products.first()
    query = '''
    query {
        category(id: "%(category_id)s") {
            products {
                edges {
                    node {
                        id
                        name
                        url
                        thumbnailUrl
                        images {
                            edges {
                                node {
                                    url
                                }
                            }
                        }
                        variants {
                            edges {
                                node {
                                    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)
    }
    response = admin_api_client.post(reverse('api'), {'query': query})
    content = get_graphql_content(response)
    assert 'errors' not in content
    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']
Beispiel #58
0
def test_update_product(admin_api_client, category, non_default_category,
                        product):
    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 = json.dumps({
        '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 = admin_api_client.post(reverse('api'), {
        'query': query,
        'variables': variables
    })
    content = get_graphql_content(response)
    assert 'errors' not in content
    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
Beispiel #59
0
def test_create_product(admin_api_client, product_type, category,
                        size_attribute):
    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 = json.dumps({
        '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 = admin_api_client.post(reverse('api'), {
        'query': query,
        'variables': variables
    })
    content = get_graphql_content(response)
    assert 'errors' not in content
    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
Beispiel #60
0
def test_create_variant(admin_api_client, product, product_type):
    query = """
        mutation createVariant (
            $productId: ID!,
            $sku: String!,
            $priceOverride: Decimal,
            $costPrice: Decimal,
            $quantity: Int!,
            $attributes: [AttributeValueInput],
            $weight: WeightScalar,
            $trackInventory: Boolean!) {
                productVariantCreate(
                    input: {
                        product: $productId,
                        sku: $sku,
                        priceOverride: $priceOverride,
                        costPrice: $costPrice,
                        quantity: $quantity,
                        attributes: $attributes,
                        trackInventory: $trackInventory,
                        weight: $weight
                    }) {
                    productVariant {
                        name
                        sku
                        attributes {
                            attribute {
                                slug
                            }
                            value {
                                slug
                            }
                        }
                        quantity
                        priceOverride {
                            currency
                            amount
                            localized
                        }
                        costPrice {
                            currency
                            amount
                            localized
                        }
                        weight {
                            value
                            unit
                        }
                    }
                }
            }

    """
    product_id = graphene.Node.to_global_id('Product', product.pk)
    sku = "1"
    price_override = 1.32
    cost_price = 3.22
    quantity = 10
    weight = 10.22
    variant_slug = product_type.variant_attributes.first().slug
    variant_value = 'test-value'

    variables = json.dumps({
        'productId':
        product_id,
        'sku':
        sku,
        'quantity':
        quantity,
        'costPrice':
        cost_price,
        'priceOverride':
        price_override,
        'weight':
        weight,
        'attributes': [{
            'slug': variant_slug,
            'value': variant_value
        }],
        'trackInventory':
        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']['productVariantCreate']['productVariant']
    assert data['name'] == variant_value
    assert data['quantity'] == quantity
    assert data['costPrice']['amount'] == cost_price
    assert data['priceOverride']['amount'] == price_override
    assert data['sku'] == sku
    assert data['attributes'][0]['attribute']['slug'] == variant_slug
    assert data['attributes'][0]['value']['slug'] == variant_value
    assert data['weight']['unit'] == 'kg'
    assert data['weight']['value'] == weight