diff --git a/db/api/tests.py b/db/api/tests.py index cc5277c..929b9b5 100644 --- a/db/api/tests.py +++ b/db/api/tests.py @@ -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 diff --git a/db/base/tests.py b/db/base/tests.py index 3962df5..2fb8979 100644 --- a/db/base/tests.py +++ b/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, 'active') + assertContains(response, 'inactive') + + 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') diff --git a/db/base/urls.py b/db/base/urls.py index a22d7f5..b276f88 100644 --- a/db/base/urls.py +++ b/db/base/urls.py @@ -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( diff --git a/db/base/utils.py b/db/base/utils.py index 3a101b6..ddd52db 100644 --- a/db/base/utils.py +++ b/db/base/utils.py @@ -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'] diff --git a/db/base/views.py b/db/base/views.py index c28fcd4..88dca34 100644 --- a/db/base/views.py +++ b/db/base/views.py @@ -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