Fixing a few bugs in preparation for sneak peek.

This commit is contained in:
Roland 2022-01-15 18:05:51 -07:00
parent 064147a769
commit 474e68cc3d
No known key found for this signature in database
GPG key ID: 9D6DBD3ACF11AB93
8 changed files with 119 additions and 20 deletions

View file

@ -117,13 +117,17 @@ def put_item(_: Request, item_id: int, data: dict):
@bp.delete('/item/<item_ids:[0-9,]+>')
@bp.delete('/item/<item_ids:int>')
@validate_doc(
'Delete items from an inventory.',
)
@run_after(save_inventories_file)
def item_delete(_: Request, item_ids: str):
try:
item_ids = [int(i) for i in item_ids.split(',')]
if isinstance(item_ids, int):
item_ids = [item_ids, ]
else:
item_ids = [int(i) for i in item_ids.split(',')]
except ValueError:
raise ValidationError('Could not parse item_ids')

View file

@ -0,0 +1,26 @@
import pytest
from modules.inventory import Inventory, Item, DEFAULT_CATEGORIES, DEFAULT_INVENTORIES
@pytest.fixture
def test_inventory(test_session):
inventory = Inventory(name='Test Inventory')
test_session.add(inventory)
test_session.commit()
return inventory
@pytest.fixture
def init_test_inventory(test_session):
for subcategory, category in DEFAULT_CATEGORIES:
item = Item(subcategory=subcategory, category=category)
test_session.add(item)
for name in DEFAULT_INVENTORIES:
inv = Inventory(name=name)
test_session.add(inv)
inventory = test_session.query(Inventory).filter_by(name='Food Storage').one()
test_session.commit()
return inventory

View file

@ -10,6 +10,7 @@ from sqlalchemy.orm.exc import NoResultFound
from wrolpi.common import logger, Base
from wrolpi.db import get_db_session, get_db_curs
from wrolpi.errors import APIError
from .models import Inventory, Item, InventoriesVersion
logger = logger.getChild(__name__)
@ -174,7 +175,10 @@ def update_item(item_id: int, item: dict):
def delete_items(items_ids: List[int]):
with get_db_curs(commit=True) as curs:
curs.execute('UPDATE item SET deleted_at=current_timestamp WHERE id = ANY(%s)', (items_ids,))
curs.execute('UPDATE item SET deleted_at=current_timestamp WHERE id = ANY(%s) RETURNING id', (items_ids,))
deleted_ids = {i['id'] for i in curs.fetchall()}
if set(items_ids) != deleted_ids:
raise APIError('Could not delete the items')
def get_inventories_version():

View file

@ -0,0 +1,51 @@
from http import HTTPStatus
from modules.inventory import Item
from modules.inventory.inventory import save_item
def test_delete_items(test_session, init_test_inventory, test_client):
"""
Multiple Items can be deleted in a single request.
"""
item = dict(
brand='Ocean',
name='Salt',
count='8.0',
unit='lbs',
item_size='25.0',
category='cooking ingredients',
subcategory='salt',
)
save_item(init_test_inventory.id, item)
save_item(init_test_inventory.id, item)
items = test_session.query(Item).filter(Item.brand != None).all()
request, response = test_client.delete(f'/api/inventory/item/{items[0].id},{items[1].id}')
assert response.status_code == HTTPStatus.NO_CONTENT, response.status_code
# Refresh all items. Verify they were deleted.
[test_session.refresh(i) for i in items]
assert all([i.deleted_at for i in items])
def test_delete_item(test_session, init_test_inventory, test_client):
"""
An item can be deleted by itself.
"""
item = dict(
brand='Ocean',
name='Salt',
count='8.0',
unit='lbs',
item_size='25.0',
category='cooking ingredients',
subcategory='salt',
)
save_item(init_test_inventory.id, item)
item = test_session.query(Item).filter(Item.brand != None).one()
assert not item.deleted_at
request, response = test_client.delete(f'/api/inventory/item/{item.id}')
assert response.status_code == HTTPStatus.NO_CONTENT, response.status_code
test_session.refresh(item)
assert item.deleted_at

View file

@ -277,7 +277,7 @@ def quantity_to_string(quantity: Quantity) -> str:
]
)
def test_compact_unit(quantity, expected):
# Round the result so we don't have to specify all those zeros for the test definition.
# Round the result, so we don't have to specify all those zeros for the test definition.
assert quantity_to_string(compact_unit(quantity)) == expected
@ -296,7 +296,7 @@ length = gallon.dimensionality
{(('grains',), oz.dimensionality): Decimal('1') * oz},
),
(
# The larger of the units is what is returned.
# The largest of the units is what is returned.
[
{'category': 'grains', 'count': Decimal('1'), 'item_size': Decimal('1'), 'unit': 'oz'},
{'category': 'grains', 'count': Decimal('1'), 'item_size': Decimal('1'), 'unit': 'lbs'},

View file

@ -1 +1,8 @@
from modules.videos import downloader
from wrolpi import before_startup
@before_startup
def startup_spread_channel_downloads():
from .channel import lib as channel_lib
channel_lib.spread_channel_downloads()

View file

@ -5,7 +5,6 @@ from http import HTTPStatus
from sanic import Blueprint, response
from sanic.request import Request
from wrolpi import before_startup
from wrolpi.common import create_websocket_feed, get_sanic_url, \
wrol_mode_check
from wrolpi.common import logger
@ -128,8 +127,3 @@ async def favorite(_: Request, data: dict):
async def statistics(_: Request):
ret = await get_statistics()
return json_response(ret, HTTPStatus.OK)
@before_startup
def startup_spread_channel_downloads():
channel_lib.spread_channel_downloads()