Commit 6f664838 by Christina Roberts

Merge pull request #11202 from edx/release

Release for Jan 12, 2016
parents 775c3cac dd6dc019
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='AssetBaseUrlConfig',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('change_date', models.DateTimeField(auto_now_add=True, verbose_name='Change date')),
('enabled', models.BooleanField(default=False, verbose_name='Enabled')),
('base_url', models.TextField(help_text=b'The alternative hostname to serve static assets from. Should be in the form of hostname[:port].', blank=True)),
('changed_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='Changed by')),
],
),
]
...@@ -7,6 +7,18 @@ ...@@ -7,6 +7,18 @@
<input type="text" id="calculator_input" tabindex="-1" /> <input type="text" id="calculator_input" tabindex="-1" />
<div class="help-wrapper"> <div class="help-wrapper">
<a id="calculator_hint" href="#" role="button" aria-haspopup="true" tabindex="-1">Hints</a> <a id="calculator_hint" href="#" role="button" aria-haspopup="true" tabindex="-1">Hints</a>
<ul id="calculator_input_help" class="help" aria-activedescendant="hint-integers" role="tooltip" aria-hidden="true">
<li class="hint-item" id="hint-moreinfo" tabindex="-1">
<p>
<span class="bold">For detailed information, see
<a id="hint-link-first" href="http://edx-guide-for-students.readthedocs.org/en/latest/SFD_mathformatting.html">Entering Mathematical and Scientific Expressions</a>in the
<a id="hint-link-second" href="http://edx-guide-for-students.readthedocs.org/en/latest/index.html">edX Guide for Students </a> format
</span>
</p>
</li>
<li class="hint-item" id="hint-integers" tabindex="-1"><p><span class="bold">Integers:</span> 2520</p></li>
<li class="hint-item" id="hint-decimals" tabindex="-1"><p><span class="bold">Decimals:</span> 3.14 or .98</p></li>
</ul>
</div> </div>
</div> </div>
<input id="calculator_button" type="submit" title="Calculate" arial-label="Calculate" value="=" tabindex="-1" /> <input id="calculator_button" type="submit" title="Calculate" arial-label="Calculate" value="=" tabindex="-1" />
...@@ -14,18 +26,4 @@ ...@@ -14,18 +26,4 @@
</form> </form>
</div> </div>
</li> </li>
<li>
<ul id="calculator_input_help" class="calc-help-popup" aria-activedescendant="hint-integers" role="tooltip" aria-hidden="true">
<li class="hint-item" id="hint-moreinfo" tabindex="-1">
<p>
<span class="bold">For detailed information, see
<a id="hint-link-first" href="http://edx-guide-for-students.readthedocs.org/en/latest/SFD_mathformatting.html">Entering Mathematical and Scientific Expressions</a>in the
<a id="hint-link-second" href="http://edx-guide-for-students.readthedocs.org/en/latest/index.html">edX Guide for Students </a> format
</span>
</p>
</li>
<li class="hint-item" id="hint-integers" tabindex="-1"><p><span class="bold">Integers:</span> 2520</p></li>
<li class="hint-item" id="hint-decimals" tabindex="-1"><p><span class="bold">Decimals:</span> 3.14 or .98</p></li>
</ul>
</li>
</ul> </ul>
...@@ -61,35 +61,35 @@ describe 'Calculator', -> ...@@ -61,35 +61,35 @@ describe 'Calculator', ->
describe 'showHint', -> describe 'showHint', ->
it 'show the help overlay', -> it 'show the help overlay', ->
@calculator.showHint() @calculator.showHint()
expect($('.calc-help-popup')).toHaveClass('shown') expect($('.help')).toHaveClass('shown')
expect($('.calc-help-popup')).toHaveAttr('aria-hidden', 'false') expect($('.help')).toHaveAttr('aria-hidden', 'false')
describe 'hideHint', -> describe 'hideHint', ->
it 'show the help overlay', -> it 'show the help overlay', ->
@calculator.hideHint() @calculator.hideHint()
expect($('.calc-help-popup')).not.toHaveClass('shown') expect($('.help')).not.toHaveClass('shown')
expect($('.calc-help-popup')).toHaveAttr('aria-hidden', 'true') expect($('.help')).toHaveAttr('aria-hidden', 'true')
describe 'handleClickOnHintButton', -> describe 'handleClickOnHintButton', ->
it 'on click hint button hint popup becomes visible ', -> it 'on click hint button hint popup becomes visible ', ->
e = jQuery.Event('click'); e = jQuery.Event('click');
$('#calculator_hint').trigger(e); $('#calculator_hint').trigger(e);
expect($('.calc-help-popup')).toHaveClass 'shown' expect($('.help')).toHaveClass 'shown'
describe 'handleClickOnDocument', -> describe 'handleClickOnDocument', ->
it 'on click out of the hint popup it becomes hidden', -> it 'on click out of the hint popup it becomes hidden', ->
@calculator.showHint() @calculator.showHint()
e = jQuery.Event('click'); e = jQuery.Event('click');
$(document).trigger(e); $(document).trigger(e);
expect($('.calc-help-popup')).not.toHaveClass 'shown' expect($('.help')).not.toHaveClass 'shown'
describe 'handleClickOnHintPopup', -> describe 'handleClickOnHintPopup', ->
it 'on click of hint popup it remains visible', -> it 'on click of hint popup it remains visible', ->
@calculator.showHint() @calculator.showHint()
e = jQuery.Event('click'); e = jQuery.Event('click');
$('#calculator_input_help').trigger(e); $('#calculator_input_help').trigger(e);
expect($('.calc-help-popup')).toHaveClass 'shown' expect($('.help')).toHaveClass 'shown'
describe 'selectHint', -> describe 'selectHint', ->
it 'select correct hint item', -> it 'select correct hint item', ->
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
class @Calculator class @Calculator
constructor: -> constructor: ->
@hintButton = $('#calculator_hint') @hintButton = $('#calculator_hint')
@hintPopup = $('.calc-help-popup') @hintPopup = $('.help')
@hintsList = @hintPopup.find('.hint-item') @hintsList = @hintPopup.find('.hint-item')
@selectHint($('#' + @hintPopup.attr('aria-activedescendant'))); @selectHint($('#' + @hintPopup.attr('aria-activedescendant')));
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
@include transition(bottom $tmg-avg linear 0s); @include transition(bottom $tmg-avg linear 0s);
-webkit-appearance: none; -webkit-appearance: none;
width: 100%; width: 100%;
direction: ltr;
&.open { &.open {
bottom: -36px; bottom: -36px;
...@@ -53,6 +52,17 @@ ...@@ -53,6 +52,17 @@
background: $black; background: $black;
color: $white; color: $white;
// UI: input help table
.calculator-input-help-table {
margin: ($baseline/2) 0;
tr th, tr td {
vertical-align: top;
border: 1px solid $gray-l4;
padding: ($baseline/2);
}
}
form { form {
@extend .clearfix; @extend .clearfix;
@include box-sizing(border-box); @include box-sizing(border-box);
...@@ -147,7 +157,6 @@ ...@@ -147,7 +157,6 @@
border: none; border: none;
background: url("#{$static-path}/images/info-icon.png") center center no-repeat; background: url("#{$static-path}/images/info-icon.png") center center no-repeat;
color: $white; color: $white;
cursor: pointer;
&:focus { &:focus {
outline: 5px auto #5b9dd9; outline: 5px auto #5b9dd9;
...@@ -160,85 +169,47 @@ ...@@ -160,85 +169,47 @@
color: $white; color: $white;
} }
} }
}
}
}
}
}
.calc-help-popup {
@include transition(none);
position: fixed; .help {
left: 180px; @include transition(none);
right: 180px; background: $white;
top: 70px; border-radius: 3px;
bottom: 90px; box-shadow: 0 0 3px #999;
overflow: auto; color: #333;
padding: 10px;
background: $white; position: absolute;
border-radius: 3px; right: -40px;
box-shadow: // Standard 3px black shadow. bottom: 57px;
0 0 3px #999, width: 600px;
// Places a overlay black transparent popup background. overflow: hidden;
0 0 0 4000em rgba(0, 0, 0, 0.20); pointer-events: none;
display: none;
color: #333; margin: 0;
padding: 10px; list-style: none;
pointer-events: none; &.shown {
display: none; display: block;
margin: 0; pointer-events: auto;
list-style: none; }
// UI: input help table
.calculator-input-help-table {
margin: ($baseline/2) auto;
tr th, tr td {
vertical-align: top;
border: 1px solid $gray-l4;
padding: ($baseline/2);
}
}
&.shown {
display: block;
pointer-events: auto;
}
.bold { .bold {
font-weight: bold; font-weight: bold;
} }
p, p+p { p, p+p {
margin: 0; margin: 0;
} }
.calc-postfixes { .calc-postfixes {
margin: 10px auto; margin: 10px auto;
td, th { td, th {
padding: 2px 15px; padding: 2px 15px;
}
}
}
}
}
} }
} }
@media screen and (max-width: 990px) {
left: 20px;
right: 20px;
}
@media screen and (min-width: 991px) and (max-width: 1999px) {
left: 20%;
right: 20%;
}
@media screen and (min-width: 2000px) {
left: 35%;
right: 35%;
padding-bottom: 40px;
bottom: auto;
}
} }
...@@ -17,7 +17,121 @@ from django.core.urlresolvers import reverse ...@@ -17,7 +17,121 @@ from django.core.urlresolvers import reverse
<div class="help-wrapper"> <div class="help-wrapper">
<p class="sr" id="hint-instructions">${_('Use the arrow keys to navigate the tips or use the tab key to return to the calculator')}</p> <p class="sr" id="hint-instructions">${_('Use the arrow keys to navigate the tips or use the tab key to return to the calculator')}</p>
<a href="#" id="calculator_hint" aria-haspopup="true" aria-expanded="false" aria-controls="calculator_input_help" aria-describedby="hint-instructions"><span class="calc-hint sr">${_("Hints")}</span></a> <button id="calculator_hint" aria-haspopup="true" aria-expanded="false" aria-controls="calculator_input_help" aria-describedby="hint-instructions"><span class="calc-hint sr">${_("Hints")}</span></button>
<ul id="calculator_input_help" class="help" aria-hidden="true">
<li class="hint-item" id="hint-moreinfo">
<p><span class="bold">${_("For detailed information, see {math_link_start}Entering Mathematical and Scientific Expressions{math_link_end} in the {guide_link_start}edX Guide for Students{guide_link_end}.").format(
math_link_start='<a href="http://edx-guide-for-students.readthedocs.org/en/latest/SFD_mathformatting.html">',
math_link_end='</a>',
guide_link_start='<a href="http://edx-guide-for-students.readthedocs.org/en/latest/index.html">',
guide_link_end='</a>',
)}</span></p>
</li>
<li class="hint-item" id="hint-tips"><p><span class="bold">${_("Tips")}:</span> </p>
<ul>
<li class="hint-item" id="hint-paren"><p>${_("Use parentheses () to make expressions clear. You can use parentheses inside other parentheses.")}</p></li>
<li class="hint-item" id="hint-spaces"><p>${_("Do not use spaces in expressions.")}</p></li>
<li class="hint-item" id="hint-howto-constants"><p>${_("For constants, indicate multiplication explicitly (example: 5*c).")}</p></li>
<li class="hint-item" id="hint-howto-maffixes"><p>${_("For affixes, type the number and affix without a space (example: 5c).")}</p></li>
<li class="hint-item" id="hint-howto-functions"><p>${_("For functions, type the name of the function, then the expression in parentheses.")}</p></li>
</ul>
</li>
<li class="hint-item" id="hint-list">
<table class="calculator-input-help-table">
<tbody>
<tr>
<th scope="col">${_("To Use")}</th>
<th scope="col">${_("Type")}</th>
<th scope="col">${_("Examples")}</th>
</tr>
<tr>
<th scope="row">${_("Numbers")}</th>
<td>${_("Integers")}<br />
${_("Fractions")}<br />
${_("Decimals")}
</td>
<td>2520<br />
2/3<br />
3.14, .98
</td>
</tr>
<tr>
<th scope="row">${_("Operators")}</th>
## Translators: Please do not translate mathematical symbols.
<td>${_("+ - * / (add, subtract, multiply, divide)")}<br />
## Translators: Please do not translate mathematical symbols.
${_("^ (raise to a power)")}<br />
## Translators: Please do not translate mathematical symbols.
${_("_ (add a subscript)")}<br />
## Translators: Please do not translate mathematical symbols.
${_("|| (parallel resistors)")}
</td>
<td>x+(2*y)/x-1
x^(n+1)<br />
v_IN+v_OUT<br />
1||2
</td>
</tr>
<tr>
<th scope="row">${_("Greek letters")}</th>
<td>${_("Name of letter")}</td>
<td>alpha<br />
lambda
</td>
</tr>
<tr>
<th scope="row">${_("Constants")}</th>
<td>c, e, g, i, j, k, pi, q, T</td>
<td>20*c<br />
418*T
</td>
</tr>
<tr>
<th scope="row">${_("Affixes")}</th>
<td>${_("Percent sign (%) and metric affixes (d, c, m, u, n, p, k, M, G, T)")}</td>
<td>20%<br />
20c<br />
418T
</td>
</tr>
<tr>
<th scope="row">${_("Basic functions")}</th>
<td>abs, exp, fact or factorial, ln, log2, log10, sqrt</td>
<td>abs(x+y)<br />
sqrt(x^2-y)
</td>
</tr>
<tr>
<th scope="row">${_("Trigonometric functions")}</th>
<td>sin, cos, tan, sec, csc, cot<br />
arcsin, sinh, arcsinh, etc.<br />
</td>
<td>sin(4x+y)<br />
arccsch(4x+y)
</td>
<td></td>
</tr>
<tr>
## Translators: Please see http://en.wikipedia.org/wiki/Scientific_notation
<th scope="row">${_("Scientific notation")}</th>
## Translators: 10^ is a mathematical symbol. Please do not translate.
<td>${_("10^ and the exponent")}</td>
<td>10^-9</td>
</tr>
<tr>
## Translators: this is part of scientific notation. Please see http://en.wikipedia.org/wiki/Scientific_notation#E_notation
<th scope="row">${_("e notation")}</th>
## Translators: 1e is a mathematical symbol. Please do not translate.
<td>${_("1e and the exponent")}</td>
<td>1e-9</td>
</tr>
</tbody>
</table>
</li>
</ul>
</div> </div>
</div> </div>
...@@ -26,119 +140,4 @@ from django.core.urlresolvers import reverse ...@@ -26,119 +140,4 @@ from django.core.urlresolvers import reverse
<input type="text" id="calculator_output" readonly /> <input type="text" id="calculator_output" readonly />
</form> </form>
</div> </div>
</div> </div>
<div id="calculator_input_help" class="calc-help-popup" aria-hidden="true">
<ul>
<li class="hint-item" id="hint-moreinfo">
<p><span class="bold">${_("For detailed information, see {math_link_start}Entering Mathematical and Scientific Expressions{math_link_end} in the {guide_link_start}edX Guide for Students{guide_link_end}.").format(
math_link_start='<a href="http://edx-guide-for-students.readthedocs.org/en/latest/SFD_mathformatting.html">',
math_link_end='</a>',
guide_link_start='<a href="http://edx-guide-for-students.readthedocs.org/en/latest/index.html">',
guide_link_end='</a>',
)}</span></p>
</li>
<li class="hint-item" id="hint-tips"><p><span class="bold">${_("Tips")}:</span> </p>
<ul>
<li class="hint-item" id="hint-paren"><p>${_("Use parentheses () to make expressions clear. You can use parentheses inside other parentheses.")}</p></li>
<li class="hint-item" id="hint-spaces"><p>${_("Do not use spaces in expressions.")}</p></li>
<li class="hint-item" id="hint-howto-constants"><p>${_("For constants, indicate multiplication explicitly (example: 5*c).")}</p></li>
<li class="hint-item" id="hint-howto-maffixes"><p>${_("For affixes, type the number and affix without a space (example: 5c).")}</p></li>
<li class="hint-item" id="hint-howto-functions"><p>${_("For functions, type the name of the function, then the expression in parentheses.")}</p></li>
</ul>
</li>
<li class="hint-item" id="hint-list">
<table class="calculator-input-help-table">
<tbody>
<tr>
<th scope="col">${_("To Use")}</th>
<th scope="col">${_("Type")}</th>
<th scope="col">${_("Examples")}</th>
</tr>
<tr>
<th scope="row">${_("Numbers")}</th>
<td dir="auto">${_("Integers")}<br />
${_("Fractions")}<br />
${_("Decimals")}
</td>
<td dir="auto">2520<br />
2/3<br />
3.14, .98
</td>
</tr>
<tr>
## Translators: This refers to mathematical operators such as `plus`, `minus`, `division` and others.
<th scope="row">${_("Operators")}</th>
<td dir="auto">
## Translators: Please do not translate mathematical symbols.
${_("+ - * / (add, subtract, multiply, divide)")}<br />
## Translators: Please do not translate mathematical symbols.
${_("^ (raise to a power)")}<br />
## Translators: Please do not translate mathematical symbols.
${_("|| (parallel resistors)")}
</td>
<td dir="auto">x+(2*y)/x-1
x^(n+1)<br />
v_IN+v_OUT<br />
1||2
</td>
</tr>
<tr>
## Translators: This refers to symbols that are mathematical constants, such as "i" (square root of -1)
<th scope="row">${_("Constants")}</th>
<td dir="auto">c, e, g, i, j, k, pi, q, T</td>
<td dir="auto">20*c<br />
418*T
</td>
</tr>
<tr>
## Translators: This refers to symbols that appear at the end of a number, such as the percent sign (%) and metric affixes
<th scope="row">${_("Affixes")}</th>
<td dir="auto">${_("Percent sign (%) and metric affixes (d, c, m, u, n, p, k, M, G, T)")}</td>
<td dir="auto">20%<br />
20c<br />
418T
</td>
</tr>
<tr>
## Translators: This refers to basic mathematical functions such as "square root"
<th scope="row">${_("Basic functions")}</th>
<td dir="auto">abs, exp, fact or factorial, ln, log2, log10, sqrt</td>
<td dir="auto">abs(x+y)<br />
sqrt(x^2-y)
</td>
</tr>
<tr>
## Translators: This refers to mathematical Sine, Cosine and Tan
<th scope="row">${_("Trigonometric functions")}</th>
<td dir="auto">sin, cos, tan, sec, csc, cot<br />
arcsin, sinh, arcsinh, etc.<br />
</td>
<td dir="auto">sin(4x+y)<br />
arccsch(4x+y)
</td>
<td dir="auto"></td>
</tr>
<tr>
## Translators: Please see http://en.wikipedia.org/wiki/Scientific_notation
<th scope="row">${_("Scientific notation")}</th>
## Translators: 10^ is a mathematical symbol. Please do not translate.
<td dir="auto">${_("10^ and the exponent")}</td>
<td dir="auto">10^-9</td>
</tr>
<tr>
## Translators: this is part of scientific notation. Please see http://en.wikipedia.org/wiki/Scientific_notation#E_notation
<th scope="row">${_("e notation")}</th>
## Translators: 1e is a mathematical symbol. Please do not translate.
<td dir="auto">${_("1e and the exponent")}</td>
<td dir="auto">1e-9</td>
</tr>
</tbody>
</table>
</li>
</ul>
</div>
...@@ -680,8 +680,9 @@ class CourseOverviewImageSet(TimeStampedModel): ...@@ -680,8 +680,9 @@ class CourseOverviewImageSet(TimeStampedModel):
# an error or the course has no source course_image), our url fields # an error or the course has no source course_image), our url fields
# just keep their blank defaults. # just keep their blank defaults.
try: try:
image_set.save() with transaction.atomic():
course_overview.image_set = image_set image_set.save()
course_overview.image_set = image_set
except (IntegrityError, ValueError): except (IntegrityError, ValueError):
# In the event of a race condition that tries to save two image sets # In the event of a race condition that tries to save two image sets
# to the same CourseOverview, we'll just silently pass on the one # to the same CourseOverview, we'll just silently pass on the one
......
...@@ -32,7 +32,7 @@ from xmodule.modulestore.django import modulestore ...@@ -32,7 +32,7 @@ from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls, check_mongo_calls_range from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls, check_mongo_calls_range
from .models import CourseOverview, CourseOverviewImageConfig from .models import CourseOverview, CourseOverviewImageSet, CourseOverviewImageConfig
@ddt.ddt @ddt.ddt
...@@ -494,6 +494,27 @@ class CourseOverviewTestCase(ModuleStoreTestCase): ...@@ -494,6 +494,27 @@ class CourseOverviewTestCase(ModuleStoreTestCase):
{c.id for c in org_courses[1]}, {c.id for c in org_courses[1]},
) )
def test_get_all_courses_by_mobile_available(self):
non_mobile_course = CourseFactory.create(emit_signals=True)
mobile_course = CourseFactory.create(mobile_available=True, emit_signals=True)
test_cases = (
(None, {non_mobile_course.id, mobile_course.id}),
(dict(mobile_available=True), {mobile_course.id}),
(dict(mobile_available=False), {non_mobile_course.id}),
)
for filter_, expected_courses in test_cases:
self.assertEqual(
{
course_overview.id
for course_overview in
CourseOverview.get_all_courses(filter_=filter_)
},
expected_courses,
"testing CourseOverview.get_all_courses with filter_={}".format(filter_),
)
@ddt.ddt @ddt.ddt
class CourseOverviewImageSetTestCase(ModuleStoreTestCase): class CourseOverviewImageSetTestCase(ModuleStoreTestCase):
...@@ -797,6 +818,43 @@ class CourseOverviewImageSetTestCase(ModuleStoreTestCase): ...@@ -797,6 +818,43 @@ class CourseOverviewImageSetTestCase(ModuleStoreTestCase):
self.assertEqual(src_x, image_x) self.assertEqual(src_x, image_x)
self.assertEqual(src_y, image_y) self.assertEqual(src_y, image_y)
def test_image_creation_race_condition(self):
"""
Test for race condition in CourseOverviewImageSet creation.
CourseOverviewTestCase already tests for race conditions with
CourseOverview as a whole, but we still need to test the case where a
CourseOverview already exists and we have a race condition purely in the
part that adds a new CourseOverviewImageSet.
"""
# Set config to False so that we don't create the image yet
self.set_config(False)
course = CourseFactory.create()
# First create our CourseOverview
overview = CourseOverview.get_from_id(course.id)
self.assertFalse(hasattr(overview, 'image_set'))
# Now create an ImageSet by hand...
CourseOverviewImageSet.objects.create(course_overview=overview)
# Now do it the normal way -- this will cause an IntegrityError to be
# thrown and suppressed in create_for_course()
self.set_config(True)
CourseOverviewImageSet.create_for_course(overview)
self.assertTrue(hasattr(overview, 'image_set'))
# The following is actually very important for this test because
# set_config() does a model insert after create_for_course() has caught
# and supressed an IntegrityError above. If create_for_course() properly
# wraps that operation in a transaction.atomic() block, the following
# will execute fine. If create_for_course() doesn't use an atomic block,
# the following line will cause a TransactionManagementError because
# Django will detect that something has already been rolled back in this
# transaction. So we don't really care about setting the config -- it's
# just a convenient way to cause a database write operation to happen.
self.set_config(False)
def _assert_image_urls_all_default(self, modulestore_type, raw_course_image_name, expected_url=None): def _assert_image_urls_all_default(self, modulestore_type, raw_course_image_name, expected_url=None):
""" """
Helper for asserting that all image_urls are defaulting to a particular value. Helper for asserting that all image_urls are defaulting to a particular value.
...@@ -826,24 +884,3 @@ class CourseOverviewImageSetTestCase(ModuleStoreTestCase): ...@@ -826,24 +884,3 @@ class CourseOverviewImageSetTestCase(ModuleStoreTestCase):
} }
) )
return course_overview return course_overview
def test_get_all_courses_by_mobile_available(self):
non_mobile_course = CourseFactory.create(emit_signals=True)
mobile_course = CourseFactory.create(mobile_available=True, emit_signals=True)
test_cases = (
(None, {non_mobile_course.id, mobile_course.id}),
(dict(mobile_available=True), {mobile_course.id}),
(dict(mobile_available=False), {non_mobile_course.id}),
)
for filter_, expected_courses in test_cases:
self.assertEqual(
{
course_overview.id
for course_overview in
CourseOverview.get_all_courses(filter_=filter_)
},
expected_courses,
"testing CourseOverview.get_all_courses with filter_={}".format(filter_),
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment