Esempio n. 1
0
def test_get_dandiset_stats_one_item(server, dandiset_1, request_auth):
    dandi_id = dandiset_1["_id"]
    identifier = dandiset_1["name"]
    mkitem(server, request_auth, "Test Item", dandi_id)
    resp = server.request(f"/dandi/{identifier}/stats", method="GET")
    assertStatusOk(resp)
    assert {"bytes": 0, "folders": 0, "items": 1} == resp.json
Esempio n. 2
0
def testReviewerUser(provisionedServer):
    # Create a reviewer user
    resp = provisionedServer.request(path='/user',
                                     method='POST',
                                     params={
                                         'email':
                                         '*****@*****.**',
                                         'login': '******',
                                         'firstName': 'reviewer',
                                         'lastName': 'user',
                                         'password': '******'
                                     })
    assertStatusOk(resp)
    reviewerUser = User().findOne({'login': '******'})
    assert reviewerUser is not None

    # Add the user to the reviewers group
    reviewersGroup = Group().findOne({'name': 'Dataset QC Reviewers'})
    assert reviewersGroup is not None
    Group().addUser(reviewersGroup, reviewerUser, level=AccessType.READ)

    # Ensure they can review datasets
    resp = provisionedServer.request(path='/user/me',
                                     method='GET',
                                     user=reviewerUser)
    assertStatusOk(resp)
    assert resp.json['permissions']['reviewDataset']
Esempio n. 3
0
def testStudyAdminUser(provisionedServer):
    # Create a study admin user
    resp = provisionedServer.request(path='/user',
                                     method='POST',
                                     params={
                                         'email':
                                         '*****@*****.**',
                                         'login': '******',
                                         'firstName': 'study admin',
                                         'lastName': 'user',
                                         'password': '******'
                                     })
    assertStatusOk(resp)
    studyAdminUser = User().findOne({'login': '******'})
    assert studyAdminUser is not None

    # Add the user to the study admins group
    studyAdminsGroup = Group().findOne({'name': 'Study Administrators'})
    assert studyAdminsGroup is not None
    Group().addUser(studyAdminsGroup, studyAdminUser, level=AccessType.READ)

    # Ensure they can admin studies
    resp = provisionedServer.request(path='/user/me',
                                     method='GET',
                                     user=studyAdminUser)
    assertStatusOk(resp)
    assert resp.json['permissions']['adminStudy']
Esempio n. 4
0
def test_get(server, user, admin, project, postmortem):
    r = server.request('/edp/projects/%s/postmortems/%s' %
                       (project['_id'], postmortem['_id']),
                       method='GET',
                       user=user)
    assertStatusOk(r)
    assert postmortem.items() <= r.json.items()
Esempio n. 5
0
def testListNotificationsSinceTime(server, user, notifications):
    resp = server.request(path='/notification',
                          user=user,
                          params={'since': SINCE.isoformat()})
    assertStatusOk(resp)
    assert len(resp.json) == 1
    assert resp.json[0]['_id'] == str(notifications[0]['_id'])
Esempio n. 6
0
def testReadingSettingsAsAdmin(server, admin):
    # Reading settings as admin should work
    resp = server.request(path='/system/setting',
                          params={'key': SettingKey.SMTP_PORT},
                          user=admin)
    assertStatusOk(resp)
    assert resp.json == 25
Esempio n. 7
0
def test_get_dandiset_stats_tree(server, dandiset_1, request_auth,
                                 fsAssetstore):  # noqa: N803
    dandi_id = dandiset_1["_id"]
    identifier = dandiset_1["name"]

    folder_a_id = mkfolder(server, request_auth, "Folder A", dandi_id)
    folder_b_id = mkfolder(server, request_auth, "Folder B", folder_a_id)
    folder_c_id = mkfolder(server, request_auth, "Folder C",
                           folder_b_id)  # noqa: F841
    folder_d_id = mkfolder(server, request_auth, "Folder D", folder_b_id)

    item_a_id = mkitem(server, request_auth, "Item A", dandi_id)
    item_b_id = mkitem(server, request_auth, "Item B", folder_a_id)
    item_c_id = mkitem(server, request_auth, "Item C",
                       folder_d_id)  # noqa: F841

    contents = [
        "This is test text.",
        "Lorem ipsum dolor sit amet",
        "'Twas brillig, and the slithy toves did gyre and gimble in the wabe.",
    ]

    mkfile(server, request_auth, "test.txt", item_a_id, contents[0])
    mkfile(server, request_auth, "lorem.txt", item_b_id, contents[1])
    mkfile(server, request_auth, "jabberwocky.txt", item_b_id, contents[2])

    resp = server.request(f"/dandi/{identifier}/stats", method="GET")
    assertStatusOk(resp)
    assert {
        "bytes": len("".join(contents)),
        "folders": 4,
        "items": 3
    } == resp.json
Esempio n. 8
0
def test_find(server, user, project, cycle, batch):
    r = server.request('/edp/projects/%s/cycles/%s/batches' %
                       (project['_id'], cycle['_id']),
                       method='GET',
                       user=user)
    assertStatusOk(r)
    assert len(r.json) == 1
