Commit 20cd73dc by Vedran Karacic

Load courses asynchronously on dynamic coupon preview.

parent 47d7812b
......@@ -41,21 +41,30 @@ class CatalogViewSet(NestedViewSetMixin, ReadOnlyModelViewSet):
"""
query = request.GET.get('query')
seat_types = request.GET.get('seat_types')
offset = request.GET.get('offset')
limit = request.GET.get('limit', DEFAULT_CATALOG_PAGE_SIZE)
if query and seat_types:
seat_types = seat_types.split(',')
try:
results = get_range_catalog_query_results(
limit=DEFAULT_CATALOG_PAGE_SIZE,
response = get_range_catalog_query_results(
limit=limit,
query=query,
site=request.site
)['results']
site=request.site,
offset=offset
)
results = response['results']
course_ids = [result['key'] for result in results]
courses = serializers.CourseSerializer(
Course.objects.filter(id__in=course_ids),
many=True,
context={'request': request}
).data
return Response(data=[course for course in courses if course['type'] in seat_types])
data = {
'next': response['next'],
'courses': [course for course in courses if course['type'] in seat_types]
}
return Response(data=data)
except (ConnectionError, SlumberBaseException, Timeout):
logger.error('Unable to connect to Course Catalog service.')
return Response(status=status.HTTP_400_BAD_REQUEST)
......
......@@ -46,37 +46,18 @@ define([
});
});
it('should call Course Catalog API if previewCatalog was called', function () {
it('should call Course Catalog API if previewCatalog was called and create a datatable', function () {
var args,
calls,
e = $.Event('click');
spyOn(e, 'preventDefault');
spyOn(Backbone, 'ajax');
spyOn($.prototype, 'DataTable').and.callThrough();
view.previewCatalog(e);
expect(e.preventDefault).toHaveBeenCalled();
expect(Backbone.ajax).toHaveBeenCalled();
calls = Backbone.ajax.calls;
args = calls.argsFor(calls.count() - 1)[0];
expect(args.type).toEqual('GET');
expect(args.url).toEqual(window.location.origin + '/api/v2/catalogs/preview/');
expect(args.data).toEqual({query: view.query, seat_types: view.seat_types.join()});
expect(args.success).toEqual(view.onSuccess);
});
it('should fill datatable on successful AJAX call to Course Catalog API', function () {
var API_data = [{
key: 'a/b/c'
}, {
key: 'd/e/f'
}],
args;
spyOn($.prototype, 'DataTable');
view.onSuccess(API_data);
expect($.prototype.DataTable).toHaveBeenCalled();
args = $.prototype.DataTable.calls.argsFor(0)[0];
......@@ -87,10 +68,52 @@ define([
expect(args.ordering).toBeFalsy();
expect(args.searching).toBeFalsy();
expect(args.columns).toEqual([
{title: 'Course ID', data: 'id'},
{title: 'Course name', data: 'name'},
{title: 'Seat type', data: 'type'}
{
title: 'Course ID', data: 'id',
sTitle: 'Course ID', mData: 'id'
},
{
title: 'Course name', data: 'name',
sTitle: 'Course name', mData: 'name',
},
{
title: 'Seat type', data: 'type',
sTitle: 'Seat type', mData: 'type',
}
]);
calls = Backbone.ajax.calls;
args = calls.argsFor(calls.count() - 1)[0];
expect(args.type).toEqual('GET');
expect(args.url).toEqual(window.location.origin + '/api/v2/catalogs/preview/');
expect(args.data).toEqual(
{query: view.query, seat_types: view.seat_types.join(), limit: 10, offset: 0}
);
expect(args.success).toEqual(view.onSuccess);
});
it('should fill datatable on successful AJAX call to Course Catalog API', function () {
var API_data = {
'next': 'test.link',
'courses': [{
id: 'a/b/c',
name: 'Test course 1',
type: 'verified'
}, {
id: 'd/e/f',
name: 'Test course 2',
type: 'professional'
}]
};
view.previewCatalog($.Event('click'));
this.table = view.$('#coursesTable').DataTable();
_.bind(view.onSuccess, this);
spyOn(window, 'setTimeout');
view.onSuccess(API_data);
expect(window.setTimeout).toHaveBeenCalled();
expect(this.table.row(0).data()).toEqual(view.getRowData(API_data.courses[0]));
expect(this.table.row(1).data()).toEqual(view.getRowData(API_data.courses[1]));
});
it('should call stopEventPropagation when disabled or active button pressed', function () {
......
......@@ -38,44 +38,62 @@ define(['jquery',
},
previewCatalog: function (event) {
this.limit = 10;
this.offset = 0;
event.preventDefault();
if (!$.fn.dataTable.isDataTable('#coursesTable') ||
(this.used_query !== this.query || this.used_seat_types !== this.seat_types)
) {
this.table = this.$('#coursesTable').DataTable({
autoWidth: false,
destroy: true,
info: true,
paging: true,
ordering: false,
searching: false,
columns: [
{
title: gettext('Course ID'),
data: 'id'
},
{
title: gettext('Course name'),
data: 'name'
},
{
title: gettext('Seat type'),
data: 'type'
}
]
}, this).clear().draw();
this.used_query = this.query;
this.used_seat_types = this.seat_types;
this.fetchCourseData();
}
},
fetchCourseData: function() {
Backbone.ajax({
context: this,
type: 'GET',
url: window.location.origin + '/api/v2/catalogs/preview/',
data: {
query : this.query,
seat_types: this.seat_types.join()
seat_types: this.seat_types.join(),
limit: this.limit,
offset: this.offset
},
success: this.onSuccess
});
},
onSuccess: function(data) {
this.$el.find('#coursesTable').DataTable({
autoWidth: false,
destroy: true,
info: true,
paging: true,
ordering: false,
searching: false,
columns: [
{
title: gettext('Course ID'),
data: 'id'
},
{
title: gettext('Course name'),
data: 'name'
},
{
title: gettext('Seat type'),
data: 'type'
}
],
data: data.map(this.getRowData, this)
}, this);
var tableData = data.courses.map(this.getRowData, this);
this.table.rows.add(tableData).draw();
if (data.next) {
this.offset += this.limit;
setTimeout(_.bind(this.fetchCourseData, this), 500);
}
},
render: function () {
......
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