Skip to content
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions cms/data/notifications.yml
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,15 @@ journal:maned:discontinuing_soon:notify:
Journal "{title}" (id: {id}) will discontinue in {days} days.
short:
Journal discontinuing

flag:assigned:
long: |
"A new flag in "{journal_title}" (id: {id}) has been assigned to you"
short:
New flag

flag:reminder:
long: |
"The deadline for the flag in "{journal_title}" (id: {id}) is in 7 days."
short:
Deadline reminder
69 changes: 62 additions & 7 deletions doajtest/testbook/flagged_journals/flagged_journals.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,32 @@ tests:
role: Admin
steps:
- step: Navigate to /testdrive/flags
- step: Login as an admin
- step: Open Feline Aerodynamics Review application (available on your dashboard)
- step: In a separate tab login as LordWiggleworth (admin)
- step: Open Feline Aerodynamics Review journal (available on your dashboard)
results:
- Above the notes there is the Add Flag button visible and active
- step: Click Add Flag button
results:
- An empty flag form is displayed
- step: In assigned_to input attempt to add editor's id (you can find it in your testdrive/flags data)
- step: In assigned_to input attempt to add "MadamPonderleaf" (an editor)
results:
- No matches found is displayed and it is not possible to assign the editor
- step: In assigned_to input add random_user's id (you can find it in your testdrive/flags data)
- step: In assigned_to input add "ProfessorQuibbleton" (admin)
results:
- Id is found and it can be selected
- step: Select the random_user's id
- step: Select "ProfessorQuibbleton"
- step: In deadline input add an improbable date (e.g., 2025-02-31)
results:
- It's not possible to enter an improbable date
- step: In deadline input add a valid date
- step: In deadline input add a date in a past
results:
- A warning "Provided deadline is in the past. Is it correct?" is displayed under the deadline input
- step: Save the form (do not close it)
results:
- Journal form is saved correctly
- step: In deadline input add a date in exactly 1 week
results:
- Warning disappears
- step: In text area add flag's note (any text)
- step: Save application
results:
Expand Down Expand Up @@ -72,6 +80,53 @@ tests:
- In the flag form, in the Assign a User input, there is your id with a red flag icon
- Resolve Flag button is active and all fields are editable

- title: Admin - Flags Notifications
context:
role: Admin
setup:
- If you haven't performed previous test (Admin - Add, Edit, Resolve) prepare the Journal by following all the steps; otherwise you may omit steps 2-9
steps:
- step: Navigate to /testdrive/flags
- step: In a separate tab login as LordWiggleworth (admin)
- step: Open Feline Aerodynamics Review journal (available on your dashboard)
- step: Click Add Flag button
- step: Assign "ProfessorQuibbleton" (admin)
- step: Add deadline in exactly 1 week
- step: In text area add flag's note (any text)
- step: Save application, Unlock & Close the form
- step: Log out
- step: In a separate tab log in as "ProfessorQuibbleton"
results:
- At the top navbar Notifications indicate a new notification
- step: Hover over Notifications button
result:
- At the top of the list new notification "New flag" is listed
- step: Click on the notification
results:
- Feline Aerodynamics Review journal form is opened in a new tab
- On the right the flag is displayed and assigned to you ("ProfessorQuibbleton")
- step: Unlock & Close the form, close the tab
- step: Click the Notifications button at the top navigation bar
results:
- /dashboard/notifications opens
- At the top of the list "New flag" notification is displayed.
- The long description says "A new flag in 'Feline Aerodynamics Review' (id) has been assigned to you"
- step: Open the testdrive/flags page <b>do not close the page where you are logged in</b>
- step: Click "Run background task" button, wait for the task to execute
result:
- Message "Script executed successfully!" is displayed
- step: Go back to the tab where you are logged as ProfessorQuibbleton
- step: refresh the page
- step: navigate to /dashboard/notifications if not already there
results:
- At the top of the notifications list a new notification "Deadline reminder" is listed
- Long description says "The deadline for the flag in 'Feline Aerodynamics Review' (id) is in 7 days."
- At the top navbar Notifications button has a new notification marked
- step: Click "See action" link at the right of the new "Deadline reminder" notification
results:
- Feline Aerodynamics Review journal form is opened in a new tab
- step: Unlock & Close the form, close the tab