Esempio n. 9
0
def testReadingSettingsWithAdminScopedToken(server, adminSettingToken):
    # Reading settings with a properly scoped token should work
    resp = server.request(path='/system/setting',
                          params={'key': SettingKey.SMTP_PORT},
                          token=adminSettingToken)
    assertStatusOk(resp)
    assert resp.json == 25
Esempio n. 10
0
def test_get_molecule_inchikey(server, molecule, user):
    molecule = molecule(user)

    # The molecule will have been created by the fixture
    assert '_id' in molecule
    assert 'inchi' in molecule
    assert 'inchikey' in molecule
    assert 'smiles' in molecule

    # This one is not essential, but we set it ourselves
    assert 'name' in molecule

    _id = molecule['_id']
    inchi = molecule['inchi']
    inchikey = molecule['inchikey']
    smiles = molecule['smiles']
    name = molecule['name']

    # Find the molecule by its inchikey
    r = server.request('/molecules/inchikey/%s' % inchikey,
                       method='GET',
                       user=user)
    assertStatusOk(r)

    mol = r.json

    assert mol.get('_id') == _id
    assert mol.get('inchi') == inchi
    assert mol.get('inchikey') == inchikey
    assert mol.get('smiles') == smiles
    assert mol.get('name') == name
Esempio n. 11
0
def testWorkerStatusEndpoint(server, models):
    # Create a job to be handled by the worker plugin
    job = Job().createJob(
        title='title', type='foo', handler='worker_handler',
        user=models['admin'], public=False, args=(), kwargs={})

    job['kwargs'] = {
        'jobInfo': utils.jobInfoSpec(job),
        'inputs': [
            utils.girderInputSpec(models['adminFolder'], resourceType='folder')
        ],
        'outputs': [
            utils.girderOutputSpec(models['adminFolder'], token=models['adminToken'])
        ]
    }
    job = Job().save(job)
    assert job['status'] == JobStatus.INACTIVE

    # Schedule the job
    with mock.patch('celery.Celery') as celeryMock:
        instance = celeryMock.return_value
        instance.send_task.return_value = FakeAsyncResult()

        Job().scheduleJob(job)

    # Call the worker status endpoint
    resp = server.request('/worker/status', method='GET', user=models['admin'])
    assertStatusOk(resp)
    for key in ['report', 'stats', 'ping', 'active', 'reserved']:
        assert key in resp.json
Esempio n. 12
0
    def endpointsExist(self, name, present=None, absent=None):
        """
        Test if endpoints for particular image exist.

        :param name: name of the image used to determine endpoint location.
        :param present: a list of endpoints within the image that must exist.
        :param absent: a list of endpoints that should be in the image but not
            have endpoints.
        """
        present = present or []
        absent = absent or []
        userAndRepo, tag = splitName(name)
        data = self.getEndpoint()
        for cli in present:
            self.assertHasKeys(data, [userAndRepo])
            self.assertHasKeys(data[userAndRepo], [tag])
            self.assertHasKeys(data[userAndRepo][tag], [cli])
            path = data[userAndRepo][tag][cli]['xmlspec']
            resp = self.server.request(path=path,
                                       user=self.admin,
                                       isJson=False)
            assertStatusOk(resp)
        for cli in absent:
            self.assertHasKeys(data, [userAndRepo])
            self.assertHasKeys(data[userAndRepo], [tag])
            self.assertNotHasKeys(data[userAndRepo][tag], [cli])
Esempio n. 13
0
def multi_owner_dandiset(server, admin, user):
    resp = server.request(
        path="/dandi",
        method="POST",
        user=admin,
        params={
            "name": "multi_owner_dandiset",
            "description": "Dandiset that has multiple owners.",
        },
    )
    assertStatusOk(resp)

    created_dandiset = resp.json
    identifier = created_dandiset["meta"]["dandiset"]["identifier"]

    assertStatusOk(
        server.request(
            path=f"/dandi/{identifier}/owners",
            method="PUT",
            body=json.dumps([admin, user], default=str),
            user=admin,
            type="application/json",
        )
    )

    return created_dandiset
Esempio n. 14
0
def testTokenSessionDeletion(server, token):
    # With the token should succeed
    resp = server.request(path='/token/session', method='DELETE', token=token)
    assertStatusOk(resp)
    # Now the token is gone, so it should fail
    resp = server.request(path='/token/session', method='DELETE', token=token)
    assertStatus(resp, 401)
Esempio n. 15
0
def test_delete_with_file(server, user, project, postmortem, postmortemtest,
                          make_girder_file, fsAssetstore):
    from girder.plugins.edp.models.postmortemtest import PostmortemTest
    from girder.models.file import File

    image_file = make_girder_file(fsAssetstore, user, 'data')

    updates = {
        'imageFileId': image_file['_id'],
        'comments': 'We now have files.'
    }
    r = server.request(
        '/edp/projects/%s/postmortems/%s/tests/%s' %
        (project['_id'], postmortem['_id'], postmortemtest['_id']),
        method='PATCH',
        body=json.dumps({k: str(v)
                         for (k, v) in updates.items()}),
        type='application/json',
        user=user)
    assertStatusOk(r)

    r = server.request(
        '/edp/projects/%s/postmortems/%s/tests/%s' %
        (project['_id'], postmortem['_id'], postmortemtest['_id']),
        method='DELETE',
        user=user)
    assertStatusOk(r)

    postmortemtest = PostmortemTest().load(postmortemtest['_id'], force=True)
    assert postmortemtest is None

    image_file = File().load(image_file['_id'], force=True)
    assert image_file is None
