def test_next_lesson(self): """ Method used to test the 'next_lesson' function """ nextLesson = Lesson(language=self.language, lesson_title="Conditionals", lesson_description="Test Description", lesson_content="Test content", check_result="function check_result(result)\{\}", lesson_number=2, lesson_code="""test""") nextLesson.save() self.login_client() response = self.client.get(reverse("lesson-next-lesson", kwargs={ "languageTitle": self.language.language_name, "currentLessonTitle": self.lesson.lesson_title, "nextLessonTitle": nextLesson.lesson_title }), follow=True) newProgress = Progress.objects.filter( lesson__lesson_title=self.lesson.lesson_title) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "lesson/lesson_base.html") self.assertInHTML(nextLesson.lesson_title, response.content.decode()) self.assertIsNotNone(newProgress)
class AttachmentViewTests(TestCase): """Test views for user interaction with attachments""" course1_data = { 'code': 'EDU02', 'name': 'A Course of Leeches', 'abstract': 'Learn practical benefits of leeches', } lesson1_data = { 'name': 'Introduction to Music', 'abstract': 'A summary of what we cover', } att1_data = { 'name': 'Reading List', 'desc': 'Useful stuff you might need', 'seq': 3, 'attachment': 'empty_attachment_test.txt', } att2_data = { 'name': 'Grammar Guide', 'desc': 'How do you even spell grammer?', 'seq': 2, 'attachment': 'empty_attachment_test.txt', } def setUp(self): self.user1 = User.objects.create_user( 'bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.user2 = User.objects.create_user('dave', '*****@*****.**', 'dave') self.user2.is_active = True self.user2.save() self.course1 = Course(**self.course1_data) self.course1.organiser = self.user1 self.course1.instructor = self.user1 self.course1.save() self.lesson1 = Lesson(course=self.course1, **self.lesson1_data) self.lesson1.save() self.uc = UserCourse(course=self.course1, user=self.user2) self.uc.save() self.att1 = Attachment(course=self.course1, **self.att1_data) self.att2 = Attachment(lesson=self.lesson1, **self.att2_data) self.att1.save() self.att2.save() def test_view_metadata(self): """Verify that the relevant metadata get rendered""" response = self.client.get(self.att1.get_metadata_url()) self.assertEqual(response.status_code, 200) self.assertTrue(x in response.context for x in ['attachment']) self.assertIn("Reading List", response.content, u"detail missing from response")
class UserLessonViewTests(TestCase): """Test userlesson views""" def setUp(self): self.user1 = User.objects.create_user('bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.user2 = User.objects.create_user('Van Gogh', '*****@*****.**', 'vancode') self.user2.is_active = True self.user2.save() self.user3 = User.objects.create_user('Chuck Norris', '*****@*****.**', 'dontask') self.user3.is_active = True self.user3.save() self.user4 = User.objects.create_user('James Maxwell', 'em@c', 'pdq') self.user4.is_active = True self.user4.save() self.course1 = Course(**course1_data) self.course1.organiser = self.user1 self.course1.instructor = self.user1 self.course1.save() self.course2 = Course(**course2_data) self.course2.organiser = self.user2 self.course2.instructor = self.user2 self.course2.save() self.uc = UserCourse(course=self.course1, user=self.user2) self.uc.save() self.lesson1 = Lesson(name="Test Lesson 1", course = self.course1) self.lesson1.save() self.ul = UserLesson(user=self.user2, lesson=self.lesson1) self.ul.save() def test_userlesson_single(self): """View contains correct context variables""" u2 = self.user2.id l1 = self.lesson1.id url1 = "/interaction/user/{0}/lesson/{1}/".format(u2,l1) #Not logged in response = self.client.get(url1) self.assertEqual(response.status_code, 302) #Now logged in self.client.login(username='******', password='******') response = self.client.get(url1) self.assertEqual(response.status_code, 200) self.assertTrue(x in response.context for x in ['ul', 'history']) #non existent record response = self.client.get('/interaction/user/2/lesson/4000/') self.assertEqual(response.status_code, 404)
class CourseViewTests(TestCase): """Test the course views""" course1_data = { 'code': 'EDU02', 'name': 'A Course of Leeches', 'abstract': 'Learn practical benefits of leeches', 'published': True, } course2_data = { 'code': 'FBR9', 'name': 'Basic Knitting', 'abstract': 'Casting on', 'published': True, } course3_data = { 'code': 'G3', 'name': 'Nut Bagging', 'abstract': 'Put the nuts in the bag', 'published': True, } course4_data = { 'code': 'W1', 'name': 'Washing', 'abstract': 'How to *wash* a cat', 'published': True, } course5_data = { 'code': 'E1', 'name': 'Electronics', 'abstract': 'Intro to Electronics', 'published': False, } lesson1_data = { 'name': 'Introduction to Music', 'abstract': 'A summary of what we cover', } lesson2_data = { 'name': 'Stuff', 'abstract': 'Not a lot', } def setUp(self): self.user1 = User.objects.create_user('bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.user2 = User.objects.create_user('hank', '*****@*****.**', 'hankdo') self.user2.is_active = True self.user2.save() self.course1 = Course(**self.course1_data) self.course1.organiser = self.user1 self.course1.instructor = self.user1 self.course1.save() self.course2 = Course(**self.course2_data) self.course2.organiser = self.user1 self.course2.instructor = self.user2 self.course2.save() self.course3 = Course(**self.course3_data) self.course3.organiser = self.user2 self.course3.instructor = self.user2 self.course3.save() self.course4 = Course(**self.course4_data) self.course4.organiser = self.user2 self.course4.instructor = self.user2 self.course4.save() self.course5 = Course(**self.course5_data) self.course5.organiser = self.user2 self.course5.instructor = self.user2 self.course5.save() self.lesson1 = Lesson(course=self.course1, **self.lesson1_data) self.lesson1.save() self.lesson2 = Lesson(course=self.course3, **self.lesson2_data) self.lesson2.save() def tearDown(self): testfile = os.getcwd() + '/media/attachments/atest.txt' if os.path.isfile(testfile): os.remove(testfile) def test__user_permitted_to_edit_course(self): self.client.login(username='******', password='******') course = Course.objects.get(pk=1) user = User.objects.get(username='******') self.assertTrue(_user_permitted_to_edit_course(user, course.id)) def test__user_permitted_to_publish_course(self): self.client.login(username='******', password='******') course = Course.objects.get(pk=1) user = User.objects.get(username='******') self.assertFalse(_user_permitted_to_publish_course(user, course.id)) self.client.logout() self.client.login(username='******', password='******') course = Course.objects.get(pk=1) user = User.objects.get(username='******') self.assertTrue(_user_permitted_to_publish_course(user, course.id)) def test_helper__courses_n_24ths_returns_list(self): course_list = Course.objects.all() cn24 = _courses_n_24ths(course_list) self.assertIsInstance(cn24, list) self.assertIs(type(cn24[0]), tuple) #entry should be 2-tuple self.assertEqual(len(course_list), len(cn24)) def test_course_page_has_no_enrol_button_for_organiser_instructor(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/') self.assertNotIn("id='id_enrol_button'", response.content) self.assertNotIn("id='id_enrol_button2'", response.content) def test_course_page_has_edit_button_for_organiser_instructor(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/') self.assertContains( response, "<a href='/courses/1/edit/' id='id_edit_course' class='pure-button pure-button-primary'>Edit Course</a>", html=True) self.assertEqual(response.context['user_can_edit'], True) def test_course_page_has_no_edit_button_if_not_organiser_instructor(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/') self.assertNotIn("id='id_edit_course'", response.content) self.assertEqual(response.context['user_can_edit'], False) def test_course_edits_actually_saved(self): self.client.login(username='******', password='******') fp = SimpleUploadedFile('atest.txt', 'A simple test file') mod_data = { 'course_form-code': 'F1', 'course_form-name': 'Dingbat', 'course_form-abstract': 'Fingbot', 'course_form-organiser': self.user1, 'course_form-instructor': self.user1, 'lesson_formset-TOTAL_FORMS': 4, 'lesson_formset-INITIAL_FORMS': 1, 'lesson_formset-0-id': u'1', #prevent MultiVal dict key err. 'lesson_formset-0-name': 'Boo', 'lesson_formset-0-abstract': 'Hoo', 'video_formset-0-url': 'http://www.youtube.com/embed/EJiUWBiM8HE', 'video_formset-0-name': 'Cmdr Hadfield\'s Soda', 'video_formset-TOTAL_FORMS': u'1', 'video_formset-INITIAL_FORMS': u'0', 'attachment_formset-0-name': 'A test file', 'attachment_formset-0-desc': 'A description of a file', 'attachment_formset-0-attachment': fp, 'attachment_formset-TOTAL_FORMS': u'1', 'attachment_formset-INITIAL_FORMS': u'0' } ##This should trigger modification of the course response = self.client.post('/courses/1/edit/', mod_data) self.assertRedirects(response, '/courses/1/') ##Then visiting the course should reflect the changes response = self.client.get('/courses/1/') self.assertContains(response, '<h3>F1 : Dingbat Course Homepage</h3>', html=True) self.assertContains(response, '<p>Fingbot</p>', html=True) self.assertIn('Boo</a>', response.content) self.assertIn('<p>Hoo', response.content) self.assertIn(escape('Cmdr Hadfield\'s Soda'), response.content) self.assertIn('EJiUWBiM8HE', response.content) #youtube video self.assertIn('A test file', response.content) self.assertIn('A description of a file', response.content) target = "<a href='/interaction/attachment/1/download/'>A test file</a>" self.assertIn(target, response.content) def test_course_edit_redirects_if_not_loggedin(self): response = self.client.get('/courses/1/edit/') login_redirect_url = '/accounts/login/?next=/courses/1/edit/' self.assertRedirects(response, login_redirect_url, 302, 200) def test_course_edit_forbidden_if_user_not_permitted(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIsInstance(response, HttpResponseForbidden) def test_course_edit_200_if_user_permitted(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertEqual(response.status_code, 200) def test_course_edit_page_has_correct_title_and_breadcrumb(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') needle = "<h2 id='id_page_title'>Editing: A Course of Leeches</h2>" self.assertIn(needle, response.content) self.assertIn("<p id='id_breadcrumb'>", response.content) self.assertContains(response, '<a href="/courses/">All Courses</a>', html=True) self.assertContains(response, '<a href="/courses/1/">A Course of Leeches</a>', html=True) def test_course_edit_uses_correct_template(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertTemplateUsed(response, 'courses/course_edit.html') def test_course_edit_page_uses_correct_form(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIsInstance(response.context['course_form'], CourseFullForm) def test_course_edit_page_uses_correct_formsets(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIsInstance(response.context['lesson_formset'], LessonInlineFormset) self.assertIsInstance(response.context['video_formset'], VideoInlineFormset) self.assertIsInstance(response.context['attachment_formset'], AttachmentInlineFormset) self.assertTrue( hasattr(response.context['lesson_formset'], 'management_form')) self.assertTrue( hasattr(response.context['video_formset'], 'management_form')) self.assertTrue( hasattr(response.context['attachment_formset'], 'management_form')) def test_course_edit_page_validation_errors_sent_to_template(self): self.client.login(username='******', password='******') data = { 'course_form-code': '', 'course_form-name': '', 'course_form-abstract': '', 'lesson_formset-0-id': u'1', #prevent MultiVal dict key err. 'lesson_formset-TOTAL_FORMS': u'4', 'lesson_formset-INITIAL_FORMS': u'1', 'video_formset-0-url': 'err://err.err/EJiUWBiM8HE', 'video_formset-TOTAL_FORMS': u'1', 'video_formset-INITIAL_FORMS': u'0', 'attachment_formset-TOTAL_FORMS': u'1', 'attachment_formset-INITIAL_FORMS': u'0' } response = self.client.post('/courses/1/edit/', data) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'courses/course_edit.html') def test_course_edit_page_validation_errors_generate_error_msg(self): self.client.login(username='******', password='******') ##First with missing basic course data data = { 'course_form-code': '', 'course_form-name': '', 'course_form-abstract': '', 'lesson_formset-0-id': u'1', #prevent MultiVal dict key err. 'lesson_formset-TOTAL_FORMS': u'4', 'lesson_formset-INITIAL_FORMS': u'1', 'video_formset-0-url': 'http://youtu.be/EJiUWBiM8HE', 'video_formset-TOTAL_FORMS': u'1', 'video_formset-INITIAL_FORMS': u'0', 'attachment_formset-TOTAL_FORMS': u'1', 'attachment_formset-INITIAL_FORMS': u'0' } response = self.client.post('/courses/1/edit/', data) self.assertIn('Please correct the following:', response.content) self.assertIn(COURSE_NAME_FIELD_REQUIRED_ERROR, response.content) self.assertIn(COURSE_ABSTRACT_FIELD_REQUIRED_ERROR, response.content) ##Then with missing required fields in lesson formset data = { 'course_form-code': 'T1', 'course_form-name': 'Test', 'course_form-abstract': 'With some invalid lessons', 'lesson_formset-0-id': u'1', #prevent MultiVal dict key err. 'lesson_formset-0-name': '', 'lesson_formset-TOTAL_FORMS': u'4', 'lesson_formset-INITIAL_FORMS': u'1', 'video_formset-0-url': 'http://youtu.be/EJiUWBiM8HE', 'video_formset-TOTAL_FORMS': u'1', 'video_formset-INITIAL_FORMS': u'0', 'attachment_formset-TOTAL_FORMS': u'1', 'attachment_formset-INITIAL_FORMS': u'0' } response = self.client.post('/courses/1/edit/', data) self.assertIn('Please correct the following:', response.content) self.assertIn(LESSON_NAME_FIELD_REQUIRED_ERROR, response.content) ##And with invalid url in video formset data = { 'course_form-code': 'T1', 'course_form-name': 'Test', 'course_form-abstract': 'With invalid video url', 'lesson_formset-0-id': u'1', #prevent MultiVal dict key err. 'lesson_formset-0-name': 'Test', 'lesson_formset-TOTAL_FORMS': u'4', 'lesson_formset-INITIAL_FORMS': u'1', 'video_formset-0-id': u'1', #prevent MultiVal dict key err. 'video_formset-0-name': 'Invalid url', 'video_formset-0-url': 'htp://yotub.vom/56tyY', 'video_formset-TOTAL_FORMS': u'1', 'video_formset-INITIAL_FORMS': u'0', 'attachment_formset-TOTAL_FORMS': u'1', 'attachment_formset-INITIAL_FORMS': u'0' } response = self.client.post('/courses/1/edit/', data) self.assertIn('Please correct the following:', response.content) self.assertIn(VIDEO_URL_FIELD_INVALID_ERROR, response.content) ## Then with missing attachment data data = { 'course_form-code': 'T1', 'course_form-name': 'Test', 'course_form-abstract': 'With invalid video url', 'lesson_formset-0-id': u'1', #prevent MultiVal dict key err. 'lesson_formset-0-name': 'Test', 'lesson_formset-TOTAL_FORMS': u'4', 'lesson_formset-INITIAL_FORMS': u'1', 'video_formset-TOTAL_FORMS': u'1', 'video_formset-INITIAL_FORMS': u'0', 'attachment_formset-0-id': u'1', 'attachment_formset-0-name': '', 'attachment_formset-0-attachment': None, 'attachment_formset-0-desc': 'A failure', 'attachment_formset-TOTAL_FORMS': u'1', 'attachment_formset-INITIAL_FORMS': u'0' } response = self.client.post('/courses/1/edit/', data) self.assertIn('Please correct the following:', response.content) self.assertIn(ATTACHMENT_NAME_FIELD_REQUIRED_ERROR, response.content) self.assertIn(escape(ATTACHMENT_ATTACHMENT_FIELD_REQUIRED_ERROR), response.content) def test_course_edit_page_has_course_detail_area(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIn('id_course_basics_area', response.content) self.assertIn('value="EDU02"', response.content) self.assertIn('value="A Course of Leeches"', response.content) self.assertIn('Learn practical benefits of leeches', response.content) def test_course_edit_page_has_populated_lesson_area(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIn('id_lesson_formset_area', response.content) self.assertIn('Introduction to Music', response.content) def test_course_edit_page_has_video_area(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIn('id_video_formset_area', response.content) def test_course_edit_page_has_attachment_area(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIn('id_attachment_formset_area', response.content) def test_course_edit_attachment_area_doesnt_show_lesson_fk(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertNotRegexpMatches(response.content, 'id_attachment_formset-\d+-lesson', 'Lesson field shouldn\'t be showing up') def test_course_create_redirects_if_not_loggedin(self): response = self.client.get('/courses/create/') login_redirect_url = '/accounts/login/?next=/courses/create/' self.assertRedirects(response, login_redirect_url, 302, 200) def test_course_create_page_200_if_loggedin(self): self.client.login(username='******', password='******') response = self.client.get('/courses/create/') self.assertEqual(response.status_code, 200) def test_course_create_view_uses_correct_template(self): self.client.login(username='******', password='******') response = self.client.get('/courses/create/') self.assertTemplateUsed(response, 'courses/course_create.html') def test_course_create_view_uses_correct_form(self): self.client.login(username='******', password='******') response = self.client.get('/courses/create/') self.assertIsInstance(response.context['form'], CourseFullForm) def test_course_create_page_has_correct_title_and_breadcrumb(self): self.client.login(username='******', password='******') response = self.client.get('/courses/create/') needle = "<h2 id='id_page_title'>Create a Course</h2>" self.assertIn("<p id='id_breadcrumb'>", response.content) self.assertIn(needle, response.content) def test_course_create_page_has_correct_fields(self): self.client.login(username='******', password='******') response = self.client.get('/courses/create/') self.assertIn('<input id="id_code"', response.content) self.assertIn('<input id="id_name"', response.content) self.assertIn('id="id_abstract"', response.content) def test_course_create_page_has_create_button(self): self.client.login(username='******', password='******') response = self.client.get('/courses/create/') target = 'id="id_course_create"' self.assertIn(target, response.content) def test_course_create_page_invalid_form_sent_to_template(self): self.client.login(username='******', password='******') response = self.client.post('/courses/create/', data={ 'code': '', 'name': '', 'abstract': '' }) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'courses/course_create.html') def test_course_create_page_validation_errors_sent_to_template(self): self.client.login(username='******', password='******') response = self.client.post('/courses/create/', data={ 'code': '', 'name': '', 'abstract': '', }) expected_errors = ( COURSE_NAME_FIELD_REQUIRED_ERROR, COURSE_ABSTRACT_FIELD_REQUIRED_ERROR, ) for err in expected_errors: self.assertContains(response, err) def test_course_create_page_doesnot_show_errors_by_default(self): """ Check that errors don't show up when the form first loads """ self.client.login(username='******', password='******') response = self.client.get('/courses/create/') not_expected_errors = ( COURSE_NAME_FIELD_REQUIRED_ERROR, COURSE_ABSTRACT_FIELD_REQUIRED_ERROR, ) for err in not_expected_errors: self.assertNotContains(response, err) def test_course_create_page_invalid_form_passes_form_to_template(self): self.client.login(username='******', password='******') response = self.client.post('/courses/create/', data={ 'code': '', 'name': '', 'abstract': '' }) self.assertIsInstance(response.context['form'], CourseFullForm) def test_course_create_page_can_save_data(self): self.client.login(username='******', password='******') response = self.client.post('/courses/create/', data={ 'code': 'T01', 'name': 'Test', 'abstract': 'A test course' }) self.assertRedirects(response, '/courses/6/', 302, 200) response = self.client.get('/courses/6/') self.assertIn('T01', response.content) self.assertIn('Test', response.content) self.assertIn('A test course', response.content) def test_course_enrol_page_requires_login(self): response = self.client.get('/courses/1/enrol/') login_redirect_url = '/accounts/login/?next=/courses/1/enrol/' self.assertRedirects(response, login_redirect_url, 302, 200) def test_course_enrol_page_200_if_loggedin(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/enrol/') self.assertEqual(response.status_code, 200) def test_course_enrol_page_uses_correct_template(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/enrol/') self.assertTemplateUsed(response, 'courses/course_enrol.html') def test_course_enrol_page_has_enrol_button(self): self.client.login(username='******', password='******') response = self.client.get('/courses/3/enrol/') target = "id='id_enrol_button'" self.assertIn(target, response.content) def test_course_enrol_page_no_enrol_button_if_author(self): """Course organiser or instructor can't enrol!""" self.client.login(username='******', password='******') response = self.client.get('/courses/1/enrol/') target1 = "id='id_enrol_button'" self.assertNotIn(target1, response.content) target2 = "you can't enrol since you are involved in running "\ "this course." self.assertIn(target2, response.content) def test_course_enrol_page_has_correct_context_vars(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/enrol/') self.assertIn('course', response.context) self.assertIn('status', response.context) self.assertIn('fee_value', response.context) def test_course_enrol_page_status_auth_enrolled(self): """An authenticated and enrolled user status is passed to template""" self.client.login(username='******', password='******') #Enrol the user on the course (bertie is not organiser) uc = UserCourse(user=self.user1, course=self.course3) uc.save() response = self.client.get('/courses/3/enrol/') self.assertEqual('auth_enrolled', response.context['status'], "Registration status should be auth_enrolled") def test_course_enrol_page_status_noenrol(self): """Course instructor/organiser bar_enrol status passed to template""" self.client.login(username='******', password='******') #bert is course organiser response = self.client.get('/courses/1/enrol/') self.assertEqual('auth_bar_enrol', response.context['status'], "Registration status should be auth_bar_enrol") def test_enrol_page_abstract_renders_markdown(self): self.client.login(username='******', password='******') response = self.client.get('/courses/4/enrol/') self.assertIn('How to <em>wash</em> a cat', response.content) def test_enrol_page_has_organiser_instructor_links(self): """Course enrol template has correct links to instructor etc""" self.client.login(username='******', password='******') # Load up a course enrol page c2 = self.course2 c2.instructor.first_name = "Hank" c2.instructor.last_name = "Rancho" c2.instructor.save() url2 = '/courses/{0}/enrol/'.format(c2.pk) response = self.client.get(url2) # Check username appears for organiser org = c2.organiser t = '<p>Course organiser <a href="/accounts/profile/{1}/public/">{0}</a>' target = t.format(org.username, org.pk) resp = response.content.replace("\n", "").replace("\t", "") self.assertIn(target, resp) # Check full name appears for instructor inst = c2.instructor t = '<p>Course instructor <a href="/accounts/profile/{1}/public/">{0}</a>' target = t.format(inst.get_full_name(), inst.pk) self.assertIn(target, resp) def test_course_enrol_page_shows_free_course_enrol(self): """Free courses allow direct enrolment, no payment overlay""" self.client.login(username='******', password='******') course5 = Course.objects.get(pk=5) priced_item = PricedItem.objects.get(object_id=course5.id) priced_item.fee_value = 0 priced_item.save() response = self.client.get('/courses/5/enrol/') self.assertEqual(response.context['fee_value'], priced_item.fee_value) self.assertEqual(priced_item.fee_value, 0) #testing a free course self.assertRegexpMatches( response.content, "<button id=\\\'id_enrol_button\\\'[\s\S]*Enrol £Free"\ "[\S\s]*<\/button>") def test_course_enrol_stripe_Pay_with_Card_not_visible_free_course(self): self.client.login(username='******', password='******') response = self.client.get('/courses/5/enrol') #free course self.assertNotIn('stripe-button', response.content) def test_course_index_not_logged_in(self): """Check course index page loads OK and has correct variables""" response = self.client.get('/courses/') self.assertEqual(response.status_code, 200) #Next check template variables are present self.assertTrue(x in response.context for x in ['course_list', 'course_count']) def test_course_index_logged_in(self): """Check course index loads for logged in user""" url1 = '/courses/' self.client.login(username='******', password='******') response = self.client.get(url1) self.assertEqual(response.status_code, 200) self.assertIn('course_list', response.context, \ "Missing template var: course_list") self.assertIn('course_count', response.context, \ "Missing template var: course_count") def test_course_index_only_shows_published_courses(self): response = self.client.get('/courses/') self.assertIn('A Course of Leeches', response.content) self.assertIn('Basic Knitting', response.content) self.assertIn('Nut Bagging', response.content) self.assertIn('Washing', response.content) self.assertNotIn('Electronics', response.content) def test_course_index_shows_unpublished_course_to_author(self): self.client.login(username='******', password='******') response = self.client.get('/courses/') self.assertIn('A Course of Leeches', response.content) self.assertIn('Basic Knitting', response.content) self.assertIn('Nut Bagging', response.content) self.assertIn('Washing', response.content) self.assertIn('Electronics', response.content)
class TestServices(TestCase): def setUp(self): """ Method to set up the client and database content for Users, Programming Environments, Languages and Lessons """ self.client = Client() self.username = "******" self.password = "******" self.user = get_user_model().objects.create_user( "*****@*****.**", "Test", "TEACHER", "Tester", "Testing", "TestingPassword") self.saveLessonsToDB() pass def saveLessonsToDB(self): """ Method to create Programming Environment, Language and Lesson for the test database """ self.environment = ProgrammingEnvironment( environment_name="Web Applications", description="Test Description") self.environment.save() self.language = Language(language_name="JavaScript", description="Test Description", environment=self.environment) self.language.save() self.lesson = Lesson(language=self.language, lesson_title="Variables", lesson_description="Test Description", lesson_content="Test content", check_result="function check_result(result)\{\}", lesson_number=1, lesson_code=""" function variable_exercise(){ //Write variable here //Return the variable here }""") self.lesson.save() def login_client(self): """ Method for logging in the client """ self.client.login(username=self.username, password=self.password) def test_get_value(self): """ Method to test the 'get_value' function """ dictionary = {"TestKey": "TestValue"} result = services.get_value(dictionary, "TestKey") self.assertEqual(result, "TestValue") def test_get_lessons(self): """ Method to test the 'get_lessons' function """ testLesson = services.get_lessons(self.language.language_name) self.assertEqual(testLesson[0].lesson_title, self.lesson.lesson_title) def test_get_languages(self): """ Method to test the 'get_languages' function """ testLanguage = services.get_languages( self.environment.environment_name) self.assertEqual(testLanguage[0].language_name, self.language.language_name) def test_get_lesson_progress(self): """ Method to test the 'get_lesson_progress' function """ testProgress = Progress(lesson=self.lesson, user=self.user, completed=True) testProgress.save() progress = services.get_lesson_progress(self.lesson.lesson_title, self.language.language_name, self.user.username)[0] self.assertTrue(progress.completed) self.assertEqual(progress.lesson.lesson_title, self.lesson.lesson_title) def test_get_all_user_progress(self): """ Method to test the 'get_all_user_progress' function """ testProgress = Progress(lesson=self.lesson, user=self.user, completed=True) testProgress.save() progress = services.get_all_user_progress(self.user.username)[0] self.assertTrue(progress.completed) self.assertEqual(progress.lesson.lesson_title, self.lesson.lesson_title) self.assertEqual(progress.user, self.user) def test_get_lesson_by_number(self): """ Method to test the 'get_lesson_by_number' function """ testLesson = services.get_lesson_by_number(self.language.language_name, 1)[0] self.assertEqual(testLesson, self.lesson) self.assertEqual(testLesson.lesson_number, self.lesson.lesson_number) def test_get_all_languages(self): """ Method to test the 'get_all_languages' function """ testLanguages = services.get_all_languages() self.assertEqual(testLanguages[0].language_name, self.language.language_name) def test_language_lesson(self): """ Method to test the 'get_language_lesson' function """ testLesson = services.get_language_lesson(self.language.language_name, self.lesson.lesson_title) self.assertEqual(testLesson[0].lesson_title, self.lesson.lesson_title) def test_get_single_language(self): """ Method to test the 'get_single_language' function """ testLanguage = services.get_single_language( self.language.language_name) self.assertEqual(testLanguage[0].language_name, self.language.language_name) def test_get_lesson_hint(self): """ Method to test the 'get_lesson_hint' function """ testLessonHint = LessonHint(lesson=self.lesson, hint_title="Test Hint Title", hint_description="Test hint description") testLessonHint.save() lessonHint = services.get_lesson_hint(self.lesson) self.assertEqual(lessonHint[0].hint_title, "Test Hint Title") def test_check_lesson_enabled_valid(self): """ Method to test the 'check_lesson_enabled' function for a valid lesson """ testProgress = Progress(lesson=self.lesson, user=self.user, completed=True) testProgress.save() testEnabled = services.check_lesson_enabled( self.language.language_name, self.lesson.lesson_title, self.user.username) self.assertTrue(testEnabled) def test_check_lesson_enabled_invalid(self): """ Method to test the 'check_lesson_enabled' function for a invalid lesson """ testProgress = Progress(lesson=self.lesson, user=self.user, completed=True) testProgress.save() testEnabled = services.check_lesson_enabled( self.language.language_name, "Fake Lesson", self.user.username) self.assertFalse(testEnabled) def test_compile_javascript_code(self): """ Method to test the 'compile_javascript_code' method """ factory = RequestFactory() request = factory.get( r'/get_code/?untrustedCode=function%20variable_exercise()%7B%0A%20%20%2F%2FWrite%20variable%20here%0A%09return%20%22Test%22%0A%20%20%2F%2FReturn%20the%20variable%20here%0A%7D&language=javascript' ) data = services.compile_javascript_code(request) data = json.loads(data.content) self.assertEqual(data['output'], "Test") def test_compile_python_code(self): """ Method to test the 'compile_python_code' method """ factory = RequestFactory() request = factory.get( r'/get_code/?untrustedCode=def%20variables_exercise()%3A%0A%20%20%20%20%23%20Write%20variable%20here%20%0A%09return%20%22Test%22%0A%20%20%20%20%23%20Return%20the%20variable&language=python' ) data = services.compile_python_code(request) data = json.loads(data.content) self.assertEqual(data['output'], "Test") def test_compile_web_code_valid(self): """ Method to test the 'compile_code' function for HTML & CSS with valid structure """ factory = RequestFactory() request = factory.get( r'/get_code/?untrustedCode=%3Chtml%3E%0A%3Chead%3E%0A%3C%2Fhead%3E%0A%3Cbody%3E%0A%3C!--%20Create%20a%20H1%20tag%20here%20with%20the%20text%20%22Hello%20World!%22%20in%20--%3E%0A%20%20%3Ch1%3ETest%3C%2Fh1%3E%0A%3C%2Fbody%3E%0A%3C%2Fhtml%3E&language=html%20and%20css' ) data = services.compile_web_code(request) data = json.loads(data.content) self.assertInHTML(r'<h1>Test</h1>', data['HTML']) def test_compile_web_code_invalid(self): """ Method to test the 'compile_code' function for HTML & CSS with invalid structure """ factory = RequestFactory() request = factory.get( r'/get_code/?untrustedCode=%3Chead%3E%0A%3C%2Fhead%3E%0A%3Cbody%3E%0A%3C!--%20Create%20a%20H1%20tag%20here%20with%20the%20text%20%22Hello%20World!%22%20in%20--%3E%0A%20%20%3Ch1%3ETest%3C%2Fh1%3E%0A%3C%2Fbody%3E&language=html%20and%20css' ) data = services.compile_web_code(request) data = json.loads(data.content) self.assertInHTML( "You forgot to add core HTML structures such as <html>, <body> or <head>!", data['output'])
def getGrades(user, jwxt_user): gradesStr = jwxt_user.getScore() pattern = pattern = re.compile(r'\{"[^\}]*"\}') results = pattern.finditer(gradesStr) for item in results: grade = item.group() try: lessonIdPattern = re.compile(r'(?<="kch":")([^"]+?)(?=")') lessonId = lessonIdPattern.search(grade).group() teacherPattern = re.compile(r'(?<="jsxm":")([^"]+?)(?=")') try: teacher = teacherPattern.search(grade).group() except: teacher = '' lesson = Lesson.objects.get(lessonId=lessonId, teacher=teacher) except Lesson.DoesNotExist: schoolNumber = lessonId[:5] try: schoolObj = School.objects.get(number=schoolNumber) except: schoolObj = School.objects.get(number='69000') titlePattern = re.compile(r'(?<="kcmc":")([^"]+?)(?=")') title = titlePattern.search(grade).group() classHour = 'None' creditPattern = re.compile(r'(?<="xf":")([^"]+?)(?=")') try: credit = creditPattern.search(grade).group() except: credit = '0' campus = '' teachType = '01' typePattern = re.compile(r'(?<="kclb":")([^"]+?)(?=")') type = typePattern.search(grade).group() lesson = Lesson(school=schoolObj, lessonId=lessonId, title=title, description='', classHour=classHour, credit=credit, campus=campus, teacher=teacher[:128], teachType=teachType, type=type ) lesson.save() yearPattern = re.compile(r'(?<="xnd":")([^"]+?)(?=")') try: year = yearPattern.search(grade).group() except: year = 'unknow' scorePattern = re.compile(r'(?<="zzcj":")([^"]+?)(?=")') try: score = int(scorePattern.search(grade).group()) except: continue rankPattern = re.compile(r'(?<="jxbpm":")([^"]+?)(?=")') try: rank = rankPattern.search(grade).group() except: ranking = int total = int else: rank_list = map(int, re.findall(r'\d+', rank)) try: ranking = rank_list[0] total = rank_list[1] except: ranking = int total = int termPattern = re.compile(r'(?<="xq":")([^"]+?)(?=")') try: term = termPattern.search(grade).group() except: term = '4' try: gradeObj = Grade.objects.get(user=user, lesson=lesson) except Grade.DoesNotExist: gradeObj = Grade( user=user, lesson=lesson, year=year, term=term, score=score, ranking=ranking, total=total ) gradeObj.save() lesson.add_grade_number() lesson.save()
class UserAttachmentModelTests(TestCase): """Test model behaviour of user interaction with attachments""" att1_data = { 'name': 'Reading List', 'desc': 'Useful stuff you might need', 'seq': 3, 'attachment': 'empty_attachment_test.txt', } att2_data = { 'name': 'Grammer Guide', 'desc': 'How do you even spell grammer?', 'seq': 2, 'attachment': 'empty_attachment_test.txt', } def setUp(self): self.user1 = User.objects.create_user('bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.user2 = User.objects.create_user('flo', '*****@*****.**', 'flo') self.user2.is_active = True self.user2.save() self.course1 = Course(**course1_data) self.course1.instructor = self.user1 self.course1.organiser = self.user1 self.course1.save() self.course2 = Course(**course2_data) self.course2.instructor = self.user1 self.course2.organiser = self.user1 self.course2.save() self.uc = UserCourse(course=self.course1, user=self.user2) self.uc.save() self.lesson1 = Lesson(name="Test Lesson 1", course = self.course1) self.lesson1.save() self.lesson2 = Lesson(name="Test Lesson 2", course = self.course2) self.lesson2.save() #att1 attached to course self.att1 = Attachment(course=self.course1, **self.att1_data) self.att1.save() #att2 attached to lesson self.att2 = Attachment(lesson=self.lesson1, **self.att1_data) self.att2.save() #att3 attached to lesson in course2 self.att3 = Attachment(lesson=self.lesson2, **self.att1_data) self.att3.save() self.u_att1 = UserAttachment(attachment=self.att1, user=self.user2) self.u_att2 = UserAttachment(attachment=self.att2, user=self.user2) self.u_att1.save() self.u_att2.save() def test_hist2list(self): """Test conversion of JSON encoded history to tuple list""" #History will need some activity to test. Since model doesn't need a #download method, best to create this in views via client self.client.login(username='******', password='******') response = self.client.get('/interaction/attachment/1/download') assert(response) response = self.client.get('/interaction/attachment/1/download') h2l_output = self.u_att1.hist2list() self.assertIsInstance(h2l_output, list, "Output should be a list") for row in h2l_output: self.assertIsInstance(row, tuple, "Entry should be a tuple") self.assertIsInstance(row[0], datetime.datetime, "Should be a datetime") self.assertTrue(is_aware(row[0]), "Datetime not TZ aware") self.assertIn(row[1], UAActions, "Action should be DOWNLOADING etc") def test__checkrep(self): #TODO test the history checking in _checkrep self.fail("write me") def test___unicode__(self): self.assertEqual( u"UA:%s, User:%s, Attachment:%s" % \ (self.u_att2.pk, self.user2.pk, self.att2.pk), self.u_att2.__unicode__()) def test___str__(self): t = u"User {0}'s data for attachment: ...{1}" \ .format(self.user2.username, str(self.att1.attachment)[-10:]) s = self.u_att2.__str__() self.assertEqual(s, t) def test_get_absolute_url(self): t = u"/interaction/attachment/{0}/download/".format(self.att1.pk) url = self.u_att1.get_absolute_url() self.assertEqual(t,url) def test_save(self): """Test that save only saves when user is enrolled on course""" u_att3 = UserAttachment(attachment=self.att3, user=self.user2) u_att3.save() self.assertIsNone(u_att3.pk)
class UserLearningIntentionDetailModelTests(TestCase): """Test model behaviour of user interaction with learning intention details""" def setUp(self): self.user1 = User.objects.create_user('bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.user2 = User.objects.create_user('flo', '*****@*****.**', 'flo') self.user2.is_active = True self.user2.save() self.course1 = Course(**course1_data) self.course1.instructor = self.user1 self.course1.organiser = self.user1 self.course1.save() self.course2 = Course(**course2_data) self.course2.instructor = self.user1 self.course2.organiser = self.user1 self.course2.save() self.uc = UserCourse(course=self.course1, user=self.user2) self.uc.save() self.lesson = Lesson(name="Test Lesson 1", course = self.course1) self.lesson.save() self.lesson2 = Lesson(name="Test Lesson 2", course = self.course2) self.lesson2.save() self.li = LearningIntention(lesson=self.lesson, text="Intend...") self.li2 = LearningIntention(lesson=self.lesson2, text="Explore...") self.li.save() self.li2.save() self.lid = LearningIntentionDetail( learning_intention=self.li, text ="Criterion...", lid_type=LearningIntentionDetail.SUCCESS_CRITERION) self.lid2 = LearningIntentionDetail( learning_intention=self.li2, text ="Criterion...", lid_type=LearningIntentionDetail.SUCCESS_CRITERION) self.lid.save() self.lid2.save() self.ulid = UserLearningIntentionDetail( user=self.user2, learning_intention_detail=self.lid) self.ulid.save() def test_cycling_first_click_on_a_LID_triggers_save(self): """When user first clicks on a LID, a ULID needs a primary key The first time a user clicks on a LID (learning intention detail), a ULID interaction will be created in memory by the view userlearningintentiondetail_cycle, having no PK. The model cycle() should check and save to the database if this is the first click.""" # Enrol user on course 2: UserCourse(course=self.course2, user=self.user2).save() # Simulate first click on LID: ulid_mem = UserLearningIntentionDetail( user=self.user2, learning_intention_detail=self.lid2) self.assertFalse(ulid_mem.pk) ulid_mem.cycle() self.assertTrue(ulid_mem.pk) def test__checkrep_passes_initial_state(self): """Test the internal representation checker with LID interaction""" self.assertTrue(self.ulid._checkrep(), "ULID _checkrep failed") def test__checkrep_picks_up_errored_initial_states(self): self.ulid.condition = ULIDConditions.amber #errored state self.assertFalse(self.ulid._checkrep()) self.ulid.condition = ULIDConditions.green #errored state self.assertFalse(self.ulid._checkrep()) def test__checkrep_picks_up_nonsense_conditions(self): self.ulid.condition = None with self.assertRaises(CheckRepError): self.ulid._checkrep() self.ulid.condition = "topaz" with self.assertRaises(CheckRepError): self.ulid._checkrep() def test_save(self): """Test the save functionality Principally, it should not save unless the user is enrolled on the corresponding course""" ulid2 = UserLearningIntentionDetail(user=self.user1, learning_intention_detail=self.lid2) ulid2.save() self.assertIsNone(ulid2.pk) #should fail, user not on corr. course def test_cycle(self): """Check that state cycling works""" self.assertTrue(self.ulid._checkrep(), "Failure prior to cycle") self.assertEqual(self.ulid.condition, ULIDConditions.red) self.ulid.cycle() self.assertTrue(self.ulid._checkrep(), "Fail after first cycle") self.assertEqual(self.ulid.condition, ULIDConditions.amber) self.ulid.cycle() self.assertTrue(self.ulid._checkrep(), "Fail after second cycle") self.assertEqual(self.ulid.condition, ULIDConditions.green) self.ulid.cycle() self.assertTrue(self.ulid._checkrep(), "Fail after third cycle") self.assertEqual(self.ulid.condition, ULIDConditions.red) def test_cycle_history_timebar(self): """Test 5 minute timebar on history updates History of cycling events should append a new event if over 5 mins have elapsed since the last event, otherwise replace last history. """ self.assertTrue(self.ulid._checkrep(), "Failure prior to cycle") #First check that rapid successive cycles don't append to history, #intead, last entry should be replaced #NB: ulid.hist is JSON string. Count hist2list elements instead self.ulid.cycle() count1 = len(self.ulid.hist2list()) self.ulid.cycle() count2 = len(self.ulid.hist2list()) self.assertEqual(count2, count1, "History grew when it shouldn't have") #Doctor the date to 10 mins prior, #check that subsequent cycle does append to history hist = json.loads(self.ulid.history) last_event = hist.pop() last_time = last_event[0] last_time = last_time - 600 #600 seconds earlier hist.append((last_time, last_event[1])) self.ulid.history = json.dumps(hist) self.ulid.cycle() count3 = len(self.ulid.hist2list()) self.assertGreater(count3, count2, "History did not grow when it should") def test_hist2list(self): """See that history converts to list properly""" h2l_output = self.ulid.hist2list() self.assertIsInstance(h2l_output, list, "Output should be a list") for row in h2l_output: self.assertIsInstance(row, tuple, "Entry should be a tuple") self.assertIsInstance(row[0], datetime.datetime, "Should be a datetime") self.assertTrue(is_aware(row[0]), "Datetime not TZ aware") self.assertIsInstance(row[1], str, "Action should be a string") last = h2l_output.pop() self.assertEqual(last[1], 'SET_RED', "Action should be SET_RED") def test_get_status(self): """Test that the correct status is returned""" self.assertEqual(self.ulid.get_status(), 'red', "Status should be 'red'") self.ulid.cycle() self.assertEqual(self.ulid.get_status(), 'amber', "Status should be 'amber'") self.ulid.cycle() self.assertEqual(self.ulid.get_status(), 'green', "Status should be 'green'") self.ulid.cycle() self.assertEqual(self.ulid.get_status(), 'red', "Status should be 'red'") def test___str__(self): """Test that the desired info is in the unicode method""" s = self.ulid.__str__() self.assertIn(self.ulid.user.username, s, "The username should be in the unicode") self.assertIn(self.ulid.learning_intention_detail.text[:10], s, "The first 10 chars of the criterion_text " "should be in the unicode") def test___unicode__(self): """Test that the desired info is in the unicode method""" unicod = self.ulid.__unicode__() s = u"ULID:%s, User:%s, LID:%s" % \ (self.ulid.pk, self.ulid.user.pk, self.ulid.learning_intention_detail.pk) self.assertEqual(unicod, s, "Unicode output failure")
class CourseViewTests(TestCase): """Test the course views""" course1_data = { 'code': 'EDU02', 'name': 'A Course of Leeches', 'abstract': 'Learn practical benefits of leeches', 'published': True, } course2_data = { 'code': 'FBR9', 'name': 'Basic Knitting', 'abstract': 'Casting on', 'published': True, } course3_data = { 'code': 'G3', 'name': 'Nut Bagging', 'abstract': 'Put the nuts in the bag', 'published': True, } course4_data = { 'code': 'W1', 'name': 'Washing', 'abstract': 'How to *wash* a cat', 'published': True, } course5_data = { 'code': 'E1', 'name': 'Electronics', 'abstract': 'Intro to Electronics', 'published': False, } lesson1_data = { 'name': 'Introduction to Music', 'abstract': 'A summary of what we cover', } lesson2_data = { 'name': 'Stuff', 'abstract': 'Not a lot', } def setUp(self): self.user1 = User.objects.create_user( 'bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.user2 = User.objects.create_user( 'hank', '*****@*****.**', 'hankdo') self.user2.is_active = True self.user2.save() self.course1 = Course(**self.course1_data) self.course1.organiser = self.user1 self.course1.instructor = self.user1 self.course1.save() self.course2 = Course(**self.course2_data) self.course2.organiser = self.user1 self.course2.instructor = self.user2 self.course2.save() self.course3 = Course(**self.course3_data) self.course3.organiser = self.user2 self.course3.instructor = self.user2 self.course3.save() self.course4 = Course(**self.course4_data) self.course4.organiser = self.user2 self.course4.instructor = self.user2 self.course4.save() self.course5 = Course(**self.course5_data) self.course5.organiser = self.user2 self.course5.instructor = self.user2 self.course5.save() self.lesson1 = Lesson(course=self.course1, **self.lesson1_data) self.lesson1.save() self.lesson2 = Lesson(course=self.course3, **self.lesson2_data) self.lesson2.save() def tearDown(self): testfile = os.getcwd()+'/media/attachments/atest.txt' if os.path.isfile(testfile): os.remove(testfile) def test__user_permitted_to_edit_course(self): self.client.login(username='******', password='******') course = Course.objects.get(pk=1) user = User.objects.get(username='******') self.assertTrue(_user_permitted_to_edit_course(user, course.id)) def test__user_permitted_to_publish_course(self): self.client.login(username='******', password='******') course = Course.objects.get(pk=1) user = User.objects.get(username='******') self.assertFalse(_user_permitted_to_publish_course(user, course.id)) self.client.logout() self.client.login(username='******', password='******') course = Course.objects.get(pk=1) user = User.objects.get(username='******') self.assertTrue(_user_permitted_to_publish_course(user, course.id)) def test_helper__courses_n_24ths_returns_list(self): course_list = Course.objects.all() cn24 = _courses_n_24ths(course_list) self.assertIsInstance(cn24, list) self.assertIs(type(cn24[0]), tuple) #entry should be 2-tuple self.assertEqual(len(course_list), len(cn24)) def test_course_page_has_no_enrol_button_for_organiser_instructor(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/') self.assertNotIn("id='id_enrol_button'", response.content) self.assertNotIn("id='id_enrol_button2'", response.content) def test_course_page_has_edit_button_for_organiser_instructor(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/') self.assertContains( response, "<a href='/courses/1/edit/' id='id_edit_course' class='pure-button pure-button-primary'>Edit Course</a>", html=True) self.assertEqual(response.context['user_can_edit'], True) def test_course_page_has_no_edit_button_if_not_organiser_instructor(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/') self.assertNotIn("id='id_edit_course'", response.content) self.assertEqual(response.context['user_can_edit'], False) def test_course_edits_actually_saved(self): self.client.login(username='******', password='******') fp = SimpleUploadedFile('atest.txt', 'A simple test file') mod_data = { 'course_form-code': 'F1', 'course_form-name': 'Dingbat', 'course_form-abstract': 'Fingbot', 'course_form-organiser': self.user1, 'course_form-instructor': self.user1, 'lesson_formset-TOTAL_FORMS':4, 'lesson_formset-INITIAL_FORMS':1, 'lesson_formset-0-id':u'1', #prevent MultiVal dict key err. 'lesson_formset-0-name':'Boo', 'lesson_formset-0-abstract':'Hoo', 'video_formset-0-url':'http://www.youtube.com/embed/EJiUWBiM8HE', 'video_formset-0-name':'Cmdr Hadfield\'s Soda', 'video_formset-TOTAL_FORMS':u'1', 'video_formset-INITIAL_FORMS':u'0', 'attachment_formset-0-name':'A test file', 'attachment_formset-0-desc':'A description of a file', 'attachment_formset-0-attachment':fp, 'attachment_formset-TOTAL_FORMS':u'1', 'attachment_formset-INITIAL_FORMS':u'0' } ##This should trigger modification of the course response = self.client.post('/courses/1/edit/', mod_data) self.assertRedirects(response, '/courses/1/') ##Then visiting the course should reflect the changes response = self.client.get('/courses/1/') self.assertContains(response, '<h3>F1 : Dingbat Course Homepage</h3>', html=True) self.assertContains(response, '<p>Fingbot</p>', html=True) self.assertIn('Boo</a>', response.content) self.assertIn('<p>Hoo', response.content) self.assertIn(escape('Cmdr Hadfield\'s Soda'), response.content) self.assertIn('EJiUWBiM8HE', response.content) #youtube video self.assertIn('A test file', response.content) self.assertIn('A description of a file', response.content) target = "<a href='/interaction/attachment/1/download/'>A test file</a>" self.assertIn(target, response.content) def test_course_edit_redirects_if_not_loggedin(self): response = self.client.get('/courses/1/edit/') login_redirect_url = '/accounts/login/?next=/courses/1/edit/' self.assertRedirects(response, login_redirect_url, 302, 200) def test_course_edit_forbidden_if_user_not_permitted(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIsInstance(response, HttpResponseForbidden) def test_course_edit_200_if_user_permitted(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertEqual(response.status_code, 200) def test_course_edit_page_has_correct_title_and_breadcrumb(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') needle = "<h2 id='id_page_title'>Editing: A Course of Leeches</h2>" self.assertIn(needle, response.content) self.assertIn("<p id='id_breadcrumb'>", response.content) self.assertContains( response, '<a href="/courses/">All Courses</a>', html=True) self.assertContains( response, '<a href="/courses/1/">A Course of Leeches</a>', html=True) def test_course_edit_uses_correct_template(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertTemplateUsed(response, 'courses/course_edit.html') def test_course_edit_page_uses_correct_form(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIsInstance(response.context['course_form'], CourseFullForm) def test_course_edit_page_uses_correct_formsets(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIsInstance( response.context['lesson_formset'], LessonInlineFormset) self.assertIsInstance( response.context['video_formset'], VideoInlineFormset) self.assertIsInstance( response.context['attachment_formset'], AttachmentInlineFormset) self.assertTrue( hasattr(response.context['lesson_formset'], 'management_form')) self.assertTrue( hasattr(response.context['video_formset'], 'management_form')) self.assertTrue( hasattr(response.context['attachment_formset'], 'management_form')) def test_course_edit_page_validation_errors_sent_to_template(self): self.client.login(username='******', password='******') data = { 'course_form-code': '', 'course_form-name': '', 'course_form-abstract': '', 'lesson_formset-0-id':u'1', #prevent MultiVal dict key err. 'lesson_formset-TOTAL_FORMS':u'4', 'lesson_formset-INITIAL_FORMS':u'1', 'video_formset-0-url':'err://err.err/EJiUWBiM8HE', 'video_formset-TOTAL_FORMS':u'1', 'video_formset-INITIAL_FORMS':u'0', 'attachment_formset-TOTAL_FORMS':u'1', 'attachment_formset-INITIAL_FORMS':u'0' } response = self.client.post('/courses/1/edit/', data) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'courses/course_edit.html') def test_course_edit_page_validation_errors_generate_error_msg(self): self.client.login(username='******', password='******') ##First with missing basic course data data = { 'course_form-code': '', 'course_form-name': '', 'course_form-abstract': '', 'lesson_formset-0-id':u'1', #prevent MultiVal dict key err. 'lesson_formset-TOTAL_FORMS':u'4', 'lesson_formset-INITIAL_FORMS':u'1', 'video_formset-0-url':'http://youtu.be/EJiUWBiM8HE', 'video_formset-TOTAL_FORMS':u'1', 'video_formset-INITIAL_FORMS':u'0', 'attachment_formset-TOTAL_FORMS':u'1', 'attachment_formset-INITIAL_FORMS':u'0' } response = self.client.post('/courses/1/edit/', data) self.assertIn('Please correct the following:', response.content) self.assertIn(COURSE_NAME_FIELD_REQUIRED_ERROR, response.content) self.assertIn(COURSE_ABSTRACT_FIELD_REQUIRED_ERROR, response.content) ##Then with missing required fields in lesson formset data = { 'course_form-code': 'T1', 'course_form-name': 'Test', 'course_form-abstract': 'With some invalid lessons', 'lesson_formset-0-id':u'1', #prevent MultiVal dict key err. 'lesson_formset-0-name':'', 'lesson_formset-TOTAL_FORMS':u'4', 'lesson_formset-INITIAL_FORMS':u'1', 'video_formset-0-url':'http://youtu.be/EJiUWBiM8HE', 'video_formset-TOTAL_FORMS':u'1', 'video_formset-INITIAL_FORMS':u'0', 'attachment_formset-TOTAL_FORMS':u'1', 'attachment_formset-INITIAL_FORMS':u'0' } response = self.client.post('/courses/1/edit/', data) self.assertIn('Please correct the following:', response.content) self.assertIn(LESSON_NAME_FIELD_REQUIRED_ERROR, response.content) ##And with invalid url in video formset data = { 'course_form-code': 'T1', 'course_form-name': 'Test', 'course_form-abstract': 'With invalid video url', 'lesson_formset-0-id':u'1', #prevent MultiVal dict key err. 'lesson_formset-0-name':'Test', 'lesson_formset-TOTAL_FORMS':u'4', 'lesson_formset-INITIAL_FORMS':u'1', 'video_formset-0-id':u'1', #prevent MultiVal dict key err. 'video_formset-0-name':'Invalid url', 'video_formset-0-url':'htp://yotub.vom/56tyY', 'video_formset-TOTAL_FORMS':u'1', 'video_formset-INITIAL_FORMS':u'0', 'attachment_formset-TOTAL_FORMS':u'1', 'attachment_formset-INITIAL_FORMS':u'0' } response = self.client.post('/courses/1/edit/', data) self.assertIn('Please correct the following:', response.content) self.assertIn(VIDEO_URL_FIELD_INVALID_ERROR, response.content) ## Then with missing attachment data data = { 'course_form-code': 'T1', 'course_form-name': 'Test', 'course_form-abstract': 'With invalid video url', 'lesson_formset-0-id':u'1', #prevent MultiVal dict key err. 'lesson_formset-0-name':'Test', 'lesson_formset-TOTAL_FORMS':u'4', 'lesson_formset-INITIAL_FORMS':u'1', 'video_formset-TOTAL_FORMS':u'1', 'video_formset-INITIAL_FORMS':u'0', 'attachment_formset-0-id':u'1', 'attachment_formset-0-name':'', 'attachment_formset-0-attachment':None, 'attachment_formset-0-desc':'A failure', 'attachment_formset-TOTAL_FORMS':u'1', 'attachment_formset-INITIAL_FORMS':u'0' } response = self.client.post('/courses/1/edit/', data) self.assertIn('Please correct the following:', response.content) self.assertIn(ATTACHMENT_NAME_FIELD_REQUIRED_ERROR, response.content) self.assertIn( escape(ATTACHMENT_ATTACHMENT_FIELD_REQUIRED_ERROR), response.content ) def test_course_edit_page_has_course_detail_area(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIn('id_course_basics_area', response.content) self.assertIn('value="EDU02"', response.content) self.assertIn('value="A Course of Leeches"', response.content) self.assertIn( 'Learn practical benefits of leeches', response.content) def test_course_edit_page_has_populated_lesson_area(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIn('id_lesson_formset_area', response.content) self.assertIn('Introduction to Music', response.content) def test_course_edit_page_has_video_area(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIn('id_video_formset_area', response.content) def test_course_edit_page_has_attachment_area(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertIn('id_attachment_formset_area', response.content) def test_course_edit_attachment_area_doesnt_show_lesson_fk(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/edit/') self.assertNotRegexpMatches( response.content, 'id_attachment_formset-\d+-lesson', 'Lesson field shouldn\'t be showing up') def test_course_create_redirects_if_not_loggedin(self): response = self.client.get('/courses/create/') login_redirect_url = '/accounts/login/?next=/courses/create/' self.assertRedirects(response, login_redirect_url, 302, 200) def test_course_create_page_200_if_loggedin(self): self.client.login(username='******', password='******') response = self.client.get('/courses/create/') self.assertEqual(response.status_code, 200) def test_course_create_view_uses_correct_template(self): self.client.login(username='******', password='******') response = self.client.get('/courses/create/') self.assertTemplateUsed(response, 'courses/course_create.html') def test_course_create_view_uses_correct_form(self): self.client.login(username='******', password='******') response = self.client.get('/courses/create/') self.assertIsInstance(response.context['form'], CourseFullForm) def test_course_create_page_has_correct_title_and_breadcrumb(self): self.client.login(username='******', password='******') response = self.client.get('/courses/create/') needle = "<h2 id='id_page_title'>Create a Course</h2>" self.assertIn("<p id='id_breadcrumb'>", response.content) self.assertIn(needle, response.content) def test_course_create_page_has_correct_fields(self): self.client.login(username='******', password='******') response = self.client.get('/courses/create/') self.assertIn('<input id="id_code"', response.content) self.assertIn('<input id="id_name"', response.content) self.assertIn('id="id_abstract"', response.content) def test_course_create_page_has_create_button(self): self.client.login(username='******', password='******') response = self.client.get('/courses/create/') target = 'id="id_course_create"' self.assertIn(target, response.content) def test_course_create_page_invalid_form_sent_to_template(self): self.client.login(username='******', password='******') response = self.client.post('/courses/create/', data={ 'code': '', 'name': '', 'abstract': '' }) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'courses/course_create.html') def test_course_create_page_validation_errors_sent_to_template(self): self.client.login(username='******', password='******') response = self.client.post('/courses/create/', data={ 'code': '', 'name': '', 'abstract': '', }) expected_errors = ( COURSE_NAME_FIELD_REQUIRED_ERROR, COURSE_ABSTRACT_FIELD_REQUIRED_ERROR, ) for err in expected_errors: self.assertContains(response, err) def test_course_create_page_doesnot_show_errors_by_default(self): """ Check that errors don't show up when the form first loads """ self.client.login(username='******', password='******') response = self.client.get('/courses/create/') not_expected_errors = ( COURSE_NAME_FIELD_REQUIRED_ERROR, COURSE_ABSTRACT_FIELD_REQUIRED_ERROR, ) for err in not_expected_errors: self.assertNotContains(response, err) def test_course_create_page_invalid_form_passes_form_to_template(self): self.client.login(username='******', password='******') response = self.client.post('/courses/create/', data={ 'code': '', 'name': '', 'abstract': '' }) self.assertIsInstance(response.context['form'], CourseFullForm) def test_course_create_page_can_save_data(self): self.client.login(username='******', password='******') response = self.client.post('/courses/create/', data={ 'code': 'T01', 'name': 'Test', 'abstract': 'A test course' }) self.assertRedirects(response, '/courses/6/', 302, 200) response = self.client.get('/courses/6/') self.assertIn('T01', response.content) self.assertIn('Test', response.content) self.assertIn('A test course', response.content) def test_course_enrol_page_requires_login(self): response = self.client.get('/courses/1/enrol/') login_redirect_url = '/accounts/login/?next=/courses/1/enrol/' self.assertRedirects(response, login_redirect_url, 302, 200) def test_course_enrol_page_200_if_loggedin(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/enrol/') self.assertEqual(response.status_code, 200) def test_course_enrol_page_uses_correct_template(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/enrol/') self.assertTemplateUsed(response, 'courses/course_enrol.html') def test_course_enrol_page_has_enrol_button(self): self.client.login(username='******', password='******') response = self.client.get('/courses/3/enrol/') target = "id='id_enrol_button'" self.assertIn(target, response.content) def test_course_enrol_page_no_enrol_button_if_author(self): """Course organiser or instructor can't enrol!""" self.client.login(username='******', password='******') response = self.client.get('/courses/1/enrol/') target1 = "id='id_enrol_button'" self.assertNotIn(target1, response.content) target2 = "you can't enrol since you are involved in running "\ "this course." self.assertIn(target2, response.content) def test_course_enrol_page_has_correct_context_vars(self): self.client.login(username='******', password='******') response = self.client.get('/courses/1/enrol/') self.assertIn('course', response.context) self.assertIn('status', response.context) self.assertIn('fee_value', response.context) def test_course_enrol_page_status_auth_enrolled(self): """An authenticated and enrolled user status is passed to template""" self.client.login(username='******', password='******') #Enrol the user on the course (bertie is not organiser) uc = UserCourse(user=self.user1, course=self.course3) uc.save() response = self.client.get('/courses/3/enrol/') self.assertEqual('auth_enrolled', response.context['status'], "Registration status should be auth_enrolled") def test_course_enrol_page_status_noenrol(self): """Course instructor/organiser bar_enrol status passed to template""" self.client.login(username='******', password='******') #bert is course organiser response = self.client.get('/courses/1/enrol/') self.assertEqual('auth_bar_enrol', response.context['status'], "Registration status should be auth_bar_enrol") def test_enrol_page_abstract_renders_markdown(self): self.client.login(username='******', password='******') response = self.client.get('/courses/4/enrol/') self.assertIn('How to <em>wash</em> a cat', response.content) def test_enrol_page_has_organiser_instructor_links(self): """Course enrol template has correct links to instructor etc""" self.client.login(username='******', password='******') # Load up a course enrol page c2 = self.course2 c2.instructor.first_name="Hank" c2.instructor.last_name="Rancho" c2.instructor.save() url2 = '/courses/{0}/enrol/'.format(c2.pk) response = self.client.get(url2) # Check username appears for organiser org = c2.organiser t = '<p>Course organiser <a href="/accounts/profile/{1}/public/">{0}</a>' target = t.format(org.username, org.pk) resp = response.content.replace("\n", "").replace("\t", "") self.assertIn(target, resp) # Check full name appears for instructor inst = c2.instructor t = '<p>Course instructor <a href="/accounts/profile/{1}/public/">{0}</a>' target = t.format(inst.get_full_name(), inst.pk) self.assertIn(target, resp) def test_course_enrol_page_shows_free_course_enrol(self): """Free courses allow direct enrolment, no payment overlay""" self.client.login(username='******', password='******') course5 = Course.objects.get(pk=5) priced_item = PricedItem.objects.get(object_id=course5.id) priced_item.fee_value = 0 priced_item.save() response = self.client.get('/courses/5/enrol/') self.assertEqual(response.context['fee_value'], priced_item.fee_value) self.assertEqual(priced_item.fee_value, 0) #testing a free course self.assertRegexpMatches( response.content, "<button id=\\\'id_enrol_button\\\'[\s\S]*Enrol £Free"\ "[\S\s]*<\/button>") def test_course_enrol_stripe_Pay_with_Card_not_visible_free_course(self): self.client.login(username='******', password='******') response = self.client.get('/courses/5/enrol') #free course self.assertNotIn('stripe-button', response.content) def test_course_index_not_logged_in(self): """Check course index page loads OK and has correct variables""" response = self.client.get('/courses/') self.assertEqual(response.status_code, 200) #Next check template variables are present self.assertTrue( x in response.context for x in ['course_list', 'course_count']) def test_course_index_logged_in(self): """Check course index loads for logged in user""" url1 = '/courses/' self.client.login(username='******', password='******') response = self.client.get(url1) self.assertEqual(response.status_code, 200) self.assertIn('course_list', response.context, \ "Missing template var: course_list") self.assertIn('course_count', response.context, \ "Missing template var: course_count") def test_course_index_only_shows_published_courses(self): response = self.client.get('/courses/') self.assertIn('A Course of Leeches', response.content) self.assertIn('Basic Knitting', response.content) self.assertIn('Nut Bagging', response.content) self.assertIn('Washing', response.content) self.assertNotIn('Electronics', response.content) def test_course_index_shows_unpublished_course_to_author(self): self.client.login(username='******', password='******') response = self.client.get('/courses/') self.assertIn('A Course of Leeches', response.content) self.assertIn('Basic Knitting', response.content) self.assertIn('Nut Bagging', response.content) self.assertIn('Washing', response.content) self.assertIn('Electronics', response.content)
class TestViews(TestCase): """ Test suite for 'lesson' views """ def setUp(self): """ Method to set up the client and database content for Users, Programming Environments, Languages and Lessons """ self.client = Client() self.username = "******" self.password = "******" self.user = get_user_model().objects.create_user( "*****@*****.**", "Test", "TEACHER", "Tester", "Testing", "TestingPassword") self.saveLessonsToDB() pass def saveLessonsToDB(self): """ Method to create Programming Environment, Language and Lesson for the test database """ self.environment = ProgrammingEnvironment( environment_name="Web Applications", description="Test Description") self.environment.save() self.language = Language(language_name="JavaScript", description="Test Description", environment=self.environment) self.language.save() self.lesson = Lesson(language=self.language, lesson_title="Variables", lesson_description="Test Description", lesson_content="Test content", check_result="function check_result(result)\{\}", lesson_number=1, lesson_code=""" function variable_exercise(){ //Write variable here //Return the variable here }""") self.lesson.save() self.lessonHint = LessonHint(lesson=self.lesson, hint_title="Test Hint Title", hint_description="Test hint description") self.lessonHint.save() def login_client(self): """ Method for logging in the client """ self.client.login(username=self.username, password=self.password) def test_select_env_notloggedin(self): """ Method to test requesting the select environments page when not logged in """ response = self.client.get(reverse("lesson-select-env"), follow=True) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "classroom_main/login.html") def test_select_env_loggedin(self): """ Method to test requesting the select environments page when logged in """ self.login_client() response = self.client.get(reverse("lesson-select-env"), follow=True) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "lesson/select_env.html") def test_select_language_notloggedin(self): """ Method to test requesting the select language page when not logged in """ response = self.client.get(reverse( "lesson-select-language", kwargs={'environmentName': self.environment.environment_name}), follow=True) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "classroom_main/login.html") def test_select_language_loggedin(self): """ Method to test requesting the select language page when logged in """ self.login_client() response = self.client.get(reverse( "lesson-select-language", kwargs={'environmentName': self.environment.environment_name}), follow=True) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "lesson/select_language.html") def test_select_lesson_notloggedin(self): """ Method to test requesting the select lesson page when not logged in """ response = self.client.get(reverse( "lesson-select-lesson", kwargs={'languageTitle': self.language.language_name}), follow=True) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "classroom_main/login.html") def test_select_lesson_loggedin(self): """ Method to test requesting the select lesson page when logged in """ self.login_client() response = self.client.get(reverse( "lesson-select-lesson", kwargs={'languageTitle': self.language.language_name}), follow=True) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "lesson/select_lesson.html") def test_lesson_loggedin(self): """ Method to test requesting the lesson page when logged in """ self.login_client() response = self.client.get(reverse("lesson-lesson-specific", kwargs={ 'languageTitle': self.language.language_name, 'lessonTitle': self.lesson.lesson_title }), follow=True) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "lesson/lesson_base.html") self.assertInHTML(self.lesson.lesson_code, response.content.decode()) def test_next_lesson(self): """ Method used to test the 'next_lesson' function """ nextLesson = Lesson(language=self.language, lesson_title="Conditionals", lesson_description="Test Description", lesson_content="Test content", check_result="function check_result(result)\{\}", lesson_number=2, lesson_code="""test""") nextLesson.save() self.login_client() response = self.client.get(reverse("lesson-next-lesson", kwargs={ "languageTitle": self.language.language_name, "currentLessonTitle": self.lesson.lesson_title, "nextLessonTitle": nextLesson.lesson_title }), follow=True) newProgress = Progress.objects.filter( lesson__lesson_title=self.lesson.lesson_title) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "lesson/lesson_base.html") self.assertInHTML(nextLesson.lesson_title, response.content.decode()) self.assertIsNotNone(newProgress) def test_language_complete(self): self.login_client() response = self.client.get( reverse("lesson-language-complete", kwargs={ 'languageTitle': self.language.language_name, 'lessonTitle': self.lesson.lesson_title })) newProgress = Progress.objects.filter( lesson__lesson_title=self.lesson.lesson_title) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "lesson/language_complete.html") self.assertInHTML("Language Complete!", response.content.decode()) self.assertIsNotNone(newProgress) def test_compile_code_JS(self): """ Method to test the 'compile_code' function for JavaScript """ factory = RequestFactory() request = factory.get( r'/get_code/?untrustedCode=function%20variable_exercise()%7B%0A%20%20%2F%2FWrite%20variable%20here%0A%09return%20%22Test%22%0A%20%20%2F%2FReturn%20the%20variable%20here%0A%7D&language=javascript' ) data = compile_code(request) data = json.loads(data.content) self.assertEqual(data['output'], "Test") def test_compile_code_python(self): """ Method to test the 'compile_code' function for Python """ factory = RequestFactory() request = factory.get( r'/get_code/?untrustedCode=def%20variables_exercise()%3A%0A%20%20%20%20%23%20Write%20variable%20here%20%0A%09return%20%22Test%22%0A%20%20%20%20%23%20Return%20the%20variable&language=python' ) data = compile_code(request) data = json.loads(data.content) self.assertEqual(data['output'], "Test") def test_compile_code_htmlcss_valid(self): """ Method to test the 'compile_code' function for HTML & CSS """ factory = RequestFactory() request = factory.get( r'/get_code/?untrustedCode=%3Chtml%3E%0A%3Chead%3E%0A%3C%2Fhead%3E%0A%3Cbody%3E%0A%3C!--%20Create%20a%20H1%20tag%20here%20with%20the%20text%20%22Hello%20World!%22%20in%20--%3E%0A%20%20%3Ch1%3ETest%3C%2Fh1%3E%0A%3C%2Fbody%3E%0A%3C%2Fhtml%3E&language=html%20and%20css' ) data = compile_code(request) data = json.loads(data.content) self.assertInHTML(r'<h1>Test</h1>', data['HTML']) def test_compile_code_htmlcss_invalid(self): """ Method to test the 'compile_code' function for HTML & CSS """ factory = RequestFactory() request = factory.get( r'/get_code/?untrustedCode=%3Chead%3E%0A%3C%2Fhead%3E%0A%3Cbody%3E%0A%3C!--%20Create%20a%20H1%20tag%20here%20with%20the%20text%20%22Hello%20World!%22%20in%20--%3E%0A%20%20%3Ch1%3ETest%3C%2Fh1%3E%0A%3C%2Fbody%3E&language=html%20and%20css' ) data = compile_code(request) data = json.loads(data.content) self.assertInHTML( "You forgot to add core HTML structures such as <html>, <body> or <head>!", data['output'])
class OutcomeModelTests(TestCase): """Test the models of the outcome app""" course1_data = {'code': 'EDU02', 'name': 'A Course of Leeches', 'abstract': 'Learn practical benefits of leeches', } lesson1_data = {'name': 'Introduction to Music', 'abstract': 'A summary of what we cover', } def setUp(self): self.user1 = User.objects.create_user('bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.course1 = Course(**self.course1_data) self.course1.organiser = self.user1 self.course1.instructor = self.user1 self.course1.save() self.lesson1 = Lesson(course=self.course1, **self.lesson1_data) self.lesson1.save() self.learningintention1 = LearningIntention(lesson = self.lesson1, text = "Practise") self.learningintention1.save() self.lid1 = LearningIntentionDetail( learning_intention = self.learningintention1, text = "Choose", lid_type = LearningIntentionDetail.SUCCESS_CRITERION ) self.lid1.save() self.lid2 = LearningIntentionDetail( learning_intention = self.learningintention1, text = "Calculate", lid_type = LearningIntentionDetail.LEARNING_OUTCOME ) self.lid2.save() def test_learningIntention_checkrep_True_case(self): self.assertTrue(self.learningintention1._checkrep()) def test_learningIntention_checkrep_False_case(self): self.learningintention1.text = "" self.assertFalse(self.learningintention1._checkrep()) def test_learningIntention_checkrep_Error_case(self): with self.assertRaises(ValueError): self.learningintention1.lesson = None def test_learningIntention_create(self): """LearningIntention instance attributes are created OK""" self.assertEqual(self.learningintention1.lesson, self.lesson1) self.assertEqual(self.learningintention1.text, "Practise") def test_learningIntention_get_absolute_url(self): """Test that LI return correct absolute url""" url = self.learningintention1.get_absolute_url() target = u"/lesson/{0}/lint/{1}/".format( self.lesson1.pk, self.learningintention1.pk) self.assertEqual(target, url, "course URL error") def test_learningIntentionDetail_checkrep_True_case(self): self.lid1._checkrep() def test_learningIntentionDetail_checkrep_False_case_text(self): self.lid1.text = "" self.assertFalse(self.lid1._checkrep()) def test_learningIntentionDetail_checkrep_Raises_no_lidtype(self): self.lid1.lid_type = None with self.assertRaises(CheckRepError): self.lid1._checkrep() def test_learningIntentionDetail_checkrep_Error_case(self): with self.assertRaises(ValueError): self.lid1.learning_intention = None def test_learningIntentionDetail_no_save_without_lidtype(self): self.lid1.lid_type = None with self.assertRaises(CheckRepError): self.lid1.save() def test_successCriterion_create(self): """SuccessCriterion instance attributes are created OK""" self.assertEqual(self.lid1.learning_intention, self.learningintention1) self.assertEqual(self.lid1.text, "Choose") self.assertEqual(self.lid1.lid_type, LearningIntentionDetail.SUCCESS_CRITERION) def test_learningOutcome_create(self): """LearningOutcome instance attributes are created OK""" self.assertEqual(self.lid2.learning_intention, self.learningintention1) self.assertEqual(self.lid2.text, "Calculate") self.assertEqual(self.lid2.lid_type, LearningIntentionDetail.LEARNING_OUTCOME)
class OutcomeViewTests(TestCase): """Test the outcome specific views""" course1_data = {'code': 'EDU02', 'name': 'A Course of Leeches', 'abstract': 'Learn practical benefits of leeches', } lesson1_data = { 'name': 'Introduction to Music', 'abstract': 'A summary of what we cover', } def setUp(self): self.user1 = User.objects.create_user( 'bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.user2 = User.objects.create_user('dave', '*****@*****.**', 'dave') self.user2.is_active = True self.user2.save() self.course1 = Course(**self.course1_data) self.course1.instructor = self.user2 self.course1.organiser = self.user2 self.course1.save() self.lesson1 = Lesson(course=self.course1, **self.lesson1_data) self.lesson1.save() self.learningintention1 = LearningIntention( lesson = self.lesson1, text = "Practise") self.learningintention1.save() self.lid1 = LearningIntentionDetail( learning_intention = self.learningintention1, text = "Choose Topaz", lid_type = LearningIntentionDetail.SUCCESS_CRITERION ) self.lid1.save() self.lid2 = LearningIntentionDetail( learning_intention = self.learningintention1, text = "Eat fish", lid_type = LearningIntentionDetail.SUCCESS_CRITERION ) self.lid2.save() self.lid3 = LearningIntentionDetail( learning_intention = self.learningintention1, text = "Calculate 6*9", lid_type = LearningIntentionDetail.LEARNING_OUTCOME ) self.lid3.save() self.profile1 = self.user1.profile self.profile1.accepted_terms = True self.profile1.signature_line = 'Learning stuff' self.profile1.save() def test_learning_intention(self): """Test view of a single learning intention""" les1 = self.lesson1.id lint1 = self.learningintention1.id url1 = "/lesson/{0}/lint/{1}/".format(les1,lint1) response = self.client.get(url1) self.assertEqual(response.status_code, 200) self.assertTrue(x in response.context for x in ['lesson_id', 'lesson_intention_id']) self.assertIn("Choose Topaz", response.content, "SC missing") self.assertIn("Calculate 6*9", response.content, "LO missing") cycle1 = "cycle{0}".format(self.lid1.id) cycle2 = "cycle{0}".format(self.lid2.id) self.assertIn(cycle1, response.content, "Cycle button missing") self.assertIn(cycle2, response.content, "Cycle button missing") #test non-existing LI response = self.client.get('/lesson/1/lint/5000/') self.assertEqual(response.status_code, 404) #test not logged in response = self.client.get(url1) self.assertNotIn('progressSC', response.context) ### Success Criteria Cycle Tests #press some buttons and see what happens self.client.login(username='******', password='******') #Register user on course first: uc = UserCourse(course=self.course1, user=self.user1) uc.save() #cycle to amber response = self.client.post(url1, {cycle1:'Cycle'}) self.assertEqual(response.status_code, 200) trafficlight = response.context['usc_list'][0][2].condition self.assertEqual(trafficlight, 1) self.assertInHTML( "<img id='id_SC1' class='tl-amber' "\ "src='/static/images/img_trans.png'>", response.content) self.assertContains( response, '<li class="criterion" data-id="1">') self.assertIn( '<li class="learning_outcome" data-id="3">', response.content) self.assertEqual( response.context['progressSC'], (0,2,2,100)) #progress bar self.assertEqual( response.context['progressLO'], (0,1,1,100)) #progress bar #cycle to green response = self.client.post(url1, {cycle1:'Cycle'}) self.assertEqual(response.status_code, 200) trafficlight = response.context['usc_list'][0][2].condition self.assertEqual(trafficlight, 2) self.assertInHTML( "<img id='id_SC1' class='tl-green' "\ "src='/static/images/img_trans.png'>", response.content) self.assertEqual( response.context['progressSC'], (1,1,2,100)) #progress bar self.assertEqual( response.context['progressLO'], (0,1,1,100)) #progress bar #cycle to red response = self.client.post(url1, {cycle1:'Cycle'}) self.assertEqual(response.status_code, 200) trafficlight = response.context['usc_list'][0][2].condition self.assertEqual(trafficlight, 0) self.assertInHTML( "<img id='id_SC1' class='tl-red' "\ "src='/static/images/img_trans.png'>", response.content) self.assertEqual( response.context['progressSC'], (0,2,2,100)) #progress bar self.assertEqual( response.context['progressLO'], (0,1,1,100)) #progress bar
class AttachmentModelTests(TestCase): """Test models user interaction with courses""" course1_data = { 'code': 'EDU01', 'name': 'A Course of Leeches', 'abstract': 'Learn practical benefits of leeches', } lesson1_data = { 'name': 'Introduction to Music', 'abstract': 'A summary of what we cover', } att1_data = { 'name': 'Reading List', 'desc': 'Useful stuff you might need', 'seq': 3, 'attachment': 'empty_attachment_test.txt', } att2_data = { 'name': 'Grammar Guide', 'desc': 'How do you even spell grammer?', 'seq': 2, 'attachment': 'empty_attachment_test.txt', } def setUp(self): self.user1 = User.objects.create_user( 'bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.user2 = User.objects.create_user('dave', '*****@*****.**', 'dave') self.user2.is_active = True self.user2.save() self.course1 = Course(**self.course1_data) self.course1.instructor = self.user1 self.course1.organiser = self.user1 self.course1.save() self.lesson1 = Lesson(course=self.course1, **self.lesson1_data) self.lesson1.save() #att1 attached to course self.att1 = Attachment(course=self.course1, **self.att1_data) self.att1.save() #att2 attached to lesson self.att2 = Attachment(lesson=self.lesson1, **self.att1_data) self.att2.save() self.uc = UserCourse(course=self.course1, user=self.user2) self.uc.save() def test_checkrep(self): """Test the internal representation checker with attachments""" self.assertTrue(self.uc._checkrep(), "New attachment checkrep failed") def test___str__(self): """Test that the desired info is in the __str__ method""" s = self.att1.__str__() target = u"Attachment %s, '%s...'" % (self.att1.pk, self.att1.name[:10]) self.assertEqual(s, target, "Incorrect __str__ return") def test___unicode__(self): """Test that the desired info is in the unicode method""" unicod = self.att1.__unicode__() target = u"Att. ID:%s, '%s...'" % (self.att1.pk, self.att1.name[:10]) self.assertEqual(unicod, target, "Incorrect __unicode__ return") def test_get_absolute_url(self): """Test the correct url is returned""" url = self.att1.get_absolute_url() target = self.att1.attachment self.assertEqual(target.url, url, "attachment URL error") def test_get_metadata_url(self): """Test that the correct metadata url is returned""" url = self.att1.get_metadata_url() target = u"/attachment/%s/metadata/" % self.att1.pk self.assertEqual(target, url, "attachment metadata URL error")
class UserAttachmentViewTests(TestCase): """Test view functions for user interaction with attachments""" att1_data = { 'name': 'Reading List', 'desc': 'Useful stuff you might need', 'seq': 3, 'attachment': 'attachments/empty_attachment_test.txt', } att2_data = { 'name': 'Grammer Guide', 'desc': 'How do you even spell grammer?', 'seq': 2, 'attachment': 'attachments/empty_attachment_test.txt', } def setUp(self): self.user1 = User.objects.create_user( 'bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.user2 = User.objects.create_user('dave', '*****@*****.**', 'dave') self.user2.is_active = True self.user2.save() self.user3 = User.objects.create_user( 'Chuck Norris', '*****@*****.**', 'dontask') self.user3.is_active = True self.user3.save() self.course1 = Course(**course1_data) self.course1.organiser = self.user1 self.course1.instructor = self.user1 self.course1.save() self.uc = UserCourse(course=self.course1, user=self.user2) self.uc.save() self.lesson1 = Lesson(name="Test Lesson 1", course = self.course1) self.lesson1.save() #att1 attached to course self.att1 = Attachment(course=self.course1, **self.att1_data) self.att1.save() #att2 attached to lesson self.att2 = Attachment(lesson=self.lesson1, **self.att1_data) self.att2.save() with open('media/attachments/empty_attachment_test.txt', 'w') as f: f.write('test') def test_attachment_download_not_logged_in(self): """Casual visitor - download not permitted, redirect to login""" a1 = self.att1.id a2 = self.att2.id url1 = '/interaction/attachment/{0}/download/'.format(a1) url1_r = '/accounts/login/?next={0}'.format(url1) url2 = '/interaction/attachment/{0}/download/'.format(a2) url2_r = '/accounts/login/?next={0}'.format(url2) #First try attachment linked to course page response = self.client.get(url1) self.assertRedirects(response, url1_r, 302, 200) self.assertRaises(ObjectDoesNotExist, UserAttachment.objects.get, id=a1) #Second, try attachment linked to a lesson page response = self.client.get(url2) self.assertRedirects(response, url2_r, 302, 200) self.assertRaises(ObjectDoesNotExist, UserAttachment.objects.get, id=a2) # @override_settings(DEBUG=True) def test_attachment_download_author(self): """Course author can download attachments""" a1 = self.att1.id #attached to course a2 = self.att2.id #attached to lesson url1 = '/interaction/attachment/{0}/download/'.format(a1) url1_r = self.att1.get_absolute_url() url2 = '/interaction/attachment/{0}/download/'.format(a2) url2_r = self.att2.get_absolute_url() #First, try attachment linked to course page self.client.login(username='******', password='******') response = self.client.get(url1) self.assertEqual(response.status_code, 302) #having to comment out redirect tests as can't get TestClient to #server STATIC content #self.assertRedirects(response, url1_r, 302, 200) #Second, try attachment linked to lesson page response = self.client.get(url2) self.assertEqual(response.status_code, 302) #self.assertRedirects(response, url2_r, 302, 200) def test_attachment_download_loggedin_but_not_enrolled(self): """Not enrolled visitor - redirect to enrol page""" a1 = self.att1.id a2 = self.att2.id url1 = '/interaction/attachment/{0}/download/'.format(a1) url1_r = '/courses/{0}/enrol/'.format(self.att1.course.id) url2 = '/interaction/attachment/{0}/download/'.format(a2) url2_r = '/courses/{0}/enrol/'.format(self.att2.lesson.course.id) self.client.login(username='******', password='******') #First, try attachment linked to course page response = self.client.get(url1) self.assertRedirects(response, url1_r, 302, 200) self.assertRaises(ObjectDoesNotExist, UserAttachment.objects.get, id=a1) #Second, try attachment linked to lesson page response = self.client.get(url2) self.assertRedirects(response, url2_r, 302, 200) self.assertRaises(ObjectDoesNotExist, UserAttachment.objects.get, id=a2) def test_attachment_download_loggedin_and_enrolled(self): """Enrolled visitor - download is recorded""" a1 = self.att1.id a2 = self.att2.id url1 = "/interaction/attachment/{0}/download/".format(a1) url2 = "/interaction/attachment/{0}/download/".format(a2) #First, try attachment linked to course page self.client.login(username='******', password='******') response = self.client.get(url1) self.assertEqual(response.status_code, 302) u_att1 = UserAttachment.objects.get( user=self.user2.id, attachment=self.att1.id ) self.assertEqual(len(u_att1.hist2list()),1) #Calling get(url1) again, history should grow by one log entry response = self.client.get(url1) u_att1 = UserAttachment.objects.get( user=self.user2.id, attachment=a1 ) self.assertEqual(len(u_att1.hist2list()),2) #Second, try attachment linked to lesson page response = self.client.get(url2) self.assertEqual(response.status_code, 302) u_att2 = UserAttachment.objects.get( user=self.user2.id, attachment=a2 ) self.assertEqual(len(u_att2.hist2list()),1) #Calling get(url2) again, history should grow by one log entry response = self.client.get(url2) u_att2 = UserAttachment.objects.get( user=self.user2.id, attachment=a2 ) self.assertEqual(len(u_att2.hist2list()),2)
class UserLearningIntentionViewTests(TestCase): """Test views for learning intention interaction""" def setUp(self): self.user1 = User.objects.create_user('bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.user2 = User.objects.create_user('Van Gogh', '*****@*****.**', 'vancode') self.user2.is_active = True self.user2.save() self.user3 = User.objects.create_user('Chuck Norris', '*****@*****.**', 'dontask') self.user3.is_active = True self.user3.save() self.course1 = Course(**course1_data) self.course1.instructor = self.user2 self.course1.organiser = self.user2 self.course1.save() self.uc = UserCourse(course=self.course1, user=self.user1) self.uc.save() self.lesson = Lesson(name="Test Lesson 1", course = self.course1) self.lesson.save() self.li = LearningIntention(lesson=self.lesson, text="Intend...") self.li.save() self.uli = UserLearningIntention(user=self.user1, learning_intention = self.li) self.lid1 = LearningIntentionDetail( learning_intention=self.li, text ="LID A", lid_type=LearningIntentionDetail.SUCCESS_CRITERION) self.lid2 = LearningIntentionDetail( learning_intention=self.li, text ="LID B", lid_type=LearningIntentionDetail.SUCCESS_CRITERION) self.lid3 = LearningIntentionDetail( learning_intention=self.li, text ="LID C", lid_type=LearningIntentionDetail.LEARNING_OUTCOME) self.lid1.save() self.lid2.save() self.lid3.save() self.ulid1 = UserLearningIntentionDetail(user=self.user1, learning_intention_detail=self.lid1) self.ulid1.save() self.ulid2 = UserLearningIntentionDetail(user=self.user1, learning_intention_detail=self.lid2) self.ulid2.save() self.ulid3 = UserLearningIntentionDetail(user=self.user1, learning_intention_detail=self.lid3) self.ulid3.save() def test_userlearningintention_cycle_redirect_not_enrolled(self): """If user not enrolled, can't cycle learning intentions""" not_enrolled_user = self.user3 course = self.course1 lid = self.lid1 self.client.login(username='******', password='******') cycle_url = "/interaction/learningintentiondetail/{0}/cycle/" \ .format(lid.pk) response = self.client.get(cycle_url) parsed_json = json.loads(response.content) self.assertEqual(parsed_json['authenticated'], True) self.assertEqual(parsed_json['enrolled'], False) self.assertEqual(parsed_json['course_pk'], 1) def test_userlearningintention_cycle_context(self): """Ensure correct context variables present for enrolled user""" enrolled_user = self.user1 course = self.course1 lid = self.lid1 self.client.login(username="******", password="******") cycle_url = "/interaction/learningintentiondetail/{0}/cycle/" \ .format(lid.pk) response = self.client.get(cycle_url) self.assertEqual(response.status_code, 200) parsed_json = json.loads(response.content) self.assertEqual(parsed_json['authenticated'], True) self.assertEqual(parsed_json['enrolled'], True) self.assertEqual(parsed_json['progress'], {u'SC': [0, 2], u'LO': [0, 1]}) self.assertEqual(parsed_json['condition'], 1) def test_userlearningintention_progress_bar(self): """View returns correct data for AJAX call""" #self.fail("fix"); #Not logged in response = self.client.get('/interaction/learningintentiondetail'\ '/1/progress/') self.assertEqual(response.status_code, 302) #Now logged in self.client.login(username='******', password='******') #current implementation will not record progress without an #initial cycle self.client.get('/interaction/learningintentiondetail/{0}/cycle/'\ .format(self.lid1.pk)) response = self.client.get( '/interaction/learningintentiondetail/{0}/progress/'\ .format(self.lid1.pk)) self.assertEqual(response.status_code, 200)
def lesson_edit(request, lesson_id=None): if lesson_id: lesson = get_object_or_404(Lesson, pk=lesson_id) title = "レッスン受講記録編集" else: lesson = Lesson() title = "レッスン受講記録登録" if request.method == 'POST': form = LessonForm(request.POST, instance=lesson) if form.is_valid(): lesson = form.save(commit=False) lesson.charge_yen = 0 lesson.save() # 対象ユーザーの対象プランの当月受講履歴を取得 year = int(lesson.date.strftime('%Y')) month = int(lesson.date.strftime('%m')) first_day = date(year, month, 1) end_day = date(year, month + 1, 1) - timedelta(days=1) q = Q(member=lesson.member, plan=lesson.plan, date__range=[first_day, end_day]) t_lessons = Lesson.objects.filter(q).order_by('date') ruiseki_start = 0 # 累積開始時間 ruiseki_end = 0 # 累積終了時間 # 当月受講履歴をひとつずつ計算する for t_lesson in t_lessons: print("id:" + str(t_lesson.id)) # 今回の累積レッスン終了時間 ruiseki_end += t_lesson.hour # 今回の支払金額 charge_yen = 0 # 基本時間 > 0 if t_lesson.plan.basic_include_hour > 0: # 累積終了時間 <= 基本時間 if ruiseki_end <= t_lesson.plan.basic_include_hour: t_lesson.charge_yen = charge_yen t_lesson.save() continue else: ruiseki_start = t_lesson.plan.basic_include_hour # 従量開始時間 <= 累積終了時間 # 従量開始時間 <= 累積開始時間 # 累積開始時間 <= 従量終了時間 または 従量終了時間 is null plan_paygs = PlanPayg.objects.filter( Q(Q(plan=t_lesson.plan), Q( payg_end_hour__gte=ruiseki_start), Q(payg_start_hour__lte=ruiseki_end)) | Q(Q( plan=t_lesson.plan), Q( payg_start_hour__lte=ruiseki_end), Q(payg_end_hour__isnull=True))).order_by( 'payg_start_hour') for plan_payg in plan_paygs: print("ruiseki_start:" + str(ruiseki_start)) print("ruiseki_end:" + str(ruiseki_end)) print("before_charge_yen:" + str(charge_yen)) if plan_paygs.count( ) > 1 and plan_payg.payg_end_hour is not None: if plan_payg == plan_paygs.last(): # (累積終了時間 - 現在の従量開始時間) × 従量料金 now_hour = (ruiseki_end - ruiseki_start) charge_yen += (ruiseki_end - ruiseki_start ) * plan_payg.payg_charge_yen ruiseki_start = ruiseki_end else: # (現在の従量終了時間 - 累積開始時間) × 従量料金 now_hour = (plan_payg.payg_end_hour - ruiseki_start) charge_yen += ( plan_payg.payg_end_hour - ruiseki_start) * plan_payg.payg_charge_yen ruiseki_start = plan_payg.payg_end_hour else: # (累積終了時間 - 累積開始時間) × 従量料金 now_hour = (ruiseki_end - ruiseki_start) charge_yen += (ruiseki_end - ruiseki_start ) * plan_payg.payg_charge_yen ruiseki_start = ruiseki_end print("now_hour:" + str(now_hour)) print("after_charge_yen:" + str(charge_yen)) print("payg_charge_yen:" + str(plan_payg.payg_charge_yen)) # 支払金額を更新 t_lesson.charge_yen = charge_yen t_lesson.save() return redirect('lesson:lesson_list') else: form = LessonForm(instance=lesson) return render(request, 'lesson/edit.html', dict(form=form, lesson_id=lesson_id, title=title))
class UserLessonModelTests(TestCase): """Test models user interaction with lessons""" def setUp(self): #set up courses, one user, enrol the user on course1, but not course2 self.user1 = User.objects.create_user('bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.user2 = User.objects.create_user('flo', '*****@*****.**', 'flo') self.user2.is_active = True self.user2.save() self.course1 = Course(**course1_data) self.course1.organiser = self.user1 self.course1.instructor = self.user1 self.course1.save() self.course2 = Course(**course2_data) self.course2.organiser = self.user1 self.course2.instructor = self.user1 self.course2.save() self.uc = UserCourse(course=self.course1, user=self.user2) self.uc.save() self.lesson1 = Lesson(name="Test Lesson 1", course = self.course1) self.lesson1.save() self.ul = UserLesson(user=self.user2, lesson=self.lesson1) self.ul.save() self.lesson2 = Lesson(name="Test Lesson 2", course = self.course1) self.lesson2.save() self.ul2 = UserLesson(user=self.user2, lesson=self.lesson2) self.ul2.save() self.lesson3 = Lesson(name="Test Lesson 3", course = self.course1) self.lesson3.save() self.ul3 = UserLesson(user=self.user2, lesson=self.lesson3) self.ul3.save() self.lesson4 = Lesson(name="Test Lesson 4, in course 2", course = self.course2) self.lesson4.save() def test_checkrep(self): """Test the internal representation checker with lesson 1""" self.assertTrue(self.ul._checkrep(), "First visit to lesson - checkrep failed") self.ul.visited = False self.ul.completed = False with self.assertRaises(CheckRepError): self.ul._checkrep() self.ul.visited = False self.ul.completed = True with self.assertRaises(CheckRepError): self.ul._checkrep() self.ul.visited = True self.ul.completed = False self.assertTrue(self.ul._checkrep(), "Checkrep false failure") self.ul.visited = True self.ul.completed = True self.assertTrue(self.ul._checkrep(), "Checkrep false failure") self.ul.completed = False self.ul.complete() self.assertTrue(self.ul2._checkrep(), "Checkrep false failure") self.ul.completed = False self.assertFalse(self.ul._checkrep(), "Checkrep didn't pick up failing state") # Test states of flags 'visited' 'completed' or VC # --, -C would be Error state # VC, V- OK def test__checkrep_VC_flags_OK(self): # new ul, activated by save() method self.ul.complete() self.assertTrue(self.ul.completed) self.assertTrue(self.ul.visited) self.assertTrue(self.ul._checkrep()) def test__checkrep_V_flags_OK(self): self.assertTrue(self.ul.visited) self.assertFalse(self.ul.completed) self.assertTrue(self.ul._checkrep()) def test__checkrep_False_flags_Error(self): self.ul.visited = False self.ul.completed = False with self.assertRaises(CheckRepError): self.ul._checkrep() def test__checkrep_flags_Error(self): self.ul.completed = True self.ul.visited = False with self.assertRaises(CheckRepError): self.ul._checkrep() def test_userlesson_create(self): """Test creating new row with lesson 2 and 4""" self.assertTrue(self.ul2.pk, "Failed to create new db entry") self.assertTrue(self.ul2._checkrep(), "_checkrep failed") #userlesson for lesson 4 should fail, as not enrolled on course2 ul4 = UserLesson(user=self.user1, lesson=self.lesson4) ul4.save() self.assertIsNone(ul4.pk) def test_hist2list(self): """Test conversion of JSON encoded history to tuple list with course 3""" self.ul3.complete() self.ul3.reopen() self.ul3.complete() h2l_output = self.ul3.hist2list() self.assertIsInstance(h2l_output, list, "Output should be a list") for row in h2l_output: self.assertIsInstance(row, tuple, "Entry should be a tuple") self.assertIsInstance(row[0], datetime.datetime, "Should be a datetime") self.assertTrue(is_aware(row[0]), "Datetime not TZ aware") self.assertIsInstance(row[1], str, "Action should be a string") #Now check the history messages in reverse order. last = h2l_output.pop() self.assertEqual(last[1], 'COMPLETING', "Action should be COMPLETING") last = h2l_output.pop() self.assertEqual(last[1], 'REOPENING', "Action should be REOPENING") last = h2l_output.pop() self.assertEqual(last[1], 'COMPLETING', "Action should be COMPLETING") last = h2l_output.pop() self.assertEqual(last[1], 'VISITING', "Action should be VISITING") def test_reopen(self): """Test the lesson reopen method""" self.ul.complete() self.ul.reopen() h2l_output = self.ul.hist2list() last = h2l_output.pop() self.assertEqual(last[1], 'REOPENING', "Wrong action in history") self.assertEqual(self.ul.visited, True, "Visited should be set") self.assertEqual(self.ul.completed, False, "Completed should not be set") def test_complete(self): """Test the lesson complete method""" self.ul.complete() h2l_output = self.ul.hist2list() last = h2l_output.pop() self.assertEqual(last[1], 'COMPLETING', "Wrong action in history") self.assertEqual(self.ul.visited, True, "Visited should be set") self.assertEqual(self.ul.completed, True, "Completed should be set") def test_visit(self): """Test visiting lessons""" self.ul.visit() h2l_output = self.ul.hist2list() last = h2l_output.pop() self.assertEqual(last[1], 'VISITING', "Wrong action in history") self.assertEqual(self.ul.visited, True, "Visited should be set") #The following should not produce a database record. #The user is not enrolled on the corresponding course. #ul4 = UserLesson(user=self.user1, lesson=self.lesson4) #ul4.visit() #can't run test, visit() asserts on failed _checkrep (as it should) #self.assertIsNone(ul4.pk) def test_get_status(self): """Test that the correct status is returned""" self.assertEqual(self.ul.get_status(), 'visited', "Status should be 'active'") self.ul.complete() self.assertEqual(self.ul.get_status(), 'completed', "Status should be 'completed'") self.ul.reopen() self.assertEqual(self.ul.get_status(), 'visited', "Status should be 'active'") def test___str__(self): """Test that the desired info is in the unicode method""" s = self.ul3.__str__() self.assertIn(self.ul3.user.username, s, "The username should be in the unicode") self.assertIn(self.ul3.lesson.name, s, "The lesson_name should be in the unicode") def test___unicode__(self): """Test that the desired info is in the unicode method""" unicod = self.ul3.__unicode__() s = u"UL:%s, User:%s, Lesson:%s" % \ (self.ul3.pk, self.ul3.user.pk, self.ul3.lesson.pk) self.assertEqual(unicod, s, "Unicode output failure") def test_get_absolute_url(self): """Test the correct url is returned""" url = self.ul3.get_absolute_url() u = self.ul3.user.pk l = self.ul3.lesson.pk s = u"/interaction/user/%s/lesson/%s/"% (u,l) self.assertEqual(s, url, "URL error")
class UserLearningIntentionModelTests(TestCase): """Test model behaviour of user interaction with learning intentions""" def setUp(self): self.user1 = User.objects.create_user('bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.user2 = User.objects.create_user('flo', '*****@*****.**', 'flo') self.user2.is_active = True self.user2.save() self.course1 = Course(**course1_data) self.course1.instructor = self.user1 self.course1.organiser = self.user1 self.course1.save() self.uc = UserCourse(course=self.course1, user=self.user2) self.uc.save() self.lesson = Lesson(name="Test Lesson 1", course = self.course1) self.lesson.save() self.li = LearningIntention(lesson=self.lesson, text="Intend...") self.li.save() self.uli = UserLearningIntention(user=self.user2, learning_intention = self.li) self.lid1 = LearningIntentionDetail( learning_intention=self.li, text ="LID A", lid_type=LearningIntentionDetail.SUCCESS_CRITERION) self.lid2 = LearningIntentionDetail( learning_intention=self.li, text ="LID B", lid_type=LearningIntentionDetail.SUCCESS_CRITERION) self.lid3 = LearningIntentionDetail( learning_intention=self.li, text ="LID C", lid_type=LearningIntentionDetail.SUCCESS_CRITERION) self.lid4 = LearningIntentionDetail( learning_intention=self.li, text ="LID D", lid_type=LearningIntentionDetail.LEARNING_OUTCOME) self.lid5 = LearningIntentionDetail( learning_intention=self.li, text ="LID E", lid_type=LearningIntentionDetail.LEARNING_OUTCOME) self.lid6 = LearningIntentionDetail( learning_intention=self.li, text ="LID F", lid_type=LearningIntentionDetail.LEARNING_OUTCOME) self.lid1.save() self.lid2.save() self.lid3.save() self.lid4.save() self.lid5.save() self.lid6.save() self.ulid1 = UserLearningIntentionDetail(user=self.user2, learning_intention_detail=self.lid1) self.ulid1.save() self.ulid2 = UserLearningIntentionDetail(user=self.user2, learning_intention_detail=self.lid2) self.ulid2.save() self.ulid3 = UserLearningIntentionDetail(user=self.user2, learning_intention_detail=self.lid3) self.ulid3.save() self.ulid4 = UserLearningIntentionDetail(user=self.user2, learning_intention_detail=self.lid4) self.ulid4.save() self.ulid5 = UserLearningIntentionDetail(user=self.user2, learning_intention_detail=self.lid5) self.ulid5.save() self.ulid6 = UserLearningIntentionDetail(user=self.user2, learning_intention_detail=self.lid6) self.ulid6.save() def test___unicode__(self): self.assertEqual(u"ULI:%s, User:%s, LI:%s" % \ (self.uli.pk, self.user2.pk, self.li.pk), self.uli.__unicode__()) def test___str__(self): self.assertEqual(u"User %s's data for LI:%s..." % \ (self.user2.username, self.li.text[:10]), self.uli.__str__()) def test_progress(self): self.assertEqual(self.uli.progress(), {u'SC':(0,3), u'LO':(0,3)}) self.ulid1.cycle() self.assertEqual(self.uli.progress(), {u'SC':(0,3), u'LO':(0,3)}) self.ulid1.cycle() self.assertEqual(self.uli.progress(), {u'SC':(1,3), u'LO':(0,3)}) self.ulid4.cycle() self.assertEqual(self.uli.progress(), {u'SC':(1,3), u'LO':(0,3)}) self.ulid4.cycle() self.assertEqual(self.uli.progress(), {u'SC':(1,3), u'LO':(1,3)}) self.ulid2.cycle() self.ulid2.cycle() self.ulid3.cycle() self.assertEqual(self.uli.progress(), {u'SC':(2,3), u'LO':(1,3)}) self.ulid3.cycle() self.ulid4.cycle() self.assertEqual(self.uli.progress(), {u'SC':(3,3), u'LO':(0,3)}) self.ulid5.cycle() self.ulid5.cycle() self.assertEqual(self.uli.progress(), {u'SC':(3,3), u'LO':(1,3)}) self.ulid6.cycle() self.ulid6.cycle() self.assertEqual(self.uli.progress(), {u'SC':(3,3), u'LO':(2,3)})
class AttachmentModelTests(TestCase): """Test models user interaction with courses""" course1_data = {"code": "EDU01", "name": "A Course of Leeches", "abstract": "Learn practical benefits of leeches"} lesson1_data = {"name": "Introduction to Music", "abstract": "A summary of what we cover"} att1_data = { "name": "Reading List", "desc": "Useful stuff you might need", "seq": 3, "attachment": "empty_attachment_test.txt", } att2_data = { "name": "Grammar Guide", "desc": "How do you even spell grammer?", "seq": 2, "attachment": "empty_attachment_test.txt", } def setUp(self): self.user1 = User.objects.create_user("bertie", "*****@*****.**", "bertword") self.user1.is_active = True self.user1.save() self.user2 = User.objects.create_user("dave", "*****@*****.**", "dave") self.user2.is_active = True self.user2.save() self.course1 = Course(**self.course1_data) self.course1.instructor = self.user1 self.course1.organiser = self.user1 self.course1.save() self.lesson1 = Lesson(course=self.course1, **self.lesson1_data) self.lesson1.save() # att1 attached to course self.att1 = Attachment(course=self.course1, **self.att1_data) self.att1.save() # att2 attached to lesson self.att2 = Attachment(lesson=self.lesson1, **self.att1_data) self.att2.save() self.uc = UserCourse(course=self.course1, user=self.user2) self.uc.save() def test_checkrep(self): """Test the internal representation checker with attachments""" self.assertTrue(self.uc._checkrep(), "New attachment checkrep failed") def test___str__(self): """Test that the desired info is in the __str__ method""" s = self.att1.__str__() target = u"Attachment %s, '%s...'" % (self.att1.pk, self.att1.name[:10]) self.assertEqual(s, target, "Incorrect __str__ return") def test___unicode__(self): """Test that the desired info is in the unicode method""" unicod = self.att1.__unicode__() target = u"Att. ID:%s, '%s...'" % (self.att1.pk, self.att1.name[:10]) self.assertEqual(unicod, target, "Incorrect __unicode__ return") def test_get_absolute_url(self): """Test the correct url is returned""" url = self.att1.get_absolute_url() target = self.att1.attachment self.assertEqual(target.url, url, "attachment URL error") def test_get_metadata_url(self): """Test that the correct metadata url is returned""" url = self.att1.get_metadata_url() target = u"/attachment/%s/metadata/" % self.att1.pk self.assertEqual(target, url, "attachment metadata URL error")
class OutcomeModelTests(TestCase): """Test the models of the outcome app""" course1_data = { 'code': 'EDU02', 'name': 'A Course of Leeches', 'abstract': 'Learn practical benefits of leeches', } lesson1_data = { 'name': 'Introduction to Music', 'abstract': 'A summary of what we cover', } def setUp(self): self.user1 = User.objects.create_user('bertie', '*****@*****.**', 'bertword') self.user1.is_active = True self.user1.save() self.course1 = Course(**self.course1_data) self.course1.organiser = self.user1 self.course1.instructor = self.user1 self.course1.save() self.lesson1 = Lesson(course=self.course1, **self.lesson1_data) self.lesson1.save() self.learningintention1 = LearningIntention(lesson=self.lesson1, text="Practise") self.learningintention1.save() self.lid1 = LearningIntentionDetail( learning_intention=self.learningintention1, text="Choose", lid_type=LearningIntentionDetail.SUCCESS_CRITERION) self.lid1.save() self.lid2 = LearningIntentionDetail( learning_intention=self.learningintention1, text="Calculate", lid_type=LearningIntentionDetail.LEARNING_OUTCOME) self.lid2.save() def test_learningIntention_checkrep_True_case(self): self.assertTrue(self.learningintention1._checkrep()) def test_learningIntention_checkrep_False_case(self): self.learningintention1.text = "" self.assertFalse(self.learningintention1._checkrep()) def test_learningIntention_checkrep_Error_case(self): with self.assertRaises(ValueError): self.learningintention1.lesson = None def test_learningIntention_create(self): """LearningIntention instance attributes are created OK""" self.assertEqual(self.learningintention1.lesson, self.lesson1) self.assertEqual(self.learningintention1.text, "Practise") def test_learningIntention_get_absolute_url(self): """Test that LI return correct absolute url""" url = self.learningintention1.get_absolute_url() target = u"/lesson/{0}/lint/{1}/".format(self.lesson1.pk, self.learningintention1.pk) self.assertEqual(target, url, "course URL error") def test_learningIntentionDetail_checkrep_True_case(self): self.lid1._checkrep() def test_learningIntentionDetail_checkrep_False_case_text(self): self.lid1.text = "" self.assertFalse(self.lid1._checkrep()) def test_learningIntentionDetail_checkrep_Raises_no_lidtype(self): self.lid1.lid_type = None with self.assertRaises(CheckRepError): self.lid1._checkrep() def test_learningIntentionDetail_checkrep_Error_case(self): with self.assertRaises(ValueError): self.lid1.learning_intention = None def test_learningIntentionDetail_no_save_without_lidtype(self): self.lid1.lid_type = None with self.assertRaises(CheckRepError): self.lid1.save() def test_successCriterion_create(self): """SuccessCriterion instance attributes are created OK""" self.assertEqual(self.lid1.learning_intention, self.learningintention1) self.assertEqual(self.lid1.text, "Choose") self.assertEqual(self.lid1.lid_type, LearningIntentionDetail.SUCCESS_CRITERION) def test_learningOutcome_create(self): """LearningOutcome instance attributes are created OK""" self.assertEqual(self.lid2.learning_intention, self.learningintention1) self.assertEqual(self.lid2.text, "Calculate") self.assertEqual(self.lid2.lid_type, LearningIntentionDetail.LEARNING_OUTCOME)