Пример #1
0
    def test_02_classification_required(self):
        # Check we can mark an application 'completed' with a subject classification present
        in_progress_application = models.Suggestion(**ApplicationFixtureFactory.make_application_source())
        in_progress_application.set_application_status(constants.APPLICATION_STATUS_IN_PROGRESS)

        fc = formcontext.ApplicationFormFactory.get_form_context(role='associate_editor', source=in_progress_application)

        # Make changes to the application status via the form, check it validates
        fc.form.application_status.data = constants.APPLICATION_STATUS_COMPLETED

        assert fc.validate()

        # Without a subject classification, we should not be able to set the status to 'completed'
        no_class_application = models.Suggestion(**ApplicationFixtureFactory.make_application_source())
        del no_class_application.data['bibjson']['subject']
        fc = formcontext.ApplicationFormFactory.get_form_context(role='associate_editor', source=no_class_application)
        # Make changes to the application status via the form
        assert fc.source.bibjson().subjects() == []
        fc.form.application_status.data = constants.APPLICATION_STATUS_COMPLETED

        assert not fc.validate()

        # However, we should be able to set it to a different status rather than 'completed'
        fc.form.application_status.data = constants.APPLICATION_STATUS_PENDING

        assert fc.validate()
Пример #2
0
    def test_03_classification_required(self):
        # Check we can accept an application with a subject classification present
        ready_application = models.Suggestion(**ApplicationFixtureFactory.make_application_source())
        ready_application.set_application_status(constants.APPLICATION_STATUS_READY)

        fc = formcontext.ApplicationFormFactory.get_form_context(role='admin', source=ready_application)

        # Make changes to the application status via the form, check it validates
        fc.form.application_status.data = constants.APPLICATION_STATUS_ACCEPTED

        assert fc.validate()

        # Without a subject classification, we should not be able to set the status to 'accepted'
        no_class_application = models.Suggestion(**ApplicationFixtureFactory.make_application_source())
        del no_class_application.data['bibjson']['subject']
        fc = formcontext.ApplicationFormFactory.get_form_context(role='admin', source=no_class_application)
        # Make changes to the application status via the form
        assert fc.source.bibjson().subjects() == []
        fc.form.application_status.data = constants.APPLICATION_STATUS_ACCEPTED

        assert not fc.validate()

        # However, we should be able to set it to a different status rather than 'accepted'
        fc.form.application_status.data = constants.APPLICATION_STATUS_IN_PROGRESS

        assert fc.validate()
Пример #3
0
    def test_08_publisher_result_filter(self):
        apsrc_admin = ApplicationFixtureFactory.make_application_source()['admin']
        # Not all of these properties are applicable to applications, but these test objects are not applications:
        # they are made-up admin sections designed solely to test whether the filter lets the right keys through.
        # We just use applications as a base to construct them.
        apsrc_admin['ticked'] = True
        apsrc_admin['in_doaj'] = True
        apsrc_admin['related_applications'] = [1,2,3]
        apsrc_admin['current_application'] = 'abcde'

        allowed = ["ticked", "seal", "in_doaj", "related_applications", "current_application", "current_journal", "application_status"]
        forbidden = ['notes', 'contact', 'editor_group', 'editor', 'related_journal']

        res = {
            "hits": {
                "hits": [
                    { "_type": "article", "_source": { "admin": deepcopy(apsrc_admin), "bibjson": {}}},
                    { "_type": "article", "_source": { "admin": deepcopy(apsrc_admin), "bibjson": {}}},
                    { "_type": "article", "_source": { "admin": deepcopy(apsrc_admin), "bibjson": {}}}
                ],
                "total": 3
            }
        }

        newres = query_filters.publisher_result_filter(res)

        for n, r in enumerate(newres['hits']['hits']):
            for allowed_k in allowed:
                assert allowed_k in r['_source']['admin'], \
                    '{} key not found in result {}, but it is allowed and should have been left intact by the filter'.format(allowed_k, n)
            for forbidden_k in forbidden:
                assert forbidden_k not in r['_source']['admin'], \
                    '{} key was found in result {}, but it is forbidden and should have been stripped out by the filter'.format(forbidden_k, n)
Пример #4
0
    def test_15_create_application_update_request_dryrun(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")
        account.add_role("publisher")

        journal = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True))
        journal.bibjson().remove_identifiers()
        journal.bibjson().add_identifier(journal.bibjson().E_ISSN, "9999-8888")
        journal.bibjson().add_identifier(journal.bibjson().P_ISSN, "7777-6666")
        journal.bibjson().title = "not changed"
        journal.set_id(data["admin"]["current_journal"])
        journal.set_owner(account.id)
        journal.save(blocking=True)

        # call create on the object, with the dry_run flag set
        a = ApplicationsCrudApi.create(data, account, dry_run=True)

        time.sleep(2)

        # now check that the application index remains empty
        ss = [x for x in models.Suggestion.iterall()]
        assert len(ss) == 0
Пример #5
0
def create_edit_cases():
    application_source = ApplicationFixtureFactory.make_application_source()
    account_source = AccountFixtureFactory.make_publisher_source()

    editable_application = Suggestion(**application_source)
    editable_application.set_application_status(constants.APPLICATION_STATUS_UPDATE_REQUEST)

    non_editable_application = Suggestion(**application_source)
    non_editable_application.set_application_status(constants.APPLICATION_STATUS_READY)

    owner_account = Account(**deepcopy(account_source))
    owner_account.set_id(editable_application.owner)

    non_owner_publisher = Account(**deepcopy(account_source))

    non_publisher = Account(**deepcopy(account_source))
    non_publisher.remove_role("publisher")

    admin = Account(**deepcopy(account_source))
    admin.add_role("admin")

    return [
        param("no_app_no_account", None, None, raises=exceptions.ArgumentException),
        param("no_app_with_account", None, owner_account, raises=exceptions.ArgumentException),
        param("app_no_account", editable_application, None, raises=exceptions.ArgumentException),
        param("editable_app_owning_account", editable_application, owner_account, expected=True),
        param("editable_app_nonowning_account", editable_application, non_owner_publisher, raises=exceptions.AuthoriseException),
        param("editable_app_non_publisher_account", editable_application, non_publisher, raises=exceptions.AuthoriseException),
        param("editable_app_admin_account", editable_application, admin, expected=True),
        param("non_editable_app_owning_account", non_editable_application, owner_account, raises=exceptions.AuthoriseException),
        param("non_editable_app_nonowning_account", non_editable_application, non_owner_publisher, raises=exceptions.AuthoriseException),
        param("non_editable_app_non_publisher_account", non_editable_application, non_publisher, raises=exceptions.AuthoriseException),
        param("non_editable_app_admin_account", non_editable_application, admin, expected=True)
    ]
Пример #6
0
    def test_06_make_journal(self):
        s = models.Suggestion(**ApplicationFixtureFactory.make_application_source())
        j = s.make_journal()

        assert j.id != s.id
        assert "suggestion" not in j.data
        assert j.data.get("bibjson", {}).get("active")