Esempio n. 16
0
def test_get_cube(server, molecule, calculation, user):
    molecule = molecule(user, 'water')
    calculation_water = calculation(user, molecule, 'water')
    assert '_id' in calculation_water
    assert 'moleculeId' in calculation_water
    assert 'properties' in calculation_water
    calc_id = str(calculation_water['_id'])

    r = server.request('/calculations/%s/cube/%s' % (calc_id, 'h**o'),
                       method='GET',
                       user=user)
    assertStatusOk(r)

    cjson = r.json

    # Should now have a new cube field with orbital data
    assert 'cube' in cjson
    assert 'dimensions' in cjson['cube']
    assert 'origin' in cjson['cube']
    assert 'scalars' in cjson['cube']
    assert 'spacing' in cjson['cube']

    calc_dims = cjson['cube']['dimensions']
    calc_dims_prod = calc_dims[0] * calc_dims[1] * calc_dims[2]
    calc_scalars_len = len(cjson['cube']['scalars'])
    assert calc_dims_prod == calc_scalars_len
Esempio n. 17
0
def testDisableApiKeysSetting(server, user):
    errMsg = 'API key functionality is disabled on this instance.'

    resp = server.request('/api_key', method='POST', user=user, params={
        'name': 'test key'
    })
    assertStatusOk(resp)

    # Disable API keys
    Setting().set(SettingKey.API_KEYS, False)

    # Key should still exist
    key = ApiKey().load(resp.json['_id'], force=True, exc=True)

    # No longer possible to authenticate with existing key
    resp = server.request('/api_key/token', method='POST', params={
        'key': key['key']
    })
    assertStatus(resp, 400)
    assert resp.json['message'] == errMsg

    # No longer possible to create new keys
    resp = server.request('/api_key', method='POST', user=user, params={
        'name': 'should not work'
    })
    assertStatus(resp, 400)
    assert resp.json['message'] == errMsg

    # Still possible to delete key
    resp = server.request('/api_key/%s' % key['_id'], method='DELETE', user=user)
    assertStatusOk(resp)
    assert ApiKey().load(key['_id'], force=True) is None
Esempio n. 18
0
def test_get_cjson(server, molecule, calculation, user):
    molecule = molecule(user)
    calculation = calculation(user, molecule)

    assert '_id' in calculation
    assert 'moleculeId' in calculation
    calc_id = str(calculation['_id'])
    calc_molecule_id = str(calculation['moleculeId'])

    # Get the cjson for the calculation
    r = server.request('/calculations/%s/cjson' % calc_id,
                       method='GET',
                       user=user)
    assertStatusOk(r)

    cjson = r.json

    # Should have all the needed cjson components
    assert 'atoms' in cjson
    assert 'coords' in cjson['atoms']
    assert '3d' in cjson['atoms']['coords']
    assert len(cjson['atoms']['coords']['3d']) == 24  # 3 * 8 atoms = 24

    assert 'elements' in cjson['atoms']
    assert 'number' in cjson['atoms']['elements']
    assert cjson['atoms']['elements']['number'].count(1) == 6
    assert cjson['atoms']['elements']['number'].count(6) == 2
    assert len(cjson['atoms']['elements']['number']) == 8

    assert 'bonds' in cjson
    assert 'connections' in cjson['bonds']
    assert 'order' in cjson['bonds']
    assert len(cjson['bonds']['order']) == 7
Esempio n. 19
0
def testItemPosition7(server, makeResources, admin):
    resp = server.request(
        '/item/%s/position' % str(makeResources['privateItems'][7]['_id']),
        user=admin,
        params={'folderId': str(makeResources['folders'][1]['_id'])})
    assertStatusOk(resp)
    assert resp.json == 17
Esempio n. 20
0
def testTokenSessionReturnsPassedToken(server, token):
    # If we ask for another token, passing in the first one, we should get
    # the first one back
    resp = server.request(path='/token/session', method='GET', token=token)
    assertStatusOk(resp)
    token2 = resp.json['token']
    assert token == token2
Esempio n. 21
0
def test_get(server, project, cycle, batch, make_batch, user, admin,
             cycletest):
    r = server.request(
        '/edp/projects/%s/cycles/%s/batches/%s/tests/%s' %
        (project['_id'], cycle['_id'], batch['_id'], cycletest['_id']),
        method='GET',
        user=user)
    assertStatusOk(r)
    assert cycletest.items() <= r.json.items()

    # Make another project and try to fetch a test that is not associated
    # with it
    body = {
        'startDate': datetime.datetime.utcnow().timestamp(),
        'title': 'another title',
        'experimentalDesign': 'I designed the cool experiment.',
        'experimentalNotes': 'These are my notes.',
        'dataNotes': 'Here are some notes.',
        'motivation': 'I have some.'
    }
    another_batch = make_batch(user, project, cycle, body)
    r = server.request(
        '/edp/projects/%s/cycles/%s/batches/%s/tests/%s' %
        (project['_id'], cycle['_id'], another_batch['_id'], cycletest['_id']),
        method='GET',
        user=user)
    assertStatus(r, 400)
