Created endpoint to fetch a location associated with a device
parent
a55211f0b5
commit
f3e67f9677
|
@ -2,6 +2,7 @@ import os
|
|||
|
||||
from flask import Flask
|
||||
|
||||
from public_api.endpoints.device_location import DeviceLocationEndpoint
|
||||
from selene.api import SeleneResponse, selene_api
|
||||
from selene.api.base_config import get_base_config
|
||||
from selene.api.public_endpoint import check_oauth_token
|
||||
|
@ -115,7 +116,11 @@ public.add_url_rule(
|
|||
view_func=WolframAlphaSpokenEndpoint.as_view('wolfram_alpha_spoken_api'),
|
||||
methods=['GET']
|
||||
)
|
||||
|
||||
public.add_url_rule(
|
||||
'/v1/device/<string:device_id>/location',
|
||||
view_func=DeviceLocationEndpoint.as_view('device_location_api'),
|
||||
methods=['GET']
|
||||
)
|
||||
|
||||
"""
|
||||
This is a workaround to allow the API return 401 when we call a non existent path. Use case:
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
from http import HTTPStatus
|
||||
|
||||
from selene.api import PublicEndpoint
|
||||
from selene.data.device import GeographyRepository
|
||||
from selene.util.db import get_db_connection
|
||||
|
||||
|
||||
class DeviceLocationEndpoint(PublicEndpoint):
|
||||
|
||||
def __init__(self):
|
||||
super(DeviceLocationEndpoint, self).__init__()
|
||||
|
||||
def get(self, device_id):
|
||||
with get_db_connection(self.config['DB_CONNECTION_POOL']) as db:
|
||||
location = GeographyRepository(db, None).get_location_by_device_id(device_id)
|
||||
response = (location, HTTPStatus.OK) if location else ('', HTTPStatus.NOT_FOUND)
|
||||
return response
|
|
@ -0,0 +1,5 @@
|
|||
Feature: Fetch device's location
|
||||
|
||||
Scenario: Location is successfully retrieved from a device
|
||||
When a api call to get the location is done
|
||||
Then the location should be retrieved
|
|
@ -0,0 +1,47 @@
|
|||
import json
|
||||
from http import HTTPStatus
|
||||
|
||||
from behave import when, then
|
||||
from hamcrest import assert_that, equal_to, has_key
|
||||
|
||||
|
||||
@when('a api call to get the location is done')
|
||||
def get_device_location(context):
|
||||
login = context.device_login
|
||||
device_id = login['uuid']
|
||||
access_token = login['accessToken']
|
||||
headers = dict(Authorization='Bearer {token}'.format(token=access_token))
|
||||
context.get_location_response = context.client.get(
|
||||
'/v1/device/{uuid}/location'.format(uuid=device_id),
|
||||
headers=headers
|
||||
)
|
||||
|
||||
|
||||
@then('the location should be retrieved')
|
||||
def validate_location(context):
|
||||
response = context.get_location_response
|
||||
assert_that(response.status_code, equal_to(HTTPStatus.OK))
|
||||
location = json.loads(response.data)
|
||||
assert_that(location, has_key('coordinate'))
|
||||
assert_that(location, has_key('timezone'))
|
||||
assert_that(location, has_key('city'))
|
||||
|
||||
coordinate = location['coordinate']
|
||||
assert_that(coordinate, has_key('latitude'))
|
||||
assert_that(coordinate, has_key('longitude'))
|
||||
|
||||
timezone = location['timezone']
|
||||
assert_that(timezone, has_key('name'))
|
||||
assert_that(timezone, has_key('offset'))
|
||||
assert_that(timezone, has_key('dstOffset'))
|
||||
|
||||
city = location['city']
|
||||
assert_that(city, has_key('name'))
|
||||
assert_that(city, has_key('state'))
|
||||
|
||||
state = city['state']
|
||||
assert_that(state, has_key('name'))
|
||||
assert_that(state, has_key('country'))
|
||||
|
||||
country = state['country']
|
||||
assert_that(country, has_key('name'))
|
|
@ -46,3 +46,10 @@ class GeographyRepository(RepositoryBase):
|
|||
db_result = self.cursor.insert_returning(db_request)
|
||||
|
||||
return db_result['id']
|
||||
|
||||
def get_location_by_device_id(self, device_id):
|
||||
db_request = self._build_db_request(
|
||||
sql_file_name='get_location_by_device_id.sql',
|
||||
args=dict(device_id=device_id)
|
||||
)
|
||||
return self.cursor.select_one(db_request)
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
SELECT
|
||||
json_build_object(
|
||||
'latitude', city.latitude,
|
||||
'longitude', city.longitude
|
||||
) as coordinate,
|
||||
json_build_object(
|
||||
'name', timezone.name,
|
||||
'offset', timezone.gmt_offset,
|
||||
'dstOffset', timezone.dst_offset
|
||||
) as timezone,
|
||||
json_build_object(
|
||||
'name', city.name,
|
||||
'state', json_build_object(
|
||||
'name', region.name,
|
||||
'country', json_build_object(
|
||||
'name', country.name
|
||||
)
|
||||
)
|
||||
) as city
|
||||
FROM
|
||||
device.device dev
|
||||
INNER JOIN
|
||||
device.geography geo ON dev.geography_id = geo.id
|
||||
INNER JOIN
|
||||
geography.country country ON geo.country_id = country.id
|
||||
INNER JOIN
|
||||
geography.region region ON geo.region_id = region.id
|
||||
INNER JOIN
|
||||
geography.city city ON geo.city_id = city.id
|
||||
INNER JOIN
|
||||
geography.timezone timezone ON geo.timezone_id = timezone.id
|
||||
WHERE
|
||||
dev.id = %(device_id)s
|
Loading…
Reference in New Issue