Example #1
0
def test_lists_dto_update__when_user_is_guest__and_updates_only_items__then_update_list(
        dynamodb_lists_table, dynamodb_user_to_lists_table, sample_data):
    from sf_shopping_list.data.db.lists import Lists
    from sf_shopping_list.data.dto.lists_dto import ListsDto
    from sf_shopping_list.data.clients.dynamodb import lists_table

    list1 = sample_data['lists'][1]
    new_list1 = ListModel.parse_obj(list1)

    Lists.save(ListMappers.map_dto_to_doc(new_list1))

    # guest is allowed to change items
    new_list1.items = ['item3', 'item4', 'item5']

    new_list1_res = ListsDto.update(new_list1.id, new_list1, tested_user_id)
    new_list1_saved = lists_table().get_item(Key={'id': new_list1.id})

    assert new_list1_res == new_list1
    assert ListDocModel.from_db_doc(
        new_list1_saved['Item']) == ListMappers.map_dto_to_doc(new_list1)

    # guest is not allowed to modify guests list or name
    new_list1.guests += 'some_other_user_id'
    with pytest.raises(NoAccessError):
        ListsDto.update(new_list1.id, new_list1, tested_user_id)

    new_list1.listName = 'new list name'
    with pytest.raises(NoAccessError):
        ListsDto.update(new_list1.id, new_list1, tested_user_id)
    def update(id: str, new_list: ListModel,
               user_sub: str) -> Optional[ListModel]:
        curr_list = ListsDto.get(id, user_sub)
        if not curr_list:
            return None
        else:
            if user_sub in curr_list.guests:  # is guest, cannot modify listName and guests
                if curr_list.listName != new_list.listName or curr_list.guests != new_list.guests:
                    raise NoAccessError(
                        'Guest is not allowed to modify those attributes')

        # rewrite immutable properties from existing item
        new_list.id = id
        new_list.createdAt = curr_list.createdAt
        new_list.userId = curr_list.userId

        # update access entries for users denied access
        for non_guest in (set(curr_list.guests) - set(new_list.guests)):
            UserToLists.remove_list(non_guest, id)

        # update access entries for users given access
        for guest in new_list.guests:
            UserToLists.add_list(guest, id)

        Lists.save(ListMappers.map_dto_to_doc(new_list))
        return new_list
Example #3
0
def test_lists_dto_get__if_list_exists__and_user_is_in_guests_list__return_the_list(
        dynamodb_lists_table, sample_data):
    from sf_shopping_list.data.dto.lists_dto import ListsDto
    from sf_shopping_list.data.clients.dynamodb import lists_table

    list1 = sample_data['lists'][1]

    lists_table().put_item(Item=list1)

    res = ListsDto.get(list1['id'], list1['guests'][0])
    assert ListMappers.map_dto_to_doc(res) == ListDocModel.from_db_doc(list1)
Example #4
0
def test_lists_dto_get_all__if_user_owns_lists_and_has_guest_access_to_list__then_return_list_of_the_lists_sorted_from_old_to_new(
        dynamodb_lists_table, dynamodb_user_to_lists_table, sample_data):
    from sf_shopping_list.data.dto.lists_dto import ListsDto
    from sf_shopping_list.data.clients.dynamodb import lists_table, user_to_lists_table

    list0 = sample_data['lists'][0]
    list1 = sample_data['lists'][1]

    lists_table().put_item(Item=list0)
    lists_table().put_item(Item=list1)
    user_to_lists_table().put_item(Item={
        'user_id': tested_user_id,
        'lists': [list0['id'], list1['id']]
    })

    res = ListsDto.get_all(tested_user_id)
    assert len(res) == 2
    assert ListMappers.map_dto_to_doc(
        res[0]) == ListDocModel.from_db_doc(list1)
    assert ListMappers.map_dto_to_doc(
        res[1]) == ListDocModel.from_db_doc(list0)
 def create(new_list_dto: NewList, user_sub: str) -> ListModel:
     list_dto = ListModel(
         id=ShortUUID.random(length=6),
         userId=user_sub,
         listName=new_list_dto.name,
         createdAt=datetime.utcnow(),
         items=new_list_dto.items,
         guests=new_list_dto.guests,
     )
     Lists.save(ListMappers.map_dto_to_doc(list_dto))
     UserToLists.add_list(user_sub, list_dto.id)
     for guest_id in new_list_dto.guests:
         UserToLists.add_list(guest_id, list_dto.id)
     return list_dto
