Example #1
0
class DescibeCursorPaginationView(
    APIViewTest,
    UsesGetMethod,

    ReturnsCursorPagination,
):
    url = lambda_fixture(lambda: url_for('pagination-cursor'))
Example #2
0
class DescibeLimitOffsetPaginationView(
    APIViewTest,
    UsesGetMethod,

    ReturnsLimitOffsetPagination,
):
    url = lambda_fixture(lambda: url_for('pagination-limit-offset'))
Example #3
0
class DescibePageNumberPaginationView(
    APIViewTest,
    UsesGetMethod,

    ReturnsPageNumberPagination,
):
    url = lambda_fixture(lambda: url_for('pagination-page-number'))
Example #4
0
class DescribeLoginRequired(
        APIViewTest,
        UsesGetMethod,
        ForbidsAnonymousUsers,
        AsUser('user'),
        Returns200,
):
    # NOTE: this view simply returns 200, but requires an authenticated user
    #       (i.e. it declares IsAuthenticated for its permission_classes)
    url = lambda_fixture(lambda: url_for('authorization-login-required'))
Example #5
0
class DescribeData(
        APIViewTest,
        UsesPostMethod,
):
    # NOTE: this view simply returns the request's POST data as the response
    url = lambda_fixture(lambda: url_for('views-data'))

    # This fixture supports passing POST data in the request
    data = static_fixture({
        'post': 'malone',
        'fizzbuzz': 'zibbzuff',
    })

    def it_posts_data(self, json, data):
        expected = data
        actual = json
        assert expected == actual
Example #6
0
class DescribeHeaders(
        APIViewTest,
        UsesGetMethod,
):
    # NOTE: this view simply returns the request's headers as the response
    url = lambda_fixture(lambda: url_for('views-headers'))

    # This fixture supports passing headers (e.g. `Authorization: Api-Key 123`) in the request
    headers = static_fixture({
        'Custom-Header': 'abc',
        'Head': 'Shoulders, Knees, Toes',
    })

    def it_passes_headers(self, json, headers):
        expected = headers
        actual = json
        assert_dict_is_subset(expected, actual)
Example #7
0
class DescribeQueryParams(
        APIViewTest,
        UsesGetMethod,
):
    # NOTE: this view simply returns the request's query params as the response
    url = lambda_fixture(lambda: url_for('views-query-params'))

    # This fixture supports passing query params (e.g. ?key=val) with the requested URL
    query_params = static_fixture({
        'key': 'val',
        'param': 'value',
        'pink': 'floyd',
    })

    def it_passes_query_params(self, json, query_params):
        expected = query_params
        actual = json
        assert expected == actual
class DescribeUserInfo(
    APIViewTest,
    UsesGetMethod,
):
    # NOTE: this view returns the username, first_name, last_name, and email of
    #       the authenticated user.
    url = lambda_fixture(lambda: url_for('authentication-user-info'))


    class CaseAlice(AsUser('alice')):
        def it_returns_alices_info(self, alice, json):
            expected = {
                'username': alice.username,
                'first_name': alice.first_name,
                'last_name': alice.last_name,
                'email': alice.email,
            }
            actual = json
            assert expected == actual


    class CaseBob(AsUser('bob')):
        def it_returns_bobs_info(self, bob, json):
            expected = {
                'username': bob.username,
                'first_name': bob.first_name,
                'last_name': bob.last_name,
                'email': bob.email,
            }
            actual = json
            assert expected == actual


    class CaseAnonymous:
        def it_returns_no_info(self, json):
            # NOTE: AnonymousUser does not define first_name, last_name, or email.
            expected = {'username': ''}
            actual = json
            assert expected == actual