- title: Admin - Dashboard [NOT CURRENTLY USED]
context:
role: Admin
Expand Down Expand Up @@ -129,7 +184,7 @@ tests:
role: Editor
steps:
- step: Navigate to /testdrive/flags
- step: Login as an editor
- step: Login as MadamPonderleaf (editor)
- step: Navigate to /applications
- step: Open to Open Journal of Intergalactic Diplomacy - make sure you haven't resolved the flag while logged as an admin in one of the previous tests
results:
Expand Down
74 changes: 39 additions & 35 deletions doajtest/testdrive/flags.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from doajtest.fixtures import ApplicationFixtureFactory, JournalFixtureFactory
from doajtest.fixtures import JournalFixtureFactory
from doajtest.testdrive.factory import TestDrive
from portality.lib import dates
from portality import models, constants
Expand All @@ -8,9 +8,10 @@ class Flags(TestDrive):

def __init__(self):
self.another_eg = None
self.apps = []
self.journals = []
self.admin_password = None
self.admin = None
self.anotheradmin = None
self.editor = None
self.editor_password = None
self.random_user = None
Expand All @@ -19,13 +20,17 @@ def __init__(self):

def setup(self) -> dict:
self.create_accounts()
self.build_applications()
self.build_journals()
return {
"accounts": {
"admin": {
"username": self.admin.id,
"password": self.admin_password
},
"another admin": {
"username": self.anotheradmin.id,
"password": self.anotheradmin_password
},
"editor": {
"username": self.editor.id,
"password": self.editor_password
Expand All @@ -35,30 +40,42 @@ def setup(self) -> dict:
"password": self.random_user_password
}
},
"applications": self.apps,
"journals": self.build_journals,
"non_renderable": {
"editor_groups": [self.eg.name, self.another_eg.name]
},
"script": {
"script_name": "find_approaching_deadlines",
"title": "Run background task"
}
}

def create_accounts(self):
admin_name = self.create_random_str()

admin_name = "LordWiggleworth"
self.admin_password = self.create_random_str()
self.admin = models.Account.make_account(admin_name + "@example.com", admin_name, "FlagsManed " + admin_name,
["admin", "editor"])
self.admin.set_password(self.admin_password)
self.admin.save()

random_name = self.create_random_str()
anotheradmin_name = "ProfessorQuibbleton"
self.anotheradmin_password = self.create_random_str()
self.anotheradmin = models.Account.make_account(anotheradmin_name + "@example.com", anotheradmin_name, "Admin " + anotheradmin_name,
["admin", "editor"])
self.anotheradmin.set_password(self.anotheradmin_password)
self.anotheradmin.save()

random_name = "BaronFeatherfall"
self.random_user_password = self.create_random_str()
self.random_user = models.Account.make_account(random_name + "@example.com", random_name,
"FlagsManed " + random_name,
"Admin " + random_name,
["admin"])
self.random_user.set_password(self.random_user_password)
self.random_user.save()

