More improved unit testing
Additional pytests, including tests for a fully populated DB Also: - simplify a conditional statement in the home page view - fix broken robots.txt url parsing - fix case in cached stats generation where new satellite id association could trip a comparison against a NoneType by adding a default - removed a print statement leftover from satellite id development Signed-off-by: Corey Shields <cshields@gmail.com>spacecruft
parent
33357e9207
commit
79ca1834c9
|
@ -227,6 +227,7 @@ class TelemetryViewApiTest(TestCase):
|
|||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
@pytest.mark.django_db(transaction=True)
|
||||
class LoginView(TestCase):
|
||||
"""
|
||||
Tests various API endpoints with authentication
|
||||
|
|
168
db/base/tests.py
168
db/base/tests.py
|
@ -1,13 +1,16 @@
|
|||
"""SatNOGS DB test suites"""
|
||||
# pylint: disable=R0903
|
||||
# pylint: disable=R0903,W0612
|
||||
# flake8: noqa: F841
|
||||
from datetime import timedelta
|
||||
|
||||
import factory
|
||||
import pytest
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import User # pylint: disable=E5142
|
||||
from django.test import TestCase
|
||||
from django.utils.timezone import now
|
||||
from factory import fuzzy
|
||||
from pytest_django.asserts import assertContains # pylint: disable=E0611
|
||||
|
||||
from db.base.models import DATA_SOURCES, DemodData, Mode, Satellite, SatelliteEntry, \
|
||||
SatelliteIdentifier, Telemetry, Transmitter, TransmitterSuggestion
|
||||
|
@ -127,6 +130,7 @@ class TelemetryFactory(factory.django.DjangoModelFactory):
|
|||
model = Telemetry
|
||||
|
||||
|
||||
# @pytest.mark.django_db
|
||||
class DemodDataFactory(factory.django.DjangoModelFactory):
|
||||
"""DemodData model factory."""
|
||||
satellite = factory.SubFactory(SatelliteFactory)
|
||||
|
@ -146,39 +150,145 @@ class DemodDataFactory(factory.django.DjangoModelFactory):
|
|||
|
||||
|
||||
@pytest.mark.django_db(transaction=True)
|
||||
class HomeViewTest(TestCase):
|
||||
"""
|
||||
Simple test to make sure the home page is working
|
||||
"""
|
||||
def test_home_page(self):
|
||||
"""Tests for a known string in the SatNOGS DB home page template"""
|
||||
response = self.client.get('/')
|
||||
self.assertContains(response, 'New Satellites')
|
||||
# class HomeViewTest(TestCase):
|
||||
# """
|
||||
# Simple test to make sure the home page is working
|
||||
# """
|
||||
def test_home_page(client):
|
||||
"""Tests the SatNOGS DB home page in an unpopulated state"""
|
||||
response = client.get('/')
|
||||
assertContains(response, 'no contributions')
|
||||
|
||||
|
||||
@pytest.mark.django_db(transaction=True)
|
||||
class SatelliteViewTest(TestCase):
|
||||
"""
|
||||
Test to make sure the satellite page is working
|
||||
"""
|
||||
satellite = None
|
||||
def test_satellite_norad_404(client):
|
||||
"""Tests for satellite not found by norad ID"""
|
||||
response = client.get('/satellite/999999/')
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
@pytest.mark.django_db(transaction=True)
|
||||
def test_satellite_id_404(client):
|
||||
"""Tests for satellite not found by satellite ID"""
|
||||
response = client.get('/satellite/AAAA-AAAA-AAAA-AAAA-AAAA/')
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
@pytest.mark.django_db(transaction=True)
|
||||
# class AboutViewTest(TestCase):
|
||||
# """
|
||||
# Test to make sure the about page is working
|
||||
# """
|
||||
def test_about_page(client):
|
||||
"""Tests for a known string in the SatNOGS DB about page template"""
|
||||
response = client.get('/about/')
|
||||
assertContains(response, 'SatNOGS DB is an effort to create an hollistic')
|
||||
|
||||
|
||||
@pytest.mark.django_db(transaction=True)
|
||||
@pytest.mark.usefixtures('celery_session_app')
|
||||
@pytest.mark.usefixtures('celery_session_worker')
|
||||
class PopulatedDBTest(TestCase):
|
||||
"""
|
||||
Tests with sample data populated
|
||||
"""
|
||||
def setUp(self):
|
||||
self.satellite = SatelliteFactory()
|
||||
self.satellite.save()
|
||||
self.client.force_login(User.objects.get_or_create(username='testuser')[0])
|
||||
|
||||
def test_satellite_page(self):
|
||||
"""Tests for satellite name in a SatNOGS DB satellite page"""
|
||||
response = self.client.get('/satellite/%s/' % self.satellite.satellite_entry.norad_cat_id)
|
||||
self.assertContains(response, self.satellite.satellite_entry.name)
|
||||
# start by creating a bunch of satellite entries
|
||||
satellites = []
|
||||
satellites = [SatelliteFactory() for i in range(10)]
|
||||
|
||||
# now create transmitters and some DemodData in the past 24h for the satellites
|
||||
for sat in range(0, len(satellites) - 1):
|
||||
demod = []
|
||||
demod = [
|
||||
DemodDataFactory(
|
||||
satellite=satellites[sat],
|
||||
timestamp=fuzzy.FuzzyDateTime(now() - timedelta(days=1), now())
|
||||
) for i in range(10)
|
||||
]
|
||||
transmitters = []
|
||||
transmitters = [TransmitterFactory(satellite=satellites[sat]) for i in range(2)]
|
||||
|
||||
bad_transmitter = TransmitterFactory(status='inactive')
|
||||
good_transmitter = TransmitterFactory(status='active')
|
||||
|
||||
# make sure we have a recent demoddata to show
|
||||
recent_demod_data = DemodDataFactory(timestamp=now())
|
||||
|
||||
# and the newest satellite with no data
|
||||
recent_satellite_entry = SatelliteEntryFactory(created=now())
|
||||
recent_satellite = SatelliteFactory(satellite_entry=recent_satellite_entry)
|
||||
|
||||
def test_home_page(self):
|
||||
"""Tests for known strings in the populated SatNOGS DB home page"""
|
||||
response = self.client.get('/')
|
||||
assertContains(response, 'Latest data timestamp')
|
||||
assertContains(response, 'Data - Last 24h')
|
||||
assertContains(response, 'No Data')
|
||||
|
||||
def test_satellites_page(self):
|
||||
"""Tests for known strings in the populated satellites page"""
|
||||
check_sat = Satellite.objects.first()
|
||||
response = self.client.get('/satellites/')
|
||||
assertContains(response, check_sat.satellite_identifier)
|
||||
|
||||
def test_satellite_by_id(self):
|
||||
"""Tests for a good satellite entry by satellite ID"""
|
||||
check_sat = Satellite.objects.first()
|
||||
# go ahead and test transmitter suggestions here too
|
||||
TransmitterSuggestionFactory(satellite=check_sat)
|
||||
response = self.client.get('/satellite/%s/' % check_sat.satellite_identifier)
|
||||
assertContains(response, check_sat.satellite_entry.name)
|
||||
|
||||
def test_satellite_by_norad(self):
|
||||
"""Tests for a good satellite entry by NORAD ID"""
|
||||
check_sat = Satellite.objects.first()
|
||||
response = self.client.get('/satellite/%s/' % check_sat.satellite_entry.norad_cat_id)
|
||||
assertContains(response, check_sat.satellite_entry.name)
|
||||
|
||||
def test_transmitter_page(self):
|
||||
"""Tests for known strings in the populated transmitters page"""
|
||||
response = self.client.get('/transmitters/')
|
||||
assertContains(response, '<td>active</td>')
|
||||
assertContains(response, '<td>inactive</td>')
|
||||
|
||||
def test_search_redirect(self):
|
||||
"""Tests satellite search redirect"""
|
||||
check_sat = Satellite.objects.first()
|
||||
response = self.client.get('/search/?q=%s' % check_sat.satellite_entry.name)
|
||||
assert response.status_code == 302
|
||||
|
||||
def test_multiple_search_results(self):
|
||||
"""Tests satellite search with multiple results"""
|
||||
check_sat = Satellite.objects.first()
|
||||
# assume our population has created enough data for multiple hits of 1
|
||||
response = self.client.get('/search/?q=1')
|
||||
assertContains(response, 'multiple results')
|
||||
|
||||
def test_bad_search(self):
|
||||
"""Tests satellite search ending in 404"""
|
||||
check_sat = Satellite.objects.first()
|
||||
response = self.client.get('/search/?q=XXXXXXXXXX')
|
||||
assertContains(response, 'No results found')
|
||||
|
||||
def test_stats(self):
|
||||
"""Tests stats page against count of satellites"""
|
||||
# At some point we should force a celery run and test against the total sat cnt
|
||||
# refresh statistics first
|
||||
refresh = self.client.get('/statistics/')
|
||||
response = self.client.get('/stats/')
|
||||
assertContains(response, 'Total Satellites')
|
||||
|
||||
|
||||
@pytest.mark.django_db(transaction=True)
|
||||
class AboutViewTest(TestCase):
|
||||
"""
|
||||
Test to make sure the about page is working
|
||||
"""
|
||||
def test_about_page(self):
|
||||
"""Tests for a known string in the SatNOGS DB about page template"""
|
||||
response = self.client.get('/about/')
|
||||
self.assertContains(response, 'SatNOGS DB is an effort to create an hollistic')
|
||||
def test_robots(client):
|
||||
"""Tests for a known string in the SatNOGS DB about page template"""
|
||||
response = client.get('/robots.txt')
|
||||
assertContains(response, 'Disallow')
|
||||
|
||||
|
||||
def test_help(client):
|
||||
"""Tests for a known string in the help modal"""
|
||||
response = client.get('/help/')
|
||||
assertContains(response, 'You can ask questions')
|
||||
|
|
|
@ -31,7 +31,7 @@ BASE_URLPATTERNS = (
|
|||
path('statistics/', views.statistics, name='statistics'),
|
||||
path('stats/', views.stats, name='stats'),
|
||||
path('users/edit/', views.users_edit, name='users_edit'),
|
||||
path(r'robots\.txt', views.robots, name='robots'),
|
||||
path('robots.txt', views.robots, name='robots'),
|
||||
path('search/', views.search, name='search_results'),
|
||||
path('create_satellite/', views.SatelliteCreateView.as_view(), name='create_satellite'),
|
||||
path(
|
||||
|
|
|
@ -451,14 +451,15 @@ def cache_statistics():
|
|||
|
||||
# Aggregate stats for satellites and their associated ones
|
||||
for sat in satellites:
|
||||
print(sat, sat['associated_satellite'], flush=True)
|
||||
# if satellite is merged then add statistics to its association
|
||||
if sat['associated_satellite']:
|
||||
if sat['associated_satellite'] in sat_stats:
|
||||
sat_stats[sat['associated_satellite']]['count'] += sat['count']
|
||||
sat_stats[sat['associated_satellite']]['decoded'] += sat['decoded']
|
||||
sat_stats[sat['associated_satellite']]['latest_payload'] = max(
|
||||
sat_stats[sat['associated_satellite']]['latest_payload'], sat['latest_payload']
|
||||
sat_stats[sat['associated_satellite']]['latest_payload'],
|
||||
sat['latest_payload'],
|
||||
default=sat['latest_payload']
|
||||
)
|
||||
else:
|
||||
del sat['associated_satellite']
|
||||
|
|
|
@ -56,9 +56,8 @@ def home(request):
|
|||
page = paginator.page(1)
|
||||
while not found:
|
||||
for data in page.object_list:
|
||||
if data.satellite.id in latest_data_satellites:
|
||||
continue
|
||||
latest_data_satellites.append(data.satellite.id)
|
||||
if data.satellite.id not in latest_data_satellites:
|
||||
latest_data_satellites.append(data.satellite.id)
|
||||
if len(latest_data_satellites) > 5:
|
||||
found = True
|
||||
break
|
||||
|
@ -206,7 +205,7 @@ def request_export(request, sat_pk, period=None):
|
|||
completed.
|
||||
:returns: the originating satellite page
|
||||
"""
|
||||
satellite_obj = get_object_or_404(Satellite, pk=sat_pk)
|
||||
satellite_obj = get_object_or_404(Satellite, id=sat_pk)
|
||||
if satellite_obj.associated_satellite:
|
||||
satellite_obj = satellite_obj.associated_satellite
|
||||
|
||||
|
|
Loading…
Reference in New Issue