From 48c7facbed229629b604b422c17bfcb58797d170 Mon Sep 17 00:00:00 2001 From: arsalansufi Date: Mon, 8 Jan 2024 15:46:03 -0500 Subject: [PATCH] Translate election date and add to election packages (#4487) --- apps/design/backend/src/app.test.ts | 17 ++++++++++++- .../src/worker/generate_election_package.ts | 25 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/apps/design/backend/src/app.test.ts b/apps/design/backend/src/app.test.ts index 79d5a8ad8..e86d53eff 100644 --- a/apps/design/backend/src/app.test.ts +++ b/apps/design/backend/src/app.test.ts @@ -18,6 +18,7 @@ import { District, DistrictId, Election, + ElectionStringKey, ElectionType, LanguageCode, Parties, @@ -317,10 +318,11 @@ test('Election package export', async () => { // Check overall structure of zip file const zip = await JsZip.loadAsync(electionPackageContents); - expect(Object.keys(zip.files)).toEqual([ + expect(Object.keys(zip.files).sort()).toEqual([ 'appStrings.json', 'election.json', 'systemSettings.json', + 'vxElectionStrings.json', ]); // Check appStrings.json @@ -360,6 +362,19 @@ test('Election package export', async () => { } } + // Check vxElectionStrings.json + + const vxElectionStrings = safeParseJson( + await assertDefined(zip.file('vxElectionStrings.json')).async('text'), + UiStringsPackageSchema + ).unsafeUnwrap(); + + for (const languageCode of Object.values(LanguageCode)) { + expect( + vxElectionStrings[languageCode]?.[ElectionStringKey.ELECTION_DATE] + ).toBeDefined(); + } + // Check election.json const electionDefinition = safeParseElectionDefinition( diff --git a/apps/design/backend/src/worker/generate_election_package.ts b/apps/design/backend/src/worker/generate_election_package.ts index 733e5206e..2dcf7b247 100644 --- a/apps/design/backend/src/worker/generate_election_package.ts +++ b/apps/design/backend/src/worker/generate_election_package.ts @@ -8,13 +8,16 @@ import { assertDefined } from '@votingworks/basics'; import { layOutAllBallotStyles } from '@votingworks/hmpb-layout'; import { BallotType, + Election, ElectionPackageFileName, + ElectionStringKey, getDisplayElectionHash, Id, LanguageCode, safeParseJson, UiStringsPackage, } from '@votingworks/types'; +import { format } from '@votingworks/utils'; import { PORT } from '../globals'; import { GoogleCloudTranslator } from '../language_and_audio/translator'; @@ -55,6 +58,22 @@ async function translateAppStrings( return appStrings; } +function translateVxElectionStrings(election: Election): UiStringsPackage { + const electionDate = new Date(election.date); + const vxElectionStrings: UiStringsPackage = {}; + for (const languageCode of Object.values(LanguageCode)) { + vxElectionStrings[languageCode] = {}; + const electionDateInLanguage = format.localeLongDate( + electionDate, + languageCode + ); + assertDefined(vxElectionStrings[languageCode])[ + ElectionStringKey.ELECTION_DATE + ] = electionDateInLanguage; + } + return vxElectionStrings; +} + export async function generateElectionPackage( { translator, workspace }: WorkerContext, { electionId }: { electionId: Id } @@ -72,6 +91,12 @@ export async function generateElectionPackage( JSON.stringify(appStrings, null, 2) ); + const vxElectionStrings = translateVxElectionStrings(election); + zip.file( + ElectionPackageFileName.VX_ELECTION_STRINGS, + JSON.stringify(vxElectionStrings, null, 2) + ); + const { electionDefinition } = layOutAllBallotStyles({ election, // Ballot type and ballot mode shouldn't change the election definition, so it doesn't matter