Example #9
0
class DescribeMovieViewSet(ViewSetTest):
    list_url = lambda_fixture(lambda: url_for('movies-list'))
    detail_url = lambda_fixture(
        lambda movie: url_for('movies-detail', pk=movie.pk))

    class DescribeList(
            UsesGetMethod,
            UsesListEndpoint,
            Returns200,
            ReturnsPageNumberPagination,
    ):
        movies = lambda_fixture(
            lambda: Movie.objects.bulk_create([
                Movie(title="Alfred Hitchcock's The Byrds: A Biopic",
                      year=1975),
                Movie(title='Forty-Two Monkeys', year=1997),
            ]),
            autouse=True,
        )

        def it_returns_movies(self, movies, results):
            expected = express_movies(movies)
            actual = results
            assert expected == actual

        class ContextSearch(
                Returns200, ):
            matching_movies = lambda_fixture(
                lambda: Movie.objects.bulk_create([
                    Movie(title='Forty-Two Monkeys', year=1997),
                ]))
            non_matching_movies = lambda_fixture(
                lambda: Movie.objects.bulk_create([
                    Movie(title="Alfred Hitchcock's The Byrds: A Biopic",
                          year=1975),
                ]))
            movies = lambda_fixture(
                lambda matching_movies, non_matching_movies:
                (matching_movies + non_matching_movies),
                autouse=True,
            )

            query_params = static_fixture({
                'q': 'monkey',
            })

            def it_returns_only_matching_movies(self, matching_movies,
                                                results):
                expected = express_movies(matching_movies)
                actual = results
                assert expected == actual

    class DescribeRetrieve(
            UsesGetMethod,
            UsesDetailEndpoint,
            Returns200,
    ):
        movie = lambda_fixture(lambda: Movie.objects.create(
            title='The Muffin Man',
            year=2038,
        ))

        def it_returns_movie(self, movie, json):
            expected = express_movie(movie)
            actual = json
            assert expected == actual
Example #10
0
class DescribeKeyValueViewSet(ViewSetTest):
    list_url = lambda_fixture(lambda: url_for('views-key-values-list'))

    detail_url = lambda_fixture(
        lambda key_value: url_for('views-key-values-detail', pk=key_value.pk))

    class DescribeList(
            UsesGetMethod,
            UsesListEndpoint,
            Returns200,
    ):
        # Here, we create some rows in the DB to play with. We set autouse=True,
        # so the fixture is evaluated even though nothing explicitly requests it.
        # The @pytest.mark.late (from pytest-fixture-order) mark ensures our
        # http request is run *after* all autouse fixtures.
        key_values = lambda_fixture(
            lambda: (KeyValue.objects.create_batch(
                alpha='beta',
                delta='gamma',
            )),
            autouse=True,
        )

        def it_returns_key_values_rows(self, key_values, results):
            expected = express_key_values(key_values)
            actual = results
            assert expected == actual

    class DescribeCreate(
            UsesPostMethod,
            UsesListEndpoint,
            Returns201,
    ):
        data = static_fixture({
            'key': 'apple',
            'value': 'π',
        })

        ###
        # precondition_fixture uses the pytest dependency graph to ensure that,
        # if requested, this fixture is *always* evaluated before our HTTP request
        # is made.
        #
        # Here, we record the existing KeyValue IDs, so we can verify that a
        # new row was indeed created by our endpoint.
        #
        initial_key_value_ids = precondition_fixture(
            lambda: set(KeyValue.objects.values_list('pk', flat=True)))

        def it_creates_key_value(self, initial_key_value_ids, json):
            expected = initial_key_value_ids | {json['id']}
            actual = set(KeyValue.objects.values_list('pk', flat=True))
            assert expected == actual

        def it_returns_key_value(self, json):
            key_value = KeyValue.objects.get(pk=json['id'])

            expected = express_key_value(key_value)
            actual = json
            assert expected == actual

        def it_sets_model_fields(self, data, json):
            key_value = KeyValue.objects.get(pk=json['id'])

            expected = data
            assert_model_attrs(key_value, expected)

    class DescribeRetrieve(
            UsesGetMethod,
            UsesDetailEndpoint,
            Returns200,
    ):
        # NOTE: autouse=True is not used, because the detail_url requests this
        #       fixture
        key_value = lambda_fixture(lambda: KeyValue.objects.create(
            key='apple',
            value='π',
        ))

        def it_returns_key_value(self, key_value, json):
            expected = express_key_value(key_value)
            actual = json
            assert expected == actual

    class DescribeUpdate(
            UsesPatchMethod,
            UsesDetailEndpoint,
            Returns200,
    ):
        # NOTE: autouse=True is not used, because the detail_url requests this
        #       fixture
        key_value = lambda_fixture(lambda: KeyValue.objects.create(
            key='apple',
            value='π',
        ))

        data = static_fixture({
            'key': 'banana',
            'value': 'ρ',
        })

        ###
        # precondition_fixture uses the pytest dependency graph to ensure that,
        # if requested, this fixture is *always* evaluated before our HTTP request
        # is made.
        #
        # Here, we record the existing KeyValue IDs, so we can verify that no
        # new rows are created by our endpoint. We request the `key_value` fixture,
        # to ensure it's included in this set.
        #
        initial_key_value_ids = precondition_fixture(lambda key_value: set(
            KeyValue.objects.values_list('pk', flat=True)))

        def it_updates_key_value(self, key_value, data):
            # After updating, refreshing our DB row is vital — otherwise, it
            # will appear as though our endpoint is not doing its job.
            key_value.refresh_from_db()

            expected = data
            assert_model_attrs(key_value, expected)

        def it_returns_key_value(self, key_value, json):
            # After updating, refreshing our DB row is vital — otherwise, it
            # will appear as though our endpoint is not doing its job.
            key_value.refresh_from_db()

            expected = express_key_value(key_value)
            actual = json
            assert expected == actual

        def it_doesnt_create_or_destroy_rows(self, initial_key_value_ids):
            expected = initial_key_value_ids
            actual = set(KeyValue.objects.values_list('pk', flat=True))
            assert expected == actual

    class DescribeDestroy(
            UsesDeleteMethod,
            UsesDetailEndpoint,
            Returns204,
    ):
        # NOTE: autouse=True is not used, because the detail_url requests this
        #       fixture
        key_value = lambda_fixture(lambda: KeyValue.objects.create(
            key='apple',
            value='π',
        ))

        ###
        # precondition_fixture uses the pytest dependency graph to ensure that,
        # if requested, this fixture is *always* evaluated before our HTTP request
        # is made.
        #
        # Here, we record the existing KeyValue IDs, so we can verify that our
        # endpoint actually deletes the row
        #
        initial_key_value_ids = precondition_fixture(
            lambda: set(KeyValue.objects.values_list('pk', flat=True)))

        def it_deletes_key_value(self, key_value, initial_key_value_ids):
            expected = initial_key_value_ids - {key_value.id}
            actual = set(KeyValue.objects.values_list('pk', flat=True))
            assert expected == actual
