Improve testing and handling of telemetry upload API
Improved handling of input data for the telemetry API and added tests for such ensure that we return a 400 on an empty frame, station, timestamp return 400 when lat/lng value conversion fails or when the resulting lat/lng is out of range. Fixes #463 Signed-off-by: Corey Shields <cshields@gmail.com>spacecruft
parent
286c744141
commit
4141e275cc
|
@ -1,5 +1,5 @@
|
||||||
FROM python:3.8.7
|
FROM python:3.8.7
|
||||||
MAINTAINER SatNOGS project <dev@satnogs.org>
|
LABEL maintainer="SatNOGS project <dev@satnogs.org>"
|
||||||
|
|
||||||
WORKDIR /workdir/
|
WORKDIR /workdir/
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
"""pytest configuration file"""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='session')
|
||||||
|
def celery_config():
|
||||||
|
return {
|
||||||
|
'broker_url': 'memory://',
|
||||||
|
'result_backend': 'rpc',
|
||||||
|
}
|
|
@ -87,15 +87,20 @@ class TransmitterViewApiTest(TestCase):
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db(transaction=True)
|
@pytest.mark.django_db(transaction=True)
|
||||||
|
@pytest.mark.usefixtures('celery_session_app')
|
||||||
|
@pytest.mark.usefixtures('celery_session_worker')
|
||||||
class TelemetryViewApiTest(TestCase):
|
class TelemetryViewApiTest(TestCase):
|
||||||
"""
|
"""
|
||||||
Tests the Telemetry View API
|
Tests the Telemetry View API
|
||||||
"""
|
"""
|
||||||
datum = None
|
datum = None
|
||||||
|
satellite = None
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.datum = DemodDataFactory()
|
self.datum = DemodDataFactory()
|
||||||
self.datum.save()
|
self.datum.save()
|
||||||
|
self.satellite = SatelliteFactory()
|
||||||
|
self.satellite.save()
|
||||||
|
|
||||||
def test_list(self):
|
def test_list(self):
|
||||||
"""Test the Telemetry API listing"""
|
"""Test the Telemetry API listing"""
|
||||||
|
@ -106,3 +111,38 @@ class TelemetryViewApiTest(TestCase):
|
||||||
"""Test the Telemetry API retrieval"""
|
"""Test the Telemetry API retrieval"""
|
||||||
response = self.client.get('/api/telemetry/{0}/'.format(self.datum.id), format='json')
|
response = self.client.get('/api/telemetry/{0}/'.format(self.datum.id), format='json')
|
||||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||||
|
|
||||||
|
def test_post(self):
|
||||||
|
"""Test the SiDS posting capability"""
|
||||||
|
norad = self.satellite.satellite_entry.norad_cat_id
|
||||||
|
frame = '60A060A0A46E609C8262A6A640E082A0A4A682A86103F02776261C6C201C5'
|
||||||
|
frame += '3495D41524953532D496E7465726E6174696F6E616C2053706163652053746174696F6E3D0D'
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'frame': frame,
|
||||||
|
'locator': 'longLat',
|
||||||
|
'latitude': '06.12S',
|
||||||
|
'longitude': '59.34W',
|
||||||
|
'noradID': str(norad),
|
||||||
|
'source': 'T3ST',
|
||||||
|
'timestamp': '2021-03-15T13:14:04.940Z',
|
||||||
|
'version': '1.2.3'
|
||||||
|
}
|
||||||
|
response = self.client.post('/api/telemetry/', data=data)
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||||
|
|
||||||
|
def test_bad_post(self):
|
||||||
|
"""Test the SiDS posting capability with bad data"""
|
||||||
|
norad = self.satellite.satellite_entry.norad_cat_id
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'frame': '',
|
||||||
|
'locator': 'longLat',
|
||||||
|
'latitude': '206.12S',
|
||||||
|
'longitude': '59.34WE',
|
||||||
|
'noradID': str(norad),
|
||||||
|
'source': '',
|
||||||
|
'timestamp': ''
|
||||||
|
}
|
||||||
|
response = self.client.post('/api/telemetry/', data=data)
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
|
@ -226,7 +226,7 @@ class LatestTleSetViewSet(viewsets.ReadOnlyModelViewSet): # pylint: disable=R09
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
class TelemetryViewSet( # pylint: disable=R0901
|
class TelemetryViewSet( # pylint: disable=R0901,R0912,R0915
|
||||||
mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin,
|
mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin,
|
||||||
viewsets.GenericViewSet):
|
viewsets.GenericViewSet):
|
||||||
"""
|
"""
|
||||||
|
@ -241,7 +241,7 @@ class TelemetryViewSet( # pylint: disable=R0901
|
||||||
serializer_class = serializers.TelemetrySerializer
|
serializer_class = serializers.TelemetrySerializer
|
||||||
filterset_class = filters.TelemetryViewFilter
|
filterset_class = filters.TelemetryViewFilter
|
||||||
permission_classes = [SafeMethodsWithPermission]
|
permission_classes = [SafeMethodsWithPermission]
|
||||||
parser_classes = (FormParser, FileUploadParser)
|
parser_classes = (FormParser, MultiPartParser, FileUploadParser)
|
||||||
pagination_class = pagination.LinkedHeaderPageNumberPagination
|
pagination_class = pagination.LinkedHeaderPageNumberPagination
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
|
@ -291,14 +291,17 @@ class TelemetryViewSet( # pylint: disable=R0901
|
||||||
# Convert coordinates to omit N-S and W-E designators
|
# Convert coordinates to omit N-S and W-E designators
|
||||||
lat = request.data.get('latitude')
|
lat = request.data.get('latitude')
|
||||||
lng = request.data.get('longitude')
|
lng = request.data.get('longitude')
|
||||||
if any(x.isalpha() for x in lat):
|
try:
|
||||||
data['lat'] = (-float(lat[:-1]) if ('S' in lat) else float(lat[:-1]))
|
if any(x.isalpha() for x in lat):
|
||||||
else:
|
data['lat'] = (-float(lat[:-1]) if ('S' in lat) else float(lat[:-1]))
|
||||||
data['lat'] = float(lat)
|
else:
|
||||||
if any(x.isalpha() for x in lng):
|
data['lat'] = float(lat)
|
||||||
data['lng'] = (-float(lng[:-1]) if ('W' in lng) else float(lng[:-1]))
|
if any(x.isalpha() for x in lng):
|
||||||
else:
|
data['lng'] = (-float(lng[:-1]) if ('W' in lng) else float(lng[:-1]))
|
||||||
data['lng'] = float(lng)
|
else:
|
||||||
|
data['lng'] = float(lng)
|
||||||
|
except ValueError:
|
||||||
|
return Response(status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
# Network or SiDS submission?
|
# Network or SiDS submission?
|
||||||
if request.data.get('satnogs_network'):
|
if request.data.get('satnogs_network'):
|
||||||
|
|
|
@ -243,7 +243,7 @@ LOGGING = {
|
||||||
# Sentry
|
# Sentry
|
||||||
SENTRY_ENABLED = config('SENTRY_ENABLED', default=False, cast=bool)
|
SENTRY_ENABLED = config('SENTRY_ENABLED', default=False, cast=bool)
|
||||||
if SENTRY_ENABLED:
|
if SENTRY_ENABLED:
|
||||||
sentry_sdk.init(
|
sentry_sdk.init( # pylint: disable=abstract-class-instantiated
|
||||||
environment=ENVIRONMENT,
|
environment=ENVIRONMENT,
|
||||||
dsn=config('SENTRY_DSN', default=''),
|
dsn=config('SENTRY_DSN', default=''),
|
||||||
release='satnogs-db@{}'.format(__version__),
|
release='satnogs-db@{}'.format(__version__),
|
||||||
|
|
|
@ -18,10 +18,11 @@ iniconfig==1.1.1
|
||||||
mock==4.0.3
|
mock==4.0.3
|
||||||
packaging==20.9
|
packaging==20.9
|
||||||
pluggy==0.13.1
|
pluggy==0.13.1
|
||||||
pur==5.4.0
|
pur==5.4.1
|
||||||
py==1.10.0
|
py==1.10.0
|
||||||
pyparsing==2.4.7
|
pyparsing==2.4.7
|
||||||
pytest==6.2.4
|
pytest==6.2.4
|
||||||
|
pytest-celery==0.0.0
|
||||||
pytest-cov==2.12.0
|
pytest-cov==2.12.0
|
||||||
pytest-django==4.2.0
|
pytest-django==4.2.0
|
||||||
pytest-forked==1.3.0
|
pytest-forked==1.3.0
|
||||||
|
|
|
@ -84,6 +84,7 @@ install_requires =
|
||||||
|
|
||||||
[options.extras_require]
|
[options.extras_require]
|
||||||
dev =
|
dev =
|
||||||
|
pytest-celery
|
||||||
pytest-cov~=2.12.0
|
pytest-cov~=2.12.0
|
||||||
pytest-django~=4.2.0
|
pytest-django~=4.2.0
|
||||||
pytest-forked~=1.3.0
|
pytest-forked~=1.3.0
|
||||||
|
|
10
tox.ini
10
tox.ini
|
@ -2,11 +2,11 @@
|
||||||
envlist = flake8,isort,yapf,pylint,build,pytest,docs
|
envlist = flake8,isort,yapf,pylint,build,pytest,docs
|
||||||
|
|
||||||
[depversions]
|
[depversions]
|
||||||
flake8 = 3.8.4
|
flake8 = 3.9.2
|
||||||
isort = 5.7.0
|
isort = 5.8.0
|
||||||
yapf = 0.30.0
|
yapf = 0.31.0
|
||||||
pylint = 2.6.0
|
pylint = 2.8.2
|
||||||
pylint_django = 2.4.2
|
pylint_django = 2.4.4
|
||||||
sphinx_rtd_theme = 0.5.1
|
sphinx_rtd_theme = 0.5.1
|
||||||
twine = 3.3.0
|
twine = 3.3.0
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue