Покрыть тестами - заполнение курсов.

remotes/origin/feature/testing_courses_30-01-19
gzbender 7 years ago
parent 2c310f3714
commit 837be11bfe
  1. 32
      apps/content/tests/mixins.py
  2. 91
      apps/course/tests/test_views.py
  3. 8
      web/src/components/LessonRedactor.vue

@ -8,19 +8,16 @@ from django.utils.html import strip_tags
class TestContentMixin: class TestContentMixin:
content_data = [] content_data = []
autosave = True
def check_auto_saving(self): def check_saving(self):
if not self.autosave: if not self.autosave:
return return
raise NotImplementedError() raise NotImplementedError()
def check_content_auto_saving(self, object): def check_content_saving(self, obj):
if not self.autosave: print('Check content saving',)
return self.assertEqual(obj.content.all().count(), len(self.content_data))
print('Check content autosaving',) for i, item in enumerate(obj.content.all().order_by('position', '-created_at',)):
self.assertEqual(object.content.all().count(), len(self.content_data))
for i, item in enumerate(object.content.all().order_by('position', '-created_at',)):
item_data = self.content_data[i].get('data') item_data = self.content_data[i].get('data')
for key, value in item_data.items(): for key, value in item_data.items():
if key == 'txt': if key == 'txt':
@ -89,9 +86,10 @@ class TestContentMixin:
text_el.click() text_el.click()
text_el.send_keys(text) text_el.send_keys(text)
block_obj['data']['txt'] = text block_obj['data']['txt'] = text
self.check_auto_saving() self.check_saving()
def check_block_image(self, inside_el=None): def check_block_image(self, inside_el=None):
return
print('Check block image') print('Check block image')
time.sleep(1) time.sleep(1)
block_obj = {'type': 'image', 'data': {}} block_obj = {'type': 'image', 'data': {}}
@ -104,9 +102,10 @@ class TestContentMixin:
title_el.send_keys(title) title_el.send_keys(title)
block_obj['data']['title'] = title block_obj['data']['title'] = title
# TODO: check image upload # TODO: check image upload
self.check_auto_saving() self.check_saving()
def check_block_image_text(self, inside_el=None): def check_block_image_text(self, inside_el=None):
return
print('Check block image-text') print('Check block image-text')
time.sleep(1) time.sleep(1)
block_obj = {'type': 'image-text', 'data': {}} block_obj = {'type': 'image-text', 'data': {}}
@ -125,10 +124,21 @@ class TestContentMixin:
text_el.send_keys(text) text_el.send_keys(text)
block_obj['data']['txt'] = text block_obj['data']['txt'] = text
# TODO: check image upload # TODO: check image upload
self.check_auto_saving() self.check_saving()
def check_block_images(self, inside_el=None): def check_block_images(self, inside_el=None):
print('Check block images') print('Check block images')
time.sleep(1)
block_obj = {'type': 'images', 'data': {}}
self.content_data.append(block_obj)
# block_el = self.wait_elem_name('block-images', inside_el)
# title_el = self.wait_elem_name('block-images-title', block_el)
# title = Faker('sentence', nb_words=6).generate({})
# title_el.send_keys(title)
# block_obj['data']['title'] = title
self.check_saving()
def check_block_video(self, inside_el=None): def check_block_video(self, inside_el=None):
return
print('Check block images') print('Check block images')

