Completed
Push — master ( e4fa6a...7cecba )
by Chris
59s
created

test_metadata()   A

Complexity

Conditions 4

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 4
dl 0
loc 9
rs 9.2
c 3
b 1
f 0
1
import json
2
import os
3
from datetime import datetime as dt
4
from random import shuffle
5
6
from flask import (
7
    Flask,
8
    current_app,
9
    url_for,
10
)
11
12
from pyquery import PyQuery as pq
13
14
import pytest
15
16
from conftest import (
17
    URL_BASE,
18
    auth_invalid,
19
    auth_valid,
20
    read,
21
    update,
22
)
23
24
from flask_jsondash import charts_builder
25
from flask_jsondash import settings
26
27
REDIRECT_MSG = 'You should be redirected automatically'
28
cwd = os.getcwd()
29
30
31
# Py2/3 compat.
32
try:
33
    _unicode = unicode
34
except NameError:
35
    _unicode = str
36
37
38
def get_json_config(name):
39
    parent = cwd.replace('tests/', '')
40
    path = '{0}/example_app/examples/config/{1}'.format(parent, name)
41
    view = json.load(open(path, 'r'))
42
    return view
43
44
45 View Code Duplication
@pytest.mark.globalflag
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
46
def test_noset_global_flag_when_creating_dashboard(ctx, client, monkeypatch):
47
    app, test = client
48
    app.config['JSONDASH_GLOBALDASH'] = True
49
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
50
    data = dict(name='global-check')
51
    test.post('/charts/create', data=data).data
52
    assert len(read()) == 1
53
    assert read()[0]['name'] == 'global-check'
54
    assert read()[0]['created_by'] == 'Username'
55
56
57 View Code Duplication
@pytest.mark.globalflag
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
58
def test_set_global_flag_when_creating_dashboard(ctx, client, monkeypatch):
59
    app, test = client
60
    app.config['JSONDASH_GLOBALDASH'] = True
61
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
62
    data = dict(name='global-check', is_global='on')
63
    test.post('/charts/create', data=data).data
64
    assert len(read()) == 1
65
    assert read()[0]['name'] == 'global-check'
66
    assert read()[0]['created_by'] == app.config.get('JSONDASH_GLOBAL_USER')
67
68
69
@pytest.mark.globalflag
70
def test_no_config_sanity_test(ctx, client):
71
    app, test = client
72
    assert not app.config.get('JSONDASH_GLOBALDASH')
73
    assert not app.config.get('JSONDASH_FILTERUSERS')
74
    assert app.config.get('JSONDASH_GLOBAL_USER') == 'global-test'
75
76
77
@pytest.mark.globalflag
78
def test_setting(ctx, client):
79
    app, test = client
80
    _get = charts_builder.setting
81
    assert not _get('JSONDASH_GLOBALDASH')
82
    assert not _get('JSONDASH_FILTERUSERS')
83
    assert _get('JSONDASH_GLOBAL_USER') == 'global-test'
84
85
86
@pytest.mark.globalflag
87
def test_is_global_dashboard_true(ctx, client):
88
    app, test = client
89
    app.config.update(JSONDASH_GLOBALDASH=True)
90
    assert charts_builder.is_global_dashboard(
91
        dict(created_by='global-test'))
92
93
94
@pytest.mark.globalflag
95
def test_is_global_dashboard_false(ctx, client):
96
    app, test = client
97
    is_global = charts_builder.is_global_dashboard
98
    assert not is_global(dict(created_by='foo'))
99
    assert not is_global(dict(created_by='Username'))
100
101
102
@pytest.mark.auth
103
def test_auth_no_appconfig(ctx, client):
104
    app, test = client
105
    del app.config['JSONDASH']
106
    assert charts_builder.auth()
107
108
109
@pytest.mark.auth
110
def test_auth_no_authconfig(ctx, client):
111
    app, test = client
