Completed
Push — master ( ffced1...adac64 )
by Chris
34s
created

test_basic_routes()   A

Complexity

Conditions 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
import json
2
3
from flask import url_for
4
5
from pyquery import PyQuery as pq
6
7
import pytest
8
9
from conftest import (
10
    get_json_config,
11
    auth_valid,
12
    read,
13
    setup_dashboard,
14
    make_chart,
15
)
16
17
from flask_jsondash import charts_builder
18
from flask_jsondash import settings
19
from flask_jsondash.utils import adapter
20
21
REDIRECT_MSG = 'You should be redirected automatically'
22
23
24
def test_app_redirects(client):
25
    _, test = client
26
    res = test.get('/charts')
27
    assert REDIRECT_MSG in str(res.data)
28
29
30
@pytest.mark.parametrize('url, expected', [
31
    ('jsondash.dashboard', '/charts/'),
32
    ('jsondash.create', '/charts/create'),
33
])
34
def test_basic_routes(client, url, expected):
35
    assert url_for(url) == expected
36
37
38
@pytest.mark.parametrize('url, expected', [
39
    ('jsondash.view', '/charts/foo'),
40
    ('jsondash.update', '/charts/foo/update'),
41
    ('jsondash.clone', '/charts/foo/clone'),
42
    ('jsondash.delete', '/charts/foo/delete'),
43
])
44
def test_chart_routes(client, url, expected):
45
    assert url_for(url, c_id='foo') == expected
46
47
48
def test_get_dashboard_contains_all_chart_types_list(monkeypatch, client):
49
    _, test = client
50
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
51
    view = get_json_config('inputs.json')
52
    readfunc = read(override=dict(view))
53
    monkeypatch.setattr(adapter, 'read', readfunc)
54
    res = test.get(url_for('jsondash.view', c_id=view['id']))
55
    assert res.status_code == 200
56
    for family, config in settings.CHARTS_CONFIG.items():
57
        for chart in config['charts']:
58 View Code Duplication
            _, label = chart
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
59
            assert label in str(res.data)
60
61
62
def test_get_dashboard_contains_no_chart_msg(monkeypatch, client):
63
    _, test = client
64
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
65
    res = str(test.get(url_for('jsondash.dashboard')).data)
66
    assert 'No dashboards exist. Create one below to get started.' in res
67
68
69
def test_dashboards_override_perpage_pagination(monkeypatch, client):
70
    _, test = client
71 View Code Duplication
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
72
    for i in range(10):
73
        data = dict(name=i, modules=[])
74
        res = test.post(url_for('jsondash.create'), data=data)
75
    res = test.get(url_for('jsondash.dashboard') + '?per_page=2')
76
    # Ensure 10 exist, but only 5 are shown
77
    assert len(read()) == 10
78
    dom = pq(res.data)
79
    assert len(dom.find('.pagination').find('li:not(.active)')) == 5
80
81
82
def test_create_dashboards_check_index_count(monkeypatch, client):
83
    _, test = client
84
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
85
    for i in range(10):
86
        data = dict(name=i, modules=[])
87
        res = test.post(url_for('jsondash.create'), data=data)
88
    res = test.get(url_for('jsondash.dashboard'))
89
    assert len(read()) == 10
90
    heading = pq(res.data).find('h1.lead').text()
91
    assert 'Showing 10 dashboards with 0 charts' in heading
92
93
94
def test_get_view_valid_id_invalid_config(monkeypatch, client):
95
    _, test = client
96
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
97
    view = dict(modules=[dict(foo='bar')])
98
    readfunc = read(override=dict(view))
99
    monkeypatch.setattr(adapter, 'read', readfunc)
100
    with pytest.raises(ValueError):
101
        res = test.get(url_for('jsondash.view', c_id='123'))
102
        assert 'Invalid config!' in str(res.data)
103
104
105
def test_get_view_valid_id_invalid_modules(monkeypatch, client):
106
    _, test = client
107
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
108
    view = dict(id='123')
109
    readfunc = read(override=dict(view))
110
    monkeypatch.setattr(adapter, 'read', readfunc)
111
    res = test.get(
112
        url_for('jsondash.view', c_id='123'),
113
        follow_redirects=True)
114
    assert 'Invalid configuration - missing modules.' in str(res.data)
115
116
117
def test_get_view_valid_id_ensure_id_popped(monkeypatch, client):
118
    _, test = client
119
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
120
    view = get_json_config('inputs.json')
121
    view = dict(view)
122
    view.update(_id='foo')
123
    readfunc = read(override=view)
124
    monkeypatch.setattr(adapter, 'read', readfunc)