Esempio n. 22
0
def test_find(server, user, project):
    from girder.plugins.edp.models.project import Project

    r = server.request('/edp/projects',
                       method='GET', user=user)
    assertStatusOk(r)
    assert len(r.json) == 1
Esempio n. 23
0
def testDeleteItemUpdatesSize(server, admin, hierarchy):
    resp = server.request(path='/item/%s' % hierarchy.items[0]['_id'], method='DELETE', user=admin)
    assertStatusOk(resp)

    assertNodeSize(hierarchy.folders[0], Folder, 0)
    assertNodeSize(hierarchy.folders[1], Folder, 10)
    assertNodeSize(hierarchy.collections[0], Collection, 10)
Esempio n. 24
0
def testAdminCanAccessOtherUsersKeys(server, admin, user):
    # Admins should be able to see other users' keys
    resp = server.request('/api_key',
                          params={'userId': user['_id']},
                          user=admin)
    assertStatusOk(resp)
    assert resp.json == []
Esempio n. 25
0
def testCustomWebRoot(route, server):
    """
    Tests the ability of plugins to serve their own custom server roots.
    """
    resp = server.request(route)
    assertStatusOk(resp)
    assert resp.json == ['custom REST route']
Esempio n. 26
0
def test_get_geometry(server, geometry, molecule, user):

    molecule = molecule(user)
    geometry = geometry(user, molecule)

    # The geometry will have been created by the fixture
    assert '_id' in geometry
    assert 'moleculeId' in geometry
    assert 'cjson' in geometry

    # These are not essential, but we set it ourselves
    assert 'provenanceType' in geometry
    assert 'provenanceId' in geometry

    _id = geometry['_id']
    molecule_id = geometry['moleculeId']
    cjson = geometry['cjson']
    provenance_type = geometry['provenanceType']
    provenance_id = geometry['provenanceId']

    # Find the geometry by its parent molecule.
    path = '/molecules/%s/geometries' % molecule_id
    r = server.request(path, method='GET', user=user)
    assertStatusOk(r)

    # There should be exactly one
    assert len(r.json['results']) == 1
    geometry = r.json['results'][0]

    # Everything should match
    assert geometry.get('_id') == str(_id)
    assert geometry.get('moleculeId') == str(molecule_id)
    assert geometry.get('provenanceType') == provenance_type
    assert geometry.get('provenanceId') == str(provenance_id)
Esempio n. 27
0
def testUserCanAccessTheirOwnApiKeys(server, user):
    # Users should be able to request their own keys
    resp = server.request('/api_key',
                          params={'userId': user['_id']},
                          user=user)
    assertStatusOk(resp)
    assert resp.json == []
Esempio n. 28
0
def testCustomWebRoot(route, server):
    """
    Tests the ability of plugins to serve their own custom server roots.
    """
    resp = server.request(route)
    assertStatusOk(resp)
    assert resp.json == ['custom REST route']
Esempio n. 29
0
def test_get_calc(server, molecule, calculation, user):

    assert '_id' in calculation
    assert 'moleculeId' in calculation
    calc_id = str(calculation['_id'])
    calc_molecule_id = str(calculation['moleculeId'])

    # Find it by molecule id
    params = {'moleculeId': calc_molecule_id}
    r = server.request('/calculations', method='GET', params=params, user=user)
    assertStatusOk(r)

    # Should just be one calculation
    assert len(r.json) == 1

    calc = r.json[0]

    assert '_id' in calc
    assert str(calc['_id']) == calc_id

    # Find it by its own id
    r = server.request('/calculations/%s' % calc_id, method='GET', user=user)
    assertStatusOk(r)

    calc = r.json

    assert '_id' in calc
    assert str(calc['_id']) == calc_id
Esempio n. 30
0
def test_get(server, user, admin, project, cycle):
    r = server.request('/edp/projects/%s/cycles/%s' %
                       (project['_id'], cycle['_id']),
                       method='GET',
                       user=user)
    assertStatusOk(r)
    assert cycle.items() <= r.json.items()
def test_get_cjson(server, calculation, user):

    assert '_id' in calculation
    assert 'moleculeId' in calculation
    calc_id = str(calculation['_id'])
    calc_molecule_id = str(calculation['moleculeId'])

    # Get the cjson for the calculation
    r = server.request(
        '/calculations/%s/cjson' %
        calc_id, method='GET', user=user)
    assertStatusOk(r)

    cjson = json.loads(r.json)

    # Should have all the needed cjson components
    assert 'atoms' in cjson
    assert 'coords' in cjson['atoms']
    assert '3d' in cjson['atoms']['coords']
    assert len(cjson['atoms']['coords']['3d']) == 24  # 3 * 8 atoms = 24

    assert 'elements' in cjson['atoms']
    assert 'number' in cjson['atoms']['elements']
    assert cjson['atoms']['elements']['number'].count(1) == 6
    assert cjson['atoms']['elements']['number'].count(6) == 2
    assert len(cjson['atoms']['elements']['number']) == 8

    assert 'bonds' in cjson
    assert 'connections' in cjson['bonds']
    assert 'order' in cjson['bonds']
    assert len(cjson['bonds']['order']) == 7
