# This file is part of Tryton.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.

from contextlib import contextmanager
from decimal import Decimal
from unittest.mock import ANY, patch

from trytond.modules.company.tests import (
    CompanyTestMixin, create_company, set_company)
from trytond.modules.web_shop_vue_storefront.exceptions import LoginException
from trytond.pool import Pool
from trytond.protocols.wrappers import exceptions
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
from trytond.transaction import Transaction

CUSTOMER = {
    'email': 'customer@example.com',
    'firstname': 'John',
    'lastname': 'Doe',
    }
ADDRESS = {
    'region': {
        'region': None,
        },
    'country_id': "US",
    'street': [
        "Cliff Street",
        "300"
        ],
    'telephone': '+1 202-555-0148',
    'postcode': '18503',
    'city': "Scranton",
    'firstname': CUSTOMER['firstname'],
    'lastname': CUSTOMER['lastname'],
    }
ADDRESS_COMPANY = ADDRESS.copy()
ADDRESS_COMPANY['company'] = 'Saber'
ADDRESS_COMPANY['vat_id'] = 'BE0500923836'


class WebVueStorefrontTestCase(CompanyTestMixin, ModuleTestCase):
    'Test Web Shop Vue Storefront module'
    module = 'web_shop_vue_storefront'
    extras = [
        'product_attribute',
        'product_image',
        'sale_promotion_coupon',
        'sale_shipment_cost',
        'carrier',
        ]
    maxDiff = None

    @contextmanager
    def create_web_shop(self):
        pool = Pool()
        WebShop = pool.get('web.shop')
        Location = pool.get('stock.location')
        Party = pool.get('party.party')

        company = create_company()
        warehouse, = Location.search([('type', '=', 'warehouse')], limit=1)
        web_shop = WebShop(name="Web Shop")
        web_shop.company = company
        web_shop.currency = company.currency
        web_shop.warehouses = [warehouse]
        web_shop.type = 'vsf'
        web_shop.guest_party = Party(name="Guest")
        web_shop.save()
        with Transaction().set_context(**web_shop.get_context()):
            yield web_shop

    def create_product(self, web_shop, quantity=0, code="CODE"):
        pool = Pool()
        Template = pool.get('product.template')
        Product = pool.get('product.product')
        Category = pool.get('product.category')
        Uom = pool.get('product.uom')
        Location = pool.get('stock.location')
        Move = pool.get('stock.move')

        unit, = Uom.search([('name', '=', "Unit")], limit=1)
        template = Template(name="Product")
        template.type = 'goods'
        template.list_price = Decimal(100)
        template.default_uom = unit
        template.salable = True
        template.sale_uom = unit
        template.products = [Product(suffix_code=code, web_shops=[web_shop])]
        template.account_category = Category(name="Category", accounting=True)
        template.save()
        product, = template.products

        if quantity:
            supplier, = Location.search([('code', '=', 'SUP')])
            storage, = Location.search([('code', '=', 'STO')])
            with set_company(web_shop.company):
                move = Move(product=product)
                move.unit = unit
                move.quantity = quantity
                move.from_location = supplier
                move.to_location = storage
                move.unit_price = Decimal(50)
                move.currency = web_shop.company.currency
                move.save()
                Move.do([move])
        Product.set_vsf_identifier([product])
        return product

    def create_coupon(self, code='CODE'):
        pool = Pool()
        Promotion = pool.get('sale.promotion')
        Coupon = pool.get('sale.promotion.coupon')

        promotion = Promotion(name="10%")
        promotion.formula = '0.9 * unit_price'
        promotion.coupons = coupon, = [Coupon(name="Promo")]
        coupon.numbers = [{'number': code}]
        promotion.save()

    def create_carrier(
            self, name='Carrier', product_name="Delivery",
            price=Decimal('10')):
        pool = Pool()
        Carrier = pool.get('carrier')
        Party = pool.get('party.party')
        Template = pool.get('product.template')
        Product = pool.get('product.product')
        Category = pool.get('product.category')
        Uom = pool.get('product.uom')

        unit, = Uom.search([('name', '=', "Unit")], limit=1)
        template = Template(name=product_name)
        template.type = 'service'
        template.list_price = price
        template.default_uom = template.sale_uom = unit
        template.salable = True
        template.products = [Product()]
        template.account_category = Category(name="Service", accounting=True)
        template.save()

        carrier = Carrier()
        carrier.party = Party(name=name)
        carrier.carrier_product, = template.products
        carrier.save()
        return carrier

    @with_transaction(user=0)
    def test_user_create(self):
        pool = Pool()
        User = pool.get('web.user')
        with self.create_web_shop() as web_shop:
            result = web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "SecretPassword"
                    })
            users = User.search([])

            self.assertEqual(result, {
                    "email": CUSTOMER['email'],
                    "firstname": CUSTOMER['firstname'],
                    "lastname": CUSTOMER['lastname'],
                    "addresses": [],
                    })
            self.assertEqual(len(users), 1)

    @with_transaction(user=0)
    def test_user_login(self):
        with self.create_web_shop() as web_shop:
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "TopSecretPassword",
                    })

            result = web_shop.POST_vsf_user_login({
                    "username": CUSTOMER['email'],
                    "password": "TopSecretPassword",
                    })

            self.assertTrue(result)

    @with_transaction(user=0)
    def test_user_login_wrong_password(self):
        with self.create_web_shop() as web_shop:
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "TopSecretPassword",
                    })

            with self.assertRaises(LoginException):
                web_shop.POST_vsf_user_login({
                        "username": CUSTOMER['email'],
                        "password": "Bad",
                        })

    @with_transaction(user=0)
    def test_user_reset_password(self):
        pool = Pool()
        User = pool.get('web.user')
        with self.create_web_shop() as web_shop:
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "SecretPassword",
                    })

            with patch.object(User, 'reset_password') as reset_password:
                result = web_shop.POST_vsf_user_reset_password({
                        "email": CUSTOMER['email'],
                        })

            self.assertFalse(result)
            reset_password.assert_called_once_with(ANY)

    @with_transaction(user=0)
    def test_user_change_password(self):
        with self.create_web_shop() as web_shop:
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "OldPassword",
                    })
            token = web_shop.POST_vsf_user_login({
                    "username": CUSTOMER['email'],
                    "password": "OldPassword",
                    })

            result = web_shop.POST_vsf_user_change_password({
                    "currentPassword": "OldPassword",
                    "newPassword": "NewPassword",
                    }, token=token)

            self.assertFalse(result)

    @with_transaction(user=0)
    def test_user_change_password_wrong_token(self):
        with self.create_web_shop() as web_shop:
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "OldPassword",
                    })

            with self.assertRaises(exceptions.Unauthorized):
                web_shop.POST_vsf_user_change_password({
                        "currentPassword": "BadPassword",
                        "newPassword": "NewPassword",
                        }, 'wrong token')

    @with_transaction(user=0)
    def test_user_change_password_wrong_password(self):
        with self.create_web_shop() as web_shop:
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "OldPassword",
                    })
            token = web_shop.POST_vsf_user_login({
                    "username": CUSTOMER['email'],
                    "password": "OldPassword",
                    })

            with self.assertRaises(LoginException):
                web_shop.POST_vsf_user_change_password({
                        "currentPassword": "BadPassword",
                        "newPassword": "NewPassword",
                        }, token=token)

    @with_transaction(user=0)
    def test_user_order_history(self):
        pool = Pool()
        Country = pool.get('country.country')
        Country(name="US", code="US").save()
        with self.create_web_shop() as web_shop:
            self.create_product(web_shop)
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "TopSecretPassword",
                    })
            token = web_shop.POST_vsf_user_login({
                    "username": CUSTOMER['email'],
                    "password": "TopSecretPassword",
                    })
            cart = web_shop.POST_vsf_cart_create(None, token=token)
            web_shop.POST_vsf_order_create({
                    'products': [{
                            'sku': 'CODE',
                            'qty': 2,
                            }],
                    'addressInformation': {
                        'shippingAddress': ADDRESS,
                        'billingAddress': ADDRESS_COMPANY,
                        'shipping_method_code': None,
                        'shipping_carrier_code': None,
                        'payment_method_code': 'cashondelivery',
                        'payment_method_additional': {},
                        },
                    }, cart, token=token)

            items = web_shop.GET_vsf_user_order_history(None, token=token)

            self.assertEqual(items, {
                    'items': [{
                            'entity_id': ANY,
                            'increment_id': ANY,
                            'created_at': ANY,
                            'customer_firstname': CUSTOMER['firstname'],
                            'customer_lastname': CUSTOMER['lastname'],
                            'grand_total': 200,
                            'status': "Confirmed",
                            'items': [{
                                    'name': "Product",
                                    'sku': 'CODE',
                                    'price_incl_tax': 100,
                                    'qty_ordered': 2,
                                    'row_total_incl_tax': 200,
                                    }],
                            }],
                    })

    @with_transaction(user=0)
    def test_user_order_history_wrong_token(self):
        with self.create_web_shop() as web_shop:
            with self.assertRaises(exceptions.Unauthorized):
                web_shop.GET_vsf_user_order_history(None, 'wrong token')

    @with_transaction(user=0)
    def test_user_me(self):
        pool = Pool()
        Country = pool.get('country.country')
        Country(name="US", code="US").save()
        with self.create_web_shop() as web_shop:
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "TopSecretPassword",
                    })
            token = web_shop.POST_vsf_user_login({
                    "username": CUSTOMER['email'],
                    "password": "TopSecretPassword",
                    })

            result = web_shop.GET_vsf_user_me(None, token=token)

            data = {'customer': CUSTOMER.copy()}
            data['customer']['addresses'] = []
            self.assertEqual(result, data['customer'])

            data = {'customer': CUSTOMER.copy()}
            data['customer']['addresses'] = [ADDRESS_COMPANY.copy()]
            result = web_shop.POST_vsf_user_me(data, token=token)

            data['customer']['addresses'][0]['id'] = ANY
            data['customer']['addresses'][0].pop('region')
            self.assertEqual(result, data['customer'])

    @with_transaction(user=0)
    def test_user_me_wrong_token(self):
        with self.create_web_shop() as web_shop:

            with self.assertRaises(exceptions.Unauthorized):
                web_shop.GET_vsf_user_me(None, 'wrong token')

            with self.assertRaises(exceptions.Unauthorized):
                web_shop.POST_vsf_user_me({}, 'wrong token')

    @with_transaction(user=0)
    def test_user_me_change_address(self):
        pool = Pool()
        Address = pool.get('party.address')
        Country = pool.get('country.country')
        Country(name="US", code="US").save()
        with self.create_web_shop() as web_shop:
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "TopSecretPassword",
                    })
            token = web_shop.POST_vsf_user_login({
                    "username": CUSTOMER['email'],
                    "password": "TopSecretPassword",
                    })
            data = {'customer': CUSTOMER.copy()}
            data['customer']['addresses'] = [ADDRESS_COMPANY]
            result = web_shop.POST_vsf_user_me(data, token=token)

            data = {'customer': CUSTOMER.copy()}
            address = ADDRESS.copy()
            address['lastname'] = "Scott"
            data['customer']['addresses'] = [address]
            result = web_shop.POST_vsf_user_me(
                {"customer": result}, token=token)

            inactive_addresses = Address.search([('active', '=', False)])
            self.assertEqual(len(inactive_addresses), 1)

    @with_transaction(user=0)
    def test_stock_check(self):
        with self.create_web_shop() as web_shop:
            product = self.create_product(web_shop, quantity=10)

            result = web_shop.GET_vsf_stock_check(None, product.vsf_sku)

            self.assertEqual(result, {
                    'product_id': product.vsf_identifier.id,
                    'qty': 10,
                    'is_in_stock': True,
                    })

    @with_transaction(user=0)
    def test_stock_list(self):
        with self.create_web_shop() as web_shop:
            product1 = self.create_product(web_shop, quantity=10)
            product2 = self.create_product(web_shop, quantity=0, code="CODE2")

            result = web_shop.GET_vsf_stock_list(
                None, ','.join([p.vsf_sku for p in [product1, product2]]))

            self.assertEqual(result, [{
                        'product_id': product1.vsf_identifier.id,
                        'qty': 10,
                        'is_in_stock': True,
                        }, {
                        'product_id': product2.vsf_identifier.id,
                        'qty': 0,
                        'is_in_stock': False,
                        }])

    @with_transaction(user=0)
    def test_cart_create_without_token(self):
        with self.create_web_shop() as web_shop:
            cart = web_shop.POST_vsf_cart_create(None)

            self.assertIsInstance(cart, str)

    @with_transaction(user=0)
    def test_cart_create_with_token(self):
        with self.create_web_shop() as web_shop:
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "TopSecretPassword",
                    })
            token = web_shop.POST_vsf_user_login({
                    "username": CUSTOMER['email'],
                    "password": "TopSecretPassword",
                    })

            cart = web_shop.POST_vsf_cart_create(None, token=token)

            self.assertIsInstance(cart, int)

    @with_transaction(user=0)
    def test_cart_pull_without_token(self):
        with self.create_web_shop() as web_shop:
            self.create_product(web_shop)
            cart = web_shop.POST_vsf_cart_create(None)
            web_shop.POST_vsf_cart_update({
                    'cartItem': {
                        'sku': 'CODE',
                        'qty': 1,
                        },
                    }, cart)

            items = web_shop.GET_vsf_cart_pull(None, cart)

            self.assertEqual(items, [{
                        'item_id': ANY,
                        'sku': 'CODE',
                        'qty': 1,
                        'name': 'Product',
                        'price': 100,
                        'product_type': 'simple',
                        'quote_id': ANY,
                        'product_option': {
                            'extension_attributes': {},
                            },
                        }])

    @with_transaction(user=0)
    def test_cart_pull_with_token(self):
        with self.create_web_shop() as web_shop:
            self.create_product(web_shop)
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "TopSecretPassword",
                    })
            token = web_shop.POST_vsf_user_login({
                    "username": CUSTOMER['email'],
                    "password": "TopSecretPassword",
                    })
            cart = web_shop.POST_vsf_cart_create(None, token=token)
            web_shop.POST_vsf_cart_update({
                    'cartItem': {
                        'sku': 'CODE',
                        'qty': 1,
                        },
                    }, cart, token=token)

            items = web_shop.GET_vsf_cart_pull(None, cart, token=token)

            self.assertEqual(items, [{
                        'item_id': ANY,
                        'sku': 'CODE',
                        'qty': 1,
                        'name': 'Product',
                        'price': 100,
                        'product_type': 'simple',
                        'quote_id': ANY,
                        'product_option': {
                            'extension_attributes': {},
                            },
                        }])

    @with_transaction(user=0)
    def test_cart_update_without_token(self):
        pool = Pool()
        SaleLine = pool.get('sale.line')
        with self.create_web_shop() as web_shop:
            self.create_product(web_shop)
            cart = web_shop.POST_vsf_cart_create(None)

            item = web_shop.POST_vsf_cart_update({
                    'cartItem': {
                        'sku': 'CODE',
                        'qty': 1,
                        },
                    }, cart)

            self.assertEqual(item, {
                    'item_id': ANY,
                    'sku': 'CODE',
                    'qty': 1,
                    'name': 'Product',
                    'price': 100,
                    'product_type': 'simple',
                    'quote_id': ANY,
                    'product_option': {
                        'extension_attributes': {},
                        },
                    })
            sale_lines = SaleLine.search([])
            self.assertEqual(len(sale_lines), 1)

    @with_transaction(user=0)
    def test_cart_update_with_token(self):
        pool = Pool()
        SaleLine = pool.get('sale.line')
        with self.create_web_shop() as web_shop:
            self.create_product(web_shop)
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "TopSecretPassword",
                    })
            token = web_shop.POST_vsf_user_login({
                    "username": CUSTOMER['email'],
                    "password": "TopSecretPassword",
                    })
            cart = web_shop.POST_vsf_cart_create(None, token=token)

            item = web_shop.POST_vsf_cart_update({
                    'cartItem': {
                        'sku': 'CODE',
                        'qty': 1,
                        },
                    }, cart, token=token)

            self.assertEqual(item, {
                    'item_id': ANY,
                    'sku': 'CODE',
                    'qty': 1,
                    'name': 'Product',
                    'price': 100,
                    'product_type': 'simple',
                    'quote_id': ANY,
                    'product_option': {
                        'extension_attributes': {},
                        },
                    })
            sale_lines = SaleLine.search([])
            self.assertEqual(len(sale_lines), 1)

    @with_transaction(user=0)
    def test_cart_update2(self):
        pool = Pool()
        SaleLine = pool.get('sale.line')
        with self.create_web_shop() as web_shop:
            self.create_product(web_shop)
            cart = web_shop.POST_vsf_cart_create(None)
            item = web_shop.POST_vsf_cart_update({
                    'cartItem': {
                        'sku': 'CODE',
                        'qty': 1,
                        },
                    }, cart)

            item = web_shop.POST_vsf_cart_update({
                    'cartItem': {
                        'sku': 'CODE',
                        'qty': 2,
                        'item_id': item['item_id'],
                        },
                    }, cart)

            self.assertEqual(item, {
                    'item_id': ANY,
                    'sku': 'CODE',
                    'qty': 2,
                    'name': 'Product',
                    'price': 100,
                    'product_type': 'simple',
                    'quote_id': ANY,
                    'product_option': {
                        'extension_attributes': {},
                        },
                    })
            sale_lines = SaleLine.search([])
            self.assertEqual(len(sale_lines), 1)

    @with_transaction(user=0)
    def test_cart_delete(self):
        pool = Pool()
        SaleLine = pool.get('sale.line')
        with self.create_web_shop() as web_shop:
            self.create_product(web_shop)
            cart = web_shop.POST_vsf_cart_create(None)
            item = web_shop.POST_vsf_cart_update({
                    'cartItem': {
                        'sku': 'CODE',
                        'qty': 1,
                        },
                    }, cart)

            result = web_shop.POST_vsf_cart_delete({
                    'cartItem': {
                        'sku': 'CODE',
                        'qty': 1,
                        'item_id': item['item_id'],
                        },
                    }, cart)

            self.assertTrue(result)
            sale_lines = SaleLine.search([])
            self.assertEqual(len(sale_lines), 0)

    @with_transaction(user=0)
    def test_cart_apply_coupon(self):
        with self.create_web_shop() as web_shop:
            self.create_coupon()
            cart = web_shop.POST_vsf_cart_create(None)

            result = web_shop.POST_vsf_cart_apply_coupon(None, cart, 'CODE')

            self.assertTrue(result)

    @with_transaction(user=0)
    def test_cart_delete_coupon(self):
        with self.create_web_shop() as web_shop:
            self.create_coupon()
            cart = web_shop.POST_vsf_cart_create(None)
            web_shop.POST_vsf_cart_apply_coupon(None, cart, 'CODE')

            result = web_shop.POST_vsf_cart_delete_coupon(None, cart)

            self.assertTrue(result)

    @with_transaction(user=0)
    def test_cart_coupon(self):
        with self.create_web_shop() as web_shop:
            self.create_coupon()
            cart = web_shop.POST_vsf_cart_create(None)
            web_shop.POST_vsf_cart_apply_coupon(None, cart, 'CODE')

            result = web_shop.POST_vsf_cart_coupon(None, cart)

            self.assertEqual(result, 'CODE')

    @with_transaction(user=0)
    def test_cart_coupon_empty(self):
        with self.create_web_shop() as web_shop:
            cart = web_shop.POST_vsf_cart_create(None)

            result = web_shop.POST_vsf_cart_coupon(None, cart)

            self.assertEqual(result, '')

    @with_transaction(user=0)
    def test_cart_totals(self):
        with self.create_web_shop() as web_shop:
            self.create_product(web_shop)
            cart = web_shop.POST_vsf_cart_create(None)
            web_shop.POST_vsf_cart_update({
                    'cartItem': {
                        'sku': 'CODE',
                        'qty': 1,
                        },
                    }, cart)

            totals = web_shop.GET_vsf_cart_totals(None, cart)

            self.assertEqual(totals, {
                    'grand_total': 100,
                    'items': [{
                            'item_id': ANY,
                            'sku': 'CODE',
                            'qty': 1,
                            'name': 'Product',
                            'price': 100,
                            'product_type': 'simple',
                            'quote_id': ANY,
                            'product_option': {
                                'extension_attributes': {
                                    },
                                },
                            }],
                    'total_segments': [{
                            'code': 'subtotal',
                            'title': ANY,
                            'value': 100,
                            }, {
                            'code': 'tax',
                            'title': ANY,
                            'value': 0,
                            }, {
                            'code': 'grand_total',
                            'title': ANY,
                            'value': 100,
                            }],
                    })

    @with_transaction(user=0)
    def test_cart_payment_methods(self):
        with self.create_web_shop() as web_shop:
            cart = web_shop.POST_vsf_cart_create(None)

            result = web_shop.GET_vsf_cart_payment_methods(None, cart)

            self.assertEqual(result, [])

    @with_transaction(user=0)
    def test_cart_shipping_methods(self):
        pool = Pool()
        Country = pool.get('country.country')
        Country(name="US", code="US").save()
        with self.create_web_shop() as web_shop:
            carrier = self.create_carrier()
            self.create_product(web_shop)
            cart = web_shop.POST_vsf_cart_create(None)
            web_shop.POST_vsf_cart_update({
                    'cartItem': {
                        'sku': 'CODE',
                        'qty': 1,
                        },
                    }, cart)

            methods = web_shop.POST_vsf_cart_shipping_methods(
                {'address': {'country_id': 'US'}}, cart)

            self.assertEqual(methods, [{
                        'carrier_code': str(carrier.id),
                        'method_code': str(carrier.id),
                        'carrier_title': "Carrier",
                        'method_title': "Delivery",
                        'price_incl_tax': Decimal(10),
                        }])

    @with_transaction(user=0)
    def test_cart_shipping_information(self):
        pool = Pool()
        Country = pool.get('country.country')
        Country(name="US", code="US").save()
        with self.create_web_shop() as web_shop:
            carrier = self.create_carrier()
            self.create_product(web_shop)
            cart = web_shop.POST_vsf_cart_create(None)
            web_shop.POST_vsf_cart_update({
                    'cartItem': {
                        'sku': 'CODE',
                        'qty': 1,
                        },
                    }, cart)

            information = web_shop.POST_vsf_cart_shipping_information({
                    'addressInformation': {
                        'shipping_address': {
                            'country_id': 'US',
                            },
                        'shipping_method_code': str(carrier.id),
                        'shipping_carrier_code': str(carrier.id),
                        },
                    }, cart)

            self.assertEqual(information, {
                    'grand_total': 110,
                    'items': ANY,
                    'total_segments': [{
                            'code': 'subtotal',
                            'title': ANY,
                            'value': 100,
                            }, {
                            'code': 'shipping',
                            'title': ANY,
                            'value': 10,
                            }, {
                            'code': 'tax',
                            'title': ANY,
                            'value': 0,
                            }, {
                            'code': 'grand_total',
                            'title': ANY,
                            'value': 110,
                            }],
                    })

    @with_transaction(user=0)
    def test_order_create(self):
        pool = Pool()
        Sale = pool.get('sale.sale')
        Country = pool.get('country.country')
        Country(name="US", code="US").save()
        with self.create_web_shop() as web_shop:
            carrier = self.create_carrier()
            self.create_product(web_shop)
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "TopSecretPassword",
                    })
            token = web_shop.POST_vsf_user_login({
                    "username": CUSTOMER['email'],
                    "password": "TopSecretPassword",
                    })
            cart = web_shop.POST_vsf_cart_create(None, token=token)
            web_shop.POST_vsf_cart_update({
                    'cartItem': {
                        'sku': 'CODE',
                        'qty': 1,
                        },
                    }, cart, token=token)

            result = web_shop.POST_vsf_order_create({
                    'products': [{
                            'sku': 'CODE',
                            'qty': 1,
                            }],
                    'addressInformation': {
                        'shippingAddress': ADDRESS,
                        'billingAddress': ADDRESS_COMPANY,
                        'shipping_method_code': str(carrier.id),
                        'shipping_carrier_code': str(carrier.id),
                        'payment_method_code': 'cashondelivery',
                        'payment_method_additional': {},
                        },
                    }, cart, token=token)

            self.assertEqual(result, 'OK')

            sale, = Sale.search([])
            self.assertEqual(sale.state, 'confirmed')
            self.assertEqual(len(sale.lines), 2)
            self.assertEqual(sale.total_amount, Decimal(110))

    @with_transaction(user=0)
    def test_order_create_from_guest(self):
        pool = Pool()
        Sale = pool.get('sale.sale')
        Country = pool.get('country.country')
        Country(name="US", code="US").save()
        with self.create_web_shop() as web_shop:
            carrier = self.create_carrier()
            self.create_product(web_shop)
            cart = web_shop.POST_vsf_cart_create(None)
            web_shop.POST_vsf_cart_update({
                    'cartItem': {
                        'sku': 'CODE',
                        'qty': 1,
                        },
                    }, cart)
            web_shop.POST_vsf_user_create({
                    "customer": CUSTOMER,
                    "password": "TopSecretPassword",
                    })
            token = web_shop.POST_vsf_user_login({
                    "username": CUSTOMER['email'],
                    "password": "TopSecretPassword",
                    })
            result = web_shop.POST_vsf_order_create({
                    'products': [{
                            'sku': 'CODE',
                            'qty': 1,
                            }],
                    'addressInformation': {
                        'shippingAddress': ADDRESS,
                        'billingAddress': ADDRESS_COMPANY,
                        'shipping_method_code': str(carrier.id),
                        'shipping_carrier_code': str(carrier.id),
                        'payment_method_code': 'cashondelivery',
                        'payment_method_additional': {},
                        },
                    }, cart, token=token)

            self.assertEqual(result, 'OK')

            sale, = Sale.search([])
            self.assertNotEqual(sale.party, web_shop.guest_party)
            self.assertEqual(sale.state, 'confirmed')
            self.assertEqual(len(sale.lines), 2)
            self.assertEqual(sale.total_amount, Decimal(110))


del ModuleTestCase
