Skip to content

Commit d273c93

Browse files
committed
more tests and cleanup
1 parent 2aa90fe commit d273c93

File tree

9 files changed

+98
-27
lines changed

9 files changed

+98
-27
lines changed

.coveragerc

+8
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,11 @@ omit =
33
test/*
44
feeds/biokbase/*
55
source = feeds
6+
7+
[report]
8+
exclude_lines =
9+
# Have to re-enable the standard pragma
10+
pragma: no cover
11+
12+
# Don't complain if tests don't hit defensive assertion code:
13+
raise NotImplementedError

feeds/activity/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ class BaseActivity(object):
88
"""
99
@abstractmethod
1010
def to_dict(self):
11-
pass
11+
raise NotImplementedError

test-ui/src/api/feeds.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
* Basic feeds API.
33
*/
44
import axios from 'axios';
5-
// const feedsUrl = 'https://ci.kbase.us/services/feeds/';
6-
const feedsUrl = 'http://localhost:5000/';
5+
const feedsUrl = 'https://ci.kbase.us/services/feeds/';
6+
// const feedsUrl = 'http://localhost:5000/';
77

88
/**
99
*

test-ui/src/feeds/feed.js

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ export default class Feed {
8686
// get filter info from controls
8787
// run the refresh function
8888
// update this feed with the results
89+
console.log(this.ctrlState);
8990
this.refreshFn(this.ctrlState);
9091
}
9192

test-ui/src/feeds/notification.js

+28-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export default class Notification {
77
* has keys: actor, context, created, expires, id, level, object, source, verb
88
*/
99
constructor(note, token, refreshFn, showSeen) {
10+
console.log(note);
1011
this.note = note;
1112
this.token = token;
1213
this.refreshFn = refreshFn;
@@ -40,10 +41,18 @@ export default class Notification {
4041
}
4142

4243
renderControl() {
43-
if (!this.showSeen) {
44-
return '';
44+
let control = '';
45+
if (this.showSeen) {
46+
control += this.renderSeen();
47+
}
48+
if (this.note.context && this.note.context.link) {
49+
control += this.renderLink(this.note.context.link);
4550
}
46-
return this.renderSeen();
51+
return control;
52+
}
53+
54+
renderLink(url) {
55+
return `<span style="font-size: 1.5em;"><a href="${url}" target="_blank"><i class="fas fa-external-link-alt"></i></a></span>`;
4756
}
4857

4958
renderLevel() {
@@ -95,7 +104,22 @@ export default class Notification {
95104
return this.note.context.text;
96105
}
97106
else {
98-
return this.note.actor + ' ' + this.note.verb + ' ' + this.note.object;
107+
let msg;
108+
switch(this.note.verb) {
109+
case "invited":
110+
let obj = this.note.object;
111+
if (this.note.context && this.note.context.groupid) {
112+
obj = this.note.context.groupid;
113+
}
114+
msg = this.note.actor + ' ' + this.note.verb + ' you to join ' + obj;
115+
break;
116+
case "shared":
117+
msg = this.note.actor + ' ' + this.note.verb + ' with you.';
118+
break;
119+
default:
120+
msg = this.note.actor + ' ' + this.note.verb + ' ' + this.note.object;
121+
}
122+
return msg;
99123
}
100124
}
101125

test-ui/src/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ function main() {
2020

2121
let tokenForm = new TokenInput(handleTokenLookup);
2222
let globalPoster = new GlobalFeedPoster(() => {
23-
myFeed.refreshFeed();
23+
myFeed.refreshFeed({});
2424
});
2525
let targetedPoster = new TargetedFeedPoster(() => {
26-
myFeed.refreshFeed();
26+
myFeed.refreshFeed({});
2727
});
2828
let myFeed = new FeedController();
2929

test/api/test_api_v1.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import json
2+
import pytest
3+
4+
5+
def test_api_root(client):
6+
response = client.get('/api/V1')
7+
data = json.loads(response.data)
8+
assert 'routes' in data
9+
assert len(data['routes']) == 8
10+

test/conftest.py

+30-12
Original file line numberDiff line numberDiff line change
@@ -74,48 +74,66 @@ def mock_valid_user_token(requests_mock):
7474
def auth_valid_user_token(user_id, user_name):
7575
cfg = test_config()
7676
auth_url = cfg.get('feeds', 'auth-url')
77-
requests_mock.get('{}/api/V2/token'.format(auth_url), text=json.dumps({
77+
requests_mock.get('{}/api/V2/token'.format(auth_url), json={
7878
'user': user_id,
7979
'type': 'Login',
8080
'name': None
81-
}))
82-
requests_mock.get('{}/api/V2/me'.format(auth_url), text=json.dumps({
81+
})
82+
requests_mock.get('{}/api/V2/me'.format(auth_url), json={
8383
'customroles': [],
8484
'display': user_name,
8585
'user': user_id
86-
}))
86+
})
8787
return auth_valid_user_token
8888

8989
@pytest.fixture
9090
def mock_valid_service_token(requests_mock):
9191
def auth_valid_service_token(user_id, user_name, service_name):
9292
cfg = test_config()
9393
auth_url = cfg.get('feeds', 'auth-url')
94-
requests_mock.get('{}/api/V2/token'.format(auth_url), text=json.dumps({
94+
requests_mock.get('{}/api/V2/token'.format(auth_url), json={
9595
'user': user_id,
9696
'type': 'Service',
9797
'name': service_name
98-
}))
99-
requests_mock.get('{}/api/V2/me'.format(auth_url), text=json.dumps({
98+
})
99+
requests_mock.get('{}/api/V2/me'.format(auth_url), json={
100100
'customroles': [],
101101
'display': user_name,
102102
'user': user_id
103-
}))
103+
})
104104
return auth_valid_service_token
105105

106106
@pytest.fixture
107107
def mock_valid_admin_token(requests_mock):
108108
def auth_valid_admin_token(user_id, user_name):
109109
cfg = test_config()
110110
auth_url = cfg.get('feeds', 'auth-url')
111-
requests_mock.get('{}/api/V2/token'.format(auth_url), text=json.dumps({
111+
requests_mock.get('{}/api/V2/token'.format(auth_url), json={
112112
'user': user_id,
113113
'type': 'Login',
114114
'name': None
115-
}))
116-
requests_mock.get('{}/api/V2/me'.format(auth_url), text=json.dumps({
115+
})
116+
requests_mock.get('{}/api/V2/me'.format(auth_url), json={
117117
'customroles': ['FEEDS_ADMIN'],
118118
'display': user_name,
119119
'user': user_id
120-
}))
120+
})
121121
return auth_valid_admin_token
122+
123+
@pytest.fixture
124+
def mock_invalid_user_token(requests_mock):
125+
def auth_invalid_user_token(user_id):
126+
cfg = test_config()
127+
auth_url = cfg.get('feeds', 'auth-url')
128+
requests_mock.register_uri('GET', '{}/api/V2/token'.format(auth_url),
129+
status_code=401,
130+
json={
131+
"error": {
132+
"appcode": 10020,
133+
"apperror": "Invalid token",
134+
"httpcode": 401,
135+
"httpstatus": "Unauthorized"
136+
}
137+
}
138+
)
139+
return auth_invalid_user_token

test/test_server.py

+16-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from uuid import uuid4
88
cfg = test_config()
99

10+
1011
@pytest.mark.parametrize('path', (
1112
'/api/V1/notifications',
1213
'/api/V1/notifications?',
@@ -20,6 +21,7 @@ def test_server_get_paths_noauth(client, path):
2021
assert data['error'].get('http_status') == 'Forbidden'
2122
assert 'Authentication token required' in data['error'].get('message')
2223

24+
2325
@pytest.mark.parametrize('path', (
2426
'/api/V1/notification',
2527
'/api/V1/notification/global',
@@ -34,6 +36,7 @@ def test_server_post_paths_noauth(client, path):
3436
assert data['error'].get('http_status') == 'Forbidden'
3537
assert 'Authentication token required' in data['error'].get('message')
3638

39+
3740
def test_root(client):
3841
response = client.get('/')
3942
data = json.loads(response.data)
@@ -42,11 +45,6 @@ def test_root(client):
4245
assert 'service' in data and data['service'] == 'Notification Feeds Service'
4346
assert 'version' in data
4447

45-
def test_api_root(client):
46-
response = client.get('/api/V1')
47-
data = json.loads(response.data)
48-
assert 'routes' in data
49-
assert len(data['routes']) == 8
5048

5149
def test_permissions_noauth(client, requests_mock):
5250
response = client.get('/permissions')
@@ -56,6 +54,7 @@ def test_permissions_noauth(client, requests_mock):
5654
assert 'permissions' in data
5755
assert data['permissions'] == {'GET': ['/api/V1/notifications/global'], 'POST': []}
5856

57+
5958
def test_permissions_user(client, requests_mock, mock_valid_user_token):
6059
user_id = 'a_user'
6160
user_name = 'A User'
@@ -102,4 +101,15 @@ def test_permissions_admin(client, requests_mock, mock_valid_admin_token):
102101
valid_gets = set(['/api/V1/notifications/global', '/api/V1/notifications', '/api/V1/notification/<note_id>'])
103102
assert valid_gets == set(data['permissions']['GET'])
104103
valid_posts = set(['/api/V1/notifications/see', '/api/V1/notifications/unsee', '/api/V1/notification/global'])
105-
assert valid_posts == set(data['permissions']['POST'])
104+
assert valid_posts == set(data['permissions']['POST'])
105+
106+
107+
def test_permissions_bad_token(client, mock_invalid_user_token):
108+
user_id = 'bad_user'
109+
mock_invalid_user_token(user_id)
110+
response = client.get('/permissions', headers={'Authorization': 'bad_token-'+str(uuid4())})
111+
data = json.loads(response.data)
112+
assert 'token' in data
113+
assert data['token'] == {'service': None, 'user': None, 'admin': False}
114+
assert 'permissions' in data
115+
assert data['permissions'] == {'GET': ['/api/V1/notifications/global'], 'POST': []}

0 commit comments

Comments
 (0)