Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.206.0 #5058

Merged
merged 9 commits into from
Sep 28, 2021
Merged
Show file tree
Hide file tree
Changes from all 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 RELEASE.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
Release Notes
=============

Version 0.206.0
---------------

- Only prompt for login for enrollable runs (#5051)
- fix: all DEDP courseware will be on mitxonline (#5055)
- Bump pillow from 8.2.0 to 8.3.2 (#5036)
- Add Course backend filter in course run admin list (#5052)
- update employment form design city field fix (#5053)
- Bump wagtail from 2.12.4 to 2.12.5 (#4980)
- V2 of login prompts for mitx online/edx
- fix degree and employment form fields (#5034)

Version 0.205.0 (Released September 15, 2021)
---------------

Expand Down
2 changes: 1 addition & 1 deletion courses/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class CourseRunAdmin(admin.ModelAdmin):
"""ModelAdmin for Courses"""
list_display = ('title', 'course_number', 'edx_course_key', 'enrollment_start', 'start_date', 'enrollment_end',
'end_date', 'upgrade_deadline', 'freeze_grade_date', )
list_filter = ('course__program__live', 'course__program', 'course', 'course__course_number', )
list_filter = ('course__program__live', 'course__program', 'course', 'course__course_number', 'courseware_backend',)
list_editable = ('enrollment_start', 'start_date', 'enrollment_end', 'end_date', 'upgrade_deadline',
'freeze_grade_date', )
search_fields = ('edx_course_key',)
Expand Down
10 changes: 10 additions & 0 deletions courses/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,13 @@ class CourseRunFactory(DjangoModelFactory):

class Meta:
model = CourseRun

class Params:
future_run = factory.Trait(
enrollment_start = factory.Faker(
'date_time_between',
start_date="+1d",
end_date="+30d",
tzinfo=pytz.utc
)
)
28 changes: 26 additions & 2 deletions courses/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.db import models
from django.utils.functional import cached_property

from grades.constants import FinalGradeStatus
from micromasters.models import TimestampedModel
Expand All @@ -29,7 +30,6 @@ class Topic(models.Model):
def __str__(self):
return self.name


class Program(TimestampedModel):
"""
A degree someone can pursue, e.g. "Supply Chain Management"
Expand All @@ -54,11 +54,22 @@ def has_frozen_grades_for_all_courses(self):
"""
return all([course.has_frozen_runs() for course in self.course_set.all()])

@cached_property
def enrollable_course_runs(self):
""" Return the set of course runs """
return CourseRun.objects.filter(course__program=self).enrollable()

@cached_property
def enrollable_courseware_backends(self):
""" Return the set of courseware backends """
return list({run.courseware_backend for run in self.enrollable_course_runs})

@cached_property
def has_mitxonline_courses(self):
"""
Return true if as least one course has at least one run that is on mitxonline
"""
return CourseRun.objects.filter(course__program=self, courseware_backend=BACKEND_MITX_ONLINE).exists()
return BACKEND_MITX_ONLINE in self.enrollable_courseware_backends


class Course(models.Model):
Expand Down Expand Up @@ -178,12 +189,25 @@ def first_unexpired_run(self):
)



class CourseRunQuerySet(models.QuerySet):
"""
Custom QuerySet for CourseRuns
"""
def enrollable(self):
"""Returns a new query that returns currently enrollable runs"""
now = now_in_utc()
return self.filter(enrollment_start__lte=now, enrollment_end__gt=now)


class CourseRun(models.Model):
"""
An individual run of a course within a Program, e.g. "Supply Chain 101
- Summer 2017". This is different than the logical notion of a course, but
rather a specific instance of that course being taught.
"""
objects = CourseRunQuerySet.as_manager()

title = models.CharField(max_length=255)
edx_course_key = models.CharField(max_length=255, blank=True, null=True, unique=True)
enrollment_start = models.DateTimeField(blank=True, null=True, db_index=True)
Expand Down
15 changes: 15 additions & 0 deletions courses/models_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ def test_complete(self, first_has_frozen, second_has_frozen, result):

assert course_1.program.has_frozen_grades_for_all_courses() is result

def test_enrollable_course_runs(self):
""" Test that enrollable_course_runs only returns currently enrollable runs """
program = ProgramFactory.create()
enrollable_run = CourseRunFactory.create(course__program=program) # enrollable
CourseRunFactory.create(course__program=program, future_run=True) # not enrollable

assert list(program.enrollable_course_runs) == [enrollable_run]


def from_weeks(weeks, now=None):
"""Helper function to get a date adjusted by a number of weeks"""
Expand Down Expand Up @@ -563,3 +571,10 @@ def test_has_future_exam(self):
date_last_eligible=(now_in_utc() - timedelta(days=1)).date(),
)
assert course_run.has_future_exam is False

def test_enrollable(self):
""" Test CourseRun.objects.enrollable() """
enrollable_run = CourseRunFactory.create() # enrollable
CourseRunFactory.create(future_run=True) # not enrollable

assert list(CourseRun.objects.enrollable()) == [enrollable_run]
1 change: 1 addition & 0 deletions courses/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Meta:
'enrolled',
'total_courses',
'topics',
'enrollable_courseware_backends',
)


Expand Down
21 changes: 13 additions & 8 deletions courses/serializers_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def setUpTestData(cls):
super().setUpTestData()

cls.program = ProgramFactory.create()
cls.course_run = CourseRunFactory.create(course__program=cls.program)
cls.user = UserFactory.create()
cls.context = {
"request": Mock(user=cls.user)
Expand All @@ -97,8 +98,9 @@ def test_program_no_programpage(self):
'title': self.program.title,
'programpage_url': None,
'enrolled': False,
'total_courses': 0,
'topics': [{'name': topic.name} for topic in self.program.topics.iterator()]
'total_courses': 1,
'topics': [{'name': topic.name} for topic in self.program.topics.iterator()],
"enrollable_courseware_backends": ["edxorg"],
}

def test_program_with_programpage(self):
Expand All @@ -114,8 +116,9 @@ def test_program_with_programpage(self):
'title': self.program.title,
'programpage_url': programpage.get_full_url(),
'enrolled': False,
'total_courses': 0,
'topics': [{'name': topic.name} for topic in self.program.topics.iterator()]
'total_courses': 1,
'topics': [{'name': topic.name} for topic in self.program.topics.iterator()],
"enrollable_courseware_backends": ["edxorg"],
}
assert len(programpage.url) > 0

Expand All @@ -130,8 +133,9 @@ def test_program_enrolled(self):
'title': self.program.title,
'programpage_url': None,
'enrolled': True,
'total_courses': 0,
'topics': [{'name': topic.name} for topic in self.program.topics.iterator()]
'total_courses': 1,
'topics': [{'name': topic.name} for topic in self.program.topics.iterator()],
"enrollable_courseware_backends": ["edxorg"],
}

def test_program_courses(self):
Expand All @@ -145,8 +149,9 @@ def test_program_courses(self):
'title': self.program.title,
'programpage_url': None,
'enrolled': False,
'total_courses': 5,
'topics': [{'name': topic.name} for topic in self.program.topics.iterator()]
'total_courses': 6,
'topics': [{'name': topic.name} for topic in self.program.topics.iterator()],
"enrollable_courseware_backends": ["edxorg"],
}


Expand Down
2 changes: 1 addition & 1 deletion financialaid/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class FinancialAidStatus:
"After reviewing your income documentation, the {program_name} MicroMasters team has determined "
"that your personalized course price is ${price}.\n\n"
"You can pay for MicroMasters courses through the MITx MicroMasters portal "
"(https://micromasters.mit.edu/dashboard). All coursework will be conducted on edx.org."
"(https://micromasters.mit.edu/dashboard). All coursework will be conducted on mitxonline.mit.edu"
)

