Ticket: Paging - AssertionError

Hi all,

Like some others, I’ve been running into an AssertionError for this ticket.

client = <FlaskClient <Flask 'mflix.factory'>>

    @pytest.mark.paging
    def test_supports_paging_by_text(client):
        filter = {'text': 'bank robbery'}
        (movies0, results0) = get_movies(filter, 0, 20)
        assert len(list(movies0)) == 20
        assert results0 == 475
        assert movies0[0].get('title') == 'The Bank'
        last_page = int(475 / 20)
        (movies2, results2) = get_movies(filter, last_page, 20)
        assert len(list(movies2)) == 15
>       assert movies2[0].get('title') == "Ugetsu"
E       assert "Operation 'Y...'s Adventures" == 'Ugetsu'
E         - Operation 'Y' & Other Shurik's Adventures
E         + Ugetsu

tests/test_paging.py:46: AssertionError

I have read through the thread Bug in movies.py - paging but the suggested fix for api/movies.py seems to be related to filters in the UI not being passed to the URL when scrolling and appears separate from the issue described where the unit test fails in v4.4 but passes in v4.2

I am using an Atlas cluster v4.4.4

I have included the complete function below:

def get_movies(filters, page, movies_per_page):
    """
    Returns a cursor to a list of movie documents.

    Based on the page number and the number of movies per page, the result may
    be skipped and limited.

    The `filters` from the API are passed to the `build_query_sort_project`
    method, which constructs a query, sort, and projection, and then that query
    is executed by this method (`get_movies`).

    Returns 2 elements in a tuple: (movies, total_num_movies)
    """

    query, sort, project = build_query_sort_project(filters)
    if project:
        cursor = db.movies.find(query, project).sort(sort)
    else:
        cursor = db.movies.find(query).sort(sort)

    total_num_movies = 0
    if page == 0:
        total_num_movies = db.movies.count_documents(query)

    """
    Ticket: Paging

    Before this method returns back to the API, use the "movies_per_page"
    argument to decide how many movies get displayed per page. The "page"
    argument will decide which page

    Paging can be implemented by using the skip() and limit() methods against
    the Pymongo cursor.
    """

    # TODO: Paging
    # Use the cursor to only return the movies that belong on the current page.
    movies = cursor.skip(movies_per_page * page).limit(movies_per_page)

    return (list(movies), total_num_movies)

After having read several other threads on this particular ticket, my understanding is that the above is the correct solution. Can someone confirm this? Do I need to switch to a cluster of version 4.2?

Does anyone know the answer?

Hi @Felix_Stubner

Without seeing the value of sort, it’s difficult to work out what might be causing your problem. If the value of sort is {}, for example, then I think the sort operation won’t do anything, and your result will probably be invalid.

Can you print out the value of your sort variable, and maybe post it here, so we can see what’s going on?

Thanks for your response. I’ve added a print(query, sort, project) statement as shown below:

query, sort, project = build_query_sort_project(filters)
if project:
    cursor = db.movies.find(query, project).sort(sort)
else:
    cursor = db.movies.find(query).sort(sort)

print(query, sort, project)

This is the output:

client = <FlaskClient <Flask 'mflix.factory'>>

    @pytest.mark.paging
    def test_supports_paging_by_text(client):
        filter = {'text': 'bank robbery'}
        (movies0, results0) = get_movies(filter, 0, 20)
        assert len(list(movies0)) == 20
        assert results0 == 475
        assert movies0[0].get('title') == 'The Bank'
        last_page = int(475 / 20)
        (movies2, results2) = get_movies(filter, last_page, 20)
        assert len(list(movies2)) == 15
>       assert movies2[0].get('title') == "Ugetsu"
E       assert "Operation 'Y...'s Adventures" == 'Ugetsu'
E         - Operation 'Y' & Other Shurik's Adventures
E         + Ugetsu

tests/test_paging.py:46: AssertionError
------------------------------------------- Captured stdout call --------------------------------------------------
{'$text': {'$search': 'bank robbery'}} [('score', {'$meta': 'textScore'})] {'score': {'$meta': 'textScore'}}

Let me know if this will suffice.

does anyone know how to solve this? I am running into the same exact error, thanks!

Yes, I think this is the right answer, @Felix_Stubner!

I had the same error and found out that for some reason the sort method is inconsistent and gives different answers on consecutives executions even if we are giving with the same arguments.

To pass the test simply run it again until it passes, using this solution

@Wellington_Zenon thanks for your response.

I have tried your suggestion but after several reruns, I keep getting the same two.

client = <FlaskClient <Flask 'mflix.factory'>>

    @pytest.mark.paging
    def test_supports_paging_by_text(client):
        filter = {'text': 'bank robbery'}
        (movies0, results0) = get_movies(filter, 0, 20)
        assert len(list(movies0)) == 20
        assert results0 == 475
        assert movies0[0].get('title') == 'The Bank'
        last_page = int(475 / 20)
        (movies2, results2) = get_movies(filter, last_page, 20)
        assert len(list(movies2)) == 15
>       assert movies2[0].get('title') == "Ugetsu"
E       AssertionError: assert 'Skippy' == 'Ugetsu'
E         - Skippy
E         + Ugetsu

tests/test_paging.py:46: AssertionError

and

client = <FlaskClient <Flask 'mflix.factory'>>

    @pytest.mark.paging
    def test_supports_paging_by_text(client):
        filter = {'text': 'bank robbery'}
        (movies0, results0) = get_movies(filter, 0, 20)
        assert len(list(movies0)) == 20
        assert results0 == 475
        assert movies0[0].get('title') == 'The Bank'
        last_page = int(475 / 20)
        (movies2, results2) = get_movies(filter, last_page, 20)
        assert len(list(movies2)) == 15
>       assert movies2[0].get('title') == "Ugetsu"
E       assert "Operation 'Y...'s Adventures" == 'Ugetsu'
E         - Operation 'Y' & Other Shurik's Adventures
E         + Ugetsu

tests/test_paging.py:46: AssertionError

Hey, I found the solution!

The sort method ends up finding movies with the same score and for that those movies order are not consistent. The solution is to add a second sort tuple ( ("_id", ASCENDING) ) in the build_query_sort_project function:

def build_query_sort_project(filters):

if filters:
    if "text" in filters:
        query = {"$text": {"$search": filters["text"]}}
        meta_score = {"$meta": "textScore"}
        sort = [("score", meta_score), ("_id", ASCENDING)]  <----new tuple
6 Likes

This does indeed fix the issue and allow the paging test to pass.

However, I am very curious if this is the intended solution.

1 Like

I guess only the staff could really answer that, but I can tell you the same function has this same pattern just before this if statement, so it just might be the case they forgot to add it the second time, a code bug but nothing related to the ticket itself

def build_query_sort_project(filters):
  
    query = {}
    sort = [("tomatoes.viewer.numReviews", DESCENDING), ("_id", ASCENDING)]  <---- HERE
    project = None
    if filters:
        if "text" in filters:
            query = {"$text": {"$search": filters["text"]}}
            meta_score = {"$meta": "textScore"}
            sort = [("score", meta_score), ("_id", ASCENDING)]                     < -----HERE
2 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.