Пример #7
0
    def test_03_delete_application_success(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        dataset = [data] * 10

        # create the account we're going to work as
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")
        account.add_role("publisher")

        # call create on the objects (which will save it to the index)
        ids = ApplicationsBulkApi.create(dataset, account)

        # let the index catch up
        time.sleep(2)

        # now delete half of them
        dels = ids[:5]
        ApplicationsBulkApi.delete(dels, account)

        # let the index catch up
        time.sleep(2)

        for id in dels:
            ap = models.Suggestion.pull(id)
            assert ap is None
        for id in ids[5:]:
            ap = models.Suggestion.pull(id)
            assert ap is not None
Пример #8
0
    def test_01_create_applications_success(self):
        # set up all the bits we need - 10 applications
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        dataset = [data] * 10

        # create an account that we'll do the create as
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")

        # call create on the object (which will save it to the index)
        ids = ApplicationsBulkApi.create(dataset, account)

        # check that we got the right number of ids back
        assert len(ids) == 10

        # let the index catch up
        time.sleep(2)

        # check that each id was actually created
        for id in ids:
            s = models.Suggestion.pull(id)
            assert s is not None
Пример #9
0
    def test_02a_create_application_success_variations(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")

        # try with only one issn
        data["bibjson"]["identifier"] = [
            {
                "type" : "pissn",
                "id": "1234-5678"
            }
        ]

        # call create on the object (which will save it to the index)
        a = ApplicationsCrudApi.create(data, account)

        # check that it got created successfully
        assert isinstance(a, models.Suggestion)

        time.sleep(2)

        s = models.Suggestion.pull(a.id)
        assert s is not None
Пример #10
0
    def setUp(self):
        super(TestTaskSuggestionBulkEdit, self).setUp()

        acc = models.Account()
        acc.set_id("0987654321")
        acc.set_email("*****@*****.**")
        acc.save()

        egs = EditorGroupFixtureFactory.make_editor_group_source("1234567890", "0987654321")
        egm = models.EditorGroup(**egs)
        egm.save(blocking=True)

        self.suggestions = []
        for app_src in ApplicationFixtureFactory.make_many_application_sources(count=TEST_SUGGESTION_COUNT):
            self.suggestions.append(models.Suggestion(**app_src))
            self.suggestions[-1].set_editor_group("1234567890")
            self.suggestions[-1].set_editor("0987654321")
            self.suggestions[-1].save()

        self.default_eg = EditorGroupFixtureFactory.setup_editor_group_with_editors()

        self.forbidden_accounts = [
            AccountFixtureFactory.make_editor_source()['id'],
            AccountFixtureFactory.make_assed1_source()['id'],
            AccountFixtureFactory.make_assed2_source()['id'],
            AccountFixtureFactory.make_assed3_source()['id']
        ]

        self._make_and_push_test_context(acc=models.Account(**AccountFixtureFactory.make_managing_editor_source()))
Пример #11
0
    def test_09_update_application_fail(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")

        # call create on the object (which will save it to the index)
        a = ApplicationsCrudApi.create(data, account)

        # let the index catch up
        time.sleep(2)

        # get a copy of the newly created version for use in assertions later
        created = models.Suggestion.pull(a.id)

        # now make an updated version of the object
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        data["bibjson"]["title"] = "An updated title"

        # call update on the object in various context that will fail

        # without an account
        with self.assertRaises(Api401Error):
            ApplicationsCrudApi.update(a.id, data, None)

        # with the wrong account
        account.set_id("other")
        with self.assertRaises(Api404Error):
            ApplicationsCrudApi.update(a.id, data, account)

        # on the wrong id
        account.set_id("test")
        with self.assertRaises(Api404Error):
            ApplicationsCrudApi.update("adfasdfhwefwef", data, account)

        # on one with a disallowed workflow status
        created.set_application_status(constants.APPLICATION_STATUS_ACCEPTED)
        created.save()
        time.sleep(2)
        account.add_role("publisher")

        with self.assertRaises(Api403Error):
            ApplicationsCrudApi.update(a.id, data, account)
Пример #12
0
    def test_16_update_application_update_request_success(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")
        account.add_role("publisher")

        journal = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True))
        journal.bibjson().remove_identifiers()
        journal.bibjson().add_identifier(journal.bibjson().E_ISSN, "9999-8888")
        journal.bibjson().add_identifier(journal.bibjson().P_ISSN, "7777-6666")
        journal.bibjson().title = "not changed"
        journal.set_id(data["admin"]["current_journal"])
        journal.set_owner(account.id)
        journal.save(blocking=True)

        # call create on the object (which will save it to the index)
        a = ApplicationsCrudApi.create(data, account)

        # let the index catch up
        time.sleep(2)

        # get a copy of the newly created version for use in assertions later
        created = models.Suggestion.pull(a.id)

        # now make an updated version of the object
        data = ApplicationFixtureFactory.incoming_application()
        data["bibjson"]["title"] = "An updated title"
        data["bibjson"]["publisher"] = "An updated publisher"

        # call update on the object
        a2 = ApplicationsCrudApi.update(a.id, data, account)
        assert a2 != a

        # let the index catch up
        time.sleep(2)

        # get a copy of the updated version
        updated = models.Suggestion.pull(a.id)

        # now check the properties to make sure the update tool
        assert updated.bibjson().title == "not changed"
        assert updated.bibjson().publisher == "An updated publisher"
        assert updated.created_date == created.created_date
Пример #13
0
    def test_14_make_journal_from_reapp(self):
        # with history
        j = models.Journal()
        j.set_id("1234567")
        j.set_created("2001-01-01T00:00:00Z")
        j.add_history({"title" : "old title"})
        j.save()

        s = models.Suggestion(**ApplicationFixtureFactory.make_application_source())
        s.set_current_journal("1234567")

        time.sleep(1)
        j = s.make_journal()
        j.save()

        assert j.id == "1234567"
        assert "suggestion" not in j.data
        assert j.last_reapplication is not None
        assert j.data.get("bibjson", {}).get("active")
        assert j.current_application is None
        assert j.data.get("admin", {}).get("current_journal") is None
        assert j.created_date == "2001-01-01T00:00:00Z"
        assert j.get_history_raw()[0].get("bibjson", {}).get("title") == "old title"

        # without history
        j = models.Journal()
        j.set_id("1234567")
        j.set_created("2001-01-01T00:00:00Z")
        j.save()

        s = models.Suggestion(**ApplicationFixtureFactory.make_application_source())
        s.set_current_journal("1234567")

        time.sleep(1)
        j = s.make_journal()
        j.save()

        assert j.id == "1234567"
        assert "suggestion" not in j.data
        assert j.last_reapplication is not None
        assert j.data.get("bibjson", {}).get("active")
        assert j.current_application is None
        assert j.data.get("admin", {}).get("current_journal") is None
        assert j.created_date == "2001-01-01T00:00:00Z"
        assert len(j.history()) == 0
Пример #14
0
    def test_03b_create_update_request_fail(self):
        # update request target not found
        with self.assertRaises(Api404Error):
            data = ApplicationFixtureFactory.incoming_application()
            publisher = models.Account(**AccountFixtureFactory.make_publisher_source())
            try:
                a = ApplicationsCrudApi.create(data, publisher)
            except Api404Error as e:
                raise

        # if a formcontext exception is raised on finalise
        publisher = models.Account(**AccountFixtureFactory.make_publisher_source())
        journal = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True))
        journal.set_id(journal.makeid())
        journal.set_owner(publisher.id)
        journal.save(blocking=True)
        formcontext.FormContext.finalise = mock_finalise_exception
        with self.assertRaises(Api400Error):
            data = ApplicationFixtureFactory.incoming_application()
            data["admin"]["current_journal"] = journal.id

            try:
                a = ApplicationsCrudApi.create(data, publisher)
            except Api400Error as e:
                assert e.message == "test exception"
                raise
        formcontext.FormContext.finalise = self.old_finalise

        # validation fails on the formcontext
        publisher = models.Account(**AccountFixtureFactory.make_publisher_source())
        journal = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True))
        journal.set_id(journal.makeid())
        journal.set_owner(publisher.id)
        journal.save(blocking=True)
        IncomingApplication.custom_validate = mock_custom_validate_always_pass
        with self.assertRaises(Api400Error):
            data = ApplicationFixtureFactory.incoming_application()
            # duff submission charges url should trip the validator
            data["bibjson"]["submission_charges_url"] = "not a url!"
            data["admin"]["current_journal"] = journal.id
            try:
                a = ApplicationsCrudApi.create(data, publisher)
            except Api400Error as e:
                raise
Пример #15
0
    def test_13_create_application_update_request_success(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")
        account.add_role("publisher")
        account.save(blocking=True)

        journal = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True))
        journal.bibjson().remove_identifiers()
        journal.bibjson().add_identifier(journal.bibjson().E_ISSN, "9999-8888")
        journal.bibjson().add_identifier(journal.bibjson().P_ISSN, "7777-6666")
        journal.bibjson().title = "not changed"
        journal.set_id(data["admin"]["current_journal"])
        journal.set_owner(account.id)
        journal.save(blocking=True)

        # call create on the object (which will save it to the index)
        a = ApplicationsCrudApi.create(data, account)

        # check that it got created with the right properties
        assert isinstance(a, models.Suggestion)
        assert a.id != "ignore_me"
        assert a.created_date != "2001-01-01T00:00:00Z"
        assert a.last_updated != "2001-01-01T00:00:00Z"
        assert a.suggester.get("name") == "Tester"           # The suggester should be the owner of the existing journal
        assert a.suggester.get("email") == "*****@*****.**"
        assert a.owner == "test"
        assert a.suggested_on is not None
        assert a.bibjson().issns() == ["9999-8888", "7777-6666"] or a.bibjson().issns() == ["7777-6666", "9999-8888"]
        assert a.bibjson().title == "not changed"

        # also, because it's a special case, check the archiving_policy
        archiving_policy = a.bibjson().archiving_policy
        assert len(archiving_policy.get("policy")) == 4
        lcount = 0
        scount = 0
        for ap in archiving_policy.get("policy"):
            if isinstance(ap, list):
                lcount += 1
                assert ap[0] in ["A national library", "Other"]
                assert ap[1] in ["Trinity", "A safe place"]
            else:
                scount += 1
        assert lcount == 2
        assert scount == 2
        assert "CLOCKSS" in archiving_policy.get("policy")
        assert "LOCKSS" in archiving_policy.get("policy")

        time.sleep(2)

        s = models.Suggestion.pull(a.id)
        assert s is not None
