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()
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()
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)
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
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) ]
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")
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
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
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
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()))
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)
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
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
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
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
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)
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
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
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
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"
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
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"
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
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()
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
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
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
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()
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
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) ]
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
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
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
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)
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()
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()
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)
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
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
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"
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)
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
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
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
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
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
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
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):
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
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"
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