112
    del app.config['JSONDASH']['auth']
113
    assert charts_builder.auth()
114
115
116
@pytest.mark.auth
117
def test_auth_false_realauth(ctx, client):
118
    app, test = client
119
    assert not charts_builder.auth(authtype='create')
120
    assert not charts_builder.auth(authtype='view')
121
    assert not charts_builder.auth(authtype='delete')
122
    assert not charts_builder.auth(authtype='clone')
123
    assert not charts_builder.auth(authtype='edit_global')
124
    assert not charts_builder.auth(authtype='edit_others')
125
126
127
@pytest.mark.auth
128
def test_no_auth_view(ctx, client, monkeypatch):
129
    app, test = client
130
    monkeypatch.setattr(charts_builder, 'auth', auth_invalid)
131
    res = str(test.get('/charts/foo', follow_redirects=True).data)
132
    alerts = pq(res).find('.alert-danger').text()
133
    assert 'You do not have access to view this dashboard.' in alerts
134
135
136
@pytest.mark.auth
137
def test_no_auth_delete(ctx, client, monkeypatch):
138
    app, test = client
139
    monkeypatch.setattr(charts_builder, 'auth', auth_invalid)
140
    res = str(test.post('/charts/foo/delete',
141
              data=dict(), follow_redirects=True).data)
142
    alerts = pq(res).find('.alert-danger').text()
143
    assert 'You do not have access to delete dashboards.' in alerts
144
145
146
@pytest.mark.auth
147
def test_no_auth_update(ctx, client, monkeypatch):
148
    app, test = client
149
    monkeypatch.setattr(charts_builder, 'auth', auth_invalid)
150
    res = str(test.post('/charts/foo/update',
151
              data=dict(), follow_redirects=True).data)
152
    alerts = pq(res).find('.alert-danger').text()
153
    assert 'You do not have access to update dashboards.' in alerts
154
155
156
@pytest.mark.auth
157
def test_no_auth_create(ctx, client, monkeypatch):
158
    app, test = client
159
    monkeypatch.setattr(charts_builder, 'auth', auth_invalid)
160
    res = str(test.post('/charts/create',
161
              data=dict(), follow_redirects=True).data)
162
    alerts = pq(res).find('.alert-danger').text()
163
    assert 'You do not have access to create dashboards.' in alerts
164
165
166
@pytest.mark.auth
167
def test_no_auth_clone(ctx, client, monkeypatch):
168
    app, test = client
169
    monkeypatch.setattr(charts_builder, 'auth', auth_invalid)
170
    res = str(test.post('/charts/foo/clone', follow_redirects=True).data)
171
    alerts = pq(res).find('.alert-danger').text()
172
    assert 'You do not have access to clone dashboards.' in alerts
173
174
175
@pytest.mark.auth
176
def test_auth_true_realauth(ctx, client):
177
    app, test = client
178
179
    def authfunc(*args):
180
        return True
181
182
    app.config['JSONDASH']['auth'] = dict(
183
        clone=authfunc,
184
        edit_global=authfunc,
185
        create=authfunc,
186
        delete=authfunc,
187
        view=authfunc,
188
    )
189
    assert charts_builder.auth(authtype='create')
190
    assert charts_builder.auth(authtype='view')
191
    assert charts_builder.auth(authtype='delete')
192
    assert charts_builder.auth(authtype='clone')
193
    assert charts_builder.auth(authtype='edit_global')
194
    assert charts_builder.auth(authtype='edit_others')
195
196
197
@pytest.mark.auth
198
@pytest.mark.metadata
199
def test_auth_true_fakeauth(ctx, client):
200
    app, test = client
201
    assert charts_builder.auth(authtype=None)
202
    assert charts_builder.auth(authtype='foo')
203
    assert charts_builder.metadata(key='foo') is None
204
205
206
@pytest.mark.metadata
207
def test_metadata(ctx, client):
208
    app, test = client