@ -8,16 +8,16 @@ from factory.faker import Faker
from django.utils import timezone from django.utils import timezone
from django.test import TestCase from django.test import TestCase
from django.shortcuts import reverse from django.shortcuts import reverse
from django.conf import settings
from django.utils.text import slugify from django.utils.text import slugify
from unidecode import unidecode from unidecode import unidecode
from selenium.webdriver.common.by import By
from django.utils.html import strip_tags
from project.tests.factories import create_admin, create_batch_unique, User, UserFactory, Course, CourseFactory from project.tests.factories import create_admin, create_batch_unique, User, UserFactory, Course, CourseFactory, login_admin
from project.tests import SeleniumTestCase from project.tests import SeleniumTestCase
from apps.content.tests.mixins import TestContentMixin from apps.content.tests.mixins import TestContentMixin
from project.utils.selenium_utils import SeleniumExtensions as SE
'''
class CoursesTestCase(TestCase): class CoursesTestCase(TestCase):
@classmethod @classmethod
@ -26,17 +26,14 @@ class CoursesTestCase(TestCase):
create_batch_unique(CourseFactory, status=Course.STATUS_CHOICES[:3], price=[0, 1000], create_batch_unique(CourseFactory, status=Course.STATUS_CHOICES[:3], price=[0, 1000],
age=Course.AGE_CHOICES[:2], deferred_start_at=[None, timezone.now() + timedelta(days=randint(5, 15))]) age=Course.AGE_CHOICES[:2], deferred_start_at=[None, timezone.now() + timedelta(days=randint(5, 15))])
@classmethod
def tearDownClass(cls):
print('teardown CoursesTestCase')
super().tearDownClass()
def test_courses_url_accessible(self): def test_courses_url_accessible(self):
print('test_courses_url_accessible')
print('get ', reverse('courses')) print('get ', reverse('courses'))
resp = self.client.get(reverse('courses')) resp = self.client.get(reverse('courses'))
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
def test_course_url_accessible(self): def test_course_url_accessible(self):
print('test_course_url_accessible')
for course in Course.objects.filter(status=Course.PUBLISHED): for course in Course.objects.filter(status=Course.PUBLISHED):
print('get ', course.url) print('get ', course.url)
resp = self.client.get(course.url) resp = self.client.get(course.url)
@ -44,11 +41,11 @@ class CoursesTestCase(TestCase):
@login_admin @login_admin
def test_course_edit_url_accessible(self): def test_course_edit_url_accessible(self):
print('test_course_edit_url_accessible')
for course in Course.objects.all(): for course in Course.objects.all():
print('get ', reverse('course_edit', args=[course.id])) print('get ', reverse('course_edit', args=[course.id]))
resp = self.client.get(reverse('course_edit', args=[course.id])) resp = self.client.get(reverse('course_edit', args=[course.id]))
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
'''
class CourseEditTestCase(TestContentMixin, SeleniumTestCase): class CourseEditTestCase(TestContentMixin, SeleniumTestCase):
@ -61,26 +58,31 @@ class CourseEditTestCase(TestContentMixin, SeleniumTestCase):
super().setUpClass() super().setUpClass()
create_admin() create_admin()
UserFactory.create_batch(5, role=User.AUTHOR_ROLE) UserFactory.create_batch(5, role=User.AUTHOR_ROLE)
# create_batch_unique(CourseFactory, status=Course.STATUS_CHOICES[:3], price=[0, 1000],
# age=Course.AGE_CHOICES[:2], deferred_start_at=[None, timezone.now() + timedelta(days=randint(5, 15))])
@classmethod def check_saving(self, url=None, response_code=200):
def tearDownClass(cls): print('Check saving')
print('teardown CourseEditTestCase') time.sleep(1)
super().tearDownClass() request = self.wait_for_request(url or f'/api/v1/courses/{self.object_id}/')
self.assertEqual(request[2].get('status'), response_code)
def check_auto_saving(self):
time.sleep(0.5)
request = self.wait_for_request(f'/api/v1/courses/{self.object_id}/')
obj = self.model.objects.get(id=self.object_id)
self.assertEqual(request[2].get('status'), 200)
self.assertNotEqual(request[2].get('response'), None) self.assertNotEqual(request[2].get('response'), None)
obj = self.model.objects.get(id=self.object_id)
for key, value in self.object_data.items(): for key, value in self.object_data.items():
if key != 'content': if key not in ['content', 'lessons']:
self.assertEqual(getattr(obj, key), value) self.assertEqual(getattr(obj, key), value)
self.check_content_auto_saving(obj) self.check_content_saving(obj)
self.check_lessons_saving(obj)
def check_lessons_saving(self, obj):
print('Check lessons saving', )
lessons = self.object_data.get('lessons', [])
self.assertEqual(obj.lessons.all().count(), len(lessons))
for i, lesson in enumerate(obj.lessons.all().order_by('title',)):
self.assertEqual(strip_tags(lesson.short_description), lessons[i]['short_description'])
self.assertEqual(lesson.title, lessons[i]['title'])
print('OK')
def test_course_edit(self): def test_course_edit(self):
print('test_course_edit')
user = User.objects.filter(role=User.AUTHOR_ROLE).first() user = User.objects.filter(role=User.AUTHOR_ROLE).first()
self.login(user) self.login(user)
url = self.get_url(reverse('course_create')) url = self.get_url(reverse('course_create'))
@ -122,7 +124,6 @@ class CourseEditTestCase(TestContentMixin, SeleniumTestCase):
self.assertEqual(bool(obj), True) self.assertEqual(bool(obj), True)
self.object_id = obj.id self.object_id = obj.id
print("is_paid_input_el.get_attribute('checked')", is_paid_input_el.get_attribute('checked'))
self.assertEqual(is_paid_input_el.get_attribute('value'), 'false') self.assertEqual(is_paid_input_el.get_attribute('value'), 'false')
self.assertRaises(TimeoutException, callable=lambda: self.driver.find_element_by_name('course-price')) self.assertRaises(TimeoutException, callable=lambda: self.driver.find_element_by_name('course-price'))
self.assertRaises(TimeoutException, callable=lambda: self.driver.find_element_by_name('course-old-price')) self.assertRaises(TimeoutException, callable=lambda: self.driver.find_element_by_name('course-old-price'))
@ -148,10 +149,48 @@ class CourseEditTestCase(TestContentMixin, SeleniumTestCase):
except: except:
self.fail('Date and time elements not shown') self.fail('Date and time elements not shown')
price_el.send_keys(1000)
self.object_data['price'] = 1000
old_price_el.send_keys(1500)
self.object_data['old_price'] = 1500
access_duration_el.send_keys(15)
self.object_data['access_duration'] = 15
self.check_saving()
self.check_content(content_el) self.check_content(content_el)
lessons_btn_el.click()
time.sleep(0.5)
# lessons_el = self.wait_elem_name('course-lessons') # lessons_el = self.wait_elem_name('course-lessons')
# add_lesson_el = self.wait_elem_name('course-add-lesson')
# lesson_edit_el = self.wait_elem_name('course-lesson-edit') # lesson_edit_el = self.wait_elem_name('course-lesson-edit')
# stream_el = self.wait_elem_name('course-stream') # stream_el = self.wait_elem_name('course-stream')
add_lesson_el = self.wait_elem_name('course-add-lesson')
add_lesson_el.click()
time.sleep(0.5)
lesson_title_el = self.wait_elem_name('course-lesson-title')
lesson_text_el = self.wait_elem_name('course-lesson-text-wrap').find_element(
By.XPATH, './/div[contains(@class, "redactor-layer")][@contenteditable]')
lesson_save_btn_el = self.wait_elem_name('course-lesson-save')
lesson = {}
title = Faker('sentence', nb_words=6).generate({})
lesson_title_el.send_keys(title)
lesson['title'] = title
text = Faker('sentence', nb_words=50).generate({})
lesson_text_el.click()
lesson_text_el.send_keys(text)
time.sleep(0.5)
lesson_save_btn_el.click()
self.object_data['lessons'] = [{
'title': title,
'short_description': text
}]
self.check_saving('/api/v1/lessons/', 201)

