コード例 #1
0
ファイル: base.py プロジェクト: kwbock/eulfedora
class FedoraTestCase(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        unittest.TestCase.__init__(self, *args, **kwargs)
        self.fedora_fixtures_ingested = []
        self.pidspace = FEDORA_PIDSPACE

        self.repo = Repository(FEDORA_ROOT, FEDORA_USER, FEDORA_PASSWORD)

        # fixture cleanup happens in tearDown, which doesn't always run
        # if a test fails - clean up stale test objects from a previous run here
        stale_objects = list(self.repo.find_objects(pid__contains="%s:*" % self.pidspace))
        if stale_objects:
            print "Removing %d stale test object(s) in pidspace %s" % (len(stale_objects), self.pidspace)
            for obj in stale_objects:
                try:
                    self.repo.purge_object(obj.pid)
                except RequestFailed as rf:
                    logger.warn("Error purging stale test object %s (TestCase init): %s" % (obj.pid, rf))

    def setUp(self):
        # NOTE: queries require RI flush=True or test objects will not show up in RI
        self.repo.risearch.RISEARCH_FLUSH_ON_QUERY = True
        self.opener = self.repo.opener
        self.api = ApiFacade(self.opener)
        fixtures = getattr(self, "fixtures", [])
        for fixture in fixtures:
            self.ingestFixture(fixture)

    def tearDown(self):
        for pid in self.fedora_fixtures_ingested:
            try:
                self.repo.purge_object(pid)
            except RequestFailed as rf:
                logger.warn("Error purging test object %s in tear down: %s" % (pid, rf))

    def getNextPid(self):
        pidspace = getattr(self, "pidspace", None)
        return self.repo.get_next_pid(namespace=pidspace)

    def loadFixtureData(self, fname):
        data = load_fixture_data(fname)
        # if pidspace is specified, get a new pid from fedora and set it as the pid in the xml
        if hasattr(self, "pidspace"):
            xml = xmlmap.load_xmlobject_from_string(data, _MinimalFoxml)
            xml.pid = self.getNextPid()
            return xml.serialize()
        else:
            return data

    def ingestFixture(self, fname):
        object = self.loadFixtureData(fname)
        pid = self.repo.ingest(object)
        if pid:
            # we'd like this always to be true. if ingest fails we should
            # throw an exception. that probably hasn't been thoroughly
            # tested yet, though, so we'll check it until it has been.
            self.append_test_pid(pid)

    def append_test_pid(self, pid):
        self.fedora_fixtures_ingested.append(pid)
コード例 #2
0
ファイル: purge_object.py プロジェクト: abrennr/drlrepo
def purge_item(item_id):
    repo = Repository()
    pid = 'pitt:%s' % (item_id,)
    objs = repo.find_objects(pid__contains=pid)
    for o in objs:
        repo.purge_object(o.pid)
        print '%s purged' % (o.pid,)
コード例 #3
0
ファイル: testutil.py プロジェクト: bodleian/eulfedora
    def remove_test_objects(self):
        # remove any leftover test object before or after running tests
        # NOTE: This method expects to be called only when FEDORA_PIDSPACE has been
        # switched to a test pidspace

        # use test fedora credentials if they are set
        repo = Repository(root=getattr(settings, 'FEDORA_TEST_ROOT', None),
                          username=getattr(settings, 'FEDORA_TEST_USER', None),
                          password=getattr(settings, 'FEDORA_TEST_PASSWORD',
                                           None))
        test_objects = repo.find_objects(pid__contains='%s:*' %
                                         settings.FEDORA_PIDSPACE)
        count = 0
        for obj in test_objects:
            # if objects are unexpectedly not being cleaned up, pid/label may help
            # to isolate which test is creating the leftover objects
            try:
                repo.purge_object(obj.pid, "removing test object")
                # NOTE: not displaying label because we may not have permission to access it
                logger.info('Purged test object %s' % obj.pid)
                count += 1
            except RequestFailed:
                logger.warn('Error purging test object %s' % obj.pid)
        if count:
            print >> sys.stderr, "Removed %s test object(s) with pidspace %s" \
                % (count, settings.FEDORA_PIDSPACE)
コード例 #4
0
ファイル: tests.py プロジェクト: Tutt-Library/ccetd
class ThesisBase(unittest.TestCase):
    """Base class for testing the functionality of the ETD Django 
     application."""

    def __init__(self, *args, **kwargs):
        unittest.TestCase.__init__(self, *args, **kwargs)
        self.fedora_fixtures_ingested = []
        self.pidspace = FEDORA_PIDSPACE

    def setUp(self):
        """Creates a base class instance of an `eulfedora` Repository 
        for testing the basic functionality of the ingesting
        a thesis object into a Fedora Repository."""
        self.repo = Repository()
#        self.repo = Repository(FEDORA_ROOT,FEDORA_USER,FEDORA_PASSWORD)
        self.repo.risearch.RISEARCH_FLUSH_ON_QUERY = True
    
    def tearDown(self):
        """Removes test objects from the repository"""
        for pid in self.fedora_fixtures_ingested:
            try:
                self.repo.purge_object(pid)
            except RequestFailed as rf:
                logger.warn('Error purging test object %s in tear down:%s' %\
                            (pid,rf)) 
コード例 #5
0
ファイル: test_util.py プロジェクト: jrhoads/eulfedora
class PdfToTextTest(unittest.TestCase):
    fixture_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'fixtures')
    pdf_filepath = os.path.join(fixture_dir, 'test.pdf')
    pdf_text = 'This is a short PDF document to use for testing.'

    def setUp(self):
        self.repo = Repository(settings.FEDORA_ROOT, settings.FEDORA_USER,
                               settings.FEDORA_PASSWORD)
        with open(self.pdf_filepath) as pdf:
            self.pdfobj = self.repo.get_object(type=TestPdfObject)
            self.pdfobj.label = 'eulindexer test pdf object'
            self.pdfobj.pdf.content = pdf
            self.pdfobj.save()

    def tearDown(self):
        self.repo.purge_object(self.pdfobj.pid)
        
    def test_file(self):
        # extract text from a pdf from a file on the local filesystem
        text = pdf_to_text(open(self.pdf_filepath, 'rb'))
        self.assertEqual(self.pdf_text, text)

    def test_object_datastream(self):
        # extract text from a pdf datastream in fedora
        pdfobj = self.repo.get_object(self.pdfobj.pid, type=TestPdfObject)
        text = pdf_to_text(pdfobj.pdf.content)
        self.assertEqual(self.pdf_text, text)
コード例 #6
0
class PdfToTextTest(unittest.TestCase):
    fixture_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                               'fixtures')
    pdf_filepath = os.path.join(fixture_dir, 'test.pdf')
    pdf_text = 'This is a short PDF document to use for testing.'

    def setUp(self):
        self.repo = Repository(settings.FEDORA_ROOT, settings.FEDORA_USER,
                               settings.FEDORA_PASSWORD)
        with open(self.pdf_filepath) as pdf:
            self.pdfobj = self.repo.get_object(type=TestPdfObject)
            self.pdfobj.label = 'eulindexer test pdf object'
            self.pdfobj.pdf.content = pdf
            self.pdfobj.save()

    def tearDown(self):
        self.repo.purge_object(self.pdfobj.pid)

    def test_file(self):
        # extract text from a pdf from a file on the local filesystem
        text = pdf_to_text(open(self.pdf_filepath, 'rb'))
        self.assertEqual(self.pdf_text, text)

    def test_object_datastream(self):
        # extract text from a pdf datastream in fedora
        pdfobj = self.repo.get_object(self.pdfobj.pid, type=TestPdfObject)
        text = pdf_to_text(pdfobj.pdf.content)
        self.assertEqual(self.pdf_text, text)
コード例 #7
0
ファイル: testutil.py プロジェクト: jrhoads/eulfedora
    def remove_test_objects(self):
        # remove any leftover test object before or after running tests
        # NOTE: This method expects to be called only when FEDORA_PIDSPACE has been
        # switched to a test pidspace

        # use test fedora credentials if they are set
        repo = Repository(root=getattr(settings, 'FEDORA_TEST_ROOT', None),
                          username=getattr(settings, 'FEDORA_TEST_USER', None),
                          password=getattr(settings, 'FEDORA_TEST_PASSWORD', None))
        test_objects = repo.find_objects(pid__contains='%s:*' % settings.FEDORA_PIDSPACE)
        count = 0
        for obj in test_objects:
            # if objects are unexpectedly not being cleaned up, pid/label may help
            # to isolate which test is creating the leftover objects
            try:
                repo.purge_object(obj.pid, "removing test object")
                # NOTE: not displaying label because we may not have permission to access it
                logger.info('Purged test object %s' % obj.pid)
                count += 1
            except RequestFailed:
                logger.warn('Error purging test object %s' % obj.pid)
        if count:
            print "Removed %s test object(s) with pidspace %s" % (count, settings.FEDORA_PIDSPACE)