def test_put_properties(server, molecule, calculation, user):
    from girder.plugins.molecules.models.calculation import Calculation
    from girder.constants import AccessType

    assert '_id' in calculation
    assert 'moleculeId' in calculation
    assert 'properties' in calculation
    calc_id = str(calculation['_id'])
    calc_molecule_id = str(calculation['moleculeId'])
    calc_properties = calculation['properties']

    # We put these properties in ourselves
    assert 'molecular mass' in calc_properties
    assert 'boiling point' in calc_properties
    assert 'melting point' in calc_properties

    # Make sure these have the right values
    assert pytest.approx(calc_properties['molecular mass'], 1.e-4) == 30.0690
    assert calc_properties['melting point'] == -172
    assert calc_properties['boiling point'] == -88

    # Replace these properties with some new properties
    new_properties = {
        'critical temperature': 32.2,
        'critical pressure': 49.0
    }
    r = server.request('/calculations/%s/properties' % calc_id, method='PUT',
                       body=json.dumps(new_properties), user=user,
                       type='application/json')
    assertStatusOk(r)

    # Grab the new calculation
    updated_calc = Calculation().load(calc_id, level=AccessType.READ, user=user)

    # It should have an _id and a molecule id, and it should match
    assert '_id' in updated_calc
    assert 'moleculeId' in updated_calc
    assert 'properties' in updated_calc

    assert str(updated_calc['_id']) == calc_id
    assert str(updated_calc['moleculeId']) == calc_molecule_id

    # Make sure the old properties are no longer here
    updated_calc_properties = updated_calc['properties']
    assert 'molecular mass' not in updated_calc_properties
    assert 'boiling point' not in updated_calc_properties
    assert 'melting point' not in updated_calc_properties

    # The new properties should be here, though
    assert 'critical temperature' in updated_calc_properties
    assert 'critical pressure' in updated_calc_properties

    # Make sure these are correct also
    assert pytest.approx(
        updated_calc_properties['critical temperature'],
        1.e-1) == new_properties['critical temperature']
    assert pytest.approx(
        updated_calc_properties['critical pressure'],
        1.e-1) == new_properties['critical pressure']
Esempio n. 33
0
def testWorker(server, models):
    # Test the settings
    resp = server.request('/system/setting', method='PUT', params={
        'list': json.dumps([{
            'key': PluginSettings.BROKER,
            'value': 'amqp://[email protected]'
        }, {
            'key': PluginSettings.BACKEND,
            'value': 'amqp://[email protected]'
        }])
    }, user=models['admin'])
    assertStatusOk(resp)

    # Create a job to be handled by the worker plugin
    jobModel = Job()
    job = jobModel.createJob(
        title='title', type='foo', handler='worker_handler',
        user=models['admin'], public=False, args=(), kwargs={})

    job['kwargs'] = {
        'jobInfo': utils.jobInfoSpec(job),
        'inputs': [
            utils.girderInputSpec(models['adminFolder'], resourceType='folder')
        ],
        'outputs': [
            utils.girderOutputSpec(models['adminFolder'], token=models['adminToken'])
        ]
    }
    job = jobModel.save(job)
    assert job['status'] == JobStatus.INACTIVE

    # Schedule the job, make sure it is sent to celery
    with mock.patch('celery.Celery') as celeryMock:
        instance = celeryMock.return_value
        instance.send_task.return_value = FakeAsyncResult()

        jobModel.scheduleJob(job)

        # Make sure we sent the job to celery
        assert len(celeryMock.mock_calls) == 2
        assert celeryMock.mock_calls[0][1] == ('girder_worker',)
        assert celeryMock.mock_calls[0][2] == {
            'broker': 'amqp://[email protected]',
            'backend': 'amqp://[email protected]'
        }

        sendTaskCalls = celeryMock.return_value.send_task.mock_calls

        assert len(sendTaskCalls) == 1
        assert sendTaskCalls[0][1] == (
            'girder_worker.run', job['args'], job['kwargs'])

        assert 'headers' in sendTaskCalls[0][2]
        assert 'jobInfoSpec' in sendTaskCalls[0][2]['headers']

        # Make sure we got and saved the celery task id
        job = jobModel.load(job['_id'], force=True)
        assert job['celeryTaskId'] == 'fake_id'
        assert job['status'] == JobStatus.QUEUED
def test_list_dandisets_limit(server, request_auth, dandiset_1, dandiset_2):
    resp = server.request(path=path,
                          method="GET",
                          params={"limit": 1},
                          **request_auth)
    assertStatusOk(resp)
    assert len(resp.json) == 1
    assert_dandisets_are_equal(dandiset_1, resp.json[0])
Esempio n. 35
0
def testPluginRestRoutes(server):
    resp = server.request('/describe')
    assertStatusOk(resp)
    assert '/other' in resp.json['paths']

    resp = server.request('/other')
    assertStatusOk(resp)
    assert resp.json == ['custom REST route']
Esempio n. 36
0
def testPluginRestRoutes(server):
    resp = server.request('/describe')
    assertStatusOk(resp)
    assert '/other' in resp.json['paths']

    resp = server.request('/other')
    assertStatusOk(resp)
    assert resp.json == ['custom REST route']