editor_name = self.create_random_str()
self.editor = models.Account.make_account(editor_name + "@example.com", editor_name, "editor " + editor_name,
editor_name = "MadamPonderleaf"
self.editor = models.Account.make_account(editor_name + "@example.com", editor_name, "Editor " + editor_name,
["editor"])
self.editor_password = self.create_random_str()
self.editor.set_password(self.editor_password)
Expand All @@ -80,8 +97,8 @@ def create_accounts(self):
self.another_eg.set_editor(self.editor.id)
self.another_eg.save()

def build_applications(self):
applications = [
def build_journals(self):
journals = [
{
"type": models.Journal,
"title": "Journal of Quantum Homeopathy",
Expand All @@ -92,30 +109,25 @@ def build_applications(self):
"note": "Peer review process unclear. The journal claims to use “ancient wisdom and telepathic consensus” to select papers. Should we request further clarification, or just accept that the universe decides?"
},
{
"type": models.Application,
"type": models.Journal,
"title": "The Mars Agricultural Review",
"application_type": constants.APPLICATION_TYPE_NEW_APPLICATION,
"status": "in progress",
"assigned_to": self.editor.id,
"flagged_to": self.admin.id,
"group": self.eg.name,
"deadline": 10,
"note": "Ethical concerns? Their conflict of interest statement is just 'Trust us.' Also, every editorial board member shares the same last name. Suspicious? Or just an enthusiastic family business?"
},
{
"type": models.Application,
"type": models.Journal,
"title": "Cryptid Behavioral Studies Quarterly",
"application_type": constants.APPLICATION_TYPE_UPDATE_REQUEST,
"assigned_to": self.editor.id,
"flagged_to": self.admin.id,
"group": self.eg.name,
"note": "Formatting issues. Their abstracts are in Comic Sans, their references are in Wingdings, and their figures appear to be hand-drawn with crayon. Surprisingly, it almost adds to the charm."
},
{
"type": models.Application,
"type": models.Journal,
"title": "The Bermuda Triangle Journal of Lost and Found",
"application_type": constants.APPLICATION_TYPE_NEW_APPLICATION,
"status": "on hold",
"assigned_to": self.editor.id,
"flagged_to": self.editor.id,
"group": self.eg.name,
Expand All @@ -128,42 +140,34 @@ def build_applications(self):
"group": self.eg.name
},
{
"type": models.Application,
"type": models.Journal,
"title": "Journal of Intergalactic Diplomacy",
"application_type": constants.APPLICATION_TYPE_NEW_APPLICATION,
"assigned_to": self.random_user.id,
"flagged_to": self.admin.id,
"group": self.another_eg.name,
"deadline": 0,
"note": "Editorial process... innovative? They claim to have a 100% acceptance rate because “rejecting knowledge is against our values.” Admirable, but I feel like that’s not how this works."
},
{
"type": models.Application,
"type": models.Journal,
"title": "Applied Alchemy & Unstable Chemistry",
"application_type": constants.APPLICATION_TYPE_UPDATE_REQUEST,
"assigned_to": self.random_user.id,
"flagged_to": self.editor.id,
"note": "Journal scope mismatch. The journal is called The International Review of Advanced Neuroscience but 90\% of its articles are about cat memes. Honestly, I’d subscribe, but should we approve it?",
"group": self.another_eg.name
}
]

for record in applications:
source = ApplicationFixtureFactory.make_application_source()
ap = models.Application(**source)
if "application_type" in record:
source["admin"]["application_type"] = record["application_type"]
for record in journals:
source = JournalFixtureFactory.make_journal_source(True)
ap = models.Journal(**source)
bj = ap.bibjson()
bj.title = record["title"]
ap.set_id(ap.makeid())
ap.set_last_manual_update(dates.today())
ap.set_created(dates.before_now(200))
ap.remove_current_journal()
ap.remove_related_journal()
ap.set_editor_group(record["group"])
ap.set_editor(record["assigned_to"])
if "status" in record:
ap.set_application_status(record["status"])
if "flagged_to" in record:
note = {"id": self.create_random_str(),
"note": record["note"],
Expand All @@ -176,14 +180,14 @@ def build_applications(self):
}}
ap.set_notes(note)
ap.save()
self.apps.append(ap.id)
self.journals.append(ap.id)

def teardown(self, params):
for acc in params.get("accounts").values():
models.Account.remove_by_id(acc["username"])

for app in params.get("applications"):
models.Application.remove_by_id(app)
for app in params.get("journals"):
models.Journal.remove_by_id(app)

print(params.get("non_renderable"))
print(params.get("non_renderable").get("editor_groups"))
Expand Down
53 changes: 53 additions & 0 deletions doajtest/unit/event_consumers/test_flag_assigned.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from portality import models
from portality import constants
from portality.bll import exceptions
from doajtest.helpers import DoajTestCase
from portality.events.consumers.flag_assigned import FlagAssigned
from doajtest.fixtures import JournalFixtureFactory
import time


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

def tearDown(self):
super(TestFlagAssigned, self).tearDown()

def test_should_consume(self):
event = models.Event(constants.EVENT_FLAG_ASSIGNED, context={"assignee": "rudolph", "journal": JournalFixtureFactory.make_journal_source()})
assert FlagAssigned.should_consume(event)

def test_consume_success(self):
with self._make_and_push_test_context_manager("/"):

jsource = JournalFixtureFactory.make_journal_source()
j = models.Journal(**jsource)
j.save()

acc = models.Account()
acc.set_id("LadyBranbury")
acc.set_email("ladybranbury@example.com")
acc.save()

event = models.Event(constants.EVENT_FLAG_ASSIGNED, context={"journal": j.data, "assignee": acc.id})
FlagAssigned.consume(event)

time.sleep(1)
ns = models.Notification.all()
assert len(ns) == 1

n = ns[0]
assert n.who == "LadyBranbury"
assert n.created_by == FlagAssigned.ID
assert n.classification == constants.NOTIFICATION_CLASSIFICATION_ASSIGN
assert n.long is not None
assert n.short is not None
assert n.action is not None
assert not n.is_seen()

def test_consume_fail(self):
event = models.Event(constants.EVENT_FLAG_ASSIGNED, context={"application": {'stuff': 'nonsense'}})
with self.assertRaises(exceptions.NoSuchObjectException):
FlagAssigned.consume(event)

Loading