Created endpoint to fetch a location associated with a device

pull/83/head
Matheus Lima 2019-03-25 20:48:45 -03:00
parent a55211f0b5
commit f3e67f9677
6 changed files with 115 additions and 1 deletions

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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'))

View File

@ -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)

View File

@ -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