mirror of
https://github.com/valitydev/redash.git
synced 2024-11-07 01:25:16 +00:00
test_dashboards passes
This commit is contained in:
parent
bb755b5c25
commit
dff39a6849
@ -3,9 +3,10 @@ from itertools import chain
|
||||
from flask import request, url_for
|
||||
from flask_restful import abort
|
||||
from funcy import distinct, project, take
|
||||
from sqlalchemy.orm.exc import StaleDataError
|
||||
|
||||
from redash import models, serializers
|
||||
from redash.handlers.base import BaseResource, get_object_or_404
|
||||
from redash.models import ConflictDetectedError
|
||||
from redash.permissions import (can_modify, require_admin_or_owner,
|
||||
require_object_modify_permission,
|
||||
require_permission)
|
||||
@ -37,9 +38,10 @@ class DashboardListResource(BaseResource):
|
||||
user=self.current_user,
|
||||
is_draft=True,
|
||||
layout='[]')
|
||||
models.db.session.add(dashboard)
|
||||
models.db.session.commit()
|
||||
return dashboard.to_dict()
|
||||
|
||||
|
||||
class DashboardResource(BaseResource):
|
||||
@require_permission('list_dashboards')
|
||||
def get(self, dashboard_slug=None):
|
||||
@ -63,13 +65,23 @@ class DashboardResource(BaseResource):
|
||||
|
||||
require_object_modify_permission(dashboard, self.current_user)
|
||||
|
||||
|
||||
updates = project(dashboard_properties, ('name', 'layout', 'version',
|
||||
'is_draft'))
|
||||
|
||||
# SQLAlchemy handles the case where a concurrent transaction beats us
|
||||
# to the update. But we still have to make sure that we're not starting
|
||||
# out behind.
|
||||
if 'version' in updates and updates['version'] != dashboard.version:
|
||||
abort(409)
|
||||
|
||||
updates['changed_by'] = self.current_user
|
||||
|
||||
self.update_model(dashboard, updates)
|
||||
models.db.session.add(dashboard)
|
||||
try:
|
||||
dashboard.update_instance(**updates)
|
||||
except ConflictDetectedError:
|
||||
models.db.session.commit()
|
||||
except StaleDataError:
|
||||
abort(409)
|
||||
|
||||
result = dashboard.to_dict(with_widgets=True, user=self.current_user)
|
||||
@ -79,9 +91,11 @@ class DashboardResource(BaseResource):
|
||||
def delete(self, dashboard_slug):
|
||||
dashboard = models.Dashboard.get_by_slug_and_org(dashboard_slug, self.current_org)
|
||||
dashboard.is_archived = True
|
||||
dashboard.save(changed_by=self.current_user)
|
||||
|
||||
return dashboard.to_dict(with_widgets=True, user=self.current_user)
|
||||
dashboard.record_changes(changed_by=self.current_user)
|
||||
models.db.session.add(dashboard)
|
||||
d = dashboard.to_dict(with_widgets=True, user=self.current_user)
|
||||
models.db.session.commit()
|
||||
return d
|
||||
|
||||
|
||||
class PublicDashboardResource(BaseResource):
|
||||
@ -100,6 +114,7 @@ class DashboardShareResource(BaseResource):
|
||||
dashboard = models.Dashboard.get_by_id_and_org(dashboard_id, self.current_org)
|
||||
require_admin_or_owner(dashboard.user_id)
|
||||
api_key = models.ApiKey.create_for_object(dashboard, self.current_user)
|
||||
models.db.session.flush()
|
||||
public_url = url_for('redash.public_dashboard', token=api_key.api_key, org_slug=self.current_org.slug, _external=True)
|
||||
|
||||
self.record_event({
|
||||
@ -117,10 +132,11 @@ class DashboardShareResource(BaseResource):
|
||||
|
||||
if api_key:
|
||||
api_key.active = False
|
||||
api_key.save()
|
||||
models.db.session.add(api_key)
|
||||
|
||||
self.record_event({
|
||||
'action': 'deactivate_api_key',
|
||||
'object_id': dashboard.id,
|
||||
'object_type': 'dashboard',
|
||||
})
|
||||
models.db.session.commit()
|
||||
|
@ -894,7 +894,7 @@ class AccessPermission(GFKBase, db.Model):
|
||||
|
||||
@classmethod
|
||||
def find(cls, obj, access_type=None, grantee=None, grantor=None):
|
||||
return cls._query(cls.select(cls), obj, access_type, grantee, grantor)
|
||||
return cls._query(obj, access_type, grantee, grantor)
|
||||
|
||||
@classmethod
|
||||
def exists(cls, obj, access_type, grantee):
|
||||
@ -902,7 +902,8 @@ class AccessPermission(GFKBase, db.Model):
|
||||
|
||||
@classmethod
|
||||
def _query(cls, obj, access_type=None, grantee=None, grantor=None):
|
||||
q = cls.query.filter(cls.object_id==obj.id, cls.object_type==obj.__tablename__)
|
||||
q = cls.query.filter(cls.object_id == obj.id,
|
||||
cls.object_type == obj.__tablename__)
|
||||
|
||||
if access_type:
|
||||
q.filter(AccessPermission.access_type == access_type)
|
||||
@ -1076,18 +1077,14 @@ class Dashboard(ChangeTrackingMixin, TimestampMixin, BelongsToOrgMixin, db.Model
|
||||
layout = json.loads(self.layout)
|
||||
|
||||
if with_widgets:
|
||||
widget_list = Widget.select(Widget, Visualization, Query, User)\
|
||||
.where(Widget.dashboard == self.id)\
|
||||
.join(Visualization, join_type=peewee.JOIN_LEFT_OUTER)\
|
||||
.join(Query, join_type=peewee.JOIN_LEFT_OUTER)\
|
||||
.join(User, join_type=peewee.JOIN_LEFT_OUTER)
|
||||
widget_list = Widget.query.filter(Widget.dashboard == self)
|
||||
|
||||
widgets = {}
|
||||
|
||||
for w in widget_list:
|
||||
if w.visualization_id is None:
|
||||
widgets[w.id] = w.to_dict()
|
||||
elif user and has_access(w.visualization.query.groups, user, view_only):
|
||||
elif user and has_access(w.visualization.query_rel.groups, user, view_only):
|
||||
widgets[w.id] = w.to_dict()
|
||||
else:
|
||||
widgets[w.id] = project(w.to_dict(),
|
||||
@ -1175,7 +1172,7 @@ class Dashboard(ChangeTrackingMixin, TimestampMixin, BelongsToOrgMixin, db.Model
|
||||
|
||||
@classmethod
|
||||
def get_by_slug_and_org(cls, slug, org):
|
||||
return cls.get(cls.slug == slug, cls.org==org)
|
||||
return cls.query.filter(cls.slug == slug, cls.org==org).one()
|
||||
|
||||
def tracked_save(self, changing_user, old_object=None, *args, **kwargs):
|
||||
self.version += 1
|
||||
@ -1330,11 +1327,13 @@ class ApiKey(TimestampMixin, GFKBase, db.Model):
|
||||
|
||||
@classmethod
|
||||
def get_by_object(cls, object):
|
||||
return cls.select().where(cls.object_type==object._meta.db_table, cls.object_id==object.id, cls.active==True).first()
|
||||
return cls.query.filter(cls.object_type==object.__class__.__tablename__, cls.object_id==object.id, cls.active==True).first()
|
||||
|
||||
@classmethod
|
||||
def create_for_object(cls, object, user):
|
||||
return cls.create(org=user.org, object=object, created_by=user)
|
||||
k = cls(org=user.org, object=object, created_by=user)
|
||||
db.session.add(k)
|
||||
return k
|
||||
|
||||
|
||||
class NotificationDestination(BelongsToOrgMixin, db.Model):
|
||||
|
@ -52,7 +52,7 @@ class TestInvitePost(BaseTestCase):
|
||||
password = 'test1234'
|
||||
response = self.post_request('/invite/{}'.format(token), data={'password': password}, org=self.factory.org)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
user = User.get_by_id(self.factory.user.id)
|
||||
user = User.query.get(self.factory.user.id)
|
||||
self.assertTrue(user.verify_password(password))
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import json
|
||||
from tests import BaseTestCase
|
||||
from redash.models import ApiKey, Dashboard, AccessPermission
|
||||
from redash.models import ApiKey, Dashboard, AccessPermission, db
|
||||
from redash.permissions import ACCESS_TYPE_MODIFY
|
||||
|
||||
|
||||
@ -30,15 +30,14 @@ class TestDashboardResourceGet(BaseTestCase):
|
||||
|
||||
restricted_ds = self.factory.create_data_source(group=self.factory.create_group())
|
||||
query = self.factory.create_query(data_source=restricted_ds)
|
||||
vis = self.factory.create_visualization(query=query)
|
||||
vis = self.factory.create_visualization(query_rel=query)
|
||||
restricted_widget = self.factory.create_widget(visualization=vis, dashboard=dashboard)
|
||||
widget = self.factory.create_widget(dashboard=dashboard)
|
||||
dashboard.layout = '[[{}, {}]]'.format(widget.id, restricted_widget.id)
|
||||
dashboard.save()
|
||||
db.session.commit()
|
||||
|
||||
rv = self.make_request('get', '/api/dashboards/{0}'.format(dashboard.slug))
|
||||
self.assertEquals(rv.status_code, 200)
|
||||
|
||||
self.assertTrue(rv.json['widgets'][0][1]['restricted'])
|
||||
self.assertNotIn('restricted', rv.json['widgets'][0][0])
|
||||
|
||||
@ -59,8 +58,7 @@ class TestDashboardResourcePost(BaseTestCase):
|
||||
def test_raises_error_in_case_of_conflict(self):
|
||||
d = self.factory.create_dashboard()
|
||||
d.name = 'Updated'
|
||||
d.save()
|
||||
|
||||
db.session.commit()
|
||||
new_name = 'New Name'
|
||||
rv = self.make_request('post', '/api/dashboards/{0}'.format(d.id),
|
||||
data={'name': new_name, 'layout': '[]', 'version': d.version - 1})
|
||||
@ -70,7 +68,6 @@ class TestDashboardResourcePost(BaseTestCase):
|
||||
def test_overrides_existing_if_no_version_specified(self):
|
||||
d = self.factory.create_dashboard()
|
||||
d.name = 'Updated'
|
||||
d.save()
|
||||
|
||||
new_name = 'New Name'
|
||||
rv = self.make_request('post', '/api/dashboards/{0}'.format(d.id),
|
||||
@ -122,8 +119,7 @@ class TestDashboardShareResourcePost(BaseTestCase):
|
||||
res = self.make_request('post', '/api/dashboards/{}/share'.format(dashboard.id), user=user)
|
||||
self.assertEqual(res.status_code, 403)
|
||||
|
||||
user.groups.append(self.factory.org.admin_group.id)
|
||||
user.save()
|
||||
user.group_ids.append(self.factory.org.admin_group.id)
|
||||
|
||||
res = self.make_request('post', '/api/dashboards/{}/share'.format(dashboard.id), user=user)
|
||||
self.assertEqual(res.status_code, 200)
|
||||
@ -151,8 +147,7 @@ class TestDashboardShareResourceDelete(BaseTestCase):
|
||||
res = self.make_request('delete', '/api/dashboards/{}/share'.format(dashboard.id), user=user)
|
||||
self.assertEqual(res.status_code, 403)
|
||||
|
||||
user.groups.append(self.factory.org.admin_group.id)
|
||||
user.save()
|
||||
user.group_ids.append(self.factory.org.admin_group.id)
|
||||
|
||||
res = self.make_request('delete', '/api/dashboards/{}/share'.format(dashboard.id), user=user)
|
||||
self.assertEqual(res.status_code, 200)
|
||||
|
Loading…
Reference in New Issue
Block a user