コード例 #8
0
ファイル: tests.py プロジェクト: emory-libraries/genrepo-demo
class ModelUtilsTest(TestCase):
    # tests for utility methods declared in file.models

    repo_admin = None

    def setUp(self):
        # instantiate repo_admin the first time we run, after the test settings are in place
        if self.repo_admin is None:
            self.repo_admin = Repository(username=getattr(settings, 'FEDORA_TEST_USER', None),
                                         password=getattr(settings, 'FEDORA_TEST_PASSWORD', None))
        self.pids = []

    def tearDown(self):
        for pid in self.pids:
            self.repo_admin.purge_object(pid)

    def test_object_type_from_mimetype(self):
        self.assertEqual(ImageObject, object_type_from_mimetype('image/jpeg'))
        self.assertEqual(ImageObject, object_type_from_mimetype('image/gif'))
        self.assertEqual(FileObject, object_type_from_mimetype('image/unsupported-img'))
        self.assertEqual(FileObject, object_type_from_mimetype('text/plain'))
        
    def test_init_by_cmodel(self):
        # create file and image objects to test initialization
        fileobj = self.repo_admin.get_object(type=FileObject)
        fileobj.save()
        imgobj = self.repo_admin.get_object(type=ImageObject)
        imgobj.save()
        self.pids.extend([fileobj.pid, imgobj.pid])
        # init a new object from file pid - should be a file object
        initobj = init_by_cmodel(fileobj.pid)
        self.assert_(isinstance(initobj, FileObject))
        # since ImageObject extends FileObject, confirm that we didn't get the wrong thing
        self.assert_(not isinstance(initobj, ImageObject))
        # image pid should be returned as an ImageObject
        initobj = init_by_cmodel(imgobj.pid)
        self.assert_(isinstance(initobj, ImageObject))
