|
| 1 | +import uuid |
| 2 | + |
1 | 3 | from django.db.models.query import QuerySet |
| 4 | +from django.utils import timezone |
2 | 5 | from le_utils.constants import content_kinds |
3 | 6 | from mock import Mock |
4 | 7 | from rest_framework import serializers |
|
7 | 10 | from contentcuration.models import Channel |
8 | 11 | from contentcuration.models import ContentNode |
9 | 12 | from contentcuration.models import DEFAULT_CONTENT_DEFAULTS |
| 13 | +from contentcuration.models import RecommendationsEvent |
10 | 14 | from contentcuration.tests import testdata |
11 | 15 | from contentcuration.viewsets.channel import ChannelSerializer as BaseChannelSerializer |
12 | 16 | from contentcuration.viewsets.common import ContentDefaultsSerializer |
13 | 17 | from contentcuration.viewsets.contentnode import ContentNodeSerializer |
14 | 18 | from contentcuration.viewsets.feedback import FlagFeedbackEventSerializer |
| 19 | +from contentcuration.viewsets.feedback import RecommendationsEventSerializer |
| 20 | +from contentcuration.viewsets.feedback import RecommendationsInteractionEventSerializer |
15 | 21 |
|
16 | 22 |
|
17 | 23 | def ensure_no_querysets_in_serializer(object): |
@@ -225,3 +231,111 @@ def test_invalid_data(self): |
225 | 231 | data = {'context': 'invalid'} |
226 | 232 | serializer = FlagFeedbackEventSerializer(data=data) |
227 | 233 | self.assertFalse(serializer.is_valid()) |
| 234 | + |
| 235 | + |
| 236 | +class RecommendationsInteractionEventSerializerTestCase(BaseAPITestCase): |
| 237 | + def setUp(self): |
| 238 | + super(RecommendationsInteractionEventSerializerTestCase, self).setUp() |
| 239 | + self.channel = testdata.channel("testchannel") |
| 240 | + self.interaction_node = testdata.node( |
| 241 | + { |
| 242 | + "kind_id": content_kinds.VIDEO, |
| 243 | + "title": "Recommended Video content", |
| 244 | + }, |
| 245 | + ) |
| 246 | + self.node_where_import_is_initiated = testdata.node( |
| 247 | + { |
| 248 | + "kind_id": content_kinds.TOPIC, |
| 249 | + "title": "Node where content is imported", |
| 250 | + }, |
| 251 | + ) |
| 252 | + self.recommendation_event = RecommendationsEvent.objects.create( |
| 253 | + user=self.user, |
| 254 | + target_channel_id=self.channel.id, |
| 255 | + content_id=self.node_where_import_is_initiated.content_id, |
| 256 | + contentnode_id=self.node_where_import_is_initiated.id, |
| 257 | + context={'model_version': 1, 'breadcrumbs': "#Title#->Random"}, |
| 258 | + time_hidden=timezone.now(), |
| 259 | + content=[{'content_id': str(uuid.uuid4()), 'node_id': str(uuid.uuid4()), 'channel_id': str(uuid.uuid4()), 'score': 4}] |
| 260 | + ) |
| 261 | + |
| 262 | + def test_deserialization_and_validation(self): |
| 263 | + data = { |
| 264 | + 'context': {'test_key': 'test_value'}, |
| 265 | + 'contentnode_id': str(self.interaction_node.id), |
| 266 | + 'content_id': str(self.interaction_node.content_id), |
| 267 | + 'feedback_type': 'IGNORED', |
| 268 | + 'feedback_reason': '----', |
| 269 | + 'recommendation_event_id': str(self.recommendation_event.id) |
| 270 | + } |
| 271 | + serializer = RecommendationsInteractionEventSerializer(data=data) |
| 272 | + self.assertTrue(serializer.is_valid(), serializer.errors) |
| 273 | + instance = serializer.save() |
| 274 | + self.assertEqual(instance.context, data['context']) |
| 275 | + self.assertEqual(instance.feedback_type, data['feedback_type']) |
| 276 | + self.assertEqual(str(instance.recommendation_event_id), data['recommendation_event_id']) |
| 277 | + |
| 278 | + def test_invalid_data(self): |
| 279 | + data = {'context': 'invalid'} |
| 280 | + serializer = RecommendationsInteractionEventSerializer(data=data) |
| 281 | + self.assertFalse(serializer.is_valid()) |
| 282 | + |
| 283 | + data = { |
| 284 | + 'context': {'test_key': 'test_value'}, |
| 285 | + 'contentnode_id': str(self.interaction_node.id), |
| 286 | + 'content_id': str(self.interaction_node.content_id), |
| 287 | + 'feedback_type': 'INVALID_TYPE', |
| 288 | + 'feedback_reason': '-----', |
| 289 | + 'recommendation_event_id': 'invalid-uuid' |
| 290 | + } |
| 291 | + serializer = RecommendationsInteractionEventSerializer(data=data) |
| 292 | + self.assertFalse(serializer.is_valid()) |
| 293 | + |
| 294 | + |
| 295 | +class RecommendationsEventSerializerTestCase(BaseAPITestCase): |
| 296 | + def setUp(self): |
| 297 | + super(RecommendationsEventSerializerTestCase, self).setUp() |
| 298 | + self.channel = testdata.channel("testchannel") |
| 299 | + self.node_where_import_is_initiated = testdata.node( |
| 300 | + { |
| 301 | + "kind_id": content_kinds.TOPIC, |
| 302 | + "title": "Title of the topic", |
| 303 | + }, |
| 304 | + ) |
| 305 | + |
| 306 | + def test_deserialization_and_validation(self): |
| 307 | + data = { |
| 308 | + 'user': self.user.id, |
| 309 | + 'target_channel_id': str(self.channel.id), |
| 310 | + 'context': {'model_version': 1, 'breadcrumbs': "#Title#->Random"}, |
| 311 | + 'contentnode_id': str(self.node_where_import_is_initiated.id), |
| 312 | + 'content_id': str(self.node_where_import_is_initiated.content_id), |
| 313 | + 'time_hidden': timezone.now().isoformat(), |
| 314 | + 'content': [{'content_id': str(uuid.uuid4()), 'node_id': str(uuid.uuid4()), 'channel_id': str(uuid.uuid4()), 'score': 4}] |
| 315 | + } |
| 316 | + serializer = RecommendationsEventSerializer(data=data) |
| 317 | + self.assertTrue(serializer.is_valid(), serializer.errors) |
| 318 | + instance = serializer.save() |
| 319 | + self.assertEqual(instance.context, data['context']) |
| 320 | + self.assertEqual(instance.user.id, data['user']) |
| 321 | + self.assertEqual(str(instance.contentnode_id).replace('-', ''), data['contentnode_id'].replace('-', '')) |
| 322 | + self.assertEqual(instance.content, data['content']) |
| 323 | + |
| 324 | + def test_invalid_data(self): |
| 325 | + # Test with missing required fields |
| 326 | + data = {'context': 'invalid'} |
| 327 | + serializer = RecommendationsEventSerializer(data=data) |
| 328 | + self.assertFalse(serializer.is_valid()) |
| 329 | + |
| 330 | + # Test with invalid contentnode_id |
| 331 | + data = { |
| 332 | + 'user': self.user.id, |
| 333 | + 'target_channel_id': str(self.channel.id), |
| 334 | + 'context': {'model_version': 1, 'breadcrumbs': "#Title#->Random"}, |
| 335 | + 'contentnode_id': 'invalid-uuid', |
| 336 | + 'content_id': str(self.node_where_import_is_initiated.content_id), |
| 337 | + 'time_hidden': timezone.now().isoformat(), |
| 338 | + 'content': [{'content_id': str(uuid.uuid4()), 'node_id': str(uuid.uuid4()), 'channel_id': str(uuid.uuid4()), 'score': 4}] |
| 339 | + } |
| 340 | + serializer = RecommendationsEventSerializer(data=data) |
| 341 | + self.assertFalse(serializer.is_valid()) |
0 commit comments