Пример #16
0
    def test_02_applications_crud(self):
        # add some data to the index with a Create
        user_data = ApplicationFixtureFactory.incoming_application()
        del user_data["admin"]["current_journal"]

        with self.app_test.test_client() as t_client:
            # log into the app as our user
            self.login(t_client, 'test', 'password123')

            # CREATE a new application
            response = t_client.post('/api/v1/applications?api_key=' + self.api_key, data=json.dumps(user_data))
            assert response.status_code == 201          # 201 "Created"
            assert response.mimetype == 'application/json'

            # Check it gives back a newly created application, with an ID
            new_app_id = json.loads(response.data)['id']
            new_app_loc = json.loads(response.data)['location']
            assert new_app_id is not None
            assert new_app_id in new_app_loc

            # RETRIEVE the same application using the ID
            response = t_client.get('/api/v1/applications/{0}?api_key={1}'.format(new_app_id, self.api_key))
            assert response.status_code == 200          # 200 "OK"
            assert response.mimetype == 'application/json'

            retrieved_application = json.loads(response.data)
            new_app_title = retrieved_application['bibjson']['title']
            assert new_app_title == user_data['bibjson']['title']

            # UPDATE the title of the application
            updated_data = deepcopy(user_data)
            updated_data['bibjson']['title'] = 'This is a new title for this application'
            response = t_client.put('/api/v1/applications/{0}?api_key={1}'.format(new_app_id, self.api_key), data=json.dumps(updated_data))
            assert response.status_code == 204          # 204 "No Content"
            assert response.mimetype == 'application/json'

            response = t_client.get('/api/v1/applications/{0}?api_key={1}'.format(new_app_id, self.api_key))
            retrieved_application = json.loads(response.data)
            new_app_title = retrieved_application['bibjson']['title']
            assert new_app_title == updated_data['bibjson']['title']
            assert new_app_title != user_data['bibjson']['title']

            # DELETE the application
            assert models.Suggestion.pull(new_app_id) is not None
            response = t_client.delete('/api/v1/applications/{0}?api_key={1}'.format(new_app_id, self.api_key))
            assert response.status_code == 204          # 204 "No Content"
            assert response.mimetype == 'application/json'

            # Try to RETRIEVE the Application again - check it isn't there anymore
            response = t_client.get('/api/v1/applications/{0}?api_key={1}'.format(new_app_id, self.api_key))
            assert response.status_code == 404
            assert response.mimetype == 'application/json'

            self.logout(t_client)
Пример #17
0
    def test_32_application_all_by_related_journal(self):
        j = models.Journal()
        j.set_id(j.makeid())

        app1 = models.Suggestion(**ApplicationFixtureFactory.make_application_source())
        app1.set_id(app1.makeid())
        app1.set_related_journal(j.id)
        app1.set_created("1970-01-01T00:00:00Z")
        app1.save()

        app2 = models.Suggestion(**ApplicationFixtureFactory.make_application_source())
        app2.set_id(app2.makeid())
        app2.set_related_journal(j.id)
        app2.set_created("1971-01-01T00:00:00Z")
        app2.save(blocking=True)

        # check that we find all the applications when we search, and that they're in the right order
        all = models.Suggestion.find_all_by_related_journal(j.id)
        assert len(all) == 2
        assert all[0].id == app1.id
        assert all[1].id == app2.id
Пример #18
0
 def test_03c_update_update_request_fail(self):
     # update request target in disallowed status
     journal = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True))
     journal.set_id(journal.makeid())
     journal.save(blocking=True)
     with self.assertRaises(Api404Error):
         data = ApplicationFixtureFactory.incoming_application()
         data["admin"]["current_journal"] = journal.id
         publisher = models.Account(**AccountFixtureFactory.make_publisher_source())
         try:
             a = ApplicationsCrudApi.create(data, publisher)
         except Api404Error as e:
             raise