125
    res = test.get(url_for('jsondash.view', c_id=view['id']))
126
    dom = pq(res.data)
127
    assert len(dom.find('.item')) == len(view['modules'])
128
129
130
def test_view_valid_dashboard_count_and_inputs(monkeypatch, client):
131
    _, test = client
132
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
133
    view = get_json_config('inputs.json')
134
    readfunc = read(override=dict(view))
135
    monkeypatch.setattr(adapter, 'read', readfunc)
136
    res = test.get(url_for('jsondash.view', c_id=view['id']))
137
    dom = pq(res.data)
138
    assert len(dom.find('.item')) == len(view['modules'])
139
    assert len(dom.find('.charts-input-icon')) == 1
140
141
142
def test_view_valid_dashboard_inputs_form(monkeypatch, client):
143
    _, test = client
144
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
145
    view = get_json_config('inputs.json')
146
    readfunc = read(override=dict(view))
147
    monkeypatch.setattr(adapter, 'read', readfunc)
148
    res = test.get(url_for('jsondash.view', c_id=view['id']))
149
    dom = pq(res.data)
150
    charts_with_inputs = [m for m in view['modules'] if 'inputs' in m]
151
    num_config_inputs = len(charts_with_inputs[0]['inputs']['options'])
152
    assert num_config_inputs == 5  # Sanity check
153
    assert len(charts_with_inputs) == 1
154
    assert len(dom.find('.chart-inputs')) == 1
155
    assert dom.find('.chart-inputs').hasClass('collapse')
156
    # There are 7 input fields generated for this particular json file.
157
    assert len(dom.find('.chart-inputs form input')) == 7
158
159
160
def test_view_valid_dashboard_inputs_form_counts(monkeypatch, client):
161
    _, test = client
162
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
163
    view = get_json_config('inputs.json')
164
    readfunc = read(override=dict(view))
165
    monkeypatch.setattr(adapter, 'read', readfunc)
166
    res = test.get(url_for('jsondash.view', c_id=view['id']))
167
    dom = pq(res.data)
168
    charts_with_inputs = [m for m in view['modules'] if 'inputs' in m]
169
    input_options = charts_with_inputs[0]['inputs']['options']
170
    radio_opts = [o for o in input_options if o['type'] == 'radio'][0]
171
    radio_opts = radio_opts['options']
172
    assert len(dom.find('.chart-inputs form .input-radio')) == len(radio_opts)
173
    select = [o for o in input_options if o['type'] == 'select']
174
    assert len(dom.find('.chart-inputs form select')) == len(select)
175
    options = select[0]['options']
176
    assert len(dom.find('.chart-inputs form select option')) == len(options)
177
    numbers = [inp for inp in input_options if inp['type'] == 'number']
178
    assert len(dom.find('.chart-inputs [type="number"]')) == len(numbers)
179
    text = [inp for inp in input_options if inp['type'] == 'text']
180
    assert len(dom.find('.chart-inputs [type="text"]')) == len(text)
181
    checkbox = [inp for inp in input_options if inp['type'] == 'checkbox']
182
    assert len(dom.find('.chart-inputs [type="checkbox"]')) == len(checkbox)
183
184
185
def test_get_view_valid_modules_valid_dash_title(monkeypatch, client):
186
    _, test = client
187
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
188
    view = get_json_config('inputs.json')
189
    readfunc = read(override=dict(view))
190
    monkeypatch.setattr(adapter, 'read', readfunc)
191
    res = test.get(url_for('jsondash.view', c_id=view['id']))
192
    dom = pq(res.data)
193
    assert dom.find('.dashboard-title').text() == view['name']
194
195
196
def test_create_valid(monkeypatch, client):
197
    _, test = client
198
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
199
    res = test.post(
200
        url_for('jsondash.create'),
201
        data=dict(name='mydash-valid'),
202
        follow_redirects=True)
203
    dom = pq(res.data)
204
    flash_msg = 'Created new dashboard "mydash-valid"'
205
    assert dom.find('.alert-info').text() == flash_msg
206
207
208
@pytest.mark.invalid_id_redirect
209
def test_get_view_invalid_id_redirect(monkeypatch, client):
210
    _, test = client
211
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
212
    res = test.get(url_for('jsondash.view', c_id='123'))
213
    assert REDIRECT_MSG in str(res.data)
214
215
216
@pytest.mark.invalid_id_redirect
217
def test_clone_invalid_id_redirect(monkeypatch, client):
218
    _, test = client
219
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
220
    res = test.post(url_for('jsondash.clone', c_id='123'))
221
    assert REDIRECT_MSG in str(res.data)
