1
0
Fork 0

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
Corey Shields 2021-05-16 18:54:48 -04:00
parent 286c744141
commit 4141e275cc
8 changed files with 73 additions and 18 deletions

View File

@ -1,5 +1,5 @@
FROM python:3.8.7
MAINTAINER SatNOGS project <dev@satnogs.org>
LABEL maintainer="SatNOGS project <dev@satnogs.org>"
WORKDIR /workdir/

10
conftest.py 100644
View File

@ -0,0 +1,10 @@
"""pytest configuration file"""
import pytest
@pytest.fixture(scope='session')
def celery_config():
return {
'broker_url': 'memory://',
'result_backend': 'rpc',
}

View File

@ -87,15 +87,20 @@ class TransmitterViewApiTest(TestCase):
@pytest.mark.django_db(transaction=True)
@pytest.mark.usefixtures('celery_session_app')
@pytest.mark.usefixtures('celery_session_worker')
class TelemetryViewApiTest(TestCase):
"""
Tests the Telemetry View API
"""
datum = None
satellite = None
def setUp(self):
self.datum = DemodDataFactory()
self.datum.save()
self.satellite = SatelliteFactory()
self.satellite.save()
def test_list(self):
"""Test the Telemetry API listing"""
@ -106,3 +111,38 @@ class TelemetryViewApiTest(TestCase):
"""Test the Telemetry API retrieval"""
response = self.client.get('/api/telemetry/{0}/'.format(self.datum.id), format='json')
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)

View File

@ -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,
viewsets.GenericViewSet):
"""
@ -241,7 +241,7 @@ class TelemetryViewSet( # pylint: disable=R0901
serializer_class = serializers.TelemetrySerializer
filterset_class = filters.TelemetryViewFilter
permission_classes = [SafeMethodsWithPermission]
parser_classes = (FormParser, FileUploadParser)
parser_classes = (FormParser, MultiPartParser, FileUploadParser)
pagination_class = pagination.LinkedHeaderPageNumberPagination
@extend_schema(
@ -291,14 +291,17 @@ class TelemetryViewSet( # pylint: disable=R0901
# Convert coordinates to omit N-S and W-E designators
lat = request.data.get('latitude')
lng = request.data.get('longitude')
if any(x.isalpha() for x in lat):
data['lat'] = (-float(lat[:-1]) if ('S' in lat) else float(lat[:-1]))
else:
data['lat'] = float(lat)
if any(x.isalpha() for x in lng):
data['lng'] = (-float(lng[:-1]) if ('W' in lng) else float(lng[:-1]))
else:
data['lng'] = float(lng)
try:
if any(x.isalpha() for x in lat):
data['lat'] = (-float(lat[:-1]) if ('S' in lat) else float(lat[:-1]))
else:
data['lat'] = float(lat)
if any(x.isalpha() for x in lng):
data['lng'] = (-float(lng[:-1]) if ('W' in lng) else float(lng[:-1]))
else:
data['lng'] = float(lng)
except ValueError:
return Response(status=status.HTTP_400_BAD_REQUEST)
# Network or SiDS submission?
if request.data.get('satnogs_network'):

View File

@ -243,7 +243,7 @@ LOGGING = {
# Sentry
SENTRY_ENABLED = config('SENTRY_ENABLED', default=False, cast=bool)
if SENTRY_ENABLED:
sentry_sdk.init(
sentry_sdk.init( # pylint: disable=abstract-class-instantiated
environment=ENVIRONMENT,
dsn=config('SENTRY_DSN', default=''),
release='satnogs-db@{}'.format(__version__),

View File

@ -18,10 +18,11 @@ iniconfig==1.1.1
mock==4.0.3
packaging==20.9
pluggy==0.13.1
pur==5.4.0
pur==5.4.1
py==1.10.0
pyparsing==2.4.7
pytest==6.2.4
pytest-celery==0.0.0
pytest-cov==2.12.0
pytest-django==4.2.0
pytest-forked==1.3.0

View File

@ -84,6 +84,7 @@ install_requires =
[options.extras_require]
dev =
pytest-celery
pytest-cov~=2.12.0
pytest-django~=4.2.0
pytest-forked~=1.3.0

10
tox.ini
View File

@ -2,11 +2,11 @@
envlist = flake8,isort,yapf,pylint,build,pytest,docs
[depversions]
flake8 = 3.8.4
isort = 5.7.0
yapf = 0.30.0
pylint = 2.6.0
pylint_django = 2.4.2
flake8 = 3.9.2
isort = 5.8.0
yapf = 0.31.0
pylint = 2.8.2
pylint_django = 2.4.4
sphinx_rtd_theme = 0.5.1
twine = 3.3.0