Example #1
0
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']
Example #2
0
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]
Example #3
0
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
Example #4
0
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
Example #5
0
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'
Example #6
0
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'
Example #7
0
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
Example #8
0
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'
Example #9
0
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