def test_update_user(orig_share_amt, share_add_amt, share_del_amt,
                     update_name):
    if share_del_amt > orig_share_amt:
        return
    serializer = UserSerializer()
    user = random_users(1)[0]
    orig_shares = random_shares(orig_share_amt)
    orig_time = user.updated_at
    for share in orig_shares:
        share.users.add(user)

    validated_data = {'name': user.name + random_str(2)} if update_name else {}

    if share_add_amt + share_del_amt > 0:
        added = random_shares(share_add_amt)
        new_shares = orig_shares[:-share_del_amt] + added
        deleted = orig_shares[-share_del_amt:]
        validated_data['shares'] = new_shares
    else:
        deleted = []
        new_shares = list(orig_shares)

    serializer.update(user, validated_data)
    assert_update_time(orig_time, user)

    assert user.name == validated_data.get('name', user.name)
    user_shares = user.shares
    assert user_shares.count() == len(new_shares)
    assert set(user_shares) == set(new_shares)
    for deleted_share in deleted:
        assert deleted_share not in user_shares
def test_create_expense(user_count, resolved, timed):
    users = random_users(user_count)
    paid_for = {user: (1, len(users)) for user in users}
    validated_data = {
        'description': random_str(100),
        'share': random_shares(1)[0],
        'total': uniform(0.5, 1000.0),
        'paid_by': users[0],
        'paid_for': paid_for
    }

    if timed:
        validated_data['created_at'] = rand_time(False)
    if resolved is not None:
        validated_data['resolved'] = resolved

    serializer = ExpenseSerializer()
    expense = serializer.create(validated_data)

    if not timed:
        assert_creation_time(expense)
    if resolved is None:
        assert expense.resolved is False

    assert_expense_items(validated_data, expense)
示例#3
0
def test_deserialize_expense_fail_bad_paid_for(cond):
    share = random_shares(1)[0]
    users = random_users(5)
    user_ids = [u.id for u in users]
    share.users.add(users[0])
    share.save()
    if cond == 'no_user':
        for user in users[1:]:
            share.users.add(user)
            share.save()
        paid_for = {id_: '1/6' for id_ in chain(user_ids, '999')}
    elif cond == 'user_not_in_share':
        paid_for = {id_: '1/5' for id_ in user_ids}
    elif cond == 'bad_sum':
        paid_for = {id_: '1/4' for id_ in user_ids}
    elif cond == 'empty':
        paid_for = {}
    elif cond == 'bad_fraction':
        paid_for = {id_: '1/5/' for id_ in user_ids}
    else:
        return
    data = {'paid_for': paid_for, 'description': 'foo', 'total': 3,
            'share': share.id, 'paid_by': user_ids[0]}
    serializer = ExpenseSerializer(data=data)
    with pytest.raises(ValidationError) as e:
        serializer.is_valid(True)
    assert e.value.args[0]['paid_for']
示例#4
0
def test_user_shares():
    user, *_ = random_users(1)
    shares_in = random_shares(3)[:2]
    for share in shares_in:
        share.users.add(user)
        share.save()
    assert user.shares.count() == len(shares_in)
    assert set(user.shares) == set(shares_in)
示例#5
0
def test_serialize_share(user_count, expense_count):
    share = random_shares(1)[0]
    if user_count:
        users = random_users(user_count)
        for user in users:
            share.users.add(user)
            share.save()
    if expense_count:
        random_expenses(expense_count, share=share)
    _assert_round_trip(ShareSerializer, share)