222
223
224
@pytest.mark.invalid_id_redirect
225
def test_delete_invalid_id_redirect(monkeypatch, client):
226
    _, test = client
227
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
228
    res = test.post(
229
        url_for('jsondash.delete', c_id='123'))
230
    assert REDIRECT_MSG in str(res.data)
231
232
233
@pytest.mark.update_raw
234
@pytest.mark.invalid_id_redirect
235
def test_update_invalid_id_redirect(monkeypatch, client):
236
    _, test = client
237
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
238
    res = test.post(url_for('jsondash.update', c_id='123'))
239
    assert REDIRECT_MSG in str(res.data)
240
241
242
def test_clone_valid(monkeypatch, client):
243
    _, test = client
244
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
245
    assert len(read()) == 0
246
    res = test.post(url_for('jsondash.create'),
247
                    data=dict(name='mydash', modules=[]),
248
                    follow_redirects=True)
249
    dom = pq(res.data)
250
    new_id = read()[0]['id']
251
    assert read()[0]['name'] == 'mydash'
252
    flash_msg = 'Created new dashboard "mydash"'
253
    assert dom.find('.alert-info').text() == flash_msg
254
    assert len(read()) == 1
255
    assert read()[0]['name'] == 'mydash'
256
    res = test.post(
257
        url_for('jsondash.clone', c_id=new_id),
258
        follow_redirects=True)
259
    dom = pq(res.data)
260
    flash_msg = 'Created new dashboard clone "Clone of mydash"'
261
    assert flash_msg in dom.find('.alert').text()
262
    assert len(read()) == 2
263
264
265
def test_delete_valid(monkeypatch, client):
266
    _, test = client
267
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
268
    view = dict(name='mydash', modules=[])
269
    readfunc = read(override=dict(view))
270
    monkeypatch.setattr(adapter, 'read', readfunc)
271
    assert not read()
272
    # Create first one.
273
    res = test.post(url_for('jsondash.create'),
274
                    data=view,
275
                    follow_redirects=True)
276
    assert len(read()) == 1
277
    view_id = read()[0]['id']
278
    dom = pq(res.data)
279
    flash_msg = 'Created new dashboard "mydash"'
280
    assert dom.find('.alert-info').text() == flash_msg
281
    assert len(read()) == 1
282
    res = test.post(url_for('jsondash.delete', c_id=view_id),
283
                    follow_redirects=True)
284
    dom = pq(res.data)
285
    flash_msg = 'Deleted dashboard "{}"'.format(view_id)
286
    assert dom.find('.alert-info').text() == flash_msg
287
    assert len(read()) == 0
288
289
290
@pytest.mark.update_raw
291
def test_update_edit_raw_invalid(monkeypatch, client):
292
    _, test = client
293
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
294
    view = get_json_config('inputs.json')
295
    readfunc = read(override=dict(view))
296
    monkeypatch.setattr(adapter, 'read', readfunc)
297
    res = test.post(
298
        url_for('jsondash.update', c_id=view['id']),
299
        data={'edit-raw': 'on'},
300
        follow_redirects=True)
301
    dom = pq(res.data)
302
    assert 'Error: Invalid JSON config.' in dom.find('.alert-danger').text()
303
304
305
@pytest.mark.schema
306
@pytest.mark.update_raw
307
@pytest.mark.parametrize('field', [
308
    'type',
309
    'family',
310
])
311
def test_update_edit_raw_invalidschema_missing_x(field, monkeypatch,
312
                                                 client):
313
    _, test = client
314
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
315
    module = dict(
316
        name='foo', width=1, height=1,
317
        guid='a-b-c-d-e', dataSource='...',
318
        family='C3', type='line',
319
    )
320
    view = dict(id='a-b-c-d-e', name='foo', modules=[module])
321
    del module[field]
322
    readfunc = read(override=dict(view))
323
    monkeypatch.setattr(adapter, 'read', readfunc)
324
    res = test.post(
325
        url_for('jsondash.update', c_id=view['id']),
326
        data={'edit-raw': 'on', 'config': json.dumps(view)},
327
        follow_redirects=True)
328
    dom = pq(res.data)
329
    err_msg = "{'" + field + "': ['required field']"
330
    assert err_msg in dom.find('.alert-danger').text()
331
332
333
@pytest.mark.update_raw
334
def test_update_edit_raw_valid(monkeypatch, client):
335
    _, test = client
336
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
337
    assert not read()
338
    res = test.post(
339
        url_for('jsondash.create'),
340
        data=dict(
341
            id='a-b-c-d-e',
342
            layout='freeform',
343
            name='newname', date='', modules=[]),
344
        follow_redirects=True)
345
    assert len(read()) == 1
346
    view_id = read()[0]['id']
