2025-01-11 21:35:06 -06:00
|
|
|
# -*- coding: utf-8; -*-
|
|
|
|
|
|
|
|
import datetime
|
|
|
|
from unittest.mock import patch, MagicMock
|
|
|
|
|
|
|
|
from wuttjamaican.reports import Report
|
|
|
|
|
|
|
|
import colander
|
|
|
|
from pyramid.httpexceptions import HTTPNotFound
|
|
|
|
|
|
|
|
from wuttaweb.views import reports as mod
|
|
|
|
from wuttaweb.testing import WebTestCase
|
|
|
|
|
|
|
|
|
|
|
|
class SomeRandomReport(Report):
|
|
|
|
"""
|
|
|
|
This report shows something random.
|
|
|
|
"""
|
|
|
|
report_key = 'testing_some_random'
|
|
|
|
report_title = "Random Test Report"
|
|
|
|
|
|
|
|
def add_params(self, schema):
|
|
|
|
|
|
|
|
schema.add(colander.SchemaNode(
|
|
|
|
colander.String(),
|
|
|
|
name='foo',
|
|
|
|
missing=colander.null))
|
|
|
|
|
|
|
|
schema.add(colander.SchemaNode(
|
|
|
|
colander.Date(),
|
|
|
|
name='start_date',
|
|
|
|
missing=colander.null))
|
|
|
|
|
|
|
|
def get_output_columns(self):
|
|
|
|
return ['foo']
|
|
|
|
|
|
|
|
def make_data(self, params, **kwargs):
|
|
|
|
return {
|
|
|
|
'output_title': "Testing Output",
|
|
|
|
'data': [{'foo': 'bar'}],
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class TestReportViews(WebTestCase):
|
|
|
|
|
|
|
|
def make_view(self):
|
|
|
|
return mod.ReportView(self.request)
|
|
|
|
|
|
|
|
def test_includeme(self):
|
|
|
|
self.pyramid_config.include('wuttaweb.views.reports')
|
|
|
|
|
|
|
|
def test_get_grid_data(self):
|
|
|
|
view = self.make_view()
|
2025-01-11 23:55:40 -06:00
|
|
|
providers = dict(self.app.providers)
|
|
|
|
providers['wuttatest'] = MagicMock(report_modules=['tests.views.test_reports'])
|
|
|
|
with patch.object(self.app, 'providers', new=providers):
|
|
|
|
|
|
|
|
data = view.get_grid_data()
|
|
|
|
self.assertIsInstance(data, list)
|
|
|
|
self.assertTrue(data) # 1+ reports
|
2025-01-11 21:35:06 -06:00
|
|
|
|
|
|
|
def test_normalize_report(self):
|
|
|
|
view = self.make_view()
|
|
|
|
report = SomeRandomReport(self.config)
|
|
|
|
normal = view.normalize_report(report)
|
|
|
|
help_text = normal.pop('help_text').strip()
|
|
|
|
self.assertEqual(help_text, "This report shows something random.")
|
|
|
|
self.assertEqual(normal, {
|
|
|
|
'report_key': 'testing_some_random',
|
|
|
|
'report_title': "Random Test Report",
|
|
|
|
})
|
|
|
|
|
|
|
|
def test_configure_grid(self):
|
|
|
|
view = self.make_view()
|
|
|
|
grid = view.make_model_grid()
|
|
|
|
self.assertIn('report_title', grid.searchable_columns)
|
|
|
|
self.assertIn('help_text', grid.searchable_columns)
|
|
|
|
|
|
|
|
def test_get_instance(self):
|
|
|
|
view = self.make_view()
|
|
|
|
providers = {
|
|
|
|
'wuttatest': MagicMock(report_modules=['tests.views.test_reports']),
|
|
|
|
}
|
|
|
|
with patch.object(self.app, 'providers', new=providers):
|
|
|
|
|
|
|
|
# normal
|
|
|
|
with patch.object(self.request, 'matchdict', new={'report_key': 'testing_some_random'}):
|
|
|
|
report = view.get_instance()
|
|
|
|
self.assertIsInstance(report, dict)
|
|
|
|
self.assertEqual(report['report_key'], 'testing_some_random')
|
|
|
|
self.assertEqual(report['report_title'], "Random Test Report")
|
|
|
|
|
|
|
|
# not found
|
|
|
|
with patch.object(self.request, 'matchdict', new={'report_key': 'this-should_notEXIST'}):
|
|
|
|
self.assertRaises(HTTPNotFound, view.get_instance)
|
|
|
|
|
|
|
|
def test_get_instance_title(self):
|
|
|
|
view = self.make_view()
|
|
|
|
result = view.get_instance_title({'report_title': 'whatever'})
|
|
|
|
self.assertEqual(result, 'whatever')
|
|
|
|
|
|
|
|
def test_view(self):
|
|
|
|
self.pyramid_config.add_route('home', '/')
|
|
|
|
self.pyramid_config.add_route('login', '/auth/login')
|
|
|
|
self.pyramid_config.add_route('reports', '/reports/')
|
|
|
|
self.pyramid_config.add_route('reports.view', '/reports/{report_key}')
|
|
|
|
view = self.make_view()
|
|
|
|
providers = dict(self.app.providers)
|
|
|
|
providers['wuttatest'] = MagicMock(report_modules=['tests.views.test_reports'])
|
|
|
|
with patch.object(self.app, 'providers', new=providers):
|
|
|
|
with patch.object(self.request, 'matchdict', new={'report_key': 'testing_some_random'}):
|
|
|
|
|
|
|
|
# initial view
|
|
|
|
response = view.view()
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
# nb. there's a button in there somewhere, but no output title
|
|
|
|
self.assertIn("Run Report", response.text)
|
|
|
|
self.assertNotIn("Testing Output", response.text)
|
|
|
|
|
|
|
|
# run the report
|
|
|
|
with patch.object(self.request, 'GET', new={
|
|
|
|
'__start__': 'start_date:mapping',
|
|
|
|
'date': '2025-01-11',
|
|
|
|
'__end__': 'start_date',
|
|
|
|
}):
|
|
|
|
response = view.view()
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
# nb. there's a button in there somewhere, *and* an output title
|
|
|
|
self.assertIn("Run Report", response.text)
|
|
|
|
self.assertIn("Testing Output", response.text)
|
|
|
|
|
|
|
|
def test_configure_form(self):
|
|
|
|
view = self.make_view()
|
|
|
|
providers = dict(self.app.providers)
|
|
|
|
providers['wuttatest'] = MagicMock(report_modules=['tests.views.test_reports'])
|
|
|
|
with patch.object(self.app, 'providers', new=providers):
|
|
|
|
|
|
|
|
with patch.object(self.request, 'matchdict', new={'report_key': 'testing_some_random'}):
|
|
|
|
report = view.get_instance()
|
|
|
|
form = view.make_model_form(report)
|
|
|
|
self.assertIn('help_text', form.readonly_fields)
|
|
|
|
self.assertIn('foo', form)
|
|
|
|
|
|
|
|
def test_normalize_columns(self):
|
|
|
|
view = self.make_view()
|
|
|
|
|
|
|
|
columns = view.normalize_columns(['foo'])
|
|
|
|
self.assertEqual(columns, [
|
|
|
|
{'name': 'foo', 'label': 'foo'},
|
|
|
|
])
|
|
|
|
|
|
|
|
columns = view.normalize_columns([{'name': 'foo'}])
|
|
|
|
self.assertEqual(columns, [
|
|
|
|
{'name': 'foo', 'label': 'foo'},
|
|
|
|
])
|
|
|
|
|
|
|
|
columns = view.normalize_columns([{'name': 'foo', 'label': "FOO"}])
|
|
|
|
self.assertEqual(columns, [
|
|
|
|
{'name': 'foo', 'label': 'FOO'},
|
|
|
|
])
|
|
|
|
|
|
|
|
columns = view.normalize_columns([{'name': 'foo', 'label': "FOO", 'numeric': True}])
|
|
|
|
self.assertEqual(columns, [
|
|
|
|
{'name': 'foo', 'label': 'FOO', 'numeric': True},
|
|
|
|
])
|
|
|
|
|
|
|
|
def test_run_report(self):
|
|
|
|
view = self.make_view()
|
|
|
|
providers = dict(self.app.providers)
|
|
|
|
providers['wuttatest'] = MagicMock(report_modules=['tests.views.test_reports'])
|
|
|
|
with patch.object(self.app, 'providers', new=providers):
|
|
|
|
|
|
|
|
with patch.object(self.request, 'matchdict', new={'report_key': 'testing_some_random'}):
|
|
|
|
report = view.report_handler.get_report('testing_some_random')
|
|
|
|
normal = view.normalize_report(report)
|
|
|
|
form = view.make_model_form(normal)
|
|
|
|
|
|
|
|
# typical
|
|
|
|
context = view.run_report(report, {'form': form})
|
|
|
|
self.assertEqual(sorted(context['report_params']), ['foo', 'start_date'])
|
|
|
|
self.assertEqual(context['report_data'], {
|
|
|
|
'output_title': "Testing Output",
|
|
|
|
'data': [{'foo': 'bar'}],
|
|
|
|
})
|
|
|
|
self.assertIn('report_generated', context)
|
|
|
|
|
|
|
|
# invalid params
|
|
|
|
with patch.object(self.request, 'GET', new={'start_date': 'NOT_GOOD'}):
|
|
|
|
context = view.run_report(report, {'form': form})
|
|
|
|
self.assertNotIn('report_params', context)
|
|
|
|
self.assertNotIn('report_data', context)
|
|
|
|
self.assertNotIn('report_generated', context)
|
|
|
|
|
|
|
|
# custom formatter
|
|
|
|
with patch.object(report, 'get_output_columns') as get_output_columns:
|
|
|
|
get_output_columns.return_value = [
|
|
|
|
'foo',
|
|
|
|
{'name': 'start_date',
|
|
|
|
'formatter': lambda val: "FORMATTED VALUE"},
|
|
|
|
]
|
|
|
|
|
|
|
|
with patch.object(report, 'make_data') as make_data:
|
|
|
|
make_data.return_value = [
|
|
|
|
{'foo': 'bar', 'start_date': datetime.date(2025, 1, 11)},
|
|
|
|
]
|
|
|
|
|
|
|
|
context = view.run_report(report, {'form': form})
|
|
|
|
get_output_columns.assert_called_once_with()
|
|
|
|
self.assertEqual(len(context['report_columns']), 2)
|
|
|
|
self.assertEqual(context['report_columns'][0]['name'], 'foo')
|
|
|
|
self.assertEqual(context['report_columns'][1]['name'], 'start_date')
|
|
|
|
self.assertEqual(context['report_data'], {
|
|
|
|
'output_title': "Random Test Report",
|
|
|
|
'data': [{'foo': 'bar', 'start_date': 'FORMATTED VALUE'}],
|
|
|
|
})
|
|
|
|
|
|
|
|
def test_download_data(self):
|
|
|
|
view = self.make_view()
|
|
|
|
providers = dict(self.app.providers)
|
|
|
|
providers['wuttatest'] = MagicMock(report_modules=['tests.views.test_reports'])
|
|
|
|
with patch.object(self.app, 'providers', new=providers):
|
|
|
|
with patch.object(self.request, 'matchdict', new={'report_key': 'testing_some_random'}):
|
|
|
|
|
|
|
|
params, columns, data = view.get_download_data()
|
|
|
|
self.assertEqual(params, {})
|
|
|
|
self.assertEqual(columns, [{'name': 'foo', 'label': 'foo'}])
|
|
|
|
self.assertEqual(data, {
|
|
|
|
'output_title': "Testing Output",
|
|
|
|
'data': [{'foo': 'bar'}],
|
|
|
|
})
|
|
|
|
|
|
|
|
def test_download_path(self):
|
|
|
|
view = self.make_view()
|
|
|
|
data = {'output_title': "My Report"}
|
|
|
|
path = view.get_download_path(data, 'csv')
|
|
|
|
self.assertTrue(path.endswith('My Report.csv'))
|