mirror of
https://github.com/valitydev/redash.git
synced 2024-11-07 01:25:16 +00:00
More tests (Dasboard API).
This commit is contained in:
parent
6ee3bc099d
commit
1e4f70747b
2
Makefile
2
Makefile
@ -1,5 +1,5 @@
|
||||
NAME=redash
|
||||
VERSION=0.2
|
||||
VERSION=0.3
|
||||
FULL_VERSION=$(VERSION).$(CIRCLE_BUILD_NUM)
|
||||
FILENAME=$(CIRCLE_ARTIFACTS)/$(NAME).$(FULL_VERSION).tar.gz
|
||||
|
||||
|
@ -94,7 +94,7 @@ class DashboardListAPI(BaseResource):
|
||||
return dashboards
|
||||
|
||||
def post(self):
|
||||
dashboard_properties = json.loads(self.request.body)
|
||||
dashboard_properties = request.get_json(force=True)
|
||||
dashboard = models.Dashboard(name=dashboard_properties['name'],
|
||||
user=self.current_user,
|
||||
layout='[]')
|
||||
@ -104,13 +104,18 @@ class DashboardListAPI(BaseResource):
|
||||
|
||||
class DashboardAPI(BaseResource):
|
||||
def get(self, dashboard_slug=None):
|
||||
# TODO: prefetching?
|
||||
dashboard = models.Dashboard.get_by_slug(dashboard_slug)
|
||||
# TODO: prefetching of widgets and queries?
|
||||
try:
|
||||
dashboard = models.Dashboard.get_by_slug(dashboard_slug)
|
||||
except models.Dashboard.DoesNotExist:
|
||||
abort(404)
|
||||
|
||||
return dashboard.to_dict(with_widgets=True)
|
||||
|
||||
def post(self, dashboard_id):
|
||||
dashboard_properties = request.json
|
||||
dashboard = models.Dashboard.get(models.Dashboard.id == dashboard_id)
|
||||
def post(self, dashboard_slug):
|
||||
# TODO: either convert all requests to use slugs or ids
|
||||
dashboard_properties = request.get_json(force=True)
|
||||
dashboard = models.Dashboard.get(models.Dashboard.id == dashboard_slug)
|
||||
dashboard.layout = dashboard_properties['layout']
|
||||
dashboard.name = dashboard_properties['name']
|
||||
dashboard.save()
|
||||
@ -128,7 +133,7 @@ api.add_resource(DashboardAPI, '/api/dashboards/<dashboard_slug>', endpoint='das
|
||||
|
||||
class WidgetListAPI(BaseResource):
|
||||
def post(self):
|
||||
widget_properties = request.json
|
||||
widget_properties = request.get_json(force=True)
|
||||
widget_properties['options'] = json.dumps(widget_properties['options'])
|
||||
widget = models.Widget(**widget_properties)
|
||||
widget.save()
|
||||
|
@ -202,4 +202,4 @@ def create_db(create_tables, drop_tables):
|
||||
if create_tables:
|
||||
model.create_table()
|
||||
|
||||
db.close_db(None)
|
||||
db.close_db(None)
|
@ -1 +1,56 @@
|
||||
from tests import controllers
|
||||
from unittest import TestCase
|
||||
from redash import settings, db, app
|
||||
import redash.models
|
||||
|
||||
# TODO: this isn't pretty... :-)
|
||||
settings.DATABASE_CONFIG = {
|
||||
'name': 'rd_test',
|
||||
'engine': 'peewee.PostgresqlDatabase',
|
||||
'threadlocals': True
|
||||
}
|
||||
app.config['DATABASE'] = settings.DATABASE_CONFIG
|
||||
db.load_database()
|
||||
|
||||
|
||||
def model_factory(model, **kwargs):
|
||||
def factory(**properties):
|
||||
kwargs.update(properties)
|
||||
|
||||
return model(**kwargs)
|
||||
|
||||
return factory
|
||||
|
||||
|
||||
class ModelFactory(object):
|
||||
def __init__(self, model, **kwargs):
|
||||
self.model = model
|
||||
self.kwargs = kwargs
|
||||
|
||||
def _get_kwargs(self, override_kwargs):
|
||||
kwargs = self.kwargs.copy()
|
||||
kwargs.update(override_kwargs)
|
||||
return kwargs
|
||||
|
||||
def instance(self, **override_kwargs):
|
||||
kwargs = self._get_kwargs(override_kwargs)
|
||||
|
||||
return self.model(**kwargs)
|
||||
|
||||
def create(self, **override_kwargs):
|
||||
kwargs = self._get_kwargs(override_kwargs)
|
||||
|
||||
return self.model.create(**kwargs)
|
||||
|
||||
DashboardFactory = ModelFactory(redash.models.Dashboard,
|
||||
name='test', user='test@everything.me', layout='[]')
|
||||
|
||||
dashboard_factory = model_factory(redash.models.Dashboard, name='test', user='test@everything.me', layout='[]')
|
||||
|
||||
|
||||
class BaseTestCase(TestCase):
|
||||
def setUp(self):
|
||||
redash.models.create_db(True, True)
|
||||
|
||||
def tearDown(self):
|
||||
db.close_db(None)
|
||||
redash.models.create_db(False, True)
|
@ -1,16 +1,31 @@
|
||||
from contextlib import contextmanager
|
||||
import unittest
|
||||
from redash import app
|
||||
import json
|
||||
from tests import BaseTestCase, DashboardFactory
|
||||
from redash import app, models
|
||||
|
||||
|
||||
@contextmanager
|
||||
def authenticated_user(c):
|
||||
def authenticated_user(c, user='test@example.com', name='John Test'):
|
||||
with c.session_transaction() as sess:
|
||||
sess['openid'] = {'email': 'test@example.com', 'name': 'John Test'}
|
||||
sess['openid'] = {'email': user, 'name': name}
|
||||
|
||||
yield
|
||||
|
||||
|
||||
def json_request(method, path, data=None):
|
||||
if data:
|
||||
response = method(path, data=json.dumps(data))
|
||||
else:
|
||||
response = method(path)
|
||||
|
||||
if response.data:
|
||||
response.json = json.loads(response.data)
|
||||
else:
|
||||
response.json = None
|
||||
|
||||
return response
|
||||
|
||||
|
||||
class AuthenticationTestMixin():
|
||||
def test_redirects_when_not_authenticated(self):
|
||||
with app.test_client() as c:
|
||||
@ -19,14 +34,13 @@ class AuthenticationTestMixin():
|
||||
self.assertEquals(302, rv.status_code)
|
||||
|
||||
def test_returns_content_when_authenticated(self):
|
||||
with app.test_client() as c:
|
||||
with authenticated_user(c):
|
||||
for path in self.paths:
|
||||
rv = c.get(path)
|
||||
self.assertEquals(200, rv.status_code)
|
||||
with app.test_client() as c, authenticated_user(c):
|
||||
for path in self.paths:
|
||||
rv = c.get(path)
|
||||
self.assertEquals(200, rv.status_code)
|
||||
|
||||
|
||||
class PingTest(unittest.TestCase):
|
||||
class PingTest(BaseTestCase):
|
||||
def test_ping(self):
|
||||
with app.test_client() as c:
|
||||
rv = c.get('/ping')
|
||||
@ -34,36 +48,83 @@ class PingTest(unittest.TestCase):
|
||||
self.assertEquals('PONG.', rv.data)
|
||||
|
||||
|
||||
class IndexTest(unittest.TestCase, AuthenticationTestMixin):
|
||||
class IndexTest(BaseTestCase, AuthenticationTestMixin):
|
||||
def setUp(self):
|
||||
self.paths = ['/', '/dashboard/example', '/queries/1', '/admin/status']
|
||||
super(IndexTest, self).setUp()
|
||||
|
||||
|
||||
class StatusTest(unittest.TestCase, AuthenticationTestMixin):
|
||||
class StatusTest(BaseTestCase, AuthenticationTestMixin):
|
||||
def setUp(self):
|
||||
self.paths = ['/status.json']
|
||||
super(StatusTest, self).setUp()
|
||||
|
||||
|
||||
class DashboardAPITest(unittest.TestCase, AuthenticationTestMixin):
|
||||
class DashboardAPITest(BaseTestCase, AuthenticationTestMixin):
|
||||
def setUp(self):
|
||||
self.paths = ['/api/dashboards']
|
||||
super(DashboardAPITest, self).setUp()
|
||||
|
||||
def test_get_dashboard(self):
|
||||
d1 = DashboardFactory.create()
|
||||
with app.test_client() as c, authenticated_user(c):
|
||||
rv = c.get('/api/dashboards/{0}'.format(d1.slug))
|
||||
self.assertEquals(rv.status_code, 200)
|
||||
self.assertDictEqual(json.loads(rv.data), d1.to_dict(with_widgets=True))
|
||||
|
||||
def test_get_non_existint_dashbaord(self):
|
||||
with app.test_client() as c, authenticated_user(c):
|
||||
rv = c.get('/api/dashboards/not_existing')
|
||||
self.assertEquals(rv.status_code, 404)
|
||||
|
||||
def test_create_new_dashboard(self):
|
||||
user_email = 'test@everything.me'
|
||||
with app.test_client() as c, authenticated_user(c, user=user_email):
|
||||
dashboard_name = 'Test Dashboard'
|
||||
rv = json_request(c.post, '/api/dashboards', data={'name': dashboard_name})
|
||||
self.assertEquals(rv.status_code, 200)
|
||||
self.assertEquals(rv.json['name'], 'Test Dashboard')
|
||||
self.assertEquals(rv.json['user'], user_email)
|
||||
self.assertEquals(rv.json['layout'], [])
|
||||
|
||||
def test_update_dashboard(self):
|
||||
d = DashboardFactory.create()
|
||||
new_name = 'New Name'
|
||||
with app.test_client() as c, authenticated_user(c):
|
||||
rv = json_request(c.post, '/api/dashboards/{0}'.format(d.id),
|
||||
data={'name': new_name, 'layout': '[]'})
|
||||
self.assertEquals(rv.status_code, 200)
|
||||
self.assertEquals(rv.json['name'], new_name)
|
||||
|
||||
def test_delete_dashbaord(self):
|
||||
d = DashboardFactory.create()
|
||||
with app.test_client() as c, authenticated_user(c):
|
||||
rv = json_request(c.delete, '/api/dashboards/{0}'.format(d.slug))
|
||||
self.assertEquals(rv.status_code, 200)
|
||||
|
||||
d = models.Dashboard.get_by_slug(d.slug)
|
||||
self.assertTrue(d.is_archived)
|
||||
|
||||
|
||||
class QueryAPITest(unittest.TestCase, AuthenticationTestMixin):
|
||||
class QueryAPITest(BaseTestCase, AuthenticationTestMixin):
|
||||
def setUp(self):
|
||||
self.paths = ['/api/queries']
|
||||
super(QueryAPITest, self).setUp()
|
||||
|
||||
|
||||
class QueryResultAPITest(unittest.TestCase, AuthenticationTestMixin):
|
||||
class QueryResultAPITest(BaseTestCase, AuthenticationTestMixin):
|
||||
def setUp(self):
|
||||
self.paths = []
|
||||
super(QueryResultAPITest, self).setUp()
|
||||
|
||||
|
||||
class JobAPITest(unittest.TestCase, AuthenticationTestMixin):
|
||||
class JobAPITest(BaseTestCase, AuthenticationTestMixin):
|
||||
def setUp(self):
|
||||
self.paths = []
|
||||
super(JobAPITest, self).setUp()
|
||||
|
||||
|
||||
class CsvQueryResultAPITest(unittest.TestCase, AuthenticationTestMixin):
|
||||
class CsvQueryResultAPITest(BaseTestCase, AuthenticationTestMixin):
|
||||
def setUp(self):
|
||||
self.paths = []
|
||||
self.paths = []
|
||||
super(CsvQueryResultAPITest, self).setUp()
|
@ -1,31 +1,14 @@
|
||||
from unittest import TestCase
|
||||
from redash import settings, db, app, models
|
||||
|
||||
settings.DATABASE_CONFIG = {
|
||||
'name': 'rd_test',
|
||||
'engine': 'peewee.PostgresqlDatabase',
|
||||
'threadlocals': True
|
||||
}
|
||||
app.config['DATABASE'] = settings.DATABASE_CONFIG
|
||||
db.load_database()
|
||||
from tests import BaseTestCase, DashboardFactory
|
||||
|
||||
|
||||
class DatabaseTestCase(TestCase):
|
||||
def setUp(self):
|
||||
models.create_db(True, True)
|
||||
|
||||
def tearDown(self):
|
||||
models.create_db(False, True)
|
||||
|
||||
|
||||
class DashboardTest(DatabaseTestCase):
|
||||
class DashboardTest(BaseTestCase):
|
||||
def test_appends_suffix_to_slug_when_duplicate(self):
|
||||
d1 = models.Dashboard.create(name='test', user='arik', layout='')
|
||||
d1 = DashboardFactory.create()
|
||||
self.assertEquals(d1.slug, 'test')
|
||||
|
||||
d2 = models.Dashboard.create(name='test', user='arik', layout='')
|
||||
d2 = DashboardFactory.create()
|
||||
self.assertNotEquals(d1.slug, d2.slug)
|
||||
|
||||
d3 = models.Dashboard.create(name='test', user='arik', layout='')
|
||||
d3 = DashboardFactory.create()
|
||||
self.assertNotEquals(d1.slug, d3.slug)
|
||||
self.assertNotEquals(d2.slug, d3.slug)
|
Loading…
Reference in New Issue
Block a user