예제 #1
0
    def get(self, id):
        row = database.query_db(PATCH_QUERY + ' where id = ?', (id,), one=True)
        if not row:
            abort(404)
        data = process_patch_row(row)
        data['mergeable'] = patching.is_mergeable(data['original_patch'])
        headers = {}

        comments = database.query_db(
            '''
            SELECT author, message, posted_at
            FROM patch_request_comment
            WHERE patch_request_id=?
            ORDER BY posted_at ASC
            ''',
            (id,)
        )
        data['comments'] = [dict(row) for row in comments]

        try:
            if auth.accept_patch_permission.can():
                headers['Link'] = '<{}>;rel="merge"'.format(
                    url_for('patchmerge', id=id))
        except auth.AuthenticationFailed:
            pass

        return marshal(data, patch_fields), 200, headers
예제 #2
0
 def get(self, id):
     row = database.query_db(PATCH_QUERY + ' where id = ?', (id,), one=True)
     if row['merged']:
         p = row['applied_patch']
     else:
         p = row['original_patch']
     return json.loads(p), 200
예제 #3
0
    def test_comment_on_patch(self):
        with open(filepath('test-patch-adds-items.json')) as f:
            patch = f.read()
        with self.client as client:
            res = client.patch(
                '/d/',
                data=patch,
                content_type='application/json',
                headers={'Authorization': 'Bearer '
                         + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'})
            patch_id = int(res.headers['Location'].split('/')[-2])
            patch_url = urlparse(res.headers['Location']).path
            res = client.post(
                patch_url + 'messages',
                data=json.dumps({'message': 'This is a comment'}),
                content_type='application/json',
                headers={'Authorization': 'Bearer ' +
                         'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}
            )

            self.assertEqual(res.status_code, http.client.OK)
            self.assertEqual(patch_url, urlparse(res.headers['Location']).path)

            row = database.query_db(
                'SELECT * FROM patch_request_comment WHERE patch_request_id=?',
                (patch_id,), one=True)
            self.assertEqual('https://orcid.org/1234-5678-9101-112X',
                             row['author'])
            self.assertEqual(patch_id, row['patch_request_id'])
            self.assertEqual('This is a comment', row['message'])

            res = client.get(patch_url)
            comments = json.loads(res.get_data(as_text=True)).get('comments')
            self.assertEqual(1, len(comments))
예제 #4
0
 def test_initial_patch(self):
     with self.client as client:
         client.patch(
             '/d/',
             data=self.patch,
             content_type='application/json',
             headers={'Authorization': 'Bearer '
                      + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'})
         created_entities = database.query_db(
             'SELECT created_entities FROM patch_request WHERE id = 1',
             one=True)['created_entities']
         self.assertEqual(created_entities, '["p0trgkv", "p0trgkvwbjd"]')
         updated_entities = database.query_db(
             'SELECT updated_entities FROM patch_request WHERE id = 1',
             one=True)['updated_entities']
         self.assertEqual(updated_entities, '[]')
    def test_admin_merge(self):
        with self.client as client:
            res = client.patch(
                '/d/',
                data=self.patch,
                content_type='application/json',
                headers={'Authorization': 'Bearer '
                         + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'})
            patch_id = int(res.headers['Location'].split('/')[-2])

            # Test that there's a link header
            patch_url = urlparse(res.headers['Location']).path
            res = self.client.get(patch_url, headers={
                'Authorization': 'Bearer '
                + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'})
            self.assertEqual(res.headers.get('Link'),
                             '<{}>;rel="merge"'.format(patch_url + 'merge'))

            res = client.post(
                patch_url + 'merge',
                headers={'Authorization': 'Bearer '
                         + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'})
            self.assertEqual(res.status_code, http.client.NO_CONTENT)
            merger = database.query_db(
                'SELECT merged_by FROM patch_request WHERE id = ?',
                (patch_id,), one=True)['merged_by']
            self.assertEqual(merger, 'http://orcid.org/1211-1098-7654-321X')
예제 #6
0
def add_new_version_of_dataset(data):
    now = database.query_db(
        "SELECT CAST(strftime('%s', 'now') AS INTEGER) AS now", one=True)['now']
    cursor = database.get_db().cursor()
    cursor.execute(
        'INSERT into DATASET (data, description, created_at) VALUES (?,?,?)',
        (json.dumps(data), void.describe_dataset(data, now), now))
    return cursor.lastrowid
 def test_add_admin_user(self):
     with app.app_context():
         row = database.query_db(
             'SELECT permissions FROM user WHERE id = ?',
             (self.admin_identity.id,), one=True)
         self.assertEqual(
             row['permissions'],
             '[["action", "submit-patch"], ["action", "accept-patch"]]')
예제 #8
0
def merge(patch_id, user_id):
    row = database.query_db(
        'SELECT * FROM patch_request WHERE id = ?', (patch_id,), one=True)

    if not row:
        raise MergeError('No patch with ID {}.'.format(patch_id))
    if row['merged']:
        raise MergeError('Patch is already merged.')
    if not row['open']:
        raise MergeError('Closed patches cannot be merged.')

    dataset = database.get_dataset()
    mergeable = is_mergeable(row['original_patch'], dataset)

    if not mergeable:
        raise UnmergeablePatchError('Patch is not mergeable.')

    data = json.loads(dataset['data'])
    original_patch = from_text(row['original_patch'])
    applied_patch, id_map = replace_skolem_ids(
        original_patch, data, database.get_removed_entity_keys())
    created_entities = set(id_map.values())

    # Should this be ordered?
    new_data = applied_patch.apply(data)

    db = database.get_db()
    curs = db.cursor()
    curs.execute(
        '''
        UPDATE patch_request
        SET merged = 1,
            open = 0,
            merged_at = strftime('%s', 'now'),
            merged_by = ?,
            applied_to = ?,
            created_entities = ?,
            identifier_map = ?,
            applied_patch = ?
        WHERE id = ?;
        ''',
        (user_id,
         dataset['id'],
         json.dumps(sorted(created_entities)),
         json.dumps(id_map),
         applied_patch.to_string(),
         row['id'])
    )
    version_id = add_new_version_of_dataset(new_data)
    curs.execute(
        '''
        UPDATE patch_request
        SET resulted_in = ?
        WHERE id = ?;
        ''',
        (version_id, row['id'])
    )
예제 #9
0
 def test_submit_patch(self):
     with self.client as client:
         res = client.patch(
             '/d/',
             data=self.patch,
             content_type='application/json',
             headers={'Authorization': 'Bearer '
                      + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'})
         self.assertEqual(res.status_code, http.client.ACCEPTED)
         patch_id = int(res.headers['Location'].split('/')[-2])
         updated_entities = database.query_db(
             'SELECT updated_entities FROM patch_request WHERE id = ?',
             (patch_id,), one=True)['updated_entities']
         self.assertEqual(updated_entities, '["p0trgkv", "p0trgkvwbjd"]')
         created_entities = database.query_db(
             'SELECT created_entities FROM patch_request WHERE id = ?',
             (patch_id,), one=True)['created_entities']
         self.assertEqual(created_entities, '[]')
예제 #10
0
 def test_merge_patch(self):
     with open(filepath('test-patch-adds-items.json')) as f:
         patch = f.read()
     with self.client as client:
         res = client.patch(
             '/d/',
             data=patch,
             content_type='application/json',
             headers={'Authorization': 'Bearer '
                      + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'})
         patch_id = int(res.headers['Location'].split('/')[-2])
         updated_entities = database.query_db(
             'SELECT updated_entities FROM patch_request WHERE id = ?',
             (patch_id,), one=True)['updated_entities']
         self.assertEqual(updated_entities, '["p0trgkv"]')
         created_entities = database.query_db(
             'SELECT created_entities FROM patch_request WHERE id = ?',
             (patch_id,), one=True)['created_entities']
         self.assertEqual(created_entities, '[]')
         patch_url = urlparse(res.headers['Location']).path
         res = client.post(
             patch_url + 'merge',
             buffered=True,
             headers={'Authorization': 'Bearer '
                      + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'})
         self.assertEqual(res.status_code, http.client.NO_CONTENT)
         row = database.query_db(
             'SELECT applied_to, resulted_in FROM patch_request WHERE id=?',
             (patch_id,), one=True)
         self.assertEqual(1, row['applied_to'])
         self.assertEqual(2, row['resulted_in'])
         updated_entities = database.query_db(
             'SELECT updated_entities FROM patch_request WHERE id = ?',
             (patch_id,), one=True)['updated_entities']
         self.assertEqual(updated_entities, '["p0trgkv"]')
         created_entities = json.loads(database.query_db(
             'SELECT created_entities FROM patch_request WHERE id = ?',
             (patch_id,), one=True)['created_entities'])
         self.assertEqual(4, len(created_entities))
         for entity_id in created_entities:
             self.assertRegex(entity_id, identifier.IDENTIFIER_RE)
예제 #11
0
 def test_authorized_user(self):
     with self.client as client:
         res = client.patch(
             '/d/',
             data=self.patch,
             content_type='application/json',
             headers={'Authorization': 'Bearer '
                      + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'})
         self.assertEqual(res.status_code, http.client.ACCEPTED)
         patch_id = int(res.headers['Location'].split('/')[-2])
         creator = database.query_db(
             'SELECT created_by FROM patch_request WHERE id = ?',
             (patch_id,), one=True)['created_by']
         self.assertEqual(creator, 'http://orcid.org/1234-5678-9101-112X')
 def test_add_user(self):
     self.assertEqual(
         self.identity.id, 'http://orcid.org/1234-5678-9101-112X')
     self.assertEqual(
         self.identity.auth_type, 'bearer')
     with app.app_context():
         row = database.query_db(
             'SELECT name, permissions, b64token FROM user WHERE id = ?',
             (self.identity.id,), one=True)
         self.assertEqual(row['name'], 'Testy Testerson')
         self.assertEqual(
             row['permissions'], '[["action", "submit-patch"]]')
         self.assertEqual(
             row['b64token'],
             b'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4')
예제 #13
0
def add_comment(patch_id, user_id, message):
    row = database.query_db(
        'SELECT * FROM patch_request WHERE id = ?', (patch_id,), one=True)

    if not row:
        raise MergeError('No patch with ID {}.'.format(patch_id))

    db = database.get_db()
    curs = db.cursor()
    curs.execute(
        '''
        INSERT INTO patch_request_comment
        (patch_request_id, author, message)
        VALUES (?, ?, ?)
        ''',
        (patch_id, user_id, message)
    )
예제 #14
0
    def get(self, id):
        row = database.query_db(PATCH_QUERY + ' where id = ?', (id,), one=True)
        if not row:
            abort(404)
        data = process_patch_row(row)
        data['mergeable'] = patching.is_mergeable(data['original_patch'])
        data['comments'] = [dict(c) for c in
                            database.get_patch_request_comments(id)]
        headers = {}
        try:
            if auth.accept_patch_permission.can():
                headers['Link'] = '<{}>;rel="merge"'.format(
                    url_for('patchmerge', id=id))
        except auth.AuthenticationFailed:
            pass

        return marshal(data, patch_fields), 200, headers
예제 #15
0
    def test_reject_patch(self):
        with open(filepath('test-patch-adds-items.json')) as f:
            patch = f.read()
        with self.client as client:
            res = client.patch(
                '/d/',
                data=patch,
                content_type='application/json',
                headers={'Authorization': 'Bearer '
                         + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'})
            patch_id = int(res.headers['Location'].split('/')[-2])
            patch_url = urlparse(res.headers['Location']).path
            res = client.post(
                patch_url + 'reject',
                headers={'Authorization': 'Bearer '
                         + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'})
            self.assertEqual(res.status_code, http.client.NO_CONTENT)
            row = database.query_db(
                'SELECT open, merged FROM patch_request WHERE id=?',
                (patch_id,), one=True)

            self.assertEqual(0, row['open'])
            self.assertEqual(0, row['merged'])
예제 #16
0
def reject(patch_id, user_id):
    row = database.query_db(
        'SELECT * FROM patch_request WHERE id = ?', (patch_id,), one=True)

    if not row:
        raise MergeError('No patch with ID {}.'.format(patch_id))
    if row['merged']:
        raise MergeError('Patch is already merged.')
    if not row['open']:
        raise MergeError('Closed patches cannot be merged.')

    db = database.get_db()
    curs = db.cursor()
    curs.execute(
        '''
        UPDATE patch_request
        SET merged = 0,
            open = 0,
            merged_at = strftime('%s', 'now'),
            merged_by = ?
        WHERE id = ?;
        ''',
        (user_id, row['id'],)
    )
예제 #17
0
    def get(self):
        args = patch_list_parser.parse_args()
        query = PATCH_QUERY
        params = ()

        where = []
        if args['open'] is not None:
            where.append('open = ?')
            params += (True if args['open'] == 'true' else False,)
        if args['merged'] is not None:
            where.append('merged = ?')
            params += (True if args['merged'] == 'true' else False,)
        if where:
            query += ' where ' + ' AND '.join(where)

        query += ' order by ' + args['sort'] + ' ' + args['order']

        limit = args['limit']
        if limit < 0:
            limit = 25
        if limit > 250:
            limit = 250

        offset = args['from']
        if offset < 0:
            offset = 0
        query += ' limit ' + str(limit + 1) + ' offset ' + str(offset)

        rows = database.query_db(query, params)
        data = [process_patch_row(row) for row in rows][:limit]

        link_headers = []

        if offset > 0:
            prev_url = url_for('patches', _external=True)

            prev_params = request.args.to_dict().copy()
            prev_params['from'] = offset - limit
            if (prev_params['from'] <= 0):
                prev_params.pop('from')

            prev_params = urlencode(prev_params)
            if (prev_params):
                prev_url += '?' + prev_params

            link_headers.append('<{}>; rel="prev"'.format(prev_url))

        # We fetched 1 more than the limit. If there are limit+1 rows in the
        # retrieved query, then there are more rows to be fetched
        if len(rows) > limit:
            next_url = url_for('patches', _external=True)
            next_params = request.args.to_dict().copy()

            next_params['from'] = offset + limit
            link_headers.append(
                '<{}?{}>; rel="next"'.format(next_url, urlencode(next_params)))

        headers = {}
        if (link_headers):
            headers['Link'] = ', '.join(link_headers)

        return marshal(data, patch_list_fields), 200, headers