def test_get_election0_xlsx(self):
        response = self.client.get(
            reverse('results-export'),
            { 'election': str(Election.objects.get(name='Election 0').id) }
        )

        self.assertEqual(response.status_code, 200)        

        self.assertEqual(
            response['Content-Disposition'],
            'attachment; filename="Election 0 Results.xlsx"'
        )

        wb = openpyxl.load_workbook(io.BytesIO(response.content))

        self.assertEqual(len(wb.worksheets), 1)

        # Check first worksheet.
        ws = wb.worksheets[0]

        self.assertEqual(wb.sheetnames[0], 'Election 0')

        row_count = ws.max_row
        col_count = ws.max_column
        self.assertEqual(row_count, 25)
        self.assertEqual(col_count, 5)

        self.assertEqual(str(ws.cell(1, 1).value), 'Election 0 Results')

        self.assertEqual(str(ws.cell(2, 1).value), 'Candidates')

        cellContents = [
            'Position 0',
            'Party 0',
            '0, 0',
            'Party 1',
            '3, 3',
            'Party 2',
            'None',
            'Position 1',
            'Party 0',
            '1, 1',
            'Party 1',
            '4, 4',
            'Party 2',
            'None',
            'Position 2',
            'Party 0',
            '2, 2',
            'Party 1',
            '5, 5',
            'Party 2',
            'None'
        ]
        for cellIndex, content in enumerate(cellContents, 5):
            self.assertEqual(str(ws.cell(cellIndex, 1).value), content) 

        self.assertEqual(str(ws.cell(2, 2).value), 'Number of Votes')

        self.assertEqual(str(ws.cell(3, 2).value), '0')

        self.assertEqual(str(ws.cell(4, 2).value), '0') # Section

        self.assertEqual(str(ws.cell(7, 2).value), '1')
        self.assertEqual(str(ws.cell(9, 2).value), '0')
        self.assertEqual(str(ws.cell(11, 2).value), 'N/A')
        self.assertEqual(str(ws.cell(14, 2).value), '2')
        self.assertEqual(str(ws.cell(16, 2).value), '0')
        self.assertEqual(str(ws.cell(18, 2).value), 'N/A')
        self.assertEqual(str(ws.cell(21, 2).value), '0')
        self.assertEqual(str(ws.cell(23, 2).value), '0')
        self.assertEqual(str(ws.cell(25, 2).value), 'N/A')

        self.assertEqual(str(ws.cell(4, 3).value), '1') # Section

        self.assertEqual(str(ws.cell(7, 3).value), '0')
        self.assertEqual(str(ws.cell(9, 3).value), '1')
        self.assertEqual(str(ws.cell(11, 2).value), 'N/A')
        self.assertEqual(str(ws.cell(14, 3).value), '0')
        self.assertEqual(str(ws.cell(16, 3).value), '0')
        self.assertEqual(str(ws.cell(18, 2).value), 'N/A')
        self.assertEqual(str(ws.cell(21, 3).value), '1')
        self.assertEqual(str(ws.cell(23, 3).value), '0')
        self.assertEqual(str(ws.cell(25, 2).value), 'N/A')

        self.assertEqual(str(ws.cell(3, 4).value), '1')

        self.assertEqual(str(ws.cell(4, 4).value), '2') # Section

        self.assertEqual(str(ws.cell(7, 4).value), '0')
        self.assertEqual(str(ws.cell(9, 4).value), '0')
        self.assertEqual(str(ws.cell(11, 2).value), 'N/A')
        self.assertEqual(str(ws.cell(14, 4).value), '0')
        self.assertEqual(str(ws.cell(16, 4).value), '1')
        self.assertEqual(str(ws.cell(18, 2).value), 'N/A')
        self.assertEqual(str(ws.cell(21, 4).value), '0')
        self.assertEqual(str(ws.cell(23, 4).value), '1')
        self.assertEqual(str(ws.cell(25, 2).value), 'N/A')

        self.assertEqual(str(ws.cell(3, 5).value), 'Total Votes')
        self.assertEqual(str(ws.cell(7, 5).value), '1')
        self.assertEqual(str(ws.cell(9, 5).value), '1')
        self.assertEqual(str(ws.cell(11, 2).value), 'N/A')
        self.assertEqual(str(ws.cell(14, 5).value), '2')
        self.assertEqual(str(ws.cell(16, 5).value), '1')
        self.assertEqual(str(ws.cell(18, 2).value), 'N/A')
        self.assertEqual(str(ws.cell(21, 5).value), '1')
        self.assertEqual(str(ws.cell(23, 5).value), '1')
        self.assertEqual(str(ws.cell(25, 2).value), 'N/A')
def find_storm_images_2d3d_myrorss(
        top_directory_name, first_spc_date_string, last_spc_date_string,
        reflectivity_heights_m_agl):
    """Locates files with 2-D and 3-D storm-centered radar images.

    Fields in 2-D images: low-level and mid-level azimuthal shear
    Field in 3-D images: reflectivity

    D = number of SPC dates in time period (`first_spc_date_string`...
        `last_spc_date_string`)

    :param top_directory_name: See doc for `find_storm_images_2d`.
    :param first_spc_date_string: Same.
    :param last_spc_date_string: Same.
    :param reflectivity_heights_m_agl: Same.
    :return: az_shear_file_name_matrix: D-by-2 numpy array of file paths.  Files
        in column 0 are low-level az shear; files in column 1 are mid-level az
        shear.
    :return: reflectivity_file_name_matrix: D-by-H numpy array of file paths,
        where H = number of reflectivity heights.
    """

    first_spc_date_unix_sec = time_conversion.spc_date_string_to_unix_sec(
        first_spc_date_string)
    last_spc_date_unix_sec = time_conversion.spc_date_string_to_unix_sec(
        last_spc_date_string)

    field_names = AZIMUTHAL_SHEAR_FIELD_NAMES + [radar_utils.REFL_NAME]

    storm_image_file_dict = storm_images.find_many_files_myrorss_or_mrms(
        top_directory_name=top_directory_name,
        radar_source=radar_utils.MYRORSS_SOURCE_ID,
        radar_field_names=field_names,
        reflectivity_heights_m_agl=reflectivity_heights_m_agl,
        start_time_unix_sec=first_spc_date_unix_sec,
        end_time_unix_sec=last_spc_date_unix_sec,
        one_file_per_time_step=False,
        raise_error_if_all_missing=True, raise_error_if_any_missing=False)

    radar_file_name_matrix = storm_image_file_dict[
        storm_images.IMAGE_FILE_NAMES_KEY]
    time_missing_indices = numpy.unique(
        numpy.where(radar_file_name_matrix == '')[0]
    )
    radar_file_name_matrix = numpy.delete(
        radar_file_name_matrix, time_missing_indices, axis=0)

    return radar_file_name_matrix[:, :2], radar_file_name_matrix[:, 2:]