Пример #19
0
    def test_03_view_application(self,
                                 name,
                                 account_type,
                                 role,
                                 owner,
                                 application_type,
                                 raises=None,
                                 returns=None,
                                 auth_reason=None):
        # set up the objects
        application = None
        if application_type == "exists":
            application = Suggestion(
                **ApplicationFixtureFactory.make_application_source())

        account = None
        if account_type == "exists":
            if role == "none":
                account = Account(
                    **AccountFixtureFactory.make_publisher_source())
                account.remove_role("publisher")
            elif role == "publisher":
                account = Account(
                    **AccountFixtureFactory.make_publisher_source())
            elif role == "admin":
                account = Account(
                    **AccountFixtureFactory.make_managing_editor_source())

            if owner == "yes":
                application.set_owner(account.id)

        svc = DOAJ.authorisationService()
        if raises is not None and raises != "":
            exception = None
            with self.assertRaises(EXCEPTIONS[raises]):
                try:
                    svc.can_view_application(account, application)
                except Exception as e:
                    exception = e
                    raise e
            if raises == "AuthoriseException":
                if auth_reason == "not_owner":
                    assert exception.reason == exception.NOT_OWNER
                elif auth_reason == "wrong_role":
                    assert exception.reason == exception.WRONG_ROLE

        elif returns is not None:
            expected = returns == "true"
            assert svc.can_view_application(account, application) is expected
        else:
            assert False, "Specify either raises or returns"
    def test_02_create_application_success(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        data["admin"]["application_status"] = "on_hold"
        data["admin"]["owner"] = "someaccount"

        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")

        # call create on the object (which will save it to the index)
        a = ApplicationsCrudApi.create(data, account)

        # check that it got created with the right properties
        assert isinstance(a, models.Suggestion)
        assert a.id != "ignore_me"
        assert a.created_date != "2001-01-01T00:00:00Z"
        assert a.last_updated != "2001-01-01T00:00:00Z"
        assert a.suggester.get("name") == "Tester"
        assert a.suggester.get("email") == "*****@*****.**"
        assert a.owner == "test"
        assert a.suggested_on is not None
        assert len(a.bibjson().keywords) > 1

        # check the stuff that should default
        assert a.application_status == "pending"
        assert a.owner == "test"

        # also, because it's a special case, check the archiving_policy
        archiving_policy = a.bibjson().archiving_policy
        assert len(archiving_policy.get("policy")) == 4
        lcount = 0
        scount = 0
        for ap in archiving_policy.get("policy"):
            if isinstance(ap, list):
                lcount += 1
                assert ap[0] in ["A national library", "Other"]
                assert ap[1] in ["Trinity", "A safe place"]
            else:
                scount += 1
        assert lcount == 2
        assert scount == 2
        assert "CLOCKSS" in archiving_policy.get("policy")
        assert "LOCKSS" in archiving_policy.get("policy")

        time.sleep(2)

        s = models.Suggestion.pull(a.id)
        assert s is not None
Пример #21
0
    def test_05_sync_owners(self):
        # suggestion with no current_journal
        s = models.Suggestion(
            **ApplicationFixtureFactory.make_application_source())
        s.save()

        models.Suggestion.refresh()
        s = models.Suggestion.pull(s.id)
        assert s is not None

        # journal with no current_application
        j = models.Journal(**JournalFixtureFactory.make_journal_source())
        j.save()

        models.Journal.refresh()
        j = models.Journal.pull(j.id)
        assert j is not None

        # suggestion with erroneous current_journal
        s.set_current_journal("asdklfjsadjhflasdfoasf")
        s.save()

        models.Suggestion.refresh()
        s = models.Suggestion.pull(s.id)
        assert s is not None

        # journal with erroneous current_application
        j.set_current_application("kjwfuiwqhu220952gw")
        j.save()

        models.Journal.refresh()
        j = models.Journal.pull(j.id)
        assert j is not None

        # suggestion with journal
        s.set_owner("my_new_owner")
        s.set_current_journal(j.id)
        s.save()

        models.Journal.refresh()
        j = models.Journal.pull(j.id)
        assert j.owner == "my_new_owner"

        # journal with suggestion
        j.set_owner("another_new_owner")
        j.set_current_application(s.id)
        j.save()

        models.Suggestion.refresh()
        s = models.Suggestion.pull(s.id)
        assert s.owner == "another_new_owner"
Пример #22
0
    def test_32_application_all_by_related_journal(self):
        j = models.Journal()
        j.set_id(j.makeid())

        app1 = models.Suggestion(
            **ApplicationFixtureFactory.make_application_source())
        app1.set_id(app1.makeid())
        app1.set_related_journal(j.id)
        app1.set_created("1970-01-01T00:00:00Z")
        app1.save()

        app2 = models.Suggestion(
            **ApplicationFixtureFactory.make_application_source())
        app2.set_id(app2.makeid())
        app2.set_related_journal(j.id)
        app2.set_created("1971-01-01T00:00:00Z")
        app2.save(blocking=True)

        # check that we find all the applications when we search, and that they're in the right order
        all = models.Suggestion.find_all_by_related_journal(j.id)
        assert len(all) == 2
        assert all[0].id == app1.id
        assert all[1].id == app2.id
Пример #23
0
    def test_08_sync_owners(self):
        # suggestion with no current_journal
        s = models.Suggestion(**ApplicationFixtureFactory.make_application_source())
        s.save()

        models.Suggestion.refresh()
        s = models.Suggestion.pull(s.id)
        assert s is not None

        # journal with no current_application
        j = models.Journal(**JournalFixtureFactory.make_journal_source())
        j.save()

        models.Journal.refresh()
        j = models.Journal.pull(j.id)
        assert j is not None

        # suggestion with erroneous current_journal
        s.set_current_journal("asdklfjsadjhflasdfoasf")
        s.save()

        models.Suggestion.refresh()
        s = models.Suggestion.pull(s.id)
        assert s is not None

        # journal with erroneous current_application
        j.set_current_application("kjwfuiwqhu220952gw")
        j.save()

        models.Journal.refresh()
        j = models.Journal.pull(j.id)
        assert j is not None

        # suggestion with journal
        s.set_owner("my_new_owner")
        s.set_current_journal(j.id)
        s.save()

        models.Journal.refresh()
        j = models.Journal.pull(j.id)
        assert j.owner == "my_new_owner"

        # journal with suggestion
        j.set_owner("another_new_owner")
        j.set_current_application(s.id)
        j.save()

        models.Suggestion.refresh()
        s = models.Suggestion.pull(s.id)
        assert s.owner == "another_new_owner"
Пример #24
0
    def test_08_update_application_success(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")
        account.add_role("publisher")

        # call create on the object (which will save it to the index)
        a = ApplicationsCrudApi.create(data, account)

        # let the index catch up
        time.sleep(2)

        # get a copy of the newly created version for use in assertions later
        created = models.Suggestion.pull(a.id)

        # now make an updated version of the object
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        data["bibjson"]["title"] = "An updated title"

        # call update on the object
        a2 = ApplicationsCrudApi.update(a.id, data, account)
        assert a2 != a

        # let the index catch up
        time.sleep(2)

        # get a copy of the updated version
        updated = models.Suggestion.pull(a.id)

        # now check the properties to make sure the update tool
        assert updated.bibjson().title == "An updated title"
        assert updated.created_date == created.created_date
Пример #25
0
    def test_08_update_application_success(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")
        account.add_role("publisher")

        # call create on the object (which will save it to the index)
        a = ApplicationsCrudApi.create(data, account)

        # let the index catch up
        time.sleep(2)

        # get a copy of the newly created version for use in assertions later
        created = models.Suggestion.pull(a.id)

        # now make an updated version of the object
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        data["bibjson"]["title"] = "An updated title"

        # call update on the object
        a2 = ApplicationsCrudApi.update(a.id, data, account)
        assert a2 != a

        # let the index catch up
        time.sleep(2)

        # get a copy of the updated version
        updated = models.Suggestion.pull(a.id)

        # now check the properties to make sure the update tool
        assert updated.bibjson().title == "An updated title"
        assert updated.created_date == created.created_date
Пример #26
0
    def test_03_workflow_editor_notifications(self):
        ctx = self._make_and_push_test_context()

        emails = {}

        # When we make the application unchanged for a short period of time, we don't tell the editors
        [APPLICATION_SOURCE_1, APPLICATION_SOURCE_2, APPLICATION_SOURCE_3
         ] = ApplicationFixtureFactory.make_many_application_sources(count=3)
        comfortably_idle = app.config['ASSOC_ED_IDLE_DAYS'] + 1
        APPLICATION_SOURCE_1['last_manual_update'] = datetime.utcnow(
        ) - timedelta(days=comfortably_idle)
        application1 = models.Suggestion(**APPLICATION_SOURCE_1)
        application1.save()

        # This exceeds the idle limit, editors should be notified.
        APPLICATION_SOURCE_2['admin'][
            'application_status'] = constants.APPLICATION_STATUS_IN_PROGRESS
        extremely_idle = app.config['ED_IDLE_WEEKS'] + 1
        APPLICATION_SOURCE_2['last_manual_update'] = datetime.utcnow(
        ) - timedelta(weeks=extremely_idle)
        application2 = models.Suggestion(**APPLICATION_SOURCE_2)
        application2.save()

        # This one is assigned to the group but not an associate - editors are reminded.
        extremely_idle = app.config['ED_IDLE_WEEKS'] + 1
        APPLICATION_SOURCE_2['admin'][
            'application_status'] = constants.APPLICATION_STATUS_UPDATE_REQUEST
        APPLICATION_SOURCE_3['last_manual_update'] = datetime.utcnow(
        ) - timedelta(days=extremely_idle)
        APPLICATION_SOURCE_3['admin']['editor'] = None
        application3 = models.Suggestion(**APPLICATION_SOURCE_3)
        application3.save()

        models.Suggestion.blockall([
            (application1.id, application1.last_updated),
            (application2.id, application2.last_updated),
            (application3.id, application3.last_updated)
        ])

        async_workflow_notifications.editor_notifications(emails)

        assert len(emails) > 0
        assert EDITOR_SOURCE['email'] in list(emails.keys())

        email_text_catted = " ".join(emails[EDITOR_SOURCE['email']][1])
        assert '1 application(s) currently assigned to your Editor Group, "editorgroup", which have no Associate Editor' in email_text_catted
        assert "1 application(s) which have been assigned to an Associate Editor but have been idle" in email_text_catted

        ctx.pop()
Пример #27
0
 def test_03c_update_update_request_fail(self):
     # update request target in disallowed status
     journal = models.Journal(**JournalFixtureFactory.make_journal_source(
         in_doaj=True))
     journal.set_id(journal.makeid())
     journal.save(blocking=True)
     with self.assertRaises(Api404Error):
         data = ApplicationFixtureFactory.incoming_application()
         data["admin"]["current_journal"] = journal.id
         publisher = models.Account(
             **AccountFixtureFactory.make_publisher_source())
         try:
             a = ApplicationsCrudApi.create(data, publisher)
         except Api404Error as e:
             raise
Пример #28
0
    def test_31_application_latest_by_current_journal(self):
        j = models.Journal()
        j.set_id(j.makeid())

        app1 = models.Suggestion(**ApplicationFixtureFactory.make_application_source())
        app1.set_id(app1.makeid())
        app1.set_current_journal(j.id)
        app1.set_created("1970-01-01T00:00:00Z")
        app1.save()

        app2 = models.Suggestion(**ApplicationFixtureFactory.make_application_source())
        app2.set_id(app2.makeid())
        app2.set_current_journal(j.id)
        app2.set_created("1971-01-01T00:00:00Z")
        app2.save(blocking=True)

        # check that we find the right application when we search
        app3 = models.Suggestion.find_latest_by_current_journal(j.id)
        assert app3 is not None
        assert app3.id == app2.id

        # make sure we get a None response when there's no application
        app0 = models.Suggestion.find_latest_by_current_journal("whatever")
        assert app0 is None
Пример #29
0
    def test_03a_create_application_dryrun(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")

        # call create on the object, with the dry_run flag set
        a = ApplicationsCrudApi.create(data, account, dry_run=True)

        time.sleep(2)

        # now check that the application index remains empty
        ss = [x for x in models.Suggestion.iterall()]
        assert len(ss) == 0
Пример #30
0
    def test_03a_create_application_dryrun(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")

        # call create on the object, with the dry_run flag set
        a = ApplicationsCrudApi.create(data, account, dry_run=True)

        time.sleep(2)

        # now check that the application index remains empty
        ss = [x for x in models.Suggestion.iterall()]
        assert len(ss) == 0
Пример #31
0
    def test_02_workflow_managing_editor_notifications(self):
        ctx = self._make_and_push_test_context()

        emails = {}

        # When we make the application unchanged for a short period of time, we don't tell the managing editors
        [APPLICATION_SOURCE_1, APPLICATION_SOURCE_2, APPLICATION_SOURCE_3
         ] = ApplicationFixtureFactory.make_many_application_sources(count=3)
        comfortably_idle = app.config['ASSOC_ED_IDLE_DAYS'] + 1
        APPLICATION_SOURCE_1['last_manual_update'] = datetime.utcnow(
        ) - timedelta(days=comfortably_idle)
        application1 = models.Suggestion(**APPLICATION_SOURCE_1)
        application1.save()

        # This exceeds the idle limit, managing editors should be notified.
        APPLICATION_SOURCE_2['admin'][
            'application_status'] = constants.APPLICATION_STATUS_IN_PROGRESS
        extremely_idle = app.config['MAN_ED_IDLE_WEEKS'] + 1
        APPLICATION_SOURCE_2['last_manual_update'] = datetime.utcnow(
        ) - timedelta(weeks=extremely_idle)
        application2 = models.Suggestion(**APPLICATION_SOURCE_2)
        application2.save()

        # This one is ready - managing editors are told as it's now their responsibility.
        APPLICATION_SOURCE_3['last_manual_update'] = datetime.utcnow()
        APPLICATION_SOURCE_3['admin'][
            'application_status'] = constants.APPLICATION_STATUS_READY
        application3 = models.Suggestion(**APPLICATION_SOURCE_3)
        application3.save()

        models.Suggestion.blockall([
            (application1.id, application1.last_updated),
            (application2.id, application2.last_updated),
            (application3.id, application3.last_updated)
        ])

        async_workflow_notifications.managing_editor_notifications(emails)
        assert len(emails) > 0
        assert app.config['MANAGING_EDITOR_EMAIL'] in list(emails.keys())

        email_text_catted = " ".join(
            emails[app.config['MANAGING_EDITOR_EMAIL']][1])
        assert '1 application(s) are assigned to an Associate Editor' in email_text_catted
        assert "There are 1 records in status 'Ready'" in email_text_catted
        ctx.pop()
Пример #32
0
    def test_06_retrieve_application_success(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.make_application_source()
        ap = models.Suggestion(**data)
        ap.save()
        time.sleep(2)

        account = models.Account()
        account.set_id(ap.owner)
        account.set_name("Tester")
        account.set_email("*****@*****.**")

        # call retrieve on the object
        a = ApplicationsCrudApi.retrieve(ap.id, account)

        # check that we got back the object we expected
        assert isinstance(a, OutgoingApplication)
        assert a.id == ap.id
Пример #33
0
def load_application_cases():
    account = Account(**AccountFixtureFactory.make_publisher_source())
    account.set_id(account.makeid())

    application = Suggestion(**ApplicationFixtureFactory.make_application_source())
    application.makeid()

    wrong_id = uuid.uuid4()

    return [
        param("a_id_acc_lock", application, application.id, account, True, raises=lock.Locked),
        param("a_id_acc_nolock", application, application.id, account, False),
        param("a_id_noacc_nolock", application, application.id, None, False),
        param("a_noid_noacc_nolock", application, None, None, False, raises=exceptions.ArgumentException),
        param("a_wid_noacc_nolock", application, wrong_id, None, False),
        param("noa_id_noacc_nolock", None, application.id, None, False),
        param("noa_noid_noacc_nolock", None, None, None, False, raises=exceptions.ArgumentException)
    ]
Пример #34
0
    def test_06_retrieve_application_success(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.make_update_request_source()
        ap = models.Suggestion(**data)
        ap.save()
        time.sleep(2)

        account = models.Account()
        account.set_id(ap.owner)
        account.set_name("Tester")
        account.set_email("*****@*****.**")

        # call retrieve on the object
        a = ApplicationsCrudApi.retrieve(ap.id, account)

        # check that we got back the object we expected
        assert isinstance(a, OutgoingApplication)
        assert a.id == ap.id
Пример #35
0
    def test_02_create_application_success(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")

        # call create on the object (which will save it to the index)
        a = ApplicationsCrudApi.create(data, account)

        # check that it got created with the right properties
        assert isinstance(a, models.Suggestion)
        assert a.id != "ignore_me"
        assert a.created_date != "2001-01-01T00:00:00Z"
        assert a.last_updated != "2001-01-01T00:00:00Z"
        assert a.suggester.get("name") == "Tester"
        assert a.suggester.get("email") == "*****@*****.**"
        assert a.owner == "test"
        assert a.suggested_on is not None
        assert len(a.bibjson().keywords) > 1

        # also, because it's a special case, check the archiving_policy
        archiving_policy = a.bibjson().archiving_policy
        assert len(archiving_policy.get("policy")) == 4
        lcount = 0
        scount = 0
        for ap in archiving_policy.get("policy"):
            if isinstance(ap, list):
                lcount += 1
                assert ap[0] in ["A national library", "Other"]
                assert ap[1] in ["Trinity", "A safe place"]
            else:
                scount += 1
        assert lcount == 2
        assert scount == 2
        assert "CLOCKSS" in archiving_policy.get("policy")
        assert "LOCKSS" in archiving_policy.get("policy")

        time.sleep(2)

        s = models.Suggestion.pull(a.id)
        assert s is not None
Пример #36
0
    def test_03_apps_by_country(self):
        apps = ApplicationFixtureFactory.make_application_spread(APPLICATION_YEAR_OUTPUT, "year")
        for a in apps:
            a.save()
        time.sleep(2)

        outfiles = reporting.content_reports("1970-01-01T00:00:00Z", dates.now(), TMP_DIR)

        assert len(outfiles) == 1
        assert os.path.exists(outfiles[0])

        table = []
        with codecs.open(outfiles[0], "rb", "utf-8") as f:
            reader = clcsv.UnicodeReader(f)
            for row in reader:
                table.append(row)

        expected = self._as_output(APPLICATION_YEAR_OUTPUT)
        assert table == expected
Пример #37
0
    def test_04_delete_applications_fail(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        dataset = [data] * 10

        # create the account we're going to work as
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")

        # call create on the objects (which will save it to the index)
        ids = ApplicationsBulkApi.create(dataset, account)

        # let the index catch up
        time.sleep(2)

        # call delete on the object in various context that will fail

        # without an account
        with self.assertRaises(Api401Error):
            ApplicationsBulkApi.delete(ids, None)

        # with the wrong account
        account.set_id("other")
        with self.assertRaises(Api400Error):
            ApplicationsBulkApi.delete(ids, account)

        # on the wrong id
        ids.append("adfasdfhwefwef")
        account.set_id("test")
        with self.assertRaises(Api400Error):
            ApplicationsBulkApi.delete(ids, account)

        # on one with a disallowed workflow status
        created = models.Suggestion.pull(ids[3])
        created.set_application_status(constants.APPLICATION_STATUS_ACCEPTED)
        created.save()
        time.sleep(2)

        with self.assertRaises(Api400Error):
            ApplicationsBulkApi.delete(ids, account)
Пример #38
0
    def test_03_workflow_editor_notifications(self):
        ctx = self._make_and_push_test_context()

        emails = {}

        # When we make the application unchanged for a short period of time, we don't tell the editors
        [APPLICATION_SOURCE_1, APPLICATION_SOURCE_2, APPLICATION_SOURCE_3] = ApplicationFixtureFactory.make_many_application_sources(count=3)
        comfortably_idle = app.config['ASSOC_ED_IDLE_DAYS'] + 1
        APPLICATION_SOURCE_1['last_manual_update'] = datetime.utcnow() - timedelta(days=comfortably_idle)
        application1 = models.Suggestion(**APPLICATION_SOURCE_1)
        application1.save()

        # This exceeds the idle limit, editors should be notified.
        APPLICATION_SOURCE_2['admin']['application_status'] = constants.APPLICATION_STATUS_IN_PROGRESS
        extremely_idle = app.config['ED_IDLE_WEEKS'] + 1
        APPLICATION_SOURCE_2['last_manual_update'] = datetime.utcnow() - timedelta(weeks=extremely_idle)
        application2 = models.Suggestion(**APPLICATION_SOURCE_2)
        application2.save()

        # This one is assigned to the group but not an associate - editors are reminded.
        extremely_idle = app.config['ED_IDLE_WEEKS'] + 1
        APPLICATION_SOURCE_2['admin']['application_status'] = constants.APPLICATION_STATUS_UPDATE_REQUEST
        APPLICATION_SOURCE_3['last_manual_update'] = datetime.utcnow() - timedelta(days=extremely_idle)
        APPLICATION_SOURCE_3['admin']['editor'] = None
        application3 = models.Suggestion(**APPLICATION_SOURCE_3)
        application3.save()

        models.Suggestion.blockall([
            (application1.id, application1.last_updated),
            (application2.id, application2.last_updated),
            (application3.id, application3.last_updated)
        ])

        async_workflow_notifications.editor_notifications(emails)

        assert len(emails) > 0
        assert EDITOR_SOURCE['email'] in emails.keys()

        email_text_catted = " ".join(emails[EDITOR_SOURCE['email']][1])
        assert u'1 application(s) currently assigned to your Editor Group, "editorgroup", which have no Associate Editor' in email_text_catted
        assert u"1 application(s) which have been assigned to an Associate Editor but have been idle" in email_text_catted

        ctx.pop()
Пример #39
0
    def test_04_delete_applications_fail(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        dataset = [data] * 10

        # create the account we're going to work as
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")

        # call create on the objects (which will save it to the index)
        ids = ApplicationsBulkApi.create(dataset, account)

        # let the index catch up
        time.sleep(2)

        # call delete on the object in various context that will fail

        # without an account
        with self.assertRaises(Api401Error):
            ApplicationsBulkApi.delete(ids, None)

        # with the wrong account
        account.set_id("other")
        with self.assertRaises(Api400Error):
            ApplicationsBulkApi.delete(ids, account)

        # on the wrong id
        ids.append("adfasdfhwefwef")
        account.set_id("test")
        with self.assertRaises(Api400Error):
            ApplicationsBulkApi.delete(ids, account)

        # on one with a disallowed workflow status
        created = models.Suggestion.pull(ids[3])
        created.set_application_status(constants.APPLICATION_STATUS_ACCEPTED)
        created.save()
        time.sleep(2)

        with self.assertRaises(Api400Error):
            ApplicationsBulkApi.delete(ids, account)
Пример #40
0
    def test_04_workflow_associate_editor_notifications(self):
        ctx = self._make_and_push_test_context()

        APPLICATION_SOURCE['last_manual_update'] = datetime.utcnow()
        application = models.Suggestion(**APPLICATION_SOURCE)
        application.save(blocking=True)

        # This application is assigned to associate editor 1, but it is not yet stale enough to require a reminder
        emails = {}
        async_workflow_notifications.associate_editor_notifications(emails)
        assert_false(emails)

        # When we make the application unchanged for a period of time, we expect a message to be generated
        [APPLICATION_SOURCE_2, APPLICATION_SOURCE_3
         ] = ApplicationFixtureFactory.make_many_application_sources(count=2)
        comfortably_idle = app.config['ASSOC_ED_IDLE_DAYS'] + 1
        APPLICATION_SOURCE_2['last_manual_update'] = datetime.utcnow(
        ) - timedelta(days=comfortably_idle)
        application2 = models.Suggestion(**APPLICATION_SOURCE_2)
        application2.save()

        extremely_idle = app.config['ASSOC_ED_IDLE_WEEKS'] + 1
        APPLICATION_SOURCE_3['last_manual_update'] = datetime.utcnow(
        ) - timedelta(weeks=extremely_idle)
        application3 = models.Suggestion(**APPLICATION_SOURCE_3)
        application3.save()

        models.Suggestion.blockall([
            (application.id, application.last_updated),
            (application2.id, application2.last_updated),
            (application3.id, application3.last_updated)
        ])

        async_workflow_notifications.associate_editor_notifications(emails)
        assert len(emails) > 0
        assert ASSED1_SOURCE['email'] in list(emails.keys())

        email_text = emails[ASSED1_SOURCE['email']][1].pop()
        assert 'You have 2 application(s) assigned to you' in email_text
        assert 'including 1 which have been unchanged' in email_text

        ctx.pop()
Пример #41
0
    def test_11_delete_application_fail(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")
        account.add_role("publisher")

        # call create on the object (which will save it to the index)
        a = ApplicationsCrudApi.create(data, account)

        # let the index catch up
        time.sleep(2)

        # get a copy of the newly created version for use in test later
        created = models.Suggestion.pull(a.id)

        # call delete on the object in various context that will fail

        # without an account
        with self.assertRaises(Api401Error):
            ApplicationsCrudApi.delete(a.id, None)

        # with the wrong account
        account.set_id("other")
        with self.assertRaises(Api404Error):
            ApplicationsCrudApi.delete(a.id, account)

        # on the wrong id
        account.set_id("test")
        with self.assertRaises(Api404Error):
            ApplicationsCrudApi.delete("adfasdfhwefwef", account)

        # on one with a disallowed workflow status
        created.set_application_status(constants.APPLICATION_STATUS_ACCEPTED)
        created.save()
        time.sleep(2)

        with self.assertRaises(Api403Error):
            ApplicationsCrudApi.delete(a.id, account)
Пример #42
0
    def test_05_outgoing_application_do(self):
        # make a blank one
        oa = OutgoingApplication()

        # make one from an incoming application model fixture
        data = ApplicationFixtureFactory.make_application_source()
        ap = models.Suggestion(**data)
        oa = OutgoingApplication.from_model(ap)

        # check that it does not contain information that it shouldn't
        assert oa.data.get("index") is None
        assert oa.data.get("history") is None
        assert oa.data.get("admin", {}).get("notes") is None
        assert oa.data.get("admin", {}).get("editor_group") is None
        assert oa.data.get("admin", {}).get("editor") is None
        assert oa.data.get("admin", {}).get("seal") is None
        assert oa.data.get("admin", {}).get("related_journal") is None

        # check that it does contain admin information that it should
        assert oa.data.get("admin", {}).get("current_journal") is not None
Пример #43
0
    def test_05_outgoing_application_do(self):
        # make a blank one
        oa = OutgoingApplication()

        # make one from an incoming application model fixture
        data = ApplicationFixtureFactory.make_update_request_source()
        ap = models.Suggestion(**data)
        oa = OutgoingApplication.from_model(ap)

        # check that it does not contain information that it shouldn't
        assert oa.data.get("index") is None
        assert oa.data.get("history") is None
        assert oa.data.get("admin", {}).get("notes") is None
        assert oa.data.get("admin", {}).get("editor_group") is None
        assert oa.data.get("admin", {}).get("editor") is None
        assert oa.data.get("admin", {}).get("seal") is None
        assert oa.data.get("admin", {}).get("related_journal") is None

        # check that it does contain admin information that it should
        assert oa.data.get("admin", {}).get("current_journal") is not None
Пример #44
0
    def test_04_maned_review_continuations(self):
        # construct it from form data (with a known source)
        fc = formcontext.ApplicationFormFactory.get_form_context(
            role='admin',
            form_data=MultiDict(APPLICATION_FORM),
            source=models.Suggestion(**ApplicationFixtureFactory.make_application_source()))

        # check the form has the continuations data
        assert fc.form.replaces.data == ["1111-1111"]
        assert fc.form.is_replaced_by.data == ["2222-2222"]
        assert fc.form.discontinued_date.data == "2001-01-01"

        # run the crosswalk, don't test it at all in this test
        fc.form2target()
        # patch the target with data from the source
        fc.patch_target()

        # ensure the model has the continuations data
        assert fc.target.bibjson().replaces == ["1111-1111"]
        assert fc.target.bibjson().is_replaced_by == ["2222-2222"]
        assert fc.target.bibjson().discontinued_date == "2001-01-01"
Пример #45
0
    def test_07_retrieve_application_fail(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.make_update_request_source()
        ap = models.Suggestion(**data)
        ap.save()
        time.sleep(2)

        # no user
        with self.assertRaises(Api401Error):
            a = ApplicationsCrudApi.retrieve(ap.id, None)

        # wrong user
        account = models.Account()
        account.set_id("asdklfjaioefwe")
        with self.assertRaises(Api404Error):
            a = ApplicationsCrudApi.retrieve(ap.id, account)

        # non-existant application
        account = models.Account()
        account.set_id(ap.id)
        with self.assertRaises(Api404Error):
            a = ApplicationsCrudApi.retrieve("ijsidfawefwefw", account)
Пример #46
0
    def test_02a_create_application_success_variations(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")

        # try with only one issn
        data["bibjson"]["identifier"] = [{"type": "pissn", "id": "1234-5678"}]

        # call create on the object (which will save it to the index)
        a = ApplicationsCrudApi.create(data, account)

        # check that it got created successfully
        assert isinstance(a, models.Suggestion)

        time.sleep(2)

        s = models.Suggestion.pull(a.id)
        assert s is not None
Пример #47
0
    def test_04_background(self):
        provs = ProvenanceFixtureFactory.make_action_spread(MONTH_EDIT_OUTPUT, "edit", "month")
        for p in provs:
            p.save()

        apps = ApplicationFixtureFactory.make_application_spread(APPLICATION_YEAR_OUTPUT, "year")
        for a in apps:
            a.save()

        time.sleep(2)

        job = reporting.ReportingBackgroundTask.prepare("system", outdir=TMP_DIR, from_date="1970-01-01T00:00:00Z", to_date=dates.now())
        reporting.ReportingBackgroundTask.submit(job)

        time.sleep(2)

        job = models.BackgroundJob.pull(job.id)
        prov_outfiles = job.reference["reporting__provenance_outfiles"]
        cont_outfiles = job.reference["reporting__content_outfiles"]

        assert len(prov_outfiles) == 4
        assert len(cont_outfiles) == 1
Пример #48
0
    def test_12_delete_application_dryrun(self):
        # set up all the bits we need
        data = ApplicationFixtureFactory.incoming_application()
        del data["admin"]["current_journal"]
        account = models.Account()
        account.set_id("test")
        account.set_name("Tester")
        account.set_email("*****@*****.**")
        account.add_role("publisher")

        # call create on the object (which will save it to the index)
        a = ApplicationsCrudApi.create(data, account)

        # let the index catch up
        time.sleep(2)

        # now delete it with the dry run flag
        ApplicationsCrudApi.delete(a.id, account, dry_run=True)

        # let the index catch up
        time.sleep(2)

        ap = models.Suggestion.pull(a.id)
        assert ap is not None
Пример #49
0
    def test_02_create_applications_fail(self):
        # if the account is dud
        with self.assertRaises(Api401Error):
            data = ApplicationFixtureFactory.incoming_application()
            del data["admin"]["current_journal"]
            dataset = [data] * 10
            ids = ApplicationsBulkApi.create(dataset, None)

        # check that the index is empty, as none of them should have been made
        all = [x for x in models.Suggestion.iterall()]
        assert len(all) == 0

        # if the data is bust
        with self.assertRaises(Api400Error):
            account = models.Account()
            account.set_id("test")
            account.set_name("Tester")
            account.set_email("*****@*****.**")
            dataset = dataset[:5] + [{"some": {"junk": "data"}}] + dataset[5:]
            ids = ApplicationsBulkApi.create(dataset, account)

        # check that the index is empty, as none of them should have been made
        all = [x for x in models.Suggestion.iterall()]
        assert len(all) == 0
Пример #50
0
    eg.set_associates(["associate", "assan"])
    eg.set_name("Test Editor Group")
    return eg


mock_lcc_choices = [(u'H', u'Social Sciences'),
                    (u'HB1-3840', u'--Economic theory. Demography')]


def mock_lookup_code(code):
    if code == "H": return "Social Sciences"
    if code == "HB1-3840": return "Economic theory. Demography"
    return None


APPLICATION_SOURCE = ApplicationFixtureFactory.make_application_source()
APPLICATION_FORM = ApplicationFixtureFactory.make_application_form(
    role="assed")

######################################################
# Main test class
######################################################


class TestAssedAppReview(DoajTestCase):
    def setUp(self):
        super(TestAssedAppReview, self).setUp()

        self.editor_group_pull = models.EditorGroup.pull_by_key
        models.EditorGroup.pull_by_key = editor_group_pull
Пример #51
0
import logging
import re
from StringIO import StringIO
from copy import deepcopy

from portality import constants
from doajtest.fixtures import EditorGroupFixtureFactory, AccountFixtureFactory, ApplicationFixtureFactory, JournalFixtureFactory
from doajtest.helpers import DoajTestCase
from portality import models
from portality.formcontext import formcontext

APPLICATION_SOURCE_TEST_1 = ApplicationFixtureFactory.make_application_source()
APPLICATION_SOURCE_TEST_2 = ApplicationFixtureFactory.make_application_source()
APPLICATION_SOURCE_TEST_3 = ApplicationFixtureFactory.make_application_source()
APPLICATION_FORM = ApplicationFixtureFactory.make_application_form()

JOURNAL_SOURCE_TEST_1 = JournalFixtureFactory.make_journal_source()
JOURNAL_SOURCE_TEST_2 = JournalFixtureFactory.make_journal_source()

EDITOR_GROUP_SOURCE = EditorGroupFixtureFactory.make_editor_group_source()
EDITOR_SOURCE = AccountFixtureFactory.make_editor_source()
ASSED1_SOURCE = AccountFixtureFactory.make_assed1_source()
ASSED2_SOURCE = AccountFixtureFactory.make_assed2_source()
ASSED3_SOURCE = AccountFixtureFactory.make_assed3_source()

#####################################################################
# Mocks required to make some of the lookups work
#####################################################################


@classmethod
Пример #52
0
from portality.crosswalks.article_doaj_xml import DOAJXWalk
from portality.crosswalks.article_crossref_xml import CrossrefXWalk
from portality.formcontext import forms
from portality.formcontext.xwalks import suggestion_form
from portality import models
from werkzeug.datastructures import MultiDict
from copy import deepcopy
from portality import lcc

from doajtest.fixtures import JournalFixtureFactory, ApplicationFixtureFactory

JOURNAL_FORM = JournalFixtureFactory.make_journal_form()
JOURNAL_FORMINFO = JournalFixtureFactory.make_journal_form_info()
JOURNAL_SOURCE = JournalFixtureFactory.make_journal_source_with_legacy_info()

APPLICATION_FORM = ApplicationFixtureFactory.make_application_form()
APPLICATION_FORMINFO = ApplicationFixtureFactory.make_application_form_info()
APPLICATION_SOURCE = ApplicationFixtureFactory.make_update_request_source()

OLD_STYLE_APP = ApplicationFixtureFactory.make_update_request_source()
del OLD_STYLE_APP["bibjson"]["persistent_identifier_scheme"]
del OLD_STYLE_APP["bibjson"]["deposit_policy"]
del OLD_STYLE_APP["bibjson"]["author_copyright"]
del OLD_STYLE_APP["bibjson"]["author_publishing_rights"]

######################################################################
# Mocks
######################################################################


def mock_lookup_code(code):
import re
from copy import deepcopy

from werkzeug.datastructures import MultiDict

from portality import constants
from doajtest.fixtures import JournalFixtureFactory, ApplicationFixtureFactory
from doajtest.helpers import DoajTestCase
from portality import models
from portality.formcontext import formcontext

#####################################################################
# Source objects to be used for testing
#####################################################################

UPDATE_REQUEST_SOURCE = ApplicationFixtureFactory.make_update_request_source()
UPDATE_REQUEST_SOURCE["admin"][
    "application_status"] = constants.APPLICATION_STATUS_UPDATE_REQUEST
UPDATE_REQUEST_FORM = ApplicationFixtureFactory.make_application_form(
    role="publisher")

######################################################
# Main test class
######################################################


class TestPublisherUpdateRequestFormContext(DoajTestCase):
    def setUp(self):
        super(TestPublisherUpdateRequestFormContext, self).setUp()

    def tearDown(self):
Пример #54
0
from datetime import datetime, timedelta

from nose.tools import assert_raises, assert_false

from portality import constants
from doajtest.fixtures import EditorGroupFixtureFactory, AccountFixtureFactory, ApplicationFixtureFactory, JournalFixtureFactory
from doajtest.helpers import DoajTestCase
from portality import models
from portality.background import BackgroundException
from portality.core import app
from portality.tasks import async_workflow_notifications

APPLICATION_SOURCE = ApplicationFixtureFactory.make_application_source()

JOURNAL_SOURCE_TEST_1 = JournalFixtureFactory.make_journal_source()
JOURNAL_SOURCE_TEST_2 = JournalFixtureFactory.make_journal_source()

EDITOR_GROUP_SOURCE = EditorGroupFixtureFactory.make_editor_group_source()
EDITOR_SOURCE = AccountFixtureFactory.make_editor_source()
ASSED1_SOURCE = AccountFixtureFactory.make_assed1_source()
ASSED2_SOURCE = AccountFixtureFactory.make_assed2_source()
ASSED3_SOURCE = AccountFixtureFactory.make_assed3_source()

#####################################################################
# Mocks required to make some of the lookups work
#####################################################################

@classmethod
def editor_group_pull_by_key(cls, field, value):
    eg = models.EditorGroup(**EDITOR_GROUP_SOURCE)
    return eg
Пример #55
0
import requests, json, time
from copy import deepcopy
from doajtest.fixtures import ApplicationFixtureFactory, ArticleFixtureFactory

# applications
API = "http://localhost:5004/api/v1/bulk/applications"
KEY = "d117ad1b35b94469b3dae09c29bfed55"

dataset = [ApplicationFixtureFactory.incoming_application()] * 10

resp = requests.post(API + "?api_key=" + KEY, data=json.dumps(dataset))
assert resp.status_code == 201

j = resp.json()
assert len(j) == 10

print j

ids = [r.get("id") for r in j]
print ids

time.sleep(2)

resp = requests.delete(API + "?api_key=" + KEY, data=json.dumps(ids))
assert resp.status_code == 204

# articles
# make sure you give the api key of a user who has a journal which is
# in_doaj = True and also has the same ISSNs as the articles in the test
# data - usually this will be PISSN 1234-5678 and EISSN 9876-5432
API = "http://localhost:5004/api/v1/bulk/articles"
Пример #56
0
    def test_01_delete_application(self, name, application_type, account_type,
                                   current_journal, related_journal, raises):

        ###############################################
        ## set up

        # create the test application (if needed), and the associated current_journal and related_journal in suitable states
        application = None
        cj = None
        rj = None
        if application_type == "found" or application_type == "locked":
            application = Suggestion(
                **ApplicationFixtureFactory.make_application_source())

            if current_journal == "none":
                application.remove_current_journal()
            elif current_journal == "not_found":
                application.set_current_journal("123456789987654321")
            elif current_journal == "found":
                cj = Journal(**JournalFixtureFactory.make_journal_source())
                cj.set_id(cj.makeid())
                cj.save(blocking=True)
                application.set_current_journal(cj.id)
            elif current_journal == "locked":
                cj = Journal(**JournalFixtureFactory.make_journal_source())
                cj.set_id(cj.makeid())
                cj.save(blocking=True)
                application.set_current_journal(cj.id)
                lock.lock(constants.LOCK_JOURNAL, cj.id, "otheruser")

            if related_journal == "none":
                application.remove_related_journal()
            elif related_journal == "not_found":
                application.set_related_journal("123456789987654321")
            elif related_journal == "found":
                rj = Journal(**JournalFixtureFactory.make_journal_source())
                rj.set_id(rj.makeid())
                rj.save(blocking=True)
                application.set_related_journal(rj.id)
            elif related_journal == "locked":
                rj = Journal(**JournalFixtureFactory.make_journal_source())
                rj.set_id(rj.makeid())
                rj.save(blocking=True)
                application.set_related_journal(rj.id)
                lock.lock(constants.LOCK_JOURNAL, rj.id, "otheruser")

        acc = None
        if account_type != "none":
            acc = Account(**AccountFixtureFactory.make_publisher_source())
            if account_type == "not_permitted":
                acc.remove_role("publisher")
            if application_type == "locked":
                thelock = lock.lock(constants.LOCK_APPLICATION, application.id,
                                    "otheruser")
                # we can't explicitly block on the lock, but we can halt until we confirm it is saved
                thelock.blockall([(thelock.id, thelock.last_updated)])

        application_id = None
        if application is not None:
            if acc is not None:
                application.set_owner(acc.id)
            application.save(blocking=True)
            application_id = application.id
        elif application_type == "not_found":
            application_id = "sdjfasofwefkwflkajdfasjd"

        ###########################################################
        # Execution

        svc = DOAJ.applicationService()
        if raises != "":
            with self.assertRaises(EXCEPTIONS[raises]):
                svc.delete_application(application_id, acc)
            time.sleep(1)
            check_locks(application, cj, rj, acc)
        else:
            svc.delete_application(application_id, acc)

            # we need to sleep, so the index catches up
            time.sleep(1)

            # check that no locks remain set for this user
            check_locks(application, cj, rj, acc)

            # check that the application actually is gone
            if application is not None:
                assert Suggestion.pull(application.id) is None

            # check that the current journal no longer has a reference to the application
            if cj is not None:
                cj = Journal.pull(cj.id)
                assert cj.current_application is None

            # check that the related journal has a record that the application was deleted
            if rj is not None:
                rj = Journal.pull(rj.id)
                record = rj.related_application_record(application.id)
                assert "status" in record
                assert record["status"] == "deleted"
    def test_01_accept_application(self, name, application_type, account_type, manual_update, provenance, raises, result_provenance, result_manual_update):

        ###############################################
        ## set up

        # create the application
        application = None
        if application_type == "save_fail":
            application = Suggestion(**ApplicationFixtureFactory.make_application_source())
            application.save = mock_save
            Journal.save = mock_save
        elif application_type == "with_current_journal":
            application = Suggestion(**ApplicationFixtureFactory.make_application_source())
            application.remove_notes()
            application.add_note("unique 1", "2002-01-01T00:00:00Z")
            application.add_note("duplicate", "2001-01-01T00:00:00Z")
            cj = application.current_journal
            journal = Journal(**JournalFixtureFactory.make_journal_source())
            journal.set_id(cj)
            journal.remove_notes()
            journal.add_note("unique 2", "2003-01-01T00:00:00Z")
            journal.add_note("duplicate", "2001-01-01T00:00:00Z")
            journal.save(blocking=True)
        elif application_type == "no_current_journal":
            application = Suggestion(**ApplicationFixtureFactory.make_application_source())
            application.remove_current_journal()


        acc = None
        if account_type == "not_allowed":
            acc = Account(**AccountFixtureFactory.make_publisher_source())
        elif account_type == "allowed":
            acc = Account(**AccountFixtureFactory.make_managing_editor_source())

        mu = None
        if manual_update in ["true", "false"]:
            mu = manual_update == "true"

        prov = None
        if provenance in ["true", "false"]:
            prov = provenance == "true"

        save = bool(randint(0,1))

        ###########################################################
        # Execution

        svc = DOAJ.applicationService()
        if raises != "":
            with self.assertRaises(EXCEPTIONS[raises]):
                svc.accept_application(application, acc, mu, prov)
        else:
            journal = svc.accept_application(application, acc, mu, prov, save_journal=save, save_application=save)

            # we need to sleep, so the index catches up
            time.sleep(1)

            # check a few common things
            assert application.application_status == constants.APPLICATION_STATUS_ACCEPTED
            assert application.current_journal is None
            assert journal.current_application is None
            assert application.related_journal == journal.id

            related = journal.related_applications
            if application_type == "with_current_journal":
                assert len(related) == 3
            elif application_type == "no_current_journal":
                assert len(related) == 1
            assert related[0].get("application_id") == application.id
            assert related[0].get("date_accepted") is not None

            if result_manual_update == "yes":
                assert journal.last_manual_update is not None
                assert journal.last_manual_update != "1970-01-01T00:00:00Z"
                assert application.last_manual_update is not None
                assert application.last_manual_update != "1970-01-01T00:00:00Z"
            elif result_manual_update == "no":
                assert journal.last_manual_update is None
                assert application.last_manual_update is None

            if application_type == "with_current_journal":
                assert len(journal.notes) == 3
                notevals = [note.get("note") for note in journal.notes]
                assert "duplicate" in notevals
                assert "unique 1" in notevals
                assert "unique 2" in notevals

            app_prov = Provenance.get_latest_by_resource_id(application.id)
            if result_provenance == "yes":
                assert app_prov is not None
            elif result_provenance == "no":
                assert app_prov is None

            if save:
                pass