1
0
Fork 0
satnogs-network/network/base/tests.py

433 lines
15 KiB
Python

import random
from datetime import datetime, timedelta
import factory
from django.contrib.auth.models import Group
from django.db import transaction
from django.test import Client, TestCase
from django.utils.timezone import now
from factory import fuzzy
import pytest
from network.base.models import ANTENNA_BANDS, ANTENNA_TYPES, \
OBSERVATION_STATUSES, Antenna, DemodData, Observation, Satellite, \
Station, Tle
from network.users.tests import UserFactory
ANTENNA_BAND_IDS = [c[0] for c in ANTENNA_BANDS]
ANTENNA_TYPE_IDS = [c[0] for c in ANTENNA_TYPES]
OBSERVATION_STATUS_IDS = [c[0] for c in OBSERVATION_STATUSES]
def generate_payload():
payload = '{0:b}'.format(random.randint(500000000, 510000000))
digits = 1824
while digits:
digit = random.randint(0, 1)
payload += str(digit)
digits -= 1
return payload
def generate_payload_name():
filename = datetime.strftime(fuzzy.FuzzyDateTime(now() - timedelta(days=10), now()).fuzz(),
'%Y%m%dT%H%M%SZ')
return filename
class AntennaFactory(factory.django.DjangoModelFactory):
"""Antenna model factory."""
frequency = fuzzy.FuzzyFloat(200, 500)
frequency_max = fuzzy.FuzzyFloat(500, 800)
band = fuzzy.FuzzyChoice(choices=ANTENNA_BAND_IDS)
antenna_type = fuzzy.FuzzyChoice(choices=ANTENNA_TYPE_IDS)
class Meta:
model = Antenna
class StationFactory(factory.django.DjangoModelFactory):
"""Station model factory."""
owner = factory.SubFactory(UserFactory)
name = fuzzy.FuzzyText()
image = factory.django.ImageField()
alt = fuzzy.FuzzyInteger(0, 800)
lat = fuzzy.FuzzyFloat(-20, 70)
lng = fuzzy.FuzzyFloat(-180, 180)
featured_date = fuzzy.FuzzyDateTime(now() - timedelta(days=10), now())
testing = fuzzy.FuzzyChoice(choices=[True, False])
last_seen = fuzzy.FuzzyDateTime(now() - timedelta(days=3), now())
horizon = fuzzy.FuzzyInteger(10, 20)
@factory.post_generation
def antennas(self, create, extracted, **kwargs):
if not create:
return
if extracted:
for antenna in extracted:
if random.randint(0, 1):
self.antenna.add(antenna)
class Meta:
model = Station
class SatelliteFactory(factory.django.DjangoModelFactory):
"""Sattelite model factory."""
norad_cat_id = fuzzy.FuzzyInteger(2000, 4000)
name = fuzzy.FuzzyText()
class Meta:
model = Satellite
class TleFactory(factory.django.DjangoModelFactory):
"""Tle model factory."""
tle0 = 'ISS (ZARYA)'
tle1 = '1 25544U 98067A 17355.27738426 .00002760 00000-0 48789-4 0 9995'
tle2 = '2 25544 51.6403 185.6460 0002546 270.9261 71.9125 15.54204066 90844'
updated = fuzzy.FuzzyDateTime(now() - timedelta(days=3), now())
satellite = factory.SubFactory(SatelliteFactory)
class Meta:
model = Tle
class ObservationFactory(factory.django.DjangoModelFactory):
"""Observation model factory."""
satellite = factory.SubFactory(SatelliteFactory)
tle = factory.SubFactory(TleFactory)
author = factory.SubFactory(UserFactory)
start = fuzzy.FuzzyDateTime(now() - timedelta(days=3),
now() + timedelta(days=3))
end = factory.LazyAttribute(
lambda x: x.start + timedelta(hours=random.randint(1, 8))
)
ground_station = factory.Iterator(Station.objects.all())
payload = factory.django.FileField(filename='data.ogg')
vetted_datetime = factory.LazyAttribute(
lambda x: x.end + timedelta(hours=random.randint(1, 20))
)
vetted_user = factory.SubFactory(UserFactory)
vetted_status = fuzzy.FuzzyChoice(choices=OBSERVATION_STATUS_IDS)
transmitter_uuid = fuzzy.FuzzyText(length=20)
transmitter_description = fuzzy.FuzzyText()
transmitter_uplink_low = fuzzy.FuzzyInteger(200000000, 500000000, step=10000)
transmitter_uplink_high = fuzzy.FuzzyInteger(200000000, 500000000, step=10000)
transmitter_downlink_low = fuzzy.FuzzyInteger(200000000, 500000000, step=10000)
transmitter_downlink_high = fuzzy.FuzzyInteger(200000000, 500000000, step=10000)
transmitter_mode = fuzzy.FuzzyText(length=10)
transmitter_invert = fuzzy.FuzzyChoice(choices=[True, False])
transmitter_baud = fuzzy.FuzzyInteger(4000, 22000, step=1000)
transmitter_created = fuzzy.FuzzyDateTime(now() - timedelta(days=100),
now() - timedelta(days=3))
class Meta:
model = Observation
class DemodDataFactory(factory.django.DjangoModelFactory):
observation = factory.Iterator(Observation.objects.all())
payload_demod = factory.django.FileField()
class Meta:
model = DemodData
@pytest.mark.django_db(transaction=True)
class HomeViewTest(TestCase):
"""
Simple test to make sure the home page is working
"""
def test_home_page(self):
response = self.client.get('/')
self.assertContains(response, 'Crowd-sourced satellite operations')
@pytest.mark.django_db(transaction=True)
class AboutViewTest(TestCase):
"""
Simple test to make sure the about page is working
"""
def test_about_page(self):
response = self.client.get('/about/')
self.assertContains(response, 'SatNOGS Network is a global management interface')
@pytest.mark.django_db
class StationListViewTest(TestCase):
"""
Test to ensure the station list is generated by Django
"""
client = Client()
stations = []
def setUp(self):
for x in xrange(1, 10):
self.stations.append(StationFactory())
def test_station_list(self):
response = self.client.get('/stations/')
for x in self.stations:
self.assertContains(response, x.owner)
self.assertContains(response, x.name)
@pytest.mark.django_db(transaction=True)
class ObservationsListViewTest(TestCase):
"""
Test to ensure the observation list is generated by Django
"""
client = Client()
observations = []
satellites = []
stations = []
def setUp(self):
# Clear the data and create some new random data
with transaction.atomic():
Observation.objects.all().delete()
Satellite.objects.all().delete()
self.satellites = []
self.observations_bad = []
self.observations_good = []
self.observations_unvetted = []
self.observations = []
with transaction.atomic():
for x in xrange(1, 10):
self.satellites.append(SatelliteFactory())
for x in xrange(1, 10):
self.stations.append(StationFactory())
for x in xrange(1, 5):
obs = ObservationFactory(vetted_status='bad')
self.observations_bad.append(obs)
self.observations.append(obs)
for x in xrange(1, 5):
obs = ObservationFactory(vetted_status='good')
self.observations_good.append(obs)
self.observations.append(obs)
for x in xrange(1, 5):
obs = ObservationFactory(vetted_status='unknown')
self.observations_unvetted.append(obs)
self.observations.append(obs)
def test_observations_list(self):
response = self.client.get('/observations/')
for x in self.observations:
self.assertContains(response, x.transmitter_mode)
def test_observations_list_select_bad(self):
response = self.client.get('/observations/?bad=1')
for x in self.observations_bad:
self.assertContains(response, x.transmitter_mode)
def test_observations_list_select_good(self):
response = self.client.get('/observations/?good=1')
for x in self.observations_good:
self.assertContains(response, x.transmitter_mode)
def test_observations_list_select_unvetted(self):
response = self.client.get('/observations/?unvetted=1')
for x in self.observations_unvetted:
self.assertContains(response, x.transmitter_mode)
class NotFoundErrorTest(TestCase):
"""
Test the 404 not found handler
"""
client = Client()
def test_404_not_found(self):
response = self.client.get('/blah')
self.assertEquals(response.status_code, 404)
class RobotsViewTest(TestCase):
"""
Test the robots.txt handler
"""
client = Client()
def test_robots(self):
response = self.client.get('/robots.txt')
self.assertContains(response, 'Disallow: /')
@pytest.mark.django_db(transaction=True)
class ObservationViewTest(TestCase):
"""
Test to ensure the observation list is generated by Django
"""
client = Client()
observation = None
satellites = []
stations = []
user = None
def setUp(self):
self.user = UserFactory()
g = Group.objects.get(name='Moderators')
g.user_set.add(self.user)
for x in xrange(1, 10):
self.satellites.append(SatelliteFactory())
for x in xrange(1, 10):
self.stations.append(StationFactory())
self.observation = ObservationFactory()
def test_observation(self):
response = self.client.get('/observations/%d/' % self.observation.id)
self.assertContains(response, self.observation.author.username)
self.assertContains(response, self.observation.transmitter_mode)
@pytest.mark.django_db(transaction=True)
class ObservationDeleteTest(TestCase):
"""
Test to ensure the observation list is generated by Django
"""
client = Client()
user = None
future_observation = None
past_observation = None
satellites = []
def setUp(self):
self.user = UserFactory()
self.client.force_login(self.user)
for x in xrange(1, 10):
self.satellites.append(SatelliteFactory())
self.future_observation = ObservationFactory()
self.future_observation.author = self.user
self.future_observation.start = now() + timedelta(days=1)
self.future_observation.end = self.future_observation.start + timedelta(minutes=15)
self.future_observation.save()
self.past_observation = ObservationFactory()
self.past_observation.author = self.user
self.past_observation.start = now() - timedelta(days=1)
self.past_observation.end = self.past_observation.start + timedelta(minutes=15)
self.past_observation.save()
def test_future_observation_delete_author(self):
"""Deletion OK when user is the author of the observation and observation is in future"""
response = self.client.get('/observations/%d/delete/' % self.future_observation.id)
self.assertRedirects(response, '/observations/')
response = self.client.get('/observations/')
with self.assertRaises(Observation.DoesNotExist):
_lookup = Observation.objects.get(pk=self.future_observation.id) # noqa:F841
def test_future_observation_delete_moderator(self):
"""Deletion OK when user is moderator and observation is in future"""
self.user = UserFactory()
g = Group.objects.get(name='Moderators')
g.user_set.add(self.user)
self.client.force_login(self.user)
response = self.client.get('/observations/%d/delete/' % self.future_observation.id)
self.assertRedirects(response, '/observations/')
response = self.client.get('/observations/')
with self.assertRaises(Observation.DoesNotExist):
_lookup = Observation.objects.get(pk=self.future_observation.id) # noqa:F841
def test_past_observation_delete_author(self):
"""Deletion NOT OK when user is the author of the observation and observation is in past"""
response = self.client.get('/observations/%d/delete/' % self.past_observation.id)
self.assertRedirects(response, '/observations/')
response = self.client.get('/observations/')
self.assertContains(response, self.past_observation.id)
def test_past_observation_delete_moderator(self):
"""Deletion NOT OK when user is moderator and observation is in past"""
self.user = UserFactory()
g = Group.objects.get(name='Moderators')
g.user_set.add(self.user)
self.client.force_login(self.user)
response = self.client.get('/observations/%d/delete/' % self.past_observation.id)
self.assertRedirects(response, '/observations/')
response = self.client.get('/observations/')
self.assertContains(response, self.past_observation.id)
@pytest.mark.django_db(transaction=True)
class StationViewTest(TestCase):
"""
Test to ensure the observation list is generated by Django
"""
client = Client()
station = None
def setUp(self):
self.station = StationFactory()
def test_observation(self):
response = self.client.get('/stations/%d/' % self.station.id)
self.assertContains(response, self.station.owner.username)
self.assertContains(response, self.station.alt)
self.assertContains(response, self.station.horizon)
@pytest.mark.django_db(transaction=True)
class StationDeleteTest(TestCase):
"""
Test to ensure the observation list is generated by Django
"""
client = Client()
station = None
user = None
def setUp(self):
self.user = UserFactory()
self.client.force_login(self.user)
self.station = StationFactory()
self.station.owner = self.user
self.station.save()
def test_station_delete(self):
response = self.client.get('/stations/%d/delete/' % self.station.id)
self.assertRedirects(response, '/users/%s/' % self.user.username)
with self.assertRaises(Station.DoesNotExist):
_lookup = Station.objects.get(pk=self.station.id) # noqa:F841
@pytest.mark.django_db(transaction=True)
class SettingsSiteViewTest(TestCase):
"""
Test to ensure the satellite fetch feature works
"""
client = Client()
user = None
def setUp(self):
self.user = UserFactory()
self.user.is_superuser = True
self.user.save()
self.client.force_login(self.user)
def test_get(self):
response = self.client.get('/settings_site/')
self.assertContains(response, 'Fetch Data')
@pytest.mark.django_db(transaction=True)
class ObservationModelTest(TestCase):
"""
Test various properties of the Observation Model
"""
observation = None
satellites = []
user = None
admin = None
def setUp(self):
for x in xrange(1, 10):
self.satellites.append(SatelliteFactory())
self.observation = ObservationFactory()
self.observation.end = now()
self.observation.save()
def test_is_passed(self):
self.assertTrue(self.observation.is_past)