2014-10-03 14:02:11 +00:00
|
|
|
import datetime
|
2014-10-04 13:23:04 +00:00
|
|
|
import os
|
2014-10-03 14:02:11 +00:00
|
|
|
from functools import wraps
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
from django.conf import settings
|
2015-04-04 18:10:39 +00:00
|
|
|
from django.contrib.auth import BACKEND_SESSION_KEY, SESSION_KEY
|
2014-05-08 16:59:35 +00:00
|
|
|
from django.contrib.sessions.backends.db import SessionStore
|
2014-10-07 13:08:59 +00:00
|
|
|
from django.core.urlresolvers import reverse
|
2014-05-08 16:59:35 +00:00
|
|
|
from django.test import LiveServerTestCase, TestCase
|
|
|
|
from selenium.webdriver.firefox.webdriver import WebDriver
|
|
|
|
from xvfbwrapper import Xvfb
|
|
|
|
|
2015-04-05 10:46:24 +00:00
|
|
|
from orchestra.contrib.accounts.models import Account
|
2014-05-08 16:59:35 +00:00
|
|
|
|
2015-03-04 21:06:16 +00:00
|
|
|
from .python import random_ascii
|
2014-05-08 16:59:35 +00:00
|
|
|
|
2014-10-01 21:03:16 +00:00
|
|
|
|
2014-05-08 16:59:35 +00:00
|
|
|
class AppDependencyMixin(object):
|
|
|
|
DEPENDENCIES = ()
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def setUpClass(cls):
|
|
|
|
current_app = cls.__module__.split('.tests.')[0]
|
|
|
|
INSTALLED_APPS = (
|
|
|
|
'orchestra',
|
2015-04-05 10:46:24 +00:00
|
|
|
'orchestra.contrib.accounts',
|
2014-05-08 16:59:35 +00:00
|
|
|
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):
|
2014-10-02 15:58:27 +00:00
|
|
|
def create_account(self, username='', superuser=False):
|
|
|
|
if not username:
|
|
|
|
username = '%s_superaccount' % random_ascii(5)
|
2014-10-01 21:03:16 +00:00
|
|
|
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')
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
class BaseLiveServerTestCase(AppDependencyMixin, LiveServerTestCase):
|
|
|
|
@classmethod
|
|
|
|
def setUpClass(cls):
|
2014-10-23 15:38:46 +00:00
|
|
|
# Avoid problems with the overlaping menu when clicking
|
|
|
|
settings.ADMIN_TOOLS_MENU = 'admin_tools.menu.Menu'
|
2014-05-08 16:59:35 +00:00
|
|
|
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()
|
|
|
|
|
2014-10-02 15:58:27 +00:00
|
|
|
def create_account(self, username='', superuser=False):
|
|
|
|
if not username:
|
|
|
|
username = '%s_superaccount' % random_ascii(5)
|
2014-10-01 21:03:16 +00:00
|
|
|
password = 'orchestra'
|
2014-10-02 15:58:27 +00:00
|
|
|
self.account_password = password
|
2014-10-01 16:42:40 +00:00
|
|
|
if superuser:
|
2014-10-01 21:03:16 +00:00
|
|
|
return Account.objects.create_superuser(username, password=password, email='orchestra@orchestra.org')
|
|
|
|
return Account.objects.create_user(username, password=password, email='orchestra@orchestra.org')
|
2014-10-01 16:42:40 +00:00
|
|
|
|
2014-05-08 16:59:35 +00:00
|
|
|
def setUp(self):
|
2015-05-13 13:52:20 +00:00
|
|
|
from orm.api import Api
|
2014-05-08 16:59:35 +00:00
|
|
|
super(BaseLiveServerTestCase, self).setUp()
|
|
|
|
self.rest = Api(self.live_server_url + '/api/')
|
2014-10-04 09:29:18 +00:00
|
|
|
self.rest.enable_logging()
|
2014-10-01 16:42:40 +00:00
|
|
|
self.account = self.create_account(superuser=True)
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
def admin_login(self):
|
2021-02-10 19:27:53 +00:00
|
|
|
# Original option
|
2014-05-08 16:59:35 +00:00
|
|
|
session = SessionStore()
|
2021-02-03 09:47:35 +00:00
|
|
|
session[SESSION_KEY] = self.account.id
|
2014-05-08 16:59:35 +00:00
|
|
|
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='/',
|
|
|
|
))
|
2021-02-10 19:27:53 +00:00
|
|
|
|
|
|
|
# Selenium option
|
|
|
|
# self.selenium.get(self.live_server_url + '/admin/')
|
|
|
|
# self.selenium.find_element_by_id("id_username").send_keys(self.account.username)
|
|
|
|
# self.selenium.find_element_by_id("id_password").send_keys(self.account_password)
|
|
|
|
# self.selenium.find_element_by_css_selector("input[type='submit']").click()
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
def rest_login(self):
|
2014-10-02 15:58:27 +00:00
|
|
|
self.rest.login(username=self.account.username, password=self.account_password)
|
2014-10-06 14:57:02 +00:00
|
|
|
|
|
|
|
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))
|
2014-10-07 13:08:59 +00:00
|
|
|
|
|
|
|
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)
|
2014-10-03 14:02:11 +00:00
|
|
|
|
|
|
|
def snapshot_on_error(test):
|
2014-10-06 14:57:02 +00:00
|
|
|
@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):
|
2014-10-03 14:02:11 +00:00
|
|
|
@wraps(test)
|
|
|
|
def inner(*args, **kwargs):
|
|
|
|
try:
|
|
|
|
test(*args, **kwargs)
|
|
|
|
except:
|
|
|
|
self = args[0]
|
|
|
|
timestamp = datetime.datetime.now().isoformat().replace(':', '')
|
2014-10-06 14:57:02 +00:00
|
|
|
filename = '%s_%s.html' % (self.id(), timestamp)
|
2014-10-04 13:23:04 +00:00
|
|
|
path = '/home/orchestra/snapshots'
|
2014-10-06 14:57:02 +00:00
|
|
|
with open(os.path.join(path, filename), 'w') as dumpfile:
|
|
|
|
dumpfile.write(self.rest.last_response.content)
|
2014-10-03 14:02:11 +00:00
|
|
|
raise
|
|
|
|
return inner
|