def test_a_initialize(self):
        """Initialize the database for /rememberedforms tests."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        self.create_db()

        db.clear_all_models()
        administrator = omb.generate_default_administrator(
            settings=self.settings)
        contributor = omb.generate_default_contributor(settings=self.settings)
        viewer = omb.generate_default_viewer(settings=self.settings)
        dbsession.add_all([administrator, contributor, viewer])
        dbsession.commit()

        _create_test_data(dbsession, db, self.n)
        add_SEARCH_to_web_test_valid_methods()

        # Create an application settings where the contributor is unrestricted
        viewer, contributor, administrator = get_users(db)
        application_settings = omb.generate_default_application_settings()
        application_settings.unrestricted_users = [contributor]
        dbsession.add(application_settings)
        dbsession.commit()
Beispiel #2
0
    def test_zzz_cleanup(self):
        """Clean up after the tests."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)
        # Destruction
        db.clear_all_tables()
        h.destroy_all_directories('users', self.settings)
        h.destroy_all_directories('corpora', self.settings)
        dbsession.commit()

        self.create_db()
    def test_e_cleanup(self):
        """Clean up the database after /rememberedforms tests."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        db.clear_all_models()
        administrator = omb.generate_default_administrator(
            settings=self.settings)
        contributor = omb.generate_default_contributor(settings=self.settings)
        viewer = omb.generate_default_viewer(settings=self.settings)
        dbsession.add_all([administrator, contributor, viewer])
        dbsession.commit()
Beispiel #4
0
 def tearDown(self, **kwargs):
     """Clean up after a test."""
     db = DBUtils(self.dbsession, self.settings)
     clear_all_tables = kwargs.get('clear_all_tables', False)
     dirs_to_clear = kwargs.get('dirs_to_clear', [])
     dirs_to_destroy = kwargs.get('dirs_to_destroy', [])
     if clear_all_tables:
         db.clear_all_tables(['language'])
     else:
         self.clear_all_models(self.dbsession)
     for dir_path in dirs_to_clear:
         h.clear_directory_of_files(getattr(self, dir_path))
     for dir_name in dirs_to_destroy:
         h.destroy_all_directories(self.inflect_p.plural(dir_name),
                                   self.settings)
     if self.Session2:
         db = DBUtils(self.dbsession, self.settings2)
         clear_all_tables = kwargs.get('clear_all_tables', False)
         dirs_to_clear = kwargs.get('dirs_to_clear', [])
         dirs_to_destroy = kwargs.get('dirs_to_destroy', [])
         if clear_all_tables:
             db.clear_all_tables(['language'])
         else:
             self.clear_all_models(self.dbsession2)
         for attr_name in dirs_to_clear:
             dir_name = attr_name.replace('_path', '')
             dir_path = h.get_old_directory_path(dir_name,
                                                 settings=self.settings2)
             h.clear_directory_of_files(dir_path)
         for dir_name in dirs_to_destroy:
             h.destroy_all_directories(self.inflect_p.plural(dir_name),
                                       self.settings2)
     self.tear_down_dbsession()
Beispiel #5
0
    def test_edit(self):
        """Tests that GET /orthographies/id/edit returns a JSON object of data necessary to edit the orthography with id=id.

        The JSON object is of the form {'orthography': {...}, 'data': {...}} or
        {'error': '...'} (with a 404 status code) depending on whether the id is
        valid or invalid/unspecified, respectively.
        """

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create an orthography to edit.
        params = self.orthography_create_params.copy()
        params.update({'name': 'orthography', 'orthography': 'a, b, c'})
        params = json.dumps(params)
        response = self.app.post(url('create'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = response.json_body
        assert resp['name'] == 'orthography'
        assert resp['orthography'] == 'a, b, c'
        assert resp[
            'lowercase'] is False  # default value from model/orthography.py
        assert resp[
            'initial_glottal_stops'] is True  # default value from model/orthography.py
        orthography_id = resp['id']

        # Not logged in: expect 401 Unauthorized
        response = self.app.get(url('edit', id=orthography_id), status=401)
        resp = response.json_body
        assert resp[
            'error'] == 'Authentication is required to access this resource.'
        assert response.content_type == 'application/json'

        # Invalid id
        id = 9876544
        response = self.app.get(url('edit', id=id),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin,
                                status=404)
        assert 'There is no orthography with id %s' % id in response.json_body[
            'error']
        assert response.content_type == 'application/json'

        # No id
        response = self.app.get(url('edit', id=''),
                                status=404,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        assert response.json_body[
            'error'] == 'The resource could not be found.'

        # Valid id
        response = self.app.get(url('edit', id=orthography_id),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        resp = response.json_body
        assert resp['orthography']['name'] == 'orthography'
        assert resp['orthography']['orthography'] == 'a, b, c'
        assert resp['data'] == {}
        assert response.content_type == 'application/json'
    def test_show(self):
        """Tests that GET /syntacticcategories/id returns the syntactic category with id=id or an appropriate error."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create an syntactic category to show.
        params = json.dumps({'name': 'name', 'type': 'lexical', 'description': 'description'})
        response = self.app.post(url('create'), params, self.json_headers,
                                    self.extra_environ_admin)
        resp = response.json_body
        syntactic_category_id = resp['id']

        # Try to get a syntactic_category using an invalid id
        id = 100000000000
        response = self.app.get(url('show', id=id),
            headers=self.json_headers, extra_environ=self.extra_environ_admin,
            status=404)
        resp = response.json_body
        assert 'There is no syntactic category with id %s' % id in response.json_body['error']
        assert response.content_type == 'application/json'

        # No id
        response = self.app.get(url('show', id=''), status=404,
            headers=self.json_headers, extra_environ=self.extra_environ_admin)
        assert response.json_body['error'] == 'The resource could not be found.'
        assert response.content_type == 'application/json'

        # Valid id
        response = self.app.get(url('show', id=syntactic_category_id), headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        resp = response.json_body
        assert resp['name'] == 'name'
        assert resp['description'] == 'description'
        assert response.content_type == 'application/json'
    def test_new(self):
        """Tests that GET /elicitationmethods/new returns an empty JSON object."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)
        response = self.app.get(url('new'), headers=self.json_headers,
                                extra_environ=self.extra_environ_contrib)
        resp = response.json_body
        assert resp == {}
        assert response.content_type == 'application/json'
    def test_new(self):
        """Tests that GET /syntacticcategories/new returns an empty JSON object."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)
        response = self.app.get(url('new'), headers=self.json_headers,
                                extra_environ=self.extra_environ_contrib)
        resp = response.json_body
        assert resp['syntactic_category_types'] == list(oldc.SYNTACTIC_CATEGORY_TYPES)
        assert response.content_type == 'application/json'
    def test_delete(self):
        """Tests that DELETE /formsearches/id deletes the form search with id=id."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create a form search to delete.
        query = {'filter': ['Form', 'transcription', 'regex', '[a-g]{3,}']}
        params = self.form_search_create_params.copy()
        params.update({
            'name': 'form search',
            'description': 'This one\'s worth saving!',
            'search': query
        })
        params = json.dumps(params)
        response = self.app.post(url('create'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = response.json_body
        form_search_count = dbsession.query(FormSearch).count()
        form_search_id = resp['id']
        assert resp['name'] == 'form search'
        assert resp['description'] == "This one's worth saving!"
        assert resp['search'] == query

        # Now delete the form_search
        response = self.app.delete(url('delete', id=form_search_id),
                                   headers=self.json_headers,
                                   extra_environ=self.extra_environ_admin)
        resp = response.json_body
        new_form_search_count = dbsession.query(FormSearch).count()
        assert new_form_search_count == form_search_count - 1
        assert resp['id'] == form_search_id
        assert response.content_type == 'application/json'

        # Trying to get the deleted form_search from the db should return None
        deleted_form_search = dbsession.query(FormSearch).get(form_search_id)
        assert deleted_form_search is None

        # Delete with an invalid id
        id = 9999999999999
        response = self.app.delete(url('delete', id=id),
                                   headers=self.json_headers,
                                   extra_environ=self.extra_environ_admin,
                                   status=404)
        assert 'There is no form search with id %s' % id in response.json_body[
            'error']
        assert response.content_type == 'application/json'

        # Delete without an id
        response = self.app.delete(url('delete', id=''),
                                   status=404,
                                   headers=self.json_headers,
                                   extra_environ=self.extra_environ_admin)
        assert response.json_body[
            'error'] == 'The resource could not be found.'
    def test_new(self):
        """Tests that GET /speakers/new returns an empty JSON object."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)
        response = self.app.get(url('new'),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_contrib)
        resp = response.json_body
        assert resp == {'markup_languages': list(oldc.MARKUP_LANGUAGES)}
        assert response.content_type == 'application/json'
    def test_delete(self):
        """Tests that DELETE /speakers/id deletes the speaker with id=id."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create a speaker to delete.
        params = self.speaker_create_params.copy()
        params.update({
            'first_name': 'first_name',
            'last_name': 'last_name',
            'page_content': 'page_content',
            'dialect': 'dialect'
        })
        params = json.dumps(params)
        response = self.app.post(url('create'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = response.json_body
        speaker_count = dbsession.query(Speaker).count()
        speaker_id = resp['id']

        # Now delete the speaker
        response = self.app.delete(url('delete', id=speaker_id),
                                   headers=self.json_headers,
                                   extra_environ=self.extra_environ_admin)
        resp = response.json_body
        new_speaker_count = dbsession.query(Speaker).count()
        assert new_speaker_count == speaker_count - 1
        assert resp['id'] == speaker_id
        assert response.content_type == 'application/json'

        # Trying to get the deleted speaker from the db should return None
        deleted_speaker = dbsession.query(Speaker).get(speaker_id)
        assert deleted_speaker is None
        assert response.content_type == 'application/json'

        # Delete with an invalid id
        id = 9999999999999
        response = self.app.delete(url('delete', id=id),
                                   headers=self.json_headers,
                                   extra_environ=self.extra_environ_admin,
                                   status=404)
        assert 'There is no speaker with id %s' % id in response.json_body[
            'error']
        assert response.content_type == 'application/json'

        # Delete without an id
        response = self.app.delete(url('delete', id=''),
                                   status=404,
                                   headers=self.json_headers,
                                   extra_environ=self.extra_environ_admin)
        assert response.json_body[
            'error'] == 'The resource could not be found.'
        assert response.content_type == 'application/json'
    def test_new(self):
        """Tests that GET /formsearches/new returns the data necessary to create a new form search."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)
        response = self.app.get(url('new'),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_contrib)
        resp = response.json_body
        assert 'attributes' in resp['search_parameters']
        assert 'relations' in resp['search_parameters']
        assert response.content_type == 'application/json'
    def test_new_search(self):
        """Tests that GET /languages/new_search returns the search parameters for searching the languages resource."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)
        query_builder = SQLAQueryBuilder(
            dbsession, model_name='Language', settings=self.settings)
        response = self.app.get(
            url('new_search'), headers=self.json_headers,
            extra_environ=self.extra_environ_view)
        resp = response.json_body
        assert resp['search_parameters'] == query_builder.get_search_parameters()
    def test_show(self):
        """Tests that GET /formsearches/id returns the formsearch with id=id or an appropriate error."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create a form search to show.
        query = {'filter': ['Form', 'transcription', 'regex', '[a-g]{3,}']}
        params = self.form_search_create_params.copy()
        params.update({
            'name': 'form search',
            'description': 'This one\'s worth saving!',
            'search': query
        })
        params = json.dumps(params)
        response = self.app.post(url('create'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = response.json_body
        form_search_id = resp['id']
        assert resp['name'] == 'form search'
        assert resp['description'] == "This one's worth saving!"
        assert resp['search'] == query

        # Try to get a form search using an invalid id
        id = 100000000000
        response = self.app.get(url('show', id=id),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin,
                                status=404)
        resp = response.json_body
        assert 'There is no form search with id %s' % id in response.json_body[
            'error']
        assert response.content_type == 'application/json'

        # No id
        response = self.app.get(url('show', id=''),
                                status=404,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        assert response.json_body[
            'error'] == 'The resource could not be found.'

        # Valid id
        response = self.app.get(url('show', id=form_search_id),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        resp = response.json_body
        assert resp['name'] == 'form search'
        assert resp['description'] == "This one's worth saving!"
        assert response.content_type == 'application/json'
    def test_new_search(self):
        """Tests that GET /collectionbackups/new_search returns the search parameters for searching the collection backups resource."""

        db = DBUtils(self.dbsession, self.settings)

        query_builder = SQLAQueryBuilder(self.dbsession,
                                         'CollectionBackup',
                                         settings=self.settings)
        response = self.app.get(url('new_search'),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = response.json_body
        assert resp[
            'search_parameters'] == query_builder.get_search_parameters()
Beispiel #16
0
    def test_show(self):
        """Tests that GET /orthographies/id returns the orthography with id=id or an appropriate error."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create an orthography to show.
        params = self.orthography_create_params.copy()
        params.update({'name': 'orthography', 'orthography': 'a, b, c'})
        params = json.dumps(params)
        response = self.app.post(url('create'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = response.json_body
        assert resp['name'] == 'orthography'
        assert resp['orthography'] == 'a, b, c'
        assert resp[
            'lowercase'] is False  # default value from model/orthography.py
        assert resp[
            'initial_glottal_stops'] is True  # default value from model/orthography.py
        orthography_id = resp['id']

        # Try to get an orthography using an invalid id
        id = 100000000000
        response = self.app.get(url('show', id=id),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin,
                                status=404)
        resp = response.json_body
        assert 'There is no orthography with id %s' % id in response.json_body[
            'error']
        assert response.content_type == 'application/json'

        # No id
        response = self.app.get(url('show', id=''),
                                status=404,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        assert response.json_body[
            'error'] == 'The resource could not be found.'
        assert response.content_type == 'application/json'

        # Valid id
        response = self.app.get(url('show', id=orthography_id),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        resp = response.json_body
        assert resp['name'] == 'orthography'
        assert resp['orthography'] == 'a, b, c'
        assert response.content_type == 'application/json'
    def test_new_search(self):
        """Tests that GET /formbackups/new_search returns the search parameters for searching the form backups resource."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)
        query_builder = SQLAQueryBuilder(dbsession,
                                         'FormBackup',
                                         settings=self.settings)
        response = self.app.get('/{}/formbackups/new_search'.format(
            self.old_name),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = response.json_body
        assert resp[
            'search_parameters'] == query_builder.get_search_parameters()
    def test_show(self):
        """Tests that GET /speakers/id returns the speaker with id=id or an appropriate error."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create a speaker to show.
        params = self.speaker_create_params.copy()
        params.update({
            'first_name': 'first_name',
            'last_name': 'last_name',
            'page_content': 'page_content',
            'dialect': 'dialect'
        })
        params = json.dumps(params)
        response = self.app.post(url('create'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = response.json_body
        speaker_id = resp['id']

        # Try to get a speaker using an invalid id
        id = 100000000000
        response = self.app.get(url('show', id=id),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin,
                                status=404)
        resp = response.json_body
        assert 'There is no speaker with id %s' % id in response.json_body[
            'error']
        assert response.content_type == 'application/json'

        # No id
        response = self.app.get(url('show', id=''),
                                status=404,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        assert response.json_body[
            'error'] == 'The resource could not be found.'
        assert response.content_type == 'application/json'

        # Valid id
        response = self.app.get(url('show', id=speaker_id),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        resp = response.json_body
        assert resp['first_name'] == 'first_name'
        assert resp['dialect'] == 'dialect'
        assert response.content_type == 'application/json'
    def test_create(self):
        """Tests that POST /speakers creates a new speaker
        or returns an appropriate error if the input is invalid.
        """

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        original_speaker_count = dbsession.query(Speaker).count()

        # Create a valid one
        params = self.speaker_create_params.copy()
        params.update({
            'first_name': 'John',
            'last_name': 'Doe',
            'page_content': 'page_content',
            'dialect': 'dialect'
        })
        params = json.dumps(params)
        response = self.app.post(url('create'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = response.json_body
        new_speaker_count = dbsession.query(Speaker).count()
        assert new_speaker_count == original_speaker_count + 1
        assert resp['first_name'] == 'John'
        assert resp['dialect'] == 'dialect'
        assert response.content_type == 'application/json'

        # Invalid because first_name is too long
        params = self.speaker_create_params.copy()
        params.update({
            'first_name': 'John' * 400,
            'last_name': 'Doe',
            'page_content': 'page_content',
            'dialect': 'dialect'
        })
        params = json.dumps(params)
        response = self.app.post(url('create'),
                                 params,
                                 self.json_headers,
                                 self.extra_environ_admin,
                                 status=400)
        resp = response.json_body
        assert resp['errors'][
            'first_name'] == 'Enter a value not more than 255 characters long'
        assert response.content_type == 'application/json'
    def test_create(self):
        """Tests that POST /syntacticcategories creates a new syntactic category
        or returns an appropriate error if the input is invalid.
        """

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        original_SC_count = dbsession.query(SyntacticCategory).count()

        # Create a valid one
        params = json.dumps({'name': 'sc', 'type': 'lexical', 'description': 'Described.'})
        response = self.app.post(url('create'), params, self.json_headers, self.extra_environ_admin)
        resp = response.json_body
        new_SC_count = dbsession.query(SyntacticCategory).count()
        assert new_SC_count == original_SC_count + 1
        assert resp['name'] == 'sc'
        assert resp['description'] == 'Described.'
        assert resp['type'] == 'lexical'
        assert response.content_type == 'application/json'

        # Invalid because name is not unique
        params = json.dumps({'name': 'sc', 'type': 'lexical', 'description': 'Described.'})
        response = self.app.post(url('create'), params, self.json_headers, self.extra_environ_admin, status=400)
        resp = response.json_body
        assert resp['errors']['name'] == 'The submitted value for SyntacticCategory.name is not unique.'
        assert response.content_type == 'application/json'

        # Invalid because name is empty
        params = json.dumps({'name': '', 'type': 'lexical', 'description': 'Described.'})
        response = self.app.post(url('create'), params, self.json_headers, self.extra_environ_admin, status=400)
        resp = response.json_body
        assert resp['errors']['name'] == 'Please enter a value'

        # Invalid because name is too long
        params = json.dumps({'name': 'name' * 400, 'type': 'lexical', 'description': 'Described.'})
        response = self.app.post(url('create'), params, self.json_headers, self.extra_environ_admin, status=400)
        resp = response.json_body
        assert resp['errors']['name'] == 'Enter a value not more than 255 characters long'

        # Invalid because type is not in oldc.SYNTACTIC_CATEGORY_TYPES
        params = json.dumps({'name': 'name' * 400, 'type': 'spatial', 'description': 'Described.'})
        response = self.app.post(url('create'), params, self.json_headers, self.extra_environ_admin, status=400)
        resp = response.json_body
        assert resp['errors']['type'] == "Value must be one of: lexical; phrasal; sentential (not 'spatial')"
        assert response.content_type == 'application/json'
    def test_edit(self):
        """Tests that GET /syntacticcategories/id/edit returns a JSON object of data necessary to edit the syntactic category with id=id.

        The JSON object is of the form {'syntactic_category': {...}, 'data': {...}} or
        {'error': '...'} (with a 404 status code) depending on whether the id is
        valid or invalid/unspecified, respectively.
        """

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create an syntactic category to edit.
        params = json.dumps({'name': 'name', 'type': 'lexical', 'description': 'description'})
        response = self.app.post(url('create'), params, self.json_headers,
                                    self.extra_environ_admin)
        resp = response.json_body
        syntactic_category_id = resp['id']

        # Not logged in: expect 401 Unauthorized
        response = self.app.get(url('edit', id=syntactic_category_id), status=401)
        resp = response.json_body
        assert resp['error'] == 'Authentication is required to access this resource.'
        assert response.content_type == 'application/json'

        # Invalid id
        id = 9876544
        response = self.app.get(url('edit', id=id),
            headers=self.json_headers, extra_environ=self.extra_environ_admin,
            status=404)
        assert 'There is no syntactic category with id %s' % id in response.json_body['error']
        assert response.content_type == 'application/json'

        # No id
        response = self.app.get(url('edit', id=''), status=404,
            headers=self.json_headers, extra_environ=self.extra_environ_admin)
        assert response.json_body['error'] == 'The resource could not be found.'
        assert response.content_type == 'application/json'

        # Valid id
        response = self.app.get(url('edit', id=syntactic_category_id),
            headers=self.json_headers, extra_environ=self.extra_environ_admin)
        resp = response.json_body
        assert resp['syntactic_category']['name'] == 'name'
        assert resp['data']['syntactic_category_types'] == list(oldc.SYNTACTIC_CATEGORY_TYPES)
        assert response.content_type == 'application/json'
    def test_delete(self):
        """Tests that DELETE /syntacticcategories/id deletes the syntactic_category with id=id."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create an syntactic category to delete.
        params = json.dumps({'name': 'name', 'type': 'lexical', 'description': 'description'})
        response = self.app.post(url('create'), params, self.json_headers,
                                    self.extra_environ_admin)
        resp = response.json_body
        syntactic_category_count = dbsession.query(SyntacticCategory).count()
        syntactic_category_id = resp['id']

        # Now delete the syntactic category
        response = self.app.delete(url('delete', id=syntactic_category_id), headers=self.json_headers,
            extra_environ=self.extra_environ_admin)
        resp = response.json_body
        new_syntactic_category_count = dbsession.query(SyntacticCategory).count()
        assert new_syntactic_category_count == syntactic_category_count - 1
        assert resp['id'] == syntactic_category_id
        assert response.content_type == 'application/json'

        # Trying to get the deleted syntactic category from the db should return None
        deleted_syntactic_category = dbsession.query(SyntacticCategory).get(syntactic_category_id)
        assert deleted_syntactic_category is None

        # Delete with an invalid id
        id = 9999999999999
        response = self.app.delete(url('delete', id=id),
            headers=self.json_headers, extra_environ=self.extra_environ_admin,
            status=404)
        assert 'There is no syntactic category with id %s' % id in response.json_body['error']
        assert response.content_type == 'application/json'

        # Delete without an id
        response = self.app.delete(url('delete', id=''), status=404,
            headers=self.json_headers, extra_environ=self.extra_environ_admin)
        assert response.json_body['error'] == 'The resource could not be found.'
        assert response.content_type == 'application/json'
    def test_delete(self):
        """Tests that DELETE /elicitationmethods/id deletes the elicitation_method with id=id."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create an elicitation method to delete.
        params = json.dumps({'name': 'name', 'description': 'description'})
        response = self.app.post(url('create'), params, self.json_headers,
                                    self.extra_environ_admin)
        resp = response.json_body
        elicitation_method_count = dbsession.query(ElicitationMethod).count()
        elicitation_method_id = resp['id']

        # Now delete the elicitation method
        response = self.app.delete(url('delete', id=elicitation_method_id), headers=self.json_headers,
            extra_environ=self.extra_environ_admin)
        resp = response.json_body
        new_elicitation_method_count = dbsession.query(ElicitationMethod).count()
        assert new_elicitation_method_count == elicitation_method_count - 1
        assert resp['id'] == elicitation_method_id
        assert response.content_type == 'application/json'

        # Trying to get the deleted elicitation method from the db should return None
        deleted_elicitation_method = dbsession.query(ElicitationMethod).get(elicitation_method_id)
        assert deleted_elicitation_method is None

        # Delete with an invalid id
        id = 9999999999999
        response = self.app.delete(url('delete', id=id),
            headers=self.json_headers, extra_environ=self.extra_environ_admin,
            status=404)
        assert 'There is no elicitation method with id %s' % id in response.json_body['error']
        assert response.content_type == 'application/json'

        # Delete without an id
        response = self.app.delete(url('delete', id=''), status=404,
            headers=self.json_headers, extra_environ=self.extra_environ_admin)
        assert response.json_body['error'] == 'The resource could not be found.'
    def test_update(self):
        """Tests that PUT /syntacticcategories/id updates the syntacticcategory with id=id."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create an syntactic category to update.
        params = json.dumps({'name': 'name', 'type': 'lexical', 'description': 'description'})
        response = self.app.post(url('create'), params, self.json_headers,
                                    self.extra_environ_admin)
        resp = response.json_body
        syntactic_category_count = dbsession.query(SyntacticCategory).count()
        syntactic_category_id = resp['id']
        original_datetime_modified = resp['datetime_modified']

        # Update the syntactic category
        sleep(1)    # sleep for a second to ensure that MySQL registers a different datetime_modified for the update
        params = json.dumps({'name': 'name', 'type': 'lexical', 'description': 'More content-ful description.'})
        response = self.app.put(url('update', id=syntactic_category_id), params, self.json_headers,
                                    self.extra_environ_admin)
        resp = response.json_body
        datetime_modified = resp['datetime_modified']
        new_syntactic_category_count = dbsession.query(SyntacticCategory).count()
        assert syntactic_category_count == new_syntactic_category_count
        assert datetime_modified != original_datetime_modified
        assert response.content_type == 'application/json'

        # Attempt an update with no new input and expect to fail
        sleep(1)    # sleep for a second to ensure that MySQL could register a different datetime_modified for the update
        response = self.app.put(url('update', id=syntactic_category_id), params, self.json_headers,
                                    self.extra_environ_admin, status=400)
        resp = response.json_body
        syntactic_category_count = new_syntactic_category_count
        new_syntactic_category_count = dbsession.query(SyntacticCategory).count()
        our_SC_datetime_modified = dbsession.query(SyntacticCategory).get(syntactic_category_id).datetime_modified
        assert our_SC_datetime_modified.isoformat() == datetime_modified
        assert syntactic_category_count == new_syntactic_category_count
        assert resp['error'] == 'The update request failed because the submitted data were not new.'
        assert response.content_type == 'application/json'
    def test_create(self):
        """Tests that POST /elicitationmethods creates a new elicitation method
        or returns an appropriate error if the input is invalid.
        """

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        original_EM_count = dbsession.query(ElicitationMethod).count()

        # Create a valid one
        params = json.dumps({'name': 'em', 'description': 'Described.'})
        response = self.app.post(url('create'), params, self.json_headers, self.extra_environ_admin)
        resp = response.json_body
        new_EM_count = dbsession.query(ElicitationMethod).count()
        assert new_EM_count == original_EM_count + 1
        assert resp['name'] == 'em'
        assert resp['description'] == 'Described.'
        assert response.content_type == 'application/json'

        # Invalid because name is not unique
        params = json.dumps({'name': 'em', 'description': 'Described.'})
        response = self.app.post(url('create'), params, self.json_headers, self.extra_environ_admin, status=400)
        resp = response.json_body
        assert resp['errors']['name'] == 'The submitted value for ElicitationMethod.name is not unique.'
        assert response.content_type == 'application/json'

        # Invalid because name is empty
        params = json.dumps({'name': '', 'description': 'Described.'})
        response = self.app.post(url('create'), params, self.json_headers, self.extra_environ_admin, status=400)
        resp = response.json_body
        assert resp['errors']['name'] == 'Please enter a value'

        # Invalid because name is too long
        params = json.dumps({'name': 'name' * 400, 'description': 'Described.'})
        response = self.app.post(url('create'), params, self.json_headers, self.extra_environ_admin, status=400)
        resp = response.json_body
        assert resp['errors']['name'] == 'Enter a value not more than 255 characters long'
    def test_update(self):
        """Tests that PUT /speakers/id updates the speaker with id=id."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create a speaker to update.
        params = self.speaker_create_params.copy()
        params.update({
            'first_name': 'first_name',
            'last_name': 'last_name',
            'page_content': 'page_content',
            'dialect': 'dialect'
        })
        params = json.dumps(params)
        response = self.app.post(url('create'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = response.json_body
        speaker_count = dbsession.query(Speaker).count()
        speaker_id = resp['id']
        original_datetime_modified = resp['datetime_modified']

        # Update the speaker
        sleep(
            1
        )  # sleep for a second to ensure that MySQL registers a different datetime_modified for the update
        params = self.speaker_create_params.copy()
        params.update({
            'first_name': 'first_name',
            'last_name': 'last_name',
            'page_content': 'page_content',
            'dialect': 'updated dialect.'
        })
        params = json.dumps(params)
        response = self.app.put(url('update', id=speaker_id), params,
                                self.json_headers, self.extra_environ_admin)
        resp = response.json_body
        datetime_modified = resp['datetime_modified']
        new_speaker_count = dbsession.query(Speaker).count()
        assert speaker_count == new_speaker_count
        assert datetime_modified != original_datetime_modified
        assert response.content_type == 'application/json'

        # Attempt an update with no new input and expect to fail
        sleep(
            1
        )  # sleep for a second to ensure that MySQL could register a different datetime_modified for the update
        response = self.app.put(url('update', id=speaker_id),
                                params,
                                self.json_headers,
                                self.extra_environ_admin,
                                status=400)
        resp = response.json_body
        speaker_count = new_speaker_count
        new_speaker_count = dbsession.query(Speaker).count()
        our_speaker_datetime_modified = dbsession.query(Speaker).get(
            speaker_id).datetime_modified
        assert our_speaker_datetime_modified.isoformat() == datetime_modified
        assert speaker_count == new_speaker_count
        assert resp[
            'error'] == 'The update request failed because the submitted data were not new.'
        assert response.content_type == 'application/json'
Beispiel #27
0
    def test_writetofile_content_specified(self):
        """Tests file writing/retrieval of a corpus whose forms are specified in the ``content`` attribute.

        """

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        tgrep2_installed = h.command_line_program_installed('tgrep2')

        # Get ids of all sentences.
        sentences = dbsession.query(old_models.Form).\
            filter(old_models.Form.syntactic_category.\
                has(old_models.SyntacticCategory.name=='S')).all()
        len_sentences = len(sentences)
        sentences = ','.join(map(str, map(lambda f: f.id, sentences)))

        # Get ids of all sentences with more than 5 words.
        long_sentences = dbsession.query(old_models.Form).\
            filter(and_(
                old_models.Form.syntactic_category.has(old_models.SyntacticCategory.name=='S'),
                old_models.Form.transcription.op('regexp')(u'^([^ ]+ ){5}[^ ]+'))).all()
        len_long_sentences = len(long_sentences)
        long_sentences = ','.join(map(str, map(lambda f: f.id,
                                               long_sentences)))

        content = ','.join(
            [sentences, long_sentences, long_sentences, long_sentences])
        anticipated_length = len_sentences + (3 * len_long_sentences)
        name = 'Corpus of sentences with 6+ word sentences repeated'
        description = 'Ordered by content field; duplicates of words with more than 6 words.'

        # Generate some valid corpus creation input parameters.
        params = self.corpus_create_params.copy()
        params.update({
            'name': name,
            'description': description,
            'content': content
        })
        params = json.dumps(params)

        # Create the corpus
        original_corpus_count = dbsession.query(Corpus).count()
        response = self.app.post(url('create'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = response.json_body
        corpus_id = resp['id']
        new_corpus_count = dbsession.query(Corpus).count()
        corpus = dbsession.query(Corpus).get(corpus_id)
        corpus_dir = os.path.join(self.corpora_path, 'corpus_%d' % corpus_id)
        corpus_dir_contents = os.listdir(corpus_dir)
        assert new_corpus_count == original_corpus_count + 1
        assert resp['name'] == name
        assert resp['description'] == description
        assert corpus_dir_contents == []
        assert response.content_type == 'application/json'
        assert resp['content'] == content
        # The ``forms`` attribute is a collection, no repeats, that's why the following is true:
        assert len(corpus.forms) == len_sentences

        # Write the corpus to file as a treebank
        sleep(1)
        params = json.dumps({u'format': 'treebank'})
        response = self.app.put('/%s/corpora/%d/writetofile' %
                                (self.old_name, corpus_id),
                                params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        resp2 = response.json_body
        corpus_dir_contents = os.listdir(corpus_dir)
        corpus_tbk_path = os.path.join(corpus_dir, 'corpus_%d.tbk' % corpus_id)
        corpus_tbk_gzipped_path = '%s.gz' % corpus_tbk_path
        corpus_tbk_gzipped_size = get_file_size(corpus_tbk_gzipped_path)
        corpus_tbk_file_length = h.get_file_length(corpus_tbk_path)
        corpus_tbk_t2c_path = os.path.join(corpus_dir,
                                           'corpus_%d.tbk.t2c' % corpus_id)
        corpus_file_id = resp2['files'][0]['id']
        assert resp['id'] == resp2['id']
        assert resp['name'] == resp2['name']
        assert resp2['datetime_modified'] > resp['datetime_modified']
        assert os.path.exists(corpus_tbk_path)
        if tgrep2_installed:
            assert os.path.exists(corpus_tbk_t2c_path)
        else:
            assert not os.path.exists(corpus_tbk_t2c_path)
        assert os.path.exists(corpus_tbk_gzipped_path)
        assert get_file_size(corpus_tbk_path) > corpus_tbk_gzipped_size
        assert anticipated_length == corpus_tbk_file_length

        # Retrieve the corpus file directly from the filesystem.
        with open(corpus_tbk_path, 'rb') as filei:
            corpus_file_object = filei
            corpus_file_content = corpus_file_object.read()

        # Attempt to retrieve the gzipped corpus file via request as a restricted
        # user and expect to fail.
        response = self.app.get('/%s/corpora/%d/servefile/%d' %
                                (self.old_name, corpus_id, corpus_file_id),
                                status=403,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_contrib)
        resp = response.json_body
        assert resp == UNAUTHORIZED_MSG

        # Retrieve the gzipped corpus file via request.
        response = self.app.get('/%s/corpora/%d/servefile/%d' %
                                (self.old_name, corpus_id, corpus_file_id),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        assert len(response.body) < len(corpus_file_content)
        unzipped_corpus_file_content = decompress_gzip_string(response.body)
        assert unzipped_corpus_file_content == corpus_file_content

        # Write the corpus to file as a list of transcriptions, one per line.
        sleep(1)
        params = json.dumps({u'format': 'transcriptions only'})
        response = self.app.put('/%s/corpora/%d/writetofile' %
                                (self.old_name, corpus_id),
                                params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        old_resp2 = resp2
        resp2 = response.json_body
        corpus_dir_contents = os.listdir(corpus_dir)
        corpus_TO_path = os.path.join(
            corpus_dir, 'corpus_%d_transcriptions.txt' % corpus_id)
        corpus_TO_gzipped_path = '%s.gz' % corpus_TO_path
        corpus_TO_gzipped_size = get_file_size(corpus_TO_gzipped_path)
        corpus_TO_file_length = h.get_file_length(corpus_TO_path)
        if tgrep2_installed:
            # Five files should be present: tbk, tbk.gz, tbk.t2c, txt and txt.gz
            assert len(corpus_dir_contents) == 5
        else:
            # Four files should be present: tbk, tbk.gz, txt and txt.gz
            assert len(corpus_dir_contents) == 4
        assert resp2['datetime_modified'] > old_resp2['datetime_modified']
        assert os.path.exists(corpus_TO_path)
        assert os.path.exists(corpus_TO_gzipped_path)
        assert get_file_size(corpus_TO_path) > corpus_TO_gzipped_size
        assert anticipated_length == corpus_TO_file_length

        # Finally delete the corpus and expect it, its file data and corpus file
        # objects to have been deleted.
        dbsession.expire(corpus)
        assert os.path.exists(corpus_TO_path)
        assert os.path.exists(corpus_TO_gzipped_path)
        assert os.path.exists(corpus_tbk_path)
        assert os.path.exists(corpus_tbk_gzipped_path)
        if tgrep2_installed:
            assert os.path.exists(corpus_tbk_t2c_path)
        else:
            assert not os.path.exists(corpus_tbk_t2c_path)
        corpus_file_ids = [cf['id'] for cf in resp2['files']]
        self.app.delete(url('delete', id=corpus_id),
                        headers=self.json_headers,
                        extra_environ=self.extra_environ_admin)
        assert dbsession.query(old_models.Corpus).get(corpus_id) is None
        for corpus_file_id in corpus_file_ids:
            assert dbsession.query(CorpusFile).get(corpus_file_id) is None
        assert not os.path.exists(corpus_TO_path)
        assert not os.path.exists(corpus_TO_gzipped_path)
        assert not os.path.exists(corpus_tbk_path)
        assert not os.path.exists(corpus_tbk_t2c_path)
        assert not os.path.exists(corpus_tbk_gzipped_path)
    def test_index(self):
        """Tests that GET /speakers returns an array of all speakers and that order_by and pagination parameters work correctly."""

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Add 100 speakers.
        def create_speaker_from_index(index):
            speaker = old_models.Speaker()
            speaker.first_name = 'John%d' % index
            speaker.last_name = 'Doe%d' % index
            speaker.dialect = 'dialect %d' % index
            speaker.page_content = 'page content %d' % index
            return speaker

        speakers = [create_speaker_from_index(i) for i in range(1, 101)]
        dbsession.add_all(speakers)
        dbsession.commit()
        speakers = db.get_speakers(True)
        speakers_count = len(speakers)

        # Test that GET /speakers gives us all of the speakers.
        response = self.app.get(url('index'),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = response.json_body
        assert len(resp) == speakers_count
        assert resp[0]['first_name'] == 'John1'
        assert resp[0]['id'] == speakers[0].id
        assert response.content_type == 'application/json'

        # Test the paginator GET params.
        paginator = {'items_per_page': 23, 'page': 3}
        response = self.app.get(url('index'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = response.json_body
        assert len(resp['items']) == 23
        assert resp['items'][0]['first_name'] == speakers[46].first_name

        # Test the order_by GET params.
        order_by_params = {
            'order_by_model': 'Speaker',
            'order_by_attribute': 'first_name',
            'order_by_direction': 'desc'
        }
        response = self.app.get(url('index'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = response.json_body
        result_set = sorted([s.first_name for s in speakers], reverse=True)
        assert result_set == [s['first_name'] for s in resp]

        # Test the order_by *with* paginator.
        params = {
            'order_by_model': 'Speaker',
            'order_by_attribute': 'first_name',
            'order_by_direction': 'desc',
            'items_per_page': 23,
            'page': 3
        }
        response = self.app.get(url('index'),
                                params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = response.json_body
        assert result_set[46] == resp['items'][0]['first_name']

        # Expect a 400 error when the order_by_direction param is invalid
        order_by_params = {
            'order_by_model': 'Speaker',
            'order_by_attribute': 'first_name',
            'order_by_direction': 'descending'
        }
        response = self.app.get(url('index'),
                                order_by_params,
                                status=400,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = response.json_body
        assert resp['errors'][
            'order_by_direction'] == "Value must be one of: asc; desc (not 'descending')"
        assert response.content_type == 'application/json'

        # Expect the default BY id ASCENDING ordering when the order_by_model/Attribute
        # param is invalid.
        order_by_params = {
            'order_by_model': 'Speakerist',
            'order_by_attribute': 'prenom',
            'order_by_direction': 'desc'
        }
        response = self.app.get(url('index'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = response.json_body
        assert resp[0]['id'] == speakers[0].id

        # Expect a 400 error when the paginator GET params are empty
        # or are integers less than 1
        paginator = {'items_per_page': 'a', 'page': ''}
        response = self.app.get(url('index'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view,
                                status=400)
        resp = response.json_body
        assert resp['errors'][
            'items_per_page'] == 'Please enter an integer value'
        assert resp['errors']['page'] == 'Please enter a value'
        assert response.content_type == 'application/json'

        paginator = {'items_per_page': 0, 'page': -1}
        response = self.app.get(url('index'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view,
                                status=400)
        resp = response.json_body
        assert resp['errors'][
            'items_per_page'] == 'Please enter a number that is 1 or greater'
        assert resp['errors'][
            'page'] == 'Please enter a number that is 1 or greater'
        assert response.content_type == 'application/json'
    def test_edit(self):
        """Tests that GET /speakers/id/edit returns a JSON object of data necessary to edit the speaker with id=id.

        The JSON object is of the form {'speaker': {...}, 'data': {...}} or
        {'error': '...'} (with a 404 status code) depending on whether the id is
        valid or invalid/unspecified, respectively.
        """

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create a speaker to edit.
        params = self.speaker_create_params.copy()
        params.update({
            'first_name': 'first_name',
            'last_name': 'last_name',
            'page_content': 'page_content',
            'dialect': 'dialect'
        })
        params = json.dumps(params)
        response = self.app.post(url('create'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = response.json_body
        speaker_id = resp['id']

        # Not logged in: expect 401 Unauthorized
        response = self.app.get(url('edit', id=speaker_id), status=401)
        resp = response.json_body
        assert resp[
            'error'] == 'Authentication is required to access this resource.'
        assert response.content_type == 'application/json'

        # Invalid id
        id = 9876544
        response = self.app.get(url('edit', id=id),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin,
                                status=404)
        assert 'There is no speaker with id %s' % id in response.json_body[
            'error']
        assert response.content_type == 'application/json'

        # No id
        response = self.app.get(url('edit', id=''),
                                status=404,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        assert response.json_body[
            'error'] == 'The resource could not be found.'
        assert response.content_type == 'application/json'

        # Valid id
        response = self.app.get(url('edit', id=speaker_id),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        resp = response.json_body
        assert resp['speaker']['first_name'] == 'first_name'
        assert resp['data'] == {
            'markup_languages': list(oldc.MARKUP_LANGUAGES)
        }
        assert response.content_type == 'application/json'
Beispiel #30
0
    def test_search(self):
        """Tests that corpora search works correctly.

        """

        dbsession = self.dbsession
        db = DBUtils(dbsession, self.settings)

        # Create a corpus defined by ``content`` that contains all sentences
        # with five or more words.

        # Get ids of all sentences with more than 5 words.
        long_sentences = dbsession.query(old_models.Form).\
            filter(and_(
                old_models.Form.syntactic_category.has(old_models.SyntacticCategory.name=='S'),
                old_models.Form.transcription.op('regexp')(u'^([^ ]+ ){5}[^ ]+'))).all()
        long_sentence = long_sentences[0]
        len_long_sentences = len(long_sentences)
        long_sentence_ids = [f.id for f in long_sentences]
        long_sentences = ','.join(map(str, long_sentence_ids))

        # Restrict one of the forms that will be in the corpus.
        restricted_tag = db.get_restricted_tag()
        long_sentence.tags.append(restricted_tag)
        dbsession.add(long_sentence)
        dbsession.commit()

        # Create the corpus
        name = 'Sentences with 6 or more words.'
        params = self.corpus_create_params.copy()
        params.update({'name': name, 'content': long_sentences})
        params = json.dumps(params)
        original_corpus_count = dbsession.query(Corpus).count()
        response = self.app.post(url('create'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = response.json_body
        corpus_id = resp['id']
        new_corpus_count = dbsession.query(Corpus).count()
        corpus = dbsession.query(Corpus).get(corpus_id)
        corpus_dir = os.path.join(self.corpora_path, 'corpus_%d' % corpus_id)
        corpus_dir_contents = os.listdir(corpus_dir)
        assert new_corpus_count == original_corpus_count + 1
        assert resp['name'] == name
        assert corpus_dir_contents == []
        assert response.content_type == 'application/json'
        assert resp['content'] == long_sentences
        # The ``forms`` attribute is a collection, no repeats, that's why the following is true:
        assert len(corpus.forms) == len_long_sentences

        # Search the corpus for forms beginning in vowels.
        query = json.dumps({
            "query": {
                "filter": ['Form', 'transcription', 'regex', '^[AEIOUaeiou]']
            },
            "paginator": {
                'page': 1,
                'items_per_page': 10
            }
        })
        response = self.app.post(
            '/%s/corpora/%d/search' % (self.old_name, corpus_id), query,
            self.json_headers, self.extra_environ_admin)
        resp = response.json_body
        matches = resp['items']
        assert not set([f['id'] for f in matches]) - set(long_sentence_ids)
        assert len(
            list(
                filter(
                    lambda f: f['transcription'][0].lower() not in
                    ['a', 'e', 'i', 'o', 'u'], matches))) == 0
        assert len(
            list(
                filter(lambda f: len(f['transcription'].split(' ')) < 6,
                       matches))) == 0

        # Vacuous search of the corpus returns everything.
        query = json.dumps(
            {"query": {
                "filter": ['Form', 'transcription', 'like', '%']
            }})
        response = self.app.post(
            '/%s/corpora/%d/search' % (self.old_name, corpus_id), query,
            self.json_headers, self.extra_environ_admin)
        resp = response.json_body
        assert set([f['id'] for f in resp]) == set(long_sentence_ids)

        # Vacuous search as the viewer returns everything that is not restricted.
        query = json.dumps(
            {"query": {
                "filter": ['Form', 'transcription', 'like', '%']
            }})
        response = self.app.post(
            '/%s/corpora/%d/search' % (self.old_name, corpus_id), query,
            self.json_headers, self.extra_environ_view)
        resp2 = response.json_body
        # Viewer will get 1 or 2 forms fewer (2 are restricted, 1 assuredly a long sentence.)
        assert len(resp) > len(resp2)

        # Failed search with an invalid corpus id
        query = json.dumps(
            {"query": {
                "filter": ['Form', 'transcription', 'like', '%']
            }})
        response = self.app.post('/%s/corpora/123456789/search' %
                                 self.old_name,
                                 query,
                                 self.json_headers,
                                 self.extra_environ_admin,
                                 status=404)
        resp = response.json_body
        assert resp['error'] == 'There is no corpus with id 123456789'

        # Failed search with an invalid query
        query = json.dumps(
            {"query": {
                "filter": ['Form', 'thingamafracasicle', 'like', '%']
            }})
        response = self.app.post('/%s/corpora/%d/search' %
                                 (self.old_name, corpus_id),
                                 query,
                                 self.json_headers,
                                 self.extra_environ_admin,
                                 status=400)
        resp = response.json_body
        assert resp['errors'][
            'Form.thingamafracasicle'] == 'There is no attribute thingamafracasicle of Form'

        # Request GET /corpora/new_search
        response = self.app.get(url('new_search'),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        resp = response.json_body
        query_builder = SQLAQueryBuilder(dbsession,
                                         'Form',
                                         settings=self.settings)
        assert resp == {
            'search_parameters': query_builder.get_search_parameters()
        }