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_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_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_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 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_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_compliance_list_basic(client, django_assert_num_queries): device = factories.Device() policy = factories.Policy(published=True) # One provider-specific policy # provider_policy = factories.ComplianceFactory() # And one general-purpose policy compliance = factories.ComplianceFactory( rule=uuid.UUID("81b1bc92-65b7-4434-8ada-2feeb0b7b223"), geography=uuid.UUID("e0e4a085-7a50-43e0-afa4-6792ca897c5a"), policy_id=policy.id, vehicle_id=device.id, start_date=datetime.datetime(2007, 12, 6, 16, 29, 43, 79043, tzinfo=pytz.UTC), end_date=datetime.datetime(2007, 12, 7, 16, 29, 43, 79043, tzinfo=pytz.UTC), ) compliance_ongoing = factories.ComplianceFactory( rule=uuid.UUID("89b5bbb5-ba98-4498-9649-787eb8ddbb8e"), geography=uuid.UUID("2cfbdd7f-8ba2-4b48-9826-951fe3249981"), policy_id=factories.Policy().id, vehicle_id=factories.Device().id, start_date=datetime.datetime(2009, 12, 6, 16, 29, 43, 79043, tzinfo=pytz.UTC), end_date=None, ) # Test without auth n = 2 # Savepoint and release n += 1 # query on policy n += 1 # query on related compliances n += 1 # query on device n += 1 # query on other device # query Last compliance with django_assert_num_queries(n): response = client.get(reverse("agency-0.3:compliance-list")) assert response.status_code == 200 # Check why there is policy more (??? what does it mean?) assert response.data[0]["id"] == str(compliance.policy.id) # Now test with a provider ID response = client.get(reverse("agency-0.3:compliance-list"), {"provider_id": str(device.provider.id)}) # The provider can fetch a policy that applies to them # (to all providers in this case) assert response.status_code == 200 assert response.data[0]["id"] == str(compliance.policy_id) response = client.get( reverse("agency-0.3:compliance-list"), { "provider_id": str(device.provider.id), "end_date": utils.to_mds_timestamp( datetime.datetime( 2009, 12, 7, 16, 29, 43, 79043, tzinfo=pytz.UTC)), }, ) # provider is OK but timestamp is too high assert response.status_code == 200 assert response.data == [] response = client.get( reverse("agency-0.3:compliance-list"), { "provider_id": str(device.provider.id), "end_date": utils.to_mds_timestamp( datetime.datetime( 2007, 12, 7, 16, 29, 43, 79043, tzinfo=pytz.UTC)) - 60000, # XXX ?! }, ) # provider is OK and timestamp is OK assert response.status_code == 200 assert response.data[0]["id"] == str(compliance.policy_id) response = client.get( reverse("agency-0.3:compliance-list"), { "end_date": utils.to_mds_timestamp( datetime.datetime(1970, 1, 14, 0, 47, 3, 900000, tzinfo=datetime.timezone.utc)) }, ) # too low assert response.status_code == 200 and response.data == [] response = client.get( reverse("agency-0.3:compliance-list"), { "end_date": utils.to_mds_timestamp( datetime.datetime(2070, 1, 21, 3, 45, 56, 700000, tzinfo=datetime.timezone.utc)) }, ) # too high but compliance_ongoing is not finished assert response.status_code == 200 assert response.data[0]["id"] == str(compliance_ongoing.policy_id) response = client.get( reverse("agency-0.3:compliance-list"), {"provider_id": "89b5bbb5-ba98-4498-9649-787eb8ddbb8e"}, ) # this provider don't exist assert response.status_code == 200 and response.data == []
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_upsert_event_record(): device = factories.Device() # Same event_record = factories.EventRecord.build(device=device) db_helpers.upsert_event_records([event_record], "push") assert models.EventRecord.objects.get()