22Contains integration tests for the `api` app.
33"""
44
5- import urllib
6- import random
75from datetime import datetime
86from pytz import utc
97
2018# api_solr_env
2119# basic_solr_assembler
2220# api_client
21+ # pick_reference_object_having_link
22+ # assert_obj_fields_match_serializer
23+ # get_linked_view_and_objects
24+ # assemble_test_records
25+ # do_filter_search
26+ # get_found_ids
2327
2428
2529# API_ROOT: Base URL for the API we're testing.
@@ -1898,100 +1902,6 @@ def compile_ids(parameters):
18981902 return tuple (p .keys ()[0 ] for p in parameters [1 :])
18991903
19001904
1901- # HELPER FUNCTIONS used in tests
1902-
1903- def pick_reference_object_having_link (objects , link_field ):
1904- """
1905- Test helper function that picks an object (in JSON terms) from the
1906- list of `objects` -- e.g., from an API list view -- and randomly
1907- chooses one that has the given `link_field` populated.
1908- """
1909- choices = [o for o in objects if o ['_links' ].get (link_field , None )]
1910- return random .choice (choices )
1911-
1912-
1913- def assert_obj_fields_match_serializer (obj , serializer ):
1914- """
1915- Test helper function that asserts that the given `obj` conforms to
1916- the given `serializer` -- all fields on the serializer are
1917- represented on the object.
1918- """
1919- for field_name in serializer .fields :
1920- assert serializer .render_field_name (field_name ) in obj
1921-
1922-
1923- def get_linked_view_and_objects (client , ref_obj , link_field ):
1924- """
1925- Test helper function: given a `client` object fixture and
1926- `ref_obj` (i.e. reference object, from the API) -- grab objects
1927- from the given `link_field` and return them. Returns a tuple:
1928- (view_obj, linked_objs). For the sake of normalization, the
1929- returned linked_objs is ALWAYS a list, even if the link references
1930- a single object.
1931- """
1932- linked_objs = []
1933- try :
1934- resp = client .get (ref_obj ['_links' ][link_field ]['href' ])
1935- except TypeError :
1936- for link in ref_obj ['_links' ][link_field ]:
1937- resp = client .get (link ['href' ])
1938- linked_objs .append (resp .data )
1939- else :
1940- try :
1941- linked_objs = resp .data ['_embedded' ].values ()[0 ]
1942- except KeyError :
1943- linked_objs = [resp .data ]
1944- return resp .renderer_context ['view' ], linked_objs
1945-
1946-
1947- def assemble_test_records (profile , id_field , test_data , solr_env , assembler ):
1948- """
1949- Test helper function that assembles & loads a set of test records
1950- given a `profile` string, a set of static `test_data` records, the
1951- name of the `id_field` for each record (for test_data purposes), a
1952- module-level `solr_env` assembler fixture, and a function-level
1953- `assembler` fixture. Returns a tuple of default solr_env records
1954- (the ones loaded by the module-level fixture) and the new test
1955- records that were loaded from the provided test data.
1956- len(env_recs) + len(test_recs) should == the total number of Solr
1957- records for that profile.
1958- """
1959- gens = assembler .gen_factory
1960- env_recs = solr_env .records [profile ]
1961- test_recs = assembler .load_static_test_data (profile , test_data , id_field ,
1962- env_recs )
1963- return (env_recs , test_recs )
1964-
1965-
1966- def do_filter_search (resource , search , client ):
1967- """
1968- Test helper function that performs the given `search` (e.g. search
1969- query string) on the given API `resource` via the given
1970- `api_client` fixture. Returns the response.
1971- """
1972- qs = '&' .join (['=' .join ([urllib .quote_plus (v ) for v in pair .split ('=' )])
1973- for pair in search .split ('&' )])
1974- return client .get ('{}{}/?{}' .format (API_ROOT , resource , qs ))
1975-
1976-
1977- def get_found_ids (solr_id_field , response ):
1978- """
1979- Returns a list of values for identifying test records, in order,
1980- from the given `response` object. (Usually the response will come
1981- from calling `do_filter_search`.) `solr_id_field` is the name of
1982- that ID field as it exists in Solr.
1983- """
1984- serializer = response .renderer_context ['view' ].get_serializer ()
1985- api_id_field = serializer .render_field_name (solr_id_field )
1986- total_found = response .data ['totalCount' ]
1987- data = response .data .get ('_embedded' , {'data' : []}).values ()[0 ]
1988- # reality check: FAIL if there's any data returned on a different
1989- # page of results. If we don't return ALL available data, further
1990- # assertions will be invalid.
1991- assert len (data ) == total_found
1992- return [r [api_id_field ] for r in data ]
1993-
1994-
19951905# PYTEST FIXTURES
19961906
19971907@pytest .fixture
@@ -2018,7 +1928,8 @@ def api_settings(settings):
20181928
20191929@pytest .mark .django_db
20201930def test_apiusers_authenticated_requests (api_client ,
2021- simple_sig_auth_credentials ):
1931+ simple_sig_auth_credentials ,
1932+ assert_obj_fields_match_serializer ):
20221933 """
20231934 The apiusers resource requires authentication to access; users that
20241935 can authenticate can view the apiusers list and details of a single
@@ -2109,7 +2020,9 @@ def test_apiusers_repeated_requests_fail(api_client,
21092020
21102021
21112022@pytest .mark .parametrize ('resource' , RESOURCE_METADATA .keys ())
2112- def test_standard_resource (resource , api_settings , api_solr_env , api_client ):
2023+ def test_standard_resource (resource , api_settings , api_solr_env , api_client ,
2024+ pick_reference_object_having_link ,
2025+ assert_obj_fields_match_serializer ):
21132026 """
21142027 Standard resources (each with a "list" and "detail" view) should
21152028 have objects available in an "_embedded" object in the list view,
@@ -2131,7 +2044,10 @@ def test_standard_resource(resource, api_settings, api_solr_env, api_client):
21312044@pytest .mark .parametrize ('resource, links' ,
21322045 compile_resource_links (RESOURCE_METADATA ))
21332046def test_standard_resource_links (resource , links , api_settings , api_solr_env ,
2134- api_client ):
2047+ api_client ,
2048+ pick_reference_object_having_link ,
2049+ assert_obj_fields_match_serializer ,
2050+ get_linked_view_and_objects ):
21352051 """
21362052 Accessing linked resources from standard resources (via _links)
21372053 should return the expected resource(s).
@@ -2263,7 +2179,8 @@ def test_list_view_pagination(resource, default_limit, max_limit, limit,
22632179 ids = compile_ids (PARAMETERS__FILTER_TESTS__INTENDED ) +
22642180 compile_ids (PARAMETERS__FILTER_TESTS__STRANGE ))
22652181def test_list_view_filters (resource , test_data , search , expected , api_settings ,
2266- api_solr_env , basic_solr_assembler , api_client ):
2182+ assemble_test_records , api_client , get_found_ids ,
2183+ do_filter_search ):
22672184 """
22682185 Given the provided `test_data` records: requesting the given
22692186 `resource` using the provided search filter parameters (`search`)
@@ -2276,15 +2193,15 @@ def test_list_view_filters(resource, test_data, search, expected, api_settings,
22762193
22772194 profile = RESOURCE_METADATA [resource ]['profile' ]
22782195 id_field = RESOURCE_METADATA [resource ]['id_field' ]
2279- erecs , trecs = assemble_test_records (profile , id_field , test_data ,
2280- api_solr_env , basic_solr_assembler )
2196+ erecs , trecs = assemble_test_records (profile , id_field , test_data )
22812197
22822198 # First let's do a quick sanity check to make sure the resource
22832199 # returns the correct num of records before the filter is applied.
2284- check_response = api_client .get ('{}{}/' .format (API_ROOT , resource ))
2200+ full_resource_path = '{}{}' .format (API_ROOT , resource )
2201+ check_response = api_client .get ('{}/' .format (full_resource_path ))
22852202 assert check_response .data ['totalCount' ] == len (erecs ) + len (trecs )
22862203
2287- response = do_filter_search (resource , search , api_client )
2204+ response = do_filter_search (full_resource_path , search , api_client )
22882205 found_ids = set (get_found_ids (id_field , response ))
22892206 assert all ([i in found_ids for i in expected_ids ])
22902207 assert all ([i not in found_ids for i in not_expected_ids ])
@@ -2296,7 +2213,8 @@ def test_list_view_filters(resource, test_data, search, expected, api_settings,
22962213 ids = compile_ids (PARAMETERS__ORDERBY_TESTS__INTENDED ) +
22972214 compile_ids (PARAMETERS__ORDERBY_TESTS__STRANGE ))
22982215def test_list_view_orderby (resource , test_data , search , expected , api_settings ,
2299- api_solr_env , basic_solr_assembler , api_client ):
2216+ assemble_test_records , api_client , get_found_ids ,
2217+ do_filter_search ):
23002218 """
23012219 Given the provided `test_data` records: requesting the given
23022220 `resource` using the provided search filter parameters (`search`)
@@ -2305,10 +2223,10 @@ def test_list_view_orderby(resource, test_data, search, expected, api_settings,
23052223 """
23062224 profile = RESOURCE_METADATA [resource ]['profile' ]
23072225 id_field = RESOURCE_METADATA [resource ]['id_field' ]
2308- erecs , trecs = assemble_test_records (profile , id_field , test_data ,
2309- api_solr_env , basic_solr_assembler )
2226+ erecs , trecs = assemble_test_records (profile , id_field , test_data )
23102227 print [r .get ('call_number_sort' , None ) for r in trecs ]
2311- response = do_filter_search (resource , search , api_client )
2228+ full_resource_path = '{}{}' .format (API_ROOT , resource )
2229+ response = do_filter_search (full_resource_path , search , api_client )
23122230 found_ids = get_found_ids (id_field , response )
23132231 assert found_ids == expected
23142232
@@ -2317,8 +2235,8 @@ def test_list_view_orderby(resource, test_data, search, expected, api_settings,
23172235 compile_params (PARAMETERS__FIRSTITEMPERLOCATION ),
23182236 ids = compile_ids (PARAMETERS__FIRSTITEMPERLOCATION ))
23192237def test_firstitemperlocation_list (test_data , search , expected , api_settings ,
2320- api_solr_env , basic_solr_assembler ,
2321- api_client ):
2238+ assemble_test_records , api_client ,
2239+ get_found_ids , do_filter_search ):
23222240 """
23232241 The `firstitemperlocation` resource is basically a custom filter
23242242 for `items` that submits a facet-query to Solr asking for the first
@@ -2339,10 +2257,10 @@ def test_firstitemperlocation_list(test_data, search, expected, api_settings,
23392257 for resource in data .keys ():
23402258 profile = RESOURCE_METADATA [resource ]['profile' ]
23412259 id_field = RESOURCE_METADATA [resource ]['id_field' ]
2342- assemble_test_records (profile , id_field , data [resource ], api_solr_env ,
2343- basic_solr_assembler )
2260+ assemble_test_records (profile , id_field , data [resource ])
23442261
2345- rsp = do_filter_search ('firstitemperlocation' , search , api_client )
2262+ full_resource_path = '{}firstitemperlocation' .format (API_ROOT )
2263+ rsp = do_filter_search (full_resource_path , search , api_client )
23462264 found_ids = set (get_found_ids (RESOURCE_METADATA ['items' ]['id_field' ], rsp ))
23472265 assert all ([i in found_ids for i in expected_ids ])
23482266 assert all ([i not in found_ids for i in not_expected_ids ])
@@ -2352,8 +2270,8 @@ def test_firstitemperlocation_list(test_data, search, expected, api_settings,
23522270 compile_params (PARAMETERS__CALLNUMBERMATCHES ),
23532271 ids = compile_ids (PARAMETERS__CALLNUMBERMATCHES ))
23542272def test_callnumbermatches_list (test_data , search , expected , api_settings ,
2355- api_solr_env , basic_solr_assembler ,
2356- api_client ):
2273+ assemble_test_records , api_client ,
2274+ do_filter_search ):
23572275 """
23582276 The `callnumbermatches` resource simply returns an array of
23592277 callnumber strings, in order, matching the critera that's given.
@@ -2369,9 +2287,9 @@ def test_callnumbermatches_list(test_data, search, expected, api_settings,
23692287 for resource in data .keys ():
23702288 profile = RESOURCE_METADATA [resource ]['profile' ]
23712289 id_field = RESOURCE_METADATA [resource ]['id_field' ]
2372- assemble_test_records (profile , id_field , data [resource ], api_solr_env ,
2373- basic_solr_assembler )
2290+ assemble_test_records (profile , id_field , data [resource ])
23742291
2375- response = do_filter_search ('callnumbermatches' , search , api_client )
2292+ full_resource_path = '{}callnumbermatches' .format (API_ROOT )
2293+ response = do_filter_search (full_resource_path , search , api_client )
23762294 assert response .data == expected
23772295
0 commit comments