def test_serializer_embed_with_missing_relations(drf_request): """Prove that the serializer can embed data (for the detail page)""" cursor = connection.cursor() cursor.execute( "INSERT INTO test_rest_framework_dso_movie (name, category_id) VALUES ('Test', 333);" ) try: movie = Movie.objects.get(name="Test") serializer = MovieSerializer( Movie.objects.all(), many=True, fields_to_expand=["category"], context={"request": drf_request}, ) data = normalize_data(serializer.data) assert data == { "movie": [{ "name": "Test", "category_id": movie.category_id, "date_added": None }], "category": [], } finally: # Make sure the cleanup happens or unit tests report this error # instead of the actual assertion error. cursor.execute( "DELETE FROM test_rest_framework_dso_movie WHERE category_id=333")
def test_serializer_many(drf_request, movie): """Prove that the serializer can embed data (for the detail page)""" serializer = MovieSerializer( Movie.objects.all(), many=True, fields_to_expand=["actors", "category"], context={"request": drf_request}, ) data = normalize_data(serializer.data) assert data == { "movie": [{ "name": "foo123", "category_id": movie.category_id, "date_added": None }], "actors": [ { "name": "John Doe" }, { "name": "Jane Doe" }, ], "category": [{ "name": "bar" }], }
def test_location_transform_input(drf_request, location): """Prove that the serializer transforms crs, even when it's (remote) dictionary input.""" drf_request.accept_crs = WGS84 # Force WGS84 serializer = LocationSerializer( data={ "geometry": { "type": "Point", "coordinates": [10, 10] }, # GeoJSON data }, context={ "request": drf_request, "content_crs": RD_NEW, }, ) assert serializer.is_valid(), serializer.errors data = normalize_data(serializer.data) # Tell that the input data is correctly transformed into WGS84, # despite not having CRS defined in the input 'data'. # The serializer read the content_crs for this. rounder = lambda p: [round(c, 6) for c in p] assert rounder(data["geometry"]["coordinates"]) == [3.313688, 47.974858] # Serializer assigned 'response_content_crs' (used accept_crs) assert drf_request.response_content_crs == WGS84
def test_serializer_single(drf_request, movie): """Prove that the serializer can embed data (for the detail page)""" serializer = MovieSerializer(instance=movie, fields_to_expand=["actors", "category"], context={"request": drf_request}) data = normalize_data(serializer.data) assert data == { "name": "foo123", "category_id": movie.category_id, "date_added": None, "_embedded": { "actors": [ { "name": "John Doe" }, { "name": "Jane Doe" }, ], "category": { "name": "bar" }, }, }
def test_expand(afval_container_model, afval_cluster): """Prove expanding works. The _embedded section is generated, using the cluster serializer. """ drf_request = to_drf_request(api_request_with_scopes(["BAG/R"])) ContainerSerializer = serializer_factory(afval_container_model) afval_container = afval_container_model.objects.create( id=2, cluster=afval_cluster) # Prove that expands work on object-detail level container_serializer = ContainerSerializer( afval_container, context={"request": drf_request}, fields_to_expand=["cluster"], ) data = normalize_data(container_serializer.data) assert data == { "_links": { "schema": "https://schemas.data.amsterdam.nl/datasets/afvalwegingen/dataset#containers", # noqa: E501 "self": { "href": "http://testserver/v1/afvalwegingen/containers/2/", "title": "2", "id": 2, }, "cluster": { "href": "http://testserver/v1/afvalwegingen/clusters/123.456/", "title": "123.456", "id": "123.456", }, }, "id": 2, "clusterId": "123.456", "serienummer": None, "datumCreatie": None, "datumLeegmaken": None, "geometry": None, "eigenaarNaam": None, "_embedded": { "cluster": { "_links": { "self": { "href": "http://testserver/v1/afvalwegingen/clusters/123.456/", "title": "123.456", "id": "123.456", }, "schema": "https://schemas.data.amsterdam.nl/datasets/afvalwegingen/dataset#clusters", # noqa: E501 }, "id": "123.456", "status": "open", } }, }
def test_location(drf_request, location): """Prove that the serializer recorgnizes crs""" serializer = LocationSerializer( instance=location, fields_to_expand=[], context={"request": drf_request}, ) data = normalize_data(serializer.data) assert data["geometry"]["coordinates"] == [10.0, 10.0] # Serializer assigned 'response_content_crs' (auto detected) assert drf_request.response_content_crs == RD_NEW
def test_backwards_relation(drf_request, gebieden_models): """Show backwards""" drf_request.table_temporal_slice = None stadsdelen_model = gebieden_models["stadsdelen"] wijken_model = gebieden_models["wijken"] stadsdeel = stadsdelen_model.objects.create(id="0363.1", identificatie="0363", naam="Stadsdeel", volgnummer=1) wijken_model.objects.create( id="03630000000001.1", identificatie="03630000000001", volgnummer=1, ligt_in_stadsdeel=stadsdeel, ) StadsdelenSerializer = serializer_factory(stadsdelen_model) stadsdelen_serializer = StadsdelenSerializer( stadsdeel, context={"request": drf_request}, ) data = normalize_data(stadsdelen_serializer.data) assert data == { "_links": { "self": { "href": "http://testserver/v1/gebieden/stadsdelen/0363/?volgnummer=1", "title": "0363.1", "volgnummer": 1, "identificatie": "0363", }, "schema": "https://schemas.data.amsterdam.nl/datasets/gebieden/dataset#stadsdelen", # NoQA "wijken": [{ "href": "http://testserver/v1/gebieden/wijken/03630000000001/?volgnummer=1", # NoQA "title": "03630000000001.1", "volgnummer": 1, "identificatie": "03630000000001", }], }, "id": "0363.1", "naam": "Stadsdeel", "code": None, "eindGeldigheid": None, "beginGeldigheid": None, "registratiedatum": None, "documentdatum": None, "documentnummer": None, "geometrie": None, }
def test_expand_broken_relation(afval_container_model): """Prove that expanded non-existent FK values are not rendered but also don't cause the serializer to crash. The _embedded part has a None value instead. """ drf_request = to_drf_request(api_request_with_scopes(["BAG/R"])) ContainerSerializer = serializer_factory(afval_container_model) container_invalid_cluster = afval_container_model.objects.create( id=4, cluster_id=99, ) container_serializer = ContainerSerializer( container_invalid_cluster, context={"request": drf_request}, fields_to_expand=["cluster"], ) data = normalize_data(container_serializer.data) assert data == { "_links": { "self": { "href": "http://testserver/v1/afvalwegingen/containers/4/", "title": "4", "id": 4, }, "schema": "https://schemas.data.amsterdam.nl/datasets/afvalwegingen/dataset#containers", # noqa: E501 }, "id": 4, "clusterId": 99, "serienummer": None, "datumCreatie": None, "datumLeegmaken": None, "geometry": None, "eigenaarNaam": None, "_embedded": { "cluster": None }, }
def test_expand_none(afval_container_model): """Prove that expanding None values doesn't crash. The _embedded part has a None value instead. """ drf_request = to_drf_request(api_request_with_scopes(["BAG/R"])) ContainerSerializer = serializer_factory(afval_container_model) container_without_cluster = afval_container_model.objects.create( id=3, cluster=None, ) container_serializer = ContainerSerializer( container_without_cluster, context={"request": drf_request}, fields_to_expand=["cluster"], ) data = normalize_data(container_serializer.data) assert data == { "_links": { "schema": "https://schemas.data.amsterdam.nl/datasets/afvalwegingen/dataset#containers", # noqa: E501 "self": { "href": "http://testserver/v1/afvalwegingen/containers/3/", "title": "3", "id": 3, }, }, "id": 3, "clusterId": None, "serienummer": None, "datumCreatie": None, "datumLeegmaken": None, "geometry": None, "eigenaarNaam": None, "_embedded": { "cluster": None }, }
def test_location_transform(drf_request, location): """Prove that the serializer transforms crs""" drf_request.accept_crs = WGS84 serializer = LocationSerializer( instance=location, fields_to_expand=[], context={"request": drf_request}, ) data = normalize_data(serializer.data) # The lat/lon ordering that is used by the underlying GDAL library, # should always be consistent. (so axis ordering of GDAL 3 does not matter). # # From: https://gdal.org/tutorials/osr_api_tut.html#crs-and-axis-order # Starting with GDAL 3.0, the axis order mandated by the authority # defining a CRS is by default honoured by the OGRCoordinateTransformation class (...). # Consequently CRS created with the “EPSG:4326” or “WGS84” # strings use the latitude first, longitude second axis order. rounder = lambda p: [round(c, 6) for c in p] assert rounder(data["geometry"]["coordinates"]) == [3.313688, 47.974858] # Serializer assigned 'response_content_crs' (used accept_crs) assert drf_request.response_content_crs == WGS84
def test_serializer_has_nested_table(drf_request, parkeervakken_parkeervak_model, parkeervakken_regime_model): """Prove that the serializer factory properly generates nested tables. Serialiser should contain reverse relations. """ parkeervak = parkeervakken_parkeervak_model.objects.create( id="121138489047", type="File", soort="MULDER", aantal=1.0, e_type="E9", buurtcode="A05d", straatnaam="Zoutkeetsgracht", ) parkeervakken_regime_model.objects.create( id=1, parent=parkeervak, bord="", dagen=["ma", "di", "wo", "do", "vr", "za", "zo"], soort="MULDER", aantal=None, e_type="E6b", kenteken="69-SF-NT", opmerking="", eindtijd="23:59:00", begintijd="00:00:00", einddatum=None, begindatum=None, ) ParkeervakSerializer = serializer_factory( parkeervakken_parkeervak_model) # Prove that no reverse relation to containers here. assert "regimes" in ParkeervakSerializer._declared_fields # Prove that data is serialized with relations. parkeervak_serializer = ParkeervakSerializer( parkeervak, context={"request": drf_request}) data = normalize_data(parkeervak_serializer.data) assert data == { "_links": { "self": { "href": "http://testserver/v1/parkeervakken/parkeervakken/121138489047/", "id": "121138489047", }, "schema": "https://schemas.data.amsterdam.nl/datasets/parkeervakken/dataset#parkeervakken", # noqa: E501 }, "geometry": None, "id": "121138489047", "type": "File", "soort": "MULDER", "aantal": 1.0, "eType": "E9", "buurtcode": "A05d", "straatnaam": "Zoutkeetsgracht", "volgnummer": None, "regimes": [{ "bord": "", "dagen": ["ma", "di", "wo", "do", "vr", "za", "zo"], "soort": "MULDER", "aantal": None, "eType": "E6b", "kenteken": "69-SF-NT", "eindtijd": "23:59:00", "opmerking": "", "begintijd": "00:00:00", "einddatum": None, "begindatum": None, }], }
def test_basic_factory_logic( drf_request, afval_schema, afval_cluster_model, afval_container_model, afval_cluster, filled_router, ): """Prove that the serializer factory properly generates the embedded fields. This checks whether the factory generates the proper FK/embedded fields. """ # Access real models to perform 'is' test below. afval_cluster_model = unlazy(afval_cluster_model) afval_container_model = unlazy(afval_container_model) # Confirm that the model is the object that Django also has registered # (if this differs, create_tables() might be called twice). assert afval_cluster_model is apps.get_model("afvalwegingen.clusters") assert afval_container_model is apps.get_model( "afvalwegingen.containers") afval_container = afval_container_model.objects.create( id=2, cluster_id=afval_cluster.pk, serienummer="serie123", eigenaar_naam="datapunt", datum_creatie=date(2020, 2, 3), ) # Generate serializers from models ContainerSerializer = serializer_factory(afval_container_model) ClusterSerializer = serializer_factory(afval_cluster_model) # Prove that EmbeddedField is created. assert set( ContainerSerializer.Meta.embedded_fields.keys()) == {"cluster"} embedded_field: EmbeddedField = ContainerSerializer.Meta.embedded_fields[ "cluster"] assert isinstance(embedded_field, EmbeddedField) # Prove that the EmbeddedField references the proper models and serializers. # This also tests whether there aren't any old references left. assert embedded_field.related_model is afval_cluster_model, ( "Old Django models were still referenced: " f"id {id(embedded_field.related_model)} vs " f"id {id(afval_cluster_model)} " f"(creation counter {embedded_field.related_model.CREATION_COUNTER}" f" vs {afval_cluster_model.CREATION_COUNTER})", ) assert embedded_field.serializer_class.__name__ == ClusterSerializer.__name__ # Prove that data is serialized with relations. # Both the cluster_id field and 'cluster' field are generated. container_serializer = ContainerSerializer( afval_container, context={"request": drf_request}) data = normalize_data(container_serializer.data) assert data == { "_links": { "cluster": { "href": "http://testserver/v1/afvalwegingen/clusters/123.456/", "title": "123.456", "id": "123.456", }, "schema": "https://schemas.data.amsterdam.nl/datasets/afvalwegingen/dataset#containers", # noqa: E501 "self": { "href": "http://testserver/v1/afvalwegingen/containers/2/", "title": "2", "id": 2, }, }, "clusterId": "123.456", "datumCreatie": "2020-02-03", "datumLeegmaken": None, "eigenaarNaam": "datapunt", "geometry": None, "id": 2, "serienummer": "serie123", }
def test_multiple_backwards_relations( drf_request, vestiging_adres_model, vestiging_vestiging_model, vestiging1, vestiging2, post_adres1, ): """Show backwards""" VestigingSerializer = serializer_factory(vestiging_vestiging_model) vestiging_serializer = VestigingSerializer( vestiging1, context={"request": drf_request}, ) data = normalize_data(vestiging_serializer.data) assert data == { "_links": { "self": { "href": "http://testserver/v1/vestiging/vestiging/1/", "title": "1", "id": 1, }, "schema": "https://schemas.data.amsterdam.nl/datasets/vestiging/dataset#vestiging", # noqa: E501 "postAdres": { "href": "http://testserver/v1/vestiging/adres/3/", "title": "3", "id": 3, }, "bezoekAdres": { "href": "http://testserver/v1/vestiging/adres/1/", "title": "1", "id": 1, }, }, "id": 1, "naam": "Snake Oil", "postAdresId": 3, "bezoekAdresId": 1, } vestiging_serializer = VestigingSerializer( vestiging2, context={"request": drf_request}, ) data = normalize_data(vestiging_serializer.data) assert data == { "_links": { "self": { "href": "http://testserver/v1/vestiging/vestiging/2/", "title": "2", "id": 2, }, "schema": "https://schemas.data.amsterdam.nl/datasets/vestiging/dataset#vestiging", # noqa: E501 "postAdres": { "href": "http://testserver/v1/vestiging/adres/3/", "title": "3", "id": 3, }, "bezoekAdres": { "href": "http://testserver/v1/vestiging/adres/2/", "title": "2", "id": 2, }, }, "id": 2, "naam": "Haarlemmer olie", "postAdresId": 3, "bezoekAdresId": 2, } AdresSerializer = serializer_factory(vestiging_adres_model) adres_serializer = AdresSerializer( post_adres1, context={"request": drf_request}, ) data = normalize_data(adres_serializer.data) assert data == { "_links": { "schema": "https://schemas.data.amsterdam.nl/datasets/vestiging/dataset#adres", "self": { "href": "http://testserver/v1/vestiging/adres/3/", "title": "3", "id": 3, }, "vestigingenPost": [ { "href": "http://testserver/v1/vestiging/vestiging/1/", "title": "1", "id": 1, }, { "href": "http://testserver/v1/vestiging/vestiging/2/", "title": "2", "id": 2, }, ], }, "id": 3, "nummer": 1, "plaats": "Amsterdam", "postcode": "1000AA", "straat": "Dam", }
def test_dataset_path( afval_dataset, afval_container_model, afval_cluster, afval_cluster_model, filled_router, ): """Prove dataset url sub paths works. The schema in _links contains correct URLs. """ drf_request = to_drf_request(api_request_with_scopes(["BAG/R"])) afval_dataset.path = "test/" + afval_dataset.path # Update dataset in instance cache afval_container_model._dataset = afval_dataset afval_cluster_model._dataset = afval_dataset ContainerSerializer = serializer_factory(afval_container_model, 0) afval_container = afval_container_model.objects.create( id=2, cluster=afval_cluster) # Prove that expands work on object-detail level container_serializer = ContainerSerializer( afval_container, context={"request": drf_request}, fields_to_expand=["cluster"], ) data = normalize_data(container_serializer.data) assert data == { "_links": { "schema": "https://schemas.data.amsterdam.nl/datasets/test/afvalwegingen/dataset#containers", # noqa: E501 "self": { "href": "http://testserver/v1/afvalwegingen/containers/2/", "title": "2", "id": 2, }, "cluster": { "href": "http://testserver/v1/afvalwegingen/clusters/123.456/", "title": "123.456", "id": "123.456", }, }, "id": 2, "clusterId": "123.456", "serienummer": None, "datumCreatie": None, "datumLeegmaken": None, "geometry": None, "eigenaarNaam": None, "_embedded": { "cluster": { "_links": { "self": { "href": "http://testserver/v1/afvalwegingen/clusters/123.456/", "title": "123.456", "id": "123.456", }, "schema": "https://schemas.data.amsterdam.nl/datasets/test/afvalwegingen/dataset#clusters", # noqa: E501 }, "id": "123.456", "status": "open", } }, }