347
    data = {
348
        'date': '',
349
        'layout': 'freeform',
350
        'id': 'a-b-c-d-e',
351
        'name': 'foo', 'modules': []}
352
    view = json.dumps(data)
353
    readfunc = read(override=dict(data))
354
    monkeypatch.setattr(adapter, 'read', readfunc)
355
    res = test.post(
356
        url_for('jsondash.update', c_id=view_id),
357
        data={'config': view, 'edit-raw': 'on'},
358
        follow_redirects=True)
359
    dom = pq(res.data)
360
    flash_msg = 'Updated view "{}"'.format(view_id)
361
    assert dom.find('.alert-info').text() == flash_msg
362
    assert len(read()) == 1
363
364
365
@pytest.mark.update
366
def test_update_valid(monkeypatch, client):
367
    _, test = client
368
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
369
    assert not read()
370
    res = test.post(
371
        url_for('jsondash.create'),
372
        data=dict(mode='grid', name='newname', modules=[]),
373
        follow_redirects=True)
374
    assert res.status_code == 200
375
    assert len(read()) == 1
376
    view_id = read()[0]['id']
377
    res = test.post(
378
        url_for('jsondash.update', c_id=view_id),
379
        data=dict(mode='grid', name='newname'),
380
        follow_redirects=True)
381
    dom = pq(res.data)
382
    flash_msg = 'Updated view "{}"'.format(view_id)
383
    assert dom.find('.alert-info').text() == flash_msg
384
    assert len(read()) == 1
385
386
387
@pytest.mark.update
388
def test_update_invalid_swap_freeform_to_grid_no_row(monkeypatch, client):
389
    _, test = client
390
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
391
    assert not read()
392
    dash_data = dict(
393
        name='newname',
394
        mode='freeform',
395
        module_foo=json.dumps(
396
            dict(dataSource='...', width=1, height=1,
397
                 name='foo', family='C3', type='line')),
398
        module_bar=json.dumps(
399
            dict(dataSource='...', width=1, height=1,
400
                 name='foo', family='C3', type='line')),
401
    )
402
    res = test.post(url_for('jsondash.create'),
403
                    data=dash_data,
404
                    follow_redirects=True)
405
    assert res.status_code == 200
406
    assert len(read()) == 1
407
    view_id = read()[0]['id']
408 View Code Duplication
    dash_data.update(mode='grid')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
409
    res = test.post(url_for('jsondash.update', c_id=view_id),
410
                    data=dash_data,
411
                    follow_redirects=True)
412
    dom = pq(res.data)
413
    flash_msg = ('Cannot use grid layout without specifying row(s)! '
414
                 'Edit JSON manually to override this.')
415
    assert flash_msg in dom.find('.alert-danger').text()
416
    assert len(read()) == 1
417
418
419
def test_no_demo_mode(monkeypatch, client):
420
    _, test = client
421
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
422 View Code Duplication
    data = dict(name='newname', modules=[])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
423
    test.post(url_for('jsondash.create'), data=data, follow_redirects=True)
424
    view_id = read()[0]['id']
425
    url = url_for('jsondash.view', c_id=view_id)
426
    res = test.get(url)
427
    dom = pq(res.data)
428
    assert dom.find('.chart-header small > .btn')
429
    assert dom.find('.chart-header small > .btn').text().strip() == 'Back'
430
    assert dom.find('.chart-header .dropdown-toggle')
431
432
433
def test_demo_mode(monkeypatch, client):
434
    # Test that certain UI elements are removed when in demo mode.
435
    _, test = client
436
    monkeypatch.setattr(charts_builder, 'auth', auth_valid)
437
    data = dict(name='newname', modules=[])
438
    test.post(url_for('jsondash.create'), data=data, follow_redirects=True)
439
    view_id = read()[0]['id']
440
    url = url_for('jsondash.view', c_id=view_id) + '?jsondash_demo_mode=1'
441
    res = test.get(url)
442
    dom = pq(res.data)
443
    assert not dom.find('.chart-header > small .btn')
444
    assert not dom.find('.chart-header .dropdown-toggle')
445
446
447
def test_correct_charts_count(monkeypatch, client):
448
    app, test = client
449
    data = dict(
450
        mode='grid',
451
        name='Some dashboard - lots of cols and rows',
452
    )
453
    data.update({
454
        'module_{}'.format(i): make_chart(row=1) for i in range(5)
455
    })
456
    dom = setup_dashboard(monkeypatch, app, test, data)
457
    container = dom.find('#container')
458
    assert len(container.find('.item.widget')) == 5
459
    assert len(container.find('.item.widget').find('.widget-title-text')) == 5
460