import pytest from puppetboard import app from pypuppetdb.types import Node from puppetboard import default_settings from bs4 import BeautifulSoup class MockDbQuery(object): def __init__(self, responses): self.responses = responses def get(self, method, **kws): resp = None if method in self.responses: resp = self.responses[method].pop(0) return resp @pytest.fixture def mock_puppetdb_environments(mocker): environemnts = [ {'name': 'production'}, {'name': 'staging'} ] return mocker.patch.object(app.puppetdb, 'environments', return_value=environemnts) @pytest.fixture def mock_puppetdb_default_nodes(mocker): node_list = [ Node('_', 'node', report_timestamp='2013-08-01T09:57:00.000Z', latest_report_hash='1234567', catalog_timestamp='2013-08-01T09:57:00.000Z', facts_timestamp='2013-08-01T09:57:00.000Z',) ] return mocker.patch.object(app.puppetdb, 'nodes', return_value=node_list) @pytest.fixture def client(): client = app.app.test_client() return client def test_first_test(): assert app is not None, ("%s" % reg.app) def test_no_env(client, mock_puppetdb_environments): rv = client.get('/nonexsistenv/') assert rv.status_code == 404 def test_get_index(client, mocker, mock_puppetdb_environments, mock_puppetdb_default_nodes): query_data = { 'nodes': [[{'count': 10}]], 'resources': [[{'count': 40}]], } dbquery = MockDbQuery(query_data) mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get) rv = client.get('/') soup = BeautifulSoup(rv.data, 'html.parser') assert soup.title.contents[0] == 'Puppetboard' assert rv.status_code == 200 def test_offline_mode(client, mocker): app.app.config['OFFLINE_MODE'] = True mock_puppetdb_environments(mocker) mock_puppetdb_default_nodes(mocker) query_data = { 'nodes': [[{'count': 10}]], 'resources': [[{'count': 40}]], } dbquery = MockDbQuery(query_data) mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get) rv = client.get('/') soup = BeautifulSoup(rv.data, 'html.parser') assert soup.title.contents[0] == 'Puppetboard' for link in soup.find_all('link'): assert "//" not in link['href'] for script in soup.find_all('script'): if "src" in script.attrs: assert "//" not in script['src'] assert rv.status_code == 200 def test_default_node_view(client, mocker, mock_puppetdb_environments, mock_puppetdb_default_nodes): rv = client.get('/nodes') soup = BeautifulSoup(rv.data, 'html.parser') assert soup.title.contents[0] == 'Puppetboard' for label in ['failed', 'changed', 'unreported', 'noop']: vals = soup.find_all('a', {"class": "ui %s label status" % label}) assert len(vals) == 1 assert 'node-%s' % (label) in vals[0].attrs['href'] assert rv.status_code == 200 def test_radiator_view(client, mocker, mock_puppetdb_environments, mock_puppetdb_default_nodes): query_data = { 'nodes': [[{'count': 10}]], 'resources': [[{'count': 40}]], } dbquery = MockDbQuery(query_data) mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get) rv = client.get('/radiator') assert rv.status_code == 200 soup = BeautifulSoup(rv.data, 'html.parser') assert soup.title.contents[0] == 'Puppetboard' assert soup.h1 != 'Not Found' total = soup.find(class_='total') assert '10' in total.text def test_radiator_view_bad_env(client, mocker): mock_puppetdb_environments(mocker) mock_puppetdb_default_nodes(mocker) query_data = { 'nodes': [[{'count': 10}]], 'resources': [[{'count': 40}]], } dbquery = MockDbQuery(query_data) mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get) rv = client.get('/nothere/radiator') assert rv.status_code == 404 soup = BeautifulSoup(rv.data, 'html.parser') assert soup.title.contents[0] == 'Puppetboard' assert soup.h1.text == 'Not Found' def test_radiator_view_division_by_zero(client, mocker): mock_puppetdb_environments(mocker) mock_puppetdb_default_nodes(mocker) query_data = { 'nodes': [[{'count': 0}]], 'resources': [[{'count': 40}]], } dbquery = MockDbQuery(query_data) mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get) rv = client.get('/radiator') assert rv.status_code == 200 soup = BeautifulSoup(rv.data, 'html.parser') assert soup.title.contents[0] == 'Puppetboard' total = soup.find(class_='total') assert '0' in total.text