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
edx
edx-platform
Commits
d222b2d7
Commit
d222b2d7
authored
Oct 18, 2017
by
Calen Pennington
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
352fa067
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 @
d222b2d7
...
...
@@ -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 @
d222b2d7
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 @
d222b2d7
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 @
d222b2d7
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 @
d222b2d7
...
...
@@ -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 @
d222b2d7
...
...
@@ -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 @
d222b2d7
...
...
@@ -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 @
d222b2d7
This diff is collapsed.
Click to expand it.
openedx/core/djangoapps/schedules/tasks.py
View file @
d222b2d7
...
...
@@ -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 @
d222b2d7
...
...
@@ -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