Esempio n. 37
0
def testLoadModelDecorator(server, user):
    resp = server.request(
        path='/accesstest/test_loadmodel_plain/%s' % user['_id'], method='GET')
    assertStatusOk(resp)
    assert resp.json['_id'] == str(user['_id'])

    resp = server.request(path='/accesstest/test_loadmodel_query', params={'userId': None})
    assertStatus(resp, 400)
    assert resp.json['message'] == 'Invalid ObjectId: None'
Esempio n. 38
0
def apiKey(server, user):
    # Create a new API key with full access
    resp = server.request('/api_key', method='POST', params={
        'name': 'test key'
    }, user=user)
    assertStatusOk(resp)
    apiKey = ApiKey().load(resp.json['_id'], force=True)

    yield apiKey
Esempio n. 39
0
def testMoveSubfolderToUser(server, admin, hierarchy):
    resp = server.request(
        path='/folder/%s' % hierarchy.folders[1]['_id'], method='PUT',
        user=admin, params={
            'parentId': admin['_id'],
            'parentType': 'user'
        })
    assertStatusOk(resp)
    assertNodeSize(admin, User, 10)
    assertNodeSize(hierarchy.collections[0], Collection, 1)
Esempio n. 40
0
def testApiDocsContent(server):
    """
    Test content of API documentation page.
    """
    resp = server.request(path='/api/v1', method='GET', isJson=False, prefix='')
    assertStatusOk(resp)
    body = getResponseBody(resp)

    assert 'Girder REST API Documentation' in body
    assert 'This is not a sandbox' in body
    assert 'id="swagger-ui-container"' in body
Esempio n. 41
0
def testTokenCreationDuration(server, user, apiKey):
    defaultDuration = Setting().get(SettingKey.COOKIE_LIFETIME)
    # We should be able to request a duration shorter than default
    resp = server.request('/api_key/token', method='POST', params={
        'key': apiKey['key'],
        'duration': defaultDuration - 1
    })
    assertStatusOk(resp)
    token = Token().load(
        resp.json['authToken']['token'], force=True, objectId=False)
    duration = token['expires'] - token['created']
    assert duration == datetime.timedelta(days=defaultDuration - 1)
Esempio n. 42
0
def testUploaderUser(provisionedServer, smtp):
    # Create an uploader admin
    resp = provisionedServer.request(path='/user', method='POST', params={
        'email': '*****@*****.**',
        'login': '******',
        'firstName': 'uploader',
        'lastName': 'admin',
        'password': '******'
    })
    assertStatusOk(resp)
    uploaderAdmin = User().findOne({'login': '******'})
    assert uploaderAdmin is not None
    contributorsGroup = Group().findOne({'name': 'Dataset Contributors'})
    assert contributorsGroup is not None
    Group().addUser(contributorsGroup, uploaderAdmin, level=AccessType.WRITE)

    # Create an uploader user
    resp = provisionedServer.request(path='/user', method='POST', params={
        'email': '*****@*****.**',
        'login': '******',
        'firstName': 'uploader',
        'lastName': 'user',
        'password': '******'
    })
    assertStatusOk(resp)
    uploaderUser = User().findOne({'login': '******'})
    assert uploaderUser is not None

    # TODO: check if a user can upload without agreeing to terms

    # Ensure request create dataset permission works
    resp = provisionedServer.request(path='/user/requestCreateDatasetPermission',
                                     method='POST', user=uploaderUser)
    assertStatusOk(resp)
    assert smtp.waitForMail()
    assert smtp.getMail()  # pop off the queue for later assertion that the queue is empty

    # Ensure that the user can't create datasets yet
    resp = provisionedServer.request(path='/user/me', method='GET', user=uploaderUser)
    assertStatusOk(resp)
    assert not resp.json['permissions']['createDataset']

    # Ensure that a join request is pending
    contributorsGroup = Group().findOne({'name': 'Dataset Contributors'})
    joinRequestUserIds = [user['id'] for user in Group().getFullRequestList(contributorsGroup)]
    assert uploaderUser['_id'] in joinRequestUserIds
    assert smtp.isMailQueueEmpty()

    # Add the user, then ensure they can create datasets
    Group().inviteUser(contributorsGroup, uploaderUser, level=AccessType.READ)
    resp = provisionedServer.request(path='/user/me', method='GET', user=uploaderUser)
    assertStatusOk(resp)
    assert resp.json['permissions']['createDataset']
Esempio n. 43
0
def testMoveFolderToNewCollection(server, admin, hierarchy):
    assertNodeSize(hierarchy.collections[0], Collection, 11)
    assertNodeSize(hierarchy.collections[1], Collection, 0)

    resp = server.request(
        path='/folder/%s' % hierarchy.folders[0]['_id'], method='PUT',
        user=admin, params={
            'parentId': hierarchy.collections[1]['_id'],
            'parentType': 'collection'
        })
    assertStatusOk(resp)
    assertNodeSize(hierarchy.collections[0], Collection, 0)
    assertNodeSize(hierarchy.collections[1], Collection, 11)
Esempio n. 44
0
def testTokenCreatesUniqueTokens(server, user, apiKey):
    for _ in range(0, 2):
        resp = server.request('/api_key/token', method='POST', params={
            'key': apiKey['key']
        })
        assertStatusOk(resp)

    # We should have two tokens for this key
    q = {
        'userId': user['_id'],
        'apiKeyId': apiKey['_id']
    }
    count = Token().find(q).count()
    assert count == 2