コード例 #9
0
ファイル: test_views.py プロジェクト: bodleian/eulfedora
    def test_index_details(self):
        repo = Repository()
        for pid in self.pids:
            repo.purge_object(pid)

        # Test with no settings set.
        # - should be denied
        response = index_config(self.request)
        self.assertEqual(403, response.status_code,
            'index data should be forbidden if no IPs are configured to access')

        # NOTE: these aren't meaningful errors anyway, and settings
        # are now being pulled from somewhere so they fail
        # self.assertRaises(AttributeError, index_config, self.request)
        # Test with only the allowed SOLR url set.
        # self.assertRaises(AttributeError, index_config, self.request)

        # Test with this IP not allowed to hit the service.
        #settings.EUL_INDEXER_ALLOWED_IPS = ['0.13.23.134']
        with override_settings(EUL_INDEXER_ALLOWED_IPS=['0.13.23.134']):
            response = index_config(self.request)
            expected, got = 403, response.status_code
            self.assertEqual(expected, got,
                'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))
            expected, got = 'text/html', response['Content-Type']
            self.assertEqual(expected, got,
                'Expected %s but returned %s for mimetype on indexdata/index_details view' \
                % (expected, got))

        # Test with this IP allowed to hit the view.
        with override_settings(EUL_INDEXER_ALLOWED_IPS=['0.13.23.134',
                                                    self.request_ip]):
            response = index_config(self.request)
            expected, got = 200, response.status_code
            self.assertEqual(expected, got,
                'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))
            expected, got = 'application/json', response['Content-Type']
            self.assertEqual(expected, got,
                'Expected %s but returned %s for mimetype on indexdata/index_details view' \
                % (expected, got))
            # load json content so we can inspect the result
            content = json.loads(response.content)
            self.assertEqual(TEST_SOLR_URL, content['SOLR_URL'])
            self.assert_(SimpleObject.CONTENT_MODELS in content['CONTENT_MODELS'])
            self.assert_(LessSimpleDigitalObject.CONTENT_MODELS in content['CONTENT_MODELS'])
            self.assert_(ContentModel.CONTENT_MODELS not in content['CONTENT_MODELS'],
               'Fedora system content models should not be included in indexed cmodels by default')

        # Test with the "ANY" setting for allowed IPs
        with override_settings(EUL_INDEXER_ALLOWED_IPS='ANY'):
            response = index_config(self.request)
            expected, got = 200, response.status_code
            self.assertEqual(expected, got,
                'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))

        # Test with 'EUL_INDEXER_CONTENT_MODELS' setting configured to override autodetect.
        with override_settings(EUL_INDEXER_ALLOWED_IPS='ANY',
                               EUL_INDEXER_CONTENT_MODELS=[
                ['content-model_1', 'content-model_2'], ['content-model_3']]):
            response = index_config(self.request)
            expected, got = 200, response.status_code
            self.assertEqual(expected, got,
                'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))
            expected, got = 'application/json', response['Content-Type']
            self.assertEqual(expected, got,
                'Expected %s but returned %s for mimetype on indexdata/index_details view' \
                % (expected, got))
            # load json content so we can inspect the result
            content = json.loads(response.content)
            self.assertEqual(settings.EUL_INDEXER_CONTENT_MODELS,
                content['CONTENT_MODELS'])
コード例 #10
0
ファイル: base.py プロジェクト: dasch124/eulfedora
class FedoraTestCase(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        unittest.TestCase.__init__(self, *args, **kwargs)
        self.fedora_fixtures_ingested = []
        self.pidspace = FEDORA_PIDSPACE

        self.repo = Repository(FEDORA_ROOT, FEDORA_USER, FEDORA_PASSWORD)

        # fixture cleanup happens in tearDown, which doesn't always run
        # if a test fails - clean up stale test objects from a previous run here
        stale_objects = list(self.repo.find_objects(pid__contains='%s:*' % self.pidspace))
        if stale_objects:
            logger.info('Removing %d stale test object(s) in pidspace %s' \
                % (len(stale_objects), self.pidspace))

            for obj in stale_objects:
                try:
                    self.repo.purge_object(obj.pid)
                except RequestFailed as rf:
                    logger.warn('Error purging stale test object %s (TestCase init): %s' % \
                                (obj.pid, rf))

    def setUp(self):
        # NOTE: queries require RI flush=True or test objects will not show up in RI
        self.repo.risearch.RISEARCH_FLUSH_ON_QUERY = True
        self.opener = self.repo.opener
        self.api = ApiFacade(self.opener)
        fixtures = getattr(self, 'fixtures', [])
        for fixture in fixtures:
            self.ingestFixture(fixture)

    def tearDown(self):
        for pid in self.fedora_fixtures_ingested:
            try:
                self.repo.purge_object(pid)
            except RequestFailed as rf:
                logger.warn('Error purging test object %s in tear down: %s' % \
                            (pid, rf))

    def getNextPid(self):
        pidspace = getattr(self, 'pidspace', None)
        return self.repo.get_next_pid(namespace=pidspace)

    def loadFixtureData(self, fname):
        data = load_fixture_data(fname)
        # if pidspace is specified, get a new pid from fedora and set it as the pid in the xml
        if hasattr(self, 'pidspace'):
            xml = xmlmap.load_xmlobject_from_string(data, _MinimalFoxml)
            xml.pid = self.getNextPid()
            return xml.serialize()
        else:
            return data

    def ingestFixture(self, fname):
        object = self.loadFixtureData(fname)
        pid = self.repo.ingest(object)
        if pid:
            # we'd like this always to be true. if ingest fails we should
            # throw an exception. that probably hasn't been thoroughly
            # tested yet, though, so we'll check it until it has been.
            self.append_pid(pid)

    # note: renamed from append_test_pid so that nosetests doesn't
    # autodetect and attempt to run as a unit test.
    def append_pid(self, pid):
            self.fedora_fixtures_ingested.append(pid)
コード例 #11
0
class CollectionViewsTest(TestCase):
    fixtures = ['users']
    # repository with default access (no credentials)
    repo = Repository()

    # repository with test credentials for loading & removing test objects
    # DON'T instantiate this at load time, since Fedora Test settings are not yet switched
    repo_admin = None

    new_coll_url = reverse('collection:new')

    def setUp(self):
        # instantiate repo_admin the first time we run, after the test settings are in place
        if self.repo_admin is None:
            # repository with test credentials for loading & removing test objects
            self.repo_admin = Repository(
                username=getattr(settings, 'FEDORA_TEST_USER', None),
                password=getattr(settings, 'FEDORA_TEST_PASSWORD', None))

        self.client = Client()
        # create test collection object for testing view/edit functionality
        self.obj = self.repo_admin.get_object(type=CollectionObject)
        self.obj.label = 'Genrepo test collection'
        self.obj.dc.content.title = 'my test title'
        self.obj.dc.content.description = 'this collection contains test content'
        self.obj.save()
        self.edit_coll_url = reverse('collection:edit',
                                     kwargs={'pid': self.obj.pid})
        self.view_coll_url = reverse('collection:view',
                                     kwargs={'pid': self.obj.pid})
        self.list_coll_url = reverse('collection:list')

        self.pids = [self.obj.pid]

    def tearDown(self):
        # purge any objects created by individual tests
        for pid in self.pids:
            self.repo_admin.purge_object(pid)

    def test_get_create_form(self):
        'Test displaying the form (HTTP GET) for creating a collection object (%s)' % __name__

        # not logged in - should redirect to login page
        response = self.client.get(self.new_coll_url)
        code = response.status_code
        expected = 302
        self.assertEqual(
            code, expected,
            'Expected %s but returned %s for %s as AnonymousUser' %
            (expected, code, self.new_coll_url))

        # logged in as user without required permissions - should 403
        self.client.login(**NONADMIN_CREDENTIALS)
        response = self.client.get(self.new_coll_url)
        code = response.status_code
        expected = 403
        self.assertEqual(
            code, expected,
            'Expected %s but returned %s for %s as logged in non-repo editor' %
            (expected, code, self.new_coll_url))

        # log in as repository editor for all other tests
        # NOTE: using admin view so user credentials will be used to access fedora
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)

        # on GET, form should be displayed
        response = self.client.get(self.new_coll_url)
        expected, code = 200, response.status_code
        self.assertEqual(
            code, expected, 'Expected %s but returned %s for %s' %
            (expected, code, self.new_coll_url))
        self.assert_(
            isinstance(response.context['form'], CollectionDCEditForm),
            "CollectionDCEditForm should be set in response context")
        self.assertContains(response, 'Create a new collection')

    def test_create_invalid(self):
        'Test submitting invalid data to create a collection object'

        # log in as repository editor
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)

        # test submitting incomplete/invalid data - should redisplay form with errors
        # title is required
        test_data = {'title': '', 'description': 'a new test collection'}
        response = self.client.post(self.new_coll_url, test_data)
        self.assert_(
            isinstance(response.context['form'], CollectionDCEditForm),
            "CollectionDCEditForm is set in response context when form is POSTed without title"
        )
        self.assertContains(
            response,
            'This field is required',
            1,
            msg_prefix='error message for 1 missing required fields')

    def test_create_valid(self):
        'Test submitting valid data to create collection object'

        # log in as repository editor
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)

        # POST and create new object, verify in fedora
        test_data = {
            'title': 'genrepo test collection',
            'description': 'my second test collection'
        }
        response = self.client.post(self.new_coll_url, test_data, follow=True)
        # on success, should redirect with a message about the object
        messages = [str(msg) for msg in response.context['messages']]
        self.assert_(
            'Successfully created new collection' in messages[0],
            'successful collection creation message displayed to user')
        # inspect newly created object and in fedora
        # - pull the pid out of the success message
        pidmatch = re.search('<b>(.*)</b>', messages[0])
        pid = pidmatch.group(1)  # first parenthesized subgroup
        # append to list of pids to be cleaned up after the test
        self.pids.append(pid)

        # inspect object - use repo_admin so we can access it
        new_obj = self.repo_admin.get_object(pid, type=CollectionObject)
        self.assertTrue(
            new_obj.has_requisite_content_models,
            'new object was created with the expected content models for a CollectionObject'
        )
        self.assertEqual(test_data['title'], new_obj.dc.content.title,
         "posted title should be set in dc:title; expected '%s', got '%s'" % \
                 (test_data['title'], new_obj.dc.content.title))
        self.assertEqual(test_data['description'], new_obj.dc.content.description,
                 "posted description should be set in dc:description; expected '%s', got '%s'" % \
                 (test_data['description'], new_obj.dc.content.description))
        self.assertEqual(test_data['title'], new_obj.label,
                 "posted title should be set in object label; expected '%s', got '%s'" % \
                 (test_data['title'], new_obj.label))

        # confirm that current site user appears in fedora audit trail
        xml, uri = new_obj.api.getObjectXML(pid)
        self.assert_('<audit:responsibility>%s</audit:responsibility>' % \
                     ADMIN_CREDENTIALS['username'] in xml)

    def test_create_save_errors(self):
        'Test fedora error handling when saving a collection object'
        # simulate fedora errors with mock objects

        # log in as repository editor
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)

        testobj = Mock(name='MockDigitalObject')
        testobj.dc.content = DublinCore()
        # Create a RequestFailed exception to simulate Fedora error
        # - eulcore.fedora wrap around an httplib response
        err_resp = Mock()
        err_resp.status = 500
        err_resp.read.return_value = 'error message'
        # generate Fedora error on object save
        testobj.save.side_effect = RequestFailed(err_resp)

        # valid form data to post
        test_data = {'title': 'foo', 'description': 'bar'}

        # 500 error / request failed
        # patch the repository class to return the mock object instead of a real one
        with patch.object(Repository,
                          'get_object',
                          new=Mock(return_value=testobj)):
            response = self.client.post(self.new_coll_url,
                                        test_data,
                                        follow=True)
            expected, code = 500, response.status_code
            self.assertEqual(
                code, expected,
                'Expected %s but returned %s for %s (Fedora 500 error)' %
                (expected, code, self.new_coll_url))
            messages = [str(msg) for msg in response.context['messages']]
            self.assert_(
                'error communicating with the repository' in messages[0])

        # update the mock error to generate a permission denied error
        err_resp.status = 401
        err_resp.read.return_value = 'denied'
        # generate Fedora error on object save
        testobj.save.side_effect = PermissionDenied(err_resp)

        # 401 error -  permission denied
        with patch.object(Repository,
                          'get_object',
                          new=Mock(return_value=testobj)):
            response = self.client.post(self.new_coll_url,
                                        test_data,
                                        follow=True)
            expected, code = 401, response.status_code
            self.assertEqual(
                code, expected,
                'Expected %s but returned %s for %s (Fedora 401 error)' %
                (expected, code, self.new_coll_url))
            messages = [str(msg) for msg in response.context['messages']]
            self.assert_("You don't have permission to create a collection" in
                         messages[0])

    def test_get_edit_form(self):
        # not logged in - should redirect to login page
        response = self.client.get(self.edit_coll_url)
        code = response.status_code
        expected = 302
        self.assertEqual(
            code, expected,
            'Expected %s but returned %s for %s as AnonymousUser' %
            (expected, code, self.edit_coll_url))

        # logged in as user without required permissions - should 403
        self.client.post(settings.LOGIN_URL, NONADMIN_CREDENTIALS)
        response = self.client.get(self.edit_coll_url)
        code = response.status_code
        expected = 403
        self.assertEqual(
            code, expected,
            'Expected %s but returned %s for %s as logged in non-repo editor' %
            (expected, code, self.edit_coll_url))

        # log in as repository editor
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)

        # on GET, form should be displayed
        # add oai set values to check form fields are correctly pre-populated
        self.obj.oai_set = 'test:edit'
        self.obj.oai_setlabel = 'the edit subset in the test master set'
        self.obj.save()
        response = self.client.get(self.edit_coll_url)
        expected, code = 200, response.status_code
        self.assertEqual(
            code, expected, 'Expected %s but returned %s for %s' %
            (expected, code, self.edit_coll_url))
        self.assert_(
            isinstance(response.context['form'], CollectionDCEditForm),
            "CollectionDCEditForm should be set in response context")
        self.assertEqual(response.context['form'].instance,
                         self.obj.dc.content)
        self.assertContains(response, 'Update %s' % self.obj.label)

        # oai set values should be set
        self.assertEqual(self.obj.oai_set,
                         response.context['form']['oai_set'].value())
        self.assertEqual(self.obj.oai_setlabel,
                         response.context['form']['oai_set_name'].value())

    def test_valid_edit_form(self):
        # log in as repository editor
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)

        # POST data and update object, verify in fedora
        update_data = {
            'title': 'new title',
            'description': 'new description too',
            'oai_set': 'foo:bar',
            'oai_set_name': 'all of bar in foo',
        }
        response = self.client.post(self.edit_coll_url,
                                    update_data,
                                    follow=True)
        # on success, should redirect with a message about the object
        messages = [str(msg) for msg in response.context['messages']]
        self.assert_('Successfully updated collection' in messages[0],
                     'successful collection update message displayed to user')
        # get a fresh copy of the object to compare
        updated_obj = self.repo_admin.get_object(self.obj.pid,
                                                 type=CollectionObject)
        self.assertEqual(update_data['title'], updated_obj.dc.content.title,
         "posted title should be set in dc:title; expected '%s', got '%s'" % \
                 (update_data['title'], updated_obj.dc.content.title))
        self.assertEqual(update_data['description'], updated_obj.dc.content.description,
                 "posted description should be set in dc:description; expected '%s', got '%s'" % \
                 (update_data['description'], updated_obj.dc.content.description))
        self.assertEqual(update_data['title'], updated_obj.label,
                 "posted title should be set in object label; expected '%s', got '%s'" % \
                 (update_data['title'], updated_obj.label))
        self.assertEqual(
            update_data['oai_set'], updated_obj.oai_set,
            'posted OAI set should be set as OAI setSpec in rels-ext')
        self.assertEqual(
            update_data['oai_set_name'], updated_obj.oai_setlabel,
            'posted OAI set should be set as OAI setName in rels-ext')

        update_data.update({'oai_set': '', 'oai_set_name': ''})
        response = self.client.post(self.edit_coll_url,
                                    update_data,
                                    follow=True)
        # on success, should redirect with a message about the object
        messages = [str(msg) for msg in response.context['messages']]
        self.assert_('Successfully updated collection' in messages[0])
        # get a fresh copy of the object to check oai set values were cleared
        updated_obj = self.repo_admin.get_object(self.obj.pid,
                                                 type=CollectionObject)
        self.assertEqual(
            None, updated_obj.oai_set,
            'OAI setSpec should not be set when no value was posted on the form'
        )
        self.assertEqual(
            None, updated_obj.oai_setlabel,
            'OAI setName should not be set when no value was posted on the form'
        )

    def test_view(self):
        # test viewing an existing collection object

        # not logged in - public access content only for now, should
        # be accessible to anyone
        response = self.client.get(self.view_coll_url)
        code = response.status_code
        expected = 200
        self.assertEqual(
            code, expected,
            'Expected %s but returned %s for %s as AnonymousUser' %
            (expected, code, self.view_coll_url))
        self.assertNotContains(
            response,
            reverse('collection:edit', kwargs={'pid': self.obj.pid}),
            msg_prefix=
            'collection view should not include edit link for non repo editor')

        # logged in as user without required permissions - should still be accessible
        # NOTE: using admin view so user credentials will be used to access fedora
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)
        response = self.client.get(self.view_coll_url)
        code = response.status_code
        expected = 200
        self.assertEqual(
            code, expected,
            'Expected %s but returned %s for %s as logged in non-repo editor' %
            (expected, code, self.view_coll_url))

        # check for object display
        self.assert_(isinstance(response.context['obj'], CollectionObject),
                     'collection object should be set in response context')
        self.assertEqual(
            self.obj.pid, response.context['obj'].pid,
            'correct collection object should be set in response context')

        self.assertContains(
            response,
            self.obj.label,
            msg_prefix='response should include title of collection object')
        self.assertContains(
            response,
            self.obj.dc.content.description,
            msg_prefix=
            'response should include description of collection object')
        self.assertContains(
            response,
            reverse('collection:edit', kwargs={'pid': self.obj.pid}),
            msg_prefix=
            'collection view should include edit link for repo editor')

        # check for links to raw datastreams
        self.assertContains(
            response,
            reverse('collection:raw-ds',
                    kwargs={
                        'pid': self.obj.pid,
                        'dsid': 'DC'
                    }),
            msg_prefix='metadata view should link to raw DC view')
        self.assertContains(
            response,
            reverse('collection:raw-ds',
                    kwargs={
                        'pid': self.obj.pid,
                        'dsid': 'RELS-EXT'
                    }),
            msg_prefix='metadata view should link to raw RELS-EXT view')

    def test_view_nonexistent(self):
        # non-existent object should 404
        view_coll_url = reverse('collection:view',
                                kwargs={'pid': 'bogus:nonexistent-pid'})

        response = self.client.get(view_coll_url)
        code = response.status_code
        expected = 404
        self.assertEqual(
            code, expected,
            'Expected %s but returned %s for %s (nonexistent object)' %
            (expected, code, view_coll_url))

    def test_view_members(self):
        # collection view should include brief listing of items that belong to the collection
        # use mock objects to test collection member view
        testcoll = Mock(spec=CollectionObject, name='MockCollectionObject')
        testcoll.pid = 'coll:1'
        testcoll.label.return_value = 'mock collection'
        testcoll.exists = True
        file1 = Mock(spec=FileObject, name='MockDigitalObject')
        file1.pid = 'file:1'
        file1.label = 'One Fish'
        file2 = Mock(spec=FileObject, name='MockDigitalObject')
        file2.pid = 'file:2'
        file2.label = 'Two Fish'
        testcoll.members = (file1, file2)

        # django templates recognize Mock objects as callables; work around that
        # by setting the objects to return themselves when called
        testcoll.return_value = testcoll
        file1.return_value = file1
        file2.return_value = file2

        # patch the repository class to return the mock object instead of a real one
        with patch.object(Repository,
                          'get_object',
                          new=Mock(return_value=testcoll)):
            response = self.client.get(self.view_coll_url)
            code = response.status_code
            expected = 200
            self.assertEqual(
                code, expected,
                'Expected %s but returned %s for %s as AnonymousUser' %
                (expected, code, self.view_coll_url))

            # FIXME: works in django 1.2.5, not in django 1.3

            # member items should be listed
            self.assertContains(
                response,
                file1.label,
                msg_prefix=
                'collection view should include first member item label')
            self.assertContains(
                response,
                file2.label,
                msg_prefix=
                'collection view should include second member item label')
            self.assertContains(
                response,
                reverse('file:view', kwargs={'pid': file1.pid}),
                msg_prefix=
                'collection view should include link to view first member item'
            )
            self.assertContains(
                response,
                reverse('file:view', kwargs={'pid': file2.pid}),
                msg_prefix=
                'collection view should include link to view second member item'
            )
            self.assertNotContains(
                response,
                reverse('file:edit', kwargs={'pid': file1.pid}),
                msg_prefix=
                'collection view should include link to edit first member item (not repo editor)'
            )
            self.assertNotContains(
                response,
                reverse('file:edit', kwargs={'pid': file2.pid}),
                msg_prefix=
                'collection view should include link to edit second member item (not repo editor)'
            )

        # log in as repo editor - should also see item edit links
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)
        with patch.object(Repository,
                          'get_object',
                          new=Mock(return_value=testcoll)):
            response = self.client.get(self.view_coll_url)
            self.assertContains(
                response,
                reverse('file:edit', kwargs={'pid': file1.pid}),
                msg_prefix=
                'collection view should include link to edit first member item (repo editor)'
            )
            self.assertContains(
                response,
                reverse('file:edit', kwargs={'pid': file2.pid}),
                msg_prefix=
                'collection view should include link to edit second member item (repo editor)'
            )

    def test_list(self):
        # test listing collections

        # not logged in accessible to anyone
        response = self.client.get(self.list_coll_url)
        code = response.status_code
        expected = 200
        self.assertEqual(
            code, expected,
            'Expected %s but returned %s for %s as AnonymousUser' %
            (expected, code, self.view_coll_url))

        #when not logged in no edit link should be present
        self.assertNotContains(
            response,
            reverse('collection:edit', kwargs={'pid': self.obj.pid}),
            msg_prefix=
            'collection list should not include edit link for non repo editor')

        #label should be displayed
        self.assertContains(
            response,
            self.obj.label,
            msg_prefix='response should include title of collection object')

        #login to get edit link
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)
        response = self.client.get(self.view_coll_url)
        code = response.status_code
        expected = 200
        self.assertEqual(
            code, expected,
            'Expected %s but returned %s for %s as logged in non-repo editor' %
            (expected, code, self.view_coll_url))

        #now edit link is available
        self.assertContains(
            response,
            reverse('collection:edit', kwargs={'pid': self.obj.pid}),
            msg_prefix=
            'collection list should include edit link for repo editor')

    def test_raw_xml_datastreams(self):
        # check that raw datastream views are configured correctly
        dc_url = reverse('collection:raw-ds',
                         kwargs={
                             'pid': self.obj.pid,
                             'dsid': 'DC'
                         })
        relsext_url = reverse('collection:raw-ds',
                              kwargs={
                                  'pid': self.obj.pid,
                                  'dsid': 'RELS-EXT'
                              })

        response = self.client.get(dc_url)
        code = response.status_code
        expected = 200
        self.assertEqual(
            code, expected, 'Expected %s but returned %s for GET %s (raw DC)' %
            (expected, code, dc_url))
        self.assertEqual(response.content,
                         self.obj.dc.content.serialize(pretty=True))

        response = self.client.get(relsext_url)
        code = response.status_code
        expected = 200
        self.assertEqual(
            code, expected,
            'Expected %s but returned %s for GET %s (raw RELS-EXT)' %
            (expected, code, relsext_url))
        # may not serialize exactly the same every time
        # simple check to make sure we're getting rdf that looks corretc
        self.assert_('<rdf:RDF' in response.content)
        self.assert_(self.obj.pid in response.content)