209
    assert charts_builder.metadata() == dict(
210
        username='Username',
211
        created_by='Username',
212
    )
213
    assert charts_builder.metadata(key='username') == 'Username'
214
    assert charts_builder.metadata(key='created_by') == 'Username'
215
216 View Code Duplication
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
217
@pytest.mark.metadata
218
def test_metadata_exclude(ctx, client):
219
    app, test = client
220
    assert charts_builder.metadata() == dict(
221
        username='Username',
222
        created_by='Username',
223
    )
224
    assert charts_builder.metadata(exclude='created_by') == dict(
225
        username='Username'
226
    )
227
    assert charts_builder.metadata(exclude='username') == dict(
228 View Code Duplication
        created_by='Username'
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
229
    )
230
231
232
@pytest.mark.filters
233
def test_getdims_normal(ctx, client):
234
    app, test = client
235
    data = dict(width=100, height=100, type='foo')
236
    expected = dict(width=100, height=100)
237
    assert charts_builder.get_dims(object, data) == expected
238
239
240
@pytest.mark.filters
241
def test_getdims_youtube(ctx, client):
242
    app, test = client
243
    yt = ('<iframe width="650" height="366" '
244
          'src="https://www.youtube.com/embed/'
245
          '_hI0qMtdfng?list=RD_hI0qMtdfng&amp;'
246
          'controls=0&amp;showinfo=0" frameborder="0"'
247
          ' allowfullscreen></iframe>')
248
    data = dict(type='youtube', dataSource=yt, width=100, height=100)
249
    expected = dict(width=650 + 20, height=366 + 60)
250
    assert charts_builder.get_dims(object, data) == expected
251
252
253
@pytest.mark.filters
254
def test_jsonstring(ctx, client):
255
    app, test = client
256
    now = dt.now()
257
    data = dict(date=now, foo='bar')
258
    res = charts_builder.jsonstring(object, data)
259
    assert 'foo' in res
260
    assert isinstance(res, str)
261
    d = json.loads(res)
262
    assert isinstance(d['date'], _unicode)
263
264
265
@pytest.mark.utils
266
def test_order_sort_force_valueerror():
267
    item = dict(order='NaN')
268
    assert charts_builder.order_sort(item) == -1
269
270
271
@pytest.mark.utils
272
def test_order_sort_invalid_key():
273
    item = dict()
274
    assert charts_builder.order_sort(item) == -1
275
276
277
@pytest.mark.utils
278
def test_order_sort_valid_key():
279
    item = dict(order=1)
280
    assert charts_builder.order_sort(item) == 1
281
282
283
@pytest.mark.utils
284
def test_order_shuffled_sort_multiple_valid_key():
285
    orders = list(range(0, 10))
286
    shuffle(orders)
287
    modules = [dict(order=i, foo='bar') for i in orders]
288
    res = sorted(modules, key=charts_builder.order_sort)
289
    for i in range(0, 10):
290
        assert res[i]['order'] == i
291
292
293
@pytest.mark.utils
294
def test_order_shuffled_sort_multiple_valid_key_one_invalid_key():
295
    orders = list(range(0, 10))
296
    shuffle(orders)
297
    modules = [dict(order=i, foo='bar') for i in orders]
298
    # Add one w/o order key.
299
    modules.append(dict(foo='bar'))
300
    res = sorted(modules, key=charts_builder.order_sort)
301
    # The invalid key goes first.
302
    assert 'order' not in res[0]
303
    # The remaining will be offset since the first one has no key.
304
    for i in range(0, 10):
305
        if 'order' in res[i]:
306
            assert res[i]['order'] == i - 1
307
308
309
def test_app_redirects(ctx, client):
310
    app, test = client
311
    res = test.get('/charts')
312
    assert REDIRECT_MSG in str(res.data)
313
314
315
def test_routes(ctx, client):
316
    assert url_for('jsondash.dashboard') == '/charts/'
