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

1from django_napse.utils.serializers.fields import Field, IntField, StrField, BoolField, DatetimeField, MethodField, UUIDField 

2from django_napse.utils.serializers.serializer import Serializer, MetaSerializer 

3 

4from django_napse.core.models import Exchange, ExchangeAccount 

5from django.test import TestCase 

6from rest_framework.serializers import ValidationError 

7 

8""" 

9python tests/test_app/manage.py test tests.django_tests.test_serializer -v2 --keepdb --parallel 

10""" 

11 

12 

13class ExchangeSerializer(Serializer): 

14 Model = Exchange 

15 name = StrField(required=True) 

16 description = StrField() 

17 test_int_field = IntField() 

18 

19 

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() 

30 

31 def get_tickers(self, instance): 

32 return instance.exchange.get_tickers() 

33 

34 def validate_data(self, data): 

35 data["testing"] = True 

36 return super().validate_data(data) 

37 

38 

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 ) 

49 

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 ) 

62 

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 ) 

79 

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) 

85 

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 ) 

93 

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) 

98 

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 ) 

106 

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 ) 

114 

115 with self.assertRaises(ValueError): 

116 exchange_account_serializer.data # noqa: B018 

117 

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 ) 

125 

126 

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 ) 

137 

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) 

144 

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) 

155 

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") 

162 

163 def test_validation_with_missing_required_field(self): 

164 with self.assertRaises(ValidationError): 

165 exchange_serializer = ExchangeSerializer(data={"description": "Test exchange"}) # noqa: F841 

166 

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) 

176 

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 

188 

189 # pprint(eas.validated_data) 

190 # pprint(eas._validators) 

191 

192 def test_validation_with_invalid_data(self): 

193 data = 1 

194 with self.assertRaises(ValidationError): 

195 ExchangeSerializer(data=data) 

196 

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 ) 

216 

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 

221 

222 def test_model_action_before_validation(self): 

223 exchange_serializer = ExchangeSerializer() 

224 with self.assertRaises(ValueError): 

225 exchange_serializer.create() 

226 

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({}) 

232 

233 def _test_perf(self): 

234 instances = [self.exchange_account for _ in range(1_000_000)] 

235 from time import time 

236 

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)