コード例 #12
0
    def test_index_details(self):
        repo = Repository()
        for pid in self.pids:
            repo.purge_object(pid)

        #Test with no settings set.
        self.assertRaises(AttributeError, index_config, self.request)

        # Test with only the allowed SOLR url set.
        self.assertRaises(AttributeError, index_config, self.request)

        # Test with this IP not allowed to hit the service.
        #settings.EUL_INDEXER_ALLOWED_IPS = ['0.13.23.134']
        with override_settings(EUL_INDEXER_ALLOWED_IPS=['0.13.23.134']):
            response = index_config(self.request)
            expected, got = 403, response.status_code
            self.assertEqual(expected, got,
                'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))
            expected, got = 'text/html', response['Content-Type']
            self.assertEqual(expected, got,
                'Expected %s but returned %s for mimetype on indexdata/index_details view' \
                % (expected, got))

        # Test with this IP allowed to hit the view.
        with override_settings(
                EUL_INDEXER_ALLOWED_IPS=['0.13.23.134', self.request_ip]):
            response = index_config(self.request)
            expected, got = 200, response.status_code
            self.assertEqual(expected, got,
                'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))
            expected, got = 'application/json', response['Content-Type']
            self.assertEqual(expected, got,
                'Expected %s but returned %s for mimetype on indexdata/index_details view' \
                % (expected, got))
            # load json content so we can inspect the result
            content = simplejson.loads(response.content)
            self.assertEqual(TEST_SOLR_URL, content['SOLR_URL'])
            print '** list of cmodels is ', content['CONTENT_MODELS']
            print '*** looking for ', SimpleObject.CONTENT_MODELS
            self.assert_(
                SimpleObject.CONTENT_MODELS in content['CONTENT_MODELS'])
            self.assert_(LessSimpleDigitalObject.CONTENT_MODELS in
                         content['CONTENT_MODELS'])
            self.assert_(
                ContentModel.CONTENT_MODELS not in content['CONTENT_MODELS'],
                'Fedora system content models should not be included in indexed cmodels by default'
            )

        # Test with the "ANY" setting for allowed IPs
        with override_settings(INDEXER_ALLOWED_IPS='ANY'):
            response = index_config(self.request)
            expected, got = 200, response.status_code
            self.assertEqual(expected, got,
                'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))

        # Test with 'EUL_INDEXER_CONTENT_MODELS' setting configured to override autodetect.
        with override_settings(EUL_INDEXER_CONTENT_MODELS=[[
                'content-model_1', 'content-model_2'
        ], ['content-model_3']]):
            response = index_config(self.request)
            expected, got = 200, response.status_code
            self.assertEqual(expected, got,
                'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))
            expected, got = 'application/json', response['Content-Type']
            self.assertEqual(expected, got,
                'Expected %s but returned %s for mimetype on indexdata/index_details view' \
                % (expected, got))
            # load json content so we can inspect the result
            content = simplejson.loads(response.content)
            self.assertEqual(settings.EUL_INDEXER_CONTENT_MODELS,
                             content['CONTENT_MODELS'])
コード例 #13
0
ファイル: tests.py プロジェクト: emory-libraries/genrepo-demo
class FileViewsTest(TestCase):
    fixtures =  ['users']   # re-using collection users fixture & credentials

    # repository with test credentials for loading & removing test objects
    # DON'T instantiate this at load time, since Fedora Test settings are not yet switched
    repo_admin = None
    
    ingest_fname = os.path.join(settings.BASE_DIR, 'file', 'fixtures', 'hello.txt')
    ingest_md5sum = '746308829575e17c3331bbcb00c0898b'   # md5sum of hello.txt 
    image_fname = os.path.join(settings.BASE_DIR, 'file', 'fixtures', 'test.jpg')
    image_md5sum = 'ef7397e4bde82e558044458045bba96a'   # md5sum of test.jpeg
    
    ingest_url = reverse('file:ingest')

    # required django form management metadata for formsets on DC edit form
    edit_mgmt_data = {}
    for field in ['creator', 'contributor', 'coverage', 'relation', 'subject']:
        edit_mgmt_data['%s_list-MAX_NUM_FORMS' % field] = ''
        edit_mgmt_data['%s_list-INITIAL_FORMS' % field] = 0
        edit_mgmt_data['%s_list-TOTAL_FORMS' % field] = 0
    

    def setUp(self):
        # instantiate repo_admin the first time we run, after the test settings are in place
        if self.repo_admin is None:
            self.repo_admin = Repository(username=getattr(settings, 'FEDORA_TEST_USER', None),
                                         password=getattr(settings, 'FEDORA_TEST_PASSWORD', None))

        self.client = Client()

        # create a file object to edit
        with open(self.ingest_fname) as ingest_f:
            self.obj = self.repo_admin.get_object(type=FileObject)
            self.obj.dc.content.title =  self.obj.label = 'Test file object'
            self.obj.dc.content.date =  '2011'
            self.obj.master.content = ingest_f
            self.obj.master.label = 'hello-world.txt'
            self.obj.master.checksum = self.ingest_md5sum
            self.obj.save()
        self.edit_url = reverse('file:edit', kwargs={'pid': self.obj.pid})
        self.download_url = reverse('file:download', kwargs={'pid': self.obj.pid})
        self.view_url = reverse('file:view', kwargs={'pid': self.obj.pid})

        # create a image object for testing
        with open(self.image_fname) as ingest_f:
            self.imgobj = self.repo_admin.get_object(type=FileObject)
            self.imgobj.dc.content.title =  self.imgobj.label = 'Test file object'
            self.imgobj.master.content = ingest_f
            self.imgobj.master.label = 'test.jpg'
            self.imgobj.master.checksum = self.image_md5sum
            self.imgobj.save()

        self.pids = [self.obj.pid, self.imgobj.pid]

    def tearDown(self):
        for pid in self.pids:
            self.repo_admin.purge_object(pid)

    # ingest

    def test_get_ingest_form(self):
        # not logged in - should redirect to login page
        response = self.client.get(self.ingest_url)
        code = response.status_code
        expected = 302
        self.assertEqual(code, expected, 'Expected %s but returned %s for %s as AnonymousUser'
                             % (expected, code, self.ingest_url))

        # logged in as user without required permissions - should 403
        self.client.login(**NONADMIN_CREDENTIALS)
        response = self.client.get(self.ingest_url)
        code = response.status_code
        expected = 403
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for GET %s as logged in non-repo editor'
                         % (expected, code, self.ingest_url))

        # log in as repository editor 
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)
        # on GET, form should be displayed
        response = self.client.get(self.ingest_url)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(isinstance(response.context['form'], IngestForm))

        # collection URI passed in via GET should be pre-selected
        collections = IngestForm().fields['collection'].choices
        collection_tuple = collections[1] # 0 is blank. 1 is the first non-blank one
        collection_uri = collection_tuple[0]
        response = self.client.get(self.ingest_url, {'collection': collection_uri})
        self.assertEqual(collection_uri, response.context['form'].initial['collection'],
                         'collection URI specified in GET url parameter should be set as initial value')

    def test_incomplete_ingest_form(self):
        # not logged in - should redirect to login page
        response = self.client.post(self.ingest_url)
        code = response.status_code
        expected = 302
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for POST %s as AnonymousUser'
                         % (expected, code, self.ingest_url))

        # logged in as user without required permissions - should 403
        self.client.login(**NONADMIN_CREDENTIALS)
        response = self.client.post(self.ingest_url)
        code = response.status_code
        expected = 403
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for POST %s as logged in non-repo editor'
                         % (expected, code, self.ingest_url))

        # log in as repository editor for normal behavior
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)


        # on POST with incomplete data, should be rejected
        response = self.client.post(self.ingest_url, {
                'collection': 'info:fedora/example:42',
            })
        self.assertTrue(isinstance(response.context['form'], IngestForm))
        self.assertContains(response, 'This field is required')

    def test_correct_ingest_form(self):
        # log in as repository editor for normal behavior
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)
        
        # first find a valid collection
        collections = IngestForm().fields['collection'].choices
        collection_tuple = collections[1] # 0 is blank. 1 is the first non-blank one
        collection_uri = collection_tuple[0]

        # log in
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)

        # on POST, ingest object
        with open(self.ingest_fname) as ingest_f:
            response = self.client.post(self.ingest_url, {
                'collection': collection_uri,
                'file': ingest_f,
            }, follow=True)
        self.assertEqual(len(response.redirect_chain), 1)
        self.assertEqual(response.redirect_chain[0][1], 303)
        self.assertEqual(response.status_code, 200)
        messages = [ str(msg) for msg in response.context['messages'] ]
        self.assertTrue('Successfully ingested' in messages[0])
        pid = re.search('<b>(.*)</b>', messages[0]).group(1)
        self.pids.append(pid)

        # inspect the ingested object
        new_obj = self.repo_admin.get_object(pid, type=FileObject)
        self.assertTrue(new_obj.has_requisite_content_models)
        statement = (new_obj.uriref, relsext.isMemberOfCollection, URIRef(collection_uri))
        self.assertTrue(statement in new_obj.rels_ext.content,
                        msg='RELS-EXT should have collection statement')
        self.assertEqual('hello.txt', new_obj.label,
                         msg='filename should be set as preliminary object label')
        self.assertEqual('hello.txt', new_obj.dc.content.title,
                         msg='filename should be set as preliminary dc:title')
        self.assertEqual('hello.txt', new_obj.master.label,
                         msg='filename should be set as master datastream label')
        with open(self.ingest_fname) as ingest_f:
            self.assertEqual(new_obj.master.content.read(), ingest_f.read())
        # confirm that current site user appears in fedora audit trail
        xml, uri = new_obj.api.getObjectXML(pid)
        self.assert_('<audit:responsibility>%s</audit:responsibility>' % \
                     ADMIN_CREDENTIALS['username'] in xml)

        # supported image file should be ingested as ImageObject
        with open(self.image_fname) as ingest_f:
            response = self.client.post(self.ingest_url, {
                'collection': collection_uri,
                'file': ingest_f,
            }, follow=True)
        self.assertEqual(response.status_code, 200)
        messages = [ str(msg) for msg in response.context['messages'] ]
        self.assertTrue('Successfully ingested' in messages[0])
        pid = re.search('<b>(.*)</b>', messages[0]).group(1)
        self.pids.append(pid)
        
        # check that the object was ingested as an Image
        img_obj = self.repo_admin.get_object(pid, type=ImageObject)
        self.assertTrue(img_obj.has_requisite_content_models)


    # edit metadata

    def test_get_edit_form(self):
        # not logged in - should redirect to login page
        response = self.client.get(self.edit_url)
        code = response.status_code
        expected = 302
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for GET %s as AnonymousUser'
                         % (expected, code, self.edit_url))

        # logged in as user without required permissions - should 403
        self.client.login(**NONADMIN_CREDENTIALS)
        response = self.client.get(self.edit_url)
        code = response.status_code
        expected = 403
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for GET %s as logged in non-repo editor'
                         % (expected, code, self.edit_url))

        # log in as repository editor 
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)
        # on GET, form should be displayed with object data pre-populated
        response = self.client.get(self.edit_url)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(isinstance(response.context['form'], DublinCoreEditForm))
        self.assertContains(response, self.obj.label,
                            msg_prefix='edit form should include object label')
        self.assertContains(response, self.obj.dc.content.date,
                            msg_prefix='edit form should include DC content such as date')
        # enable_oai should be false
        self.assertFalse(response.context['form']['enable_oai'].value())
        # master ds label should be set as filename
        self.assertEqual(self.obj.master.label, response.context['form']['file_name'].value(),
            'master datastream label should be pre-populated as filename in the form')

        # enable_oai set based on presence of oai id
        self.obj.oai_id = 'oai:foo'
        self.obj.save()
        response = self.client.get(self.edit_url)
        # enable_oai should be true
        self.assertTrue(response.context['form']['enable_oai'].value()) 

    def test_edit_invalid_form(self):
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)
        
        # POST invalid data (missing required title field)
        data = self.edit_mgmt_data.copy()
        data.update({'descrition': 'test'})
        response = self.client.post(self.edit_url, data)
        self.assertTrue(isinstance(response.context['form'], DublinCoreEditForm))
        self.assertContains(response, 'This field is required')


    def test_edit_valid_form(self):
        # not logged in - should redirect to login page
        response = self.client.post(self.edit_url)
        code = response.status_code
        expected = 302
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for POST %s as AnonymousUser'
                         % (expected, code, self.edit_url))

        # logged in as user without required permissions - should 403
        self.client.login(**NONADMIN_CREDENTIALS)
        response = self.client.post(self.edit_url)
        code = response.status_code
        expected = 403
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for POST %s as logged in non-repo editor'
                         % (expected, code, self.edit_url))

        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)

        # valid form
        new_data = self.edit_mgmt_data.copy()
        subjects = ['test', 'repositories']
        new_data.update({'title': 'updated file object', 'description': 'test content',
                         'creator_list-TOTAL_FORMS': 1, 'creator_list-0-val': 'genrepo',
                         'subject_list-TOTAL_FORMS': 2, 'subject_list-0-val': subjects[0],
                         'subject_list-1-val': subjects[1],
                         'enable_oai': True,
                         'file_name': 'hello.txt'
                         })
        response = self.client.post(self.edit_url, new_data, follow=True)
        messages = [ str(msg) for msg in response.context['messages'] ]
        self.assertTrue('Successfully updated' in messages[0])

        # inspect the updated object
        updated_obj = self.repo_admin.get_object(self.obj.pid, type=FileObject)
        self.assertEqual(new_data['title'], updated_obj.label,
            msg='posted title should be set as object label; expected %s, got %s' % \
                         (new_data['title'], updated_obj.label))
        self.assertEqual(new_data['title'], updated_obj.dc.content.title,
            msg='posted title should be set as dc:title; expected %s, got %s' % \
                         (new_data['title'], updated_obj.dc.content.title))
        self.assertEqual(new_data['description'], updated_obj.dc.content.description,
            msg='posted description should be set as dc:description; expected %s, got %s' % \
                         (new_data['description'], updated_obj.dc.content.description))
        self.assertEqual(new_data['creator_list-0-val'], updated_obj.dc.content.creator,
            msg='posted creator should be set as dc:creator; expected %s, got %s' % \
                         (new_data['creator_list-0-val'], updated_obj.dc.content.creator))
        self.assertEqual(2, len(updated_obj.dc.content.subject_list),
            msg='expected 2 subjects after posting 2 subject_list values, got %d' % \
                         len(updated_obj.dc.content.subject_list))
        self.assertEqual(subjects, updated_obj.dc.content.subject_list)
        self.assertNotEqual(None, updated_obj.oai_id)
        self.assertEqual(new_data['file_name'], updated_obj.master.label,
            msg='posted file name should be set as master datastream label; expected %s, got %s' % \
                         (new_data['file_name'], updated_obj.master.label))


        # remove oai item id
        new_data.update({'enable_oai': False})
        response = self.client.post(self.edit_url, new_data, follow=True)
        messages = [ str(msg) for msg in response.context['messages'] ]
        self.assertTrue('Successfully updated' in messages[0])
        # inspect the updated object
        updated_obj = self.repo_admin.get_object(self.obj.pid, type=FileObject)
        self.assertEqual(None, updated_obj.oai_id)


    def test_edit_save_errors(self):
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)
        data = self.edit_mgmt_data.copy()
        data.update({'title': 'foo', 'description': 'bar', 'creator': 'baz', 'file_name': 'foo.txt'})
        # simulate fedora errors with mock objects
        testobj = Mock(spec=FileObject, name='MockDigitalObject')
        # django templates recognize this as a callable; set to return itself when called
        testobj.return_value = testobj
        # create a Mock object, but use a DublinCore instance for xmlobjectform to inspect
        testobj.dc.content = DublinCore()
        testobj.pid = 'pid:1'	# required for url generation 
        # Create a RequestFailed exception to simulate Fedora error 
        # - eulcore.fedora wrap around an httplib response
        err_resp = Mock()
        err_resp.status = 500
   	err_resp.read.return_value = 'error message'
        # generate Fedora error on object save
        testobj.save.side_effect = RequestFailed(err_resp)

        # 500 error / request failed
        # patch the repository class to return the mock object instead of a real one
	#with patch.object(Repository, 'get_object', new=Mock(return_value=testobj)):
        with patch('genrepo.file.views.init_by_cmodel', new=Mock(return_value=testobj)):            
            response = self.client.post(self.edit_url, data, follow=True)
            expected, code = 500, response.status_code
            self.assertEqual(code, expected,
            	'Expected %s but returned %s for %s (Fedora 500 error)'
                % (expected, code, self.edit_url))
            messages = [ str(msg) for msg in response.context['messages'] ]
            self.assert_('error communicating with the repository' in messages[0])

        # update the mock object to generate a permission denied error
        err_resp.status = 401
        err_resp.read.return_value = 'denied'
        # generate Fedora error on object save
        testobj.save.side_effect = PermissionDenied(err_resp)
        
        # 401 error -  permission denied
	#with patch.object(Repository, 'get_object', new=Mock(return_value=testobj)):            
        with patch('genrepo.file.views.init_by_cmodel', new=Mock(return_value=testobj)):
            response = self.client.post(self.edit_url, data, follow=True)
            expected, code = 401, response.status_code
            self.assertEqual(code, expected,
            	'Expected %s but returned %s for %s (Fedora 401 error)'
                % (expected, code, self.edit_url))
            messages = [ str(msg) for msg in response.context['messages'] ]
            self.assert_("You don't have permission to modify this object"
                         in messages[0])

    def test_download_master(self):
        response = self.client.get(self.download_url)
        code = response.status_code
        expected = 200
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for GET %s as AnonymousUser'
                         % (expected, code, self.download_url))
        expected = 'attachment; filename=%s' % self.obj.master.label
        self.assertEqual(response['Content-Disposition'], expected,
                        "Expected '%s' but returned '%s' for %s content disposition" % \
                        (expected, response['Content-Disposition'], self.download_url))
        with open(self.ingest_fname) as ingest_f:        
            self.assertEqual(ingest_f.read(), response.content,
                'download response content should be equivalent to file ingested as master datastream')

        # test image object (different datastraem)
        img_download_url = reverse('file:download', kwargs={'pid': self.imgobj.pid})
        response = self.client.get(img_download_url)
        code = response.status_code
        expected = 200
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for GET %s as AnonymousUser'
                         % (expected, code, img_download_url))
        expected = 'attachment; filename=%s' % self.imgobj.master.label
        self.assertEqual(response['Content-Disposition'], expected,
                        "Expected '%s' but returned '%s' for %s content disposition" % \
                        (expected, response['Content-Disposition'], img_download_url))
        with open(self.image_fname) as ingest_f:        
            self.assertEqual(ingest_f.read(), response.content,
                'download response content should be equivalent to file ingested as master datastream')
            
        # errors not tested here because they should be handled by eulcore view

    def test_view_metadata_min(self):
        # view metadata - minimal fields present
        response = self.client.get(self.view_url)
        code = response.status_code
        expected = 200
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for GET %s as AnonymousUser'
                         % (expected, code, self.view_url))
        
        dc = self.obj.dc.content
        self.assertContains(response, dc.title)
        self.assertNotContains(response, 'Creator',
            msg_prefix='metadata view should not include creator when not set in dc')
        self.assertNotContains(response, 'Contributor',
            msg_prefix='metadata view should not include contributor when not set in dc')
        self.assertNotContains(response, 'Coverage:',
            msg_prefix='metadata view should not include coverage when not set in dc')
        self.assertNotContains(response, 'Language:',
            msg_prefix='metadata view should not include language when not set in dc')
        self.assertNotContains(response, 'Publisher:',
            msg_prefix='metadata view should not include publisher when not set in dc')
        self.assertNotContains(response, 'Source',
            msg_prefix='metadata view should not include source when not set in dc')
        self.assertNotContains(response, 'Type:',
            msg_prefix='metadata view should not include type when not set in dc')
        self.assertNotContains(response, 'Format:',
            msg_prefix='metadata view should not include format when not set in dc')
        self.assertContains(response, 'Date:')
        self.assertContains(response, dc.date)

        # check for links to raw datastreams
        self.assertContains(response, reverse('file:raw-ds', kwargs={'pid': self.obj.pid, 'dsid': 'DC'}),
            msg_prefix='metadata view should link to raw DC view')
        self.assertContains(response, reverse('file:raw-ds', kwargs={'pid': self.obj.pid, 'dsid': 'RELS-EXT'}),
            msg_prefix='metadata view should link to raw RELS-EXT view')


    def test_view_metadata_full(self):        
        # update test object metadata to test template display with full fields
        self.obj.dc.content.description =  'Some explanatory text'
        self.obj.dc.content.creator_list =  ['You', 'Me']
        self.obj.dc.content.contributor_list =  ['Them']
        self.obj.dc.content.coverage_list =  ['20th Century', 'Earth']
        self.obj.dc.content.language =  'English'
        self.obj.dc.content.publisher =  'EUL'
        self.obj.dc.content.relation =  'Part of Collection Foo'
        self.obj.dc.content.source =  'the ether'
        self.obj.dc.content.subject_list =  ['testing', 'generals', 'repositories']
        self.obj.dc.content.type =  'Text'
        self.obj.dc.content.format =  'text/plain'
        self.obj.dc.content.identifier =  'foo1'
        self.obj.save('adding DC content to test metadata view')
        
        response = self.client.get(self.view_url)
        code = response.status_code
        expected = 200
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for GET %s as AnonymousUser'
                         % (expected, code, self.view_url))

        dc = self.obj.dc.content
        self.assertContains(response, dc.description)
        self.assertContains(response, 'Creators:')
        self.assertContains(response, dc.creator_list[0])
        self.assertContains(response, dc.creator_list[1])
        self.assertContains(response, 'Contributor:')
        self.assertContains(response, dc.contributor_list[0])
        self.assertContains(response, 'Coverage:')
        self.assertContains(response, dc.coverage_list[0])
        self.assertContains(response, dc.coverage_list[1])
        self.assertContains(response, 'Language:')
        self.assertContains(response, dc.language)
        self.assertContains(response, 'Publisher:')
        self.assertContains(response, dc.publisher)
        self.assertContains(response, 'Source:')
        self.assertContains(response, dc.source)
        self.assertContains(response, 'Type:')
        self.assertContains(response, dc.type)
        self.assertContains(response, 'Format:')
        self.assertContains(response, dc.format)
        self.assertContains(response, 'Date:')
        self.assertContains(response, dc.date)

    def test_view_metadata_notfound(self):
        view_url = reverse('file:view', kwargs={'pid': 'bogus:123'})

        response = self.client.get(view_url)
        code = response.status_code
        expected = 404
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for GET %s (invalid pid) as AnonymousUser'
                         % (expected, code, view_url))

    def test_raw_xml_datastreams(self):
        # check that raw datastream views are configured correctly
        dc_url = reverse('file:raw-ds', kwargs={'pid': self.obj.pid, 'dsid': 'DC'})
        relsext_url = reverse('file:raw-ds', kwargs={'pid': self.obj.pid, 'dsid': 'RELS-EXT'})
        
        response = self.client.get(dc_url)
        code = response.status_code
        expected = 200
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for GET %s (raw DC)'
                         % (expected, code, dc_url))
        self.assertEqual(response.content, self.obj.dc.content.serialize(pretty=True))

        response = self.client.get(relsext_url)
        code = response.status_code
        expected = 200
        self.assertEqual(code, expected,
                         'Expected %s but returned %s for GET %s (raw RELS-EXT)'
                         % (expected, code, relsext_url))
        # may not serialize exactly the same every time
        # simple check to make sure we're getting rdf that looks corretc
        self.assert_('<rdf:RDF' in response.content)
        self.assert_(self.obj.pid in response.content)
