Esempio n. 1
0
    def tearDown(self, **kwargs):
        clear_all_tables = kwargs.get('clear_all_tables', False)
        dirs_to_clear = kwargs.get('dirs_to_clear', [])
        del_global_app_set = kwargs.get('del_global_app_set', False)
        dirs_to_destroy = kwargs.get('dirs_to_destroy', [])

        if clear_all_tables:
            h.clear_all_tables(['language'])
        else:
            h.clear_all_models()
        administrator = h.generate_default_administrator()
        contributor = h.generate_default_contributor()
        viewer = h.generate_default_viewer()
        Session.add_all([administrator, contributor, viewer])
        Session.commit()

        for dir_path in dirs_to_clear:
            h.clear_directory_of_files(getattr(self, dir_path))

        for dir_name in dirs_to_destroy:
            {
                'user': lambda: h.destroy_all_directories('users', 'test.ini'),
                'corpus': lambda: h.destroy_all_directories('corpora', 'test.ini'),
                'phonology': lambda: h.destroy_all_directories('phonologies', 'test.ini'),
                'morphology': lambda: h.destroy_all_directories('morphologies', 'test.ini'),
                'morphological_parser': lambda: h.destroy_all_directories('morphological_parsers', 'test.ini'),
                'morpheme_language_model': lambda: h.destroy_all_directories('morpheme_language_models', 'test.ini')
            }.get(dir_name, lambda: None)()

        if del_global_app_set:
            # Perform a vacuous GET just to delete app_globals.application_settings
            # to clean up for subsequent tests.
            self.app.get(url('new_form'), extra_environ=self.extra_environ_admin_appset)