317
    assert url_for('jsondash.view', c_id='foo') == '/charts/foo'
318
    assert url_for('jsondash.update', c_id='foo') == '/charts/foo/update'
319
    assert url_for('jsondash.clone', c_id='foo') == '/charts/foo/clone'
320
    assert url_for('jsondash.delete', c_id='foo') == '/charts/foo/delete'
321
    assert url_for('jsondash.create') == '/charts/create'
322
323
324
def test_get_dashboard_contains_all_chart_types_list(monkeypatch, ctx, client):
325
    app, test = client
326
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
327
    res = test.get(url_for('jsondash.dashboard'))
328
    for family, config in settings.CHARTS_CONFIG.items():
329
        for chart in config['charts']:
330
            _, label = chart
331
            assert label in str(res.data)
332
333
334
def test_get_dashboard_contains_no_chart_msg(monkeypatch, ctx, client):
335
    app, test = client
336
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
337
    res = str(test.get(url_for('jsondash.dashboard')).data)
338
    assert 'No dashboards exist. Create one below to get started.' in res
339
340
341
def test_create_dashboards_check_index_count(monkeypatch, ctx, client):
342
    app, test = client
343
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
344
    for i in range(10):
345
        data = dict(name=i, modules=[])
346
        res = test.post(url_for('jsondash.create'), data=data)
347
    res = test.get(url_for('jsondash.dashboard'))
348
    assert len(read()) == 10
349
    heading = pq(res.data).find('h1.lead').text()
350
    assert 'Showing 10 dashboards with 0 charts' in heading
351
352
353
def test_get_view_valid_id_invalid_config(monkeypatch, ctx, client):
354
    app, test = client
355
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
356
    view = dict(modules=[dict(foo='bar')])
357
    readfunc = read(override=dict(view))
358
    monkeypatch.setattr(charts_builder.adapter, 'read', readfunc)
359
    with pytest.raises(ValueError):
360
        res = test.get(url_for('jsondash.view', c_id='123'))
361
        assert 'Invalid config!' in str(res.data)
362
363
364
def test_get_view_valid_id_invalid_modules(monkeypatch, ctx, client):
365
    app, test = client
366
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
367
    view = dict(id='123')
368
    readfunc = read(override=dict(view))
369
    monkeypatch.setattr(charts_builder.adapter, 'read', readfunc)
370
    res = test.get(
371
        url_for('jsondash.view', c_id='123'),
372
        follow_redirects=True)
373
    assert 'Invalid configuration - missing modules.' in str(res.data)
374
375
376 View Code Duplication
def test_get_view_valid_id_ensure__id_popped(monkeypatch, ctx, client):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
377
    app, test = client
378
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
379
    view = get_json_config('inputs.json')
380
    view = dict(view)
381
    view.update(_id='foo')
382
    readfunc = read(override=view)
383
    monkeypatch.setattr(charts_builder.adapter, 'read', readfunc)
384
    res = test.get(url_for('jsondash.view', c_id=view['id']))
385
    dom = pq(res.data)
386
    assert len(dom.find('.item')) == len(view['modules'])
387
388
389 View Code Duplication
def test_view_valid_dashboard_count_and_inputs(monkeypatch, ctx, client):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
390
    app, test = client
391
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
392
    view = get_json_config('inputs.json')
393
    readfunc = read(override=dict(view))
394
    monkeypatch.setattr(charts_builder.adapter, 'read', readfunc)
395
    res = test.get(url_for('jsondash.view', c_id=view['id']))
396
    dom = pq(res.data)
397
    assert len(dom.find('.item')) == len(view['modules'])
398
    assert len(dom.find('.charts-input-icon')) == 1
399
400
401
def test_view_valid_dashboard_inputs_form(monkeypatch, ctx, client):
402
    app, test = client
403
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
404
    view = get_json_config('inputs.json')
