Skip to content

Commit 0917aab

Browse files
committed
Add serializer tests
1 parent cd6ae83 commit 0917aab

File tree

6 files changed

+107
-1
lines changed

6 files changed

+107
-1
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Generated by Django 5.2.3 on 2025-07-04 13:18
2+
3+
import concurrency.fields
4+
import django.db.models.deletion
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
dependencies = [
10+
("country_workspace", "0018_rdp_hope_rdi_id_alter_rdp_status"),
11+
]
12+
13+
operations = [
14+
migrations.CreateModel(
15+
name="DataSerializer",
16+
fields=[
17+
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
18+
("last_modified", models.DateTimeField(auto_now=True)),
19+
("version", concurrency.fields.IntegerVersionField(default=0, help_text="record revision number")),
20+
("name", models.SlugField(max_length=64, unique=True)),
21+
("code", models.TextField()),
22+
],
23+
options={
24+
"abstract": False,
25+
},
26+
),
27+
migrations.AddField(
28+
model_name="program",
29+
name="serializer",
30+
field=models.ForeignKey(
31+
null=True, on_delete=django.db.models.deletion.SET_NULL, to="country_workspace.dataserializer"
32+
),
33+
),
34+
]

src/country_workspace/models/program.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import TYPE_CHECKING
1+
from typing import TYPE_CHECKING, Iterable
22

33
from django.db import models
44
from django.utils.translation import gettext as _
@@ -123,3 +123,8 @@ def get_checker_for(self, m: type[Validable] | Validable) -> DataChecker:
123123
if isinstance(m, (Individual | CountryIndividual)) or m in (Individual, CountryIndividual):
124124
return self.individual_checker
125125
raise ValueError(m)
126+
127+
def serialize(self, data: list[dict]) -> Iterable:
128+
if self.serializer:
129+
return self.serializer.serialize(data)
130+
return data

tests/extras/testutils/factories/program.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from .base import AutoRegisterModelFactory
77
from .office import OfficeFactory
8+
from .serializer import DataSerializerFactory
89
from .smart_import import DataCheckerFactory
910

1011

@@ -29,6 +30,7 @@ class ProgramFactory(AutoRegisterModelFactory):
2930
household_checker = factory.SubFactory(DataCheckerFactory)
3031
individual_checker = factory.SubFactory(DataCheckerFactory)
3132
beneficiary_group = factory.SubFactory(BeneficiaryGroupFactory)
33+
serializer = factory.SubFactory(DataSerializerFactory)
3234

3335
class Meta:
3436
model = Program
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import factory
2+
from country_workspace.models.serializer import DataSerializer
3+
from .base import AutoRegisterModelFactory
4+
5+
6+
class DataSerializerFactory(AutoRegisterModelFactory):
7+
name = factory.Sequence(lambda n: f"serializer-{n}")
8+
code = "function test(data) { return data; }"
9+
10+
class Meta:
11+
model = DataSerializer
12+
django_get_or_create = ("name",)

tests/models/test_m_program.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import pytest
2+
3+
from country_workspace.models import Program
4+
from testutils.factories import ProgramFactory
5+
6+
7+
@pytest.fixture
8+
def program():
9+
return ProgramFactory()
10+
11+
12+
def test_program_serialize(program: Program):
13+
data = [{"foo": "bar"}]
14+
result = program.serialize(data)
15+
assert result == data
16+
17+
18+
def test_program_no_serializer(program: Program):
19+
program.serializer = None
20+
data = [{"foo": "bar"}]
21+
result = program.serialize(data)
22+
assert result == data

tests/models/test_m_serializer.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import pytest
2+
from django.core.exceptions import ValidationError
3+
4+
from country_workspace.models.serializer import DataSerializer
5+
from testutils.factories.serializer import DataSerializerFactory
6+
7+
8+
@pytest.fixture
9+
def data_serializer():
10+
return DataSerializerFactory()
11+
12+
13+
def test_serialize(data_serializer: DataSerializer):
14+
data = [{"foo": "bar"}]
15+
result = data_serializer.serialize(data)
16+
assert result == data
17+
18+
19+
def test_str(data_serializer: DataSerializer):
20+
assert str(data_serializer) == f"DataSerializer: {data_serializer.name}"
21+
22+
23+
def test_clean_valid(data_serializer: DataSerializer):
24+
data_serializer.clean()
25+
26+
27+
@pytest.mark.parametrize("code", ["", "function {"])
28+
def test_clean_invalid_js(data_serializer: DataSerializer, code: str):
29+
data_serializer.code = code
30+
with pytest.raises(ValidationError, match="Invalid JavaScript code"):
31+
data_serializer.clean()

0 commit comments

Comments
 (0)