Esempio n. 45
0
def testApiDocsCustomContent(server):
    """
    Test content of API documentation page that's customized by a plugin.
    """
    resp = server.request(path='/api/v1', method='GET', isJson=False, prefix='')
    assertStatusOk(resp)
    body = getResponseBody(resp)

    assert 'Girder REST API Documentation' not in body
    assert 'This is not a sandbox' not in body

    assert 'Girder Web Application Programming Interface' in body
    assert '<p>Custom API description</p>' in body
    assert 'id="swagger-ui-container"' in body
Esempio n. 46
0
def testListScopes(server):
    resp = server.request('/token/scopes')
    assertStatusOk(resp)
    assert resp.json == TokenScope.listScopes()

    assert 'custom' in resp.json
    assert isinstance(resp.json['custom'], list)
    assert 'adminCustom' in resp.json
    assert isinstance(resp.json['adminCustom'], list)

    for scope in resp.json['custom'] + resp.json['adminCustom']:
        assert 'id' in scope
        assert 'name' in scope
        assert 'description' in scope
Esempio n. 47
0
def testInactiveKeysCannotCreateTokens(server, user, apiKey):
    newScopes = [TokenScope.DATA_READ, TokenScope.DATA_WRITE]
    resp = server.request('/api_key/%s' % apiKey['_id'], params={
        'active': False,
        'tokenDuration': 10,
        'scope': json.dumps(newScopes)
    }, method='PUT', user=user)
    assertStatusOk(resp)

    # We should not be able to create tokens for this key anymore
    resp = server.request('/api_key/token', method='POST', params={
        'key': apiKey['key']
    })
    assertStatus(resp, 400)
    assert resp.json['message'] == 'Invalid API key.'
Esempio n. 48
0
def testInactiveKeyStructure(server, user, apiKey):
    newScopes = [TokenScope.DATA_READ, TokenScope.DATA_WRITE]
    resp = server.request('/api_key/%s' % apiKey['_id'], params={
        'active': False,
        'tokenDuration': 10,
        'scope': json.dumps(newScopes)
    }, method='PUT', user=user)
    assertStatusOk(resp)

    # Make sure key itself didn't change
    assert resp.json['key'] == apiKey['key']
    apiKey = ApiKey().load(resp.json['_id'], force=True)
    assert not apiKey['active']
    assert apiKey['tokenDuration'] == 10
    assert set(apiKey['scope']) == set(newScopes)
Esempio n. 49
0
def testWebRootProperlyHandlesCustomStaticPublicPath(server):
    cherrypy.config['server']['static_public_path'] = 'http://my-cdn-url.com/static'

    resp = server.request(path='/', method='GET', isJson=False, prefix='')
    assertStatusOk(resp)
    body = getResponseBody(resp)

    assert 'href="http://my-cdn-url.com/static/built/Girder_Favicon.png"' in body

    # Same assertion should hold true for Swagger
    resp = server.request(path='/', method='GET', isJson=False)
    assertStatusOk(resp)
    body = getResponseBody(resp)

    assert 'href="http://my-cdn-url.com/static/built/Girder_Favicon.png"' in body

    cherrypy.config['server']['static_public_path'] = '/static'
Esempio n. 50
0
def testCollectionDeleteMetadata(server, collection, admin):
    collection = Collection().setMetadata(collection, METADATA)
    resp = server.request(
        path='/collection/%s/metadata' % collection['_id'],
        user=admin,
        method='DELETE',
        body=json.dumps(list(METADATA.keys())),
        type='application/json')
    assertStatusOk(resp)
    assert resp.json['meta'] != METADATA
    assert resp.json['meta'] == {}

    newDoc = server.request(
        path='/collection/%s' % collection['_id'],
        user=admin,
        method='GET')
    assert newDoc.json['meta'] != METADATA
    assert newDoc.json['meta'] == {}
Esempio n. 51
0
def testCollectionSetMetadata(server, collection, admin):
    resp = server.request(
        path='/collection/%s/metadata' % collection['_id'],
        user=admin,
        method='PUT',
        body=json.dumps(METADATA),
        type='application/json')

    assertStatusOk(resp)
    assert resp.json['meta'] == METADATA

    # Check that fetching the object again yields the same result
    newDoc = server.request(
        path='/collection/%s' % collection['_id'],
        user=admin,
        method='GET')

    assert newDoc.json['meta'] == METADATA
Esempio n. 52
0
def testApiKeyDeletionDeletesAssociatedTokens(server, user, apiKey):
    resp = server.request('/api_key/token', method='POST', params={
        'key': apiKey['key']
    })
    assertStatusOk(resp)

    q = {
        'userId': user['_id'],
        'apiKeyId': apiKey['_id']
    }

    # Deleting the API key should delete the tokens made with it
    count = Token().find(q).count()
    assert count == 1
    resp = server.request('/api_key/%s' % apiKey['_id'], method='DELETE', user=user)
    assertStatusOk(resp)
    count = Token().find(q).count()
    assert count == 0