405
    readfunc = read(override=dict(view))
406
    monkeypatch.setattr(charts_builder.adapter, 'read', readfunc)
407
    res = test.get(url_for('jsondash.view', c_id=view['id']))
408
    dom = pq(res.data)
409
    charts_with_inputs = [m for m in view['modules'] if 'inputs' in m]
410
    num_config_inputs = len(charts_with_inputs[0]['inputs']['options'])
411
    assert num_config_inputs == 5  # Sanity check
412
    assert len(charts_with_inputs) == 1
413
    assert len(dom.find('.chart-inputs')) == 1
414
    assert dom.find('.chart-inputs').hasClass('collapse')
415
    # There are 7 input fields generated for this particular json file.
416
    assert len(dom.find('.chart-inputs form input')) == 7
417
418
419
def test_view_valid_dashboard_inputs_form_counts(monkeypatch, ctx, client):
420
    app, test = client
421
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
422
    view = get_json_config('inputs.json')
423
    readfunc = read(override=dict(view))
424
    monkeypatch.setattr(charts_builder.adapter, 'read', readfunc)
425
    res = test.get(url_for('jsondash.view', c_id=view['id']))
426
    dom = pq(res.data)
427
    charts_with_inputs = [m for m in view['modules'] if 'inputs' in m]
428
    input_options = charts_with_inputs[0]['inputs']['options']
429
    radio_opts = [o for o in input_options if o['type'] == 'radio'][0]
430
    radio_opts = radio_opts['options']
431
    assert len(dom.find('.chart-inputs form .input-radio')) == len(radio_opts)
432
    select = [o for o in input_options if o['type'] == 'select']
433
    assert len(dom.find('.chart-inputs form select')) == len(select)
434
    options = select[0]['options']
435
    assert len(dom.find('.chart-inputs form select option')) == len(options)
436
    numbers = [inp for inp in input_options if inp['type'] == 'number']
437
    assert len(dom.find('.chart-inputs [type="number"]')) == len(numbers)
438
    text = [inp for inp in input_options if inp['type'] == 'text']
439
    assert len(dom.find('.chart-inputs [type="text"]')) == len(text)
440
    checkbox = [inp for inp in input_options if inp['type'] == 'checkbox']
441
    assert len(dom.find('.chart-inputs [type="checkbox"]')) == len(checkbox)
442
443
444
def test_get_view_valid_modules_valid_dash_title(monkeypatch, ctx, client):
445
    app, test = client
446
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
447
    view = get_json_config('inputs.json')
448
    readfunc = read(override=dict(view))
449
    monkeypatch.setattr(charts_builder.adapter, 'read', readfunc)
450
    res = test.get(url_for('jsondash.view', c_id=view['id']))
451
    dom = pq(res.data)
452
    assert dom.find('.dashboard-title').text() == view['name']
453
454
455
@pytest.mark.invalid_id_redirect
456
def test_get_view_invalid_id_redirect(monkeypatch, ctx, client):
457
    app, test = client
458
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
459
    res = test.get(url_for('jsondash.view', c_id='123'))
460
    assert REDIRECT_MSG in str(res.data)
461
462
463
def test_create_valid(monkeypatch, ctx, client):
464
    app, test = client
465
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
466
    res = test.post(
467
        url_for('jsondash.create'),
468
        data=dict(name='mydash-valid'),
469
        follow_redirects=True)
470
    dom = pq(res.data)
471
    flash_msg = 'Created new dashboard "mydash-valid"'
472
    assert dom.find('.alert-info').text() == flash_msg
473
474
475
@pytest.mark.invalid_id_redirect
476
def test_clone_invalid_id_redirect(monkeypatch, ctx, client):
477
    app, test = client
478
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
479
    res = test.post(url_for('jsondash.clone', c_id='123'))
480
    assert REDIRECT_MSG in str(res.data)
481
482
483
def test_clone_valid(monkeypatch, ctx, client):
484
    app, test = client
