diff --git a/crashreport_stats/tests.py b/crashreport_stats/tests.py
index 7ce503c..a204d42 100644
--- a/crashreport_stats/tests.py
+++ b/crashreport_stats/tests.py
@@ -1,3 +1,440 @@
-from django.test import TestCase
+"""Test crashreport_stats models and the 'stats' command."""
+from datetime import datetime, date
+import pytz
 
-# Create your tests here.
+from django.urls import reverse
+from django.utils.http import urlencode
+
+from rest_framework import status
+from rest_framework.test import APITestCase, APIClient
+
+from crashreport_stats.models import (
+    Version, VersionDaily, RadioVersion, RadioVersionDaily
+)
+
+from crashreports.models import User, Device
+
+
+class Dummy():
+    """Class for creating dummy instances for testing."""
+
+    # Valid unique entries
+    BUILD_FINGERPRINTS = [(
+        'Fairphone/FP2/FP2:5.1/FP2/r4275.1_FP2_gms76_1.13.0:user/release-keys'
+    ), (
+        'Fairphone/FP2/FP2:5.1.1/FP2-gms75.1.13.0/FP2-gms75.1.13.0'
+        ':user/release-keys'
+    ), (
+        'Fairphone/FP2/FP2:6.0.1/FP2-gms-18.04.1/FP2-gms-18.04.1'
+        ':user/release-keys'
+    ), (
+        'Fairphone/FP2/FP2:7.1.2/18.07.2/gms-7480c31d'
+        ':user/release-keys'
+    )]
+    RADIO_VERSIONS = ['4437.1-FP2-0-07', '4437.1-FP2-0-08',
+                      '4437.1-FP2-0-09', '4437.1-FP2-0-10']
+
+    DATES = [date(2018, 3, 19), date(2018, 3, 26), date(2018, 5, 1)]
+
+    DEFAULT_DUMMY_VERSION_VALUES = {
+        'build_fingerprint': BUILD_FINGERPRINTS[0],
+        'first_seen_on': DATES[1],
+        'released_on': DATES[0]
+    }
+
+    DEFAULT_DUMMY_VERSION_DAILY_VALUES = {
+        'date': DATES[1]
+    }
+
+    DEFAULT_DUMMY_RADIO_VERSION_VALUES = {
+        'radio_version': RADIO_VERSIONS[0],
+        'first_seen_on': DATES[1],
+        'released_on': DATES[0]
+    }
+
+    DEFAULT_DUMMY_RADIO_VERSION_DAILY_VALUES = {
+        'date': DATES[1]
+    }
+
+    DEFAULT_DUMMY_DEVICE_VALUES = {
+        'board_date': datetime(2015, 12, 15, 1, 23, 45, tzinfo=pytz.utc),
+        'chipset': 'Qualcomm MSM8974PRO-AA',
+        'token': '64111c62d521fb4724454ca6dea27e18f93ef56e'
+    }
+
+    DEFAULT_DUMMY_USER_VALUES = {
+        'username': 'testuser'
+    }
+
+    @staticmethod
+    def update_copy(original, update):
+        """Merge fields of update into a copy of original."""
+        data = original.copy()
+        data.update(update)
+        return data
+
+    @staticmethod
+    def create_dummy_user(**kwargs):
+        """Create a dummy user instance.
+
+        The dummy instance is created and saved to the database.
+        Args:
+            **kwargs:
+                Optional arguments to extend/overwrite the default values.
+
+        Returns: The created user instance.
+
+        """
+        entity = User(**Dummy.update_copy(
+            Dummy.DEFAULT_DUMMY_USER_VALUES, kwargs))
+        entity.save()
+        return entity
+
+    @staticmethod
+    def create_dummy_device(user, **kwargs):
+        """Create a dummy device instance.
+
+        The dummy instance is created and saved to the database.
+        Args:
+            user: The user instance that the device should relate to
+            **kwargs:
+                Optional arguments to extend/overwrite the default values.
+
+        Returns: The created device instance.
+
+        """
+        entity = Device(user=user, **Dummy.update_copy(
+            Dummy.DEFAULT_DUMMY_DEVICE_VALUES, kwargs))
+        entity.save()
+        return entity
+
+    @staticmethod
+    def create_dummy_version(**kwargs):
+        """Create a dummy version instance.
+
+        The dummy instance is created and saved to the database.
+        Args:
+            **kwargs:
+                Optional arguments to extend/overwrite the default values.
+
+        Returns: The created version instance.
+
+        """
+        entity = Version(**Dummy.update_copy(
+            Dummy.DEFAULT_DUMMY_VERSION_VALUES, kwargs))
+        entity.save()
+        return entity
+
+    @staticmethod
+    def create_dummy_radio_version(**kwargs):
+        """Create a dummy radio version instance.
+
+        The dummy instance is created and saved to the database.
+        Args:
+            **kwargs:
+                Optional arguments to extend/overwrite the default values.
+
+        Returns: The created radio version instance.
+
+        """
+        entity = RadioVersion(**Dummy.update_copy(
+            Dummy.DEFAULT_DUMMY_RADIO_VERSION_VALUES, kwargs))
+        entity.save()
+        return entity
+
+    @staticmethod
+    def create_dummy_daily_version(version, **kwargs):
+        """Create a dummy daily version instance.
+
+        The dummy instance is created and saved to the database.
+        Args:
+            **kwargs:
+                Optional arguments to extend/overwrite the default values.
+
+        Returns: The created daily version instance.
+
+        """
+        entity = VersionDaily(version=version, **Dummy.update_copy(
+            Dummy.DEFAULT_DUMMY_VERSION_DAILY_VALUES, kwargs))
+        entity.save()
+        return entity
+
+    @staticmethod
+    def create_dummy_daily_radio_version(version, **kwargs):
+        """Create a dummy daily radio version instance.
+
+        The dummy instance is created and saved to the database.
+        Args:
+            **kwargs:
+                Optional arguments to extend/overwrite the default values.
+
+        Returns: The created daily radio version instance.
+
+        """
+        entity = RadioVersionDaily(version=version, **Dummy.update_copy(
+            Dummy.DEFAULT_DUMMY_RADIO_VERSION_DAILY_VALUES, kwargs))
+        entity.save()
+        return entity
+
+
+class _VersionTestCase(APITestCase):
+    """Abstract class for version-related test cases to inherit from."""
+
+    # The attribute name characterising the unicity of a stats entry (the
+    # named identifier)
+    unique_entry_name = 'build_fingerprint'
+    # The collection of unique entries to post
+    unique_entries = Dummy.BUILD_FINGERPRINTS
+    # The URL to retrieve the stats entries from
+    endpoint_url = reverse('hiccup_stats_api_v1_versions')
+
+    @classmethod
+    def setUpTestData(cls):  # noqa: N802
+        """Create an admin user for accessing the API.
+
+        The APIClient that can be used to make authenticated requests to the
+        server is stored in self.admin.
+        """
+        admin_user = User.objects.create_superuser(
+            'somebody', 'somebody@example.com', 'thepassword')
+        cls.admin = APIClient()
+        cls.admin.force_authenticate(admin_user)
+
+    @staticmethod
+    def _create_dummy_version(**kwargs):
+        return Dummy.create_dummy_version(**kwargs)
+
+    def _get_with_params(self, url, params):
+        return self.admin.get('{}?{}'.format(url, urlencode(params)))
+
+    def _assert_result_length_is(self, response, count):
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertIn('results', response.data)
+        self.assertIn('count', response.data)
+        self.assertEqual(response.data['count'], count)
+        self.assertEqual(len(response.data['results']), count)
+
+    def _assert_device_owner_has_no_get_access(self, entries_url):
+        # Create a user and device
+        user = Dummy.create_dummy_user()
+        device = Dummy.create_dummy_device(user=user)
+
+        # Create authenticated client
+        user = APIClient()
+        user.credentials(HTTP_AUTHORIZATION='Token ' + device.token)
+
+        # Try getting entries using the client
+        response = user.get(entries_url)
+        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
+
+    def _assert_filter_result_matches(self, filter_params, expected_result):
+        # List entities with filter
+        response = self._get_with_params(self.endpoint_url, filter_params)
+
+        # Expect only the single matching result to be returned
+        self._assert_result_length_is(response, 1)
+        self.assertEqual(response.data['results'][0][self.unique_entry_name],
+                         getattr(expected_result, self.unique_entry_name))
+
+
+class VersionTestCase(_VersionTestCase):
+    """Test the Version and REST endpoint."""
+
+    def _create_version_entities(self):
+        versions = [
+            self._create_dummy_version(
+                **{self.unique_entry_name: unique_entry}
+            )
+            for unique_entry in self.unique_entries
+        ]
+        return versions
+
+    def test_list_versions_without_authentication(self):
+        """Test listing of versions without authentication."""
+        response = self.client.get(self.endpoint_url)
+        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
+
+    def test_list_versions_as_device_owner(self):
+        """Test listing of versions as device owner."""
+        self._assert_device_owner_has_no_get_access(self.endpoint_url)
+
+    def test_list_versions_empty_database(self):
+        """Test listing of versions on an empty database."""
+        response = self.admin.get(self.endpoint_url)
+        self._assert_result_length_is(response, 0)
+
+    def test_list_versions(self):
+        """Test listing versions."""
+        versions = self._create_version_entities()
+        response = self.admin.get(self.endpoint_url)
+        self._assert_result_length_is(response, len(versions))
+
+    def test_filter_versions_by_unique_entry_name(self):
+        """Test filtering versions by their unique entry name."""
+        versions = self._create_version_entities()
+        response = self.admin.get(self.endpoint_url)
+
+        # Listing all entities should return the correct result length
+        self._assert_result_length_is(response, len(versions))
+
+        # List entities with filter
+        filter_params = {
+            self.unique_entry_name: getattr(versions[0],
+                                            self.unique_entry_name)
+        }
+        self._assert_filter_result_matches(filter_params,
+                                           expected_result=versions[0])
+
+    def test_filter_versions_by_release_type(self):
+        """Test filtering versions by release type."""
+        # Create versions for all combinations of release types
+        versions = []
+        i = 0
+        for is_official_release in True, False:
+            for is_beta_release in True, False:
+                versions.append(self._create_dummy_version(**{
+                    'is_official_release': is_official_release,
+                    'is_beta_release': is_beta_release,
+                    self.unique_entry_name: self.unique_entries[i]
+                }))
+                i += 1
+
+        # # Listing all entities should return the correct result length
+        response = self.admin.get(self.endpoint_url)
+        self._assert_result_length_is(response, len(versions))
+
+        # List each of the entities with the matching filter params
+        for version in versions:
+            filter_params = {
+                'is_official_release': version.is_official_release,
+                'is_beta_release': version.is_beta_release
+            }
+            self._assert_filter_result_matches(filter_params,
+                                               expected_result=version)
+
+    def test_filter_versions_by_first_seen_date(self):
+        """Test filtering versions by first seen date."""
+        versions = self._create_version_entities()
+
+        # Set the first seen date of an entity
+        versions[0].first_seen_on = Dummy.DATES[2]
+        versions[0].save()
+
+        # Listing all entities should return the correct result length
+        response = self.admin.get(self.endpoint_url)
+        self._assert_result_length_is(response, len(versions))
+
+        # Expect the single matching result to be returned
+        filter_params = {'first_seen_after': Dummy.DATES[2]}
+        self._assert_filter_result_matches(filter_params,
+                                           expected_result=versions[0])
+
+
+# pylint: disable=too-many-ancestors
+class RadioVersionTestCase(VersionTestCase):
+    """Test the RadioVersion REST endpoint."""
+
+    unique_entry_name = 'radio_version'
+    unique_entries = Dummy.RADIO_VERSIONS
+    endpoint_url = reverse('hiccup_stats_api_v1_radio_versions')
+
+    @staticmethod
+    def _create_dummy_version(**kwargs):
+        return Dummy.create_dummy_radio_version(**kwargs)
+
+
+class VersionDailyTestCase(_VersionTestCase):
+    """Test the VersionDaily REST endpoint."""
+
+    endpoint_url = reverse('hiccup_stats_api_v1_version_daily')
+
+    @staticmethod
+    def _create_dummy_daily_version(version, **kwargs):
+        return Dummy.create_dummy_daily_version(version, **kwargs)
+
+    def _create_version_entities(self):
+        versions = [
+            self._create_dummy_version(
+                **{self.unique_entry_name: unique_entry}
+            )
+            for unique_entry in self.unique_entries
+        ]
+        versions_daily = [
+            self._create_dummy_daily_version(version=version)
+            for version in versions
+        ]
+        return versions_daily
+
+    def test_list_daily_versions_without_authentication(self):
+        """Test listing of daily versions without authentication."""
+        response = self.client.get(self.endpoint_url)
+        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
+
+    def test_list_daily_versions_as_device_owner(self):
+        """Test listing of daily versions as device owner."""
+        self._assert_device_owner_has_no_get_access(self.endpoint_url)
+
+    def test_list_daily_versions_empty_database(self):
+        """Test listing of daily versions on an empty database."""
+        response = self.admin.get(self.endpoint_url)
+        self._assert_result_length_is(response, 0)
+
+    def test_list_daily_versions(self):
+        """Test listing daily versions."""
+        versions_daily = self._create_version_entities()
+        response = self.admin.get(self.endpoint_url)
+        self._assert_result_length_is(response, len(versions_daily))
+
+    def test_filter_daily_versions_by_version(self):
+        """Test filtering versions by the version they relate to."""
+        # Create VersionDaily entities
+        versions = self._create_version_entities()
+
+        # Listing all entities should return the correct result length
+        response = self.admin.get(self.endpoint_url)
+        self._assert_result_length_is(response, len(versions))
+
+        # List entities with filter
+        param_name = 'version__' + self.unique_entry_name
+        filter_params = {
+            param_name: getattr(versions[0].version, self.unique_entry_name)
+        }
+        self._assert_filter_result_matches(filter_params,
+                                           expected_result=versions[0].version)
+
+    def test_filter_daily_versions_by_date(self):
+        """Test filtering daily versions by date."""
+        # Create Version and VersionDaily entities
+        versions = self._create_version_entities()
+
+        # Update the date
+        versions[0].date = Dummy.DATES[2]
+        versions[0].save()
+
+        # Listing all entities should return the correct result length
+        response = self.admin.get(self.endpoint_url)
+        self._assert_result_length_is(response, len(versions))
+
+        # Expect the single matching result to be returned
+        filter_params = {'date': versions[0].date}
+        self._assert_filter_result_matches(filter_params,
+                                           expected_result=versions[0].version)
+
+
+class RadioVersionDailyTestCase(VersionDailyTestCase):
+    """Test the RadioVersionDaily REST endpoint."""
+
+    unique_entry_name = 'radio_version'
+    unique_entries = Dummy.RADIO_VERSIONS
+    endpoint_url = reverse('hiccup_stats_api_v1_radio_version_daily')
+
+    @staticmethod
+    def _create_dummy_version(**kwargs):
+        entity = RadioVersion(**Dummy.update_copy(
+            Dummy.DEFAULT_DUMMY_RADIO_VERSION_VALUES, kwargs))
+        entity.save()
+        return entity
+
+    @staticmethod
+    def _create_dummy_daily_version(version, **kwargs):
+        return Dummy.create_dummy_daily_radio_version(version, **kwargs)
