Skip to content

Commit

Permalink
Adding links pointing to the new user profile page (#1704)
Browse files Browse the repository at this point in the history
* Adding links pointing to the new user profile page

* Raising coverage

* Fixing tests
  • Loading branch information
mistercrunch authored Dec 1, 2016
1 parent 50da4f8 commit 7eef46e
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 34 deletions.
6 changes: 4 additions & 2 deletions superset/assets/javascripts/profile/components/Favorites.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ export default class Favorites extends React.PureComponent {
renderSliceTable() {
const mutator = (data) => data.map(slice => ({
slice: <a href={slice.url}>{slice.title}</a>,
creator: <a href={slice.creator_url}>{slice.creator}</a>,
favorited: moment.utc(slice.dttm).fromNow(),
_favorited: slice.dttm,
}));
return (
<TableLoader
dataEndpoint={`/superset/fave_slices/${this.props.user.userId}/`}
className="table table-condensed"
columns={['slice', 'favorited']}
columns={['slice', 'creator', 'favorited']}
mutator={mutator}
noDataText="No favorite slices yet, go click on stars!"
sortable
Expand All @@ -36,6 +37,7 @@ export default class Favorites extends React.PureComponent {
renderDashboardTable() {
const mutator = (data) => data.map(dash => ({
dashboard: <a href={dash.url}>{dash.title}</a>,
creator: <a href={dash.creator_url}>{dash.creator}</a>,
favorited: moment.utc(dash.dttm).fromNow(),
}));
return (
Expand All @@ -44,7 +46,7 @@ export default class Favorites extends React.PureComponent {
mutator={mutator}
dataEndpoint={`/superset/fave_dashboards/${this.props.user.userId}/`}
noDataText="No favorite dashboards yet, go click on stars!"
columns={['dashboard', 'favorited']}
columns={['dashboard', 'creator', 'favorited']}
sortable
/>
);
Expand Down
1 change: 0 additions & 1 deletion superset/assets/javascripts/profile/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ const profileViewContainer = document.getElementById('app');
const bootstrap = JSON.parse(profileViewContainer.getAttribute('data-bootstrap'));

const user = bootstrap.user;

ReactDOM.render(
<App user={user} />,
profileViewContainer
Expand Down
12 changes: 9 additions & 3 deletions superset/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,19 @@ def changed_by_fk(cls): # noqa
Integer, ForeignKey('ab_user.id'),
default=cls.get_user_id, onupdate=cls.get_user_id, nullable=True)

@renders('created_on')
def _user_link(self, user):
if not user:
return ''
url = '/superset/profile/{}/'.format(user.username)
return '<a href="{}">{}</a>'.format(url, escape(user) or '')

@renders('created_by')
def creator(self): # noqa
return '{}'.format(self.created_by or '')
return self._user_link(self.created_by)

@property
def changed_by_(self):
return '{}'.format(self.changed_by or '')
return self._user_link(self.changed_by)

@renders('changed_on')
def changed_on_(self):
Expand Down
55 changes: 36 additions & 19 deletions superset/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1796,7 +1796,7 @@ def recent_activity(self, user_id):
)
.filter(
sqla.and_(
M.Log.action != 'queries',
~M.Log.action.in_(('queries', 'shortner', 'sql_json')),
M.Log.user_id == user_id,
)
)
Expand Down Expand Up @@ -1845,13 +1845,21 @@ def fave_dashboards(self, user_id):
models.FavStar.dttm.desc()
)
)
payload = [{
'id': o.Dashboard.id,
'dashboard': o.Dashboard.dashboard_link(),
'title': o.Dashboard.dashboard_title,
'url': o.Dashboard.url,
'dttm': o.dttm,
} for o in qry.all()]
payload = []
for o in qry.all():
d = {
'id': o.Dashboard.id,
'dashboard': o.Dashboard.dashboard_link(),
'title': o.Dashboard.dashboard_title,
'url': o.Dashboard.url,
'dttm': o.dttm,
}
if o.Dashboard.created_by:
user = o.Dashboard.created_by
d['creator'] = str(user)
d['creator_url'] = '/superset/profile/{}/'.format(
user.username)
payload.append(d)
return Response(
json.dumps(payload, default=utils.json_int_dttm_ser),
mimetype="application/json")
Expand Down Expand Up @@ -1934,12 +1942,20 @@ def fave_slices(self, user_id):
models.FavStar.dttm.desc()
)
)
payload = [{
'id': o.Slice.id,
'title': o.Slice.slice_name,
'url': o.Slice.slice_url,
'dttm': o.dttm,
} for o in qry.all()]
payload = []
for o in qry.all():
d = {
'id': o.Slice.id,
'title': o.Slice.slice_name,
'url': o.Slice.slice_url,
'dttm': o.dttm,
}
if o.Slice.created_by:
user = o.Slice.created_by
d['creator'] = str(user)
d['creator_url'] = '/superset/profile/{}/'.format(
user.username)
payload.append(d)
return Response(
json.dumps(payload, default=utils.json_int_dttm_ser),
mimetype="application/json")
Expand Down Expand Up @@ -2613,15 +2629,15 @@ def profile(self, username):
)
roles = {}
from collections import defaultdict
permissions = defaultdict(list)
permissions = defaultdict(set)
for role in user.roles:
perms = []
perms = set()
for perm in role.permissions:
perms.append(
perms.add(
(perm.permission.name, perm.view_menu.name)
)
if perm.permission.name in ('datasource_access', 'database_access'):
permissions[perm.permission.name].append(perm.view_menu.name)
permissions[perm.permission.name].add(perm.view_menu.name)
roles[role.name] = [
[perm.permission.name, perm.view_menu.name]
for perm in role.permissions
Expand All @@ -2643,7 +2659,8 @@ def profile(self, username):
'superset/profile.html',
title=user.username + "'s profile",
navbar_container=True,
bootstrap_data=json.dumps(payload))
bootstrap_data=json.dumps(payload, default=utils.json_iso_dttm_ser)
)

@has_access
@expose("/sqllab")
Expand Down
15 changes: 10 additions & 5 deletions tests/base_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,19 +140,23 @@ def get_druid_ds_by_name(self, name):
return db.session.query(models.DruidDatasource).filter_by(
datasource_name=name).first()

def get_resp(self, url, data=None, follow_redirects=True):
def get_resp(
self, url, data=None, follow_redirects=True, raise_on_error=True):
"""Shortcut to get the parsed results while following redirects"""
if data:
resp = self.client.post(
url, data=data, follow_redirects=follow_redirects)
return resp.data.decode('utf-8')
else:
resp = self.client.get(url, follow_redirects=follow_redirects)
return resp.data.decode('utf-8')
if raise_on_error and resp.status_code > 400:
raise Exception(
"http request failed with code {}".format(resp.status_code))
return resp.data.decode('utf-8')

def get_json_resp(self, url, data=None):
def get_json_resp(
self, url, data=None, follow_redirects=True, raise_on_error=True):
"""Shortcut to get the parsed results while following redirects"""
resp = self.get_resp(url, data=data)
resp = self.get_resp(url, data, follow_redirects, raise_on_error)
return json.loads(resp)

def get_main_database(self, session):
Expand Down Expand Up @@ -200,6 +204,7 @@ def run_sql(self, sql, client_id, user_name=None):
dbid = self.get_main_database(db.session).id
resp = self.get_json_resp(
'/superset/sql_json/',
raise_on_error=False,
data=dict(database_id=dbid, sql=sql, select_as_create_as=False,
client_id=client_id),
)
Expand Down
17 changes: 17 additions & 0 deletions tests/core_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,23 @@ def test_fetch_all_tables(self):

def test_user_profile(self):
self.login(username='admin')
slc = self.get_slice("Girls", db.session)

# Setting some faves
url = '/superset/favstar/Slice/{}/select/'.format(slc.id)
resp = self.get_json_resp(url)
self.assertEqual(resp['count'], 1)

dash = (
db.session
.query(models.Dashboard)
.filter_by(slug="births")
.first()
)
url = '/superset/favstar/Dashboard/{}/select/'.format(dash.id)
resp = self.get_json_resp(url)
self.assertEqual(resp['count'], 1)

userid = appbuilder.sm.find_user('admin').id
resp = self.get_resp('/superset/profile/admin/')
self.assertIn('"app"', resp)
Expand Down
7 changes: 3 additions & 4 deletions tests/sqllab_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,7 @@ def test_search_query_on_db_id(self):
self.run_some_queries()
self.login('admin')
# Test search queries on database Id
resp = self.get_resp('/superset/search_queries?database_id=1')
data = json.loads(resp)
data = self.get_json_resp('/superset/search_queries?database_id=1')
self.assertEquals(3, len(data))
db_ids = [data[k]['dbId'] for k in data]
self.assertEquals([1, 1, 1], db_ids)
Expand Down Expand Up @@ -164,8 +163,8 @@ def test_search_query_on_status(self):
def test_search_query_on_text(self):
self.run_some_queries()
self.login('admin')
resp = self.get_resp('/superset/search_queries?search_text=permission')
data = json.loads(resp)
url = '/superset/search_queries?search_text=permission'
data = self.get_json_resp(url)
self.assertEquals(1, len(data))
self.assertIn('permission', list(data.values())[0]['sql'])

Expand Down

0 comments on commit 7eef46e

Please sign in to comment.