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

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)