コード例 #14
0
def tearDownModule():
    global postcards
    repo = Repository()
    for p in postcards:
        repo.purge_object(p.pid)
コード例 #15
0
    pids_to_delete.append(etd.pid)
    pid_report.append(etd.related())

    for r in etd.get_related_pids():
        related = etd = repo.get_object(r, type=RelatedRecord)
        if related.check():
            pids_to_delete.append(related.pid)
        else:
            print(related.pid + ' is related to multiple ETDs.')

pp.pprint(pid_report)

if not args['no_action']:
    print(str(len(pids_to_delete)) + ' will be purged.')
    raw_input("Press Enter to continue...")

    for bad_pid in pids_to_delete:
        # TODO add error handeling for a pid that might have already been deleted.
        ark = bad_pid.split(':')[1]
        # Important: we must deactive ark first. Otherwise we'll get a 404 on the uri.
        #try:
        #    client.update_target(type="ark", noid=ark, active=False)
        #except requests.exceptions.HTTPError:
        #    pass
        
        try:
            repo.purge_object(bad_pid)
        except eulfedora.util.RequestFailed:
            pass
コード例 #16
0
ファイル: test_views.py プロジェクト: rrockenbaugh/eulfedora
    def test_index_details(self):
        repo = Repository()
        for pid in self.pids:
            repo.purge_object(pid)

        # Test with no settings set.
        # - should be denied
        response = index_config(self.request)
        self.assertEqual(
            403, response.status_code,
            'index data should be forbidden if no IPs are configured to access'
        )

        # NOTE: these aren't meaningful errors anyway, and settings
        # are now being pulled from somewhere so they fail
        # self.assertRaises(AttributeError, index_config, self.request)
        # Test with only the allowed SOLR url set.
        # self.assertRaises(AttributeError, index_config, self.request)

        # Test with this IP not allowed to hit the service.
        # settings.EUL_INDEXER_ALLOWED_IPS = ['0.13.23.134']
        with override_settings(EUL_INDEXER_ALLOWED_IPS=['0.13.23.134']):
            response = index_config(self.request)
            expected, got = 403, response.status_code
            self.assertEqual(expected, got,
                'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))
            expected, got = 'text/html', response['Content-Type']
            self.assertEqual(expected, got,
                'Expected %s but returned %s for mimetype on indexdata/index_details view' \
                % (expected, got))

        # Test with this IP allowed to hit the view.
        with override_settings(
                EUL_INDEXER_ALLOWED_IPS=['0.13.23.134', self.request_ip]):
            response = index_config(self.request)
            expected, got = 200, response.status_code
            self.assertEqual(expected, got,
                'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))
            expected, got = 'application/json', response['Content-Type']
            self.assertEqual(expected, got,
                'Expected %s but returned %s for mimetype on indexdata/index_details view' \
                % (expected, got))
            # load json content so we can inspect the result
            content = json.loads(response.content.decode('utf-8'))
            self.assertEqual(TEST_SOLR_URL, content['SOLR_URL'])
            self.assert_(
                SimpleObject.CONTENT_MODELS in content['CONTENT_MODELS'])
            self.assert_(LessSimpleDigitalObject.CONTENT_MODELS in
                         content['CONTENT_MODELS'])
            self.assert_(
                ContentModel.CONTENT_MODELS not in content['CONTENT_MODELS'],
                'Fedora system content models should not be included in indexed cmodels by default'
            )

        # Test with the "ANY" setting for allowed IPs
        with override_settings(EUL_INDEXER_ALLOWED_IPS='ANY'):
            response = index_config(self.request)
            expected, got = 200, response.status_code
            self.assertEqual(expected, got,
                'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))

        # Test with 'EUL_INDEXER_CONTENT_MODELS' setting configured to override autodetect.
        with override_settings(EUL_INDEXER_ALLOWED_IPS='ANY',
                               EUL_INDEXER_CONTENT_MODELS=[[
                                   'content-model_1', 'content-model_2'
                               ], ['content-model_3']]):
            response = index_config(self.request)
            expected, got = 200, response.status_code
            self.assertEqual(expected, got,
                'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))
            expected, got = 'application/json', response['Content-Type']
            self.assertEqual(expected, got,
                'Expected %s but returned %s for mimetype on indexdata/index_details view' \
                % (expected, got))
            # load json content so we can inspect the result
            content = json.loads(response.content.decode('utf-8'))
            self.assertEqual(settings.EUL_INDEXER_CONTENT_MODELS,
                             content['CONTENT_MODELS'])
コード例 #17
0
 def handle(self, *args, **kwargs):
     verbosity = kwargs.get('verbosity', self.v_normal)
     repo = Repository()
     video_duplicates = repo.find_objects(type=Video, label="DELETE")
     for pid in video_duplicates:
         repo.purge_object(pid.pid)
コード例 #18
0
class FedoraStorage(base.BaseStorage):
    """Fedora Commons repository storage."""

    configform = ConfigForm
    defaults = dict(
            root=getattr(settings, "FEDORA_ROOT", ""),
            username=getattr(settings, "FEDORA_USER", ""),
            password=getattr(settings, "FEDORA_PASS", ""),
            namespace=getattr(settings, "FEDORA_PIDSPACE", ""),
            image_name=getattr(settings, "FEDORA_IMAGE_NAME", ""),
            transcript_name=getattr(settings, "FEDORA_TRANSCRIPT_NAME", "")
    )

    def __init__(self, *args, **kwargs):
        super(FedoraStorage, self).__init__(*args, **kwargs)
        self.namespace = kwargs["namespace"]
        self.image_name = kwargs["image_name"]
        self.thumbnail_name = "THUMBNAIL"
        self.binary_name = "BINARY"
        self.script_name = "OCR_SCRIPT"
        self.transcript_name = kwargs["transcript_name"]

        self.repo = Repository(
                root=kwargs["root"], username=kwargs["username"],
                password=kwargs["password"])

        self.model = type("Document", (DigitalObject,), {
            "default_pidspace": kwargs["namespace"],
            "FILE_CONTENT_MODEL": "info:fedora/genrepo:File-1.0",
            "CONTENT_MODELS":     ["info:fedora/genrepo:File-1.0"],
            "image": FileDatastream(self.image_name, "Document image", defaults={
              'versionable': True,
            }),
            "binary": FileDatastream(self.binary_name, "Document image binary", defaults={
              'versionable': True,
            }),
            "thumbnail": FileDatastream(self.thumbnail_name, "Document image thumbnail", defaults={
              'versionable': True,
            }),
            "script": FileDatastream(self.script_name, "OCR Script", defaults={
                "versionable": True,
            }),
            "transcript": FileDatastream(self.transcript_name, "Document transcript", defaults={
                "versionable": True,
            }),
            "meta": FileDatastream("meta", "Document metadata", defaults={
                "versionable": False,
            }),
        })

    def read_metadata(self, doc):
        meta = doc._doc.meta.content
        if hasattr(meta, "read"):
            meta = meta.read()
        if not meta:
            return {}
        return dict([v.strip().split("=") for v in \
                meta.split("\n") if re.match("^\w+=[^=]+$", v.strip())])

    def write_metadata(self, doc, **kwargs):
        meta = self.read_metadata(doc)
        meta.update(kwargs)
        metacontent = [u"%s=%s" % (k, v) for k, v in meta.iteritems()]
        doc._doc.meta.content = "\n".join(metacontent)

    def attr_uri(self, doc, attr):
        """URI for image datastream."""
        return "%sobjects/%s/datastreams/%s/content" % (
                self.repo.fedora_root,
                urllib.quote(doc.pid),
                getattr(self, "%s_name" % attr)
        )

    def document_label(self, doc):
        """Get the document label."""
        return doc._doc.label

    def document_attr_empty(self, doc, attr):
        """Check if document attr is empty."""
        return getattr(doc._doc, attr).info.size == 0

    def document_attr_label(self, doc, attr):
        """Get label for an image type attribute."""
        return getattr(doc._doc, attr).label

    def document_attr_mimetype(self, doc, attr):
        """Get mimetype for an image type attribute."""
        return getattr(doc._doc, attr).mimetype

    def document_attr_content_handle(self, doc, attr):
        """Get content for an image type attribute."""
        handle = getattr(doc._doc, attr).content
        return StringIO() if handle is None else handle

    def document_metadata(self, doc):
        """Get document metadata. This currently
        just exposes the DC stream attributes."""                
        return self.read_metadata(doc)

    def _set_document_ds_content(self, doc, dsattr, content):
        docattr = getattr(doc._doc, dsattr)
        #checksum = hashlib.md5(content.read()).hexdigest()
        #content.seek(0)
        #docattr.checksum = checksum
        #docattr.checksum_type = "MD5"
        docattr.content = content

    def set_document_attr_content(self, doc, attr, content):
        """Set image content."""
        self._set_document_ds_content(doc, attr, content)

    def set_document_attr_mimetype(self, doc, attr, mimetype):
        """Set image mimetype."""
        getattr(doc._doc, attr).mimetype = mimetype
    
    def set_document_attr_label(self, doc, attr, label):
        """Set image label."""
        getattr(doc._doc, attr).label = label

    def set_document_label(self, doc, label):
        """Set document label."""
        doc._doc.label = label

    def set_document_metadata(self, doc, **kwargs):
        """Set arbitrary document metadata."""
        self.write_metadata(doc, kwargs)

    def save_document(self, doc):
        """Save document."""
        doc._doc.save()

    def create_document(self, label):
        """Get a new document object"""
        dobj = self.repo.get_object(type=self.model)
        dobj.label = label
        dobj.meta.label = "Document Metadata"
        dobj.meta.mimetype = "text/plain"
        doc = FedoraDocument(dobj, self)
        return doc

    def get(self, pid):
        """Get an object by id."""
        doc = self.repo.get_object(pid, type=self.model)
        if doc:
            return FedoraDocument(doc, self)

    def delete(self, doc, msg=None):
        """Delete an object."""
        self.repo.purge_object(doc.pid, log_message=msg)

    def list(self, namespace=None):
        """List documents in the repository."""
        ns = namespace if namespace is not None else self.namespace
        return [FedoraDocument(d, self) \
                for d in self.repo.find_objects("%s:*" % ns, type=self.model)]
        
    def list_pids(self, namespace=None):
        """List of pids.  This unforunately involves calling
        list(), so it not a quicker alternative."""
        return [doc.pid for doc in self.list()]
コード例 #19
0
ファイル: test_views.py プロジェクト: jrhoads/eulfedora
    def test_index_details(self):
        repo = Repository()
        for pid in self.pids:
            repo.purge_object(pid)

        #Test with no settings set.
        self.assertRaises(AttributeError, index_config, self.request)

        #Test with only the allowed SOLR url set.
        solr_url = 'http://localhost:5555'
        settings.SOLR_SERVER_URL = solr_url
        self.assertRaises(AttributeError, index_config, self.request)


        #Test with this IP not allowed to hit the service.
        settings.EUL_INDEXER_ALLOWED_IPS = ['0.13.23.134']
        response = index_config(self.request)
        expected, got = 403, response.status_code
        self.assertEqual(expected, got,
            'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))
        expected, got = 'text/html', response['Content-Type']
        self.assertEqual(expected, got,
            'Expected %s but returned %s for mimetype on indexdata/index_details view' \
                % (expected, got))
        

        #Test with this IP allowed to hit the view.
        settings.EUL_INDEXER_ALLOWED_IPS = ['0.13.23.134', self.request_ip]
        response = index_config(self.request)
        expected, got = 200, response.status_code
        self.assertEqual(expected, got,
            'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))
        expected, got = 'application/json', response['Content-Type']
        self.assertEqual(expected, got,
            'Expected %s but returned %s for mimetype on indexdata/index_details view' \
                % (expected, got))
        # load json content so we can inspect the result
        content = simplejson.loads(response.content)
        self.assertEqual(solr_url, content['SOLR_URL'])
        self.assert_(SimpleDigitalObject.CONTENT_MODELS in content['CONTENT_MODELS'])
        self.assert_(LessSimpleDigitalObject.CONTENT_MODELS in content['CONTENT_MODELS'])
        self.assert_(ContentModel.CONTENT_MODELS not in content['CONTENT_MODELS'],
                     'Fedora system content models should not be included in indexed cmodels by default')

        #Test with the "ANY" setting for allowed IPs
        settings.INDEXER_ALLOWED_IPS = 'ANY'
        response = index_config(self.request)
        expected, got = 200, response.status_code
        self.assertEqual(expected, got,
            'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))

        #Test with 'EUL_INDEXER_CONTENT_MODELS' setting configured to override autodetect.
        settings.EUL_INDEXER_CONTENT_MODELS = [['content-model_1', 'content-model_2'], ['content-model_3']]
        response = index_config(self.request)
        expected, got = 200, response.status_code
        self.assertEqual(expected, got,
            'Expected %s but returned %s for indexdata/index_details view' \
                % (expected, got))
        expected, got = 'application/json', response['Content-Type']
        self.assertEqual(expected, got,
            'Expected %s but returned %s for mimetype on indexdata/index_details view' \
                % (expected, got))
        # load json content so we can inspect the result
        content = simplejson.loads(response.content)
        self.assertEqual(settings.EUL_INDEXER_CONTENT_MODELS, content['CONTENT_MODELS'])