Skip to content

Commit f8478c6

Browse files
committed
api tests
1 parent 83d4a92 commit f8478c6

25 files changed

Lines changed: 1915 additions & 11 deletions

File tree

.github/workflows/lint-and-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
strategy:
1111
max-parallel: 5
1212
matrix:
13-
python-version: ['3.x']
13+
python-version: ['3.13']
1414
steps:
1515
- uses: actions/checkout@v4
1616
- name: Set up Python ${{ matrix.python-version }}

arch/tests/__init__.py

Whitespace-only changes.

arch/tests/test_api.py

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Copyright 2025 Marcus Furlong <furlongm@gmail.com>
2+
#
3+
# This file is part of Patchman.
4+
#
5+
# Patchman is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation, version 3 only.
8+
#
9+
# Patchman is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with Patchman. If not, see <http://www.gnu.org/licenses/>
16+
17+
from django.contrib.auth.models import User
18+
from django.test import TestCase, override_settings
19+
from rest_framework import status
20+
from rest_framework.test import APITestCase
21+
22+
from arch.models import MachineArchitecture, PackageArchitecture
23+
24+
25+
@override_settings(
26+
CELERY_TASK_ALWAYS_EAGER=True,
27+
CACHES={'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}
28+
)
29+
class ArchitectureAPITests(APITestCase):
30+
"""Tests for the Architecture API endpoints."""
31+
32+
def setUp(self):
33+
"""Set up test data."""
34+
self.user = User.objects.create_user(
35+
username='testuser', password='testpass'
36+
)
37+
self.client.force_authenticate(user=self.user)
38+
39+
self.machine_arch = MachineArchitecture.objects.create(name='x86_64')
40+
self.pkg_arch = PackageArchitecture.objects.create(name='amd64')
41+
42+
def test_list_machine_architectures(self):
43+
"""Test listing machine architectures."""
44+
response = self.client.get('/api/machine-architecture/')
45+
self.assertEqual(response.status_code, status.HTTP_200_OK)
46+
self.assertEqual(len(response.data['results']), 1)
47+
48+
def test_retrieve_machine_architecture(self):
49+
"""Test retrieving a machine architecture."""
50+
response = self.client.get(f'/api/machine-architecture/{self.machine_arch.id}/')
51+
self.assertEqual(response.status_code, status.HTTP_200_OK)
52+
self.assertEqual(response.data['name'], 'x86_64')
53+
54+
def test_list_package_architectures(self):
55+
"""Test listing package architectures."""
56+
response = self.client.get('/api/package-architecture/')
57+
self.assertEqual(response.status_code, status.HTTP_200_OK)
58+
self.assertEqual(len(response.data['results']), 1)
59+
60+
def test_retrieve_package_architecture(self):
61+
"""Test retrieving a package architecture."""
62+
response = self.client.get(f'/api/package-architecture/{self.pkg_arch.id}/')
63+
self.assertEqual(response.status_code, status.HTTP_200_OK)
64+
self.assertEqual(response.data['name'], 'amd64')
65+
66+
67+
@override_settings(
68+
CELERY_TASK_ALWAYS_EAGER=True,
69+
CACHES={'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}
70+
)
71+
class MachineArchitectureModelTests(TestCase):
72+
"""Tests for the MachineArchitecture model."""
73+
74+
def test_machine_architecture_creation(self):
75+
"""Test creating a machine architecture."""
76+
arch = MachineArchitecture.objects.create(name='aarch64')
77+
self.assertEqual(arch.name, 'aarch64')
78+
79+
def test_machine_architecture_string_representation(self):
80+
"""Test MachineArchitecture __str__ method."""
81+
arch = MachineArchitecture.objects.create(name='i686')
82+
self.assertEqual(str(arch), 'i686')
83+
84+
def test_machine_architecture_unique_name(self):
85+
"""Test that machine architecture names must be unique."""
86+
MachineArchitecture.objects.create(name='unique-arch')
87+
from django.db import IntegrityError
88+
with self.assertRaises(IntegrityError):
89+
MachineArchitecture.objects.create(name='unique-arch')
90+
91+
92+
@override_settings(
93+
CELERY_TASK_ALWAYS_EAGER=True,
94+
CACHES={'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}
95+
)
96+
class PackageArchitectureModelTests(TestCase):
97+
"""Tests for the PackageArchitecture model."""
98+
99+
def test_package_architecture_creation(self):
100+
"""Test creating a package architecture."""
101+
arch = PackageArchitecture.objects.create(name='arm64')
102+
self.assertEqual(arch.name, 'arm64')
103+
104+
def test_package_architecture_string_representation(self):
105+
"""Test PackageArchitecture __str__ method."""
106+
arch = PackageArchitecture.objects.create(name='noarch')
107+
self.assertEqual(str(arch), 'noarch')
108+
109+
def test_package_architecture_unique_name(self):
110+
"""Test that package architecture names must be unique."""
111+
PackageArchitecture.objects.create(name='all')
112+
from django.db import IntegrityError
113+
with self.assertRaises(IntegrityError):
114+
PackageArchitecture.objects.create(name='all')
115+
116+
def test_common_architectures(self):
117+
"""Test creating common architecture types."""
118+
archs = ['x86_64', 'amd64', 'i386', 'i686', 'noarch', 'all', 'arm64', 'aarch64']
119+
for arch_name in archs:
120+
arch = PackageArchitecture.objects.create(name=arch_name)
121+
self.assertEqual(str(arch), arch_name)

domains/tests/__init__.py

Whitespace-only changes.

domains/tests/test_api.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Copyright 2025 Marcus Furlong <furlongm@gmail.com>
2+
#
3+
# This file is part of Patchman.
4+
#
5+
# Patchman is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation, version 3 only.
8+
#
9+
# Patchman is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with Patchman. If not, see <http://www.gnu.org/licenses/>
16+
17+
from django.contrib.auth.models import User
18+
from django.test import TestCase, override_settings
19+
from rest_framework import status
20+
from rest_framework.test import APITestCase
21+
22+
from domains.models import Domain
23+
24+
25+
@override_settings(
26+
CELERY_TASK_ALWAYS_EAGER=True,
27+
CACHES={'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}
28+
)
29+
class DomainAPITests(APITestCase):
30+
"""Tests for the Domain API endpoints."""
31+
32+
def setUp(self):
33+
"""Set up test data."""
34+
self.user = User.objects.create_user(
35+
username='testuser', password='testpass'
36+
)
37+
self.client.force_authenticate(user=self.user)
38+
self.domain = Domain.objects.create(name='example.com')
39+
40+
def test_list_domains(self):
41+
"""Test listing all domains."""
42+
response = self.client.get('/api/domain/')
43+
self.assertEqual(response.status_code, status.HTTP_200_OK)
44+
self.assertEqual(len(response.data['results']), 1)
45+
46+
def test_retrieve_domain(self):
47+
"""Test retrieving a single domain."""
48+
response = self.client.get(f'/api/domain/{self.domain.id}/')
49+
self.assertEqual(response.status_code, status.HTTP_200_OK)
50+
self.assertEqual(response.data['name'], 'example.com')
51+
52+
53+
@override_settings(
54+
CELERY_TASK_ALWAYS_EAGER=True,
55+
CACHES={'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}
56+
)
57+
class DomainModelTests(TestCase):
58+
"""Tests for the Domain model."""
59+
60+
def test_domain_creation(self):
61+
"""Test creating a domain."""
62+
domain = Domain.objects.create(name='test.example.com')
63+
self.assertEqual(domain.name, 'test.example.com')
64+
65+
def test_domain_string_representation(self):
66+
"""Test Domain __str__ method."""
67+
domain = Domain.objects.create(name='prod.example.com')
68+
self.assertEqual(str(domain), 'prod.example.com')
69+
70+
def test_domain_unique_name(self):
71+
"""Test that domain names must be unique."""
72+
Domain.objects.create(name='unique.example.com')
73+
from django.db import IntegrityError
74+
with self.assertRaises(IntegrityError):
75+
Domain.objects.create(name='unique.example.com')
76+
77+
def test_extract_domain_from_fqdn(self):
78+
"""Test extracting domain from fully qualified domain name."""
79+
# Domain extraction is done elsewhere, but test the model can store it
80+
fqdn = 'server1.prod.example.com'
81+
domain_name = '.'.join(fqdn.split('.')[1:]) # prod.example.com
82+
domain = Domain.objects.create(name=domain_name)
83+
self.assertEqual(domain.name, 'prod.example.com')

errata/serializers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@
2222
class ErratumSerializer(serializers.HyperlinkedModelSerializer):
2323
class Meta:
2424
model = Erratum
25-
fields = ('id', 'name', 'e_type', 'issue_date', 'synopsis', 'cves', 'releases', 'references')
25+
fields = ('id', 'name', 'e_type', 'issue_date', 'synopsis', 'cves', 'osreleases', 'references')

errata/tests/__init__.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2025 Marcus Furlong <furlongm@gmail.com>
2+
#
3+
# This file is part of Patchman.
4+
#
5+
# Patchman is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation, version 3 only.
8+
#
9+
# Patchman is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with Patchman. If not, see <http://www.gnu.org/licenses/>

0 commit comments

Comments
 (0)