diff --git a/apps/admin/backend/src/__snapshots__/app.exports.test.ts.snap b/apps/admin/backend/src/__snapshots__/app.exports.test.ts.snap deleted file mode 100644 index b4709f024e..0000000000 --- a/apps/admin/backend/src/__snapshots__/app.exports.test.ts.snap +++ /dev/null @@ -1,96 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`batch export 1`] = ` -"Batch ID,Batch Name,Tabulator,Number of Ballots,"Governor - Ballots Cast","Governor - Undervotes","Governor - Overvotes","Governor - Josiah Bartlett","Governor - Hannah Dustin","Governor - John Spencer","Governor - Write In","United States Senator - Ballots Cast","United States Senator - Undervotes","United States Senator - Overvotes","United States Senator - John Langdon","United States Senator - William Preston","United States Senator - Write In","Representative in Congress - Ballots Cast","Representative in Congress - Undervotes","Representative in Congress - Overvotes","Representative in Congress - Jeremiah Smith","Representative in Congress - Nicholas Gilman","Representative in Congress - Richard Coote","Representative in Congress - Write In","Executive Councilor - Ballots Cast","Executive Councilor - Undervotes","Executive Councilor - Overvotes","Executive Councilor - Anne Waldron","Executive Councilor - Daniel Webster","Executive Councilor - Write In","State Senator - Ballots Cast","State Senator - Undervotes","State Senator - Overvotes","State Senator - James Poole","State Senator - Matthew Thornton","State Senator - Write In","State Representatives Hillsborough District 34 - Ballots Cast","State Representatives Hillsborough District 34 - Undervotes","State Representatives Hillsborough District 34 - Overvotes","State Representatives Hillsborough District 34 - Obadiah Carrigan","State Representatives Hillsborough District 34 - Mary Baker Eddy","State Representatives Hillsborough District 34 - Samuel Bell","State Representatives Hillsborough District 34 - Samuel Livermore","State Representatives Hillsborough District 34 - Elijah Miller","State Representatives Hillsborough District 34 - Isaac Hill","State Representatives Hillsborough District 34 - Abigail Bartlett","State Representatives Hillsborough District 34 - Jacob Freese","State Representatives Hillsborough District 34 - Write In","State Representative Hillsborough District 37 - Ballots Cast","State Representative Hillsborough District 37 - Undervotes","State Representative Hillsborough District 37 - Overvotes","State Representative Hillsborough District 37 - Abeil Foster","State Representative Hillsborough District 37 - Charles H. Hersey","State Representative Hillsborough District 37 - William Lovejoy","State Representative Hillsborough District 37 - Write In","Sheriff - Ballots Cast","Sheriff - Undervotes","Sheriff - Overvotes","Sheriff - Edward Randolph","Sheriff - Write In","County Attorney - Ballots Cast","County Attorney - Undervotes","County Attorney - Overvotes","County Attorney - Ezra Bartlett","County Attorney - Mary Woolson","County Attorney - Write In","County Treasurer - Ballots Cast","County Treasurer - Undervotes","County Treasurer - Overvotes","County Treasurer - John Smith","County Treasurer - Jane Jones","County Treasurer - Write In","Register of Deeds - Ballots Cast","Register of Deeds - Undervotes","Register of Deeds - Overvotes","Register of Deeds - John Mann","Register of Deeds - Ellen A. Stileman","Register of Deeds - Write In","Register of Probate - Ballots Cast","Register of Probate - Undervotes","Register of Probate - Overvotes","Register of Probate - Nathaniel Parker","Register of Probate - Claire Cutts","Register of Probate - Write In","County Commissioner - Ballots Cast","County Commissioner - Undervotes","County Commissioner - Overvotes","County Commissioner - Ichabod Goodwin","County Commissioner - Valbe Cady","County Commissioner - Write In","Constitutional Amendment Question 1 - Ballots Cast","Constitutional Amendment Question 1 - Undervotes","Constitutional Amendment Question 1 - Overvotes","Constitutional Amendment Question 1 - Yes","Constitutional Amendment Question 1 - No" -9822c71014,9822c71014,VX-00-000,184,184,2,4,2,2,172,2,184,2,2,2,176,2,184,2,4,2,2,172,2,184,2,2,2,176,2,184,2,2,2,176,2,184,12,30,60,58,56,56,56,56,56,56,56,184,2,4,2,2,172,2,184,2,0,180,2,184,2,2,2,176,2,184,2,2,2,176,2,184,2,2,2,176,2,184,2,2,2,176,2,184,2,2,2,176,2,184,178,2,2,2 -" -`; - -exports[`sems export 1`] = ` -{ - "aquarium-council-fish": { - "metadata": { - "ballots": 28, - "overvotes": 8, - "undervotes": 6, - }, - "tallies": { - "manta-ray": 10, - "pufferfish": 8, - "rockfish": 8, - "triggerfish": 8, - "write-in": 8, - }, - }, - "best-animal-fish": { - "metadata": { - "ballots": 28, - "overvotes": 2, - "undervotes": 2, - }, - "tallies": { - "salmon": 22, - "seahorse": 2, - }, - }, - "best-animal-mammal": { - "metadata": { - "ballots": 28, - "overvotes": 4, - "undervotes": 2, - }, - "tallies": { - "fox": 18, - "horse": 2, - "otter": 2, - }, - }, - "fishing": { - "metadata": { - "ballots": 56, - "overvotes": 4, - "undervotes": 44, - }, - "tallies": { - "no": 4, - "yes": 4, - }, - }, - "new-zoo-either": { - "metadata": { - "ballots": 56, - "overvotes": 4, - "undervotes": 44, - }, - "tallies": { - "no": 4, - "yes": 4, - }, - }, - "new-zoo-pick": { - "metadata": { - "ballots": 56, - "overvotes": 4, - "undervotes": 44, - }, - "tallies": { - "no": 4, - "yes": 4, - }, - }, - "zoo-council-mammal": { - "metadata": { - "ballots": 28, - "overvotes": 6, - "undervotes": 12, - }, - "tallies": { - "elephant": 12, - "kangaroo": 12, - "lion": 14, - "write-in": 12, - "zebra": 16, - }, - }, -} -`; diff --git a/apps/admin/backend/src/__snapshots__/app.sems.test.ts.snap b/apps/admin/backend/src/__snapshots__/app.sems.test.ts.snap new file mode 100644 index 0000000000..5505015833 --- /dev/null +++ b/apps/admin/backend/src/__snapshots__/app.sems.test.ts.snap @@ -0,0 +1,90 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`sems export 1`] = ` +{ + "aquarium-council-fish": { + "metadata": { + "ballots": 28, + "overvotes": 8, + "undervotes": 6, + }, + "tallies": { + "manta-ray": 10, + "pufferfish": 8, + "rockfish": 8, + "triggerfish": 8, + "write-in": 8, + }, + }, + "best-animal-fish": { + "metadata": { + "ballots": 28, + "overvotes": 2, + "undervotes": 2, + }, + "tallies": { + "salmon": 22, + "seahorse": 2, + }, + }, + "best-animal-mammal": { + "metadata": { + "ballots": 28, + "overvotes": 4, + "undervotes": 2, + }, + "tallies": { + "fox": 18, + "horse": 2, + "otter": 2, + }, + }, + "fishing": { + "metadata": { + "ballots": 56, + "overvotes": 4, + "undervotes": 44, + }, + "tallies": { + "no": 4, + "yes": 4, + }, + }, + "new-zoo-either": { + "metadata": { + "ballots": 56, + "overvotes": 4, + "undervotes": 44, + }, + "tallies": { + "no": 4, + "yes": 4, + }, + }, + "new-zoo-pick": { + "metadata": { + "ballots": 56, + "overvotes": 4, + "undervotes": 44, + }, + "tallies": { + "no": 4, + "yes": 4, + }, + }, + "zoo-council-mammal": { + "metadata": { + "ballots": 28, + "overvotes": 6, + "undervotes": 12, + }, + "tallies": { + "elephant": 12, + "kangaroo": 12, + "lion": 14, + "write-in": 12, + "zebra": 16, + }, + }, +} +`; diff --git a/apps/admin/backend/src/app.exports.test.ts b/apps/admin/backend/src/app.sems.test.ts similarity index 50% rename from apps/admin/backend/src/app.exports.test.ts rename to apps/admin/backend/src/app.sems.test.ts index e30daa7526..b3200e0a5e 100644 --- a/apps/admin/backend/src/app.exports.test.ts +++ b/apps/admin/backend/src/app.sems.test.ts @@ -1,14 +1,8 @@ -import { - electionGridLayoutNewHampshireAmherstFixtures, - electionTwoPartyPrimaryFixtures, -} from '@votingworks/fixtures'; +import { electionTwoPartyPrimaryFixtures } from '@votingworks/fixtures'; import { BooleanEnvironmentVariableName, getFeatureFlagMock, } from '@votingworks/utils'; -import { tmpNameSync } from 'tmp'; -import { readFileSync } from 'fs'; -import { LogEventId } from '@votingworks/logging'; import { buildTestEnvironment, configureMachine, @@ -41,50 +35,6 @@ afterEach(() => { featureFlagMock.resetFeatureFlags(); }); -test('batch export', async () => { - const { electionDefinition, castVoteRecordExport } = - electionGridLayoutNewHampshireAmherstFixtures; - - const { apiClient, auth, logger } = buildTestEnvironment(); - await configureMachine(apiClient, auth, electionDefinition); - mockElectionManagerAuth(auth, electionDefinition.electionHash); - - const loadFileResult = await apiClient.addCastVoteRecordFile({ - path: castVoteRecordExport.asDirectoryPath(), - }); - loadFileResult.assertOk('load file failed'); - - const path = tmpNameSync(); - const exportResult = await apiClient.exportBatchResults({ path }); - expect(exportResult.isOk()).toEqual(true); - expect(readFileSync(path, 'utf-8').toString()).toMatchSnapshot(); - expect(logger.log).toHaveBeenLastCalledWith( - LogEventId.FileSaved, - 'election_manager', - { - disposition: 'success', - filename: path, - message: `Saved batch results to ${path} on the USB drive.`, - } - ); - - // mock a failure - const offLimitsPath = '/root/hidden'; - const failedExportResult = await apiClient.exportBatchResults({ - path: offLimitsPath, - }); - expect(failedExportResult.isErr()).toEqual(true); - expect(logger.log).toHaveBeenLastCalledWith( - LogEventId.FileSaved, - 'election_manager', - { - disposition: 'failure', - filename: offLimitsPath, - message: `Failed to save batch results to ${offLimitsPath} on the USB drive.`, - } - ); -}); - test('sems export', async () => { const { electionDefinition, castVoteRecordExport } = electionTwoPartyPrimaryFixtures; diff --git a/apps/admin/backend/src/app.ts b/apps/admin/backend/src/app.ts index b4eec9200a..8ccbcb0a88 100644 --- a/apps/admin/backend/src/app.ts +++ b/apps/admin/backend/src/app.ts @@ -72,7 +72,6 @@ import { import { handleEnteredWriteInCandidateData } from './util/manual_results'; import { addFileToZipStream } from './util/zip'; import { exportFile } from './util/export_file'; -import { generateBatchResultsFile } from './exports/batch_results'; import { tabulateElectionResults } from './tabulation/full_results'; import { getSemsExportableTallies } from './exports/sems_tallies'; import { generateTallyReportCsv } from './exports/csv_tally_report'; @@ -691,43 +690,6 @@ function buildApi({ return store.getScannerBatches(loadCurrentElectionIdOrThrow(workspace)); }, - async exportBatchResults(input: { - path: string; - }): Promise { - debug('exporting batch results CSV file'); - const electionId = loadCurrentElectionIdOrThrow(workspace); - const { - electionDefinition: { election }, - } = assertDefined(store.getElection(electionId)); - - const exportFileResult = await exportFile({ - path: input.path, - data: generateBatchResultsFile({ - election, - batchGroupedResults: await tabulateElectionResults({ - electionId, - store, - groupBy: { groupByBatch: true }, - }), - allBatchMetadata: store.getScannerBatches(electionId), - }), - }); - - await logger.log( - LogEventId.FileSaved, - assertDefined(await getUserRole()), - { - disposition: exportFileResult.isOk() ? 'success' : 'failure', - message: `${ - exportFileResult.isOk() ? 'Saved' : 'Failed to save' - } batch results to ${input.path} on the USB drive.`, - filename: input.path, - } - ); - - return exportFileResult; - }, - async getSemsExportableTallies(): Promise { const electionId = loadCurrentElectionIdOrThrow(workspace); diff --git a/apps/admin/backend/src/exports/batch_results.test.ts b/apps/admin/backend/src/exports/batch_results.test.ts deleted file mode 100644 index d50e369dec..0000000000 --- a/apps/admin/backend/src/exports/batch_results.test.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { electionTwoPartyPrimaryDefinition } from '@votingworks/fixtures'; -import { Tabulation } from '@votingworks/types'; -import { buildElectionResultsFixture } from '@votingworks/utils'; -import { Buffer } from 'buffer'; -import { generateBatchResultsFile } from './batch_results'; -import { ScannerBatch } from '../types'; - -test('generateBatchResultsFile', async () => { - const { election } = electionTwoPartyPrimaryDefinition; - const batchGroupedResults: Tabulation.ElectionResultsGroupMap = { - 'root&batchId=batch-1': buildElectionResultsFixture({ - election, - cardCounts: { - hmpb: [30, 29], - bmd: 5, - }, - contestResultsSummaries: { - 'zoo-council-mammal': { - type: 'candidate', - ballots: 35, - undervotes: 2, - overvotes: 3, - officialOptionTallies: { - lion: 25, - [Tabulation.GENERIC_WRITE_IN_ID]: 5, - }, - }, - fishing: { - type: 'yesno', - ballots: 34, - undervotes: 1, - overvotes: 3, - yesTally: 25, - noTally: 5, - }, - }, - includeGenericWriteIn: true, - }), - 'root&batchId=batch-2': buildElectionResultsFixture({ - election, - cardCounts: { - hmpb: [29, 29], - bmd: 1, - }, - contestResultsSummaries: { - 'zoo-council-mammal': { - type: 'candidate', - ballots: 30, - undervotes: 1, - overvotes: 3, - officialOptionTallies: { - lion: 20, - [Tabulation.GENERIC_WRITE_IN_ID]: 6, - }, - }, - fishing: { - type: 'yesno', - ballots: 30, - undervotes: 1, - overvotes: 5, - yesTally: 20, - noTally: 4, - }, - }, - includeGenericWriteIn: true, - }), - }; - - const allBatchMetadata: ScannerBatch[] = [ - { - electionId: 'id', - batchId: 'batch-1', - label: 'Batch 1', - scannerId: 'scanner-1', - }, - { - electionId: 'id', - batchId: 'batch-2', - label: 'Batch 2', - scannerId: 'scanner-1', - }, - ]; - - const csvExportStream = generateBatchResultsFile({ - election, - batchGroupedResults, - allBatchMetadata, - }); - - const chunks = []; - - for await (const chunk of csvExportStream) { - chunks.push(Buffer.from(chunk)); - } - - const csvString = Buffer.concat(chunks).toString('utf-8'); - - expect(csvString).toMatchInlineSnapshot(` - "Batch ID,Batch Name,Tabulator,Number of Ballots,"Mammal Party Best Animal - Ballots Cast","Mammal Party Best Animal - Undervotes","Mammal Party Best Animal - Overvotes","Mammal Party Best Animal - Horse","Mammal Party Best Animal - Otter","Mammal Party Best Animal - Fox","Fish Party Best Animal - Ballots Cast","Fish Party Best Animal - Undervotes","Fish Party Best Animal - Overvotes","Fish Party Best Animal - Seahorse","Fish Party Best Animal - Salmon","Mammal Party Zoo Council - Ballots Cast","Mammal Party Zoo Council - Undervotes","Mammal Party Zoo Council - Overvotes","Mammal Party Zoo Council - Zebra","Mammal Party Zoo Council - Lion","Mammal Party Zoo Council - Kangaroo","Mammal Party Zoo Council - Elephant","Mammal Party Zoo Council - Write In","Fish Party Zoo Council - Ballots Cast","Fish Party Zoo Council - Undervotes","Fish Party Zoo Council - Overvotes","Fish Party Zoo Council - Manta Ray","Fish Party Zoo Council - Pufferfish","Fish Party Zoo Council - Rockfish","Fish Party Zoo Council - Triggerfish","Fish Party Zoo Council - Write In","Ballot Measure 1 - Ballots Cast","Ballot Measure 1 - Undervotes","Ballot Measure 1 - Overvotes","Ballot Measure 1 - Yes","Ballot Measure 1 - No","Ballot Measure 1 - Ballots Cast","Ballot Measure 1 - Undervotes","Ballot Measure 1 - Overvotes","Ballot Measure 1 - Yes","Ballot Measure 1 - No","Ballot Measure 3 - Ballots Cast","Ballot Measure 3 - Undervotes","Ballot Measure 3 - Overvotes","Ballot Measure 3 - Yes","Ballot Measure 3 - No" - batch-1,Batch 1,scanner-1,35,0,0,0,0,0,0,0,0,0,0,0,35,2,3,0,25,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,1,3,25,5 - batch-2,Batch 2,scanner-1,30,0,0,0,0,0,0,0,0,0,0,0,30,1,3,0,20,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,1,5,20,4 - " - `); -}); diff --git a/apps/admin/backend/src/exports/batch_results.ts b/apps/admin/backend/src/exports/batch_results.ts deleted file mode 100644 index 19a3aa8c83..0000000000 --- a/apps/admin/backend/src/exports/batch_results.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Election, Tabulation } from '@votingworks/types'; -import { assert } from '@votingworks/basics'; -import { Readable } from 'stream'; -import { getBallotCount, groupMapToGroupList } from '@votingworks/utils'; -import { stringify } from 'csv-stringify/sync'; -import { ScannerBatch } from '../types'; - -function generateHeaderRow(election: Election): string { - const contestSelectionHeaders: string[] = []; - for (const contest of election.contests) { - let contestTitle = contest.title; - if (contest.type === 'candidate' && contest.partyId) { - const party = election.parties.find((p) => p.id === contest.partyId); - if (party) { - contestTitle = `${party.fullName} ${contestTitle}`; - } - } - contestTitle = contestTitle.replace(/[^a-z0-9 _-]+/gi, ' ').trim(); - contestSelectionHeaders.push(`${contestTitle} - Ballots Cast`); - contestSelectionHeaders.push(`${contestTitle} - Undervotes`); - contestSelectionHeaders.push(`${contestTitle} - Overvotes`); - if (contest.type === 'candidate') { - for (const candidate of contest.candidates) { - contestSelectionHeaders.push(`${contestTitle} - ${candidate.name}`); - } - if (contest.allowWriteIns) { - contestSelectionHeaders.push(`${contestTitle} - Write In`); - } - } else if (contest.type === 'yesno') { - contestSelectionHeaders.push(`${contestTitle} - Yes`); - contestSelectionHeaders.push(`${contestTitle} - No`); - } - } - const headers = [ - 'Batch ID', - 'Batch Name', - 'Tabulator', - 'Number of Ballots', - ...contestSelectionHeaders, - ]; - - // use quotes for all headers that contain a dash i.e. the contest selection headers - return stringify([headers], { quoted_match: /-/ }); -} - -function generateResultsRow( - batchMetadata: ScannerBatch, - batchResults: Tabulation.ElectionResults, - election: Election -): string { - const contestVoteTotals: string[] = []; - for (const contest of election.contests) { - const contestResults = batchResults.contestResults[contest.id]; - assert(contestResults); - contestVoteTotals.push(contestResults.ballots.toString()); - contestVoteTotals.push(contestResults.undervotes.toString()); - contestVoteTotals.push(contestResults.overvotes.toString()); - if (contest.type === 'candidate') { - assert(contestResults.contestType === 'candidate'); - for (const candidate of contest.candidates) { - contestVoteTotals.push( - /* c8 ignore next - trivial fallback case */ - contestResults.tallies[candidate.id]?.tally.toString() ?? '0' - ); - } - if (contest.allowWriteIns) { - contestVoteTotals.push( - /* c8 ignore start - trivial fallback case */ - contestResults.tallies[ - Tabulation.GENERIC_WRITE_IN_ID - ]?.tally.toString() ?? '0' - /* c8 ignore end */ - ); - } - } else if (contest.type === 'yesno') { - assert(contestResults.contestType === 'yesno'); - contestVoteTotals.push(contestResults.yesTally.toString()); - contestVoteTotals.push(contestResults.noTally.toString()); - } - } - const row = [ - batchMetadata.batchId, - batchMetadata.label, - batchMetadata.scannerId, - getBallotCount(batchResults.cardCounts), - ...contestVoteTotals, - ]; - return stringify([row]); -} - -/** - * Generates a CSV file of election results broken down by scanning batch. Returns the - * file as a readable stream. - * - * CSV File format: - * One row for every batch, in addition to a headers row. - * Columns for every possible contest selection in every contest. - * | Batch ID | Batch Name | Tabulator | Number Of Ballots | Contest 1 - Ballots Cast | Contest 1 - Undervotes | Contest 1 - Overvotes | Contest 1 - Selection Option 1 | ... | Contest N - Selection Option M | - */ -export function generateBatchResultsFile({ - election, - batchGroupedResults, - allBatchMetadata, -}: { - election: Election; - batchGroupedResults: Tabulation.ElectionResultsGroupMap; - allBatchMetadata: ScannerBatch[]; -}): NodeJS.ReadableStream { - const electionResultsList = groupMapToGroupList(batchGroupedResults); - const batchMetadataLookup: Record = {}; - for (const batchMetadata of allBatchMetadata) { - batchMetadataLookup[batchMetadata.batchId] = batchMetadata; - } - - function* generateBatchResultsFileRows() { - yield generateHeaderRow(election); - - for (const batchResults of electionResultsList) { - // expect batch results to be grouped by batchId - assert(batchResults.batchId !== undefined); - - // every batch with results should have a batch in the database - const batchMetadata = batchMetadataLookup[batchResults.batchId]; - assert(batchMetadata); - - yield generateResultsRow(batchMetadata, batchResults, election); - } - } - - return Readable.from(generateBatchResultsFileRows()); -} diff --git a/apps/admin/frontend/src/api.ts b/apps/admin/frontend/src/api.ts index 1b831a8cea..d9f2d3028e 100644 --- a/apps/admin/frontend/src/api.ts +++ b/apps/admin/frontend/src/api.ts @@ -652,13 +652,6 @@ export const adjudicateWriteIn = { }, } as const; -export const exportBatchResults = { - useMutation() { - const apiClient = useApiClient(); - return useMutation(apiClient.exportBatchResults); - }, -} as const; - export const exportTallyReportCsv = { useMutation() { const apiClient = useApiClient(); diff --git a/apps/admin/frontend/src/components/export_batch_tally_results_button.tsx b/apps/admin/frontend/src/components/export_batch_tally_results_button.tsx deleted file mode 100644 index 93613b14bf..0000000000 --- a/apps/admin/frontend/src/components/export_batch_tally_results_button.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React, { useContext, useState } from 'react'; -import { Button } from '@votingworks/ui'; -import { generateBatchResultsDefaultFilename } from '@votingworks/utils'; -import { assert } from '@votingworks/basics'; -import { AppContext } from '../contexts/app_context'; -import { exportBatchResults, getCastVoteRecordFileMode } from '../api'; -import { SaveBackendFileModal } from './save_backend_file_modal'; - -export function ExportBatchTallyResultsButton(): JSX.Element { - const [isSaveModalOpen, setIsSaveModalOpen] = useState(false); - const { electionDefinition } = useContext(AppContext); - assert(electionDefinition); - const { election } = electionDefinition; - - const exportBatchResultsMutation = exportBatchResults.useMutation(); - - const castVoteRecordFileModeQuery = getCastVoteRecordFileMode.useQuery(); - const isTestMode = castVoteRecordFileModeQuery.data === 'test'; - const defaultFilename = generateBatchResultsDefaultFilename( - isTestMode, - election - ); - - return ( - - - {isSaveModalOpen && ( - setIsSaveModalOpen(false)} - fileTypeTitle="Batch Results" - fileType="batch results" - defaultRelativePath={defaultFilename} - /> - )} - - ); -} diff --git a/apps/admin/frontend/src/screens/reporting/reports_screen.test.tsx b/apps/admin/frontend/src/screens/reporting/reports_screen.test.tsx index 91716abf3a..47178b7e81 100644 --- a/apps/admin/frontend/src/screens/reporting/reports_screen.test.tsx +++ b/apps/admin/frontend/src/screens/reporting/reports_screen.test.tsx @@ -93,34 +93,6 @@ test('exporting SEMS results', async () => { expect(fetchMock.called('/convert/reset')).toEqual(true); }); -test('exporting batch results', async () => { - apiMock.expectGetCastVoteRecordFileMode('test'); - apiMock.expectGetCardCounts({}, [getMockCardCounts(100)]); - - renderInAppContext(, { - electionDefinition, - apiMock, - usbDriveStatus: mockUsbDriveStatus('mounted'), - }); - - await waitFor(() => { - expect(screen.getButton('Save Batch Results CSV')).toBeEnabled(); - }); - userEvent.click(screen.getButton('Save Batch Results CSV')); - await screen.findByRole('alertdialog'); - - await screen.findByText('Save Batch Results'); - await screen.findByText( - 'votingworks-test-batch-results_sample-county_example-primary-election_2020-11-03_22-22-00.csv' - ); - - apiMock.expectExportBatchResults( - 'test-mount-point/votingworks-test-batch-results_sample-county_example-primary-election_2020-11-03_22-22-00.csv' - ); - userEvent.click(screen.getByText('Save')); - await screen.findByText(/Batch Results Saved/); -}); - describe('ballot count summary text', () => { test('unlocked mode', async () => { apiMock.expectGetCastVoteRecordFileMode('unlocked'); diff --git a/apps/admin/frontend/src/screens/reporting/reports_screen.tsx b/apps/admin/frontend/src/screens/reporting/reports_screen.tsx index 47386d045d..bee4aa3787 100644 --- a/apps/admin/frontend/src/screens/reporting/reports_screen.tsx +++ b/apps/admin/frontend/src/screens/reporting/reports_screen.tsx @@ -33,7 +33,6 @@ import { getCastVoteRecordFileMode, getSemsExportableTallies, } from '../../api'; -import { ExportBatchTallyResultsButton } from '../../components/export_batch_tally_results_button'; import { MarkResultsOfficialButton } from '../../components/mark_official_button'; export function ReportsScreen(): JSX.Element { @@ -182,7 +181,6 @@ export function ReportsScreen(): JSX.Element {

- {' '} {converterName !== '' && (