def test_update_share(orig_user_count, new_name, new_des, new_users_count):
    serializer = ShareSerializer()
    share = random_shares(1)[0]
    updated_at = share.updated_at
    users = random_users(orig_user_count)
    for user in users:
        share.users.add(user)

    validated_data = {}
    if new_name:
        validated_data['name'] = share.name + random_str(3)
    if new_des:
        validated_data['description'] = share.description + random_str(3)
    if new_users_count is not None:
        user_diff = new_users_count - orig_user_count
    else:
        user_diff = 0
    user_out = []
    orig_user_list = list(share.users.all())
    if user_diff > 0:
        validated_data['users'] = orig_user_list + random_users(user_diff)
    elif user_diff < 0:
        validated_data['users'] = orig_user_list[:user_diff]
        user_out = orig_user_list[user_diff:]

    serializer.update(share, validated_data)
    assert_update_time(updated_at, share)

    new_name = validated_data.get('name', share.name)
    assert new_name == share.name

    new_des = validated_data.get('description', share.description)
    assert new_des == share.description

    new_users = share.users.all()
    new_users_count = new_users.count()
    assert new_users_count == new_users_count
    for user in user_out:
        assert user not in new_users
    if 'users' in validated_data:
        assert set(validated_data['users']) == set(new_users)
示例#7
0
def test_user_shares_duplicate():
    share, *_ = random_shares(1)
    user, *_ = random_users(1)
    id_ = share.id

    share.users.add(user)
    share.save()

    share_get_new = Share.objects.get(id=id_)
    share_get_new.users.add(user)

    assert user.shares.count() == 1
    assert set(user.shares) == {share}
示例#8
0
def test_serialize_expense(created_at, resolved, paid_for_count):
    if created_at:
        (expense,), (share,), (user,) = random_expenses(
            1, resolved=resolved, created_at=rand_time(False))
    else:
        (expense,), (share,), (user,) = random_expenses(1, resolved=resolved)
    paid_for_diff = paid_for_count - 1
    paid_for_users = random_users(paid_for_diff)
    for paid_for_u in chain(paid_for_users, [user]):
        share.users.add(paid_for_u)
        share.save()
    paid_for = {u: (1, paid_for_count) for u in chain(paid_for_users, [user])}
    expense.generate_ratio(paid_for)
    _assert_round_trip(ExpenseSerializer, expense)
示例#9
0
def test_serialize_user(paid_by_count, paid_for_count, share_count):
    user = random_users(1)[0]
    if share_count:
        shares = random_shares(share_count)
        for share in shares:
            share.users.add(user)
            share.save()
    max_expense_count = max(paid_by_count, paid_for_count)
    if max_expense_count:
        expenses, *_ = random_expenses(max_expense_count)
        for i, exp in enumerate(expenses):
            if i < paid_by_count:
                exp.paid_by = user
                exp.save()
            if i < paid_for_count:
                exp.generate_ratio({user: (1, 1)})
    _assert_round_trip(UserSerializer, user)
def test_create_share(validated_data):
    serializer = ShareSerializer()
    user_count = validated_data.get('users')
    if user_count:
        validated_data['users'] = random_users(user_count)

    share = serializer.create(validated_data)

    assert_creation_time(share)
    assert share.name == validated_data['name']
    assert share.description == validated_data['description']
    if 'users' not in validated_data:
        assert not share.users.all()
    else:
        assert share.users.count() == len(validated_data['users'])
        assert set(share.users.all()) == set(validated_data['users'])
        for user in share.users.all():
            assert share in user.shares
示例#11
0
def test_deserialize_expense_fail_bad_paid_by(cond):
    share = random_shares(1)[0]
    paid_for_user, paid_by_user = random_users(2)
    share.users.add(paid_for_user)
    share.save()
    if cond == 'not_exist':
        user_id = 9999
    elif cond == 'not_in_share':
        user_id = paid_by_user.id
    else:
        return

    data = {'paid_for': {str(paid_for_user.id): '1/1'}, 'description': 'foo',
            'total': 3, 'share': share.id, 'paid_by': user_id}
    serializer = ExpenseSerializer(data=data)
    with pytest.raises(ValidationError) as e:
        serializer.is_valid(True)
    assert e.value.args[0]['paid_by']
示例#12
0
def test_user_shares_none():
    user, *_ = random_users(1)
    Share.objects.create(name='bar', description='baz')
    assert not user.shares