Example #6
0
def test_lists_dto_update__when_user_is_guest__and_updates_guests_or_name__then_raise_no_access_error(
        dynamodb_lists_table, dynamodb_user_to_lists_table, sample_data):
    from sf_shopping_list.data.db.lists import Lists
    from sf_shopping_list.data.dto.lists_dto import ListsDto

    list1 = sample_data['lists'][1]
    new_list1 = ListModel.parse_obj(list1)

    Lists.save(ListMappers.map_dto_to_doc(new_list1))

    # guest is not allowed to modify guests list or name
    new_list1.guests += 'some_other_user_id'
    with pytest.raises(NoAccessError):
        ListsDto.update(new_list1.id, new_list1, tested_user_id)

    new_list1.listName = 'new list name'
    with pytest.raises(NoAccessError):
        ListsDto.update(new_list1.id, new_list1, tested_user_id)
Example #7
0
def test_lists_dto_update__when_user_is_owner__then_update_list(
        dynamodb_lists_table, dynamodb_user_to_lists_table, sample_data):
    from sf_shopping_list.data.dto.lists_dto import ListsDto
    from sf_shopping_list.data.db.lists import Lists
    from sf_shopping_list.data.clients.dynamodb import lists_table
    from sf_shopping_list.data.clients.dynamodb import user_to_lists_table

    list0 = sample_data['lists'][0]
    new_list0 = ListModel.parse_obj(list0)

    Lists.save(ListMappers.map_dto_to_doc(new_list0))

    # owner can change items, guests and listName
    new_list0.items = ['item4', 'item5', 'item6']
    new_list0.guests = {other_user_id}
    new_list0.listName = 'new list name'
    new_list0_res = ListsDto.update(new_list0.id, new_list0, new_list0.userId)
    new_list0_saved = lists_table().get_item(Key={'id': new_list0.id})

    # updated list is returned
    assert new_list0_res == new_list0

    # updated list is saved
    assert ListDocModel.from_db_doc(
        new_list0_saved['Item']) == ListMappers.map_dto_to_doc(new_list0)

    # if guests were added, so their user_to_lists entries were updated
    other_user_lists = user_to_lists_table().get_item(
        Key={'user_id': other_user_id})

    assert new_list0.id in UserToListsDocModel.from_db_doc(
        other_user_lists['Item']).lists

    # try removing guest
    new_list0.guests = set()
    new_list0_res = ListsDto.update(new_list0.id, new_list0, new_list0.userId)
    new_list0_saved = lists_table().get_item(Key={'id': new_list0.id})

    assert new_list0_res == new_list0
    assert ListDocModel.from_db_doc(
        new_list0_saved['Item']) == ListMappers.map_dto_to_doc(new_list0)

    # guests should have their user_to_lists entries updated
    other_user_lists = user_to_lists_table().get_item(
        Key={'user_id': other_user_id})

    assert new_list0.id not in UserToListsDocModel.from_db_doc(
        other_user_lists['Item']).lists

    # try adding guest back
    new_list0.guests = {other_user_id}
    new_list0_res = ListsDto.update(new_list0.id, new_list0, new_list0.userId)
    new_list0_saved = lists_table().get_item(Key={'id': new_list0.id})

    assert new_list0_res == new_list0
    assert ListDocModel.from_db_doc(
        new_list0_saved['Item']) == ListMappers.map_dto_to_doc(new_list0)

    # guests should have their user_to_lists entries updated
    other_user_lists = user_to_lists_table().get_item(
        Key={'user_id': other_user_id})

    # immutable fields changes should be ignored
    original_new_list_0 = new_list0.copy()
    new_list0.id = 'foo'
    new_list0.createdAt = datetime.utcnow()
    new_list0.userId = other_user_id

    new_list0_res = ListsDto.update(original_new_list_0.id, new_list0,
                                    original_new_list_0.userId)
    new_list_0_saved = lists_table().get_item(Key={'id': new_list0.id})

    assert new_list0_res == original_new_list_0
    assert ListDocModel.from_db_doc(
        new_list_0_saved['Item']) == ListMappers.map_dto_to_doc(
            original_new_list_0)

    assert new_list0.id in UserToListsDocModel.from_db_doc(
        other_user_lists['Item']).lists