def test_several_providers(client, django_assert_num_queries): """Two providers this time.""" provider1 = factories.Provider(base_api_url="http://provider1") device1 = factories.Device.build(provider=provider1) expected_event1 = factories.EventRecord.build( event_type=enums.EVENT_TYPE.rebalance_drop_off.name) provider2 = factories.Provider(base_api_url="http://provider2") device2 = factories.Device.build(provider=provider2) expected_event2 = factories.EventRecord.build( event_type=enums.EVENT_TYPE.trip_start.name) stdout, stderr = io.StringIO(), io.StringIO() n = 1 # List of providers n += 2 # List of provider IDs (for each provider) n += 2 # List of device IDs (for each provider) n += ( 2 # Savepoint/release for each provider + 1 # Insert missing devices + 1 # Insert fake register event + 1 # Insert missing event records + 1 # Update last start time polled ) * 2 # For each provider with django_assert_num_queries(n): with requests_mock.Mocker() as m: m.get( urllib.parse.urljoin(provider1.base_api_url, "/status_changes"), json=make_response( provider1, device1, expected_event1, event_type_reason="rebalance_drop_off", ), ) m.get( urllib.parse.urljoin(provider2.base_api_url, "/status_changes"), json=make_response(provider2, device2, expected_event2, event_type_reason="maintenance"), ) call_command("poll_providers", "--raise-on-error", stdout=stdout, stderr=stderr) assert_command_success(stdout, stderr) event1_register, event1_regular = device1.event_records.order_by( "timestamp") assert event1_register.event_type == enums.EVENT_TYPE.register.name assert event1_register.properties == {"created_on_register": True} assert_event_equal(event1_regular, expected_event1) event2_register, event2_regular = device2.event_records.order_by( "timestamp") assert event2_register.event_type == enums.EVENT_TYPE.register.name assert event2_register.properties == {"created_on_register": True} assert_event_equal(event2_regular, expected_event2)
def test_device_list_basic(client, django_assert_num_queries): now = timezone.now() uuid1 = "aaaaaaa1-1342-413b-8e89-db802b2f83f6" uuid2 = "ccccccc3-1342-413b-8e89-db802b2f83f6" provider = factories.Provider(name="Test provider") provider2 = factories.Provider(name="Test another provider") device1 = factories.Device( id=uuid1, provider=provider, identification_number="1AAAAA", model="Testa_Model_S", category="car", propulsion=["combustion"], registration_date=now, dn_status="available", dn_gps_point="Point(40 15.0)", dn_gps_timestamp=now, dn_battery_pct=0.5, ) device2 = factories.Device( id=uuid2, provider=provider2, identification_number="3CCCCC", model="Testa_Model_X", category="scooter", propulsion=["electric"], registration_date=now, dn_status="unavailable", dn_gps_point=None, dn_gps_timestamp=None, dn_battery_pct=None, ) # Add an event on the first device factories.EventRecord( device=device1, timestamp=now, event_type=enums.EVENT_TYPE.maintenance.name, properties={ "trip_id": "b3da2d46-065f-4036-903c-49d796f09357", "telemetry": { "timestamp": 1_325_376_000_000, "gps": {"lat": 33.996_339, "lng": -118.48153}, }, }, )
def test_poll_provider_v0_4_lag(client, requests_mock): # Note: testing with the default "POLLER_CREATE_REGISTER_EVENTS = False" # Below the lag threshold last_event_time_polled = timezone.now() - datetime.timedelta(minutes=30) provider = factories.Provider( base_api_url="http://provider", api_configuration__api_version=enums.MDS_VERSIONS.v0_4.name, api_configuration__provider_polling_lag="PT1H", # One hour last_event_time_polled=last_event_time_polled, ) stdout, stderr = io.StringIO(), io.StringIO() # No endpoint should be called requests_mock.get( urllib.parse.urljoin(provider.base_api_url, "/events"), status_code=400, ) requests_mock.get( urllib.parse.urljoin(provider.base_api_url, "/status_changes"), status_code=400, ) call_command("poll_providers", "--raise-on-error", stdout=stdout, stderr=stderr) assert_command_success(stdout, stderr) # The last poller cursor is NOT updated provider = models.Provider.objects.get(pk=provider.pk) assert provider.last_event_time_polled == last_event_time_polled # No device created assert models.Device.objects.count() == 0 # No event created assert models.EventRecord.objects.count() == 0
def test_device_event_inverted_coordinates(client): provider = factories.Provider( id=uuid.UUID("aaaa0000-61fd-4cce-8113-81af1de90942")) device_id = uuid.UUID("bbbb0000-61fd-4cce-8113-81af1de90942") device = factories.Device(id=device_id, provider=provider) data = { "event_type": "service_end", "telemetry": { "device_id": str(device_id), "timestamp": 1_325_376_000_000, "gps": { "lat": -118.279_678, # Not within [-90 90] "lng": 34.07068, # This is the latitude "altitude": 30.0, "heading": 245.2, "speed": 32.3, "hdop": 2.0, "satellites": 6, }, "charge": 0.54, }, "timestamp": 1_325_376_000_000, "trip_id": None, }
def test_device_event(client): provider = factories.Provider( id=uuid.UUID("aaaa0000-61fd-4cce-8113-81af1de90942")) device_id = uuid.UUID("bbbb0000-61fd-4cce-8113-81af1de90942") device = factories.Device(id=device_id, provider=provider) data = { "event_type": "service_end", "telemetry": { "device_id": str(device_id), "timestamp": 1_325_376_000_000, "gps": { "lat": 0.0, "lng": 3.0, "altitude": 30.0, "heading": 245.2, "speed": 32.3, "hdop": 2.0, "satellites": 6, }, "charge": 0.54, }, "timestamp": 1_325_376_000_000, "trip_id": None, }
def test_device_register(client): provider = factories.Provider( id=uuid.UUID("aaaa0000-61fd-4cce-8113-81af1de90942")) device_id = uuid.UUID("bbbb0000-61fd-4cce-8113-81af1de90942") assert models.Device.objects.count() == 0 data = { "device_id": str(device_id), "vehicle_id": "foo", "type": "scooter", "propulsion": ["electric"], "year": 2012, "mfgr": "Toto inc", "model": "IDFX 3000", } # Test auth response = client.post(reverse("agency:device-list"), data=data, content_type="application/json") assert response.status_code == 401 response = client.post( reverse("agency:device-list"), data=data, content_type="application/json", **auth_header(SCOPE_AGENCY_API, provider_id=provider.id), ) assert response.status_code == 201 assert response.data == {} device = models.Device.objects.get() # Also tests unicity assert device.provider == provider
def test_with_device_categories(): provider = factories.Provider() factories.Device.create_batch(3, category="bicycle", provider=provider) factories.Device.create_batch(2, category="scooter", provider=provider) factories.Device.create_batch(1, category="car", provider=provider) provider = models.Provider.objects.with_device_categories().get() assert provider.device_categories == {"bicycle": 3, "scooter": 2, "car": 1}
def test_poll_provider_batch(client, settings, requests_mock): """A single provider with two pages of status changes.""" settings.POLLER_CREATE_REGISTER_EVENTS = True provider = factories.Provider(base_api_url="http://provider") # The first device received already exists device1 = factories.Device(provider=provider) expected_event1 = factories.EventRecord.build( event_type=enums.EVENT_TYPE.service_start.name, properties__trip_id="e7a9d3aa-68ea-4666-8adf-7bad40e49805", ) # The second device received is unknown expected_device2 = factories.Device.build() expected_event2 = factories.EventRecord.build( event_type=enums.EVENT_TYPE.trip_end.name) stdout, stderr = io.StringIO(), io.StringIO() url = urllib.parse.urljoin(provider.base_api_url, "/status_changes") next_page = "%s?page=2" % url requests_mock.get( url, json=make_response( provider, device1, expected_event1, event_type_reason="service_start", associated_trip="e7a9d3aa-68ea-4666-8adf-7bad40e49805", next_page=next_page, ), ) requests_mock.get( next_page, json=make_response( provider, expected_device2, expected_event2, event_type_reason="maintenance_pick_up", ), ) call_command("poll_providers", "--raise-on-error", stdout=stdout, stderr=stderr) assert_command_success(stdout, stderr) event1 = device1.event_records.get() assert_event_equal(event1, expected_event1) # The second device was created on the fly device2 = models.Device.objects.get(pk=expected_device2.pk) assert device2.saved_at is not None # With a fake register event and the actual event event2_register, event2_regular = device2.event_records.order_by( "timestamp") assert event2_register.event_type == enums.EVENT_TYPE.register.name assert event2_register.properties == {"created_on_register": True} assert_event_equal(event2_regular, expected_event2) assert_device_equal(device2, expected_device2)
def test_poll_provider_v0_4_realtime(client, requests_mock): # Note: testing with the default "POLLER_CREATE_REGISTER_EVENTS = False" # This time we didn't poll long ago last_event_time_polled = timezone.now() - datetime.timedelta(3) provider = factories.Provider( base_api_url="http://provider", api_configuration__api_version=enums.MDS_VERSIONS.v0_4.name, last_event_time_polled=last_event_time_polled, ) # We're polling from zero, nothing already exists in the DB expected_device = factories.Device.build() expected_event = factories.EventRecord.build( event_type=enums.EVENT_TYPE.service_start.name, ) stdout, stderr = io.StringIO(), io.StringIO() def events_callback(request, context): """Check the query parameters""" # Start time is were the poller stopped last time start_time = utils.from_mds_timestamp(int(request.qs["start_time"][0])) assert almost_equal(start_time, last_event_time_polled) # End time is after start time but valued "now()" when the poller was running end_time = utils.from_mds_timestamp(int(request.qs["end_time"][0])) assert end_time > start_time assert almost_equal(end_time, timezone.now(), precision=datetime.timedelta(seconds=1)) context.status_code = 200 return make_response( provider, expected_device, expected_event, event_type_reason="service_start", version="0.4.0", ) events = urllib.parse.urljoin(provider.base_api_url, "/events") requests_mock.get(events, json=events_callback) # Mocking must fail if we query the archives endpoint instead requests_mock.get( urllib.parse.urljoin(provider.base_api_url, "/status_changes"), status_code=400, ) call_command("poll_providers", "--raise-on-error", stdout=stdout, stderr=stderr) assert_command_success(stdout, stderr) # The last poller cursor is updated provider = models.Provider.objects.get(pk=provider.pk) assert provider.last_event_time_polled != last_event_time_polled # The device was created on the fly device = models.Device.objects.get(pk=expected_device.pk) assert device.saved_at is not None # The actual event event = device.event_records.get() assert event.event_type == enums.EVENT_TYPE.service_start.name assert_event_equal(event, expected_event) assert_device_equal(device, expected_device)
def test_areas_metadata(client): provider = factories.Provider(name="Test provider") response = client.options( reverse("agency-0.3:area-list"), **auth_header(SCOPE_AGENCY_API, provider_id=provider.id), ) assert response.status_code == 200 assert response._headers["allow"][1] == "GET, HEAD, OPTIONS"
def test_poll_provider_v0_4_archives_resume(client, requests_mock): # Note: testing with the default "POLLER_CREATE_REGISTER_EVENTS = False" last_event_time_polled = datetime.datetime(2019, 10, 16, 14, 40, 35, tzinfo=timezone.utc) provider = factories.Provider( base_api_url="http://provider", api_configuration__api_version=enums.MDS_VERSIONS.v0_4.name, last_event_time_polled=last_event_time_polled, ) # We're polling from zero, nothing already exists in the DB expected_device = factories.Device.build() expected_event = factories.EventRecord.build( event_type=enums.EVENT_TYPE.service_start.name, ) stdout, stderr = io.StringIO(), io.StringIO() # As we're starting before the threshold, we'll poll the archives endpoint status_changes = urllib.parse.urljoin(provider.base_api_url, "/status_changes") requests_mock.get( status_changes, json=make_response( provider, expected_device, expected_event, event_type_reason="service_start", version="0.4.0", ), ) # Mocking must fail if we query the real time endpoint instead requests_mock.get( urllib.parse.urljoin(provider.base_api_url, "/events"), status_code=400, ) call_command("poll_providers", "--raise-on-error", stdout=stdout, stderr=stderr) assert_command_success(stdout, stderr) # The last poller cursor is updated provider = models.Provider.objects.get(pk=provider.pk) assert provider.last_event_time_polled > last_event_time_polled # The device was created on the fly device = models.Device.objects.get(pk=expected_device.pk) assert device.saved_at is not None # The actual event event = device.event_records.get() assert event.event_type == enums.EVENT_TYPE.service_start.name assert_event_equal(event, expected_event) assert_device_equal(device, expected_device)
def test_device_telemetry(client, django_assert_num_queries): provider = factories.Provider( id=uuid.UUID("aaaa0000-61fd-4cce-8113-81af1de90942")) provider2 = factories.Provider( id=uuid.UUID("aaaa0000-61fd-4cce-8113-81af1de90943")) device_id_pattern = "bbbb0000-61fd-4cce-8113-81af1de9094%s" factories.Device(id=uuid.UUID(device_id_pattern % 1), provider=provider) factories.Device(id=uuid.UUID(device_id_pattern % 2), provider=provider) factories.Device(id=uuid.UUID(device_id_pattern % 3), provider=provider2) data = { "data": [ { "device_id": device_id_pattern % 1, "timestamp": 1_325_376_000_000, "gps": { "lat": 0.0, "lng": 3.0, "altitude": 30.0, "heading": 245.2, "speed": 32.3, "hdop": 2.0, "satellites": 6, }, }, { "device_id": device_id_pattern % 2, "timestamp": 1_325_376_001_000, "gps": { "lat": 0.0, "lng": 3.2, "altitude": 30.1, "heading": 245.2, "speed": 32.4, "hdop": 2.0, "satellites": 6, }, "charge": 0.58, }, ] }
def test_policy_list_basic(client, django_assert_num_queries): provider = factories.Provider(name="Test provider") other_provider = factories.Provider(name="Other provider") # One provider-specific policy provider_policy = factories.Policy(providers=[provider], published=True) # And one general-purpose policy general_policy = factories.Policy(published=True) # Test without auth n = BASE_NUM_QUERIES n += 1 # query on policies n += 1 # query on related providers n += 1 # query on related previous policies with django_assert_num_queries(n - 1): # No token check response = client.get(reverse("agency-0.3:policy-list")) assert response.status_code == 200 assert [p["policy_id"] for p in response.data] == [str(general_policy.id)] # Test with provider auth with django_assert_num_queries(n): response = client.get( reverse("agency-0.3:policy-list"), **auth_header(SCOPE_AGENCY_API, provider_id=provider.id), ) assert response.status_code == 200 assert [p["policy_id"] for p in response.data] == [ str(provider_policy.id), str(general_policy.id), ] # We made this mistake before, don't serve a UUID object assert response.data[0]["provider_ids"] == [str(provider.id)] # Test with other provider auth with django_assert_num_queries(n): response = client.get( reverse("agency-0.3:policy-list"), **auth_header(SCOPE_AGENCY_API, provider_id=other_provider.id), ) assert response.status_code == 200 assert [p["policy_id"] for p in response.data] == [str(general_policy.id)]
def test_areas_detail(client, django_assert_num_queries): provider = factories.Provider(name="Test provider") area = factories.Area(providers=[provider]) other_provider = factories.Provider(name="Test other provider") response = client.get(reverse("agency-0.3:area-detail", args=[area.pk])) assert response.status_code == 401 response = client.get( reverse("agency-0.3:area-detail", args=["foobar"]), **auth_header(SCOPE_AGENCY_API, provider_id=provider.id), ) assert response.status_code == 404 # Testing DRF?! response = client.get( reverse("agency-0.3:area-detail", args=[area.pk]), **auth_header(SCOPE_AGENCY_API, provider_id=other_provider.id), ) assert response.status_code == 404 n = BASE_NUM_QUERIES n += 1 # query on areas n += 1 # query on polygons with django_assert_num_queries(n): response = client.get( reverse("agency-0.3:area-detail", args=[area.pk]), **auth_header(SCOPE_AGENCY_API, provider_id=provider.id), ) assert response.status_code == 200 assert response.data == { "service_area_id": str(area.pk), "area": { "coordinates": [[[[[0.0, 0.0], [0.0, 50.0], [50.0, 50.0], [50.0, 0.0], [0.0, 0.0]]]]], "type": "MultiPolygon", }, "type": "unrestricted", }
def device(): uuid1 = "aaaaaaa1-1342-413b-8e89-db802b2f83f6" provider = factories.Provider(name="Test provider") return factories.Device( id=uuid1, provider=provider, identification_number="1AAAAA", model="Testa_Model_S", category="car", propulsion=["combustion"], dn_status="available", dn_gps_point="Point(40 15.0)", dn_battery_pct=0.5, )
def test_poll_provider_v0_4_realtime_lag(client, requests_mock): """test the edge case of being just above the lag threshold""" lag_plus_one_second = datetime.timedelta(hours=1, seconds=1) last_event_time_polled = timezone.now() - lag_plus_one_second provider = factories.Provider( base_api_url="http://provider", api_configuration__api_version=enums.MDS_VERSIONS.v0_4.name, last_event_time_polled=last_event_time_polled, api_configuration__provider_polling_lag="PT1H", # One hour ) def events_callback(request, context): """Check the query parameters""" # Start time is were the poller stopped last time start_time = utils.from_mds_timestamp(int(request.qs["start_time"][0])) assert almost_equal(start_time, last_event_time_polled) # End time is after start time but before the lag threshold end_time = utils.from_mds_timestamp(int(request.qs["end_time"][0])) assert end_time > start_time assert almost_equal(end_time, timezone.now(), precision=lag_plus_one_second) context.status_code = 200 return { "version": "0.4.0", "data": { "status_changes": [] }, } events = urllib.parse.urljoin(provider.base_api_url, "/events") requests_mock.get(events, json=events_callback) # Mocking must fail if we query the archives endpoint instead requests_mock.get( urllib.parse.urljoin(provider.base_api_url, "/status_changes"), status_code=400, ) stdout, stderr = io.StringIO(), io.StringIO() call_command("poll_providers", "--raise-on-error", stdout=stdout, stderr=stderr) assert_command_success(stdout, stderr) # No result, the polling cursor is not updated provider = models.Provider.objects.get(pk=provider.pk) assert provider.last_event_time_polled == last_event_time_polled
def test_areas_list(client, django_assert_num_queries): provider = factories.Provider(name="Test provider") factories.Area.create_batch(5, providers=[provider]) response = client.get(reverse("agency-0.3:area-list")) assert response.status_code == 401 n = BASE_NUM_QUERIES n += 1 # query on areas n += 1 # query on polygons with django_assert_num_queries(n): response = client.get( reverse("agency-0.3:area-list"), **auth_header(SCOPE_AGENCY_API, provider_id=provider.id), ) assert response.status_code == 200 assert len(response.data) == 5
def test_poll_provider_v0_4_archives_no_result(client, requests_mock): # Note: testing with the default "POLLER_CREATE_REGISTER_EVENTS = False" provider = factories.Provider( base_api_url="http://provider", api_configuration__api_version=enums.MDS_VERSIONS.v0_4.name, last_event_time_polled=None, ) stdout, stderr = io.StringIO(), io.StringIO() # As we're starting before the threshold, we'll poll the archives endpoint status_changes = urllib.parse.urljoin(provider.base_api_url, "/status_changes") requests_mock.get( status_changes, json={ "version": "0.4.0", "data": { "status_changes": [] }, }, # No status changes in this hour ) # Mocking must fail if we query the real time endpoint instead requests_mock.get( urllib.parse.urljoin(provider.base_api_url, "/events"), status_code=400, ) call_command("poll_providers", "--raise-on-error", stdout=stdout, stderr=stderr) assert_command_success(stdout, stderr) # The last poller cursor is updated provider = models.Provider.objects.get(pk=provider.pk) # No event but we won't ask this hour again assert provider.last_event_time_polled is not None
def test_device_list_basic(client, django_assert_num_queries): today = datetime.datetime(2012, 1, 1, tzinfo=datetime.timezone.utc) uuid1 = "aaaaaaa1-1342-413b-8e89-db802b2f83f6" uuid2 = "ccccccc3-1342-413b-8e89-db802b2f83f6" provider = factories.Provider(name="Test provider") provider2 = factories.Provider(name="Test another provider") device = factories.Device( id=uuid1, provider=provider, identification_number="1AAAAA", model="Testa_Model_S", category="car", propulsion=["combustion"], registration_date=today, dn_status="available", dn_gps_point="Point(40 15.0)", dn_gps_timestamp=today, dn_battery_pct=0.5, ) factories.Device( id=uuid2, provider=provider2, identification_number="3CCCCC", model="Testa_Model_X", category="scooter", propulsion=["electric"], registration_date=today, dn_status="unavailable", dn_gps_point=None, dn_gps_timestamp=None, dn_battery_pct=None, ) # Add some telemetries on the first device factories.EventRecord(device=device, saved_at=today, event_type="reserve") factories.EventRecord.create_batch(3, device=device, saved_at=today - datetime.timedelta(seconds=10)) expected_device = { "id": uuid1, "provider_id": str(provider.id), "provider_name": "Test provider", "identification_number": "1AAAAA", "model": "Testa_Model_S", "status": "available", "category": "car", "propulsion": ["combustion"], "position": { "type": "Point", "coordinates": [40, 15.0] }, "last_telemetry_date": "2012-01-01T00:00:00Z", "registration_date": "2012-01-01T00:00:00Z", "battery": 0.5, } expected_device2 = { "id": uuid2, "provider_id": str(provider2.id), "provider_name": "Test another provider", "identification_number": "3CCCCC", "model": "Testa_Model_X", "status": "unavailable", "category": "scooter", "propulsion": ["electric"], "last_telemetry_date": None, "position": None, "registration_date": "2012-01-01T00:00:00Z", "battery": None, } # test auth response = client.get("/prv/vehicles/") assert response.status_code == 401 n = BASE_NUM_QUERIES n += 1 # query on devices n += 1 # count on devices with django_assert_num_queries(n): response = client.get( "/prv/vehicles/", **auth_header(SCOPE_PRV_API, provider_id=provider.id)) assert response.status_code == 200 data = response.data["results"] assert len(data) == 2 assert expected_device in data assert expected_device2 in data # test auth response = client.get("/prv/vehicles/%s/" % device.id) assert response.status_code == 401 n = BASE_NUM_QUERIES n += 1 # query on devices n += 1 # query to get areas of device expected_device["areas"] = [] expected_device["provider_logo"] = None with django_assert_num_queries(n): response = client.get( "/prv/vehicles/%s/" % device.id, **auth_header(SCOPE_PRV_API, provider_id=provider.id), ) assert response.status_code == 200 assert response.data == expected_device
def test_device_list_basic(client, django_assert_num_queries): today = datetime.datetime(2012, 1, 1, tzinfo=datetime.timezone.utc) uuid1 = uuid.UUID("aaaaaaa1-1342-413b-8e89-db802b2f83f6") uuid2 = uuid.UUID("ccccccc3-1342-413b-8e89-db802b2f83f6") provider = factories.Provider(name="Test provider") provider2 = factories.Provider(name="Test another provider") device = factories.Device( id=uuid1, provider=provider, identification_number="1AAAAA", model="Testa_Model_S", category="car", propulsion=["combustion"], registration_date=today, dn_status="available", ) factories.Device( id=uuid2, provider=provider, identification_number="3CCCCC", model="Testa_Model_X", category="scooter", propulsion=["electric"], registration_date=today, dn_status="available", ) other_device = factories.Device(provider=provider2) # Add some telemetries on the first device factories.EventRecord( device=device, saved_at=today - datetime.timedelta(seconds=10), timestamp=today - datetime.timedelta(seconds=10), ) # Last event factories.EventRecord( device=device, saved_at=today, event_type=enums.EVENT_TYPE.reserve.name, timestamp=today, ) # timestamp predates second record, but it was saved afterwards factories.EventRecord( device=device, saved_at=today + datetime.timedelta(seconds=10), event_type=enums.EVENT_TYPE.maintenance_drop_off.name, timestamp=today - datetime.timedelta(seconds=5), ) expected_device = { "device_id": str(uuid1), "provider_id": str(provider.id), "vehicle_id": "1AAAAA", "model": "Testa_Model_S", "type": "car", "propulsion": ["combustion"], "mfgr": "", "year": None, "status": "available", "prev_event": "reserve", "updated": 1_325_376_000_000, } expected_device2 = { "device_id": str(uuid2), "provider_id": str(provider.id), "vehicle_id": "3CCCCC", "model": "Testa_Model_X", "type": "scooter", "propulsion": ["electric"], "mfgr": "", "year": None, "status": "available", "prev_event": None, "updated": None, } # test auth response = client.get(reverse("agency:device-list")) assert response.status_code == 401 n = BASE_NUM_QUERIES n += 1 # query on devices n += 1 # query on last telemetry with django_assert_num_queries(n): response = client.get( reverse("agency:device-list"), **auth_header(SCOPE_AGENCY_API, provider_id=provider.id), ) assert response.status_code == 200 assert len(response.data) == 2 assert expected_device in response.data assert expected_device2 in response.data # test auth response = client.get(reverse("agency:device-detail", args=[device.id])) assert response.status_code == 401 n = BASE_NUM_QUERIES n += 1 # query on devices n += 1 # query on last telemetry with django_assert_num_queries(n): response = client.get( reverse("agency:device-detail", args=[device.id]), **auth_header(SCOPE_AGENCY_API, provider_id=provider.id), ) assert response.status_code == 200 assert response.data == expected_device # cannot access other providers data response = client.get( reverse("agency:device-detail", args=[other_device.id]), **auth_header(SCOPE_AGENCY_API, provider_id=provider.id), ) assert response.status_code == 404
def test_with_device_categories(admin_client): factories.Device.create_batch(10, provider=factories.Provider()) provider = models.Provider.objects.with_device_categories().get() assert provider.device_categories == {"bicycle": 4, "scooter": 3, "car": 3}
def test_provider_basic(client, django_assert_num_queries): provider = factories.Provider( id=uuid.UUID("aaaaaaa0-1342-413b-8e89-db802b2f83f6"), name="Test provider") factories.Device(provider=provider, category="car") factories.Device( provider=factories.Provider( id=uuid.UUID("bbbbbbb0-1342-413b-8e89-db802b2f83f6"), name="Test provider 2"), category="scooter", ) factories.Device( provider=factories.Provider( id=uuid.UUID("ccccccc0-1342-413b-8e89-db802b2f83f6"), name="Test provider 3"), category="bicycle", ) response = client.get("/prv/providers/") assert response.status_code == 401 response = client.get( "/prv/providers/", **auth_header(SCOPE_AGENCY_API, provider_id=provider.id)) assert response.status_code == 403 n = BASE_NUM_QUERIES n += 1 # query on providers with django_assert_num_queries(n): response = client.get("/prv/providers/", **auth_header(SCOPE_PRV_API)) assert response.status_code == 200 assert len(response.data) == 3 assert { "id": "aaaaaaa0-1342-413b-8e89-db802b2f83f6", "name": "Test provider", "logo_b64": None, "base_api_url": "http://provider", "api_configuration": { "trailing_slash": False }, "api_authentication": { "type": "none" }, "agency_api_authentication": { "type": "none" }, "colors": {}, "device_categories": { "bicycle": 0, "scooter": 0, "car": 1 }, } in response.data assert { "id": "bbbbbbb0-1342-413b-8e89-db802b2f83f6", "name": "Test provider 2", "logo_b64": None, "base_api_url": "http://provider", "api_configuration": { "trailing_slash": False }, "api_authentication": { "type": "none" }, "agency_api_authentication": { "type": "none" }, "colors": {}, "device_categories": { "bicycle": 0, "scooter": 1, "car": 0 }, } in response.data assert { "id": "ccccccc0-1342-413b-8e89-db802b2f83f6", "name": "Test provider 3", "logo_b64": None, "base_api_url": "http://provider", "api_configuration": { "trailing_slash": False }, "api_authentication": { "type": "none" }, "agency_api_authentication": { "type": "none" }, "colors": {}, "device_categories": { "bicycle": 1, "scooter": 0, "car": 0 }, } in response.data response = client.get( "/prv/providers/%s/" % "aaaaaaa0-1342-413b-8e89-db802b2f83f6", **auth_header(SCOPE_PRV_API)) assert response.status_code == 200 assert response.data == { "id": "aaaaaaa0-1342-413b-8e89-db802b2f83f6", "name": "Test provider", "logo_b64": None, "base_api_url": "http://provider", "api_configuration": { "trailing_slash": False }, "api_authentication": { "type": "none" }, "agency_api_authentication": { "type": "none" }, "colors": {}, "device_categories": { "bicycle": 0, "scooter": 0, "car": 1 }, }
def test_upsert_device(): provider = factories.Provider() # Had issue when not creating it device = factories.Device.build(provider=provider) db_helpers.upsert_devices([device]) assert models.Device.objects.get()