import unittest from unittest.mock import MagicMock from nose.tools import eq_ from helix.validators.csv_input_validator import CsvInputValidator from helix.constants.system_type import SystemType from helix.constants.module_type import ModuleType from helix.constants.file_validation_error import FileValidationError, FileValidationMessage class CsvInputValidatorTest(unittest.TestCase): def setUp(self): self.user_values = MagicMock() self.subject = CsvInputValidator(self.user_values) def should_have_error(self, result, message, row): eq_(result, FileValidationError(message, row)) def test_reports_single_tilt_file_is_invalid_when_dual_tilt(self): self.user_values.system_type.return_value = SystemType.dualTilt with open('test/fixtures/input_single_tilt.csv', 'r', newline='') as csv_file: cad_input = csv_file.read() self.should_have_error(self.subject.validate(cad_input), FileValidationMessage.DualTiltWindZone, 1) def test_reports_single_tilt_file_is_valid_when_single_tilt(self): self.user_values.system_type.return_value = SystemType.singleTilt with open('test/fixtures/input_single_tilt.csv', 'r', newline='') as csv_file: cad_input = csv_file.read() eq_(self.subject.validate(cad_input), None) def test_reports_dual_tilt_file_is_valid_when_dual_tilt(self): self.user_values.system_type.return_value = SystemType.dualTilt with open('test/fixtures/input_dual_tilt.csv', 'r', newline='') as csv_file: cad_input = csv_file.read() eq_(self.subject.validate(cad_input), None) def test_reports_dual_tilt_file_is_valid_when_single_tilt(self): # think about it. self.user_values.system_type.return_value = SystemType.singleTilt with open('test/fixtures/input_dual_tilt.csv', 'r', newline='') as csv_file: cad_input = csv_file.read() eq_(self.subject.validate(cad_input), None) def test_reports_invalid_wind_zones_when_single_tilt(self): self.user_values.system_type.return_value = SystemType.singleTilt with open('test/fixtures/invalid_wind_zone.csv', 'r', newline='') as csv_file: cad_input = csv_file.read() self.should_have_error(self.subject.validate(cad_input), FileValidationMessage.SingleTiltWindZone, 8) def test_reports_not_csv_files_as_invalid(self): self.should_have_error(self.subject.validate("What a Terrible File"), FileValidationMessage.InvalidHeaders, 0) self.should_have_error(self.subject.validate("What a Terrible File\r\nmalformed data!\r\n"), FileValidationMessage.InvalidHeaders, 0) def test_reports_no_rows_as_invalid(self): self.should_have_error(self.subject.validate("A\tB\tC\tD\tE\t\r\n"), FileValidationMessage.InvalidRowCount, 0) def test_reports_wrong_number_of_columns_in_a_row(self): self.user_values.system_type.return_value = SystemType.dualTilt with open('test/fixtures/invalid_coordinates.csv', 'r', newline='') as csv_file: cad_input = csv_file.read() self.should_have_error(self.subject.validate(cad_input), FileValidationMessage.Generic, 1) def test_reports_invalid_panel_types_when_finds_panel_type_less_than_1(self): self.user_values.system_type.return_value = SystemType.singleTilt with open('test/fixtures/invalid_panel_types_not_in_1-4.csv', 'r', newline='') as csv_file: cad_input = csv_file.read() self.should_have_error(self.subject.validate(cad_input), FileValidationMessage.PanelTypeOutOfBounds, 13) def test_reports_invalid_panel_types_when_finds_panel_type_greater_than_4(self): self.user_values.system_type.return_value = SystemType.singleTilt with open('test/fixtures/invalid_panel_types_more_than_4.csv', 'r', newline='') as csv_file: cad_input = csv_file.read() self.should_have_error(self.subject.validate(cad_input), FileValidationMessage.PanelTypeOutOfBounds, 14) def test_reports_invalid_panel_types_when_finds_less_than_4_corner_panel_types_per_subarray_in_single_tilt(self): self.user_values.system_type.return_value = SystemType.singleTilt with open('test/fixtures/invalid_panel_types_less_than_4_corner_panels.csv', 'r', newline='') as csv_file: cad_input = csv_file.read() self.should_have_error(self.subject.validate(cad_input), FileValidationMessage.PanelTypeTooFewCornersSingleTilt, None) def test_reports_invalid_panel_types_when_finds_less_than_2_corner_panel_types_per_subarray_in_dual_tilt(self): self.user_values.system_type.return_value = SystemType.dualTilt with open('test/fixtures/invalid_dual_tilt_panel_types_less_than_2_corner_panels.csv', 'r', newline='') as csv_file: cad_input = csv_file.read() self.should_have_error(self.subject.validate(cad_input), FileValidationMessage.PanelTypeTooFewCornersDualTilt, None) def test_reports_valid_when_finds_at_least_2_corner_panels_per_subarray_in_dual_tilt(self): self.user_values.system_type.return_value = SystemType.dualTilt with open('test/fixtures/input_small_dual_tilt.csv', 'r', newline='') as csv_file: cad_input = csv_file.read() eq_(self.subject.validate(cad_input), None) def test_reports_invalid_panel_types_when_finds_no_corner_panel_types_in_subarray(self): self.user_values.system_type.return_value = SystemType.dualTilt cad_input = "A\tB\tC\tD\tE\r\nhandle\tblock\tA\t3\t1\r\n" self.should_have_error(self.subject.validate(cad_input), FileValidationMessage.PanelTypeTooFewCornersDualTilt, None) def test_reports_too_close_when_finds_panel_too_close_to_another_panel(self): self.user_values.system_type.return_value = SystemType.dualTilt self.user_values.module_type.return_value = ModuleType.Cell96 self.user_values.module_system_constants().tolerance = 0.1 self.user_values.module_system_constants().panel_spacing = (88.24, 62.0) with open('test/fixtures/invalid_too_close.txt', 'r', newline='') as csv_file: cad_input = csv_file.read() self.should_have_error(self.subject.validate(cad_input), FileValidationMessage.PanelsTooClose , None)