Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
edx-platform
Commits
9a33f385
Commit
9a33f385
authored
Oct 18, 2017
by
Calen Pennington
Committed by
Dillon Dumesnil
Oct 31, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move bin-task enqueuing into a classmethod (rather than having it on the RecipientResolvers
parent
c6e9a7a8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
207 additions
and
141 deletions
+207
-141
openedx/core/djangoapps/schedules/management/commands/__init__.py
+13
-7
openedx/core/djangoapps/schedules/management/commands/send_course_update.py
+2
-4
openedx/core/djangoapps/schedules/management/commands/send_recurring_nudge.py
+2
-4
openedx/core/djangoapps/schedules/management/commands/send_upgrade_reminder.py
+2
-4
openedx/core/djangoapps/schedules/management/commands/tests/test_base.py
+7
-18
openedx/core/djangoapps/schedules/management/commands/tests/test_send_recurring_nudge.py
+23
-24
openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py
+19
-21
openedx/core/djangoapps/schedules/resolvers.py
+0
-0
openedx/core/djangoapps/schedules/tasks.py
+93
-4
openedx/core/djangoapps/schedules/tests/test_tasks.py
+46
-55
No files found.
openedx/core/djangoapps/schedules/management/commands/__init__.py
View file @
9a33f385
...
...
@@ -8,7 +8,6 @@ from openedx.core.djangoapps.schedules.utils import PrefixedDebugLoggerMixin
class
SendEmailBaseCommand
(
PrefixedDebugLoggerMixin
,
BaseCommand
):
resolver_class
=
None
# define in subclass
async_send_task
=
None
# define in subclass
def
add_arguments
(
self
,
parser
):
...
...
@@ -24,20 +23,27 @@ class SendEmailBaseCommand(PrefixedDebugLoggerMixin, BaseCommand):
parser
.
add_argument
(
'site_domain_name'
)
def
handle
(
self
,
*
args
,
**
options
):
resolver
=
self
.
make_resolver
(
*
args
,
**
options
)
self
.
send_emails
(
resolver
,
*
args
,
**
options
)
self
.
log_debug
(
'Args =
%
r'
,
options
)
def
make_resolver
(
self
,
*
args
,
**
options
):
current_date
=
datetime
.
datetime
(
*
[
int
(
x
)
for
x
in
options
[
'date'
]
.
split
(
'-'
)],
tzinfo
=
pytz
.
UTC
)
self
.
log_debug
(
'Args =
%
r'
,
options
)
self
.
log_debug
(
'Current date =
%
s'
,
current_date
.
isoformat
())
site
=
Site
.
objects
.
get
(
domain__iexact
=
options
[
'site_domain_name'
])
self
.
log_debug
(
'Running for site
%
s'
,
site
.
domain
)
return
self
.
resolver_class
(
site
,
current_date
,
async_send_task
=
self
.
async_send_task
)
def
send_emails
(
self
,
resolver
,
*
args
,
**
options
):
override_recipient_email
=
options
.
get
(
'override_recipient_email'
)
self
.
send_emails
(
site
,
current_date
,
override_recipient_email
)
def
enqueue
(
self
,
day_offset
,
site
,
current_date
,
override_recipient_email
=
None
):
self
.
async_send_task
.
enqueue
(
site
,
current_date
,
day_offset
,
override_recipient_email
,
)
def
send_emails
(
self
,
*
args
,
**
kwargs
):
pass
# define in subclass
openedx/core/djangoapps/schedules/management/commands/send_course_update.py
View file @
9a33f385
from
openedx.core.djangoapps.schedules.management.commands
import
SendEmailBaseCommand
from
openedx.core.djangoapps.schedules.resolvers
import
CourseUpdateResolver
from
openedx.core.djangoapps.schedules.tasks
import
ScheduleCourseUpdate
class
Command
(
SendEmailBaseCommand
):
resolver_class
=
CourseUpdateResolver
async_send_task
=
ScheduleCourseUpdate
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
Command
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
log_prefix
=
'Upgrade Reminder'
def
send_emails
(
self
,
resolver
,
*
args
,
**
option
s
):
def
send_emails
(
self
,
*
args
,
**
kwarg
s
):
for
day_offset
in
xrange
(
-
7
,
-
77
,
-
7
):
resolver
.
send
(
day_offset
,
options
.
get
(
'override_recipient_email'
)
)
self
.
enqueue
(
day_offset
,
*
args
,
**
kwargs
)
openedx/core/djangoapps/schedules/management/commands/send_recurring_nudge.py
View file @
9a33f385
from
openedx.core.djangoapps.schedules.management.commands
import
SendEmailBaseCommand
from
openedx.core.djangoapps.schedules.resolvers
import
ScheduleStartResolver
from
openedx.core.djangoapps.schedules.tasks
import
ScheduleRecurringNudge
class
Command
(
SendEmailBaseCommand
):
resolver_class
=
ScheduleStartResolver
async_send_task
=
ScheduleRecurringNudge
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
Command
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
log_prefix
=
'Scheduled Nudge'
def
send_emails
(
self
,
resolver
,
*
args
,
**
option
s
):
def
send_emails
(
self
,
*
args
,
**
kwarg
s
):
for
day_offset
in
(
-
3
,
-
10
):
resolver
.
send
(
day_offset
,
options
.
get
(
'override_recipient_email'
)
)
self
.
enqueue
(
day_offset
,
*
args
,
**
kwargs
)
openedx/core/djangoapps/schedules/management/commands/send_upgrade_reminder.py
View file @
9a33f385
from
openedx.core.djangoapps.schedules.management.commands
import
SendEmailBaseCommand
from
openedx.core.djangoapps.schedules.resolvers
import
UpgradeReminderResolver
from
openedx.core.djangoapps.schedules.tasks
import
ScheduleUpgradeReminder
class
Command
(
SendEmailBaseCommand
):
resolver_class
=
UpgradeReminderResolver
async_send_task
=
ScheduleUpgradeReminder
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
Command
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
log_prefix
=
'Upgrade Reminder'
def
send_emails
(
self
,
resolver
,
*
args
,
**
option
s
):
resolver
.
send
(
2
,
options
.
get
(
'override_recipient_email'
)
)
def
send_emails
(
self
,
*
args
,
**
kwarg
s
):
self
.
enqueue
(
2
,
*
args
,
**
kwargs
)
openedx/core/djangoapps/schedules/management/commands/tests/test_base.py
View file @
9a33f385
...
...
@@ -18,24 +18,13 @@ from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_un
class
TestSendEmailBaseCommand
(
CacheIsolationTestCase
):
def
setUp
(
self
):
self
.
command
=
SendEmailBaseCommand
()
self
.
site
=
SiteFactory
()
def
test_init_resolver_class
(
self
):
assert
self
.
command
.
resolver_class
is
None
def
test_make_resolver
(
self
):
with
patch
.
object
(
self
.
command
,
'resolver_class'
)
as
resolver_class
:
example_site
=
SiteFactory
(
domain
=
'example.com'
)
self
.
command
.
make_resolver
(
site_domain_name
=
'example.com'
,
date
=
'2017-09-29'
)
resolver_class
.
assert_called_once_with
(
example_site
,
def
test_handle
(
self
):
with
patch
.
object
(
self
.
command
,
'send_emails'
)
as
send_emails
:
self
.
command
.
handle
(
site_domain_name
=
self
.
site
.
domain
,
date
=
'2017-09-29'
)
send_emails
.
assert_called_once_with
(
self
.
site
,
datetime
.
datetime
(
2017
,
9
,
29
,
tzinfo
=
pytz
.
UTC
),
async_send_task
=
None
,
None
)
def
test_handle
(
self
):
with
patch
.
object
(
self
.
command
,
'make_resolver'
)
as
make_resolver
:
make_resolver
.
return_value
=
'resolver'
with
patch
.
object
(
self
.
command
,
'send_emails'
)
as
send_emails
:
self
.
command
.
handle
(
date
=
'2017-09-29'
)
make_resolver
.
assert_called_once_with
(
date
=
'2017-09-29'
)
send_emails
.
assert_called_once_with
(
'resolver'
,
date
=
'2017-09-29'
)
openedx/core/djangoapps/schedules/management/commands/tests/test_send_recurring_nudge.py
View file @
9a33f385
...
...
@@ -60,35 +60,33 @@ class TestSendRecurringNudge(FilteredQueryCountMixin, CacheIsolationTestCase):
DynamicUpgradeDeadlineConfiguration
.
objects
.
create
(
enabled
=
True
)
@patch.object
(
nudge
.
Command
,
'
resolver_class
'
)
def
test_handle
(
self
,
mock_
resolver
):
@patch.object
(
nudge
.
Command
,
'
async_send_task
'
)
def
test_handle
(
self
,
mock_
send
):
test_day
=
datetime
.
datetime
(
2017
,
8
,
1
,
tzinfo
=
pytz
.
UTC
)
nudge
.
Command
()
.
handle
(
date
=
'2017-08-01'
,
site_domain_name
=
self
.
site_config
.
site
.
domain
)
mock_resolver
.
assert_called_with
(
self
.
site_config
.
site
,
test_day
,
async_send_task
=
nudge
.
Command
.
async_send_task
,
)
for
day
in
(
-
3
,
-
10
):
mock_resolver
()
.
send
.
assert_any_call
(
day
,
None
)
mock_send
.
enqueue
.
assert_any_call
(
self
.
site_config
.
site
,
test_day
,
day
,
None
)
@patch.object
(
tasks
,
'ace'
)
def
test_resolver_send
(
self
,
mock_ace
):
current_day
=
datetime
.
datetime
(
2017
,
8
,
1
,
tzinfo
=
pytz
.
UTC
)
mock_schedule_bin
=
Mock
()
nudge
.
ScheduleStartResolver
(
self
.
site_config
.
site
,
current_day
,
mock_schedule_bin
)
.
send
(
-
3
)
test_day
=
current_day
+
datetime
.
timedelta
(
days
=-
3
)
self
.
assertFalse
(
mock_schedule_bin
.
called
)
mock_schedule_bin
.
apply_async
.
assert_any_call
(
(
self
.
site_config
.
site
.
id
,
serialize
(
test_day
),
-
3
,
0
,
[],
True
,
None
),
retry
=
False
,
)
mock_schedule_bin
.
apply_async
.
assert_any_call
(
(
self
.
site_config
.
site
.
id
,
serialize
(
test_day
),
-
3
,
resolvers
.
RECURRING_NUDGE_NUM_BINS
-
1
,
[],
True
,
None
),
retry
=
False
,
)
self
.
assertFalse
(
mock_ace
.
send
.
called
)
with
patch
.
object
(
tasks
.
ScheduleRecurringNudge
,
'apply_async'
)
as
mock_apply_async
:
tasks
.
ScheduleRecurringNudge
.
enqueue
(
self
.
site_config
.
site
,
current_day
,
-
3
)
test_day
=
current_day
+
datetime
.
timedelta
(
days
=-
3
)
mock_apply_async
.
assert_any_call
(
(
self
.
site_config
.
site
.
id
,
serialize
(
test_day
),
-
3
,
0
,
[],
True
,
None
),
retry
=
False
,
)
mock_apply_async
.
assert_any_call
(
(
self
.
site_config
.
site
.
id
,
serialize
(
test_day
),
-
3
,
resolvers
.
RECURRING_NUDGE_NUM_BINS
-
1
,
[],
True
,
None
),
retry
=
False
,
)
self
.
assertFalse
(
mock_ace
.
send
.
called
)
@ddt.data
(
1
,
10
,
100
)
@patch.object
(
tasks
,
'ace'
)
...
...
@@ -180,11 +178,12 @@ class TestSendRecurringNudge(FilteredQueryCountMixin, CacheIsolationTestCase):
mock_schedule_bin
=
Mock
()
current_datetime
=
datetime
.
datetime
(
2017
,
8
,
1
,
tzinfo
=
pytz
.
UTC
)
nudge
.
ScheduleStartResolver
(
tasks
.
ScheduleRecurringNudge
.
enqueue
(
self
.
site_config
.
site
,
current_datetime
,
mock_schedule_bin
,
)
.
send
(
3
)
3
)
self
.
assertFalse
(
mock_schedule_bin
.
called
)
self
.
assertFalse
(
mock_schedule_bin
.
apply_async
.
called
)
self
.
assertFalse
(
mock_ace
.
send
.
called
)
...
...
openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py
View file @
9a33f385
...
...
@@ -63,36 +63,34 @@ class TestUpgradeReminder(FilteredQueryCountMixin, CacheIsolationTestCase):
DynamicUpgradeDeadlineConfiguration
.
objects
.
create
(
enabled
=
True
)
@patch.object
(
reminder
.
Command
,
'
resolver_class
'
)
def
test_handle
(
self
,
mock_
resolver
):
@patch.object
(
reminder
.
Command
,
'
async_send_task
'
)
def
test_handle
(
self
,
mock_
send
):
test_day
=
datetime
.
datetime
(
2017
,
8
,
1
,
tzinfo
=
pytz
.
UTC
)
reminder
.
Command
()
.
handle
(
date
=
'2017-08-01'
,
site_domain_name
=
self
.
site_config
.
site
.
domain
)
mock_
resolver
.
assert_called_with
(
mock_
send
.
enqueue
.
assert_called_with
(
self
.
site_config
.
site
,
test_day
,
async_send_task
=
reminder
.
Command
.
async_send_task
,
2
,
None
)
mock_resolver
()
.
send
.
assert_any_call
(
2
,
None
)
@patch.object
(
tasks
,
'ace'
)
def
test_resolver_send
(
self
,
mock_ace
):
current_day
=
datetime
.
datetime
(
2017
,
8
,
1
,
tzinfo
=
pytz
.
UTC
)
test_day
=
current_day
+
datetime
.
timedelta
(
days
=
2
)
ScheduleFactory
.
create
(
upgrade_deadline
=
datetime
.
datetime
(
2017
,
8
,
3
,
15
,
34
,
30
,
tzinfo
=
pytz
.
UTC
))
mock_schedule_bin
=
Mock
()
reminder
.
UpgradeReminderResolver
(
self
.
site_config
.
site
,
current_day
,
mock_schedule_bin
)
.
send
(
2
)
self
.
assertFalse
(
mock_schedule_bin
.
called
)
mock_schedule_bin
.
apply_async
.
assert_any_call
(
(
self
.
site_config
.
site
.
id
,
serialize
(
test_day
),
2
,
0
,
[],
True
,
None
),
retry
=
False
,
)
mock_schedule_bin
.
apply_async
.
assert_any_call
(
(
self
.
site_config
.
site
.
id
,
serialize
(
test_day
),
2
,
resolvers
.
UPGRADE_REMINDER_NUM_BINS
-
1
,
[],
True
,
None
),
retry
=
False
,
)
self
.
assertFalse
(
mock_ace
.
send
.
called
)
with
patch
.
object
(
tasks
.
ScheduleUpgradeReminder
,
'apply_async'
)
as
mock_apply_async
:
tasks
.
ScheduleUpgradeReminder
.
enqueue
(
self
.
site_config
.
site
,
current_day
,
2
)
mock_
apply_async
.
assert_any_call
(
(
self
.
site_config
.
site
.
id
,
serialize
(
test_day
),
2
,
0
,
[],
True
,
None
),
retry
=
False
,
)
mock_
apply_async
.
assert_any_call
(
(
self
.
site_config
.
site
.
id
,
serialize
(
test_day
),
2
,
resolvers
.
UPGRADE_REMINDER_NUM_BINS
-
1
,
[],
True
,
None
),
retry
=
False
,
)
self
.
assertFalse
(
mock_ace
.
send
.
called
)
@ddt.data
(
1
,
10
,
100
)
@patch.object
(
tasks
,
'ace'
)
...
...
@@ -164,11 +162,11 @@ class TestUpgradeReminder(FilteredQueryCountMixin, CacheIsolationTestCase):
mock_schedule_bin
=
Mock
()
current_day
=
datetime
.
datetime
(
2017
,
8
,
1
,
tzinfo
=
pytz
.
UTC
)
reminder
.
UpgradeReminderResolver
(
tasks
.
ScheduleUpgradeReminder
.
enqueue
(
self
.
site_config
.
site
,
current_day
,
async_send_task
=
mock_schedule_bin
,
)
.
send
(
3
)
day_offset
=
3
,
)
self
.
assertFalse
(
mock_schedule_bin
.
called
)
self
.
assertFalse
(
mock_schedule_bin
.
apply_async
.
called
)
self
.
assertFalse
(
mock_ace
.
send
.
called
)
...
...
openedx/core/djangoapps/schedules/resolvers.py
View file @
9a33f385
This diff is collapsed.
Click to expand it.
openedx/core/djangoapps/schedules/tasks.py
View file @
9a33f385
...
...
@@ -13,13 +13,14 @@ from django.utils.formats import dateformat, get_format
from
edx_ace
import
ace
from
edx_ace.message
import
Message
from
edx_ace.recipient
import
Recipient
from
edx_ace.utils.date
import
deserialize
from
edx_ace.utils.date
import
deserialize
,
serialize
from
opaque_keys.edx.keys
import
CourseKey
from
openedx.core.djangoapps.monitoring_utils
import
set_custom_metric
from
openedx.core.djangoapps.schedules.models
import
Schedule
,
ScheduleConfig
from
openedx.core.djangoapps.schedules
import
resolvers
from
openedx.core.djangoapps.site_configuration.models
import
SiteConfiguration
LOG
=
logging
.
getLogger
(
__name__
)
...
...
@@ -68,12 +69,91 @@ def _recurring_nudge_schedule_send(site_id, msg_str):
class
ScheduleMessageBaseTask
(
Task
):
ignore_result
=
True
routing_key
=
ROUTING_KEY
num_bins
=
resolvers
.
DEFAULT_NUM_BINS
enqueue_config_var
=
None
# define in subclass
log_prefix
=
None
@classmethod
def
log_debug
(
cls
,
message
,
*
args
,
**
kwargs
):
LOG
.
debug
(
cls
.
log_prefix
+
': '
+
message
,
*
args
,
**
kwargs
)
@classmethod
def
enqueue
(
cls
,
site
,
current_date
,
day_offset
,
override_recipient_email
=
None
):
current_date
=
current_date
.
replace
(
hour
=
0
,
minute
=
0
,
second
=
0
)
if
not
cls
.
is_enqueue_enabled
(
site
):
cls
.
log_debug
(
'Message queuing disabled for site
%
s'
,
site
.
domain
)
return
exclude_orgs
,
org_list
=
cls
.
get_course_org_filter
(
site
)
target_date
=
current_date
+
datetime
.
timedelta
(
days
=
day_offset
)
cls
.
log_debug
(
'Target date =
%
s'
,
target_date
.
isoformat
())
for
bin
in
range
(
cls
.
num_bins
):
task_args
=
(
site
.
id
,
serialize
(
target_date
),
day_offset
,
bin
,
org_list
,
exclude_orgs
,
override_recipient_email
,
)
cls
.
log_debug
(
'Launching task with args =
%
r'
,
task_args
)
cls
.
apply_async
(
task_args
,
retry
=
False
,
)
@classmethod
def
is_enqueue_enabled
(
cls
,
site
):
if
cls
.
enqueue_config_var
:
return
getattr
(
ScheduleConfig
.
current
(
site
),
cls
.
enqueue_config_var
)
return
False
@classmethod
def
get_course_org_filter
(
cls
,
site
):
"""
Given the configuration of sites, get the list of orgs that should be included or excluded from this send.
Returns:
tuple: Returns a tuple (exclude_orgs, org_list). If exclude_orgs is True, then org_list is a list of the
only orgs that should be included in this send. If exclude_orgs is False, then org_list is a list of
orgs that should be excluded from this send. All other orgs should be included.
"""
try
:
site_config
=
SiteConfiguration
.
objects
.
get
(
site_id
=
site
.
id
)
org_list
=
site_config
.
get_value
(
'course_org_filter'
)
exclude_orgs
=
False
if
not
org_list
:
not_orgs
=
set
()
for
other_site_config
in
SiteConfiguration
.
objects
.
all
():
other
=
other_site_config
.
get_value
(
'course_org_filter'
)
if
not
isinstance
(
other
,
list
):
if
other
is
not
None
:
not_orgs
.
add
(
other
)
else
:
not_orgs
.
update
(
other
)
org_list
=
list
(
not_orgs
)
exclude_orgs
=
True
elif
not
isinstance
(
org_list
,
list
):
org_list
=
[
org_list
]
except
SiteConfiguration
.
DoesNotExist
:
org_list
=
None
exclude_orgs
=
False
finally
:
return
exclude_orgs
,
org_list
class
ScheduleRecurringNudge
(
ScheduleMessageBaseTask
):
num_bins
=
resolvers
.
RECURRING_NUDGE_NUM_BINS
enqueue_config_var
=
'enqueue_recurring_nudge'
log_prefix
=
'Scheduled Nudge'
def
run
(
self
,
site_id
,
target_day_str
,
day_offset
,
bin_num
,
org_list
,
exclude_orgs
=
False
,
override_recipient_email
=
None
,
):
return
resolvers
.
recurring_nudge_schedule_bin
(
return
resolvers
.
ScheduleStartResolver
()
.
recurring_nudge_schedule_bin
(
_recurring_nudge_schedule_send
,
site_id
,
target_day_str
,
...
...
@@ -86,10 +166,15 @@ class ScheduleRecurringNudge(ScheduleMessageBaseTask):
class
ScheduleUpgradeReminder
(
ScheduleMessageBaseTask
):
num_bins
=
resolvers
.
UPGRADE_REMINDER_NUM_BINS
enqueue_config_var
=
'enqueue_upgrade_reminder'
log_prefix
=
'Course Update'
def
run
(
self
,
site_id
,
target_day_str
,
day_offset
,
bin_num
,
org_list
,
exclude_orgs
=
False
,
override_recipient_email
=
None
,
):
return
resolvers
.
upgrade_reminder_schedule_bin
(
return
resolvers
.
UpgradeReminderResolver
()
.
upgrade_reminder_schedule_bin
(
_upgrade_reminder_schedule_send
,
site_id
,
target_day_str
,
...
...
@@ -111,10 +196,14 @@ def _upgrade_reminder_schedule_send(site_id, msg_str):
class
ScheduleCourseUpdate
(
ScheduleMessageBaseTask
):
num_bins
=
resolvers
.
COURSE_UPDATE_NUM_BINS
enqueue_config_var
=
'enqueue_course_update'
log_prefix
=
'Course Update'
def
run
(
self
,
site_id
,
target_day_str
,
day_offset
,
bin_num
,
org_list
,
exclude_orgs
=
False
,
override_recipient_email
=
None
,
):
return
resolvers
.
course_update_schedule_bin
(
return
resolvers
.
CourseUpdateResolver
()
.
course_update_schedule_bin
(
_course_update_schedule_send
,
site_id
,
target_day_str
,
...
...
openedx/core/djangoapps/schedules/tests/test_
resolver
s.py
→
openedx/core/djangoapps/schedules/tests/test_
task
s.py
View file @
9a33f385
...
...
@@ -3,9 +3,9 @@ from unittest import skipUnless
import
ddt
from
django.conf
import
settings
from
mock
import
patch
from
mock
import
patch
,
DEFAULT
,
Mock
from
openedx.core.djangoapps.schedules.
resolvers
import
BinnedSchedulesBaseResolver
from
openedx.core.djangoapps.schedules.
tasks
import
ScheduleMessageBaseTask
from
openedx.core.djangoapps.schedules.resolvers
import
DEFAULT_NUM_BINS
from
openedx.core.djangoapps.schedules.tests.factories
import
ScheduleConfigFactory
from
openedx.core.djangoapps.site_configuration.tests.factories
import
SiteConfigurationFactory
,
SiteFactory
...
...
@@ -16,68 +16,61 @@ from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_un
@skip_unless_lms
@skipUnless
(
'openedx.core.djangoapps.schedules.apps.SchedulesConfig'
in
settings
.
INSTALLED_APPS
,
"Can't test schedules if the app isn't installed"
)
class
Test
BinnedSchedulesBaseResolver
(
CacheIsolationTestCase
):
class
Test
ScheduleMessageBaseTask
(
CacheIsolationTestCase
):
def
setUp
(
self
):
super
(
Test
BinnedSchedulesBaseResolver
,
self
)
.
setUp
()
super
(
Test
ScheduleMessageBaseTask
,
self
)
.
setUp
()
self
.
site
=
SiteFactory
.
create
()
self
.
site_config
=
SiteConfigurationFactory
.
create
(
site
=
self
.
site
)
self
.
schedule_config
=
ScheduleConfigFactory
.
create
(
site
=
self
.
site
)
def
setup_resolver
(
self
,
site
=
None
,
current_date
=
None
,
async_send_task
=
None
):
if
site
is
None
:
site
=
self
.
site
if
current_date
is
None
:
current_date
=
datetime
.
datetime
.
now
()
resolver
=
BinnedSchedulesBaseResolver
(
self
.
site
,
current_date
,
async_send_task
)
return
resolver
def
test_init_site
(
self
):
resolver
=
self
.
setup_resolver
()
assert
resolver
.
site
==
self
.
site
def
test_init_current_date
(
self
):
current_time
=
datetime
.
datetime
.
now
()
resolver
=
self
.
setup_resolver
(
current_date
=
current_time
)
current_date
=
current_time
.
replace
(
hour
=
0
,
minute
=
0
,
second
=
0
)
assert
resolver
.
current_date
==
current_date
def
test_init_async_send_task
(
self
):
resolver
=
self
.
setup_resolver
()
assert
resolver
.
async_send_task
is
None
def
test_init_num_bins
(
self
):
resolver
=
self
.
setup_resolver
()
assert
resolver
.
num_bins
==
DEFAULT_NUM_BINS
self
.
basetask
=
ScheduleMessageBaseTask
def
test_send_enqueue_disabled
(
self
):
resolver
=
self
.
setup_resolver
()
resolver
.
is_enqueue_enabled
=
lambda
:
False
with
patch
.
object
(
resolver
,
'async_send_task'
)
as
send
:
with
patch
.
object
(
resolver
,
'log_debug'
)
as
log_debug
:
resolver
.
send
(
day_offset
=
2
)
log_debug
.
assert_called_once_with
(
'Message queuing disabled for site
%
s'
,
self
.
site
.
domain
)
send
.
apply_async
.
assert_not_called
()
send
=
Mock
(
name
=
'async_send_task'
)
with
patch
.
multiple
(
self
.
basetask
,
is_enqueue_enabled
=
Mock
(
return_value
=
False
),
log_debug
=
DEFAULT
,
run
=
send
,
)
as
patches
:
self
.
basetask
.
enqueue
(
site
=
self
.
site
,
current_date
=
datetime
.
datetime
.
now
(),
day_offset
=
2
)
patches
[
'log_debug'
]
.
assert_called_once_with
(
'Message queuing disabled for site
%
s'
,
self
.
site
.
domain
)
send
.
apply_async
.
assert_not_called
()
@ddt.data
(
0
,
2
,
-
3
)
def
test_send_enqueue_enabled
(
self
,
day_offset
):
resolver
=
self
.
setup_resolver
()
resolver
.
is_enqueue_enabled
=
lambda
:
True
resolver
.
get_course_org_filter
=
lambda
:
(
False
,
None
)
with
patch
.
object
(
resolver
,
'async_send_task'
)
as
send
:
with
patch
.
object
(
resolver
,
'log_debug'
)
as
log_debug
:
resolver
.
send
(
day_offset
=
day_offset
)
target_date
=
resolver
.
current_date
+
datetime
.
timedelta
(
day_offset
)
log_debug
.
assert_any_call
(
'Target date =
%
s'
,
target_date
.
isoformat
())
assert
send
.
apply_async
.
call_count
==
DEFAULT_NUM_BINS
send
=
Mock
(
name
=
'async_send_task'
)
current_date
=
datetime
.
datetime
.
now
()
with
patch
.
multiple
(
self
.
basetask
,
is_enqueue_enabled
=
Mock
(
return_value
=
True
),
get_course_org_filter
=
Mock
(
return_value
=
(
False
,
None
)),
log_debug
=
DEFAULT
,
run
=
send
,
)
as
patches
:
self
.
basetask
.
enqueue
(
site
=
self
.
site
,
current_date
=
current_date
,
day_offset
=
day_offset
)
target_date
=
current_date
.
replace
(
hour
=
0
,
minute
=
0
,
second
=
0
)
+
\
datetime
.
timedelta
(
day_offset
)
print
(
patches
[
'log_debug'
]
.
mock_calls
)
patches
[
'log_debug'
]
.
assert_any_call
(
'Target date =
%
s'
,
target_date
.
isoformat
())
assert
send
.
call_count
==
DEFAULT_NUM_BINS
@ddt.data
(
True
,
False
)
def
test_is_enqueue_enabled
(
self
,
enabled
):
resolver
=
self
.
setup_resolver
()
resolver
.
enqueue_config_var
=
'enqueue_recurring_nudge'
self
.
schedule_config
.
enqueue_recurring_nudge
=
enabled
self
.
schedule_config
.
save
()
assert
resolver
.
is_enqueue_enabled
()
==
enabled
with
patch
.
object
(
self
.
basetask
,
'enqueue_config_var'
,
'enqueue_recurring_nudge'
):
self
.
schedule_config
.
enqueue_recurring_nudge
=
enabled
self
.
schedule_config
.
save
()
assert
self
.
basetask
.
is_enqueue_enabled
(
self
.
site
)
==
enabled
@ddt.unpack
@ddt.data
(
...
...
@@ -85,10 +78,9 @@ class TestBinnedSchedulesBaseResolver(CacheIsolationTestCase):
([
'course1'
,
'course2'
],
[
'course1'
,
'course2'
])
)
def
test_get_course_org_filter_include
(
self
,
course_org_filter
,
expected_org_list
):
resolver
=
self
.
setup_resolver
()
self
.
site_config
.
values
[
'course_org_filter'
]
=
course_org_filter
self
.
site_config
.
save
()
exclude_orgs
,
org_list
=
resolver
.
get_course_org_filter
(
)
exclude_orgs
,
org_list
=
self
.
basetask
.
get_course_org_filter
(
self
.
site
)
assert
not
exclude_orgs
assert
org_list
==
expected_org_list
...
...
@@ -99,12 +91,11 @@ class TestBinnedSchedulesBaseResolver(CacheIsolationTestCase):
([
'course1'
,
'course2'
],
[
u'course1'
,
u'course2'
])
)
def
test_get_course_org_filter_exclude
(
self
,
course_org_filter
,
expected_org_list
):
resolver
=
self
.
setup_resolver
()
self
.
other_site
=
SiteFactory
.
create
()
self
.
other_site_config
=
SiteConfigurationFactory
.
create
(
site
=
self
.
other_site
,
values
=
{
'course_org_filter'
:
course_org_filter
},
)
exclude_orgs
,
org_list
=
resolver
.
get_course_org_filter
(
)
exclude_orgs
,
org_list
=
self
.
basetask
.
get_course_org_filter
(
self
.
site
)
assert
exclude_orgs
self
.
assertItemsEqual
(
org_list
,
expected_org_list
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment