feat: add basic "create order" feature, docs, tests
just the package API docs so far, narrative will come later
This commit is contained in:
parent
89265f0240
commit
ef07d30a85
86 changed files with 7749 additions and 35 deletions
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
0
tests/batch/__init__.py
Normal file
0
tests/batch/__init__.py
Normal file
539
tests/batch/test_neworder.py
Normal file
539
tests/batch/test_neworder.py
Normal file
|
@ -0,0 +1,539 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
import decimal
|
||||
|
||||
from wuttjamaican.testing import DataTestCase
|
||||
|
||||
from sideshow.batch import neworder as mod
|
||||
|
||||
|
||||
class TestNewOrderBatchHandler(DataTestCase):
|
||||
|
||||
def make_config(self, **kwargs):
|
||||
config = super().make_config(**kwargs)
|
||||
config.setdefault('wutta.model_spec', 'sideshow.db.model')
|
||||
config.setdefault('wutta.enum_spec', 'sideshow.enum')
|
||||
return config
|
||||
|
||||
def make_handler(self):
|
||||
return mod.NewOrderBatchHandler(self.config)
|
||||
|
||||
def test_set_pending_customer(self):
|
||||
model = self.app.model
|
||||
handler = self.make_handler()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
|
||||
batch = handler.make_batch(self.session, created_by=user, customer_id=42)
|
||||
self.assertEqual(batch.customer_id, 42)
|
||||
self.assertIsNone(batch.pending_customer)
|
||||
self.assertIsNone(batch.customer_name)
|
||||
self.assertIsNone(batch.phone_number)
|
||||
self.assertIsNone(batch.email_address)
|
||||
|
||||
# auto full_name
|
||||
handler.set_pending_customer(batch, {
|
||||
'first_name': "Fred",
|
||||
'last_name': "Flintstone",
|
||||
'phone_number': '555-1234',
|
||||
'email_address': 'fred@mailinator.com',
|
||||
})
|
||||
self.assertIsNone(batch.customer_id)
|
||||
self.assertIsInstance(batch.pending_customer, model.PendingCustomer)
|
||||
customer = batch.pending_customer
|
||||
self.assertEqual(customer.full_name, "Fred Flintstone")
|
||||
self.assertEqual(customer.first_name, "Fred")
|
||||
self.assertEqual(customer.last_name, "Flintstone")
|
||||
self.assertEqual(customer.phone_number, '555-1234')
|
||||
self.assertEqual(customer.email_address, 'fred@mailinator.com')
|
||||
self.assertEqual(batch.customer_name, "Fred Flintstone")
|
||||
self.assertEqual(batch.phone_number, '555-1234')
|
||||
self.assertEqual(batch.email_address, 'fred@mailinator.com')
|
||||
|
||||
# explicit full_name
|
||||
batch = handler.make_batch(self.session, created_by=user, customer_id=42)
|
||||
handler.set_pending_customer(batch, {
|
||||
'full_name': "Freddy Flintstone",
|
||||
'first_name': "Fred",
|
||||
'last_name': "Flintstone",
|
||||
'phone_number': '555-1234',
|
||||
'email_address': 'fred@mailinator.com',
|
||||
})
|
||||
self.assertIsNone(batch.customer_id)
|
||||
self.assertIsInstance(batch.pending_customer, model.PendingCustomer)
|
||||
customer = batch.pending_customer
|
||||
self.assertEqual(customer.full_name, "Freddy Flintstone")
|
||||
self.assertEqual(customer.first_name, "Fred")
|
||||
self.assertEqual(customer.last_name, "Flintstone")
|
||||
self.assertEqual(customer.phone_number, '555-1234')
|
||||
self.assertEqual(customer.email_address, 'fred@mailinator.com')
|
||||
self.assertEqual(batch.customer_name, "Freddy Flintstone")
|
||||
self.assertEqual(batch.phone_number, '555-1234')
|
||||
self.assertEqual(batch.email_address, 'fred@mailinator.com')
|
||||
|
||||
def test_add_pending_product(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = self.make_handler()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
|
||||
batch = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch)
|
||||
self.assertEqual(len(batch.rows), 0)
|
||||
|
||||
kw = dict(
|
||||
scancode='07430500132',
|
||||
brand_name='Bragg',
|
||||
description='Vinegar',
|
||||
size='32oz',
|
||||
case_size=12,
|
||||
unit_cost=decimal.Decimal('3.99'),
|
||||
unit_price_reg=decimal.Decimal('5.99'),
|
||||
created_by=user,
|
||||
)
|
||||
row = handler.add_pending_product(batch, kw, 1, enum.ORDER_UOM_UNIT)
|
||||
self.assertEqual(len(batch.rows), 1)
|
||||
self.assertIs(batch.rows[0], row)
|
||||
|
||||
self.assertEqual(row.product_scancode, '07430500132')
|
||||
self.assertEqual(row.product_brand, 'Bragg')
|
||||
self.assertEqual(row.product_description, 'Vinegar')
|
||||
self.assertEqual(row.product_size, '32oz')
|
||||
self.assertEqual(row.case_size, 12)
|
||||
self.assertEqual(row.unit_cost, decimal.Decimal('3.99'))
|
||||
self.assertEqual(row.unit_price_reg, decimal.Decimal('5.99'))
|
||||
self.assertEqual(row.unit_price_quoted, decimal.Decimal('5.99'))
|
||||
self.assertEqual(row.case_price_quoted, decimal.Decimal('71.88'))
|
||||
|
||||
product = row.pending_product
|
||||
self.assertIsInstance(product, model.PendingProduct)
|
||||
self.assertEqual(product.scancode, '07430500132')
|
||||
self.assertEqual(product.brand_name, 'Bragg')
|
||||
self.assertEqual(product.description, 'Vinegar')
|
||||
self.assertEqual(product.size, '32oz')
|
||||
self.assertEqual(product.case_size, 12)
|
||||
self.assertEqual(product.unit_cost, decimal.Decimal('3.99'))
|
||||
self.assertEqual(product.unit_price_reg, decimal.Decimal('5.99'))
|
||||
self.assertIs(product.created_by, user)
|
||||
|
||||
def test_set_pending_product(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = self.make_handler()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
|
||||
batch = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch)
|
||||
self.assertEqual(len(batch.rows), 0)
|
||||
|
||||
# start with mock product_id
|
||||
row = handler.make_row(product_id=42, order_qty=1, order_uom=enum.ORDER_UOM_UNIT)
|
||||
handler.add_row(batch, row)
|
||||
self.session.flush()
|
||||
self.assertEqual(row.product_id, 42)
|
||||
self.assertIsNone(row.pending_product)
|
||||
self.assertIsNone(row.product_scancode)
|
||||
self.assertIsNone(row.product_brand)
|
||||
self.assertIsNone(row.product_description)
|
||||
self.assertIsNone(row.product_size)
|
||||
self.assertIsNone(row.case_size)
|
||||
self.assertIsNone(row.unit_cost)
|
||||
self.assertIsNone(row.unit_price_reg)
|
||||
self.assertIsNone(row.unit_price_quoted)
|
||||
|
||||
# set pending, which clears product_id
|
||||
handler.set_pending_product(row, dict(
|
||||
scancode='07430500132',
|
||||
brand_name='Bragg',
|
||||
description='Vinegar',
|
||||
size='32oz',
|
||||
case_size=12,
|
||||
unit_cost=decimal.Decimal('3.99'),
|
||||
unit_price_reg=decimal.Decimal('5.99'),
|
||||
created_by=user,
|
||||
))
|
||||
self.session.flush()
|
||||
self.assertIsNone(row.product_id)
|
||||
self.assertIsInstance(row.pending_product, model.PendingProduct)
|
||||
self.assertEqual(row.product_scancode, '07430500132')
|
||||
self.assertEqual(row.product_brand, 'Bragg')
|
||||
self.assertEqual(row.product_description, 'Vinegar')
|
||||
self.assertEqual(row.product_size, '32oz')
|
||||
self.assertEqual(row.case_size, 12)
|
||||
self.assertEqual(row.unit_cost, decimal.Decimal('3.99'))
|
||||
self.assertEqual(row.unit_price_reg, decimal.Decimal('5.99'))
|
||||
self.assertEqual(row.unit_price_quoted, decimal.Decimal('5.99'))
|
||||
self.assertEqual(row.case_price_quoted, decimal.Decimal('71.88'))
|
||||
product = row.pending_product
|
||||
self.assertIsInstance(product, model.PendingProduct)
|
||||
self.assertEqual(product.scancode, '07430500132')
|
||||
self.assertEqual(product.brand_name, 'Bragg')
|
||||
self.assertEqual(product.description, 'Vinegar')
|
||||
self.assertEqual(product.size, '32oz')
|
||||
self.assertEqual(product.case_size, 12)
|
||||
self.assertEqual(product.unit_cost, decimal.Decimal('3.99'))
|
||||
self.assertEqual(product.unit_price_reg, decimal.Decimal('5.99'))
|
||||
self.assertIs(product.created_by, user)
|
||||
|
||||
# set again to update pending
|
||||
handler.set_pending_product(row, dict(
|
||||
scancode='07430500116',
|
||||
size='16oz',
|
||||
unit_cost=decimal.Decimal('2.19'),
|
||||
unit_price_reg=decimal.Decimal('3.59'),
|
||||
))
|
||||
self.session.flush()
|
||||
self.assertIsNone(row.product_id)
|
||||
self.assertIsInstance(row.pending_product, model.PendingProduct)
|
||||
self.assertEqual(row.product_scancode, '07430500116')
|
||||
self.assertEqual(row.product_brand, 'Bragg')
|
||||
self.assertEqual(row.product_description, 'Vinegar')
|
||||
self.assertEqual(row.product_size, '16oz')
|
||||
self.assertEqual(row.case_size, 12)
|
||||
self.assertEqual(row.unit_cost, decimal.Decimal('2.19'))
|
||||
self.assertEqual(row.unit_price_reg, decimal.Decimal('3.59'))
|
||||
self.assertEqual(row.unit_price_quoted, decimal.Decimal('3.59'))
|
||||
self.assertEqual(row.case_price_quoted, decimal.Decimal('43.08'))
|
||||
product = row.pending_product
|
||||
self.assertIsInstance(product, model.PendingProduct)
|
||||
self.assertEqual(product.scancode, '07430500116')
|
||||
self.assertEqual(product.brand_name, 'Bragg')
|
||||
self.assertEqual(product.description, 'Vinegar')
|
||||
self.assertEqual(product.size, '16oz')
|
||||
self.assertEqual(product.case_size, 12)
|
||||
self.assertEqual(product.unit_cost, decimal.Decimal('2.19'))
|
||||
self.assertEqual(product.unit_price_reg, decimal.Decimal('3.59'))
|
||||
self.assertIs(product.created_by, user)
|
||||
|
||||
def test_refresh_row(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = self.make_handler()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
|
||||
batch = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch)
|
||||
self.assertEqual(len(batch.rows), 0)
|
||||
|
||||
# missing product
|
||||
row = handler.make_row(order_qty=1, order_uom=enum.ORDER_UOM_UNIT)
|
||||
self.assertIsNone(row.status_code)
|
||||
handler.add_row(batch, row)
|
||||
self.assertEqual(row.status_code, row.STATUS_MISSING_PRODUCT)
|
||||
|
||||
# missing order_qty
|
||||
row = handler.make_row(product_id=42, order_uom=enum.ORDER_UOM_UNIT)
|
||||
self.assertIsNone(row.status_code)
|
||||
handler.add_row(batch, row)
|
||||
self.assertEqual(row.status_code, row.STATUS_MISSING_ORDER_QTY)
|
||||
|
||||
# refreshed from pending product (null price)
|
||||
product = model.PendingProduct(scancode='07430500132',
|
||||
brand_name='Bragg',
|
||||
description='Vinegar',
|
||||
size='32oz',
|
||||
created_by=user,
|
||||
status=enum.PendingProductStatus.PENDING)
|
||||
row = handler.make_row(pending_product=product, order_qty=1, order_uom=enum.ORDER_UOM_UNIT)
|
||||
self.assertIsNone(row.status_code)
|
||||
handler.add_row(batch, row)
|
||||
self.assertEqual(row.status_code, row.STATUS_OK)
|
||||
self.assertIsNone(row.product_id)
|
||||
self.assertIs(row.pending_product, product)
|
||||
self.assertEqual(row.product_scancode, '07430500132')
|
||||
self.assertEqual(row.product_brand, 'Bragg')
|
||||
self.assertEqual(row.product_description, 'Vinegar')
|
||||
self.assertEqual(row.product_size, '32oz')
|
||||
self.assertIsNone(row.case_size)
|
||||
self.assertIsNone(row.unit_cost)
|
||||
self.assertIsNone(row.unit_price_reg)
|
||||
self.assertIsNone(row.unit_price_quoted)
|
||||
self.assertIsNone(row.case_price_quoted)
|
||||
self.assertIsNone(row.total_price)
|
||||
|
||||
# refreshed from pending product (zero price)
|
||||
product = model.PendingProduct(scancode='07430500132',
|
||||
brand_name='Bragg',
|
||||
description='Vinegar',
|
||||
size='32oz',
|
||||
unit_price_reg=0,
|
||||
created_by=user,
|
||||
status=enum.PendingProductStatus.PENDING)
|
||||
row = handler.make_row(pending_product=product, order_qty=1, order_uom=enum.ORDER_UOM_UNIT)
|
||||
self.assertIsNone(row.status_code)
|
||||
handler.add_row(batch, row)
|
||||
self.assertEqual(row.status_code, row.STATUS_OK)
|
||||
self.assertIsNone(row.product_id)
|
||||
self.assertIs(row.pending_product, product)
|
||||
self.assertEqual(row.product_scancode, '07430500132')
|
||||
self.assertEqual(row.product_brand, 'Bragg')
|
||||
self.assertEqual(row.product_description, 'Vinegar')
|
||||
self.assertEqual(row.product_size, '32oz')
|
||||
self.assertIsNone(row.case_size)
|
||||
self.assertIsNone(row.unit_cost)
|
||||
self.assertEqual(row.unit_price_reg, 0)
|
||||
self.assertEqual(row.unit_price_quoted, 0)
|
||||
self.assertIsNone(row.case_price_quoted)
|
||||
self.assertEqual(row.total_price, 0)
|
||||
|
||||
# refreshed from pending product (normal, case)
|
||||
product = model.PendingProduct(scancode='07430500132',
|
||||
brand_name='Bragg',
|
||||
description='Vinegar',
|
||||
size='32oz',
|
||||
case_size=12,
|
||||
unit_cost=decimal.Decimal('3.99'),
|
||||
unit_price_reg=decimal.Decimal('5.99'),
|
||||
created_by=user,
|
||||
status=enum.PendingProductStatus.PENDING)
|
||||
row = handler.make_row(pending_product=product, order_qty=2, order_uom=enum.ORDER_UOM_CASE)
|
||||
self.assertIsNone(row.status_code)
|
||||
handler.add_row(batch, row)
|
||||
self.assertEqual(row.status_code, row.STATUS_OK)
|
||||
self.assertIsNone(row.product_id)
|
||||
self.assertIs(row.pending_product, product)
|
||||
self.assertEqual(row.product_scancode, '07430500132')
|
||||
self.assertEqual(row.product_brand, 'Bragg')
|
||||
self.assertEqual(row.product_description, 'Vinegar')
|
||||
self.assertEqual(row.product_size, '32oz')
|
||||
self.assertEqual(row.case_size, 12)
|
||||
self.assertEqual(row.unit_cost, decimal.Decimal('3.99'))
|
||||
self.assertEqual(row.unit_price_reg, decimal.Decimal('5.99'))
|
||||
self.assertEqual(row.unit_price_quoted, decimal.Decimal('5.99'))
|
||||
self.assertEqual(row.case_price_quoted, decimal.Decimal('71.88'))
|
||||
self.assertEqual(row.total_price, decimal.Decimal('143.76'))
|
||||
|
||||
def test_remove_row(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = self.make_handler()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
|
||||
batch = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch)
|
||||
self.assertEqual(len(batch.rows), 0)
|
||||
|
||||
kw = dict(
|
||||
scancode='07430500132',
|
||||
brand_name='Bragg',
|
||||
description='Vinegar',
|
||||
size='32oz',
|
||||
case_size=12,
|
||||
unit_cost=decimal.Decimal('3.99'),
|
||||
unit_price_reg=decimal.Decimal('5.99'),
|
||||
created_by=user,
|
||||
)
|
||||
row = handler.add_pending_product(batch, kw, 1, enum.ORDER_UOM_CASE)
|
||||
self.session.add(row)
|
||||
self.session.flush()
|
||||
self.assertEqual(batch.row_count, 1)
|
||||
self.assertEqual(row.total_price, decimal.Decimal('71.88'))
|
||||
self.assertEqual(batch.total_price, decimal.Decimal('71.88'))
|
||||
|
||||
handler.do_remove_row(row)
|
||||
self.assertEqual(batch.row_count, 0)
|
||||
self.assertEqual(batch.total_price, 0)
|
||||
|
||||
def test_do_delete(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = self.make_handler()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
|
||||
# make batch w/ pending customer
|
||||
customer = model.PendingCustomer(full_name="Fred Flintstone",
|
||||
status=enum.PendingCustomerStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(customer)
|
||||
batch = handler.make_batch(self.session, created_by=user, pending_customer=customer)
|
||||
self.session.add(batch)
|
||||
self.session.commit()
|
||||
|
||||
# deleting batch will also delete pending customer
|
||||
self.assertIn(batch, self.session)
|
||||
self.assertEqual(self.session.query(model.PendingCustomer).count(), 1)
|
||||
handler.do_delete(batch, user)
|
||||
self.session.commit()
|
||||
self.assertNotIn(batch, self.session)
|
||||
self.assertEqual(self.session.query(model.PendingCustomer).count(), 0)
|
||||
|
||||
# make new pending customer
|
||||
customer = model.PendingCustomer(full_name="Fred Flintstone",
|
||||
status=enum.PendingCustomerStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(customer)
|
||||
|
||||
# make 2 batches with same pending customer
|
||||
batch1 = handler.make_batch(self.session, created_by=user, pending_customer=customer)
|
||||
batch2 = handler.make_batch(self.session, created_by=user, pending_customer=customer)
|
||||
self.session.add(batch1)
|
||||
self.session.add(batch2)
|
||||
self.session.commit()
|
||||
|
||||
# deleting 1 will not delete pending customer
|
||||
self.assertEqual(self.session.query(model.PendingCustomer).count(), 1)
|
||||
handler.do_delete(batch1, user)
|
||||
self.session.commit()
|
||||
self.assertEqual(self.session.query(model.PendingCustomer).count(), 1)
|
||||
self.assertIs(batch2.pending_customer, customer)
|
||||
|
||||
def test_get_effective_rows(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = self.make_handler()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
|
||||
# make batch w/ different status rows
|
||||
batch = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch)
|
||||
# STATUS_MISSING_PRODUCT
|
||||
row = handler.make_row(order_qty=1, order_uom=enum.ORDER_UOM_UNIT)
|
||||
handler.add_row(batch, row)
|
||||
self.session.add(row)
|
||||
self.session.flush()
|
||||
# STATUS_MISSING_ORDER_QTY
|
||||
row = handler.make_row(product_id=42, order_qty=0, order_uom=enum.ORDER_UOM_UNIT)
|
||||
handler.add_row(batch, row)
|
||||
self.session.add(row)
|
||||
self.session.flush()
|
||||
# STATUS_OK
|
||||
row = handler.make_row(product_id=42, order_qty=1, order_uom=enum.ORDER_UOM_UNIT)
|
||||
handler.add_row(batch, row)
|
||||
self.session.add(row)
|
||||
self.session.commit()
|
||||
|
||||
# only 1 effective row
|
||||
rows = handler.get_effective_rows(batch)
|
||||
self.assertEqual(len(rows), 1)
|
||||
row = rows[0]
|
||||
self.assertEqual(row.status_code, row.STATUS_OK)
|
||||
|
||||
def test_why_not_execute(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = self.make_handler()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
|
||||
batch = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch)
|
||||
self.session.flush()
|
||||
|
||||
reason = handler.why_not_execute(batch)
|
||||
self.assertEqual(reason, "Must assign the customer")
|
||||
|
||||
batch.customer_id = 42
|
||||
|
||||
reason = handler.why_not_execute(batch)
|
||||
self.assertEqual(reason, "Must add at least one valid item")
|
||||
|
||||
kw = dict(
|
||||
scancode='07430500132',
|
||||
brand_name='Bragg',
|
||||
description='Vinegar',
|
||||
size='32oz',
|
||||
case_size=12,
|
||||
unit_cost=decimal.Decimal('3.99'),
|
||||
unit_price_reg=decimal.Decimal('5.99'),
|
||||
created_by=user,
|
||||
)
|
||||
row = handler.add_pending_product(batch, kw, 1, enum.ORDER_UOM_CASE)
|
||||
self.session.add(row)
|
||||
self.session.flush()
|
||||
|
||||
reason = handler.why_not_execute(batch)
|
||||
self.assertIsNone(reason)
|
||||
|
||||
def test_make_new_order(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = self.make_handler()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
|
||||
batch = handler.make_batch(self.session, created_by=user,
|
||||
customer_id=42, customer_name="John Doe")
|
||||
self.session.add(batch)
|
||||
kw = dict(
|
||||
scancode='07430500132',
|
||||
brand_name='Bragg',
|
||||
description='Vinegar',
|
||||
size='32oz',
|
||||
case_size=12,
|
||||
unit_cost=decimal.Decimal('3.99'),
|
||||
unit_price_reg=decimal.Decimal('5.99'),
|
||||
created_by=user,
|
||||
)
|
||||
row = handler.add_pending_product(batch, kw, 1, enum.ORDER_UOM_CASE)
|
||||
self.session.add(row)
|
||||
self.session.flush()
|
||||
|
||||
order = handler.make_new_order(batch, [row], user=user)
|
||||
self.assertIsInstance(order, model.Order)
|
||||
self.assertIs(order.created_by, user)
|
||||
self.assertEqual(order.customer_id, 42)
|
||||
self.assertEqual(order.customer_name, "John Doe")
|
||||
self.assertEqual(len(order.items), 1)
|
||||
item = order.items[0]
|
||||
self.assertEqual(item.product_scancode, '07430500132')
|
||||
self.assertEqual(item.product_brand, 'Bragg')
|
||||
self.assertEqual(item.product_description, 'Vinegar')
|
||||
self.assertEqual(item.product_size, '32oz')
|
||||
self.assertEqual(item.case_size, 12)
|
||||
self.assertEqual(item.unit_cost, decimal.Decimal('3.99'))
|
||||
self.assertEqual(item.unit_price_reg, decimal.Decimal('5.99'))
|
||||
|
||||
def test_execute(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = self.make_handler()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
|
||||
batch = handler.make_batch(self.session, created_by=user,
|
||||
customer_id=42, customer_name="John Doe")
|
||||
self.session.add(batch)
|
||||
kw = dict(
|
||||
scancode='07430500132',
|
||||
brand_name='Bragg',
|
||||
description='Vinegar',
|
||||
size='32oz',
|
||||
case_size=12,
|
||||
unit_cost=decimal.Decimal('3.99'),
|
||||
unit_price_reg=decimal.Decimal('5.99'),
|
||||
created_by=user,
|
||||
)
|
||||
row = handler.add_pending_product(batch, kw, 1, enum.ORDER_UOM_CASE)
|
||||
self.session.add(row)
|
||||
self.session.flush()
|
||||
|
||||
order = handler.execute(batch, user=user)
|
||||
self.assertIsInstance(order, model.Order)
|
||||
self.assertIs(order.created_by, user)
|
||||
self.assertEqual(order.customer_id, 42)
|
||||
self.assertEqual(order.customer_name, "John Doe")
|
||||
self.assertEqual(len(order.items), 1)
|
||||
item = order.items[0]
|
||||
self.assertEqual(item.product_scancode, '07430500132')
|
||||
self.assertEqual(item.product_brand, 'Bragg')
|
||||
self.assertEqual(item.product_description, 'Vinegar')
|
||||
self.assertEqual(item.product_size, '32oz')
|
||||
self.assertEqual(item.case_size, 12)
|
||||
self.assertEqual(item.unit_cost, decimal.Decimal('3.99'))
|
||||
self.assertEqual(item.unit_price_reg, decimal.Decimal('5.99'))
|
0
tests/cli/__init__.py
Normal file
0
tests/cli/__init__.py
Normal file
18
tests/cli/test_install.py
Normal file
18
tests/cli/test_install.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from wuttjamaican.testing import ConfigTestCase
|
||||
from wuttjamaican.install import InstallHandler
|
||||
|
||||
from sideshow.cli import install as mod
|
||||
|
||||
|
||||
class TestInstall(ConfigTestCase):
|
||||
|
||||
def test_run(self):
|
||||
ctx = MagicMock(params={})
|
||||
ctx.parent.wutta_config = self.config
|
||||
with patch.object(InstallHandler, 'run') as run:
|
||||
mod.install(ctx)
|
||||
run.assert_called_once_with()
|
0
tests/db/__init__.py
Normal file
0
tests/db/__init__.py
Normal file
0
tests/db/model/__init__.py
Normal file
0
tests/db/model/__init__.py
Normal file
0
tests/db/model/batch/__init__.py
Normal file
0
tests/db/model/batch/__init__.py
Normal file
23
tests/db/model/batch/test_neworder.py
Normal file
23
tests/db/model/batch/test_neworder.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from wuttjamaican.testing import DataTestCase
|
||||
|
||||
from sideshow.db.model.batch import neworder as mod
|
||||
from sideshow.db.model.products import PendingProduct
|
||||
|
||||
|
||||
class TestNewOrderBatchRow(DataTestCase):
|
||||
|
||||
def test_str(self):
|
||||
|
||||
row = mod.NewOrderBatchRow()
|
||||
self.assertEqual(str(row), "")
|
||||
|
||||
row = mod.NewOrderBatchRow(product_description="Vinegar")
|
||||
self.assertEqual(str(row), "Vinegar")
|
||||
|
||||
product = PendingProduct(brand_name="Bragg",
|
||||
description="Vinegar",
|
||||
size="32oz")
|
||||
row = mod.NewOrderBatchRow(pending_product=product)
|
||||
self.assertEqual(str(row), "Bragg Vinegar 32oz")
|
15
tests/db/model/test_customers.py
Normal file
15
tests/db/model/test_customers.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from wuttjamaican.testing import DataTestCase
|
||||
|
||||
from sideshow.db.model import customers as mod
|
||||
|
||||
|
||||
class TestPendingCustomer(DataTestCase):
|
||||
|
||||
def test_str(self):
|
||||
customer = mod.PendingCustomer()
|
||||
self.assertEqual(str(customer), "")
|
||||
|
||||
customer.full_name = "Fred Flintstone"
|
||||
self.assertEqual(str(customer), "Fred Flintstone")
|
34
tests/db/model/test_orders.py
Normal file
34
tests/db/model/test_orders.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from wuttjamaican.testing import DataTestCase
|
||||
|
||||
from sideshow.db.model import orders as mod
|
||||
from sideshow.db.model.products import PendingProduct
|
||||
|
||||
|
||||
class TestOrder(DataTestCase):
|
||||
|
||||
def test_str(self):
|
||||
|
||||
order = mod.Order()
|
||||
self.assertEqual(str(order), "None")
|
||||
|
||||
order = mod.Order(order_id=42)
|
||||
self.assertEqual(str(order), "42")
|
||||
|
||||
|
||||
class TestOrderItem(DataTestCase):
|
||||
|
||||
def test_str(self):
|
||||
|
||||
item = mod.OrderItem()
|
||||
self.assertEqual(str(item), "")
|
||||
|
||||
item = mod.OrderItem(product_description="Vinegar")
|
||||
self.assertEqual(str(item), "Vinegar")
|
||||
|
||||
product = PendingProduct(brand_name="Bragg",
|
||||
description="Vinegar",
|
||||
size="32oz")
|
||||
item = mod.OrderItem(pending_product=product)
|
||||
self.assertEqual(str(item), "Bragg Vinegar 32oz")
|
44
tests/db/model/test_products.py
Normal file
44
tests/db/model/test_products.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from wuttjamaican.testing import DataTestCase
|
||||
|
||||
from sideshow.db.model import products as mod
|
||||
|
||||
|
||||
class TestPendingProduct(DataTestCase):
|
||||
|
||||
def test_str(self):
|
||||
product = mod.PendingProduct()
|
||||
self.assertEqual(str(product), "")
|
||||
|
||||
product = mod.PendingProduct(brand_name="Bragg")
|
||||
self.assertEqual(str(product), "Bragg")
|
||||
|
||||
product = mod.PendingProduct(description="Vinegar")
|
||||
self.assertEqual(str(product), "Vinegar")
|
||||
|
||||
product = mod.PendingProduct(size="32oz")
|
||||
self.assertEqual(str(product), "32oz")
|
||||
|
||||
product = mod.PendingProduct(brand_name="Bragg",
|
||||
description="Vinegar",
|
||||
size="32oz")
|
||||
self.assertEqual(str(product), "Bragg Vinegar 32oz")
|
||||
|
||||
def test_full_description(self):
|
||||
product = mod.PendingProduct()
|
||||
self.assertEqual(product.full_description, "")
|
||||
|
||||
product = mod.PendingProduct(brand_name="Bragg")
|
||||
self.assertEqual(product.full_description, "Bragg")
|
||||
|
||||
product = mod.PendingProduct(description="Vinegar")
|
||||
self.assertEqual(product.full_description, "Vinegar")
|
||||
|
||||
product = mod.PendingProduct(size="32oz")
|
||||
self.assertEqual(product.full_description, "32oz")
|
||||
|
||||
product = mod.PendingProduct(brand_name="Bragg",
|
||||
description="Vinegar",
|
||||
size="32oz")
|
||||
self.assertEqual(product.full_description, "Bragg Vinegar 32oz")
|
17
tests/test_config.py
Normal file
17
tests/test_config.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from unittest import TestCase
|
||||
|
||||
from wuttjamaican.conf import WuttaConfig
|
||||
|
||||
from sideshow import config as mod
|
||||
|
||||
|
||||
class TestSideshowConfig(TestCase):
|
||||
|
||||
def test_configure(self):
|
||||
config = WuttaConfig(files=[])
|
||||
ext = mod.SideshowConfig()
|
||||
ext.configure(config)
|
||||
self.assertEqual(config.get('wutta.app_title'), "Sideshow")
|
||||
self.assertEqual(config.get('wutta.app_dist'), "Sideshow")
|
0
tests/web/example.conf
Normal file
0
tests/web/example.conf
Normal file
88
tests/web/forms/test_schema.py
Normal file
88
tests/web/forms/test_schema.py
Normal file
|
@ -0,0 +1,88 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from sqlalchemy import orm
|
||||
|
||||
from sideshow.testing import WebTestCase
|
||||
from sideshow.web.forms import schema as mod
|
||||
|
||||
|
||||
class TestOrderRef(WebTestCase):
|
||||
|
||||
def test_sort_query(self):
|
||||
typ = mod.OrderRef(self.request, session=self.session)
|
||||
query = typ.get_query()
|
||||
self.assertIsInstance(query, orm.Query)
|
||||
sorted_query = typ.sort_query(query)
|
||||
self.assertIsInstance(sorted_query, orm.Query)
|
||||
self.assertIsNot(sorted_query, query)
|
||||
|
||||
def test_get_object_url(self):
|
||||
self.pyramid_config.add_route('orders.view', '/orders/{uuid}')
|
||||
model = self.app.model
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
order = model.Order(order_id=42, created_by=user)
|
||||
self.session.add(order)
|
||||
self.session.commit()
|
||||
|
||||
typ = mod.OrderRef(self.request, session=self.session)
|
||||
url = typ.get_object_url(order)
|
||||
self.assertIsNotNone(url)
|
||||
self.assertIn(f'/orders/{order.uuid}', url)
|
||||
|
||||
|
||||
class TestPendingCustomerRef(WebTestCase):
|
||||
|
||||
def test_sort_query(self):
|
||||
typ = mod.PendingCustomerRef(self.request, session=self.session)
|
||||
query = typ.get_query()
|
||||
self.assertIsInstance(query, orm.Query)
|
||||
sorted_query = typ.sort_query(query)
|
||||
self.assertIsInstance(sorted_query, orm.Query)
|
||||
self.assertIsNot(sorted_query, query)
|
||||
|
||||
def test_get_object_url(self):
|
||||
self.pyramid_config.add_route('pending_customers.view', '/pending/customers/{uuid}')
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
customer = model.PendingCustomer(status=enum.PendingCustomerStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(customer)
|
||||
self.session.commit()
|
||||
|
||||
typ = mod.PendingCustomerRef(self.request, session=self.session)
|
||||
url = typ.get_object_url(customer)
|
||||
self.assertIsNotNone(url)
|
||||
self.assertIn(f'/pending/customers/{customer.uuid}', url)
|
||||
|
||||
|
||||
class TestPendingProductRef(WebTestCase):
|
||||
|
||||
def test_sort_query(self):
|
||||
typ = mod.PendingProductRef(self.request, session=self.session)
|
||||
query = typ.get_query()
|
||||
self.assertIsInstance(query, orm.Query)
|
||||
sorted_query = typ.sort_query(query)
|
||||
self.assertIsInstance(sorted_query, orm.Query)
|
||||
self.assertIsNot(sorted_query, query)
|
||||
|
||||
def test_get_object_url(self):
|
||||
self.pyramid_config.add_route('pending_products.view', '/pending/products/{uuid}')
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
product = model.PendingProduct(status=enum.PendingProductStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(product)
|
||||
self.session.commit()
|
||||
|
||||
typ = mod.PendingProductRef(self.request, session=self.session)
|
||||
url = typ.get_object_url(product)
|
||||
self.assertIsNotNone(url)
|
||||
self.assertIn(f'/pending/products/{product.uuid}', url)
|
34
tests/web/test_app.py
Normal file
34
tests/web/test_app.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
import os
|
||||
from unittest import TestCase
|
||||
|
||||
from asgiref.wsgi import WsgiToAsgi
|
||||
from pyramid.router import Router
|
||||
|
||||
from sideshow.web import app as mod
|
||||
|
||||
|
||||
here = os.path.dirname(__file__)
|
||||
example_conf = os.path.join(here, 'example.conf')
|
||||
|
||||
|
||||
class TestMain(TestCase):
|
||||
|
||||
def test_coverage(self):
|
||||
app = mod.main({}, **{'wutta.config': example_conf})
|
||||
self.assertIsInstance(app, Router)
|
||||
|
||||
|
||||
class TestMakeWsgiApp(TestCase):
|
||||
|
||||
def test_coverage(self):
|
||||
app = mod.make_wsgi_app()
|
||||
self.assertIsInstance(app, Router)
|
||||
|
||||
|
||||
class TestMakeAsgiApp(TestCase):
|
||||
|
||||
def test_coverage(self):
|
||||
app = mod.make_asgi_app()
|
||||
self.assertIsInstance(app, WsgiToAsgi)
|
12
tests/web/test_menus.py
Normal file
12
tests/web/test_menus.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from sideshow.testing import WebTestCase
|
||||
from sideshow.web import menus as mod
|
||||
|
||||
|
||||
class TestSideshowMenuHandler(WebTestCase):
|
||||
|
||||
def test_make_menus(self):
|
||||
handler = mod.SideshowMenuHandler(self.config)
|
||||
menus = handler.make_menus(self.request)
|
||||
self.assertEqual(len(menus), 4)
|
10
tests/web/test_static.py
Normal file
10
tests/web/test_static.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from sideshow.testing import WebTestCase
|
||||
from sideshow.web import static as mod
|
||||
|
||||
|
||||
class TestIncludeme(WebTestCase):
|
||||
|
||||
def test_coverage(self):
|
||||
mod.includeme(self.pyramid_config)
|
101
tests/web/views/batch/test_neworder.py
Normal file
101
tests/web/views/batch/test_neworder.py
Normal file
|
@ -0,0 +1,101 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
import datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
from wuttaweb.forms.schema import WuttaMoney
|
||||
|
||||
from sideshow.testing import WebTestCase
|
||||
from sideshow.web.views.batch import neworder as mod
|
||||
from sideshow.web.forms.schema import PendingCustomerRef
|
||||
from sideshow.batch.neworder import NewOrderBatchHandler
|
||||
|
||||
|
||||
class TestIncludeme(WebTestCase):
|
||||
|
||||
def test_coverage(self):
|
||||
mod.includeme(self.pyramid_config)
|
||||
|
||||
|
||||
class TestNewOrderBatchView(WebTestCase):
|
||||
|
||||
def make_view(self):
|
||||
return mod.NewOrderBatchView(self.request)
|
||||
|
||||
def test_get_batch_handler(self):
|
||||
view = self.make_view()
|
||||
handler = view.get_batch_handler()
|
||||
self.assertIsInstance(handler, NewOrderBatchHandler)
|
||||
|
||||
def test_configure_grid(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
grid = view.make_grid(model_class=model.NewOrderBatch)
|
||||
self.assertNotIn('total_price', grid.renderers)
|
||||
view.configure_grid(grid)
|
||||
self.assertIn('total_price', grid.renderers)
|
||||
|
||||
def test_configure_form(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
handler = view.batch_handler
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
customer = model.PendingCustomer(status=enum.PendingCustomerStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(customer)
|
||||
batch = handler.make_batch(self.session, pending_customer=customer, created_by=user)
|
||||
self.session.add(batch)
|
||||
self.session.commit()
|
||||
|
||||
# viewing
|
||||
with patch.object(view, 'viewing', new=True):
|
||||
form = view.make_form(model_instance=batch)
|
||||
view.configure_form(form)
|
||||
schema = form.get_schema()
|
||||
self.assertIsInstance(schema['pending_customer'].typ, PendingCustomerRef)
|
||||
self.assertIsInstance(schema['total_price'].typ, WuttaMoney)
|
||||
|
||||
def test_configure_row_grid(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
grid = view.make_grid(model_class=model.NewOrderBatchRow)
|
||||
self.assertNotIn('total_price', grid.renderers)
|
||||
view.configure_row_grid(grid)
|
||||
self.assertIn('total_price', grid.renderers)
|
||||
|
||||
def test_get_xref_buttons(self):
|
||||
self.pyramid_config.add_route('orders.view', '/orders/{uuid}')
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
handler = view.batch_handler
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
customer = model.PendingCustomer(status=enum.PendingCustomerStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(customer)
|
||||
|
||||
# 1st batch has no order
|
||||
batch = handler.make_batch(self.session, pending_customer=customer, created_by=user)
|
||||
self.session.add(batch)
|
||||
self.session.flush()
|
||||
buttons = view.get_xref_buttons(batch)
|
||||
self.assertEqual(len(buttons), 0)
|
||||
|
||||
# 2nd batch is executed; has order
|
||||
batch = handler.make_batch(self.session, pending_customer=customer, created_by=user,
|
||||
executed=datetime.datetime.now(), executed_by=user)
|
||||
self.session.add(batch)
|
||||
self.session.flush()
|
||||
order = model.Order(order_id=batch.id, created_by=user)
|
||||
self.session.add(order)
|
||||
self.session.flush()
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
# nb. this also requires perm
|
||||
with patch.object(self.request, 'is_root', new=True):
|
||||
buttons = view.get_xref_buttons(batch)
|
||||
self.assertEqual(len(buttons), 1)
|
184
tests/web/views/test_customers.py
Normal file
184
tests/web/views/test_customers.py
Normal file
|
@ -0,0 +1,184 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
import datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
from pyramid.httpexceptions import HTTPFound
|
||||
|
||||
from sideshow.testing import WebTestCase
|
||||
from sideshow.web.views import customers as mod
|
||||
from sideshow.batch.neworder import NewOrderBatchHandler
|
||||
|
||||
|
||||
class TestIncludeme(WebTestCase):
|
||||
|
||||
def test_coverage(self):
|
||||
mod.includeme(self.pyramid_config)
|
||||
|
||||
|
||||
class TestPendingCustomerView(WebTestCase):
|
||||
|
||||
def make_view(self):
|
||||
return mod.PendingCustomerView(self.request)
|
||||
|
||||
def test_configure_grid(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
# nb. mostly just getting coverage here
|
||||
grid = view.make_grid(model_class=model.PendingCustomer)
|
||||
view.configure_grid(grid)
|
||||
self.assertIn('full_name', grid.linked_columns)
|
||||
|
||||
def test_configure_form(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
|
||||
# creating
|
||||
with patch.object(view, 'creating', new=True):
|
||||
form = view.make_form(model_class=model.PendingCustomer)
|
||||
view.configure_form(form)
|
||||
self.assertNotIn('status', form)
|
||||
self.assertNotIn('created', form)
|
||||
self.assertNotIn('created_by', form)
|
||||
self.assertNotIn('orders', form)
|
||||
self.assertNotIn('new_order_batches', form)
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
customer = model.PendingCustomer(status=enum.PendingCustomerStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(customer)
|
||||
self.session.commit()
|
||||
|
||||
# viewing
|
||||
with patch.object(view, 'viewing', new=True):
|
||||
form = view.make_form(model_instance=customer)
|
||||
view.configure_form(form)
|
||||
self.assertIn('status', form)
|
||||
self.assertIn('created', form)
|
||||
self.assertIn('created_by', form)
|
||||
self.assertIn('orders', form)
|
||||
self.assertIn('new_order_batches', form)
|
||||
|
||||
def test_make_orders_grid(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
customer = model.PendingCustomer(status=enum.PendingCustomerStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(customer)
|
||||
order = model.Order(order_id=42, pending_customer=customer, created_by=user)
|
||||
self.session.add(order)
|
||||
self.session.commit()
|
||||
|
||||
# no view perm
|
||||
grid = view.make_orders_grid(customer)
|
||||
self.assertEqual(len(grid.actions), 0)
|
||||
|
||||
# with view perm
|
||||
with patch.object(self.request, 'is_root', new=True):
|
||||
grid = view.make_orders_grid(customer)
|
||||
self.assertEqual(len(grid.actions), 1)
|
||||
self.assertEqual(grid.actions[0].key, 'view')
|
||||
|
||||
def test_make_new_order_batches_grid(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
customer = model.PendingCustomer(status=enum.PendingCustomerStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(customer)
|
||||
batch = handler.make_batch(self.session, pending_customer=customer, created_by=user)
|
||||
self.session.add(batch)
|
||||
self.session.commit()
|
||||
|
||||
# no view perm
|
||||
grid = view.make_new_order_batches_grid(customer)
|
||||
self.assertEqual(len(grid.actions), 0)
|
||||
|
||||
# with view perm
|
||||
with patch.object(self.request, 'is_root', new=True):
|
||||
grid = view.make_new_order_batches_grid(customer)
|
||||
self.assertEqual(len(grid.actions), 1)
|
||||
self.assertEqual(grid.actions[0].key, 'view')
|
||||
|
||||
def test_objectify(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
self.session.commit()
|
||||
|
||||
with patch.object(view, 'creating', new=True):
|
||||
with patch.object(self.request, 'user', new=user):
|
||||
form = view.make_model_form()
|
||||
with patch.object(form, 'validated', create=True, new={
|
||||
'full_name': "Fred Flinstone",
|
||||
}):
|
||||
customer = view.objectify(form)
|
||||
self.assertIsInstance(customer, model.PendingCustomer)
|
||||
self.assertIs(customer.created_by, user)
|
||||
self.assertEqual(customer.status, enum.PendingCustomerStatus.PENDING)
|
||||
|
||||
def test_delete_instance(self):
|
||||
self.pyramid_config.add_route('pending_customers.view', '/pending/customers/{uuid}')
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
|
||||
# 1st customer is standalone, will be deleted
|
||||
customer = model.PendingCustomer(status=enum.PendingCustomerStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(customer)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingCustomer).count(), 1)
|
||||
view.delete_instance(customer)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingCustomer).count(), 0)
|
||||
|
||||
# 2nd customer is attached to new order batch, will not be deleted
|
||||
customer = model.PendingCustomer(status=enum.PendingCustomerStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(customer)
|
||||
batch = handler.make_batch(self.session, created_by=user, pending_customer=customer)
|
||||
self.session.add(batch)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingCustomer).count(), 1)
|
||||
self.assertRaises(HTTPFound, view.delete_instance, customer)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingCustomer).count(), 1)
|
||||
|
||||
# but after batch is executed, 2nd customer can be deleted
|
||||
batch.executed = datetime.datetime.now()
|
||||
batch.executed_by = user
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingCustomer).count(), 1)
|
||||
view.delete_instance(customer)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingCustomer).count(), 0)
|
||||
|
||||
# 3rd customer is attached to order, will not be deleted
|
||||
customer = model.PendingCustomer(status=enum.PendingCustomerStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(customer)
|
||||
order = model.Order(order_id=42, created_by=user, pending_customer=customer)
|
||||
self.session.add(order)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingCustomer).count(), 1)
|
||||
self.assertRaises(HTTPFound, view.delete_instance, customer)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingCustomer).count(), 1)
|
902
tests/web/views/test_orders.py
Normal file
902
tests/web/views/test_orders.py
Normal file
|
@ -0,0 +1,902 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
import datetime
|
||||
import decimal
|
||||
from unittest.mock import patch
|
||||
|
||||
from sqlalchemy import orm
|
||||
from pyramid.httpexceptions import HTTPForbidden, HTTPFound
|
||||
from pyramid.response import Response
|
||||
|
||||
from wuttaweb.forms.schema import WuttaMoney
|
||||
|
||||
from sideshow.batch.neworder import NewOrderBatchHandler
|
||||
from sideshow.testing import WebTestCase
|
||||
from sideshow.web.views import orders as mod
|
||||
from sideshow.web.forms.schema import OrderRef
|
||||
|
||||
|
||||
class TestIncludeme(WebTestCase):
|
||||
|
||||
def test_coverage(self):
|
||||
mod.includeme(self.pyramid_config)
|
||||
|
||||
|
||||
class TestOrderView(WebTestCase):
|
||||
|
||||
def make_view(self):
|
||||
return mod.OrderView(self.request)
|
||||
|
||||
def test_configure_grid(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
grid = view.make_grid(model_class=model.PendingProduct)
|
||||
self.assertNotIn('order_id', grid.linked_columns)
|
||||
self.assertNotIn('total_price', grid.renderers)
|
||||
view.configure_grid(grid)
|
||||
self.assertIn('order_id', grid.linked_columns)
|
||||
self.assertIn('total_price', grid.renderers)
|
||||
|
||||
def test_create(self):
|
||||
self.pyramid_config.include('sideshow.web.views')
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
self.session.flush()
|
||||
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
with patch.object(self.request, 'current_route_url', return_value='/orders/new'):
|
||||
|
||||
# this will require some perms
|
||||
with patch.multiple(self.request, create=True,
|
||||
user=user, is_root=True):
|
||||
|
||||
# fetch page to start things off
|
||||
self.assertEqual(self.session.query(model.NewOrderBatch).count(), 0)
|
||||
response = view.create()
|
||||
self.assertEqual(self.session.query(model.NewOrderBatch).count(), 1)
|
||||
batch1 = self.session.query(model.NewOrderBatch).one()
|
||||
|
||||
# start over; deletes current batch
|
||||
with patch.multiple(self.request, create=True,
|
||||
method='POST',
|
||||
POST={'action': 'start_over'}):
|
||||
response = view.create()
|
||||
self.assertIsInstance(response, HTTPFound)
|
||||
self.assertIn('/orders/new', response.location)
|
||||
self.assertEqual(self.session.query(model.NewOrderBatch).count(), 0)
|
||||
|
||||
# fetch again to get new batch
|
||||
response = view.create()
|
||||
self.assertEqual(self.session.query(model.NewOrderBatch).count(), 1)
|
||||
batch2 = self.session.query(model.NewOrderBatch).one()
|
||||
self.assertIsNot(batch2, batch1)
|
||||
|
||||
# set pending customer
|
||||
with patch.multiple(self.request, create=True,
|
||||
method='POST',
|
||||
json_body={'action': 'set_pending_customer',
|
||||
'first_name': 'Fred',
|
||||
'last_name': 'Flintstone',
|
||||
'phone_number': '555-1234',
|
||||
'email_address': 'fred@mailinator.com'}):
|
||||
response = view.create()
|
||||
self.assertIsInstance(response, Response)
|
||||
self.assertEqual(response.content_type, 'application/json')
|
||||
self.assertEqual(response.json_body, {
|
||||
'customer_is_known': False,
|
||||
'customer_id': None,
|
||||
'customer_name': 'Fred Flintstone',
|
||||
'phone_number': '555-1234',
|
||||
'email_address': 'fred@mailinator.com',
|
||||
'new_customer_name': 'Fred Flintstone',
|
||||
'new_customer_first_name': 'Fred',
|
||||
'new_customer_last_name': 'Flintstone',
|
||||
'new_customer_phone': '555-1234',
|
||||
'new_customer_email': 'fred@mailinator.com',
|
||||
})
|
||||
|
||||
# invalid action
|
||||
with patch.multiple(self.request, create=True,
|
||||
method='POST',
|
||||
POST={'action': 'bogus'},
|
||||
json_body={'action': 'bogus'}):
|
||||
response = view.create()
|
||||
self.assertIsInstance(response, Response)
|
||||
self.assertEqual(response.content_type, 'application/json')
|
||||
self.assertEqual(response.json_body, {'error': 'unknown form action'})
|
||||
|
||||
def test_get_current_batch(self):
|
||||
model = self.app.model
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
# user is required
|
||||
self.assertRaises(HTTPForbidden, view.get_current_batch)
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
self.session.commit()
|
||||
|
||||
with patch.object(view, 'batch_handler', create=True, new=handler):
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
with patch.object(self.request, 'user', new=user):
|
||||
|
||||
# batch is auto-created
|
||||
self.assertEqual(self.session.query(model.NewOrderBatch).count(), 0)
|
||||
batch = view.get_current_batch()
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.NewOrderBatch).count(), 1)
|
||||
self.assertIs(batch.created_by, user)
|
||||
|
||||
# same batch is returned subsequently
|
||||
batch2 = view.get_current_batch()
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.NewOrderBatch).count(), 1)
|
||||
self.assertIs(batch2, batch)
|
||||
|
||||
def test_get_pending_product_required_fields(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
|
||||
# only description is required by default
|
||||
fields = view.get_pending_product_required_fields()
|
||||
self.assertEqual(fields, ['description'])
|
||||
|
||||
# but config can specify otherwise
|
||||
self.config.setdefault('sideshow.orders.unknown_product.fields.brand_name.required', 'true')
|
||||
self.config.setdefault('sideshow.orders.unknown_product.fields.description.required', 'false')
|
||||
self.config.setdefault('sideshow.orders.unknown_product.fields.size.required', 'true')
|
||||
self.config.setdefault('sideshow.orders.unknown_product.fields.unit_price_reg.required', 'true')
|
||||
fields = view.get_pending_product_required_fields()
|
||||
self.assertEqual(fields, ['brand_name', 'size', 'unit_price_reg'])
|
||||
|
||||
def test_get_context_customer(self):
|
||||
self.pyramid_config.add_route('orders', '/orders/')
|
||||
model = self.app.model
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
|
||||
# with true customer
|
||||
batch = handler.make_batch(self.session, created_by=user,
|
||||
customer_id=42, customer_name='Fred Flintstone',
|
||||
phone_number='555-1234', email_address='fred@mailinator.com')
|
||||
self.session.add(batch)
|
||||
self.session.flush()
|
||||
context = view.get_context_customer(batch)
|
||||
self.assertEqual(context, {
|
||||
'customer_is_known': True,
|
||||
'customer_id': 42,
|
||||
'customer_name': 'Fred Flintstone',
|
||||
'phone_number': '555-1234',
|
||||
'email_address': 'fred@mailinator.com',
|
||||
'new_customer_name': None,
|
||||
'new_customer_first_name': None,
|
||||
'new_customer_last_name': None,
|
||||
'new_customer_phone': None,
|
||||
'new_customer_email': None,
|
||||
})
|
||||
|
||||
# with pending customer
|
||||
batch = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch)
|
||||
handler.set_pending_customer(batch, dict(
|
||||
full_name="Fred Flintstone",
|
||||
first_name="Fred", last_name="Flintstone",
|
||||
phone_number='555-1234', email_address='fred@mailinator.com',
|
||||
created_by=user,
|
||||
))
|
||||
self.session.flush()
|
||||
context = view.get_context_customer(batch)
|
||||
self.assertEqual(context, {
|
||||
'customer_is_known': False,
|
||||
'customer_id': None,
|
||||
'customer_name': 'Fred Flintstone',
|
||||
'phone_number': '555-1234',
|
||||
'email_address': 'fred@mailinator.com',
|
||||
'new_customer_name': 'Fred Flintstone',
|
||||
'new_customer_first_name': 'Fred',
|
||||
'new_customer_last_name': 'Flintstone',
|
||||
'new_customer_phone': '555-1234',
|
||||
'new_customer_email': 'fred@mailinator.com',
|
||||
})
|
||||
|
||||
# with no customer
|
||||
batch = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch)
|
||||
self.session.flush()
|
||||
context = view.get_context_customer(batch)
|
||||
self.assertEqual(context, {
|
||||
'customer_is_known': True, # nb. this is for UI default
|
||||
'customer_id': None,
|
||||
'customer_name': None,
|
||||
'phone_number': None,
|
||||
'email_address': None,
|
||||
'new_customer_name': None,
|
||||
'new_customer_first_name': None,
|
||||
'new_customer_last_name': None,
|
||||
'new_customer_phone': None,
|
||||
'new_customer_email': None,
|
||||
})
|
||||
|
||||
def test_start_over(self):
|
||||
self.pyramid_config.add_route('orders.create', '/orders/new')
|
||||
model = self.app.model
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
self.session.commit()
|
||||
|
||||
with patch.object(view, 'batch_handler', create=True, new=handler):
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
with patch.object(self.request, 'user', new=user):
|
||||
|
||||
batch = view.get_current_batch()
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.NewOrderBatch).count(), 1)
|
||||
result = view.start_over(batch)
|
||||
self.assertIsInstance(result, HTTPFound)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.NewOrderBatch).count(), 0)
|
||||
|
||||
def test_cancel_order(self):
|
||||
self.pyramid_config.add_route('orders', '/orders/')
|
||||
model = self.app.model
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
self.session.commit()
|
||||
|
||||
with patch.object(view, 'batch_handler', create=True, new=handler):
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
with patch.object(self.request, 'user', new=user):
|
||||
|
||||
batch = view.get_current_batch()
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.NewOrderBatch).count(), 1)
|
||||
result = view.cancel_order(batch)
|
||||
self.assertIsInstance(result, HTTPFound)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.NewOrderBatch).count(), 0)
|
||||
|
||||
def test_set_pending_customer(self):
|
||||
self.pyramid_config.add_route('orders.create', '/orders/new')
|
||||
model = self.app.model
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
self.session.commit()
|
||||
|
||||
data = {
|
||||
'first_name': 'Fred',
|
||||
'last_name': 'Flintstone',
|
||||
'phone_number': '555-1234',
|
||||
'email_address': 'fred@mailinator.com',
|
||||
}
|
||||
|
||||
with patch.object(view, 'batch_handler', create=True, new=handler):
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
with patch.object(self.request, 'user', new=user):
|
||||
batch = view.get_current_batch()
|
||||
self.session.flush()
|
||||
|
||||
# normal
|
||||
self.assertIsNone(batch.pending_customer)
|
||||
context = view.set_pending_customer(batch, data)
|
||||
self.assertIsInstance(batch.pending_customer, model.PendingCustomer)
|
||||
self.assertEqual(context, {
|
||||
'customer_is_known': False,
|
||||
'customer_id': None,
|
||||
'customer_name': 'Fred Flintstone',
|
||||
'phone_number': '555-1234',
|
||||
'email_address': 'fred@mailinator.com',
|
||||
'new_customer_name': 'Fred Flintstone',
|
||||
'new_customer_first_name': 'Fred',
|
||||
'new_customer_last_name': 'Flintstone',
|
||||
'new_customer_phone': '555-1234',
|
||||
'new_customer_email': 'fred@mailinator.com',
|
||||
})
|
||||
|
||||
# error
|
||||
with patch.object(handler, 'set_pending_customer', side_effect=RuntimeError):
|
||||
context = view.set_pending_customer(batch, data)
|
||||
self.assertEqual(context, {
|
||||
'error': 'RuntimeError',
|
||||
})
|
||||
|
||||
def test_add_item(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
self.session.commit()
|
||||
|
||||
data = {
|
||||
'pending_product': {
|
||||
'scancode': '07430500132',
|
||||
'brand_name': 'Bragg',
|
||||
'description': 'Vinegar',
|
||||
'size': '32oz',
|
||||
'unit_price_reg': 5.99,
|
||||
},
|
||||
'order_qty': 1,
|
||||
'order_uom': enum.ORDER_UOM_UNIT,
|
||||
}
|
||||
|
||||
with patch.object(view, 'batch_handler', create=True, new=handler):
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
with patch.object(self.request, 'user', new=user):
|
||||
batch = view.get_current_batch()
|
||||
self.session.flush()
|
||||
self.assertEqual(len(batch.rows), 0)
|
||||
|
||||
# normal pending product
|
||||
result = view.add_item(batch, data)
|
||||
self.assertIn('batch', result)
|
||||
self.assertIn('row', result)
|
||||
self.session.flush()
|
||||
self.assertEqual(len(batch.rows), 1)
|
||||
row = batch.rows[0]
|
||||
self.assertIsInstance(row.pending_product, model.PendingProduct)
|
||||
|
||||
# pending w/ invalid price
|
||||
with patch.dict(data['pending_product'], unit_price_reg='invalid'):
|
||||
result = view.add_item(batch, data)
|
||||
self.assertEqual(result, {'error': "Invalid entry for field: unit_price_reg"})
|
||||
self.session.flush()
|
||||
self.assertEqual(len(batch.rows), 1) # still just the 1st row
|
||||
|
||||
# true product not yet supported
|
||||
with patch.dict(data, product_is_known=True):
|
||||
self.assertRaises(NotImplementedError, view.add_item, batch, data)
|
||||
|
||||
def test_update_item(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
self.session.commit()
|
||||
|
||||
data = {
|
||||
'pending_product': {
|
||||
'scancode': '07430500132',
|
||||
'brand_name': 'Bragg',
|
||||
'description': 'Vinegar',
|
||||
'size': '32oz',
|
||||
'unit_price_reg': 5.99,
|
||||
'case_size': 12,
|
||||
},
|
||||
'order_qty': 1,
|
||||
'order_uom': enum.ORDER_UOM_CASE,
|
||||
}
|
||||
|
||||
with patch.object(view, 'batch_handler', create=True, new=handler):
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
with patch.object(self.request, 'user', new=user):
|
||||
batch = view.get_current_batch()
|
||||
self.session.flush()
|
||||
self.assertEqual(len(batch.rows), 0)
|
||||
|
||||
# add row w/ pending product
|
||||
view.add_item(batch, data)
|
||||
self.session.flush()
|
||||
row = batch.rows[0]
|
||||
self.assertIsInstance(row.pending_product, model.PendingProduct)
|
||||
self.assertEqual(row.unit_price_quoted, decimal.Decimal('5.99'))
|
||||
|
||||
# missing row uuid
|
||||
result = view.update_item(batch, data)
|
||||
self.assertEqual(result, {'error': "Must specify a row UUID"})
|
||||
|
||||
# row not found
|
||||
with patch.dict(data, uuid=self.app.make_true_uuid()):
|
||||
result = view.update_item(batch, data)
|
||||
self.assertEqual(result, {'error': "Row not found"})
|
||||
|
||||
# row for wrong batch
|
||||
batch2 = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch2)
|
||||
row2 = handler.make_row(order_qty=1, order_uom=enum.ORDER_UOM_UNIT)
|
||||
handler.add_row(batch2, row2)
|
||||
self.session.flush()
|
||||
with patch.dict(data, uuid=row2.uuid):
|
||||
result = view.update_item(batch, data)
|
||||
self.assertEqual(result, {'error': "Row is for wrong batch"})
|
||||
|
||||
# set row for remaining tests
|
||||
data['uuid'] = row.uuid
|
||||
|
||||
# true product not yet supported
|
||||
with patch.dict(data, product_is_known=True):
|
||||
self.assertRaises(NotImplementedError, view.update_item, batch, data)
|
||||
|
||||
# update row, pending product
|
||||
with patch.dict(data, order_qty=2):
|
||||
with patch.dict(data['pending_product'], scancode='07430500116'):
|
||||
self.assertEqual(row.product_scancode, '07430500132')
|
||||
self.assertEqual(row.order_qty, 1)
|
||||
result = view.update_item(batch, data)
|
||||
self.assertEqual(sorted(result), ['batch', 'row'])
|
||||
self.assertEqual(row.product_scancode, '07430500116')
|
||||
self.assertEqual(row.order_qty, 2)
|
||||
self.assertEqual(row.pending_product.scancode, '07430500116')
|
||||
self.assertEqual(result['row']['product_scancode'], '07430500116')
|
||||
self.assertEqual(result['row']['order_qty'], '2')
|
||||
|
||||
def test_delete_item(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
self.session.commit()
|
||||
|
||||
data = {
|
||||
'pending_product': {
|
||||
'scancode': '07430500132',
|
||||
'brand_name': 'Bragg',
|
||||
'description': 'Vinegar',
|
||||
'size': '32oz',
|
||||
'unit_price_reg': 5.99,
|
||||
'case_size': 12,
|
||||
},
|
||||
'order_qty': 1,
|
||||
'order_uom': enum.ORDER_UOM_CASE,
|
||||
}
|
||||
|
||||
with patch.object(view, 'batch_handler', create=True, new=handler):
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
with patch.object(self.request, 'user', new=user):
|
||||
batch = view.get_current_batch()
|
||||
self.session.flush()
|
||||
self.assertEqual(len(batch.rows), 0)
|
||||
|
||||
# add row w/ pending product
|
||||
view.add_item(batch, data)
|
||||
self.session.flush()
|
||||
row = batch.rows[0]
|
||||
self.assertIsInstance(row.pending_product, model.PendingProduct)
|
||||
self.assertEqual(row.unit_price_quoted, decimal.Decimal('5.99'))
|
||||
|
||||
# missing row uuid
|
||||
result = view.delete_item(batch, data)
|
||||
self.assertEqual(result, {'error': "Must specify a row UUID"})
|
||||
|
||||
# row not found
|
||||
with patch.dict(data, uuid=self.app.make_true_uuid()):
|
||||
result = view.delete_item(batch, data)
|
||||
self.assertEqual(result, {'error': "Row not found"})
|
||||
|
||||
# row for wrong batch
|
||||
batch2 = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch2)
|
||||
row2 = handler.make_row(order_qty=1, order_uom=enum.ORDER_UOM_UNIT)
|
||||
handler.add_row(batch2, row2)
|
||||
self.session.flush()
|
||||
with patch.dict(data, uuid=row2.uuid):
|
||||
result = view.delete_item(batch, data)
|
||||
self.assertEqual(result, {'error': "Row is for wrong batch"})
|
||||
|
||||
# row is deleted
|
||||
data['uuid'] = row.uuid
|
||||
self.assertEqual(len(batch.rows), 1)
|
||||
self.assertEqual(batch.row_count, 1)
|
||||
result = view.delete_item(batch, data)
|
||||
self.assertEqual(sorted(result), ['batch'])
|
||||
self.session.refresh(batch)
|
||||
self.assertEqual(len(batch.rows), 0)
|
||||
self.assertEqual(batch.row_count, 0)
|
||||
|
||||
def test_submit_new_order(self):
|
||||
self.pyramid_config.add_route('orders.view', '/orders/{uuid}')
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
self.session.commit()
|
||||
|
||||
data = {
|
||||
'pending_product': {
|
||||
'scancode': '07430500132',
|
||||
'brand_name': 'Bragg',
|
||||
'description': 'Vinegar',
|
||||
'size': '32oz',
|
||||
'unit_price_reg': 5.99,
|
||||
'case_size': 12,
|
||||
},
|
||||
'order_qty': 1,
|
||||
'order_uom': enum.ORDER_UOM_CASE,
|
||||
}
|
||||
|
||||
with patch.object(view, 'batch_handler', create=True, new=handler):
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
with patch.object(self.request, 'user', new=user):
|
||||
batch = view.get_current_batch()
|
||||
self.session.flush()
|
||||
self.assertEqual(len(batch.rows), 0)
|
||||
|
||||
# add row w/ pending product
|
||||
view.add_item(batch, data)
|
||||
self.session.flush()
|
||||
row = batch.rows[0]
|
||||
self.assertIsInstance(row.pending_product, model.PendingProduct)
|
||||
self.assertEqual(row.unit_price_quoted, decimal.Decimal('5.99'))
|
||||
|
||||
# execute not allowed yet (no customer)
|
||||
result = view.submit_new_order(batch, {})
|
||||
self.assertEqual(result, {'error': "Must assign the customer"})
|
||||
|
||||
# submit/execute ok
|
||||
batch.customer_id = 42
|
||||
result = view.submit_new_order(batch, {})
|
||||
self.assertEqual(sorted(result), ['next_url'])
|
||||
self.assertIn('/orders/', result['next_url'])
|
||||
|
||||
# error (already executed)
|
||||
result = view.submit_new_order(batch, {})
|
||||
self.assertEqual(result, {
|
||||
'error': f"ValueError: batch has already been executed: {batch}",
|
||||
})
|
||||
|
||||
def test_get_default_uom_choices(self):
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
|
||||
uoms = view.get_default_uom_choices()
|
||||
self.assertEqual(uoms, [{'key': key, 'value': val}
|
||||
for key, val in enum.ORDER_UOM.items()])
|
||||
|
||||
def test_normalize_batch(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
batch = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch)
|
||||
pending = {
|
||||
'scancode': '07430500132',
|
||||
'brand_name': 'Bragg',
|
||||
'description': 'Vinegar',
|
||||
'size': '32oz',
|
||||
'unit_price_reg': 5.99,
|
||||
'case_size': 12,
|
||||
'created_by': user,
|
||||
}
|
||||
row = handler.add_pending_product(batch, pending, 1, enum.ORDER_UOM_CASE)
|
||||
self.session.commit()
|
||||
|
||||
data = view.normalize_batch(batch)
|
||||
self.assertEqual(data, {
|
||||
'uuid': batch.uuid.hex,
|
||||
'total_price': '71.880',
|
||||
'total_price_display': '$71.88',
|
||||
'status_code': None,
|
||||
'status_text': None,
|
||||
})
|
||||
|
||||
def test_normalize_row(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
batch = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch)
|
||||
pending = {
|
||||
'scancode': '07430500132',
|
||||
'brand_name': 'Bragg',
|
||||
'description': 'Vinegar',
|
||||
'size': '32oz',
|
||||
'unit_price_reg': 5.99,
|
||||
'case_size': 12,
|
||||
'created_by': user,
|
||||
}
|
||||
row = handler.add_pending_product(batch, pending, 2, enum.ORDER_UOM_CASE)
|
||||
self.session.commit()
|
||||
|
||||
# normal
|
||||
data = view.normalize_row(row)
|
||||
self.assertIsInstance(data, dict)
|
||||
self.assertEqual(data['uuid'], row.uuid.hex)
|
||||
self.assertEqual(data['sequence'], 1)
|
||||
self.assertEqual(data['product_scancode'], '07430500132')
|
||||
self.assertEqual(data['case_size'], '12')
|
||||
self.assertEqual(data['order_qty'], '2')
|
||||
self.assertEqual(data['order_uom'], 'CS')
|
||||
self.assertEqual(data['order_qty_display'], '2 Cases (× 12 = 24 Units)')
|
||||
self.assertEqual(data['unit_price_reg'], 5.99)
|
||||
self.assertEqual(data['unit_price_reg_display'], '$5.99')
|
||||
self.assertNotIn('unit_price_sale', data)
|
||||
self.assertNotIn('unit_price_sale_display', data)
|
||||
self.assertNotIn('sale_ends', data)
|
||||
self.assertNotIn('sale_ends_display', data)
|
||||
self.assertEqual(data['unit_price_quoted'], 5.99)
|
||||
self.assertEqual(data['unit_price_quoted_display'], '$5.99')
|
||||
self.assertEqual(data['case_price_quoted'], 71.88)
|
||||
self.assertEqual(data['case_price_quoted_display'], '$71.88')
|
||||
self.assertEqual(data['total_price'], 143.76)
|
||||
self.assertEqual(data['total_price_display'], '$143.76')
|
||||
self.assertIsNone(data['special_order'])
|
||||
self.assertEqual(data['status_code'], row.STATUS_OK)
|
||||
self.assertEqual(data['pending_product'], {
|
||||
'uuid': row.pending_product_uuid.hex,
|
||||
'scancode': '07430500132',
|
||||
'brand_name': 'Bragg',
|
||||
'description': 'Vinegar',
|
||||
'size': '32oz',
|
||||
'department_id': None,
|
||||
'department_name': None,
|
||||
'unit_price_reg': 5.99,
|
||||
'vendor_name': None,
|
||||
'vendor_item_code': None,
|
||||
'unit_cost': None,
|
||||
'case_size': 12.0,
|
||||
'notes': None,
|
||||
'special_order': None,
|
||||
})
|
||||
|
||||
# unknown case size
|
||||
row.pending_product.case_size = None
|
||||
handler.refresh_row(row)
|
||||
self.session.flush()
|
||||
data = view.normalize_row(row)
|
||||
self.assertEqual(data['order_qty_display'], '2 Cases (× ?? = ?? Units)')
|
||||
|
||||
# order by unit
|
||||
row.order_uom = enum.ORDER_UOM_UNIT
|
||||
handler.refresh_row(row)
|
||||
self.session.flush()
|
||||
data = view.normalize_row(row)
|
||||
self.assertEqual(data['order_qty_display'], '2 Units')
|
||||
|
||||
# item on sale
|
||||
row.pending_product.case_size = 12
|
||||
row.unit_price_sale = decimal.Decimal('5.19')
|
||||
row.sale_ends = datetime.datetime(2025, 1, 5, 20, 32)
|
||||
handler.refresh_row(row, now=datetime.datetime(2025, 1, 5, 19))
|
||||
self.session.flush()
|
||||
data = view.normalize_row(row)
|
||||
self.assertEqual(data['unit_price_sale'], 5.19)
|
||||
self.assertEqual(data['unit_price_sale_display'], '$5.19')
|
||||
self.assertEqual(data['sale_ends'], '2025-01-05 20:32:00')
|
||||
self.assertEqual(data['sale_ends_display'], '2025-01-05')
|
||||
self.assertEqual(data['unit_price_quoted'], 5.19)
|
||||
self.assertEqual(data['unit_price_quoted_display'], '$5.19')
|
||||
self.assertEqual(data['case_price_quoted'], 62.28)
|
||||
self.assertEqual(data['case_price_quoted_display'], '$62.28')
|
||||
|
||||
def test_get_instance_title(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
order = model.Order(order_id=42, customer_name="Fred Flintstone", created_by=user)
|
||||
self.session.add(order)
|
||||
self.session.flush()
|
||||
|
||||
title = view.get_instance_title(order)
|
||||
self.assertEqual(title, "#42 for Fred Flintstone")
|
||||
|
||||
def test_configure_form(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
order = model.Order(order_id=42, created_by=user)
|
||||
self.session.add(order)
|
||||
self.session.commit()
|
||||
|
||||
# viewing
|
||||
with patch.object(view, 'viewing', new=True):
|
||||
form = view.make_form(model_instance=order)
|
||||
# nb. this is to avoid include/exclude ambiguity
|
||||
form.remove('items')
|
||||
view.configure_form(form)
|
||||
schema = form.get_schema()
|
||||
self.assertIsInstance(schema['total_price'].typ, WuttaMoney)
|
||||
|
||||
def test_get_xref_buttons(self):
|
||||
self.pyramid_config.add_route('neworder_batches.view', '/batch/neworder/{uuid}')
|
||||
model = self.app.model
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
order = model.Order(order_id=42, created_by=user)
|
||||
self.session.add(order)
|
||||
self.session.flush()
|
||||
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
|
||||
# nb. this requires perm to view batch
|
||||
with patch.object(self.request, 'is_root', new=True):
|
||||
|
||||
# order has no batch, so no buttons
|
||||
buttons = view.get_xref_buttons(order)
|
||||
self.assertEqual(buttons, [])
|
||||
|
||||
# mock up a batch to get a button
|
||||
batch = handler.make_batch(self.session,
|
||||
id=order.order_id,
|
||||
created_by=user,
|
||||
executed=datetime.datetime.now(),
|
||||
executed_by=user)
|
||||
self.session.add(batch)
|
||||
self.session.flush()
|
||||
buttons = view.get_xref_buttons(order)
|
||||
self.assertEqual(len(buttons), 1)
|
||||
button = buttons[0]
|
||||
self.assertIn("View the Batch", button)
|
||||
|
||||
def test_get_row_grid_data(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
order = model.Order(order_id=42, created_by=user)
|
||||
self.session.add(order)
|
||||
self.session.flush()
|
||||
order.items.append(model.OrderItem(product_id='07430500132',
|
||||
product_scancode='07430500132',
|
||||
order_qty=1, order_uom=enum.ORDER_UOM_UNIT,
|
||||
status_code=enum.ORDER_ITEM_STATUS_INITIATED))
|
||||
self.session.flush()
|
||||
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
query = view.get_row_grid_data(order)
|
||||
self.assertIsInstance(query, orm.Query)
|
||||
items = query.all()
|
||||
self.assertEqual(len(items), 1)
|
||||
self.assertEqual(items[0].product_scancode, '07430500132')
|
||||
|
||||
def test_configure_row_grid(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
order = model.Order(order_id=42, created_by=user)
|
||||
self.session.add(order)
|
||||
self.session.flush()
|
||||
order.items.append(model.OrderItem(product_id='07430500132',
|
||||
product_scancode='07430500132',
|
||||
order_qty=1, order_uom=enum.ORDER_UOM_UNIT,
|
||||
status_code=enum.ORDER_ITEM_STATUS_INITIATED))
|
||||
self.session.flush()
|
||||
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
grid = view.make_grid(model_class=model.OrderItem, data=order.items)
|
||||
self.assertNotIn('product_scancode', grid.linked_columns)
|
||||
view.configure_row_grid(grid)
|
||||
self.assertIn('product_scancode', grid.linked_columns)
|
||||
|
||||
def test_render_status_code(self):
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
result = view.render_status_code(None, None, enum.ORDER_ITEM_STATUS_INITIATED)
|
||||
self.assertEqual(result, "initiated")
|
||||
self.assertEqual(result, enum.ORDER_ITEM_STATUS[enum.ORDER_ITEM_STATUS_INITIATED])
|
||||
|
||||
def test_get_row_action_url_view(self):
|
||||
self.pyramid_config.add_route('order_items.view', '/order-items/{uuid}')
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
order = model.Order(order_id=42, created_by=user)
|
||||
self.session.add(order)
|
||||
self.session.flush()
|
||||
item = model.OrderItem(product_id='07430500132',
|
||||
product_scancode='07430500132',
|
||||
order_qty=1, order_uom=enum.ORDER_UOM_UNIT,
|
||||
status_code=enum.ORDER_ITEM_STATUS_INITIATED)
|
||||
order.items.append(item)
|
||||
self.session.flush()
|
||||
|
||||
url = view.get_row_action_url_view(item, 0)
|
||||
self.assertIn(f'/order-items/{item.uuid}', url)
|
||||
|
||||
|
||||
class TestOrderItemView(WebTestCase):
|
||||
|
||||
def make_view(self):
|
||||
return mod.OrderItemView(self.request)
|
||||
|
||||
def test_get_query(self):
|
||||
view = self.make_view()
|
||||
query = view.get_query(session=self.session)
|
||||
self.assertIsInstance(query, orm.Query)
|
||||
|
||||
def test_configure_grid(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
grid = view.make_grid(model_class=model.OrderItem)
|
||||
self.assertNotIn('order_id', grid.linked_columns)
|
||||
view.configure_grid(grid)
|
||||
self.assertIn('order_id', grid.linked_columns)
|
||||
|
||||
def test_render_order_id(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
order = model.Order(order_id=42)
|
||||
item = model.OrderItem()
|
||||
order.items.append(item)
|
||||
self.assertEqual(view.render_order_id(item, None, None), 42)
|
||||
|
||||
def test_render_status_code(self):
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
self.assertEqual(view.render_status_code(None, None, enum.ORDER_ITEM_STATUS_INITIATED),
|
||||
'initiated')
|
||||
|
||||
def test_configure_form(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
|
||||
item = model.OrderItem(status_code=enum.ORDER_ITEM_STATUS_INITIATED)
|
||||
|
||||
# viewing
|
||||
with patch.object(view, 'viewing', new=True):
|
||||
form = view.make_form(model_instance=item)
|
||||
view.configure_form(form)
|
||||
schema = form.get_schema()
|
||||
self.assertIsInstance(schema['order'].typ, OrderRef)
|
||||
|
||||
def test_get_xref_buttons(self):
|
||||
self.pyramid_config.add_route('orders.view', '/orders/{uuid}')
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
order = model.Order(order_id=42, created_by=user)
|
||||
self.session.add(order)
|
||||
item = model.OrderItem(order_qty=1, order_uom=enum.ORDER_UOM_UNIT,
|
||||
status_code=enum.ORDER_ITEM_STATUS_INITIATED)
|
||||
order.items.append(item)
|
||||
self.session.flush()
|
||||
|
||||
# nb. this requires perms
|
||||
with patch.object(self.request, 'is_root', new=True):
|
||||
|
||||
# one button by default
|
||||
buttons = view.get_xref_buttons(item)
|
||||
self.assertEqual(len(buttons), 1)
|
||||
self.assertIn("View the Order", buttons[0])
|
163
tests/web/views/test_products.py
Normal file
163
tests/web/views/test_products.py
Normal file
|
@ -0,0 +1,163 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
import datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
from pyramid.httpexceptions import HTTPFound
|
||||
|
||||
from sideshow.testing import WebTestCase
|
||||
from sideshow.web.views import products as mod
|
||||
from sideshow.batch.neworder import NewOrderBatchHandler
|
||||
|
||||
|
||||
class TestIncludeme(WebTestCase):
|
||||
|
||||
def test_coverage(self):
|
||||
mod.includeme(self.pyramid_config)
|
||||
|
||||
|
||||
class TestPendingProductView(WebTestCase):
|
||||
|
||||
def make_view(self):
|
||||
return mod.PendingProductView(self.request)
|
||||
|
||||
def test_configure_grid(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
# nb. mostly just getting coverage here
|
||||
grid = view.make_grid(model_class=model.PendingProduct)
|
||||
self.assertNotIn('scancode', grid.linked_columns)
|
||||
self.assertNotIn('brand_name', grid.linked_columns)
|
||||
self.assertNotIn('description', grid.linked_columns)
|
||||
view.configure_grid(grid)
|
||||
self.assertIn('scancode', grid.linked_columns)
|
||||
self.assertIn('brand_name', grid.linked_columns)
|
||||
self.assertIn('description', grid.linked_columns)
|
||||
|
||||
def test_configure_form(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
|
||||
# creating
|
||||
with patch.object(view, 'creating', new=True):
|
||||
form = view.make_form(model_class=model.PendingProduct)
|
||||
view.configure_form(form)
|
||||
self.assertNotIn('status', form)
|
||||
self.assertNotIn('created', form)
|
||||
self.assertNotIn('created_by', form)
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
product = model.PendingProduct(status=enum.PendingProductStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(product)
|
||||
self.session.commit()
|
||||
|
||||
# viewing
|
||||
with patch.object(view, 'viewing', new=True):
|
||||
form = view.make_form(model_instance=product)
|
||||
view.configure_form(form)
|
||||
self.assertIn('status', form)
|
||||
self.assertIn('created', form)
|
||||
self.assertIn('created_by', form)
|
||||
|
||||
def test_make_orders_grid(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
order = model.Order(order_id=42, customer_id=42, created_by=user)
|
||||
product = model.PendingProduct(status=enum.PendingProductStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(product)
|
||||
item = model.OrderItem(pending_product=product,
|
||||
order_qty=1, order_uom=enum.ORDER_UOM_UNIT,
|
||||
status_code=enum.ORDER_ITEM_STATUS_INITIATED)
|
||||
order.items.append(item)
|
||||
self.session.add(order)
|
||||
self.session.commit()
|
||||
|
||||
# no view perm
|
||||
grid = view.make_orders_grid(product)
|
||||
self.assertEqual(len(grid.actions), 0)
|
||||
|
||||
# with view perm
|
||||
with patch.object(self.request, 'is_root', new=True):
|
||||
grid = view.make_orders_grid(product)
|
||||
self.assertEqual(len(grid.actions), 1)
|
||||
self.assertEqual(grid.actions[0].key, 'view')
|
||||
|
||||
def test_make_new_order_batches_grid(self):
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
batch = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch)
|
||||
product = model.PendingProduct(status=enum.PendingProductStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(product)
|
||||
row = handler.make_row(pending_product=product,
|
||||
order_qty=1, order_uom=enum.ORDER_UOM_UNIT)
|
||||
handler.add_row(batch, row)
|
||||
self.session.commit()
|
||||
|
||||
# no view perm
|
||||
grid = view.make_new_order_batches_grid(product)
|
||||
self.assertEqual(len(grid.actions), 0)
|
||||
|
||||
# with view perm
|
||||
with patch.object(self.request, 'is_root', new=True):
|
||||
grid = view.make_new_order_batches_grid(product)
|
||||
self.assertEqual(len(grid.actions), 1)
|
||||
self.assertEqual(grid.actions[0].key, 'view')
|
||||
|
||||
def test_delete_instance(self):
|
||||
self.pyramid_config.add_route('pending_products.view', '/pending/products/{uuid}')
|
||||
model = self.app.model
|
||||
enum = self.app.enum
|
||||
handler = NewOrderBatchHandler(self.config)
|
||||
view = self.make_view()
|
||||
|
||||
user = model.User(username='barney')
|
||||
self.session.add(user)
|
||||
|
||||
# 1st product is standalone, will be deleted
|
||||
product = model.PendingProduct(status=enum.PendingProductStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(product)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingProduct).count(), 1)
|
||||
view.delete_instance(product)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingProduct).count(), 0)
|
||||
|
||||
# 2nd product is attached to new order batch, will not be deleted
|
||||
batch = handler.make_batch(self.session, created_by=user)
|
||||
self.session.add(batch)
|
||||
product = model.PendingProduct(status=enum.PendingProductStatus.PENDING,
|
||||
created_by=user)
|
||||
self.session.add(product)
|
||||
row = handler.make_row(pending_product=product,
|
||||
order_qty=1, order_uom=enum.ORDER_UOM_UNIT)
|
||||
handler.add_row(batch, row)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingProduct).count(), 1)
|
||||
self.assertRaises(HTTPFound, view.delete_instance, product)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingProduct).count(), 1)
|
||||
|
||||
# but after batch is executed, 2nd product can be deleted
|
||||
batch.executed = datetime.datetime.now()
|
||||
batch.executed_by = user
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingProduct).count(), 1)
|
||||
view.delete_instance(product)
|
||||
self.session.flush()
|
||||
self.assertEqual(self.session.query(model.PendingProduct).count(), 0)
|
Loading…
Add table
Add a link
Reference in a new issue