Skip to content

Commit 6740a0a

Browse files
committed
Add unit tests.
1 parent 2a59bdc commit 6740a0a

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

tests/model_fields_/test_objectidfield.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,10 @@ def test_to_python_invalid_value(self):
3232
msg = f"['“{invalid_value}” value must be an Object Id.']"
3333
with self.assertRaisesMessage(exceptions.ValidationError, msg):
3434
ObjectIdField().to_python(invalid_value)
35+
36+
def test_get_prep_value_invalud_values(self):
37+
for invalid_value in [3, "None", {}, []]:
38+
with self.subTest(invalid_value=invalid_value):
39+
msg = f"Field '{None}' expected an ObjectId but got {invalid_value!r}."
40+
with self.assertRaisesMessage(ValueError, msg):
41+
ObjectIdField().get_prep_value(invalid_value)

tests/queries_/models.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from django.db import models
22

3+
from django_mongodb.fields import ObjectIdField
4+
35

46
class Author(models.Model):
57
name = models.CharField(max_length=10)
@@ -14,3 +16,18 @@ class Book(models.Model):
1416

1517
def __str__(self):
1618
return self.title
19+
20+
21+
class Tag(models.Model):
22+
name = models.CharField(max_length=10)
23+
parent = models.ForeignKey(
24+
"self",
25+
models.SET_NULL,
26+
blank=True,
27+
null=True,
28+
related_name="children",
29+
)
30+
group_id = ObjectIdField(null=True)
31+
32+
def __str__(self):
33+
return self.name

tests/queries_/test_objectid.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
from bson import ObjectId
2+
from django.test import TestCase
3+
4+
from .models import Tag
5+
6+
7+
class QueriesFilterByObjectId(TestCase):
8+
@classmethod
9+
def setUpTestData(cls):
10+
cls.group_id_str_1 = "1" * 24
11+
cls.group_id_obj_1 = ObjectId(cls.group_id_str_1)
12+
cls.group_id_str_2 = "2" * 24
13+
cls.group_id_obj_2 = ObjectId(cls.group_id_str_2)
14+
15+
cls.t1 = Tag.objects.create(name="t1")
16+
cls.t2 = Tag.objects.create(name="t2", parent=cls.t1)
17+
cls.t3 = Tag.objects.create(name="t3", parent=cls.t1, group_id=cls.group_id_str_1)
18+
cls.t4 = Tag.objects.create(name="t4", parent=cls.t3, group_id=cls.group_id_obj_2)
19+
cls.t5 = Tag.objects.create(name="t5", parent=cls.t3)
20+
21+
def test_filter_group_id_is_null(self):
22+
"""Filter objects where group_id is not null"""
23+
for value, expected in [(False, [self.t3, self.t4]), (True, [self.t1, self.t2, self.t5])]:
24+
with self.subTest(object_id=value):
25+
qs = Tag.objects.filter(group_id__isnull=value).order_by("name")
26+
self.assertSequenceEqual(qs, expected)
27+
28+
def test_filter_group_id_equal_value(self):
29+
"""Filter by group_id with a specific value"""
30+
for value in [self.group_id_str_1, self.group_id_obj_1]:
31+
with self.subTest(object_id=value):
32+
qs = Tag.objects.filter(group_id=value).order_by("name")
33+
self.assertSequenceEqual(qs, [self.t3])
34+
35+
def test_filter_group_id_in_value(self):
36+
"""Filter by group_id where value is in a list"""
37+
test_cases = [
38+
[self.group_id_str_1, self.group_id_str_2],
39+
[self.group_id_obj_1, self.group_id_obj_2],
40+
]
41+
for values in test_cases:
42+
with self.subTest(values=values):
43+
qs = Tag.objects.filter(group_id__in=values).order_by("name")
44+
self.assertSequenceEqual(qs, [self.t3, self.t4])
45+
46+
def test_filter_group_id_equal_subquery(self):
47+
"""Filter by group_id using a subquery"""
48+
subquery = Tag.objects.filter(name="t3").values("group_id")
49+
for value in [self.group_id_str_1, self.group_id_obj_1]:
50+
with self.subTest(object_id=value):
51+
qs = Tag.objects.filter(group_id__in=subquery).order_by("name")
52+
self.assertSequenceEqual(qs, [self.t3])
53+
54+
def test_filter_group_id_in_subquery(self):
55+
"""Filter by group_id using a subquery with multiple values"""
56+
subquery = Tag.objects.filter(name__in=["t3", "t4"]).values("group_id")
57+
test_cases = [
58+
[self.group_id_str_1, self.group_id_str_2],
59+
[self.group_id_obj_1, self.group_id_obj_2],
60+
]
61+
for values in test_cases:
62+
with self.subTest(values=values):
63+
qs = Tag.objects.filter(group_id__in=subquery).order_by("name")
64+
self.assertSequenceEqual(qs, [self.t3, self.t4])
65+
66+
def test_union_children_to_select_parents(self):
67+
"""Union query to select parents of children based on group_id"""
68+
child_group_ids = [self.group_id_str_1, self.group_id_obj_1]
69+
for group_id in child_group_ids:
70+
with self.subTest(group_id=group_id):
71+
child_ids = Tag.objects.filter(group_id=group_id).values_list("id", flat=True)
72+
parent_qs = (
73+
Tag.objects.filter(children__id__in=child_ids).distinct().order_by("name")
74+
)
75+
self.assertSequenceEqual(parent_qs, [self.t1])
76+
77+
def test_filter_group_id_union_with(self):
78+
"""Combine queries using union"""
79+
test_cases = [
80+
(self.group_id_str_1, self.group_id_str_2),
81+
(self.group_id_obj_1, self.group_id_obj_2),
82+
]
83+
for value1, value2 in test_cases:
84+
with self.subTest(value1=value1, value2=value2):
85+
qs_a = Tag.objects.filter(group_id=value1)
86+
qs_b = Tag.objects.filter(group_id=value2)
87+
union_qs = qs_a.union(qs_b).order_by("name")
88+
self.assertSequenceEqual(union_qs, [self.t3, self.t4])
89+
90+
def test_invalid_object_id(self):
91+
"""Combine queries using union"""
92+
value = "value1"
93+
msg = f"Field 'group_id' expected an ObjectId but got '{value}'."
94+
with self.assertRaisesMessage(ValueError, msg):
95+
Tag.objects.filter(group_id=value)

0 commit comments

Comments
 (0)