You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
8.0 KiB
196 lines
8.0 KiB
from datetime import timedelta
|
|
from random import randint
|
|
import time
|
|
import re
|
|
|
|
from selenium.common.exceptions import TimeoutException
|
|
from factory.faker import Faker
|
|
from django.utils import timezone
|
|
from django.test import TestCase
|
|
from django.shortcuts import reverse
|
|
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, login_admin
|
|
from project.tests import SeleniumTestCase
|
|
from apps.content.tests.mixins import TestContentMixin
|
|
|
|
|
|
class CoursesTestCase(TestCase):
|
|
|
|
@classmethod
|
|
def setUpTestData(cls):
|
|
create_admin()
|
|
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))])
|
|
|
|
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)
|
|
self.assertEqual(resp.status_code, 200)
|
|
|
|
@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):
|
|
model = Course
|
|
object_id = None
|
|
object_data = {}
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
create_admin()
|
|
UserFactory.create_batch(5, role=User.AUTHOR_ROLE)
|
|
|
|
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 not in ['content', 'lessons']:
|
|
self.assertEqual(getattr(obj, key), value)
|
|
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'))
|
|
print('url is', url)
|
|
self.driver.get(url)
|
|
print('page opened', self.driver.current_url)
|
|
self.add_requests_log()
|
|
|
|
course_redactor = self.wait_elem_name('course-redactor')
|
|
# visible always elements
|
|
title_el = self.wait_elem_name('course-title')
|
|
slug_el = self.wait_elem_name('course-slug')
|
|
category_el = self.wait_elem_name('course-category')
|
|
is_paid_no_el = self.wait_elem_name('course-is-paid-no')
|
|
is_paid_yes_el = self.wait_elem_name('course-is-paid-yes')
|
|
is_paid_input_el = self.wait_elem_css('[name=course-is-paid-input]:checked')
|
|
age_el = self.wait_elem_name('course-age')
|
|
# Only for ADMIN
|
|
# is_featured_el = self.wait_elem_name('course-is-featured')
|
|
is_deferred_no_el = self.wait_elem_name('course-is-deferred-no')
|
|
is_deferred_yes_el = self.wait_elem_name('course-is-deferred-yes')
|
|
is_deferred_input_el = self.wait_elem_name('course-is-deferred-input')
|
|
content_btn_el = self.wait_elem_name('course-content-btn')
|
|
lessons_btn_el = self.wait_elem_name('course-lessons-btn')
|
|
content_el = self.wait_elem_name('course-content')
|
|
|
|
title = Faker('sentence', nb_words=6).generate({})
|
|
title_el.send_keys(title)
|
|
slug = slugify(unidecode(title[:90]))
|
|
slug = re.sub(r'[^-\w]+$', '', slug)
|
|
slug = re.sub(r'[^-\w]', '-', slug)
|
|
self.object_data['title'] = title
|
|
self.object_data['slug'] = slug
|
|
time.sleep(1)
|
|
self.assertEqual(slug_el.get_attribute('value'), slug)
|
|
|
|
# check save
|
|
obj = self.model.objects.get(title=title, slug=slug)
|
|
self.assertEqual(bool(obj), True)
|
|
self.object_id = obj.id
|
|
|
|
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'))
|
|
self.assertRaises(TimeoutException, callable=lambda: self.driver.find_element_by_name('course-access-duration'))
|
|
is_paid_yes_el.click()
|
|
time.sleep(1)
|
|
is_paid_input_el = self.wait_elem_css('[name=course-is-paid-input]:checked')
|
|
self.assertEqual(is_paid_input_el.get_attribute('value'), 'true')
|
|
try:
|
|
price_el = self.wait_elem_name('course-price')
|
|
old_price_el = self.wait_elem_name('course-old-price')
|
|
access_duration_el = self.wait_elem_name('course-access-duration')
|
|
except:
|
|
self.fail('Price, old price and access_duration elements not shown')
|
|
|
|
self.assertEqual(is_deferred_input_el.get_attribute('checked'), 'true')
|
|
self.assertRaises(TimeoutException, callable=lambda: self.driver.find_element_by_name('course-date'))
|
|
self.assertRaises(TimeoutException, callable=lambda: self.driver.find_element_by_name('course-time'))
|
|
is_deferred_yes_el.click()
|
|
try:
|
|
date_el = self.wait_elem_name('course-date')
|
|
time_el = self.wait_elem_name('course-time')
|
|
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')
|
|
# 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)
|
|
|
|
|
|
|
|
|
|
|