485
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
486
    assert len(read()) == 0
487
    res = test.post(url_for('jsondash.create'),
488
                    data=dict(name='mydash', modules=[]),
489
                    follow_redirects=True)
490
    dom = pq(res.data)
491
    new_id = read()[0]['id']
492
    assert read()[0]['name'] == 'mydash'
493
    flash_msg = 'Created new dashboard "mydash"'
494
    assert dom.find('.alert-info').text() == flash_msg
495
    assert len(read()) == 1
496
    assert read()[0]['name'] == 'mydash'
497
    res = test.post(
498
        url_for('jsondash.clone', c_id=new_id),
499
        follow_redirects=True)
500
    dom = pq(res.data)
501
    flash_msg = 'Created new dashboard clone "Clone of mydash"'
502
    assert flash_msg in dom.find('.alert').text()
503
    assert len(read()) == 2
504
505
506
@pytest.mark.invalid_id_redirect
507
def test_delete_invalid_id_redirect(monkeypatch, ctx, client):
508
    app, test = client
509
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
510
    res = test.post(
511
        url_for('jsondash.delete', c_id='123'))
512
    assert REDIRECT_MSG in str(res.data)
513
514
515
def test_delete_valid(monkeypatch, ctx, client):
516
    app, test = client
517
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
518
    view = dict(name='mydash', modules=[])
519
    readfunc = read(override=dict(view))
520
    monkeypatch.setattr(charts_builder.adapter, 'read', readfunc)
521
    assert not read()
522
    # Create first one.
523
    res = test.post(url_for('jsondash.create'),
524
                    data=view,
525
                    follow_redirects=True)
526
    assert len(read()) == 1
527
    view_id = read()[0]['id']
528
    dom = pq(res.data)
529
    flash_msg = 'Created new dashboard "mydash"'
530
    assert dom.find('.alert-info').text() == flash_msg
531
    assert len(read()) == 1
532
    res = test.post(url_for('jsondash.delete', c_id=view_id),
533
                    follow_redirects=True)
534
    dom = pq(res.data)
535
    flash_msg = 'Deleted dashboard "{}"'.format(view_id)
536
    assert dom.find('.alert-info').text() == flash_msg
537
    assert len(read()) == 0
538
539
540
@pytest.mark.invalid_id_redirect
541
def test_update_invalid_id_redirect(monkeypatch, ctx, client):
542
    app, test = client
543
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
544
    res = test.post(url_for('jsondash.update', c_id='123'))
545
    assert REDIRECT_MSG in str(res.data)
546
547
548 View Code Duplication
def test_update_invalid_config(monkeypatch, ctx, client):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
549
    app, test = client
550
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
551
    view = get_json_config('inputs.json')
552
    readfunc = read(override=dict(view))
553
    monkeypatch.setattr(charts_builder.adapter, 'read', readfunc)
554
    res = test.post(
555
        url_for('jsondash.update', c_id=view['id']),
556
        data={'edit-raw': 'on'},
557
        follow_redirects=True)
558
    dom = pq(res.data)
559
    assert dom.find('.alert-danger').text() == 'Error: Invalid JSON config.'
560
561
562
def test_update_valid(monkeypatch, ctx, client):
563
    app, test = client
564
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
565
    assert not read()
566
    res = test.post(
567
        url_for('jsondash.create'),
568
        data=dict(name='newname', modules=[]),
569
        follow_redirects=True)
570
    assert len(read()) == 1
571
    view_id = read()[0]['id']
572
    res = test.post(
573
        url_for('jsondash.update', c_id=view_id),
574
        data=dict(name='newname'),
575
        follow_redirects=True)
576
    dom = pq(res.data)
577
    flash_msg = 'Updated view "{}"'.format(view_id)
578
    assert dom.find('.alert-info').text() == flash_msg
579
    assert len(read()) == 1
580