import unittest import mockredis from nose.tools import eq_ from splinter import Browser from helix import main from helix.constants import redis_constant from helix.constants import sql_constant from helix.constants.anchor_type import AnchorType from helix.constants.system_type import SystemType from helix.constants.module_type import ModuleType from helix.models.sql.inverters import Inverter from helix.models.sql.power_monitors import PowerMonitor from helix.models.sql.power_stations import PowerStation from helix.models.sql.sites import Site from helix.models.sql.standalone_inverters import StandaloneInverter from helix.models.sql.users import User from test.test_helpers import assert_error, assert_no_error, test_db_session, reset_db_session class SiteCharacterizationTest(unittest.TestCase): @classmethod def setUpClass(cls): cls.test_db_session = test_db_session() @classmethod def tearDownClass(cls): cls.test_db_session.close_all() def setUp(self): redis_constant.redis_store = mockredis.mock_redis_client() sql_constant.sql_session_maker = lambda: self.test_db_session self.app = main.app.test_client() self.browser = Browser('flask', app=main.app) self.browser.visit('/site_characterization') def tearDown(self): self.test_db_session.rollback() reset_db_session(self.test_db_session) def fill_in_site_characterization_data(self, module_type=ModuleType.Cell96): self.browser.fill('project_name', 'Test Project Name') self.browser.fill('building_width', '200') self.browser.fill('building_height', '30') self.browser.fill('building_length', '75.5') self.browser.fill('wind_speed', '125') self.browser.fill('exposure_category', 'C') self.browser.fill('ballast_block_weight', '13') self.browser.fill('building_parapet_height', '0') self.browser.fill('max_system_pressure', '10') self.browser.fill('module_type', module_type.value) self.browser.fill('system_type', SystemType.singleTilt.value) self.browser.fill('anchor_type', AnchorType.EcoFasten.value) self.browser.fill('importance_factor', '1.5') self.browser.fill('design_spectral_response', '1') def test_page_displays_welcome_text(self): assert self.browser.is_text_present("Helix Calculator") def test_navigation_header_shows_user_on_first_step(self): assert self.browser.find_by_css('.navigation_header #step_1').has_class('active') assert not self.browser.find_by_css('.navigation_header #step_1').has_class('completed') def test_completing_site_characterization_step_updates_navigation_header(self): self.fill_in_site_characterization_data() self.browser.find_by_value('Next').first.click() assert self.browser.find_by_css('.navigation_header #step_2').has_class('active') assert not self.browser.find_by_css('.navigation_header #step_1').has_class('active') assert self.browser.find_by_css('.navigation_header #step_1').has_class('completed') self.browser.click_link_by_partial_text("Back") assert not self.browser.find_by_css('.navigation_header #step_2').has_class('active') assert self.browser.find_by_css('.navigation_header #step_1').has_class('active') assert self.browser.find_by_css('.navigation_header #step_1').has_class('completed') def test_entering_site_characterization_data_saves_entered_values(self): self.fill_in_site_characterization_data() # TODO: Fill in to change to 128 self.browser.find_by_value('Next').first.click() self.browser.click_link_by_partial_text("Back") eq_(self.browser.find_by_name('project_name').first.value, 'Test Project Name') eq_(self.browser.find_by_name('building_width').first.value, '200.0') eq_(self.browser.find_by_name('building_height').first.value, '30.0') eq_(self.browser.find_by_name('building_length').first.value, '75.5') eq_(self.browser.find_by_name('wind_speed').first.value, '125') eq_(self.browser.find_by_name('exposure_category').first.value, 'C') eq_(self.browser.find_by_name('ballast_block_weight').first.value, '13.0') eq_(self.browser.find_by_name('building_parapet_height').first.value, '0.0') eq_(self.browser.find_by_name('max_system_pressure').first.value, '10.0') eq_(self.browser.find_by_name('module_type').first.value, ModuleType.Cell96.value) eq_(self.browser.find_by_name('system_type').first.value, SystemType.singleTilt.value) eq_(self.browser.find_by_name('anchor_type').first.value, AnchorType.EcoFasten.value) eq_(self.browser.find_by_name('importance_factor').first.value, '1.5') eq_(self.browser.find_by_name('design_spectral_response').first.value, '1.0') def test_form_shows_wind_speed_link(self): info_link = self.browser.find_by_css('#wind_speed_row a').first eq_(info_link.text, 'Look up') eq_(info_link['href'], 'http://windspeed.atcouncil.org/') def test_form_shows_seismic_link(self): info_link = self.browser.find_by_css('#design_spectral_response_row a').first eq_(info_link.text, 'Look up') eq_(info_link['href'], 'http://earthquake.usgs.gov/designmaps/us/application.php') def test_form_shows_exposure_category_link(self): info_link = self.browser.find_by_css('#exposure_category_row a').first eq_(info_link.text, 'More info') info_link.click() assert self.browser.is_text_present("Urban and suburban areas, wooded areas") def test_all_site_charactarization_values_are_required(self): self.browser.fill('ballast_block_weight', '') self.browser.fill('max_system_pressure', '') self.browser.find_by_value('Next').first.click() assert_error(self.browser, 'project_name', 'Project Name is required.') assert_error(self.browser, 'building_height', 'Not a valid decimal value') assert_error(self.browser, 'building_width', 'Not a valid decimal value') assert_error(self.browser, 'building_length', 'Not a valid decimal value') assert_error(self.browser, 'wind_speed', 'Not a valid integer value') assert_error(self.browser, 'ballast_block_weight', 'Not a valid decimal value') assert_error(self.browser, 'building_parapet_height', 'Not a valid decimal value') assert_error(self.browser, 'max_system_pressure', 'Not a valid decimal value') assert_error(self.browser, 'design_spectral_response', 'Not a valid decimal value') def test_characterization_values_not_overwritten_when_Nextting_invalid_request(self): self.browser.fill('project_name', '') self.browser.fill('building_width', '-1') self.browser.fill('building_height', '-10') self.browser.fill('building_length', 'hi') self.browser.fill('wind_speed', '400') self.browser.fill('exposure_category', 'D') self.browser.fill('ballast_block_weight', '40') self.browser.fill('building_parapet_height', '-1') self.browser.fill('max_system_pressure', '0') self.browser.fill('system_type', SystemType.dualTilt.value) self.browser.fill('module_type', ModuleType.Cell128.value) self.browser.fill('anchor_type', AnchorType.OMG_PowerGrip.value) self.browser.fill('design_spectral_response', '-2') self.browser.find_by_value('Next').first.click() eq_(self.browser.find_by_name('project_name').first.value, '') eq_(self.browser.find_by_name('building_width').first.value, '-1') eq_(self.browser.find_by_name('building_height').first.value, '-10') eq_(self.browser.find_by_name('building_length').first.value, 'hi') eq_(self.browser.find_by_name('wind_speed').first.value, '400') eq_(self.browser.find_by_name('exposure_category').first.value, 'D') eq_(self.browser.find_by_name('ballast_block_weight').first.value, '40') eq_(self.browser.find_by_name('building_parapet_height').first.value, '-1') eq_(self.browser.find_by_name('max_system_pressure').first.value, '0') eq_(self.browser.find_by_name('system_type').first.value, SystemType.dualTilt.value) eq_(self.browser.find_by_name('module_type').first.value, ModuleType.Cell128.value) eq_(self.browser.find_by_name('anchor_type').first.value, AnchorType.OMG_PowerGrip.value) eq_(self.browser.find_by_name('design_spectral_response').first.value, '-2') def test_wind_speed_value_must_be_in_range(self): self.browser.fill('wind_speed', '90') self.browser.find_by_value('Next').first.click() assert_error(self.browser, 'wind_speed', 'Number must be between 100 and 200.') def test_ballast_block_weight_value_must_be_in_range(self): self.browser.fill('ballast_block_weight', '90') self.browser.find_by_value('Next').first.click() assert_error(self.browser, 'ballast_block_weight', 'Number must be between 12 and 20.') def test_building_dimensions_must_be_non_negative(self): self.browser.fill('building_width', '-4') self.browser.fill('building_height', '-10') self.browser.fill('building_length', '-1') self.browser.fill('building_parapet_height', '-3') self.browser.find_by_value('Next').first.click() assert_error(self.browser, 'building_height', 'Number must be at least 0.') assert_error(self.browser, 'building_width', 'Number must be at least 0.') assert_error(self.browser, 'building_length', 'Number must be at least 0.') assert_error(self.browser, 'building_parapet_height', 'Number must be at least 0.') def test_transition_distance_must_be_filled_out_for_interpolating_exposure_categories(self): self.browser.fill('exposure_category', 'B to C') self.browser.find_by_value('Next').first.click() assert_error(self.browser, 'exposure_category_transition_distance', 'Number must be at least 1.') def test_transition_distance_must_be_greater_than_0_for_interpolating_exposure_categories(self): self.browser.fill('exposure_category', 'B to C') self.browser.fill('exposure_category_transition_distance', '-10') self.browser.find_by_value('Next').first.click() assert_error(self.browser, 'exposure_category_transition_distance', 'Number must be at least 1.') def test_transition_distance_standard_categories_does_not_need_to_be_filled_out(self): self.browser.fill('exposure_category', 'B') self.browser.find_by_value('Next').first.click() assert_no_error(self.browser, 'exposure_category_transition_distance') def test_max_system_pressure_must_be_non_negative(self): self.browser.fill('max_system_pressure', '-2') self.browser.find_by_value('Next').first.click() assert_error(self.browser, 'max_system_pressure', 'Number must be at least 0.') def test_design_spectral_response_must_be_in_range(self): self.browser.fill('design_spectral_response', '-1') self.browser.find_by_value('Next').first.click() assert_error(self.browser, 'design_spectral_response', 'Number must be between 0 and 5.') def test_building_dimensions_allow_zero(self): self.browser.fill('building_width', '0') self.browser.fill('building_height', '0') self.browser.fill('building_length', '0') self.browser.find_by_value('Next').first.click() assert_no_error(self.browser, 'building_width') assert_no_error(self.browser, 'building_height') assert_no_error(self.browser, 'building_length') def test_ballast_block_weight_defaults_to_14(self): eq_(self.browser.find_by_name('ballast_block_weight').first.value, '14.0') def test_max_system_pressure_defaults_to_10(self): eq_(self.browser.find_by_name('max_system_pressure').first.value, '12.0') def test_system_type_defaults_to_dual_tilt(self): eq_(self.browser.find_by_name('system_type').first.value, SystemType.dualTilt.value) def test_module_type_defaults_to_96_cell(self): eq_(self.browser.find_by_name('module_type').first.value, ModuleType.Cell96.value) def test_exposure_transition_distance_defaults_to_zero(self): eq_(self.browser.find_by_name('exposure_category_transition_distance').first.value, '0')