@ -21,12 +21,12 @@
<div class="kit__field field" <div class="kit__field field"
v-bind:class="{ error: $v.currentLesson.title.$invalid }"> v-bind:class="{ error: $v.currentLesson.title.$invalid }">
<div class="field__wrap"> <div class="field__wrap">
<input type="text" class="field__input" placeholder="Название урока" v-model="lesson.title"> <input type="text" name="course-lesson-title" class="field__input" placeholder="Название урока" v-model="lesson.title">
</div> </div>
</div> </div>
<div class="kit__field field" <div class="kit__field field"
v-bind:class="{ error: $v.currentLesson.short_description.$invalid }"> v-bind:class="{ error: $v.currentLesson.short_description.$invalid }">
<div class="field__wrap"> <div class="field__wrap" name="course-lesson-text-wrap">
<vue-redactor :value="lesson.short_description" <vue-redactor :value="lesson.short_description"
v-on:update:value="(value) => { this.lesson.short_description = value; }" placeholder="Описание урока"/> v-on:update:value="(value) => { this.lesson.short_description = value; }" placeholder="Описание урока"/>
</div> </div>
@ -34,10 +34,10 @@
</div> </div>
</div> </div>
</div> </div>
<block-content :content.sync="lesson.content"></block-content> <block-content name="course-lesson-content" :content.sync="lesson.content"></block-content>
<div class="kit__foot"> <div class="kit__foot">
<button class="kit__submit btn btn_md" v-bind:class="{ loading: saving }">Сохранить</button> <button class="kit__submit btn btn_md" v-bind:class="{ loading: saving }" name="course-lesson-save">Сохранить</button>
</div> </div>
</div> </div>
</div> </div>

Loading…
Cancel
Save