Repository URL to install this package:
|
Version:
5.18.0 ▾
|
# -*- coding: utf-8 -*-
import json
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.utils.timezone import now, timedelta
from student.tests.factories import UserFactory
from courses import choices as courses_choices
from courses.models import CourseUniversityRelation
from courses.tests.factories import CourseFactory, CourseSubjectFactory
from fun.tests.utils import skipUnlessLms
from universities.tests.factories import UniversityFactory
@skipUnlessLms
class CourseAPITest(TestCase):
def setUp(self):
next_week = now() + timedelta(days=7)
self.api_url = reverse('fun-courses-api:courses-list')
self.active_1 = CourseFactory(
title='active course 1',
show_in_catalog=True,
is_active=True,
end_date=next_week,
)
self.active_2 = CourseFactory(
title='active course 2',
show_in_catalog=True,
is_active=True,
end_date=next_week,
)
self.not_active = CourseFactory(
title='course not active',
show_in_catalog=True,
is_active=False,
end_date=next_week,
)
self.not_in_catalog = CourseFactory(
title='course not in catalog',
show_in_catalog=False,
is_active=True,
end_date=next_week,
)
self.user = UserFactory(username='user', password='password') # user with profile
def login_as_admin(self):
self.user.is_staff = True
self.user.save()
self.client.login(username='user', password='password')
@property
def soon(self):
return now() + timedelta(days=1)
@property
def too_late(self):
return now() + timedelta(days=1000)
def test_course_list_api_response_loads(self):
response = self.client.get(self.api_url)
data = json.loads(response.content)
self.assertIn('results', data)
def test_response_contains_only_active_courses(self):
response = self.client.get(self.api_url)
self.assertContains(response, self.active_1.title)
self.assertContains(response, self.active_2.title)
self.assertNotContains(response, self.not_active.title)
self.assertNotContains(response, self.not_in_catalog.title)
def test_staff_user_can_see_courses_not_catalog(self):
self.user.is_staff = True
self.user.save()
self.client.login(username='user', password='password')
data = {'extended_list': True}
response = self.client.get(self.api_url, data)
self.assertContains(response, self.active_1.title)
self.assertContains(response, self.active_2.title)
self.assertContains(response, self.not_in_catalog.title)
def test_user_can_only_see_public_courses_if_not_staff(self):
self.user.is_staff = False
self.user.save()
self.client.login(username='user', password='password')
data = {'extended_list': True}
response = self.client.get(self.api_url, data)
self.assertContains(response, self.active_1.title)
self.assertContains(response, self.active_2.title)
self.assertNotContains(response, self.not_in_catalog.title)
def test_user_can_only_see_public_courses_if_not_logged_in(self):
self.client.logout()
data = {'extended_list': True}
response = self.client.get(self.api_url, data)
self.assertContains(response, self.active_1.title)
self.assertContains(response, self.active_2.title)
self.assertNotContains(response, self.not_in_catalog.title)
def test_can_update_course_score_as_admin(self):
self.login_as_admin()
self.active_1.score = 0
self.active_1.save()
data = json.dumps({'score': 100})
url = reverse('fun-courses-api:courses-detail',
args=[self.active_1.id]
)
response = self.client.put(url, data, content_type='application/json')
response_data = json.loads(response.content)
self.assertEqual(100, response_data['score'])
def test_cannot_update_course_score_if_not_logged_in(self):
self.client.logout()
data = {'score': 100}
url = reverse('fun-courses-api:courses-detail',
args=[self.active_1.id]
)
response = self.client.put(url, data)
self.assertNotEqual(response.status_code, 200)
def test_cannot_update_course_if_set_as_prevent_auto_update(self):
self.login_as_admin()
self.active_1.prevent_auto_update = True
self.active_1.save()
data = {'score': 100}
url = reverse('fun-courses-api:courses-detail',
args=[self.active_1.id]
)
response = self.client.put(url, data)
self.assertNotEqual(response.status_code, 200)
def test_only_display_courses_for_a_specific_university(self):
university = UniversityFactory(code='test-university')
UniversityFactory(code='another-university')
CourseUniversityRelation.objects.create(
course=self.active_1, university=university
)
filter_data = {'university': 'test-university'}
response = self.client.get(self.api_url, filter_data)
self.assertContains(response, self.active_1.title)
self.assertNotContains(response, self.active_2.title)
filter_data = {'university': 'another-university'}
response = self.client.get(self.api_url, filter_data)
self.assertNotContains(response, self.active_1.title)
self.assertNotContains(response, self.active_2.title)
def test_university_score_available_only_if_logged_in_as_admin(self):
university = UniversityFactory(code='test-university', score=10)
CourseUniversityRelation.objects.create(
course=self.active_1, university=university
)
filter_data = {'university': 'test-university'}
self.login_as_admin()
response = self.client.get(self.api_url, filter_data)
response_data = json.loads(response.content)
self.assertIn('score', response_data['results'][0]['universities'][0])
self.client.logout()
response = self.client.get(self.api_url, filter_data)
response_data = json.loads(response.content)
self.assertNotIn('score', response_data['results'][0]['universities'][0])
def test_only_display_courses_for_a_specific_subject(self):
subject = CourseSubjectFactory(slug='test-subject')
UniversityFactory(slug='another-subject')
self.active_1.subjects.add(subject)
filter_data = {'subject': 'test-subject'}
response = self.client.get(self.api_url, filter_data)
self.assertContains(response, self.active_1.title)
self.assertNotContains(response, self.active_2.title)
filter_data = {'subject': 'another-subject'}
response = self.client.get(self.api_url, filter_data)
self.assertNotContains(response, self.active_1.title)
self.assertNotContains(response, self.active_2.title)
def test_only_display_courses_for_a_specific_level(self):
self.active_1.level = courses_choices.COURSE_LEVEL_INTRODUCTORY
self.active_1.save()
filter_data = {'level': courses_choices.COURSE_LEVEL_INTRODUCTORY}
response = self.client.get(self.api_url, filter_data)
self.assertContains(response, self.active_1.title)
self.assertNotContains(response, self.active_2.title)
filter_data = {'level': courses_choices.COURSE_LEVEL_ADVANCED}
response = self.client.get(self.api_url, filter_data)
self.assertNotContains(response, self.active_1.title)
self.assertNotContains(response, self.active_2.title)
def test_only_display_courses_starting_soon(self):
self.active_1.start_date = self.soon
self.active_1.save()
self.active_2.start_date = now() - timedelta(days=1)
self.active_2.save()
filter_data = {'availability': 'starting_soon'}
response = self.client.get(self.api_url, filter_data)
self.assertContains(response, self.active_1.title)
self.assertNotContains(response, self.active_2.title)
def test_filter_by_current_exclude_upcoming_course(self):
self.active_1.enrollment_start_date = now() - timedelta(days=1)
self.active_1.enrollment_end_date = now() + timedelta(days=1)
self.active_1.save()
self.active_2.enrollment_start_date = now() + timedelta(days=1)
self.active_2.enrollment_end_date = now() + timedelta(days=3)
self.active_2.save()
filter_data = {'availability': 'opened'}
response = self.client.get(self.api_url, filter_data)
self.assertContains(response, self.active_1.title)
self.assertNotContains(response, self.active_2.title)
def test_filter_by_current_exclude_past_course(self):
self.active_1.enrollment_start_date = now() - timedelta(days=1)
self.active_1.enrollment_end_date = now() + timedelta(days=1)
self.active_1.save()
self.active_2.enrollment_start_date = now() - timedelta(days=3)
self.active_2.enrollment_end_date = now() - timedelta(days=1)
self.active_2.save()
filter_data = {'availability': 'opened'}
response = self.client.get(self.api_url, filter_data)
self.assertContains(response, self.active_1.title)
self.assertNotContains(response, self.active_2.title)
def test_filter_by_current_include_null_enrollment_start_date(self):
self.active_1.enrollment_start_date = None
self.active_1.enrollment_end_date = now() + timedelta(days=1)
self.active_1.save()
filter_data = {'availability': 'opened'}
response = self.client.get(self.api_url, filter_data)
self.assertContains(response, self.active_1.title)
def test_filter_by_current_include_null_enrollment_end_date(self):
self.active_1.enrollment_start_date = now() - timedelta(days=1)
self.active_1.enrollment_end_date = None
self.active_1.save()
filter_data = {'availability': 'opened'}
response = self.client.get(self.api_url, filter_data)
self.assertContains(response, self.active_1.title)
def test_public_api_results_do_not_include_score(self):
self.client.logout()
response = self.client.get(self.api_url)
response_data = json.loads(response.content)
self.assertNotIn('score', response_data['results'][0])
def test_private_api_results_include_score(self):
self.login_as_admin()
response = self.client.get(self.api_url)
response_data = json.loads(response.content)
self.assertIn('score', response_data['results'][0])
def test_enrollment_ends_soon(self):
self.active_1.enrollment_end_date = self.soon
self.active_1.save()
self.active_2.enrollment_end_date = self.too_late
self.active_2.save()
filter_data = {'availability': 'enrollment_ending_soon'}
response = self.client.get(self.api_url, filter_data)
data = json.loads(response.content)
self.assertEqual(1, len(data['results']))
self.assertEqual(self.active_1.title, data['results'][0]['title'])
def test_enrollment_ended_courses_are_listed_at_the_end(self):
yesterday = now() - timedelta(days=1)
tomorrow = now() + timedelta(days=1)
self.active_1.enrollment_end_date = yesterday
self.active_2.enrollment_end_date = tomorrow
self.active_1.score = self.active_2.score + 1
self.active_1.save()
self.active_2.save()
response = self.client.get(self.api_url, {})
data = json.loads(response.content)
self.assertEqual(2, data["count"])
self.assertEqual(self.active_2.id, data["results"][0]["id"])
self.assertEqual(self.active_1.id, data["results"][1]["id"])