ECOM-3206 allow run selection and enrollment (#12685)
This commit is contained in:
@@ -11,27 +11,49 @@
|
||||
initialize: function(data) {
|
||||
if (data){
|
||||
this.context = data;
|
||||
//we should populate our model by looking at the run_modes
|
||||
if (data.run_modes.length > 0){
|
||||
//We only have 1 run mode for this program
|
||||
this.setActiveRunMode(data.run_modes[0]);
|
||||
}
|
||||
this.setActiveRunMode(this.getRunMode(data.run_modes));
|
||||
}
|
||||
},
|
||||
|
||||
getRunMode: function(runModes){
|
||||
//we should populate our model by looking at the run_modes
|
||||
if (runModes.length > 0){
|
||||
if(runModes.length === 1){
|
||||
return runModes[0];
|
||||
}else{
|
||||
//We need to implement logic here to select the
|
||||
//most relevant run mode for the student to enroll
|
||||
return runModes[0];
|
||||
}
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
setActiveRunMode: function(runMode){
|
||||
this.set({
|
||||
display_name: this.context.display_name,
|
||||
key: this.context.key,
|
||||
marketing_url: runMode.marketing_url || '',
|
||||
start_date: runMode.start_date,
|
||||
end_date: runMode.end_date,
|
||||
is_enrolled: runMode.is_enrolled,
|
||||
is_enrollment_open: runMode.is_enrollment_open,
|
||||
course_url: runMode.course_url || '',
|
||||
course_image_url: runMode.course_image_url || '',
|
||||
mode_slug: runMode.mode_slug
|
||||
});
|
||||
if (runMode){
|
||||
this.set({
|
||||
display_name: this.context.display_name,
|
||||
key: this.context.key,
|
||||
marketing_url: runMode.marketing_url || '',
|
||||
start_date: runMode.start_date,
|
||||
end_date: runMode.end_date,
|
||||
is_enrolled: runMode.is_enrolled,
|
||||
is_enrollment_open: runMode.is_enrollment_open,
|
||||
course_key: runMode.course_key,
|
||||
course_url: runMode.course_url || '',
|
||||
course_image_url: runMode.course_image_url || '',
|
||||
mode_slug: runMode.mode_slug,
|
||||
run_key: runMode.run_key
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
updateRun: function(runKey){
|
||||
var selectedRun = _.findWhere(this.get('run_modes'), {run_key: runKey});
|
||||
if (selectedRun){
|
||||
this.setActiveRunMode(selectedRun);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Store data to enroll learners into the course
|
||||
*/
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
|
||||
define([
|
||||
'backbone'
|
||||
],
|
||||
function( Backbone) {
|
||||
return Backbone.Model.extend({
|
||||
defaults: {
|
||||
course_id: '',
|
||||
optIn: false,
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}).call(this, define || RequireJS.define);
|
||||
@@ -46,6 +46,7 @@
|
||||
if (this.titleContext){
|
||||
this.$el.before(HtmlUtils.ensureHtml(this.getTitleHtml()).toString());
|
||||
}
|
||||
|
||||
this.$el.html(childList);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
'underscore',
|
||||
'gettext',
|
||||
'edx-ui-toolkit/js/utils/html-utils',
|
||||
'js/learner_dashboard/models/course_enroll_model',
|
||||
'js/learner_dashboard/views/course_enroll_view',
|
||||
'text!../../../templates/learner_dashboard/course_card.underscore'
|
||||
],
|
||||
@@ -15,6 +16,7 @@
|
||||
_,
|
||||
gettext,
|
||||
HtmlUtils,
|
||||
EnrollModel,
|
||||
CourseEnrollView,
|
||||
pageTpl
|
||||
) {
|
||||
@@ -23,8 +25,14 @@
|
||||
|
||||
tpl: HtmlUtils.template(pageTpl),
|
||||
|
||||
initialize: function() {
|
||||
initialize: function(options) {
|
||||
this.enrollModel = new EnrollModel();
|
||||
if(options.context && options.context.urls){
|
||||
this.urlModel = new Backbone.Model(options.context.urls);
|
||||
this.enrollModel.urlRoot = this.urlModel.get('commerce_api_url');
|
||||
}
|
||||
this.render();
|
||||
this.listenTo(this.model, 'change', this.render);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
@@ -35,9 +43,10 @@
|
||||
|
||||
postRender: function(){
|
||||
this.enrollView = new CourseEnrollView({
|
||||
$el: this.$('.course-actions'),
|
||||
$parentEl: this.$('.course-actions'),
|
||||
model: this.model,
|
||||
context: this.context
|
||||
urlModel: this.urlModel,
|
||||
enrollModel: this.enrollModel
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -20,23 +20,89 @@
|
||||
tpl: HtmlUtils.template(pageTpl),
|
||||
|
||||
events: {
|
||||
'click .enroll-button': 'handleEnroll'
|
||||
'click .enroll-button': 'handleEnroll',
|
||||
'change .run-select': 'handleRunSelect',
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
if (options.$el){
|
||||
this.$el = options.$el;
|
||||
this.render();
|
||||
this.$parentEl = options.$parentEl;
|
||||
this.enrollModel = options.enrollModel;
|
||||
this.urlModel = options.urlModel;
|
||||
this.render();
|
||||
if(this.urlModel){
|
||||
this.trackSelectionUrl = this.urlModel.get('track_selection_url');
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var filledTemplate = this.tpl(this.model.toJSON());
|
||||
HtmlUtils.setHtml(this.$el, filledTemplate);
|
||||
var filledTemplate;
|
||||
if (this.$parentEl &&
|
||||
this.enrollModel &&
|
||||
this.model.get('course_key')){
|
||||
|
||||
filledTemplate = this.tpl(this.model.toJSON());
|
||||
HtmlUtils.setHtml(this.$el, filledTemplate);
|
||||
HtmlUtils.setHtml(this.$parentEl, HtmlUtils.HTML(this.$el));
|
||||
}
|
||||
},
|
||||
|
||||
handleEnroll: function(){
|
||||
//Enrollment click event handled here
|
||||
if (!this.model.get('is_enrolled')){
|
||||
// actually enroll
|
||||
this.enrollModel.save({
|
||||
course_id: this.model.get('course_key')
|
||||
}, {
|
||||
success: _.bind(this.enrollSuccess, this),
|
||||
error: _.bind(this.enrollError, this)
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
handleRunSelect: function(event){
|
||||
var runKey;
|
||||
if (event.target){
|
||||
runKey = $(event.target).val();
|
||||
if (runKey){
|
||||
this.model.updateRun(runKey);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
enrollSuccess: function(){
|
||||
var courseKey = this.model.get('course_key');
|
||||
if (this.trackSelectionUrl) {
|
||||
// Go to track selection page
|
||||
this.redirect( this.trackSelectionUrl + courseKey );
|
||||
}else{
|
||||
this.model.set({
|
||||
is_enrolled: true
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
enrollError: function(model, response) {
|
||||
|
||||
if (response.status === 403 && response.responseJSON.user_message_url) {
|
||||
/**
|
||||
* Check if we've been blocked from the course
|
||||
* because of country access rules.
|
||||
* If so, redirect to a page explaining to the user
|
||||
* why they were blocked.
|
||||
*/
|
||||
this.redirect( response.responseJSON.user_message_url );
|
||||
} else if (this.trackSelectionUrl){
|
||||
/**
|
||||
* Otherwise, go to the track selection page as usual.
|
||||
* This can occur, for example, when a course does not
|
||||
* have a free enrollment mode, so we can't auto-enroll.
|
||||
*/
|
||||
this.redirect( this.trackSelectionUrl + this.model.get('course_key') );
|
||||
}
|
||||
},
|
||||
|
||||
redirect: function( url ) {
|
||||
window.location.href = url;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
el: '.js-course-list',
|
||||
childView: CourseCardView,
|
||||
collection: this.courseCardCollection,
|
||||
context: this.programModel.toJSON(),
|
||||
context: this.options,
|
||||
titleContext: {
|
||||
el: 'h2',
|
||||
title: 'Course List'
|
||||
|
||||
@@ -10,7 +10,6 @@ define([
|
||||
describe('Course Card View', function () {
|
||||
var view = null,
|
||||
courseCardModel,
|
||||
setupView,
|
||||
context = {
|
||||
course_modes: [],
|
||||
display_name: 'Astrophysics: Exploring Exoplanets',
|
||||
@@ -32,7 +31,7 @@ define([
|
||||
is_enrolled: true,
|
||||
certificate_url: '',
|
||||
}]
|
||||
};
|
||||
},
|
||||
|
||||
setupView = function(isEnrolled){
|
||||
context.run_modes[0].is_enrolled = isEnrolled;
|
||||
@@ -41,6 +40,17 @@ define([
|
||||
view = new CourseCardView({
|
||||
model: courseCardModel
|
||||
});
|
||||
},
|
||||
|
||||
validateCourseInfoDisplay = function(){
|
||||
//DRY validation for course card in enrolled state
|
||||
expect(view.$('.header-img').attr('src')).toEqual(context.run_modes[0].course_image_url);
|
||||
expect(view.$('.course-details .course-title-link').text().trim()).toEqual(context.display_name);
|
||||
expect(view.$('.course-details .course-title-link').attr('href')).toEqual(
|
||||
context.run_modes[0].course_url);
|
||||
expect(view.$('.course-details .course-text .course-key').html()).toEqual(context.key);
|
||||
expect(view.$('.course-details .course-text .run-period').html())
|
||||
.toEqual(context.run_modes[0].start_date + ' - ' + context.run_modes[0].end_date);
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
@@ -58,22 +68,18 @@ define([
|
||||
it('should render the course card based on the data enrolled', function() {
|
||||
view.remove();
|
||||
setupView(true);
|
||||
expect(view.$('.header-img').attr('src')).toEqual(context.run_modes[0].course_image_url);
|
||||
expect(view.$('.course-details .course-title-link').text().trim()).toEqual(context.display_name);
|
||||
expect(view.$('.course-details .course-title-link').attr('href')).toEqual(
|
||||
context.run_modes[0].course_url);
|
||||
expect(view.$('.course-details .course-text .course-key').html()).toEqual(context.key);
|
||||
expect(view.$('.course-details .course-text .run-period').html())
|
||||
.toEqual(context.run_modes[0].start_date + ' - ' + context.run_modes[0].end_date);
|
||||
validateCourseInfoDisplay();
|
||||
});
|
||||
|
||||
it('should render the course card based on the data not enrolled', function() {
|
||||
expect(view.$('.header-img').attr('src')).toEqual(context.run_modes[0].course_image_url);
|
||||
expect(view.$('.course-details .course-title-link').text().trim()).toEqual(context.display_name);
|
||||
expect(view.$('.course-details .course-title-link').attr('href')).toEqual(
|
||||
context.run_modes[0].course_url);
|
||||
expect(view.$('.course-details .course-text .course-key').html()).toEqual(context.key);
|
||||
expect(view.$('.course-details .course-text .run-period').html()).not.toBeDefined();
|
||||
validateCourseInfoDisplay();
|
||||
});
|
||||
|
||||
it('should update render if the course card is_enrolled updated', function(){
|
||||
courseCardModel.set({
|
||||
is_enrolled: true
|
||||
});
|
||||
validateCourseInfoDisplay();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,70 +2,215 @@ define([
|
||||
'backbone',
|
||||
'jquery',
|
||||
'js/learner_dashboard/models/course_card_model',
|
||||
'js/learner_dashboard/models/course_enroll_model',
|
||||
'js/learner_dashboard/views/course_enroll_view'
|
||||
], function (Backbone, $, CourseCardModel, CourseEnrollView) {
|
||||
], function (Backbone, $, CourseCardModel, CourseEnrollModel, CourseEnrollView) {
|
||||
|
||||
'use strict';
|
||||
|
||||
describe('Course Enroll View', function () {
|
||||
var view = null,
|
||||
courseCardModel,
|
||||
courseEnrollModel,
|
||||
urlModel,
|
||||
setupView,
|
||||
singleRunModeList = [{
|
||||
start_date: 'Apr 25, 2016',
|
||||
end_date: 'Jun 13, 2016',
|
||||
course_key: 'course-v1:course-v1:edX+DemoX+Demo_Course',
|
||||
course_url: 'http://localhost:8000/courses/course-v1:edX+DemoX+Demo_Course/info',
|
||||
course_image_url: 'http://test.com/image1',
|
||||
marketing_url: 'http://test.com/image2',
|
||||
mode_slug: 'audit',
|
||||
run_key: '2T2016',
|
||||
is_enrolled: false
|
||||
}],
|
||||
multiRunModeList = [{
|
||||
start_date: 'May 21, 2015',
|
||||
end_date: 'Sep 21, 2015',
|
||||
course_key: 'course-v1:course-v1:edX+DemoX+Demo_Course',
|
||||
course_url: 'http://localhost:8000/courses/course-v1:edX+DemoX+Demo_Course/info',
|
||||
course_image_url: 'http://test.com/run_2_image_1',
|
||||
marketing_url: 'http://test.com/run_2_image_2',
|
||||
mode_slug: 'verified',
|
||||
run_key: '1T2015',
|
||||
is_enrolled: false
|
||||
},{
|
||||
start_date: 'Sep 22, 2015',
|
||||
end_date: 'Dec 28, 2015',
|
||||
course_key: 'course-v1:course-v1:edX+DemoX+Demo_Course',
|
||||
course_url: 'http://localhost:8000/courses/course-v1:edX+DemoX+Demo_Course/info',
|
||||
course_image_url: 'http://test.com/run_3_image_1',
|
||||
marketing_url: 'http://test.com/run_3_image_2',
|
||||
mode_slug: 'verified',
|
||||
run_key: '2T2015',
|
||||
is_enrolled: false
|
||||
}],
|
||||
context = {
|
||||
display_name: 'Astrophysics: Exploring Exoplanets',
|
||||
key: 'ANU-ASTRO1x',
|
||||
display_name: 'Edx Demo course',
|
||||
key: 'edX+DemoX+Demo_Course',
|
||||
organization: {
|
||||
display_name: 'Australian National University',
|
||||
key: 'ANUx'
|
||||
},
|
||||
run_modes: [{
|
||||
start_date: 'Apr 25, 2016',
|
||||
end_date: 'Jun 13, 2016',
|
||||
course_key: 'course-v1:ANUx+ANU-ASTRO1x+3T2015',
|
||||
course_url: 'http://localhost:8000/courses/course-v1:edX+DemoX+Demo_Course/info',
|
||||
course_image_url: 'http://test.com/image1',
|
||||
marketing_url: 'http://test.com/image2',
|
||||
mode_slug: 'verified',
|
||||
run_key: '2T2016',
|
||||
is_enrolled: false,
|
||||
certificate_url: '',
|
||||
}]
|
||||
display_name: 'edx.org',
|
||||
key: 'edX'
|
||||
}
|
||||
},
|
||||
urls = {
|
||||
dashboard_url: '/dashboard',
|
||||
id_verification_url: '/verify_student/start_flow/',
|
||||
track_selection_url: '/select_track/course/'
|
||||
};
|
||||
|
||||
setupView = function(isEnrolled){
|
||||
context.run_modes[0].is_enrolled = isEnrolled;
|
||||
setupView = function(runModes, urls){
|
||||
context.run_modes = runModes;
|
||||
setFixtures('<div class="course-actions"></div>');
|
||||
courseCardModel = new CourseCardModel(context);
|
||||
courseEnrollModel = new CourseEnrollModel({}, {
|
||||
courseId: courseCardModel.get('course_key')
|
||||
});
|
||||
if(urls){
|
||||
urlModel = new Backbone.Model(urls);
|
||||
}
|
||||
view = new CourseEnrollView({
|
||||
$el: $('.course-actions'),
|
||||
model: courseCardModel
|
||||
$parentEl: $('.course-actions'),
|
||||
model: courseCardModel,
|
||||
enrollModel: courseEnrollModel,
|
||||
urlModel: urlModel
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
setupView(false);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
view.remove();
|
||||
urlModel = null;
|
||||
courseCardModel = null;
|
||||
courseEnrollModel = null;
|
||||
});
|
||||
|
||||
it('should exist', function() {
|
||||
setupView(singleRunModeList);
|
||||
expect(view).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render the course enroll view based on not enrolled data', function() {
|
||||
setupView(singleRunModeList);
|
||||
expect(view.$('.enrollment-info').html().trim()).toEqual('not enrolled');
|
||||
expect(view.$('.enroll-button').text().trim()).toEqual('Enroll Now');
|
||||
expect(view.$('.run-select').length).toBe(0);
|
||||
});
|
||||
|
||||
it('should render the course enroll view based on enrolled data', function(){
|
||||
view.remove();
|
||||
setupView(true);
|
||||
singleRunModeList[0].is_enrolled = true;
|
||||
setupView(singleRunModeList);
|
||||
expect(view.$('.enrollment-info').html().trim()).toEqual('enrolled');
|
||||
expect(view.$('.view-course-link').attr('href')).toEqual(
|
||||
context.run_modes[0].course_url);
|
||||
expect(view.$('.view-course-link').text().trim()).toEqual('View Course');
|
||||
expect(view.$('.run-select').length).toBe(0);
|
||||
});
|
||||
|
||||
it('should not render anything if run modes is empty', function(){
|
||||
setupView([]);
|
||||
expect(view.$('.enrollment-info').length).toBe(0);
|
||||
expect(view.$('.run-select').length).toBe(0);
|
||||
expect(view.$('.enroll-button').length).toBe(0);
|
||||
});
|
||||
|
||||
it('should render run selection drop down if mulitple run available', function(){
|
||||
setupView(multiRunModeList);
|
||||
expect(view.$('.run-select').length).toBe(1);
|
||||
expect(view.$('.run-select').val()).toEqual(multiRunModeList[0].run_key);
|
||||
});
|
||||
|
||||
it('should switch run context if dropdown selection changed', function(){
|
||||
setupView(multiRunModeList);
|
||||
spyOn(courseCardModel, 'updateRun').and.callThrough();
|
||||
expect(view.$('.run-select').val()).toEqual(multiRunModeList[0].run_key);
|
||||
view.$('.run-select').val(multiRunModeList[1].run_key);
|
||||
view.$('.run-select').trigger("change");
|
||||
expect(view.$('.run-select').val()).toEqual(multiRunModeList[1].run_key);
|
||||
expect(courseCardModel.updateRun)
|
||||
.toHaveBeenCalledWith(multiRunModeList[1].run_key);
|
||||
expect(courseCardModel.get('run_key')).toEqual(multiRunModeList[1].run_key);
|
||||
});
|
||||
|
||||
it('should enroll learner when enroll button clicked', function(){
|
||||
singleRunModeList[0].is_enrolled = false;
|
||||
setupView(singleRunModeList);
|
||||
expect(view.$('.enroll-button').length).toBe(1);
|
||||
spyOn(courseEnrollModel, 'save');
|
||||
view.$('.enroll-button').click();
|
||||
expect(courseEnrollModel.save).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should enroll learner into the updated run with button click', function(){
|
||||
setupView(multiRunModeList);
|
||||
spyOn(courseEnrollModel, 'save');
|
||||
view.$('.run-select').val(multiRunModeList[1].run_key);
|
||||
view.$('.run-select').trigger("change");
|
||||
view.$('.enroll-button').click();
|
||||
expect(courseEnrollModel.save).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should redirect to trackSelectionUrl when enrollment success for audit track', function(){
|
||||
singleRunModeList[0].is_enrolled = false;
|
||||
singleRunModeList[0].mode_slug = 'audit';
|
||||
setupView(singleRunModeList, urls);
|
||||
expect(view.$('.enroll-button').length).toBe(1);
|
||||
expect(view.trackSelectionUrl).toBeDefined();
|
||||
spyOn(view, 'redirect');
|
||||
view.enrollSuccess();
|
||||
expect(view.redirect).toHaveBeenCalledWith(
|
||||
view.trackSelectionUrl + courseCardModel.get('course_key'));
|
||||
});
|
||||
|
||||
|
||||
it('should redirect when enrollment success for no track', function(){
|
||||
singleRunModeList[0].is_enrolled = false;
|
||||
singleRunModeList[0].mode_slug = null;
|
||||
setupView(singleRunModeList, urls);
|
||||
expect(view.$('.enroll-button').length).toBe(1);
|
||||
expect(view.trackSelectionUrl).toBeDefined();
|
||||
spyOn(view, 'redirect');
|
||||
view.enrollSuccess();
|
||||
expect(view.redirect).toHaveBeenCalledWith(
|
||||
view.trackSelectionUrl + courseCardModel.get('course_key'));
|
||||
});
|
||||
|
||||
it('should not redirect when urls not provided', function(){
|
||||
singleRunModeList[0].is_enrolled = false;
|
||||
singleRunModeList[0].mode_slug = 'verified';
|
||||
setupView(singleRunModeList);
|
||||
expect(view.$('.enroll-button').length).toBe(1);
|
||||
expect(view.verificationUrl).not.toBeDefined();
|
||||
expect(view.dashboardUrl).not.toBeDefined();
|
||||
expect(view.trackSelectionUrl).not.toBeDefined();
|
||||
spyOn(view, 'redirect');
|
||||
view.enrollSuccess();
|
||||
expect(view.redirect).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should redirect to track selection on error', function(){
|
||||
setupView(singleRunModeList, urls);
|
||||
expect(view.$('.enroll-button').length).toBe(1);
|
||||
expect(view.trackSelectionUrl).toBeDefined();
|
||||
spyOn(view, 'redirect');
|
||||
view.enrollError(courseEnrollModel, {status: 500});
|
||||
expect(view.redirect).toHaveBeenCalledWith(
|
||||
view.trackSelectionUrl + courseCardModel.get('course_key'));
|
||||
});
|
||||
|
||||
it('should redirect to login on 403 error', function(){
|
||||
var response = {
|
||||
status: 403,
|
||||
responseJSON:{
|
||||
user_message_url: 'test_url/haha'
|
||||
}};
|
||||
setupView(singleRunModeList, urls);
|
||||
expect(view.$('.enroll-button').length).toBe(1);
|
||||
expect(view.trackSelectionUrl).toBeDefined();
|
||||
spyOn(view, 'redirect');
|
||||
view.enrollError(courseEnrollModel, response);
|
||||
expect(view.redirect).toHaveBeenCalledWith(
|
||||
response.responseJSON.user_message_url);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,9 +8,10 @@ define([
|
||||
|
||||
describe('Program Details Header View', function () {
|
||||
var view = null,
|
||||
programModel,
|
||||
context = {
|
||||
programListingUrl: '/dashboard/programs',
|
||||
urls: {
|
||||
program_listing_url: '/dashboard/programs'
|
||||
},
|
||||
programData: {
|
||||
uuid: '12-ab',
|
||||
name: 'Astrophysics',
|
||||
@@ -58,7 +59,7 @@ define([
|
||||
expect(view.$('.org-logo').attr('alt')).toEqual(
|
||||
context.programData.organizations[0].display_name + '\'s logo'
|
||||
);
|
||||
expect(programListUrl).toEqual(context.programListingUrl);
|
||||
expect(programListUrl).toEqual(context.urls.program_listing_url);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.course-card{
|
||||
@include span(10);
|
||||
margin-left: $baseline*2 + px;
|
||||
margin-bottom: $baseline + px;
|
||||
margin-left: $baseline*2;
|
||||
margin-bottom: $baseline;
|
||||
.course-image-link{
|
||||
@include float(left);
|
||||
.header-img{
|
||||
@@ -12,25 +12,34 @@
|
||||
@include float(right);
|
||||
width: 100%;
|
||||
@include susy-media($bp-screen-sm) { width: calc(100% - 191px); }
|
||||
padding-left: $baseline*1.5 + px;
|
||||
padding-left: $baseline*1.5;
|
||||
.course-title{
|
||||
font-size: font-size(x-large);
|
||||
font-weight: font-weight(normal);
|
||||
margin-bottom: $baseline/4 + px;
|
||||
margin-bottom: $baseline/4;
|
||||
}
|
||||
.course-text{
|
||||
color: palette(grayscale, dark);
|
||||
.run-period{
|
||||
color: palette(grayscale, black);
|
||||
}
|
||||
}
|
||||
}
|
||||
.course-actions{
|
||||
.enrollment-info{
|
||||
width: $baseline*10 + px;
|
||||
width: $baseline*10;
|
||||
text-align: center;
|
||||
margin-bottom: $baseline/2 + px;
|
||||
margin-bottom: $baseline/2;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.run-select-container{
|
||||
margin-bottom: $baseline;
|
||||
.run-select{
|
||||
width: $baseline*10;
|
||||
}
|
||||
}
|
||||
.enroll-button{
|
||||
width: $baseline*10 + px;
|
||||
width: $baseline*10;
|
||||
text-align: center;
|
||||
background-color: palette(success, dark);
|
||||
border-color: palette(success, dark);
|
||||
@@ -42,7 +51,7 @@
|
||||
}
|
||||
|
||||
.view-course-link{
|
||||
width: $baseline*10 + px;
|
||||
width: $baseline*10;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user