def test_BasicGiftList_create_report(user, gift_list, purchased_items,
                                     available_items):
    basic_giftlist = BasicGiftList(user)

    basic_giftlist.gift_list = gift_list
    assert basic_giftlist.gift_list == gift_list

    # set availability and purchase amounts
    for item, quantity in purchased_items:
        basic_giftlist._purchase_map[frozenset(item.items())] = quantity
    for item, quantity in available_items:
        basic_giftlist._availability_map[frozenset(item.items())] = quantity

    with StringIO() as buf, redirect_stdout(buf):
        basic_giftlist.create_report()
        report = buf.getvalue()

    for section, items in [('Purchased items:', purchased_items),
                           ('Available items:', available_items)]:
        assert section in report
        section_index = report.index(section)
        for item, quantity in items:
            item_line = f'{item} (quantity: {quantity})'
            if quantity:
                assert item_line in report
                assert report.index(item_line) > section_index
            else:
                assert item_line not in report

    assert user in report
def test_BasicGiftList_remove_item(gift_list, item, result, exception):
    mock_giftlist = Mock()
    mock_giftlist.gift_list = gift_list
    try:
        BasicGiftList.remove_item(mock_giftlist, item)
        assert mock_giftlist.gift_list == result
    except AssertionError:
        raise
    except Exception as err:
        assert isinstance(err, exception)
def test_BasicGiftList_create_list():
    mock_giftlist = Mock()
    assert not isinstance(mock_giftlist.gift_list, list)
    assert isinstance(BasicGiftList.create_list(mock_giftlist), list)
    assert isinstance(mock_giftlist.gift_list, list)
    assert mock_giftlist.gift_list == []

    # test list is reset on second call
    mock_giftlist.gift_list = [1, 2, 3]
    assert mock_giftlist.gift_list != []
    BasicGiftList.create_list(mock_giftlist)
    assert mock_giftlist.gift_list == []
def test_BasicGiftList__init__():
    giftlist = BasicGiftList('test_user')
    assert isinstance(giftlist, BasicGiftList)
    assert giftlist.gift_list == []
    assert giftlist.user is 'test_user'
    assert not giftlist._availability_map
    assert not giftlist._purchase_map
    assert giftlist._purchase_map[random.random()] == 0
def test_BasicGiftList_super_method_raises_NotImplementedError(method, kwargs):
    basic_gift_list = BasicGiftList('test_user')
    assert isinstance(basic_gift_list, AbstractGiftList)
    try:
        func = getattr(super(BasicGiftList, basic_gift_list), method)
        if kwargs is None:
            func()  # some methods do not accept kwargs
        else:
            func(**kwargs)
        assert False
    except NotImplementedError:
        pass  # This is the expected behaviour when calling base method
def test_BasicGiftList_purchase_item(gift_list, item, quantity_available,
                                     quantity_to_purchase, exception):
    basic_giftlist = BasicGiftList('test_user')
    try:
        key = frozenset(item.items())
        assert not basic_giftlist.gift_list
        basic_giftlist.gift_list = gift_list
        assert basic_giftlist.gift_list == gift_list
        assert not basic_giftlist._availability_map
        basic_giftlist._availability_map[key] = quantity_available
        assert basic_giftlist._availability_map[key] == quantity_available
        assert basic_giftlist._purchase_map[key] == 0
        basic_giftlist.purchase_item(item, quantity_to_purchase)
        assert basic_giftlist._availability_map[key] == \
            quantity_available - quantity_to_purchase
        assert basic_giftlist._purchase_map[key] == quantity_to_purchase
    except AssertionError:
        raise
    except Exception as err:
        if not isinstance(err, exception):
            raise  # recover traceback for debugging
def test_BasicGiftList_add_item(item, error_cls, modified_list,
                                available_quantity):
    basic_giftlist = BasicGiftList('test_user')
    assert basic_giftlist.gift_list == []
    assert not basic_giftlist._availability_map
    assert not basic_giftlist._purchase_map

    try:
        # test adding item
        basic_giftlist.add_item(item, available_quantity)
        assert basic_giftlist.gift_list == modified_list
        quantity = basic_giftlist._availability_map[frozenset(item.items())]
        assert quantity == available_quantity
        assert not basic_giftlist._purchase_map  # should not be modified

        # attempt to add item twice
        basic_giftlist.add_item(item, available_quantity)
        assert basic_giftlist.gift_list == modified_list
        quantity = basic_giftlist._availability_map[frozenset(item.items())]
        assert quantity == (2 * available_quantity)
    except AssertionError:
        raise
    except Exception as err:
        assert isinstance(err, error_cls)
def test_BasicGiftList_get_user(user):
    basic_giftlist = BasicGiftList(user)
    assert basic_giftlist.get_user(
        user) == user  # NOTE: there are no type checks
def test_BasicGiftList_get_list(gift_list):
    mock_giftlist = Mock()
    mock_giftlist.gift_list = gift_list
    # test that the get_list() method simply returns the gift_list attribute
    assert BasicGiftList.get_list(mock_giftlist) == mock_giftlist.gift_list