Esempio n. 53
0
def testMoveItemToSubfolder(server, admin, hierarchy):
    assertNodeSize(hierarchy.items[0], Item, 1)
    assertNodeSize(hierarchy.items[1], Item, 10)
    assertNodeSize(hierarchy.folders[0], Folder, 1)
    assertNodeSize(hierarchy.folders[1], Folder, 10)
    assertNodeSize(hierarchy.collections[0], Collection, 11)

    resp = server.request(
        path='/item/%s' % hierarchy.items[0]['_id'], method='PUT',
        user=admin, params={
            'folderId': hierarchy.folders[1]['_id']
        })
    assertStatusOk(resp)
    assertNodeSize(hierarchy.items[0], Item, 1)
    assertNodeSize(hierarchy.items[1], Item, 10)
    assertNodeSize(hierarchy.folders[0], Folder, 0)
    assertNodeSize(hierarchy.folders[1], Folder, 11)
    assertNodeSize(hierarchy.collections[0], Collection, 11)
Esempio n. 54
0
def testWebRootProperlyHandlesStaticRouteUrls(server, db):
    Setting().set(SettingKey.ROUTE_TABLE, {
        GIRDER_ROUTE_ID: '/',
        GIRDER_STATIC_ROUTE_ID: 'http://my-cdn-url.com/static'
    })

    resp = server.request(path='/', method='GET', isJson=False, prefix='')
    assertStatusOk(resp)
    body = getResponseBody(resp)

    assert 'href="http://my-cdn-url.com/static/img/Girder_Favicon.png"' in body

    # Same assertion should hold true for Swagger
    resp = server.request(path='/', method='GET', isJson=False)
    assertStatusOk(resp)
    body = getResponseBody(resp)

    assert 'href="http://my-cdn-url.com/static/img/Girder_Favicon.png"' in body
Esempio n. 55
0
def testTokenCreation(server, user, apiKey):
    defaultDuration = Setting().get(SettingKey.COOKIE_LIFETIME)
    # Create a token using the key
    resp = server.request('/api_key/token', method='POST', params={
        'key': apiKey['key'],
        'duration': defaultDuration + 1000
    })
    assertStatusOk(resp)
    token = Token().load(
        resp.json['authToken']['token'], force=True, objectId=False)
    # Make sure token has full user auth access
    assert token['userId'] == user['_id']
    assert token['scope'] == [TokenScope.USER_AUTH]
    # Make sure the token references the API key used to create it
    assert token['apiKeyId'] == apiKey['_id']

    # Make sure the token duration is not longer than the default
    duration = token['expires'] - token['created']
    assert duration == datetime.timedelta(days=defaultDuration)
Esempio n. 56
0
def testRouteTableBehavior(server, admin):
    Setting().set(SettingKey.ROUTE_TABLE, {
        GIRDER_ROUTE_ID: '/',
        'has_webroot': '/has_webroot'
    })

    # /has_webroot should serve our plugin webroot
    resp = server.request('/has_webroot', prefix='', isJson=False, appPrefix='/has_webroot')
    assertStatusOk(resp)
    assert 'some webroot' in getResponseBody(resp)

    # girder should be at /
    resp = server.request('/', prefix='', isJson=False)
    assertStatusOk(resp)
    assert 'g-global-info-apiroot' in getResponseBody(resp)

    table = Setting().get(SettingKey.ROUTE_TABLE)
    assert 'has_webroot' in table
    assert table['has_webroot'] == '/has_webroot'
def test_ingest_pending(server, molecule, user, make_girder_file, fsAssetstore):
    body = {
        'moleculeId': molecule['_id'],
        'cjson': None,
        'public': True,
        'properties': {
            'calculationTypes': 'energy;',
            'basisSet': {
                'name': '3-21g'
            },
            'theory': 'b3lyp',
            'pending': True,
            'code': 'nwchem'
        }
    }

    # First create pending calculation
    r = server.request('/calculations', method='POST', type='application/json',
                       body=json.dumps(body), user=user)
    assertStatus(r, 201)
    calculation = r.json

    # Upload simulation result
    dir_path = os.path.dirname(os.path.realpath(__file__))

    with open(os.path.join(dir_path, 'data', 'ethane.cjson')) as f:
        file = make_girder_file(fsAssetstore, user, 'ethane.cjson', contents=f.read().encode())

    # Now we can test the ingest
    body = {
        'fileId': str(file['_id']),
        'format': 'cjson',
        'public': True
    }

    r = server.request('/calculations/%s' % calculation['_id'], method='PUT', type='application/json',
                       body=json.dumps(body), user=user)
    assertStatusOk(r)
    calculation = r.json

    assert 'pending' not in calculation['properties']
Esempio n. 58
0
def testDeactivatingKeyDeletesAssociatedTokens(server, user, apiKey):
    resp = server.request('/api_key/token', method='POST', params={
        'key': apiKey['key']
    })
    assertStatusOk(resp)

    newScopes = [TokenScope.DATA_READ, TokenScope.DATA_WRITE]
    resp = server.request('/api_key/%s' % apiKey['_id'], params={
        'active': False,
        'tokenDuration': 10,
        'scope': json.dumps(newScopes)
    }, method='PUT', user=user)
    assertStatusOk(resp)

    # This should have deleted all corresponding tokens
    q = {
        'userId': user['_id'],
        'apiKeyId': apiKey['_id']
    }
    count = Token().find(q).count()
    assert count == 0