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

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:
content_data = []
autosave = True
def check_auto_saving(self):
def check_saving(self):
if not self.autosave:
return
raise NotImplementedError()
def check_content_auto_saving(self, object):
if not self.autosave:
return
print('Check content autosaving',)
self.assertEqual(object.content.all().count(), len(self.content_data))
for i, item in enumerate(object.content.all().order_by('position', '-created_at',)):
def check_content_saving(self, obj):
print('Check content saving',)
self.assertEqual(obj.content.all().count(), len(self.content_data))
for i, item in enumerate(obj.content.all().order_by('position', '-created_at',)):
item_data = self.content_data[i].get('data')
for key, value in item_data.items():
if key == 'txt':
@ -89,9 +86,10 @@ class TestContentMixin:
text_el.click()
text_el.send_keys(text)
block_obj['data']['txt'] = text
self.check_auto_saving()
self.check_saving()
def check_block_image(self, inside_el=None):
return
print('Check block image')
time.sleep(1)
block_obj = {'type': 'image', 'data': {}}
@ -104,9 +102,10 @@ class TestContentMixin:
title_el.send_keys(title)
block_obj['data']['title'] = title
# TODO: check image upload
self.check_auto_saving()
self.check_saving()
def check_block_image_text(self, inside_el=None):
return
print('Check block image-text')
time.sleep(1)
block_obj = {'type': 'image-text', 'data': {}}
@ -125,10 +124,21 @@ class TestContentMixin:
text_el.send_keys(text)
block_obj['data']['txt'] = text
# TODO: check image upload
self.check_auto_saving()
self.check_saving()
def check_block_images(self, inside_el=None):
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):
return
print('Check block images')

@ -8,16 +8,16 @@ from factory.faker import Faker
from django.utils import timezone
from django.test import TestCase
from django.shortcuts import reverse
from django.conf import settings
from django.utils.text import slugify
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 apps.content.tests.mixins import TestContentMixin
from project.utils.selenium_utils import SeleniumExtensions as SE
'''
class CoursesTestCase(TestCase):
@classmethod
@ -26,17 +26,14 @@ class CoursesTestCase(TestCase):
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 tearDownClass(cls):
print('teardown CoursesTestCase')
super().tearDownClass()
def test_courses_url_accessible(self):
print('test_courses_url_accessible')
print('get ', reverse('courses'))
resp = self.client.get(reverse('courses'))
self.assertEqual(resp.status_code, 200)
def test_course_url_accessible(self):
print('test_course_url_accessible')
for course in Course.objects.filter(status=Course.PUBLISHED):
print('get ', course.url)
resp = self.client.get(course.url)
@ -44,11 +41,11 @@ class CoursesTestCase(TestCase):
@login_admin
def test_course_edit_url_accessible(self):
print('test_course_edit_url_accessible')
for course in Course.objects.all():
print('get ', reverse('course_edit', args=[course.id]))
resp = self.client.get(reverse('course_edit', args=[course.id]))
self.assertEqual(resp.status_code, 200)
'''
class CourseEditTestCase(TestContentMixin, SeleniumTestCase):
@ -61,26 +58,31 @@ class CourseEditTestCase(TestContentMixin, SeleniumTestCase):
super().setUpClass()
create_admin()
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 tearDownClass(cls):
print('teardown CourseEditTestCase')
super().tearDownClass()
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)
def check_saving(self, url=None, response_code=200):
print('Check saving')
time.sleep(1)
request = self.wait_for_request(url or f'/api/v1/courses/{self.object_id}/')
self.assertEqual(request[2].get('status'), response_code)
self.assertNotEqual(request[2].get('response'), None)
obj = self.model.objects.get(id=self.object_id)
for key, value in self.object_data.items():
if key != 'content':
if key not in ['content', 'lessons']:
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):
print('test_course_edit')
user = User.objects.filter(role=User.AUTHOR_ROLE).first()
self.login(user)
url = self.get_url(reverse('course_create'))
@ -122,7 +124,6 @@ class CourseEditTestCase(TestContentMixin, SeleniumTestCase):
self.assertEqual(bool(obj), True)
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.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'))
@ -148,10 +149,48 @@ class CourseEditTestCase(TestContentMixin, SeleniumTestCase):
except:
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)
lessons_btn_el.click()
time.sleep(0.5)
# 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')
# 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"
v-bind:class="{ error: $v.currentLesson.title.$invalid }">
<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 class="kit__field field"
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"
v-on:update:value="(value) => { this.lesson.short_description = value; }" placeholder="Описание урока"/>
</div>
@ -34,10 +34,10 @@
</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">
<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>

Loading…
Cancel
Save