django-orchestra-test/orchestra/utils/tests.py

181 lines
6.4 KiB
Python

import datetime
import os
from functools import wraps
from django.conf import settings
from django.contrib.auth import BACKEND_SESSION_KEY, SESSION_KEY
from django.contrib.sessions.backends.db import SessionStore
from django.urls import reverse
from django.test import LiveServerTestCase, TestCase
from selenium.webdriver.firefox.webdriver import WebDriver
from xvfbwrapper import Xvfb
from orchestra.contrib.accounts.models import Account
from .python import random_ascii
class AppDependencyMixin(object):
DEPENDENCIES = ()
@classmethod
def setUpClass(cls):
current_app = cls.__module__.split('.tests.')[0]
INSTALLED_APPS = (
'orchestra',
'orchestra.contrib.accounts',
current_app
)
INSTALLED_APPS += cls.DEPENDENCIES
INSTALLED_APPS += (
# Third-party apps
'south',
'django_extensions',
'djcelery',
'djcelery_email',
'fluent_dashboard',
'admin_tools',
'admin_tools.theming',
'admin_tools.menu',
'admin_tools.dashboard',
'rest_framework',
# Django.contrib
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
)
settings.INSTALLED_APPS = INSTALLED_APPS
super(AppDependencyMixin, cls).setUpClass()
class BaseTestCase(TestCase, AppDependencyMixin):
def create_account(self, username='', superuser=False):
if not username:
username = '%s_superaccount' % random_ascii(5)
password = 'orchestra'
if superuser:
return Account.objects.create_superuser(username, password=password, email='orchestra@orchestra.org')
return Account.objects.create_user(username, password=password, email='orchestra@orchestra.org')
class BaseLiveServerTestCase(AppDependencyMixin, LiveServerTestCase):
@classmethod
def setUpClass(cls):
# Avoid problems with the overlaping menu when clicking
settings.ADMIN_TOOLS_MENU = 'admin_tools.menu.Menu'
cls.vdisplay = Xvfb()
cls.vdisplay.start()
cls.selenium = WebDriver()
super(BaseLiveServerTestCase, cls).setUpClass()
@classmethod
def tearDownClass(cls):
cls.selenium.quit()
cls.vdisplay.stop()
super(BaseLiveServerTestCase, cls).tearDownClass()
def create_account(self, username='', superuser=False):
if not username:
username = '%s_superaccount' % random_ascii(5)
password = 'orchestra'
self.account_password = password
if superuser:
return Account.objects.create_superuser(username, password=password, email='orchestra@orchestra.org')
return Account.objects.create_user(username, password=password, email='orchestra@orchestra.org')
def setUp(self):
from orm.api import Api
super(BaseLiveServerTestCase, self).setUp()
self.rest = Api(self.live_server_url + '/api/')
self.rest.enable_logging()
self.account = self.create_account(superuser=True)
def admin_login(self):
session = SessionStore()
session[SESSION_KEY] = self.account.id
session[BACKEND_SESSION_KEY] = settings.AUTHENTICATION_BACKENDS[0]
session.save()
## to set a cookie we need to first visit the domain.
self.selenium.get(self.live_server_url + '/admin/')
self.selenium.add_cookie(dict(
name=settings.SESSION_COOKIE_NAME,
value=session.session_key, #
path='/',
))
def rest_login(self):
self.rest.login(username=self.account.username, password=self.account_password)
def take_screenshot(self):
timestamp = datetime.datetime.now().isoformat().replace(':', '')
filename = 'screenshot_%s_%s.png' % (self.id(), timestamp)
path = '/home/orchestra/snapshots'
self.selenium.save_screenshot(os.path.join(path, filename))
def admin_delete(self, obj):
opts = obj._meta
app_label, model_name = opts.app_label, opts.model_name
delete = reverse('admin:%s_%s_delete' % (app_label, model_name), args=(obj.pk,))
url = self.live_server_url + delete
self.selenium.get(url)
confirmation = self.selenium.find_element_by_name('post')
confirmation.submit()
self.assertNotEqual(url, self.selenium.current_url)
def admin_disable(self, obj):
opts = obj._meta
app_label, model_name = opts.app_label, opts.model_name
change = reverse('admin:%s_%s_change' % (app_label, model_name), args=(obj.pk,))
url = self.live_server_url + change
self.selenium.get(url)
is_active = self.selenium.find_element_by_id('id_is_active')
is_active.click()
save = self.selenium.find_element_by_name('_save')
save.submit()
self.assertNotEqual(url, self.selenium.current_url)
def admin_change_password(self, obj, password):
opts = obj._meta
app_label, model_name = opts.app_label, opts.model_name
change_password = reverse('admin:%s_%s_change_password' % (app_label, model_name), args=(obj.pk,))
url = self.live_server_url + change_password
self.selenium.get(url)
password_field = self.selenium.find_element_by_id('id_password1')
password_field.send_keys(password)
password_field = self.selenium.find_element_by_id('id_password2')
password_field.send_keys(password)
password_field.submit()
self.assertNotEqual(url, self.selenium.current_url)
def snapshot_on_error(test):
@wraps(test)
def inner(*args, **kwargs):
try:
test(*args, **kwargs)
except:
self = args[0]
self.take_screenshot()
raise
return inner
def save_response_on_error(test):
@wraps(test)
def inner(*args, **kwargs):
try:
test(*args, **kwargs)
except:
self = args[0]
timestamp = datetime.datetime.now().isoformat().replace(':', '')
filename = '%s_%s.html' % (self.id(), timestamp)
path = '/home/orchestra/snapshots'
with open(os.path.join(path, filename), 'wb') as dumpfile:
dumpfile.write(self.rest.last_response.content)
raise
return inner