Example #11
0
class DescribeStatusCode(
        APIViewTest,
        UsesGetMethod,
):
    # Status code to be returned from view.
    # This will be overridden in child test contexts.
    status_code = not_implemented_fixture()

    url = lambda_fixture(
        lambda status_code: url_for('status-code', code=status_code))

    class Case200(Returns200):
        status_code = static_fixture(200)

    class Case201(Returns201):
        status_code = static_fixture(201)

    class Case202(Returns202):
        status_code = static_fixture(202)

    class Case204(Returns204):
        status_code = static_fixture(204)

    class Case301(Returns301):
        status_code = static_fixture(301)

    class Case302(Returns302):
        status_code = static_fixture(302)

    class Case304(Returns304):
        status_code = static_fixture(304)

    class Case307(Returns307):
        status_code = static_fixture(307)

    class Case308(Returns308):
        status_code = static_fixture(308)

    class Case400(Returns400):
        status_code = static_fixture(400)

    class Case401(Returns401):
        status_code = static_fixture(401)

    class Case403(Returns403):
        status_code = static_fixture(403)

    class Case404(Returns404):
        status_code = static_fixture(404)

    class Case405(Returns405):
        status_code = static_fixture(405)

    class Case409(Returns409):
        status_code = static_fixture(409)

    class Case422(Returns422):
        status_code = static_fixture(422)

    class Case429(Returns429):
        status_code = static_fixture(429)

    class Case500(Returns500):
        status_code = static_fixture(500)

    class Case503(Returns503):
        status_code = static_fixture(503)

    class Case504(Returns504):
        status_code = static_fixture(504)

    class CaseArbitrary(ReturnsStatus(599)):
        status_code = static_fixture(599)