# Copyright 2019 Mike Shoup # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import xml.etree.ElementTree as ET from humulus.styles import import_styles, sub_to_doc, get_styles_list COMPLETE_STYLE = ''' Test Style Smelly Good looking Good tasting Good feeling Refreshing Comments Old Grains, Hops, and Water Comparison Examples one, two 1 2 1.010 1.020 1.000 1.010 1 2 1 2 ''' INCOMPLETE_STYLE = ''' Test Style Smelly Good looking Good tasting Good feeling Refreshing ''' TEST_XML = ''' Test Style Smelly Good looking Good tasting Good feeling Refreshing ''' def test_sub_to_doc(): assert sub_to_doc(ET.fromstring(COMPLETE_STYLE)) == { '_id': '1A', '$type': 'style', 'name': 'Test Style', 'aroma': 'Smelly', 'appearance': 'Good looking', 'flavor': 'Good tasting', 'mouthfeel': 'Good feeling', 'impression': 'Refreshing', 'comments': 'Comments', 'history': 'Old', 'ingredients': 'Grains, Hops, and Water', 'comparison': 'Comparison', 'examples': 'Examples', 'tags': ['one', 'two'], 'ibu': {'low': '1', 'high': '2'}, 'og': {'low': '1.010', 'high': '1.020'}, 'fg': {'low': '1.000', 'high': '1.010'}, 'srm': {'low': '1', 'high': '2'}, 'abv': {'low': '1', 'high': '2'} } assert sub_to_doc(ET.fromstring(INCOMPLETE_STYLE)) == { '_id': '2B', '$type': 'style', 'name': 'Test Style', 'aroma': 'Smelly', 'appearance': 'Good looking', 'flavor': 'Good tasting', 'mouthfeel': 'Good feeling', 'impression': 'Refreshing', 'ibu': {'low': '0', 'high': '100'}, 'og': {'low': '1.0', 'high': '1.2'}, 'fg': {'low': '1.0', 'high': '1.2'}, 'srm': {'low': '0', 'high': '100'}, 'abv': {'low': '0', 'high': '100'} } def test_import_styles(monkeypatch): class PutRecorder: doc = None class MockDB: db = {} def fake_get_db(): return MockDB.db def fake_put_doc(doc): PutRecorder.doc = doc def fake_requests_get(url): class TestXML: text = TEST_XML return TestXML monkeypatch.setattr('requests.get', fake_requests_get) monkeypatch.setattr('humulus.styles.get_db', fake_get_db) monkeypatch.setattr('humulus.styles.put_doc', fake_put_doc) import_styles(None) assert PutRecorder.doc == {'$type': 'style', '_id': '1A', 'abv': {'high': '100', 'low': '0'}, 'appearance': 'Good looking', 'aroma': 'Smelly', 'fg': {'high': '1.2', 'low': '1.0'}, 'flavor': 'Good tasting', 'ibu': {'high': '100', 'low': '0'}, 'impression': 'Refreshing', 'mouthfeel': 'Good feeling', 'name': 'Test Style', 'og': {'high': '1.2', 'low': '1.0'}, 'srm': {'high': '100', 'low': '0'} } MockDB.db = {'1A': ''} PutRecorder.doc = None import_styles(None) assert PutRecorder.doc is None def test_import_command(runner, monkeypatch): class Recorder: called = False def fake_import_styles(url): Recorder.called = True monkeypatch.setattr('humulus.styles.import_styles', fake_import_styles) result = runner.invoke(args=['import-styles']) assert Recorder.called assert 'Imported BJCP styles.' in result.output def test_get_styles_choices(app): """Test success in getting list of styles.""" with app.app_context(): styles = get_styles_list() assert styles == [ ['', ''], ['1A', '1A Test Style'] ] def test_index(auth, client): """Test success in retrieving index.""" # Test not logged in response = client.get('/styles/') assert response.status_code == 302 # Login and test get auth.login() response = client.get('/styles/') assert response.status_code == 200 assert b'1A' in response.data assert b'Test Style' in response.data # Test for bad request response = client.get('/styles/?sort_by=foobar') assert response.status_code == 400 def test_info(auth, client): """Test success in retrieving a style's info page""" # Test not logged in response = client.get('/styles/info/1A') assert response.status_code == 302 # Login and test auth.login() response = client.get('/styles/info/1A') assert response.status_code == 200 assert b'1A' in response.data assert b'Test Style' in response.data def test_recipes(client): """Test success in retrieving list of recipes matching style.""" response = client.get('/styles/info/1A/recipes') assert response.status_code == 200 assert b'Awesome Beer' in response.data def test_info_json(auth, client): """Test success in retrieving a style's json document.""" # Test not logged in response = client.get('/styles/info/1A/json') assert response.status_code == 302 # Login and test auth.login() response = client.get('/styles/info/1A/json') assert response.status_code == 200 assert response.is_json assert response.get_json()['name'] == 'Test Style' # Test for specs only response = client.get('/styles/info/1A/json?specs=y') assert response.status_code == 200 assert response.is_json assert 'name' not in response.get_json()