Esempio n. 2
0
    def test_new(self):
        """Tests that GET /applicationsettings/new returns an appropriate JSON object for creating a new application settings object.

        The properties of the JSON object are 'languages', 'users' and
        'orthographies' and their values are arrays/lists.
        """

        # Add some orthographies.
        orthography1 = h.generate_default_orthography1()
        orthography2 = h.generate_default_orthography2()
        Session.add_all([orthography1, orthography2])
        Session.commit()

        # Get the data currently in the db (see websetup.py for the test data).
        data = {
            'languages': h.get_languages(),
            'users': h.get_mini_dicts_getter('User')(),
            'orthographies': h.get_mini_dicts_getter('Orthography')()
        }

        # JSON.stringify and then re-Python-ify the data.  This is what the data
        # should look like in the response to a simulated GET request.
        data = json.loads(json.dumps(data, cls=h.JSONOLDEncoder))

        # GET /applicationsettings/new without params.  Expect a JSON array for
        # every store.
        response = self.app.get(url('new_applicationsetting'),
                                extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        assert response.content_type == 'application/json'
        assert resp['languages'] == data['languages']
        assert resp['users'] == data['users']
        assert resp['orthographies'] == data['orthographies']
        assert response.content_type == 'application/json'

        # GET /applicationsettings/new with params.  Param values are treated as
        # strings, not JSON.  If any params are specified, the default is to
        # return a JSON array corresponding to store for the param.  There are
        # three cases that will result in an empty JSON array being returned:
        # 1. the param is not specified
        # 2. the value of the specified param is an empty string
        # 3. the value of the specified param is an ISO 8601 UTC datetime
        #    string that matches the most recent datetime_modified value of the
        #    store in question.
        params = {
            # Value is empty string: 'languages' will not be in response.
            'languages': '',
            # Value is any string: 'users' will be in response.
            'users': 'anything can go here!',
            # Value is ISO 8601 UTC datetime string that does not match the most
            # recent Orthography.datetime_modified value: 'orthographies' *will*
            # be in the response.
            'orthographies': datetime.datetime.utcnow().isoformat(),
        }
        response = self.app.get(url('new_applicationsetting'), params,
                                extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        assert resp['languages'] == []
        assert resp['users'] == data['users']
        assert resp['orthographies'] == data['orthographies']
Esempio n. 3
0
    def test_delete(self):
        """Tests that DELETE /tags/id deletes the tag with id=id."""

        # Create a tag to delete.
        params = json.dumps({'name': u'name', 'description': u'description'})
        response = self.app.post(url('tags'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = json.loads(response.body)
        tag_count = Session.query(Tag).count()
        tag_id = resp['id']

        # Now delete the tag
        response = self.app.delete(url('tag', id=tag_id), headers=self.json_headers,
            extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        new_tag_count = Session.query(Tag).count()
        assert new_tag_count == tag_count - 1
        assert resp['id'] == tag_id
        assert response.content_type == 'application/json'

        # Trying to get the deleted tag from the db should return None
        deleted_tag = Session.query(Tag).get(tag_id)
        assert deleted_tag == None

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

        # Delete without an id
        response = self.app.delete(url('tag', id=''), status=404,
            headers=self.json_headers, extra_environ=self.extra_environ_admin)
        assert json.loads(response.body)['error'] == 'The resource could not be found.'
        assert response.content_type == 'application/json'

        # Create a form, tag it, delete the tag and show that the form no longer
        # has the tag.
        tag = model.Tag()
        tag.name = u'tag'
        form = model.Form()
        form.transcription = u'test'
        form.tags.append(tag)
        Session.add_all([form, tag])
        Session.commit()
        form_id = form.id
        tag_id = tag.id
        response = self.app.delete(url('tag', id=tag_id),
            headers=self.json_headers, extra_environ=self.extra_environ_admin)
        deleted_tag = Session.query(Tag).get(tag_id)
        form = Session.query(model.Form).get(form_id)
        assert response.content_type == 'application/json'
        assert deleted_tag == None
        assert form.tags == []
Esempio n. 4
0
 def test_zzz_cleanup(self):
     """Clean up after the tests."""
     # Destruction
     h.clear_all_tables()
     h.destroy_all_directories(directory_name='users', config_filename='test.ini')
     h.destroy_all_directories(directory_name='corpora', config_filename='test.ini')
     # Creation
     languages = h.get_language_objects('test.ini', self.config)
     administrator = h.generate_default_administrator()
     contributor = h.generate_default_contributor()
     viewer = h.generate_default_viewer()
     Session.add_all([administrator, contributor, viewer] + languages)
     Session.commit()
Esempio n. 5
0
 def persist(self):
     """Update the persistence layer with the value of ``self._store``.
     """
     if self.updated:
         persisted = [parse.transcription for parse in Session.query(Parse).\
             filter(Parse.parser_id==self.parser.id).\
             filter(Parse.transcription.in_(self._store.keys())).all()]
         unpersisted = [Parse(transcription=k, parse=v, parser=self.parser)
             for k, v in self._store.iteritems() if k not in persisted]
         Session.add_all(unpersisted)
         Session.commit()
         # log.warn('DB_CACHE: PERSISTED %s' % u', '.join([p.transcription for p in unpersisted]))
         self.updated = False
Esempio n. 6
0
 def test_zzz_cleanup(self):
     """Clean up after the tests."""
     # Destruction
     h.clear_all_tables()
     h.destroy_all_directories(directory_name='users',
                               config_filename='test.ini')
     h.destroy_all_directories(directory_name='corpora',
                               config_filename='test.ini')
     # Creation
     languages = h.get_language_objects('test.ini', self.config)
     administrator = h.generate_default_administrator()
     contributor = h.generate_default_contributor()
     viewer = h.generate_default_viewer()
     Session.add_all([administrator, contributor, viewer] + languages)
     Session.commit()
Esempio n. 7
0
    def test_e_cleanup(self):
        """Clean up the database after /rememberedforms tests."""

        h.clear_all_models()
        administrator = h.generate_default_administrator()
        contributor = h.generate_default_contributor()
        viewer = h.generate_default_viewer()
        Session.add_all([administrator, contributor, viewer])
        Session.commit()

        # Perform a vacuous GET just to delete app_globals.application_settings
        # to clean up for subsequent tests.
        extra_environ = {'test.authentication.role': u'administrator',
                         'test.application_settings': True}
        self.app.get(url('forms'), extra_environ=extra_environ)
Esempio n. 8
0
    def test_create(self):
        """Tests that POST /applicationsettings correctly creates a new application settings."""

        # Add some orthographies.
        orthography1 = h.generate_default_orthography1()
        orthography2 = h.generate_default_orthography2()
        Session.add_all([orthography1, orthography2])
        Session.commit()
        orthography2_id = orthography2.id
        orthography2_orthography = orthography2.orthography

        params = self.application_settings_create_params.copy()
        params.update({
            'object_language_name': u'test_create object language name',
            'object_language_id': u'tco',
            'metalanguage_name': u'test_create metalanguage name',
            'metalanguage_id': u'tcm',
            'orthographic_validation': u'Warning',
            'narrow_phonetic_validation': u'Error',
            'morpheme_break_is_orthographic': False,
            'morpheme_delimiters': u'-,+',
            'punctuation': u'!?.,;:-_',
            'grammaticalities': u'*,**,***,?,??,???,#,##,###',
            'unrestricted_users': [Session.query(User).filter(
                User.role==u'viewer').first().id],
            'storage_orthography': orthography2_id,
            'input_orthography': orthography2_id,
            'output_orthography': orthography2_id
        })
        params = json.dumps(params)

        response = self.app.post(url('applicationsettings'), params,
                                 self.json_headers, self.extra_environ_admin)
        resp = json.loads(response.body)
        assert resp['object_language_name'] == u'test_create object language name'
        assert resp['morpheme_break_is_orthographic'] is False
        assert resp['storage_orthography']['orthography'] == orthography2_orthography
        assert resp['unrestricted_users'][0]['first_name'] == u'Viewer'
        assert 'password' not in resp['unrestricted_users'][0]
        assert response.content_type == 'application/json'

        # Attempt the same above creation as a contributor and expect to fail.
        response = self.app.post(url('applicationsettings'), params,
            self.json_headers, self.extra_environ_contrib, status=403)
        resp = json.loads(response.body)
        assert response.content_type == 'application/json'
        assert resp['error'] == u'You are not authorized to access this resource.'
Esempio n. 9
0
    def test_e_cleanup(self):
        """Clean up the database after /rememberedforms tests."""

        h.clear_all_models()
        administrator = h.generate_default_administrator()
        contributor = h.generate_default_contributor()
        viewer = h.generate_default_viewer()
        Session.add_all([administrator, contributor, viewer])
        Session.commit()

        # Perform a vacuous GET just to delete app_globals.application_settings
        # to clean up for subsequent tests.
        extra_environ = {
            'test.authentication.role': u'administrator',
            'test.application_settings': True
        }
        self.app.get(url('forms'), extra_environ=extra_environ)
Esempio n. 10
0
    def test_a_initialize(self):
        """Initialize the database for /rememberedforms tests."""
        h.clear_all_models()
        administrator = h.generate_default_administrator()
        contributor = h.generate_default_contributor()
        viewer = h.generate_default_viewer()
        Session.add_all([administrator, contributor, viewer])
        Session.commit()

        _create_test_data(self.n)
        self._add_SEARCH_to_web_test_valid_methods()

        # Create an application settings where the contributor is unrestricted
        viewer, contributor, administrator = get_users()
        application_settings = h.generate_default_application_settings()
        application_settings.unrestricted_users = [contributor]
        Session.add(application_settings)
        Session.commit()
Esempio n. 11
0
    def test_a_initialize(self):
        """Initialize the database for /rememberedforms tests."""
        h.clear_all_models()
        administrator = h.generate_default_administrator()
        contributor = h.generate_default_contributor()
        viewer = h.generate_default_viewer()
        Session.add_all([administrator, contributor, viewer])
        Session.commit()

        _create_test_data(self.n)
        self._add_SEARCH_to_web_test_valid_methods()

        # Create an application settings where the contributor is unrestricted
        viewer, contributor, administrator = get_users()
        application_settings = h.generate_default_application_settings()
        application_settings.unrestricted_users = [contributor]
        Session.add(application_settings)
        Session.commit()
Esempio n. 12
0
    def tearDown(self, **kwargs):
        clear_all_tables = kwargs.get('clear_all_tables', False)
        dirs_to_clear = kwargs.get('dirs_to_clear', [])
        del_global_app_set = kwargs.get('del_global_app_set', False)
        dirs_to_destroy = kwargs.get('dirs_to_destroy', [])

        if clear_all_tables:
            h.clear_all_tables(['language'])
        else:
            h.clear_all_models()
        administrator = h.generate_default_administrator()
        contributor = h.generate_default_contributor()
        viewer = h.generate_default_viewer()
        Session.add_all([administrator, contributor, viewer])
        Session.commit()

        for dir_path in dirs_to_clear:
            h.clear_directory_of_files(getattr(self, dir_path))

        for dir_name in dirs_to_destroy:
            {
                'user':
                lambda: h.destroy_all_directories('users', 'test.ini'),
                'corpus':
                lambda: h.destroy_all_directories('corpora', 'test.ini'),
                'phonology':
                lambda: h.destroy_all_directories('phonologies', 'test.ini'),
                'morphology':
                lambda: h.destroy_all_directories('morphologies', 'test.ini'),
                'morphological_parser':
                lambda: h.destroy_all_directories('morphological_parsers',
                                                  'test.ini'),
                'morpheme_language_model':
                lambda: h.destroy_all_directories('morpheme_language_models',
                                                  'test.ini')
            }.get(dir_name, lambda: None)()

        if del_global_app_set:
            # Perform a vacuous GET just to delete app_globals.application_settings
            # to clean up for subsequent tests.
            self.app.get(url('new_form'),
                         extra_environ=self.extra_environ_admin_appset)
Esempio n. 13
0
 def persist(self):
     """Update the persistence layer with the value of ``self._store``.
     """
     if self.updated:
         persisted = [parse.transcription for parse in Session.query(Parse).\
             filter(Parse.parser_id==self.parser.id).\
             filter(Parse.transcription.in_(self._store.keys())).all()]
         unpersisted = [
             Parse(transcription=transcription,
                   parse=parse,
                   candidates=self.json_dumps_candidates(candidates),
                   parser=self.parser)
             for transcription, (parse,
                                 candidates) in self._store.iteritems()
             if transcription not in persisted
         ]
         Session.add_all(unpersisted)
         Session.commit()
         # log.warn('DB_CACHE: PERSISTED %s' % u', '.join([p.transcription for p in unpersisted]))
         self.updated = False
Esempio n. 14
0
def testCircularity():
    setUp()
    c = model.Collection()
    c.title = u'title'
    fo = model.Form()
    fo.transcription = u'transcription'
    fi = model.File()
    fi.filename = u'filename.wav'
    Session.add_all([c, fo, fi])
    Session.commit()
    fi.collections.append(c)
    fo.files.append(fi)
    c.forms.append(fo)
    Session.commit()
    c = fo = fi = None
    c = Session.query(model.Collection).first()
    print c.forms[0]
    print c.forms[0].files[0]
    print c.forms[0].files[0].collections[0]
    cleanUp()
Esempio n. 15
0
def testCircularity():
    setUp()
    c = model.Collection()
    c.title = u'title'
    fo = model.Form()
    fo.transcription = u'transcription'
    fi = model.File()
    fi.filename = u'filename.wav'
    Session.add_all([c, fo, fi])
    Session.commit()
    fi.collections.append(c)
    fo.files.append(fi)
    c.forms.append(fo)
    Session.commit()
    c = fo = fi = None
    c = Session.query(model.Collection).first()
    print c.forms[0]
    print c.forms[0].files[0]
    print c.forms[0].files[0].collections[0]
    cleanUp()
Esempio n. 16
0
def update_collections_that_reference_this_collection(collection, query_builder, **kwargs):
    """Update all collections that reference the input collection.
    
    :param collection: a collection model.
    :param query_builder: an :class:`SQLAQueryBuilder` instance.
    :param bool kwargs['contents_changed']: indicates whether the input
        collection's ``contents`` value has changed.
    :param bool kwargs['deleted']: indicates whether the input collection has
        just been deleted.
    :returns: ``None``

    Update the ``contents``, ``contents_unpacked``, ``html`` and/or ``form``
    attributes of every collection that references the input collection plus all
    of the collections that reference those collections, etc.  This function is
    called upon successful update and delete requests.

    If the contents of the ``collection`` have changed (i.e.,
    ``kwargs['contents_changed']==True``) , then retrieve all collections
    that reference ``collection`` and all collections that reference those
    referers, etc., and update their ``contents_unpacked``, ``html`` and
    ``forms`` attributes.

    If the ``collection`` has been deleted (i.e., ``kwargs['deleted']==True``),
    then recursively retrieve all collections referencing ``collection`` and
    update their ``contents``, ``contents_unpacked``, ``html`` and ``forms``
    attributes.

    If ``collection`` has just been tagged as restricted (i.e.,
    ``kwargs['restricted']==True``), then recursively restrict all collections
    that reference it.

    In all cases, update the ``datetime_modified`` value of every collection that
    recursively references ``collection``.

    """
    def update_contents_unpacked_etc(collection, **kwargs):
        deleted = kwargs.get('deleted', False)
        collection_id = kwargs.get('collection_id')
        if deleted:
            collection.contents = remove_references_to_this_collection(collection.contents, collection_id)
        collections_referenced = get_collections_referenced(collection.contents)
        collection.contents_unpacked = generate_contents_unpacked(
                                    collection.contents, collections_referenced)
        collection.html = h.get_HTML_from_contents(collection.contents_unpacked,
                                                  collection.markup_language)
        collection.forms = [Session.query(Form).get(int(id)) for id in
                    h.form_reference_pattern.findall(collection.contents_unpacked)]
    def update_modification_values(collection, now):
        collection.datetime_modified = now
        session['user'] = Session.merge(session['user'])
        collection.modifier = session['user']
    restricted = kwargs.get('restricted', False)
    contents_changed = kwargs.get('contents_changed', False)
    deleted = kwargs.get('deleted', False)
    if restricted or contents_changed or deleted:
        collections_referencing_this_collection = get_collections_referencing_this_collection(
            collection, query_builder)
        collections_referencing_this_collection_dicts = [c.get_full_dict() for c in
                                        collections_referencing_this_collection]
        now = h.now()
        if restricted:
            restricted_tag = h.get_restricted_tag()
            [c.tags.append(restricted_tag) for c in collections_referencing_this_collection]
        if contents_changed:
            [update_contents_unpacked_etc(c) for c in collections_referencing_this_collection]
        if deleted:
            [update_contents_unpacked_etc(c, collection_id=collection.id, deleted=True)
             for c in collections_referencing_this_collection]
        [update_modification_values(c, now) for c in collections_referencing_this_collection]
        [backup_collection(cd) for cd in collections_referencing_this_collection_dicts]
        Session.add_all(collections_referencing_this_collection)
        Session.commit()
Esempio n. 17
0
    def test_index(self):
        """Tests that GET /formsearches returns an array of all form searches and that order_by and pagination parameters work correctly."""

        # Add 100 form searches.
        def create_form_search_from_index(index):
            form_search = model.FormSearch()
            form_search.name = u'form_search%d' % index
            form_search.description = u'description %d' % index
            form_search.search = unicode(json.dumps(
                {'query': {'filter': ['Form', 'transcription', 'regex', '%d' % index]}}))
            return form_search
        form_searches = [create_form_search_from_index(i) for i in range(1, 101)]
        Session.add_all(form_searches)
        Session.commit()
        form_searches = h.get_form_searches(True)
        form_searches_count = len(form_searches)

        # Test that GET /formsearches gives us all of the form searches.
        response = self.app.get(url('formsearches'), headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp) == form_searches_count
        assert resp[0]['name'] == u'form_search1'
        assert resp[0]['id'] == form_searches[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('formsearches'), paginator, headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp['items']) == 23
        assert resp['items'][0]['name'] == form_searches[46].name

        # Test the order_by GET params.
        order_by_params = {'order_by_model': 'FormSearch', 'order_by_attribute': 'name',
                     'order_by_direction': 'desc'}
        response = self.app.get(url('formsearches'), order_by_params,
                        headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        result_set = sorted([t.name for t in form_searches], reverse=True)
        assert result_set == [t['name'] for t in resp]

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

        # Expect a 400 error when the order_by_direction param is invalid
        order_by_params = {'order_by_model': 'FormSearch', 'order_by_attribute': 'name',
                     'order_by_direction': 'descending'}
        response = self.app.get(url('formsearches'), order_by_params, status=400,
            headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp['errors']['order_by_direction'] == u"Value must be one of: asc; desc (not u'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': 'FormSearchist', 'order_by_attribute': 'nominal',
                     'order_by_direction': 'desc'}
        response = self.app.get(url('formsearches'), order_by_params,
            headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp[0]['id'] == form_searches[0].id

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

        paginator = {'items_per_page': 0, 'page': -1}
        response = self.app.get(url('formsearches'), paginator, headers=self.json_headers,
                                extra_environ=self.extra_environ_view, status=400)
        resp = json.loads(response.body)
        assert resp['errors']['items_per_page'] == u'Please enter a number that is 1 or greater'
        assert resp['errors']['page'] == u'Please enter a number that is 1 or greater'
Esempio n. 18
0
def setup_app(command, conf, vars):
    """Commands to setup onlinelinguisticdatabase."""

    config = load_environment(conf.global_conf, conf.local_conf)
    log.info('Environment loaded.')

    Base.metadata.create_all(bind=Session.bind)
    filename = os.path.split(conf.filename)[
        -1]  # e.g., production.ini, development.ini, test.ini, ...

    # Create the ``store`` directory and those for file, analysis and corpora
    # objects and their subdirectories.  See ``lib.utils.py`` for details.
    h.create_OLD_directories(config=config)

    # ISO-639-3 Language data for the languages table
    log.info("Retrieving ISO-639-3 languages data.")
    languages = h.get_language_objects(filename, config)

    # Get default users.
    log.info("Creating a default administrator, contributor and viewer.")
    administrator = h.generate_default_administrator(config_filename=filename)
    contributor = h.generate_default_contributor(config_filename=filename)
    viewer = h.generate_default_viewer(config_filename=filename)

    # If we are running tests, make sure the test db contains only language data.
    if filename == 'test.ini':
        # Permanently drop any existing tables
        Base.metadata.drop_all(bind=Session.bind, checkfirst=True)
        log.info("Existing tables dropped.")

        # Create the tables if they don't already exist
        Base.metadata.create_all(bind=Session.bind, checkfirst=True)
        log.info('Tables created.')

        Session.add_all(languages + [administrator, contributor, viewer])
        Session.commit()

    # Not a test: add a bunch of nice defaults.
    else:
        # Create the _requests_tests.py script
        requests_tests_path = os.path.join(config['pylons.paths']['root'],
                                           'tests', 'scripts',
                                           '_requests_tests.py')

        # This line is problematic in production apps because the
        # _requests_tests.py file is not included in the build. So, I'm
        # commenting it out by default.
        # copyfile(requests_tests_path, '_requests_tests.py')

        # Create the tables if they don't already exist
        Base.metadata.create_all(bind=Session.bind, checkfirst=True)
        log.info('Tables created.')

        # Get default home & help pages.
        log.info("Creating default home and help pages.")
        homepage = h.generate_default_home_page()
        helppage = h.generate_default_help_page()

        # Get default application settings.
        log.info("Generating default application settings.")
        application_settings = h.generate_default_application_settings()

        # Get default tags and categories
        log.info("Creating some useful tags and categories.")
        restricted_tag = h.generate_restricted_tag()
        foreign_word_tag = h.generate_foreign_word_tag()
        S = h.generate_s_syntactic_category()
        N = h.generate_n_syntactic_category()
        V = h.generate_v_syntactic_category()

        # Initialize the database
        log.info("Adding defaults.")
        data = [
            administrator, contributor, viewer, homepage, helppage,
            application_settings, restricted_tag, foreign_word_tag
        ]
        if config['add_language_data'] != '0':
            data += languages
        if config['empty_database'] == '0':
            Session.add_all(data)
            Session.commit()
        log.info("OLD successfully set up.")
Esempio n. 19
0
    def test_index(self):
        """Tests that GET & SEARCH /collectionbackups behave correctly.
        """

        # Add some test data to the database.
        application_settings = h.generate_default_application_settings()
        source = h.generate_default_source()
        restricted_tag = h.generate_restricted_tag()
        file1 = h.generate_default_file()
        file1.name = u'file1'
        file2 = h.generate_default_file()
        file2.name = u'file2'
        speaker = h.generate_default_speaker()
        Session.add_all([
            application_settings, source, restricted_tag, file1, file2, speaker
        ])
        Session.commit()
        speaker_id = speaker.id
        restricted_tag_id = restricted_tag.id
        tag_ids = [restricted_tag_id]
        file1_id = file1.id
        file2_id = file2.id
        file_ids = [file1_id, file2_id]

        # Create a restricted collection (via request) as the default contributor
        users = h.get_users()
        contributor_id = [u for u in users if u.role == u'contributor'][0].id
        administrator_id = [u for u in users
                            if u.role == u'administrator'][0].id

        # Define some extra_environs
        view = {
            'test.authentication.role': u'viewer',
            'test.application_settings': True
        }
        contrib = {
            'test.authentication.role': u'contributor',
            'test.application_settings': True
        }
        admin = {
            'test.authentication.role': u'administrator',
            'test.application_settings': True
        }

        params = self.collection_create_params.copy()
        params.update({
            'title': u'Created by the Contributor',
            'elicitor': contributor_id,
            'tags': [restricted_tag_id]
        })
        params = json.dumps(params)
        response = self.app.post(url('collections'), params, self.json_headers,
                                 contrib)
        collection_count = Session.query(model.Collection).count()
        resp = json.loads(response.body)
        collection_id = resp['id']
        assert response.content_type == 'application/json'
        assert collection_count == 1

        # Update our collection (via request) as the default administrator; this
        # will create one collection backup.
        params = self.collection_create_params.copy()
        params.update({
            'url': u'find/me/here',
            'title': u'Updated by the Administrator',
            'speaker': speaker_id,
            'tags': tag_ids + [
                None, u''
            ],  # None and u'' ('') will be ignored by collections.update_collection
            'enterer': administrator_id  # This should change nothing.
        })
        params = json.dumps(params)
        response = self.app.put(url('collection', id=collection_id), params,
                                self.json_headers, admin)
        resp = json.loads(response.body)
        collection_count = Session.query(model.Collection).count()
        assert response.content_type == 'application/json'
        assert collection_count == 1

        # Finally, update our collection (via request) as the default contributor.
        # Now we will have two collection backups.
        params = self.collection_create_params.copy()
        params.update({
            'title': u'Updated by the Contributor',
            'speaker': speaker_id,
            'tags': tag_ids,
            'files': file_ids
        })
        params = json.dumps(params)
        response = self.app.put(url('collection', id=collection_id), params,
                                self.json_headers, contrib)
        resp = json.loads(response.body)
        collection_count = Session.query(model.Collection).count()
        assert collection_count == 1

        # Now GET the collection backups as the restricted enterer of the original
        # collection and expect to get them all.
        response = self.app.get(url('collectionbackups'),
                                headers=self.json_headers,
                                extra_environ=contrib)
        resp = json.loads(response.body)
        assert len(resp) == 2
        assert response.content_type == 'application/json'

        # The admin should get them all too.
        response = self.app.get(url('collectionbackups'),
                                headers=self.json_headers,
                                extra_environ=admin)
        resp = json.loads(response.body)
        assert len(resp) == 2

        # The viewer should get none because they're all restricted.
        response = self.app.get(url('collectionbackups'),
                                headers=self.json_headers,
                                extra_environ=view)
        resp = json.loads(response.body)
        assert len(resp) == 0

        # Now update the collection and de-restrict it.
        params = self.collection_create_params.copy()
        params.update({
            'title': u'Updated and de-restricted by the Contributor',
            'speaker': speaker_id,
            'tags': [],
            'files': file_ids
        })
        params = json.dumps(params)
        response = self.app.put(url('collection', id=collection_id), params,
                                self.json_headers, contrib)
        resp = json.loads(response.body)
        collection_count = Session.query(model.Collection).count()
        assert collection_count == 1

        # Now GET the collection backups.  Admin and contrib should see 3 but the
        # viewer should still see none.
        response = self.app.get(url('collectionbackups'),
                                headers=self.json_headers,
                                extra_environ=contrib)
        resp = json.loads(response.body)
        assert len(resp) == 3
        response = self.app.get(url('collectionbackups'),
                                headers=self.json_headers,
                                extra_environ=admin)
        resp = json.loads(response.body)
        assert len(resp) == 3
        response = self.app.get(url('collectionbackups'),
                                headers=self.json_headers,
                                extra_environ=view)
        resp = json.loads(response.body)
        assert len(resp) == 0
        assert response.content_type == 'application/json'

        # Finally, update our collection in some trivial way.
        params = self.collection_create_params.copy()
        params.update({
            'title': u'Updated by the Contributor *again*',
            'speaker': speaker_id,
            'tags': [],
            'files': file_ids
        })
        params = json.dumps(params)
        response = self.app.put(url('collection', id=collection_id), params,
                                self.json_headers, contrib)
        resp = json.loads(response.body)
        collection_count = Session.query(model.Collection).count()
        assert collection_count == 1

        # Now GET the collection backups.  Admin and contrib should see 4 and the
        # viewer should see 1
        response = self.app.get(url('collectionbackups'),
                                headers=self.json_headers,
                                extra_environ=contrib)
        resp = json.loads(response.body)
        assert len(resp) == 4
        response = self.app.get(url('collectionbackups'),
                                headers=self.json_headers,
                                extra_environ=admin)
        resp = json.loads(response.body)
        all_collection_backups = resp
        assert len(resp) == 4
        response = self.app.get(url('collectionbackups'),
                                headers=self.json_headers,
                                extra_environ=view)
        resp = json.loads(response.body)
        unrestricted_collection_backup = resp[0]
        assert len(resp) == 1
        assert resp[0][
            'title'] == u'Updated and de-restricted by the Contributor'
        restricted_collection_backups = [
            cb for cb in all_collection_backups
            if cb != unrestricted_collection_backup
        ]
        assert len(restricted_collection_backups) == 3

        # Test the paginator GET params.
        paginator = {'items_per_page': 1, 'page': 2}
        response = self.app.get(url('collectionbackups'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=admin)
        resp = json.loads(response.body)
        assert len(resp['items']) == 1
        assert resp['items'][0]['title'] == all_collection_backups[1]['title']
        assert response.content_type == 'application/json'

        # Test the order_by GET params.
        order_by_params = {
            'order_by_model': 'CollectionBackup',
            'order_by_attribute': 'id',
            'order_by_direction': 'desc'
        }
        response = self.app.get(url('collectionbackups'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=admin)
        resp = json.loads(response.body)
        result_set = sorted(all_collection_backups,
                            key=lambda cb: cb['id'],
                            reverse=True)
        assert [cb['id'] for cb in resp] == [cb['id'] for cb in result_set]

        # Test the order_by *with* paginator.
        params = {
            'order_by_model': 'CollectionBackup',
            'order_by_attribute': 'id',
            'order_by_direction': 'desc',
            'items_per_page': 1,
            'page': 3
        }
        response = self.app.get(url('collectionbackups'),
                                params,
                                headers=self.json_headers,
                                extra_environ=admin)
        resp = json.loads(response.body)
        assert result_set[2]['title'] == resp['items'][0]['title']

        # Now test the show action:

        # Admin should be able to GET a particular restricted collection backup
        response = self.app.get(url('collectionbackup',
                                    id=restricted_collection_backups[0]['id']),
                                headers=self.json_headers,
                                extra_environ=admin)
        resp = json.loads(response.body)
        assert resp['title'] == restricted_collection_backups[0]['title']
        assert response.content_type == 'application/json'

        # Viewer should receive a 403 error when attempting to do so.
        response = self.app.get(url('collectionbackup',
                                    id=restricted_collection_backups[0]['id']),
                                headers=self.json_headers,
                                extra_environ=view,
                                status=403)
        resp = json.loads(response.body)
        assert resp[
            'error'] == u'You are not authorized to access this resource.'
        assert response.content_type == 'application/json'

        # Viewer should be able to GET the unrestricted collection backup
        response = self.app.get(url('collectionbackup',
                                    id=unrestricted_collection_backup['id']),
                                headers=self.json_headers,
                                extra_environ=view)
        resp = json.loads(response.body)
        assert resp['title'] == unrestricted_collection_backup['title']

        # A nonexistent cb id will return a 404 error
        response = self.app.get(url('collectionbackup', id=100987),
                                headers=self.json_headers,
                                extra_environ=view,
                                status=404)
        resp = json.loads(response.body)
        assert resp['error'] == u'There is no collection backup with id 100987'
        assert response.content_type == 'application/json'

        # Test the search action
        self._add_SEARCH_to_web_test_valid_methods()

        # A search on collection backup titles using POST /collectionbackups/search
        json_query = json.dumps({
            'query': {
                'filter':
                ['CollectionBackup', 'title', 'like', u'%Contributor%']
            }
        })
        response = self.app.post(url('/collectionbackups/search'), json_query,
                                 self.json_headers, admin)
        resp = json.loads(response.body)
        result_set = [
            cb for cb in all_collection_backups
            if u'Contributor' in cb['title']
        ]
        assert len(resp) == len(result_set) == 3
        assert set([cb['id']
                    for cb in resp]) == set([cb['id'] for cb in result_set])
        assert response.content_type == 'application/json'

        # A search on collection backup titles using SEARCH /collectionbackups
        json_query = json.dumps({
            'query': {
                'filter':
                ['CollectionBackup', 'title', 'like', u'%Administrator%']
            }
        })
        response = self.app.request(url('collectionbackups'),
                                    method='SEARCH',
                                    body=json_query,
                                    headers=self.json_headers,
                                    environ=admin)
        resp = json.loads(response.body)
        result_set = [
            cb for cb in all_collection_backups
            if u'Administrator' in cb['title']
        ]
        assert len(resp) == len(result_set) == 1
        assert set([cb['id']
                    for cb in resp]) == set([cb['id'] for cb in result_set])

        # Perform the two previous searches as a restricted viewer to show that
        # the restricted tag is working correctly.
        json_query = json.dumps({
            'query': {
                'filter':
                ['CollectionBackup', 'title', 'like', u'%Contributor%']
            }
        })
        response = self.app.post(url('/collectionbackups/search'), json_query,
                                 self.json_headers, view)
        resp = json.loads(response.body)
        result_set = [
            cb for cb in [unrestricted_collection_backup]
            if u'Contributor' in cb['title']
        ]
        assert len(resp) == len(result_set) == 1
        assert set([cb['id']
                    for cb in resp]) == set([cb['id'] for cb in result_set])

        json_query = json.dumps({
            'query': {
                'filter':
                ['CollectionBackup', 'title', 'like', u'%Administrator%']
            }
        })
        response = self.app.request(url('collectionbackups'),
                                    method='SEARCH',
                                    body=json_query,
                                    headers=self.json_headers,
                                    environ=view)
        resp = json.loads(response.body)
        result_set = [
            cb for cb in [unrestricted_collection_backup]
            if u'Administrator' in cb['title']
        ]
        assert len(resp) == len(result_set) == 0

        # I'm just going to assume that the order by and pagination functions are
        # working correctly since the implementation is essentially equivalent
        # to that in the index action already tested above.

        # Attempting to call edit/new/create/delete/update on a read-only resource
        # will return a 404 response
        response = self.app.get(url('edit_collectionbackup', id=2232),
                                status=404)
        assert json.loads(
            response.body)['error'] == u'This resource is read-only.'
        response = self.app.get(url('new_collectionbackup', id=2232),
                                status=404)
        assert json.loads(
            response.body)['error'] == u'This resource is read-only.'
        response = self.app.post(url('collectionbackups'), status=404)
        assert json.loads(
            response.body)['error'] == u'This resource is read-only.'
        response = self.app.put(url('collectionbackup', id=2232), status=404)
        assert json.loads(
            response.body)['error'] == u'This resource is read-only.'
        response = self.app.delete(url('collectionbackup', id=2232),
                                   status=404)
        assert json.loads(
            response.body)['error'] == u'This resource is read-only.'
        assert response.content_type == 'application/json'
Esempio n. 20
0
    def test_index(self):
        """Tests that GET /speakers returns an array of all speakers and that order_by and pagination parameters work correctly."""

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

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

        # Test that GET /speakers gives us all of the speakers.
        response = self.app.get(url('speakers'),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp) == speakers_count
        assert resp[0]['first_name'] == u'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('speakers'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.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('speakers'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.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('speakers'),
                                params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.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('speakers'),
                                order_by_params,
                                status=400,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp['errors'][
            'order_by_direction'] == u"Value must be one of: asc; desc (not u'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('speakers'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.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': u'a', 'page': u''}
        response = self.app.get(url('speakers'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view,
                                status=400)
        resp = json.loads(response.body)
        assert resp['errors'][
            'items_per_page'] == u'Please enter an integer value'
        assert resp['errors']['page'] == u'Please enter a value'
        assert response.content_type == 'application/json'

        paginator = {'items_per_page': 0, 'page': -1}
        response = self.app.get(url('speakers'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view,
                                status=400)
        resp = json.loads(response.body)
        assert resp['errors'][
            'items_per_page'] == u'Please enter a number that is 1 or greater'
        assert resp['errors'][
            'page'] == u'Please enter a number that is 1 or greater'
        assert response.content_type == 'application/json'
Esempio n. 21
0
    def test_index(self):
        """Tests that GET /pages returns an array of all pages and that order_by and pagination parameters work correctly."""

        # Add 100 pages.
        def create_page_from_index(index):
            page = model.Page()
            page.name = u'page%d' % index
            page.markup_language = u'Markdown'
            page.content = self.md_contents
            return page

        pages = [create_page_from_index(i) for i in range(1, 101)]
        Session.add_all(pages)
        Session.commit()
        pages = h.get_pages(True)
        pages_count = len(pages)

        # Test that GET /pages gives us all of the pages.
        response = self.app.get(url('pages'),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp) == pages_count
        assert resp[0]['name'] == u'page1'
        assert resp[0]['id'] == pages[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('pages'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp['items']) == 23
        assert resp['items'][0]['name'] == pages[46].name
        assert response.content_type == 'application/json'

        # Test the order_by GET params.
        order_by_params = {
            'order_by_model': 'Page',
            'order_by_attribute': 'name',
            'order_by_direction': 'desc'
        }
        response = self.app.get(url('pages'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        result_set = sorted([p.name for p in pages], reverse=True)
        assert result_set == [p['name'] for p in resp]

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

        # Expect a 400 error when the order_by_direction param is invalid
        order_by_params = {
            'order_by_model': 'Page',
            'order_by_attribute': 'name',
            'order_by_direction': 'descending'
        }
        response = self.app.get(url('pages'),
                                order_by_params,
                                status=400,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp['errors'][
            'order_by_direction'] == u"Value must be one of: asc; desc (not u'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': 'Pageist',
            'order_by_attribute': 'nominal',
            'order_by_direction': 'desc'
        }
        response = self.app.get(url('pages'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp[0]['id'] == pages[0].id

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

        paginator = {'items_per_page': 0, 'page': -1}
        response = self.app.get(url('pages'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view,
                                status=400)
        resp = json.loads(response.body)
        assert resp['errors'][
            'items_per_page'] == u'Please enter a number that is 1 or greater'
        assert resp['errors'][
            'page'] == u'Please enter a number that is 1 or greater'
        assert response.content_type == 'application/json'
Esempio n. 22
0
    def test_index(self):
        """Tests that GET /orthographies returns an array of all orthographies and that order_by and pagination parameters work correctly."""

        # Add 100 orthographies.
        def create_orthography_from_index(index):
            orthography = model.Orthography()
            orthography.name = u'orthography%d' % index
            orthography.orthography = u'a, b, c, %d' % index
            orthography.initial_glottal_stops = False
            orthography.lowercase = True
            return orthography
        orthographies = [create_orthography_from_index(i) for i in range(1, 101)]
        Session.add_all(orthographies)
        Session.commit()
        orthographies = h.get_orthographies(True)
        orthographies_count = len(orthographies)

        # Test that GET /orthographies gives us all of the orthographies.
        response = self.app.get(url('orthographies'), headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp) == orthographies_count
        assert resp[0]['name'] == u'orthography1'
        assert resp[0]['id'] == orthographies[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('orthographies'), paginator, headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp['items']) == 23
        assert resp['items'][0]['name'] == orthographies[46].name
        assert response.content_type == 'application/json'

        # Test the order_by GET params.
        order_by_params = {'order_by_model': 'Orthography', 'order_by_attribute': 'name',
                     'order_by_direction': 'desc'}
        response = self.app.get(url('orthographies'), order_by_params,
                        headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        result_set = sorted([o.name for o in orthographies], reverse=True)
        assert result_set == [o['name'] for o in resp]

        # Test the order_by *with* paginator.
        params = {'order_by_model': 'Orthography', 'order_by_attribute': 'name',
                     'order_by_direction': 'desc', 'items_per_page': 23, 'page': 3}
        response = self.app.get(url('orthographies'), params,
                        headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert result_set[46] == resp['items'][0]['name']
        assert response.content_type == 'application/json'

        # Expect a 400 error when the order_by_direction param is invalid
        order_by_params = {'order_by_model': 'Orthography', 'order_by_attribute': 'name',
                     'order_by_direction': 'descending'}
        response = self.app.get(url('orthographies'), order_by_params, status=400,
            headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp['errors']['order_by_direction'] == u"Value must be one of: asc; desc (not u'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': 'Orthographyist', 'order_by_attribute': 'nominal',
                     'order_by_direction': 'desc'}
        response = self.app.get(url('orthographies'), order_by_params,
            headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp[0]['id'] == orthographies[0].id

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

        paginator = {'items_per_page': 0, 'page': -1}
        response = self.app.get(url('orthographies'), paginator, headers=self.json_headers,
                                extra_environ=self.extra_environ_view, status=400)
        resp = json.loads(response.body)
        assert resp['errors']['items_per_page'] == u'Please enter a number that is 1 or greater'
        assert resp['errors']['page'] == u'Please enter a number that is 1 or greater'
        assert response.content_type == 'application/json'
Esempio n. 23
0
    def test_index(self):
        """Tests that GET & SEARCH /corpusbackups behave correctly.
        """

        tag = model.Tag()
        tag.name = u'random tag name'
        Session.add(tag)
        Session.commit()
        tag_id = tag.id

        # Add 10 forms and use them to generate a valid value for ``test_corpus_content``
        def create_form_from_index(index):
            form = model.Form()
            form.transcription = u'Form %d' % index
            translation = model.Translation()
            translation.transcription = u'Translation %d' % index
            form.translation = translation
            return form

        forms = [create_form_from_index(i) for i in range(1, 10)]
        Session.add_all(forms)
        Session.commit()
        forms = h.get_forms()
        half_forms = forms[:5]
        form_ids = [form.id for form in forms]
        half_form_ids = [form.id for form in half_forms]
        test_corpus_content = u','.join(map(str, form_ids))
        test_corpus_half_content = u','.join(map(str, half_form_ids))

        # Create a form search model
        query = {'filter': ['Form', 'transcription', 'regex', u'[a-zA-Z]{3,}']}
        params = json.dumps({
            'name': u'form search',
            'description': u'This one\'s worth saving!',
            'search': query
        })
        response = self.app.post(url('formsearches'), params,
                                 self.json_headers, self.extra_environ_admin)
        resp = json.loads(response.body)
        form_search_id = resp['id']

        # Generate some valid corpus creation input parameters.
        params = self.corpus_create_params.copy()
        params.update({
            'name': u'Corpus',
            'description': u'Covers a lot of the data.',
            'content': test_corpus_content
        })
        params = json.dumps(params)

        # Attempt to create a corpus as a viewer and expect to fail
        response = self.app.post(url('corpora'),
                                 params,
                                 self.json_headers,
                                 self.extra_environ_view,
                                 status=403)
        resp = json.loads(response.body)
        assert resp[
            'error'] == u'You are not authorized to access this resource.'
        assert response.content_type == 'application/json'

        # Successfully create a corpus as the admin
        assert os.listdir(self.corpora_path) == []
        original_corpus_count = Session.query(Corpus).count()
        response = self.app.post(url('corpora'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = json.loads(response.body)
        corpus_id = resp['id']
        new_corpus_count = Session.query(Corpus).count()
        corpus = Session.query(Corpus).get(corpus_id)
        corpus_form_ids = sorted([f.id for f in corpus.forms])
        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'] == u'Corpus'
        assert resp['description'] == u'Covers a lot of the data.'
        assert corpus_dir_contents == []
        assert response.content_type == 'application/json'
        assert resp['content'] == test_corpus_content
        assert corpus_form_ids == sorted(form_ids)

        # Update the corpus as the contributor -- now we should have one backup
        params = self.corpus_create_params.copy()
        params.update({
            'name': u'Corpus',
            'description': u'Covers a little less data.',
            'content': test_corpus_half_content
        })
        params = json.dumps(params)
        response = self.app.put(url('corpus', id=corpus_id), params,
                                self.json_headers, self.extra_environ_contrib)
        resp = json.loads(response.body)
        corpus_count = new_corpus_count
        new_corpus_count = Session.query(Corpus).count()
        corpus = Session.query(Corpus).get(corpus_id)
        corpus_form_ids = sorted([f.id for f in corpus.forms])
        assert new_corpus_count == corpus_count
        assert resp['name'] == u'Corpus'
        assert resp['description'] == u'Covers a little less data.'
        assert response.content_type == 'application/json'
        assert resp['content'] == test_corpus_half_content
        assert corpus_form_ids == sorted(half_form_ids)

        # Update the corpus again -- now we should have two backups
        sleep(1)
        params = self.corpus_create_params.copy()
        params.update({
            'name': u'Corpus',
            'description': u'Covers a little less data.',
            'content': test_corpus_half_content,
            'tags': [tag_id]
        })
        params = json.dumps(params)
        response = self.app.put(url('corpus', id=corpus_id), params,
                                self.json_headers, self.extra_environ_admin)
        resp = json.loads(response.body)
        corpus_count = new_corpus_count
        new_corpus_count = Session.query(Corpus).count()
        corpus = Session.query(Corpus).get(corpus_id)
        corpus_form_ids = sorted([f.id for f in corpus.forms])
        assert new_corpus_count == corpus_count
        assert resp['name'] == u'Corpus'
        assert resp['description'] == u'Covers a little less data.'
        assert response.content_type == 'application/json'
        assert resp['content'] == test_corpus_half_content
        assert corpus_form_ids == sorted(half_form_ids)

        all_corpus_backups = Session.query(CorpusBackup).order_by(
            CorpusBackup.id).all()
        all_corpus_backup_ids = [cb.id for cb in all_corpus_backups]
        all_corpus_backup_descriptions = [
            cb.description for cb in all_corpus_backups
        ]

        # Now request the corpus backups as either the contributor or the viewer and
        # expect to get them all.
        response = self.app.get(url('corpusbackups'),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_contrib)
        resp = json.loads(response.body)
        assert len(resp) == 2
        assert response.content_type == 'application/json'
        assert resp[0]['modifier']['role'] == u'administrator'
        assert resp[1]['modifier']['role'] == u'contributor'

        # The admin should get them all too.
        response = self.app.get(url('corpusbackups'),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp) == 2
        assert [cb['id'] for cb in resp] == all_corpus_backup_ids

        # Test the paginator GET params.
        paginator = {'items_per_page': 1, 'page': 2}
        response = self.app.get(url('corpusbackups'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        assert len(resp['items']) == 1
        assert resp['paginator']['count'] == 2
        assert response.content_type == 'application/json'
        assert resp['items'][0]['id'] == all_corpus_backup_ids[1]

        # Test the order_by GET params.
        order_by_params = {
            'order_by_model': 'CorpusBackup',
            'order_by_attribute': 'id',
            'order_by_direction': 'desc'
        }
        response = self.app.get(url('corpusbackups'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        result_set = list(reversed(all_corpus_backup_ids))
        assert [cb['id'] for cb in resp] == result_set

        # Test the order_by *with* paginator.
        params = {
            'order_by_model': 'CorpusBackup',
            'order_by_attribute': 'id',
            'order_by_direction': 'desc',
            'items_per_page': 1,
            'page': 1
        }
        response = self.app.get(url('corpusbackups'),
                                params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        assert result_set[0] == resp['items'][0]['id']

        # Now test the show action:

        # Get a specific corpus backup.
        response = self.app.get(url('corpusbackup',
                                    id=all_corpus_backup_ids[0]),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        assert resp['description'] == u'Covers a lot of the data.'
        assert resp['content'] == test_corpus_content
        assert response.content_type == 'application/json'

        # A nonexistent cb id will return a 404 error
        response = self.app.get(url('corpusbackup', id=100987),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view,
                                status=404)
        resp = json.loads(response.body)
        assert resp['error'] == u'There is no corpus backup with id 100987'
        assert response.content_type == 'application/json'

        # Test the search action
        self._add_SEARCH_to_web_test_valid_methods()

        # A search on corpus backup titles using POST /corpusbackups/search
        json_query = json.dumps({
            'query': {
                'filter': ['CorpusBackup', 'description', 'like', u'%less%']
            }
        })
        response = self.app.post(url('/corpusbackups/search'),
                                 json_query,
                                 self.json_headers,
                                 extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        result_set = [
            name for name in all_corpus_backup_descriptions if u'less' in name
        ]
        assert len(resp) == len(result_set) == 1
        assert resp[0]['description'] == result_set[0]
        assert response.content_type == 'application/json'

        # A search on corpus backup titles using SEARCH /corpusbackups
        json_query = json.dumps({
            'query': {
                'filter': ['CorpusBackup', 'description', 'like', u'%less%']
            }
        })
        response = self.app.request(url('corpusbackups'),
                                    method='SEARCH',
                                    body=json_query,
                                    headers=self.json_headers,
                                    environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        assert len(resp) == len(result_set) == 1
        assert resp[0]['description'] == result_set[0]
        assert response.content_type == 'application/json'

        # Attempting to call edit/new/create/delete/update on a read-only resource
        # will return a 404 response
        response = self.app.get(url('edit_corpusbackup', id=2232), status=404)
        assert json.loads(
            response.body)['error'] == u'This resource is read-only.'
        response = self.app.get(url('new_corpusbackup', id=2232), status=404)
        assert json.loads(
            response.body)['error'] == u'This resource is read-only.'
        response = self.app.post(url('corpusbackups'), status=404)
        assert json.loads(
            response.body)['error'] == u'This resource is read-only.'
        response = self.app.put(url('corpusbackup', id=2232), status=404)
        assert json.loads(
            response.body)['error'] == u'This resource is read-only.'
        response = self.app.delete(url('corpusbackup', id=2232), status=404)
        assert json.loads(
            response.body)['error'] == u'This resource is read-only.'
        assert response.content_type == 'application/json'
Esempio n. 24
0
    def test_index(self):
        """Tests that GET /syntacticcategories returns an array of all syntactic categories and that order_by and pagination parameters work correctly."""

        # Add 100 syntactic categories.
        def create_syntactic_category_from_index(index):
            syntactic_category = model.SyntacticCategory()
            syntactic_category.name = u'sc%d' % index
            syntactic_category.type = u'lexical'
            syntactic_category.description = u'description %d' % index
            return syntactic_category
        syntactic_categories = [create_syntactic_category_from_index(i) for i in range(1, 101)]
        Session.add_all(syntactic_categories)
        Session.commit()
        syntactic_categories = h.get_syntactic_categories(True)
        syntactic_categories_count = len(syntactic_categories)

        # Test that GET /syntacticcategories gives us all of the syntactic categories.
        response = self.app.get(url('syntacticcategories'), headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp) == syntactic_categories_count
        assert resp[0]['name'] == u'sc1'
        assert resp[0]['id'] == syntactic_categories[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('syntacticcategories'), paginator, headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp['items']) == 23
        assert resp['items'][0]['name'] == syntactic_categories[46].name
        assert response.content_type == 'application/json'

        # Test the order_by GET params.
        order_by_params = {'order_by_model': 'SyntacticCategory', 'order_by_attribute': 'name',
                     'order_by_direction': 'desc'}
        response = self.app.get(url('syntacticcategories'), order_by_params,
                        headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        result_set = sorted([sc.name for sc in syntactic_categories], reverse=True)
        assert result_set == [sc['name'] for sc in resp]

        # Test the order_by *with* paginator.
        params = {'order_by_model': 'SyntacticCategory', 'order_by_attribute': 'name',
                     'order_by_direction': 'desc', 'items_per_page': 23, 'page': 3}
        response = self.app.get(url('syntacticcategories'), params,
                        headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert result_set[46] == resp['items'][0]['name']
        assert response.content_type == 'application/json'

        # Expect a 400 error when the order_by_direction param is invalid
        order_by_params = {'order_by_model': 'SyntacticCategory', 'order_by_attribute': 'name',
                     'order_by_direction': 'descending'}
        response = self.app.get(url('syntacticcategories'), order_by_params, status=400,
            headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp['errors']['order_by_direction'] == u"Value must be one of: asc; desc (not u'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': 'SyntacticCategoryist', 'order_by_attribute': 'nominal',
                     'order_by_direction': 'desc'}
        response = self.app.get(url('syntacticcategories'), order_by_params,
            headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp[0]['id'] == syntactic_categories[0].id
        assert response.content_type == 'application/json'

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

        paginator = {'items_per_page': 0, 'page': -1}
        response = self.app.get(url('syntacticcategories'), paginator, headers=self.json_headers,
                                extra_environ=self.extra_environ_view, status=400)
        resp = json.loads(response.body)
        assert resp['errors']['items_per_page'] == u'Please enter a number that is 1 or greater'
        assert resp['errors']['page'] == u'Please enter a number that is 1 or greater'
        assert response.content_type == 'application/json'
Esempio n. 25
0
    def test_index(self):
        """Tests that GET & SEARCH /collectionbackups behave correctly.
        """

        # Add some test data to the database.
        application_settings = h.generate_default_application_settings()
        source = h.generate_default_source()
        restricted_tag = h.generate_restricted_tag()
        file1 = h.generate_default_file()
        file1.name = u'file1'
        file2 = h.generate_default_file()
        file2.name = u'file2'
        speaker = h.generate_default_speaker()
        Session.add_all([application_settings, source, restricted_tag, file1,
                         file2, speaker])
        Session.commit()
        speaker_id = speaker.id
        restricted_tag_id = restricted_tag.id
        tag_ids = [restricted_tag_id]
        file1_id = file1.id
        file2_id = file2.id
        file_ids = [file1_id, file2_id]

        # Create a restricted collection (via request) as the default contributor
        users = h.get_users()
        contributor_id = [u for u in users if u.role==u'contributor'][0].id
        administrator_id = [u for u in users if u.role==u'administrator'][0].id

        # Define some extra_environs
        view = {'test.authentication.role': u'viewer', 'test.application_settings': True}
        contrib = {'test.authentication.role': u'contributor', 'test.application_settings': True}
        admin = {'test.authentication.role': u'administrator', 'test.application_settings': True}

        params = self.collection_create_params.copy()
        params.update({
            'title': u'Created by the Contributor',
            'elicitor': contributor_id,
            'tags': [restricted_tag_id]
        })
        params = json.dumps(params)
        response = self.app.post(url('collections'), params, self.json_headers, contrib)
        collection_count = Session.query(model.Collection).count()
        resp = json.loads(response.body)
        collection_id = resp['id']
        assert response.content_type == 'application/json'
        assert collection_count == 1

        # Update our collection (via request) as the default administrator; this
        # will create one collection backup.
        params = self.collection_create_params.copy()
        params.update({
            'url': u'find/me/here',
            'title': u'Updated by the Administrator',
            'speaker': speaker_id,
            'tags': tag_ids + [None, u''], # None and u'' ('') will be ignored by collections.update_collection
            'enterer': administrator_id  # This should change nothing.
        })
        params = json.dumps(params)
        response = self.app.put(url('collection', id=collection_id), params,
                        self.json_headers, admin)
        resp = json.loads(response.body)
        collection_count = Session.query(model.Collection).count()
        assert response.content_type == 'application/json'
        assert collection_count == 1

        # Finally, update our collection (via request) as the default contributor.
        # Now we will have two collection backups.
        params = self.collection_create_params.copy()
        params.update({
            'title': u'Updated by the Contributor',
            'speaker': speaker_id,
            'tags': tag_ids,
            'files': file_ids
        })
        params = json.dumps(params)
        response = self.app.put(url('collection', id=collection_id), params,
                        self.json_headers, contrib)
        resp = json.loads(response.body)
        collection_count = Session.query(model.Collection).count()
        assert collection_count == 1

        # Now GET the collection backups as the restricted enterer of the original
        # collection and expect to get them all.
        response = self.app.get(url('collectionbackups'), headers=self.json_headers, extra_environ=contrib)
        resp = json.loads(response.body)
        assert len(resp) == 2
        assert response.content_type == 'application/json'

        # The admin should get them all too.
        response = self.app.get(url('collectionbackups'), headers=self.json_headers, extra_environ=admin)
        resp = json.loads(response.body)
        assert len(resp) == 2

        # The viewer should get none because they're all restricted.
        response = self.app.get(url('collectionbackups'), headers=self.json_headers, extra_environ=view)
        resp = json.loads(response.body)
        assert len(resp) == 0

        # Now update the collection and de-restrict it.
        params = self.collection_create_params.copy()
        params.update({
            'title': u'Updated and de-restricted by the Contributor',
            'speaker': speaker_id,
            'tags': [],
            'files': file_ids
        })
        params = json.dumps(params)
        response = self.app.put(url('collection', id=collection_id), params,
                        self.json_headers, contrib)
        resp = json.loads(response.body)
        collection_count = Session.query(model.Collection).count()
        assert collection_count == 1

        # Now GET the collection backups.  Admin and contrib should see 3 but the
        # viewer should still see none.
        response = self.app.get(url('collectionbackups'), headers=self.json_headers, extra_environ=contrib)
        resp = json.loads(response.body)
        assert len(resp) == 3
        response = self.app.get(url('collectionbackups'), headers=self.json_headers, extra_environ=admin)
        resp = json.loads(response.body)
        assert len(resp) == 3
        response = self.app.get(url('collectionbackups'), headers=self.json_headers, extra_environ=view)
        resp = json.loads(response.body)
        assert len(resp) == 0
        assert response.content_type == 'application/json'

        # Finally, update our collection in some trivial way.
        params = self.collection_create_params.copy()
        params.update({
            'title': u'Updated by the Contributor *again*',
            'speaker': speaker_id,
            'tags': [],
            'files': file_ids
        })
        params = json.dumps(params)
        response = self.app.put(url('collection', id=collection_id), params,
                        self.json_headers, contrib)
        resp = json.loads(response.body)
        collection_count = Session.query(model.Collection).count()
        assert collection_count == 1

        # Now GET the collection backups.  Admin and contrib should see 4 and the
        # viewer should see 1
        response = self.app.get(url('collectionbackups'), headers=self.json_headers, extra_environ=contrib)
        resp = json.loads(response.body)
        assert len(resp) == 4
        response = self.app.get(url('collectionbackups'), headers=self.json_headers, extra_environ=admin)
        resp = json.loads(response.body)
        all_collection_backups = resp
        assert len(resp) == 4
        response = self.app.get(url('collectionbackups'), headers=self.json_headers, extra_environ=view)
        resp = json.loads(response.body)
        unrestricted_collection_backup = resp[0]
        assert len(resp) == 1
        assert resp[0]['title'] == u'Updated and de-restricted by the Contributor'
        restricted_collection_backups = [cb for cb in all_collection_backups
                                       if cb != unrestricted_collection_backup]
        assert len(restricted_collection_backups) == 3

        # Test the paginator GET params.
        paginator = {'items_per_page': 1, 'page': 2}
        response = self.app.get(url('collectionbackups'), paginator, headers=self.json_headers,
                                extra_environ=admin)
        resp = json.loads(response.body)
        assert len(resp['items']) == 1
        assert resp['items'][0]['title'] == all_collection_backups[1]['title']
        assert response.content_type == 'application/json'

        # Test the order_by GET params.
        order_by_params = {'order_by_model': 'CollectionBackup',
            'order_by_attribute': 'id', 'order_by_direction': 'desc'}
        response = self.app.get(url('collectionbackups'), order_by_params,
                        headers=self.json_headers, extra_environ=admin)
        resp = json.loads(response.body)
        result_set = sorted(all_collection_backups, key=lambda cb: cb['id'], reverse=True)
        assert [cb['id'] for cb in resp] == [cb['id'] for cb in result_set] 

        # Test the order_by *with* paginator.  
        params = {'order_by_model': 'CollectionBackup', 'order_by_attribute': 'id',
                     'order_by_direction': 'desc', 'items_per_page': 1, 'page': 3}
        response = self.app.get(url('collectionbackups'), params,
                        headers=self.json_headers, extra_environ=admin)
        resp = json.loads(response.body)
        assert result_set[2]['title'] == resp['items'][0]['title']

        # Now test the show action:

        # Admin should be able to GET a particular restricted collection backup
        response = self.app.get(url('collectionbackup', id=restricted_collection_backups[0]['id']),
                                headers=self.json_headers, extra_environ=admin)
        resp = json.loads(response.body)
        assert resp['title'] == restricted_collection_backups[0]['title']
        assert response.content_type == 'application/json'

        # Viewer should receive a 403 error when attempting to do so.
        response = self.app.get(url('collectionbackup', id=restricted_collection_backups[0]['id']),
                                headers=self.json_headers, extra_environ=view, status=403)
        resp = json.loads(response.body)
        assert resp['error'] == u'You are not authorized to access this resource.'
        assert response.content_type == 'application/json'

        # Viewer should be able to GET the unrestricted collection backup
        response = self.app.get(url('collectionbackup', id=unrestricted_collection_backup['id']),
                                headers=self.json_headers, extra_environ=view)
        resp = json.loads(response.body)
        assert resp['title'] == unrestricted_collection_backup['title']

        # A nonexistent cb id will return a 404 error
        response = self.app.get(url('collectionbackup', id=100987),
                    headers=self.json_headers, extra_environ=view, status=404)
        resp = json.loads(response.body)
        assert resp['error'] == u'There is no collection backup with id 100987'
        assert response.content_type == 'application/json'

        # Test the search action
        self._add_SEARCH_to_web_test_valid_methods()

        # A search on collection backup titles using POST /collectionbackups/search
        json_query = json.dumps({'query': {'filter':
                        ['CollectionBackup', 'title', 'like', u'%Contributor%']}})
        response = self.app.post(url('/collectionbackups/search'), json_query,
                        self.json_headers, admin)
        resp = json.loads(response.body)
        result_set = [cb for cb in all_collection_backups if u'Contributor' in cb['title']]
        assert len(resp) == len(result_set) == 3
        assert set([cb['id'] for cb in resp]) == set([cb['id'] for cb in result_set])
        assert response.content_type == 'application/json'

        # A search on collection backup titles using SEARCH /collectionbackups
        json_query = json.dumps({'query': {'filter':
                        ['CollectionBackup', 'title', 'like', u'%Administrator%']}})
        response = self.app.request(url('collectionbackups'), method='SEARCH', body=json_query,
            headers=self.json_headers, environ=admin)
        resp = json.loads(response.body)
        result_set = [cb for cb in all_collection_backups if u'Administrator' in cb['title']]
        assert len(resp) == len(result_set) == 1
        assert set([cb['id'] for cb in resp]) == set([cb['id'] for cb in result_set])

        # Perform the two previous searches as a restricted viewer to show that
        # the restricted tag is working correctly.
        json_query = json.dumps({'query': {'filter':
                        ['CollectionBackup', 'title', 'like', u'%Contributor%']}})
        response = self.app.post(url('/collectionbackups/search'), json_query,
                        self.json_headers, view)
        resp = json.loads(response.body)
        result_set = [cb for cb in [unrestricted_collection_backup]
                     if u'Contributor' in cb['title']]
        assert len(resp) == len(result_set) == 1
        assert set([cb['id'] for cb in resp]) == set([cb['id'] for cb in result_set])

        json_query = json.dumps({'query': {'filter':
                        ['CollectionBackup', 'title', 'like', u'%Administrator%']}})
        response = self.app.request(url('collectionbackups'), method='SEARCH', body=json_query,
            headers=self.json_headers, environ=view)
        resp = json.loads(response.body)
        result_set = [cb for cb in [unrestricted_collection_backup]
                     if u'Administrator' in cb['title']]
        assert len(resp) == len(result_set) == 0

        # I'm just going to assume that the order by and pagination functions are
        # working correctly since the implementation is essentially equivalent
        # to that in the index action already tested above.

        # Attempting to call edit/new/create/delete/update on a read-only resource
        # will return a 404 response
        response = self.app.get(url('edit_collectionbackup', id=2232), status=404)
        assert json.loads(response.body)['error'] == u'This resource is read-only.'
        response = self.app.get(url('new_collectionbackup', id=2232), status=404)
        assert json.loads(response.body)['error'] == u'This resource is read-only.'
        response = self.app.post(url('collectionbackups'), status=404)
        assert json.loads(response.body)['error'] == u'This resource is read-only.'
        response = self.app.put(url('collectionbackup', id=2232), status=404)
        assert json.loads(response.body)['error'] == u'This resource is read-only.'
        response = self.app.delete(url('collectionbackup', id=2232), status=404)
        assert json.loads(response.body)['error'] == u'This resource is read-only.'
        assert response.content_type == 'application/json'
Esempio n. 26
0
def setup_app(command, conf, vars):
    """Commands to setup onlinelinguisticdatabase."""

    config = load_environment(conf.global_conf, conf.local_conf)
    log.info('Environment loaded.')

    Base.metadata.create_all(bind=Session.bind)
    filename = os.path.split(conf.filename)[-1] # e.g., production.ini, development.ini, test.ini, ...

    # Create the ``store`` directory and those for file, analysis and corpora
    # objects and their subdirectories.  See ``lib.utils.py`` for details.
    h.create_OLD_directories(config=config)

    # ISO-639-3 Language data for the languages table
    log.info("Retrieving ISO-639-3 languages data.")
    languages = h.get_language_objects(filename, config)

    # Get default users.
    log.info("Creating a default administrator, contributor and viewer.")
    administrator = h.generate_default_administrator(config_filename=filename)
    contributor = h.generate_default_contributor(config_filename=filename)
    viewer = h.generate_default_viewer(config_filename=filename)

    # If we are running tests, make sure the test db contains only language data.
    if filename == 'test.ini':
        # Permanently drop any existing tables
        Base.metadata.drop_all(bind=Session.bind, checkfirst=True)
        log.info("Existing tables dropped.")

        # Create the tables if they don't already exist
        Base.metadata.create_all(bind=Session.bind, checkfirst=True)
        log.info('Tables created.')

        Session.add_all(languages + [administrator, contributor, viewer])
        Session.commit()

    # Not a test: add a bunch of nice defaults.
    else:
        # Create the _requests_tests.py script
        requests_tests_path = os.path.join(config['pylons.paths']['root'], 'tests',
                                         'scripts', '_requests_tests.py')

        # This line is problematic in production apps because the
        # _requests_tests.py file is not included in the build. So, I'm
        # commenting it out by default.
        # copyfile(requests_tests_path, '_requests_tests.py')

        # Create the tables if they don't already exist
        Base.metadata.create_all(bind=Session.bind, checkfirst=True)
        log.info('Tables created.')

        # Get default home & help pages.
        log.info("Creating default home and help pages.")
        homepage = h.generate_default_home_page()
        helppage = h.generate_default_help_page()
    
        # Get default application settings.
        log.info("Generating default application settings.")
        application_settings = h.generate_default_application_settings()
    
        # Get default tags and categories
        log.info("Creating some useful tags and categories.")
        restricted_tag = h.generate_restricted_tag()
        foreign_word_tag = h.generate_foreign_word_tag()
        S = h.generate_s_syntactic_category()
        N = h.generate_n_syntactic_category()
        V = h.generate_v_syntactic_category()
    
        # Initialize the database
        log.info("Adding defaults.")
        data = [administrator, contributor, viewer, homepage, helppage,
                application_settings, restricted_tag, foreign_word_tag]
        if config['add_language_data'] != '0':
            data += languages
        if config['empty_database'] == '0':
            Session.add_all(data)
            Session.commit()
        log.info("OLD successfully set up.")
Esempio n. 27
0
    def test_index(self):
        """Tests that GET /elicitationmethods returns an array of all elicitation methods and that order_by and pagination parameters work correctly."""

        # Add 100 elicitation methods.
        def create_elicitation_method_from_index(index):
            elicitation_method = model.ElicitationMethod()
            elicitation_method.name = u'em%d' % index
            elicitation_method.description = u'description %d' % index
            return elicitation_method
        elicitation_methods = [create_elicitation_method_from_index(i) for i in range(1, 101)]
        Session.add_all(elicitation_methods)
        Session.commit()
        elicitation_methods = h.get_elicitation_methods(True)
        elicitation_methods_count = len(elicitation_methods)

        # Test that GET /elicitationmethods gives us all of the elicitation methods.
        response = self.app.get(url('elicitationmethods'), headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp) == elicitation_methods_count
        assert resp[0]['name'] == u'em1'
        assert resp[0]['id'] == elicitation_methods[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('elicitationmethods'), paginator, headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp['items']) == 23
        assert resp['items'][0]['name'] == elicitation_methods[46].name

        # Test the order_by GET params.
        order_by_params = {'order_by_model': 'ElicitationMethod', 'order_by_attribute': 'name',
                     'order_by_direction': 'desc'}
        response = self.app.get(url('elicitationmethods'), order_by_params,
                        headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        result_set = sorted([em.name for em in elicitation_methods], reverse=True)
        assert result_set == [em['name'] for em in resp]

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

        # Expect a 400 error when the order_by_direction param is invalid
        order_by_params = {'order_by_model': 'ElicitationMethod', 'order_by_attribute': 'name',
                     'order_by_direction': 'descending'}
        response = self.app.get(url('elicitationmethods'), order_by_params, status=400,
            headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp['errors']['order_by_direction'] == u"Value must be one of: asc; desc (not u'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': 'ElicitationMethodist', 'order_by_attribute': 'nominal',
                     'order_by_direction': 'desc'}
        response = self.app.get(url('elicitationmethods'), order_by_params,
            headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp[0]['id'] == elicitation_methods[0].id

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

        paginator = {'items_per_page': 0, 'page': -1}
        response = self.app.get(url('elicitationmethods'), paginator, headers=self.json_headers,
                                extra_environ=self.extra_environ_view, status=400)
        resp = json.loads(response.body)
        assert resp['errors']['items_per_page'] == u'Please enter a number that is 1 or greater'
        assert resp['errors']['page'] == u'Please enter a number that is 1 or greater'
Esempio n. 28
0
def update_collections_that_reference_this_collection(collection,
                                                      query_builder, **kwargs):
    """Update all collections that reference the input collection.
    
    :param collection: a collection model.
    :param query_builder: an :class:`SQLAQueryBuilder` instance.
    :param bool kwargs['contents_changed']: indicates whether the input
        collection's ``contents`` value has changed.
    :param bool kwargs['deleted']: indicates whether the input collection has
        just been deleted.
    :returns: ``None``

    Update the ``contents``, ``contents_unpacked``, ``html`` and/or ``form``
    attributes of every collection that references the input collection plus all
    of the collections that reference those collections, etc.  This function is
    called upon successful update and delete requests.

    If the contents of the ``collection`` have changed (i.e.,
    ``kwargs['contents_changed']==True``) , then retrieve all collections
    that reference ``collection`` and all collections that reference those
    referers, etc., and update their ``contents_unpacked``, ``html`` and
    ``forms`` attributes.

    If the ``collection`` has been deleted (i.e., ``kwargs['deleted']==True``),
    then recursively retrieve all collections referencing ``collection`` and
    update their ``contents``, ``contents_unpacked``, ``html`` and ``forms``
    attributes.

    If ``collection`` has just been tagged as restricted (i.e.,
    ``kwargs['restricted']==True``), then recursively restrict all collections
    that reference it.

    In all cases, update the ``datetime_modified`` value of every collection that
    recursively references ``collection``.

    """
    def update_contents_unpacked_etc(collection, **kwargs):
        deleted = kwargs.get('deleted', False)
        collection_id = kwargs.get('collection_id')
        if deleted:
            collection.contents = remove_references_to_this_collection(
                collection.contents, collection_id)
        collections_referenced = get_collections_referenced(
            collection.contents)
        collection.contents_unpacked = generate_contents_unpacked(
            collection.contents, collections_referenced)
        collection.html = h.get_HTML_from_contents(
            collection.contents_unpacked, collection.markup_language)
        collection.forms = [
            Session.query(Form).get(int(id)) for id in
            h.form_reference_pattern.findall(collection.contents_unpacked)
        ]

    def update_modification_values(collection, now):
        collection.datetime_modified = now
        session['user'] = Session.merge(session['user'])
        collection.modifier = session['user']

    restricted = kwargs.get('restricted', False)
    contents_changed = kwargs.get('contents_changed', False)
    deleted = kwargs.get('deleted', False)
    if restricted or contents_changed or deleted:
        collections_referencing_this_collection = get_collections_referencing_this_collection(
            collection, query_builder)
        collections_referencing_this_collection_dicts = [
            c.get_full_dict() for c in collections_referencing_this_collection
        ]
        now = h.now()
        if restricted:
            restricted_tag = h.get_restricted_tag()
            [
                c.tags.append(restricted_tag)
                for c in collections_referencing_this_collection
            ]
        if contents_changed:
            [
                update_contents_unpacked_etc(c)
                for c in collections_referencing_this_collection
            ]
        if deleted:
            [
                update_contents_unpacked_etc(c,
                                             collection_id=collection.id,
                                             deleted=True)
                for c in collections_referencing_this_collection
            ]
        [
            update_modification_values(c, now)
            for c in collections_referencing_this_collection
        ]
        [
            backup_collection(cd)
            for cd in collections_referencing_this_collection_dicts
        ]
        Session.add_all(collections_referencing_this_collection)
        Session.commit()
Esempio n. 29
0
    def test_index(self):
        """Tests that GET /formsearches returns an array of all form searches and that order_by and pagination parameters work correctly."""

        # Add 100 form searches.
        def create_form_search_from_index(index):
            form_search = model.FormSearch()
            form_search.name = u'form_search%d' % index
            form_search.description = u'description %d' % index
            form_search.search = unicode(
                json.dumps({
                    'query': {
                        'filter':
                        ['Form', 'transcription', 'regex',
                         '%d' % index]
                    }
                }))
            return form_search

        form_searches = [
            create_form_search_from_index(i) for i in range(1, 101)
        ]
        Session.add_all(form_searches)
        Session.commit()
        form_searches = h.get_form_searches(True)
        form_searches_count = len(form_searches)

        # Test that GET /formsearches gives us all of the form searches.
        response = self.app.get(url('formsearches'),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp) == form_searches_count
        assert resp[0]['name'] == u'form_search1'
        assert resp[0]['id'] == form_searches[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('formsearches'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp['items']) == 23
        assert resp['items'][0]['name'] == form_searches[46].name

        # Test the order_by GET params.
        order_by_params = {
            'order_by_model': 'FormSearch',
            'order_by_attribute': 'name',
            'order_by_direction': 'desc'
        }
        response = self.app.get(url('formsearches'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        result_set = sorted([t.name for t in form_searches], reverse=True)
        assert result_set == [t['name'] for t in resp]

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

        # Expect a 400 error when the order_by_direction param is invalid
        order_by_params = {
            'order_by_model': 'FormSearch',
            'order_by_attribute': 'name',
            'order_by_direction': 'descending'
        }
        response = self.app.get(url('formsearches'),
                                order_by_params,
                                status=400,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp['errors'][
            'order_by_direction'] == u"Value must be one of: asc; desc (not u'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': 'FormSearchist',
            'order_by_attribute': 'nominal',
            'order_by_direction': 'desc'
        }
        response = self.app.get(url('formsearches'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp[0]['id'] == form_searches[0].id

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

        paginator = {'items_per_page': 0, 'page': -1}
        response = self.app.get(url('formsearches'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view,
                                status=400)
        resp = json.loads(response.body)
        assert resp['errors'][
            'items_per_page'] == u'Please enter a number that is 1 or greater'
        assert resp['errors'][
            'page'] == u'Please enter a number that is 1 or greater'
Esempio n. 30
0
    def test_index(self):
        """Tests that GET /orthographies returns an array of all orthographies and that order_by and pagination parameters work correctly."""

        # Add 100 orthographies.
        def create_orthography_from_index(index):
            orthography = model.Orthography()
            orthography.name = u'orthography%d' % index
            orthography.orthography = u'a, b, c, %d' % index
            orthography.initial_glottal_stops = False
            orthography.lowercase = True
            return orthography

        orthographies = [
            create_orthography_from_index(i) for i in range(1, 101)
        ]
        Session.add_all(orthographies)
        Session.commit()
        orthographies = h.get_orthographies(True)
        orthographies_count = len(orthographies)

        # Test that GET /orthographies gives us all of the orthographies.
        response = self.app.get(url('orthographies'),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp) == orthographies_count
        assert resp[0]['name'] == u'orthography1'
        assert resp[0]['id'] == orthographies[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('orthographies'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp['items']) == 23
        assert resp['items'][0]['name'] == orthographies[46].name
        assert response.content_type == 'application/json'

        # Test the order_by GET params.
        order_by_params = {
            'order_by_model': 'Orthography',
            'order_by_attribute': 'name',
            'order_by_direction': 'desc'
        }
        response = self.app.get(url('orthographies'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        result_set = sorted([o.name for o in orthographies], reverse=True)
        assert result_set == [o['name'] for o in resp]

        # Test the order_by *with* paginator.
        params = {
            'order_by_model': 'Orthography',
            'order_by_attribute': 'name',
            'order_by_direction': 'desc',
            'items_per_page': 23,
            'page': 3
        }
        response = self.app.get(url('orthographies'),
                                params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert result_set[46] == resp['items'][0]['name']
        assert response.content_type == 'application/json'

        # Expect a 400 error when the order_by_direction param is invalid
        order_by_params = {
            'order_by_model': 'Orthography',
            'order_by_attribute': 'name',
            'order_by_direction': 'descending'
        }
        response = self.app.get(url('orthographies'),
                                order_by_params,
                                status=400,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp['errors'][
            'order_by_direction'] == u"Value must be one of: asc; desc (not u'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': 'Orthographyist',
            'order_by_attribute': 'nominal',
            'order_by_direction': 'desc'
        }
        response = self.app.get(url('orthographies'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp[0]['id'] == orthographies[0].id

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

        paginator = {'items_per_page': 0, 'page': -1}
        response = self.app.get(url('orthographies'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view,
                                status=400)
        resp = json.loads(response.body)
        assert resp['errors'][
            'items_per_page'] == u'Please enter a number that is 1 or greater'
        assert resp['errors'][
            'page'] == u'Please enter a number that is 1 or greater'
        assert response.content_type == 'application/json'
Esempio n. 31
0
    def test_index(self):
        """Tests that GET /speakers returns an array of all speakers and that order_by and pagination parameters work correctly."""

        # Add 100 speakers.
        def create_speaker_from_index(index):
            speaker = model.Speaker()
            speaker.first_name = u'John%d' % index
            speaker.last_name = u'Doe%d' % index
            speaker.dialect = u'dialect %d' % index
            speaker.page_content = u'page content %d' % index
            return speaker
        speakers = [create_speaker_from_index(i) for i in range(1, 101)]
        Session.add_all(speakers)
        Session.commit()
        speakers = h.get_speakers(True)
        speakers_count = len(speakers)

        # Test that GET /speakers gives us all of the speakers.
        response = self.app.get(url('speakers'), headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp) == speakers_count
        assert resp[0]['first_name'] == u'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('speakers'), paginator, headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.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('speakers'), order_by_params,
                        headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.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('speakers'), params,
                        headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.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('speakers'), order_by_params, status=400,
            headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp['errors']['order_by_direction'] == u"Value must be one of: asc; desc (not u'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('speakers'), order_by_params,
            headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.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': u'a', 'page': u''}
        response = self.app.get(url('speakers'), paginator, headers=self.json_headers,
                                extra_environ=self.extra_environ_view, status=400)
        resp = json.loads(response.body)
        assert resp['errors']['items_per_page'] == u'Please enter an integer value'
        assert resp['errors']['page'] == u'Please enter a value'
        assert response.content_type == 'application/json'

        paginator = {'items_per_page': 0, 'page': -1}
        response = self.app.get(url('speakers'), paginator, headers=self.json_headers,
                                extra_environ=self.extra_environ_view, status=400)
        resp = json.loads(response.body)
        assert resp['errors']['items_per_page'] == u'Please enter a number that is 1 or greater'
        assert resp['errors']['page'] == u'Please enter a number that is 1 or greater'
        assert response.content_type == 'application/json'
Esempio n. 32
0
    def test_delete(self):
        """Tests that DELETE /tags/id deletes the tag with id=id."""

        # Create a tag to delete.
        params = json.dumps({'name': u'name', 'description': u'description'})
        response = self.app.post(url('tags'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = json.loads(response.body)
        tag_count = Session.query(Tag).count()
        tag_id = resp['id']

        # Now delete the tag
        response = self.app.delete(url('tag', id=tag_id),
                                   headers=self.json_headers,
                                   extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        new_tag_count = Session.query(Tag).count()
        assert new_tag_count == tag_count - 1
        assert resp['id'] == tag_id
        assert response.content_type == 'application/json'

        # Trying to get the deleted tag from the db should return None
        deleted_tag = Session.query(Tag).get(tag_id)
        assert deleted_tag == None

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

        # Delete without an id
        response = self.app.delete(url('tag', id=''),
                                   status=404,
                                   headers=self.json_headers,
                                   extra_environ=self.extra_environ_admin)
        assert json.loads(
            response.body)['error'] == 'The resource could not be found.'
        assert response.content_type == 'application/json'

        # Create a form, tag it, delete the tag and show that the form no longer
        # has the tag.
        tag = model.Tag()
        tag.name = u'tag'
        form = model.Form()
        form.transcription = u'test'
        form.tags.append(tag)
        Session.add_all([form, tag])
        Session.commit()
        form_id = form.id
        tag_id = tag.id
        response = self.app.delete(url('tag', id=tag_id),
                                   headers=self.json_headers,
                                   extra_environ=self.extra_environ_admin)
        deleted_tag = Session.query(Tag).get(tag_id)
        form = Session.query(model.Form).get(form_id)
        assert response.content_type == 'application/json'
        assert deleted_tag == None
        assert form.tags == []
Esempio n. 33
0
    def test_index(self):
        """Tests that GET /elicitationmethods returns an array of all elicitation methods and that order_by and pagination parameters work correctly."""

        # Add 100 elicitation methods.
        def create_elicitation_method_from_index(index):
            elicitation_method = model.ElicitationMethod()
            elicitation_method.name = u'em%d' % index
            elicitation_method.description = u'description %d' % index
            return elicitation_method

        elicitation_methods = [
            create_elicitation_method_from_index(i) for i in range(1, 101)
        ]
        Session.add_all(elicitation_methods)
        Session.commit()
        elicitation_methods = h.get_elicitation_methods(True)
        elicitation_methods_count = len(elicitation_methods)

        # Test that GET /elicitationmethods gives us all of the elicitation methods.
        response = self.app.get(url('elicitationmethods'),
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp) == elicitation_methods_count
        assert resp[0]['name'] == u'em1'
        assert resp[0]['id'] == elicitation_methods[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('elicitationmethods'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp['items']) == 23
        assert resp['items'][0]['name'] == elicitation_methods[46].name

        # Test the order_by GET params.
        order_by_params = {
            'order_by_model': 'ElicitationMethod',
            'order_by_attribute': 'name',
            'order_by_direction': 'desc'
        }
        response = self.app.get(url('elicitationmethods'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        result_set = sorted([em.name for em in elicitation_methods],
                            reverse=True)
        assert result_set == [em['name'] for em in resp]

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

        # Expect a 400 error when the order_by_direction param is invalid
        order_by_params = {
            'order_by_model': 'ElicitationMethod',
            'order_by_attribute': 'name',
            'order_by_direction': 'descending'
        }
        response = self.app.get(url('elicitationmethods'),
                                order_by_params,
                                status=400,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp['errors'][
            'order_by_direction'] == u"Value must be one of: asc; desc (not u'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': 'ElicitationMethodist',
            'order_by_attribute': 'nominal',
            'order_by_direction': 'desc'
        }
        response = self.app.get(url('elicitationmethods'),
                                order_by_params,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert resp[0]['id'] == elicitation_methods[0].id

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

        paginator = {'items_per_page': 0, 'page': -1}
        response = self.app.get(url('elicitationmethods'),
                                paginator,
                                headers=self.json_headers,
                                extra_environ=self.extra_environ_view,
                                status=400)
        resp = json.loads(response.body)
        assert resp['errors'][
            'items_per_page'] == u'Please enter a number that is 1 or greater'
        assert resp['errors'][
            'page'] == u'Please enter a number that is 1 or greater'
Esempio n. 34
0
    def test_index(self):
        """Tests that GET & SEARCH /corpusbackups behave correctly.
        """

        tag = model.Tag()
        tag.name = u'random tag name'
        Session.add(tag)
        Session.commit()
        tag_id = tag.id

        # Add 10 forms and use them to generate a valid value for ``test_corpus_content``
        def create_form_from_index(index):
            form = model.Form()
            form.transcription = u'Form %d' % index
            translation = model.Translation()
            translation.transcription = u'Translation %d' % index
            form.translation = translation
            return form
        forms = [create_form_from_index(i) for i in range(1, 10)]
        Session.add_all(forms)
        Session.commit()
        forms = h.get_forms()
        half_forms = forms[:5]
        form_ids = [form.id for form in forms]
        half_form_ids = [form.id for form in half_forms]
        test_corpus_content = u','.join(map(str, form_ids))
        test_corpus_half_content = u','.join(map(str, half_form_ids))

        # Create a form search model
        query = {'filter': ['Form', 'transcription', 'regex', u'[a-zA-Z]{3,}']}
        params = json.dumps({
            'name': u'form search',
            'description': u'This one\'s worth saving!',
            'search': query
        })
        response = self.app.post(url('formsearches'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = json.loads(response.body)
        form_search_id = resp['id']

        # Generate some valid corpus creation input parameters.
        params = self.corpus_create_params.copy()
        params.update({
            'name': u'Corpus',
            'description': u'Covers a lot of the data.',
            'content': test_corpus_content
        })
        params = json.dumps(params)

        # Attempt to create a corpus as a viewer and expect to fail
        response = self.app.post(url('corpora'), params, self.json_headers,
                                 self.extra_environ_view, status=403)
        resp = json.loads(response.body)
        assert resp['error'] == u'You are not authorized to access this resource.'
        assert response.content_type == 'application/json'

        # Successfully create a corpus as the admin
        assert os.listdir(self.corpora_path) == []
        original_corpus_count = Session.query(Corpus).count()
        response = self.app.post(url('corpora'), params, self.json_headers,
                                 self.extra_environ_admin)
        resp = json.loads(response.body)
        corpus_id = resp['id']
        new_corpus_count = Session.query(Corpus).count()
        corpus = Session.query(Corpus).get(corpus_id)
        corpus_form_ids = sorted([f.id for f in corpus.forms])
        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'] == u'Corpus'
        assert resp['description'] == u'Covers a lot of the data.'
        assert corpus_dir_contents == []
        assert response.content_type == 'application/json'
        assert resp['content'] == test_corpus_content
        assert corpus_form_ids == sorted(form_ids)

        # Update the corpus as the contributor -- now we should have one backup
        params = self.corpus_create_params.copy()
        params.update({
            'name': u'Corpus',
            'description': u'Covers a little less data.',
            'content': test_corpus_half_content
        })
        params = json.dumps(params)
        response = self.app.put(url('corpus', id=corpus_id), params,
                self.json_headers, self.extra_environ_contrib)
        resp = json.loads(response.body)
        corpus_count = new_corpus_count
        new_corpus_count = Session.query(Corpus).count()
        corpus = Session.query(Corpus).get(corpus_id)
        corpus_form_ids = sorted([f.id for f in corpus.forms])
        assert new_corpus_count == corpus_count
        assert resp['name'] == u'Corpus'
        assert resp['description'] == u'Covers a little less data.' 
        assert response.content_type == 'application/json'
        assert resp['content'] == test_corpus_half_content
        assert corpus_form_ids == sorted(half_form_ids)

        # Update the corpus again -- now we should have two backups
        sleep(1)
        params = self.corpus_create_params.copy()
        params.update({
            'name': u'Corpus',
            'description': u'Covers a little less data.',
            'content': test_corpus_half_content,
            'tags': [tag_id]
        })
        params = json.dumps(params)
        response = self.app.put(url('corpus', id=corpus_id), params,
                self.json_headers, self.extra_environ_admin)
        resp = json.loads(response.body)
        corpus_count = new_corpus_count
        new_corpus_count = Session.query(Corpus).count()
        corpus = Session.query(Corpus).get(corpus_id)
        corpus_form_ids = sorted([f.id for f in corpus.forms])
        assert new_corpus_count == corpus_count
        assert resp['name'] == u'Corpus'
        assert resp['description'] == u'Covers a little less data.' 
        assert response.content_type == 'application/json'
        assert resp['content'] == test_corpus_half_content
        assert corpus_form_ids == sorted(half_form_ids)

        all_corpus_backups = Session.query(CorpusBackup).order_by(CorpusBackup.id).all()
        all_corpus_backup_ids = [cb.id for cb in all_corpus_backups]
        all_corpus_backup_descriptions = [cb.description for cb in all_corpus_backups]

        # Now request the corpus backups as either the contributor or the viewer and 
        # expect to get them all.
        response = self.app.get(url('corpusbackups'), headers=self.json_headers, extra_environ=self.extra_environ_contrib)
        resp = json.loads(response.body)
        assert len(resp) == 2
        assert response.content_type == 'application/json'
        assert resp[0]['modifier']['role'] == u'administrator'
        assert resp[1]['modifier']['role'] == u'contributor'

        # The admin should get them all too.
        response = self.app.get(url('corpusbackups'), headers=self.json_headers, extra_environ=self.extra_environ_view)
        resp = json.loads(response.body)
        assert len(resp) == 2
        assert [cb['id'] for cb in resp] == all_corpus_backup_ids

        # Test the paginator GET params.
        paginator = {'items_per_page': 1, 'page': 2}
        response = self.app.get(url('corpusbackups'), paginator, headers=self.json_headers,
                                extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        assert len(resp['items']) == 1
        assert resp['paginator']['count'] == 2
        assert response.content_type == 'application/json'
        assert resp['items'][0]['id'] == all_corpus_backup_ids[1]

        # Test the order_by GET params.
        order_by_params = {'order_by_model': 'CorpusBackup',
            'order_by_attribute': 'id', 'order_by_direction': 'desc'}
        response = self.app.get(url('corpusbackups'), order_by_params,
                        headers=self.json_headers, extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        result_set = list(reversed(all_corpus_backup_ids))
        assert [cb['id'] for cb in resp] == result_set

        # Test the order_by *with* paginator.  
        params = {'order_by_model': 'CorpusBackup', 'order_by_attribute': 'id',
                     'order_by_direction': 'desc', 'items_per_page': 1, 'page': 1}
        response = self.app.get(url('corpusbackups'), params,
                        headers=self.json_headers, extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        assert result_set[0] == resp['items'][0]['id']

        # Now test the show action:

        # Get a specific corpus backup. 
        response = self.app.get(url('corpusbackup', id=all_corpus_backup_ids[0]),
                                headers=self.json_headers, extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        assert resp['description'] == u'Covers a lot of the data.'
        assert resp['content'] == test_corpus_content
        assert response.content_type == 'application/json'

        # A nonexistent cb id will return a 404 error
        response = self.app.get(url('corpusbackup', id=100987),
                    headers=self.json_headers, extra_environ=self.extra_environ_view, status=404)
        resp = json.loads(response.body)
        assert resp['error'] == u'There is no corpus backup with id 100987'
        assert response.content_type == 'application/json'

        # Test the search action
        self._add_SEARCH_to_web_test_valid_methods()

        # A search on corpus backup titles using POST /corpusbackups/search
        json_query = json.dumps({'query': {'filter':
                        ['CorpusBackup', 'description', 'like', u'%less%']}})
        response = self.app.post(url('/corpusbackups/search'), json_query,
                        self.json_headers, extra_environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        result_set = [name for name in all_corpus_backup_descriptions if u'less' in name]
        assert len(resp) == len(result_set) == 1
        assert resp[0]['description'] == result_set[0]
        assert response.content_type == 'application/json'

        # A search on corpus backup titles using SEARCH /corpusbackups
        json_query = json.dumps({'query': {'filter':
                        ['CorpusBackup', 'description', 'like', u'%less%']}})
        response = self.app.request(url('corpusbackups'), method='SEARCH', body=json_query,
                        headers=self.json_headers, environ=self.extra_environ_admin)
        resp = json.loads(response.body)
        assert len(resp) == len(result_set) == 1
        assert resp[0]['description'] == result_set[0]
        assert response.content_type == 'application/json'

        # Attempting to call edit/new/create/delete/update on a read-only resource
        # will return a 404 response
        response = self.app.get(url('edit_corpusbackup', id=2232), status=404)
        assert json.loads(response.body)['error'] == u'This resource is read-only.'
        response = self.app.get(url('new_corpusbackup', id=2232), status=404)
        assert json.loads(response.body)['error'] == u'This resource is read-only.'
        response = self.app.post(url('corpusbackups'), status=404)
        assert json.loads(response.body)['error'] == u'This resource is read-only.'
        response = self.app.put(url('corpusbackup', id=2232), status=404)
        assert json.loads(response.body)['error'] == u'This resource is read-only.'
        response = self.app.delete(url('corpusbackup', id=2232), status=404)
        assert json.loads(response.body)['error'] == u'This resource is read-only.'
        assert response.content_type == 'application/json'