Coverage for tests/django_tests/test_serializer.py: 94%
127 statements
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-12 13:49 +0000
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-12 13:49 +0000
1from django_napse.utils.serializers.fields import Field, IntField, StrField, BoolField, DatetimeField, MethodField, UUIDField
2from django_napse.utils.serializers.serializer import Serializer, MetaSerializer
4from django_napse.core.models import Exchange, ExchangeAccount
5from django.test import TestCase
6from rest_framework.serializers import ValidationError
8"""
9python tests/test_app/manage.py test tests.django_tests.test_serializer -v2 --keepdb --parallel
10"""
13class ExchangeSerializer(Serializer):
14 Model = Exchange
15 name = StrField(required=True)
16 description = StrField()
17 test_int_field = IntField()
20class ExchangeAccountSerializer(Serializer):
21 Model = ExchangeAccount
22 uuid = UUIDField()
23 exchange = ExchangeSerializer(required=True)
24 name = StrField(required=True)
25 testing = BoolField(required=True)
26 description = StrField()
27 default = BoolField()
28 created_at = DatetimeField()
29 tickers = MethodField()
31 def get_tickers(self, instance):
32 return instance.exchange.get_tickers()
34 def validate_data(self, data):
35 data["testing"] = True
36 return super().validate_data(data)
39class SerializerSerializationTestCase(TestCase):
40 def setUp(self):
41 self.exchange = Exchange.objects.create(name="Binance", description="Binance exchange")
42 self.exchange_account = ExchangeAccount.objects.create(
43 exchange=self.exchange,
44 name="Binance Account",
45 testing=True,
46 description="Binance account description",
47 default=True,
48 )
50 def test_exchange_serialization(self):
51 self.exchange.test_int_field = 1 # Just for testing the int field
52 exchange_serializer = ExchangeSerializer(instance=self.exchange)
53 data = exchange_serializer.data
54 self.assertEqual(
55 data,
56 {
57 "name": "Binance",
58 "description": "Binance exchange",
59 "test_int_field": 1,
60 },
61 )
63 def test_exchange_account_serialization(self):
64 exchange_account_serializer = ExchangeAccountSerializer(self.exchange_account)
65 data = exchange_account_serializer.data
66 self.assertEqual(
67 data,
68 {
69 "uuid": str(self.exchange_account.uuid),
70 "exchange": {"name": "Binance", "description": "Binance exchange"},
71 "name": "Binance Account",
72 "testing": True,
73 "description": "Binance account description",
74 "default": True,
75 "created_at": self.exchange_account.created_at.strftime("%Y-%m-%d %H:%M:%S"),
76 "tickers": [],
77 },
78 )
80 def test_many_serialization(self):
81 instances = [self.exchange for _ in range(10)]
82 exchange_serializer = ExchangeSerializer(many=True, instance=instances)
83 data = exchange_serializer.data
84 self.assertEqual(len(data), 10)
86 def test_source_serialization(self):
87 exchange_account_serializer = ExchangeAccountSerializer
88 exchange_account_serializer._fields["exchange"] = StrField(source="exchange.name")
89 exchange_account_serializer._compiled_fields = MetaSerializer._compile_fields(
90 fields=exchange_account_serializer._fields,
91 serializer_cls=exchange_account_serializer,
92 )
94 exchange_account_serializer = exchange_account_serializer(self.exchange_account)
95 data = exchange_account_serializer.data
96 print(data)
97 self.assertEqual(data.get("exchange"), self.exchange.name)
99 # reset
100 exchange_account_serializer = ExchangeAccountSerializer
101 exchange_account_serializer._fields["exchange"] = ExchangeSerializer()
102 exchange_account_serializer._compiled_fields = MetaSerializer._compile_fields(
103 fields=exchange_account_serializer._fields,
104 serializer_cls=exchange_account_serializer,
105 )
107 def test_serialization_with_missing_required_field(self):
108 exchange_account_serializer = ExchangeAccountSerializer()
109 exchange_account_serializer._fields["required_field"] = Field(required=True)
110 exchange_account_serializer._compiled_fields = MetaSerializer._compile_fields(
111 fields=exchange_account_serializer._fields,
112 serializer_cls=exchange_account_serializer.__class__,
113 )
115 with self.assertRaises(ValueError):
116 exchange_account_serializer.data # noqa: B018
118 # reset
119 exchange_account_serializer = ExchangeAccountSerializer
120 exchange_account_serializer._fields.pop("required_field")
121 exchange_account_serializer._compiled_fields = MetaSerializer._compile_fields(
122 fields=exchange_account_serializer._fields,
123 serializer_cls=exchange_account_serializer,
124 )
127class SerializerValidationTestCase(TestCase):
128 def setUp(self):
129 self.exchange = Exchange.objects.create(name="Binance", description="Binance exchange")
130 self.exchange_account = ExchangeAccount.objects.create(
131 exchange=self.exchange,
132 name="Binance Account",
133 testing=True,
134 description="Binance account description",
135 default=True,
136 )
138 def test_exchange_validation_and_creation(self):
139 data = {"name": "TEST", "description": "Test exchange"}
140 exchange_serializer = ExchangeSerializer(data=data)
141 instance = exchange_serializer.create()
142 self.assertEqual(isinstance(instance, Exchange), True)
143 self.assertEqual(exchange_serializer.data, data)
145 def test_exchange_account_validation_and_creation(self):
146 data = {
147 "name": "TEST exchange account",
148 "description": "Test exchange",
149 "exchange": self.exchange.id,
150 "testing": True,
151 }
152 exchange_serializer = ExchangeAccountSerializer(data=data)
153 instance = exchange_serializer.create()
154 self.assertEqual(isinstance(instance, ExchangeAccount), True)
156 def test_exchange_validation_and_update(self):
157 data = {"name": "TEST", "description": "new description"}
158 exchange_serializer = ExchangeSerializer(data=data)
159 instance = exchange_serializer.update(instance=self.exchange)
160 self.assertEqual(isinstance(instance, Exchange), True)
161 self.assertEqual(instance.description, "new description")
163 def test_validation_with_missing_required_field(self):
164 with self.assertRaises(ValidationError):
165 exchange_serializer = ExchangeSerializer(data={"description": "Test exchange"}) # noqa: F841
167 def test_validation_with_invalid_field(self):
168 data = {
169 "name": "TEST exchange account",
170 "description": "Test exchange",
171 "exchange": {"name": 12},
172 "testing": True,
173 }
174 with self.assertRaises(ValidationError):
175 ExchangeAccountSerializer(data=data)
177 data = {
178 "name": "TEST",
179 "description": "Test exchange",
180 "test_int_field": "whatever",
181 }
182 with self.assertRaises(ValidationError):
183 ExchangeSerializer(data=data)
184 # with self.assertRaises(ValidationError):
185 # ExchangeAccountSerializer(data=data)
186 # eas = ExchangeAccountSerializer(data=data)
187 # from pprint import pprint
189 # pprint(eas.validated_data)
190 # pprint(eas._validators)
192 def test_validation_with_invalid_data(self):
193 data = 1
194 with self.assertRaises(ValidationError):
195 ExchangeSerializer(data=data)
197 def test_validation_overwrite(self):
198 data = {
199 "name": "TEST exchange account",
200 "description": "Test exchange",
201 "exchange": self.exchange.id,
202 "testing": False,
203 }
204 exchange_serializer = ExchangeAccountSerializer(data=data)
205 instance = exchange_serializer.create()
206 self.assertEqual(isinstance(instance, ExchangeAccount), True)
207 self.assertEqual(
208 exchange_serializer.validated_data,
209 {
210 "name": "TEST exchange account",
211 "description": "Test exchange",
212 "exchange": self.exchange,
213 "testing": True,
214 },
215 )
217 def test_get_validated_data_before_validation(self):
218 exchange_serializer = ExchangeSerializer()
219 with self.assertRaises(ValueError):
220 exchange_serializer.validated_data # noqa: B018
222 def test_model_action_before_validation(self):
223 exchange_serializer = ExchangeSerializer()
224 with self.assertRaises(ValueError):
225 exchange_serializer.create()
227 def test_model_action_without_model(self):
228 exchange_serializer = ExchangeSerializer()
229 exchange_serializer.Model = None
230 with self.assertRaises(ValueError):
231 exchange_serializer.create({})
233 def _test_perf(self):
234 instances = [self.exchange_account for _ in range(1_000_000)]
235 from time import time
237 start = time()
238 serializer = ExchangeAccountSerializer(instance=instances, many=True)
239 print(f"setup: {time() - start:0.3f}s")
240 data = serializer.data
241 print(f"Total time{time() - start:0.6f}s")
242 self.assertEqual(len(data), 1_000_000)