diff --git a/cloud/routes.py b/cloud/routes.py index 4c9a985..0a5bec8 100644 --- a/cloud/routes.py +++ b/cloud/routes.py @@ -278,6 +278,12 @@ def get_random_featured_nodes() -> typing.List[dict]: 'foreignField': '_id', 'as': 'node'}}, {'$unwind': {'path': '$node'}}, + {'$lookup': {"from": "users", + "localField": "node.user", + "foreignField": "_id", + "as": "node.user"}}, + {'$unwind': {'path': "$node.user"}}, + {'$match': {'node._deleted': {'$ne': True}}}, {'$project': {'url': True, 'name': True, 'summary': True, @@ -287,7 +293,10 @@ def get_random_featured_nodes() -> typing.List[dict]: 'node.permissions': True, 'node.picture': True, 'node.properties.content_type': True, - 'node.properties.url': True}}, + 'node.properties.duration_seconds': True, + 'node.properties.url': True, + 'node._created': True, + 'node.user.full_name': True,}}, ]) featured_node_documents = [] @@ -296,6 +305,7 @@ def get_random_featured_nodes() -> typing.List[dict]: # Turn the project-with-node doc into a node-with-project doc. node_document = node_info.pop('node') node_document['project'] = node_info + node_document['_id'] = str(node_document['_id']) node = Node(node_document) node.picture = get_file(node.picture, api=api) diff --git a/src/scripts/tagged_assets.js b/src/scripts/tagged_assets.js index b0598cc..05842fc 100644 --- a/src/scripts/tagged_assets.js +++ b/src/scripts/tagged_assets.js @@ -91,8 +91,8 @@ } } - if (node.video_duration){ - let card_duration = $('
' + node.video_duration + '
'); + if (node.properties.duration){ + let card_duration = $('
' + node.properties.duration + '
'); thumbnail_container.append(card_duration); } diff --git a/tests/test_routes.py b/tests/test_routes.py new file mode 100644 index 0000000..f12ef1a --- /dev/null +++ b/tests/test_routes.py @@ -0,0 +1,166 @@ +from datetime import timedelta + +from bson import ObjectId + +from abstract_cloud_test import AbstractCloudTest +from cloud.routes import get_random_featured_nodes + + +class RandomFeaturedNodeTest(AbstractCloudTest): + def setUp(self, **kwargs): + super().setUp(**kwargs) + + self.pid, _ = self.ensure_project_exists() + self.file_id, _ = self.ensure_file_exists(file_overrides={ + 'variations': [ + {'format': 'mp4', + 'duration': 75 # 01:15 + }, + ], + }) + + self.uid = self.create_user() + + from pillar.api.utils import utcnow + self.fake_now = utcnow() + + def test_random_feature_node_returns_3_nodes(self): + base_node = { + 'name': 'Just a node name', + 'project': self.pid, + 'description': '', + 'node_type': 'asset', + 'user': self.uid, + } + base_props = { + 'status': 'published', + 'file': self.file_id, + 'content_type': 'video', + 'order': 0 + } + + def create_asset(weeks): + return self.create_node({ + **base_node, + '_created': self.fake_now - timedelta(weeks=weeks), + 'properties': base_props, + }) + + all_asset_ids = [create_asset(i) for i in range(20)] + + with self.app.app_context(): + proj_col = self.app.db('projects') + proj_col.update( + {'_id': self.pid}, + {'$set': { + 'nodes_featured': all_asset_ids, + }}) + + with self.app.test_request_context(): + random_assets = get_random_featured_nodes() + actual_ids = [asset['_id'] for asset in random_assets] + + self.assertIs(len(random_assets), 3) + for aid in actual_ids: + self.assertIn(ObjectId(aid), all_asset_ids) + + def test_random_feature_ignore(self): + def assert_ignored(): + with self.app.test_request_context(): + random_assets = get_random_featured_nodes() + self.assertIs(len(random_assets), 0) + + base_node = { + 'name': 'Just a node name', + 'project': self.pid, + 'description': '', + 'node_type': 'asset', + 'user': self.uid, + } + base_props = { + 'status': 'published', + 'file': self.file_id, + 'content_type': 'video', + 'order': 0 + } + + node_id = self.create_node({ + **base_node, + '_created': self.fake_now - timedelta(days=5), + 'properties': base_props, + }) + + # Not featured, should be ignored + assert_ignored() + + # Featured but project is private, should be ignored + with self.app.app_context(): + proj_col = self.app.db('projects') + proj_col.update( + {'_id': self.pid}, + {'$set': { + 'nodes_featured': [node_id], + 'is_private': True, + }}) + assert_ignored() + + # Featured but node is deleted, should be ignored + with self.app.app_context(): + proj_col = self.app.db('projects') + proj_col.update( + {'_id': self.pid}, + {'$set': { + 'nodes_featured': [node_id], + 'is_private': False, + }}) + + node_col = self.app.db('nodes') + node_col.update( + {'_id': node_id}, + {'$set': { + '_deleted': True, + }}) + assert_ignored() + + def test_random_feature_node_data(self): + base_node = { + 'name': 'Just a node name', + 'project': self.pid, + 'description': '', + 'node_type': 'asset', + 'user': self.uid, + } + base_props = { + 'status': 'published', + 'file': self.file_id, + 'content_type': 'video', + 'duration_seconds': 75, + 'order': 0 + } + + node_id = self.create_node({ + **base_node, + '_created': self.fake_now, + 'properties': base_props, + }) + + with self.app.app_context(): + proj_col = self.app.db('projects') + proj_col.update( + {'_id': self.pid}, + {'$set': { + 'nodes_featured': [node_id], + }}) + + with self.app.test_request_context(): + random_assets = get_random_featured_nodes() + self.assertIs(len(random_assets), 1) + + asset = random_assets[0] + self.assertEquals('Just a node name', asset['name']) + self.assertEquals('Unittest project', asset['project']['name']) + self.assertEquals('video', asset['properties']['content_type']) + self.assertTrue(asset.properties.content_type == 'video') + self.assertEquals(self.fake_now, asset['_created']) + self.assertEquals(str(node_id), asset['_id']) + self.assertEquals(75, asset['properties']['duration_seconds']) \ No newline at end of file