def test_project_edit(app, project_published): """Test project edit.""" (project, video_1, video_2) = project_published assert project.status == 'published' assert video_1.status == 'published' assert video_2.status == 'published' # Edit project (change project title) new_project = project.edit() assert new_project.status == 'draft' new_project.update(title={'title': 'My project'}) # Edit videos inside project (change video titles) videos = video_resolver(new_project.video_ids) assert len(videos) == 2 for i, video in enumerate(videos): assert video.status == 'published' new_video = video.edit() assert new_video.status == 'draft' new_video.update(title={'title': 'Video {}'.format(i + 1)}) new_video.publish() # Publish all changes new_project.publish() # Check that everything is published videos = video_resolver(new_project.video_ids) assert new_project.status == 'published' assert all(video.status == 'published' for video in videos) # Check that all titles where properly changed assert new_project['title']['title'] == 'My project' assert videos[0]['title']['title'] in ['Video 1', 'Video 2'] assert videos[1]['title']['title'] in ['Video 1', 'Video 2'] assert videos[0]['title']['title'] != videos[1]['title']['title']
def project_published(app, project): """New published project with videos.""" (project, video_1, video_2) = project with app.test_request_context(): new_project = project.publish() new_videos = video_resolver(new_project.video_ids) assert len(new_videos) == 2 return new_project, new_videos[0], new_videos[1]
def test_deposit_events_on_download(api_app, db, depid, bucket, access_token, json_headers): """Test deposit events.""" db.session.add(bucket) with api_app.test_request_context(): url = url_for('invenio_webhooks.event_list', receiver_id='downloader', access_token=access_token) with mock.patch('requests.get') as mock_request, \ api_app.test_client() as client: file_size = 1024 * 1024 mock_request.return_value = type( 'Response', (object, ), { 'raw': BytesIO(b'\x00' * file_size), 'headers': { 'Content-Length': file_size } }) payload = dict(uri='http://example.com/test.pdf', bucket_id=str(bucket.id), deposit_id=depid, key='test.pdf') resp = client.post(url, headers=json_headers, data=json.dumps(payload)) assert resp.status_code == 202 file_size = 1024 * 1024 * 6 mock_request.return_value = type( 'Response', (object, ), { 'raw': BytesIO(b'\x00' * file_size), 'headers': { 'Content-Length': file_size } }) resp = client.post(url, headers=json_headers, data=json.dumps(payload)) assert resp.status_code == 202 video = video_resolver([depid])[0] events = video._events assert len(events) == 2 assert events[0].payload['deposit_id'] == depid assert events[1].payload['deposit_id'] == depid status = video._compute_tasks_status() assert status == {'download': states.STARTED} # check if the states are inside the deposit res = client.get(url_for('invenio_deposit_rest.depid_item', pid_value=depid, access_token=access_token), headers=json_headers) assert res.status_code == 200 data = json.loads(res.data.decode('utf-8'))['metadata'] assert data['_deposit']['state']['download'] == states.STARTED
def test_video_resolver(project): """Test vide resolver.""" (project, video_1, video_2) = project videos = video_resolver( [video_1['_deposit']['id'], video_2['_deposit']['id']]) original = [video_1.id, video_2.id] original.sort() resolved = [videos[0].id, videos[1].id] resolved.sort() assert original == resolved
def test_publish_all_videos(app, project): """Test video publish.""" (project, video_1, video_2) = project # check video1 is not published assert video_1['_deposit']['status'] == 'draft' assert video_2['_deposit']['status'] == 'draft' assert project['_deposit']['status'] == 'draft' # publish project new_project = project.publish() # check project and all video are published assert new_project['_deposit']['status'] == 'published' videos = video_resolver(new_project.video_ids) assert len(videos) == 2 for video in videos: assert video['_deposit']['status'] == 'published'
def test_publish_one_video(app, project): """Test video publish.""" (project, video_1, video_2) = project # check video1 is not published assert video_1['_deposit']['status'] == 'draft' assert video_2['_deposit']['status'] == 'draft' assert project['_deposit']['status'] == 'draft' # [publish project] # publish one video video_1 = video_1.publish() project = video_1.project # publish the project (with one video still not publish) project = project.publish() # check project and all video are published assert project['_deposit']['status'] == 'published' videos = video_resolver(project.video_ids) assert len(videos) == 2 for video in videos: assert video['_deposit']['status'] == 'published'
def test_deposit_events_on_worlflow(api_app, db, depid, bucket, access_token, json_headers): """Test deposit events.""" class TestReceiver(CeleryAsyncReceiver): def run(self, event): workflow = chain(simple_add.s(1, 2), group(failing_task.s(), success_task.s())) self._serialize_result(event, workflow.apply_async()) event.payload['deposit_id'] = depid flag_modified(event, 'payload') def _status_and_info(self, event, fun=_info_extractor): result = self._deserialize_result(event) status = _compute_status([ result.parent.status, result.children[0].status, result.children[1].status ]) info = fun(result.parent, 'add', [ fun(result.children[0], 'failing'), fun(result.children[1], 'failing') ]) return dict(status=status, info=info) receiver_id = 'add-receiver' current_webhooks.register(receiver_id, TestReceiver) db.session.add(bucket) with api_app.test_request_context(): url = url_for('invenio_webhooks.event_list', receiver_id=receiver_id, access_token=access_token) with api_app.test_client() as client: # run workflow resp = client.post(url, headers=json_headers, data=json.dumps({})) assert resp.status_code == 500 # run again workflow resp = client.post(url, headers=json_headers, data=json.dumps({})) assert resp.status_code == 500 # resolve deposit and events # TODO use a deposit resolver video = video_resolver([depid])[0] events = video._events # check events assert len(events) == 2 assert events[0].payload['deposit_id'] == depid assert events[1].payload['deposit_id'] == depid # check computed status status = video._compute_tasks_status() assert status['add'] == states.PENDING assert status['failing'] == states.FAILURE # check every task for every event for event in events: result = event.receiver._deserialize_result(event) assert result.parent.status == states.PENDING assert result.children[0].status == states.FAILURE assert result.children[1].status == states.SUCCESS # check if the states are inside the deposit res = client.get(url_for('invenio_deposit_rest.depid_item', pid_value=depid, access_token=access_token), headers=json_headers) assert res.status_code == 200 data = json.loads(res.data.decode('utf-8'))['metadata'] assert data['_deposit']['state']['add'] == states.PENDING assert data['_deposit']['state']['failing'] == states.FAILURE
def test_simple_workflow(app, db, es, users, location, cds_jsonresolver, project_metadata, json_headers, deposit_rest, data_file_1, data_file_2): """Test project simple workflow.""" def check_connection(videos, project): """check project <---> video connection.""" assert all({"$reference": video.ref} in project['videos'] for video in videos) assert len(videos) == len(project['videos']) project_schema = ('https://cdslabs.cern.ch/schemas/' 'deposits/records/project-v1.0.0.json') video_schema = ('https://cdslabs.cern.ch/schemas/' 'deposits/records/video-v1.0.0.json') with app.test_client() as client: login_user_via_session(client, email=User.query.get(users[0]).email) # [[ CREATE NEW PROJECT ]] res = client.post(url_for('invenio_deposit_rest.project_list'), data=json.dumps(project_metadata), headers=json_headers) # check returned value assert res.status_code == 201 project_dict = json.loads(res.data.decode('utf-8')) assert project_dict['metadata']['videos'] == [] assert project_dict['metadata']['title']['title'] == 'my project' assert project_dict['links']['bucket'].startswith( 'http://localhost/files/') assert all( link.startswith('http://localhost/deposits/project') for (key, link) in project_dict['links'].items() if key not in ['html', 'bucket']) # check database project_id = project_dict['metadata']['_deposit']['id'] project = project_resolver(project_id) assert project['$schema'] == project_schema # [[ ADD A NEW EMPTY VIDEO_1 ]] res = client.post(url_for('invenio_deposit_rest.video_list'), data=json.dumps({ '_project_id': project_dict['metadata']['_deposit']['id'], }), headers=json_headers) # check returned value assert res.status_code == 201 video_1_dict = json.loads(res.data.decode('utf-8')) assert video_1_dict['metadata']['_project_id'] == project_id assert all( link.startswith('http://localhost/deposits/video') for (key, link) in video_1_dict['links'].items() if key not in ['html', 'bucket']) # check database: connection project <---> videos video_ids = [video_1_dict['metadata']['_deposit']['id']] [video_1] = video_resolver(video_ids) check_connection([video_1], project_resolver( project_dict['metadata']['_deposit']['id'])) assert video_1['$schema'] == video_schema # [[ GET THE VIDEO 1 ]] res = client.get(video_1_dict['links']['self'], headers=json_headers) # check returned value assert res.status_code == 200 video_1_dict = json.loads(res.data.decode('utf-8')) assert video_1_dict['metadata']['_files'] == [] # [[ ADD A NEW EMPTY VIDEO_2 ]] res = client.post(url_for('invenio_deposit_rest.video_list'), data=json.dumps({ '_project_id': project_dict['metadata']['_deposit']['id'], }), headers=json_headers) # check returned value assert res.status_code == 201 video_2_dict = json.loads(res.data.decode('utf-8')) assert video_2_dict['metadata']['_project_id'] == project_id assert all( link.startswith('http://localhost/deposits/video') for (key, link) in video_2_dict['links'].items() if key not in ['html', 'bucket']) # check database: connection project <---> videos video_ids = [ video_1_dict['metadata']['_deposit']['id'], video_2_dict['metadata']['_deposit']['id'] ] [video_1, video_2] = video_resolver(video_ids) check_connection([video_1, video_2], project_resolver( project_dict['metadata']['_deposit']['id'])) assert video_2['$schema'] == video_schema # [[ ADD A FILE INSIDE VIDEO_1 ]] res = client.post(url_for( 'invenio_deposit_rest.video_files', pid_value=video_1_dict['metadata']['_deposit']['id']), data=data_file_1, content_type='multipart/form-data') # check returned value assert res.status_code == 201 file_1 = json.loads(res.data.decode('utf-8')) assert file_1['checksum'] == 'md5:eb88ae1e3666e6fe96a33ea72aab630e' assert file_1['filesize'] == 24 assert file_1['filename'] == 'test.json' assert file_1['id'] # check database: connection project <---> videos [video_1 ] = video_resolver([video_1_dict['metadata']['_deposit']['id']]) assert video_1['_files'][0]['key'] == 'test.json' video_ids = [ video_1_dict['metadata']['_deposit']['id'], video_2_dict['metadata']['_deposit']['id'] ] check_connection( video_resolver(video_ids), project_resolver(project_dict['metadata']['_deposit']['id'])) # [[ GET THE VIDEO 1 ]] res = client.get(video_1_dict['links']['self'], headers=json_headers) # check video metadata assert res.status_code == 200 video_1_dict = json.loads(res.data.decode('utf-8')) assert len(video_1_dict['metadata']['_files']) == 1 myfile = video_1_dict['metadata']['_files'][0] assert myfile['links']['self'].startswith('/api/files/') assert myfile['checksum'] == 'md5:eb88ae1e3666e6fe96a33ea72aab630e' assert myfile['completed'] is True assert 'version_id' in myfile assert myfile['key'] == 'test.json' assert myfile['progress'] == 100 assert myfile['size'] == 24 # [[ PUBLISH VIDEO_1 ]] # Not need to send _files del video_1_dict['metadata']['_files'] res = client.post(url_for('invenio_deposit_rest.video_actions', pid_value=video_1['_deposit']['id'], action='publish'), headers=json_headers) # check returned value assert res.status_code == 202 video_1_dict = json.loads(res.data.decode('utf-8')) assert video_1_dict['metadata']['_deposit']['status'] == 'published' assert video_1_dict['metadata']['recid'] == 1 assert video_1_dict['metadata']['_project_id'] == project_id # check database: connection project <---> videos video_ids = [ video_1_dict['metadata']['_deposit']['id'], video_2_dict['metadata']['_deposit']['id'] ] check_connection( video_resolver(video_ids), project_resolver(project_dict['metadata']['_deposit']['id'])) # [[ ADD A VIDEO INSIDE VIDEO_2 ]] res = client.post(url_for( 'invenio_deposit_rest.video_files', pid_value=video_2_dict['metadata']['_deposit']['id']), data=data_file_2, content_type='multipart/form-data') # check returned value assert res.status_code == 201 file_2 = json.loads(res.data.decode('utf-8')) assert file_2['checksum'] == 'md5:95405c14852500dcbb6dbfd9e27a3594' assert file_2['filesize'] == 26 assert file_2['filename'] == 'test2.json' # check connection project <---> videos [video_2 ] = video_resolver([video_2_dict['metadata']['_deposit']['id']]) assert video_2['_files'][0]['key'] == 'test2.json' video_ids = [ video_1_dict['metadata']['_deposit']['id'], video_2_dict['metadata']['_deposit']['id'] ] check_connection( video_resolver(video_ids), project_resolver(project_dict['metadata']['_deposit']['id'])) # [[ PUBLISH THE PROJECT ]] res = client.post(url_for('invenio_deposit_rest.project_actions', pid_value=project['_deposit']['id'], action='publish'), headers=json_headers) # check returned value assert res.status_code == 202 project_dict = json.loads(res.data.decode('utf-8')) assert project_dict['metadata']['_deposit']['status'] == 'published' assert project_dict['metadata']['recid'] == 3 assert project_dict['metadata']['videos'][0] == { '$reference': '/record/1' } assert project_dict['metadata']['videos'][1] == { '$reference': '/record/2' } # check database: connection project <---> videos video_ids = [ video_1_dict['metadata']['_deposit']['id'], video_2_dict['metadata']['_deposit']['id'] ] check_connection( video_resolver(video_ids), project_resolver(project_dict['metadata']['_deposit']['id'])) # [[ EDIT THE PROJECT ]] res = client.post(url_for( 'invenio_deposit_rest.project_actions', pid_value=project_dict['metadata']['_deposit']['id'], action='edit'), headers=json_headers) # check returned value assert res.status_code == 201 project_dict = json.loads(res.data.decode('utf-8')) assert project_dict['metadata']['_deposit']['status'] == 'draft' # check database project = project_resolver(project_dict['metadata']['_deposit']['id']) assert project['_deposit']['status'] == 'draft' # [[ MODIFY PROJECT ]] project_dict['metadata']['title']['title'] = 'new project title' # Not need to send _files del project_dict['metadata']['_files'] res = client.put(url_for( 'invenio_deposit_rest.project_item', pid_value=project_dict['metadata']['_deposit']['id']), data=json.dumps(project_dict['metadata']), headers=json_headers) # check returned value assert res.status_code == 200 project_dict = json.loads(res.data.decode('utf-8')) assert project_dict['metadata']['title']['title'] ==\ 'new project title' assert all( link.startswith('http://localhost/deposits/project') for (key, link) in project_dict['links'].items() if key not in ['html', 'bucket']) # check database project = project_resolver(project_dict['metadata']['_deposit']['id']) assert project['title']['title'] == 'new project title' # [[ DISCARD PROJECT ]] res = client.post(url_for( 'invenio_deposit_rest.project_actions', pid_value=project_dict['metadata']['_deposit']['id'], action='discard'), headers=json_headers) # check returned value assert res.status_code == 201 project_dict = json.loads(res.data.decode('utf-8')) assert project_dict['metadata']['title']['title'] == 'my project' # check database project = project_resolver(project_dict['metadata']['_deposit']['id']) assert project['title']['title'] == 'my project'
def test_video_publish_and_edit(project): """Test video publish and edit.""" (project, video_1, video_2) = project video_path_1 = project['videos'][0]['$reference'] video_path_2 = project['videos'][1]['$reference'] deposit_project_schema = ('https://cdslabs.cern.ch/schemas/' 'deposits/records/project-v1.0.0.json') deposit_video_schema = ('https://cdslabs.cern.ch/schemas/' 'deposits/records/video-v1.0.0.json') record_video_schema = ('https://cdslabs.cern.ch/schemas/' 'records/video-v1.0.0.json') # check video1 is not published assert video_1['_deposit']['status'] == 'draft' assert video_2['_deposit']['status'] == 'draft' assert project['_deposit']['status'] == 'draft' # and the schema is a deposit assert video_1['$schema'] == deposit_video_schema assert video_2['$schema'] == deposit_video_schema assert project['$schema'] == deposit_project_schema # update video # [publish the video 1] video_1 = video_1.publish() project = video_1.project (_, record_video_1) = video_1.fetch_published() record_video_id_1 = record_video_1['recid'] record_path_1 = record_build_url(record_video_id_1) # check new link project -> video assert video_1['_deposit']['status'] == 'published' assert video_2['_deposit']['status'] == 'draft' assert project['_deposit']['status'] == 'draft' # check the schema is a record assert record_video_1['$schema'] == record_video_schema assert video_2['$schema'] == deposit_video_schema assert project['$schema'] == deposit_project_schema # check video recid is inside the list assert any(video_ref['$reference'] == record_path_1 for video_ref in project['videos']) is True # and there is not the old id (when the video was a deposit) assert any(video_ref['$reference'] == video_path_1 for video_ref in project['videos']) is False # and still exists video 2 deposit id assert any(video_ref['$reference'] == video_path_2 for video_ref in project['videos']) is True # [edit the video 1] [video_1_v2] = video_resolver([record_video_1['_deposit']['id']]) video_1_v2 = video_1_v2.edit() # check video1 is not published assert video_1_v2['_deposit']['status'] == 'draft' assert video_2['_deposit']['status'] == 'draft' assert project['_deposit']['status'] == 'draft' # check the schema is a record assert video_1_v2['$schema'] == deposit_video_schema assert video_2['$schema'] == deposit_video_schema assert project['$schema'] == deposit_project_schema # check video1 v1 recid is NOT inside the list assert any(video_ref['$reference'] == record_path_1 for video_ref in project['videos']) is False # check video1 v2 is inside the list video_path_1_v2 = video_build_url(video_1_v2['_deposit']['id']) assert any(video_ref['$reference'] == video_path_1_v2 for video_ref in project['videos']) is True