FINANCIAL_AID_DOCUMENTS_RESET_MESSAGE = (
Expand Down
8 changes: 8 additions & 0 deletions micromasters/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ class UserSerializer(serializers.ModelSerializer):
first_name = serializers.SerializerMethodField()
last_name = serializers.SerializerMethodField()
preferred_name = serializers.SerializerMethodField()
social_auth_providers = serializers.SerializerMethodField()

class Meta:
model = User
fields = (
"username", "email",
"first_name", "last_name", "preferred_name",
"social_auth_providers",
)

def get_username(self, obj):
Expand Down Expand Up @@ -59,6 +61,12 @@ def get_preferred_name(self, obj):
except ObjectDoesNotExist:
return None

def get_social_auth_providers(self, obj):
"""
Get the list of social auth providers
"""
return list(obj.social_auth.values_list("provider", flat=True).distinct())


def serialize_maybe_user(user):
"""
Expand Down
3 changes: 3 additions & 0 deletions micromasters/serializers_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def test_basic_user(self):
"first_name": None,
"last_name": None,
"preferred_name": None,
"social_auth_providers": [],
}

def test_logged_in_user_through_maybe_wrapper(self):
Expand All @@ -45,6 +46,7 @@ def test_logged_in_user_through_maybe_wrapper(self):
"first_name": None,
"last_name": None,
"preferred_name": None,
"social_auth_providers": [],
}

def test_user_with_profile(self):
Expand All @@ -67,6 +69,7 @@ def test_user_with_profile(self):
"first_name": "Rando",
"last_name": "Cardrizzian",
"preferred_name": "Hobo",
"social_auth_providers": [],
}


Expand Down
2 changes: 1 addition & 1 deletion micromasters/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from micromasters.sentry import init_sentry

VERSION = "0.205.0"
VERSION = "0.206.0"

# initialize Sentry before doing anything else so we capture any config errors
ENVIRONMENT = get_string('MICROMASTERS_ENVIRONMENT', 'dev')
Expand Down
4 changes: 2 additions & 2 deletions requirements.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Django==2.2.24
Pillow==8.2.0
Pillow==8.3.2
boto3==1.16.63
celery==4.3.0
certifi==2018.1.18
Expand Down Expand Up @@ -43,5 +43,5 @@ robohash
static3==0.5.1
urllib3>=1.24.2
uwsgi
wagtail==2.12.4
wagtail==2.12.5
flaky==3.7.0
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ phonenumbers==8.10.23
# via -r requirements.in
pickleshare==0.7.5
# via ipython
pillow==8.2.0
pillow==8.3.2
# via
# -r requirements.in
# robohash
Expand Down Expand Up @@ -297,7 +297,7 @@ vine==1.3.0
# via
# amqp
# celery
wagtail==2.12.4
wagtail==2.12.5
# via -r requirements.in
wcwidth==0.1.7
# via prompt-toolkit
Expand Down
11 changes: 6 additions & 5 deletions static/js/components/CouponNotificationDialog_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,12 @@ const COURSE: Course = {
}

const PROGRAM: AvailableProgram = {
id: 1,
title: "Awesomesauce",
enrolled: true,
programpage_url: null,
total_courses: 0
id: 1,
title: "Awesomesauce",
enrolled: true,
programpage_url: null,
total_courses: 0,
enrollable_courseware_backends: ["edxorg"]
}

describe("CouponNotificationDialog", () => {
Expand Down
6 changes: 3 additions & 3 deletions static/js/components/EducationForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ class EducationForm extends ProfileFormFields {
true
)}
</Grid>
<Grid item xs={4}>
<Grid item md={4} sm={6} xs={12}>
<CountrySelectField
stateKeySet={keySet("school_state_or_territory")}
countryKeySet={keySet("school_country")}
Expand All @@ -418,7 +418,7 @@ class EducationForm extends ProfileFormFields {
{...this.defaultInputComponentProps()}
/>
</Grid>
<Grid item xs={4}>
<Grid item md={4} sm={6} xs={12}>
<StateSelectField
stateKeySet={keySet("school_state_or_territory")}
countryKeySet={keySet("school_country")}
Expand All @@ -428,7 +428,7 @@ class EducationForm extends ProfileFormFields {
{...this.defaultInputComponentProps()}
/>
</Grid>
<Grid item xs={4} key="school_city">
<Grid item md={4} sm={6} xs={12} key="school_city">
{/* eslint-disable-next-line no-invalid-this */}
{this.boundTextField(keySet("school_city"), "City")}
</Grid>
Expand Down
8 changes: 4 additions & 4 deletions static/js/components/EmploymentForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,26 +135,26 @@ class EmploymentForm extends ProfileFormFields {
<Grid item xs={12}>
{this.boundTextField(keySet("company_name"), "Name of Employer")}
</Grid>
<Grid item xs={4}>
<Grid item md={4} sm={6} xs={12}>
<CountrySelectField
stateKeySet={keySet("state_or_territory")}
countryKeySet={keySet("country")}
label="Country"
{...this.defaultInputComponentProps()}
/>
</Grid>
<Grid item xs={4}>
<Grid item md={4} sm={6} xs={12}>
<StateSelectField
stateKeySet={keySet("state_or_territory")}
countryKeySet={keySet("country")}
label="State or Territory"
{...this.defaultInputComponentProps()}
/>
</Grid>
<Grid item xs={4}>
<Grid item md={4} sm={6} xs={12}>
{this.boundTextField(keySet("city"), "City")}
</Grid>
<Grid item xs={12}>
<Grid item md={12} sm={6} xs={12}>
<SelectField
keySet={keySet("industry")}
label="Industry"
Expand Down
Loading