-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial Implementation of Multi-Node data syncing (#45)
* single machine, basic data persistence * multi node syncing * basic undo integration
- Loading branch information
1 parent
5a81050
commit 0194961
Showing
12 changed files
with
737 additions
and
205 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
const shared = require('../jest.config.shared'); | ||
|
||
/** | ||
* @type {import('@jest/types').Config.InitialOptions} | ||
*/ | ||
module.exports = { | ||
...shared, | ||
testEnvironment: 'jsdom', | ||
setupFilesAfterEnv: ['<rootDir>/src/setupTests.ts'], | ||
coverageThreshold: { | ||
global: { | ||
lines: 0, | ||
branches: 0, | ||
}, | ||
}, | ||
prettierPath: null, | ||
transformIgnorePatterns: [ | ||
'[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$', | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
CREATE TABLE voters ( | ||
voter_id TEXT PRIMARY KEY, | ||
voter_data TEXT not null | ||
); | ||
|
||
CREATE TABLE elections ( | ||
election_id TEXT PRIMARY KEY, | ||
election_data TEXT not null | ||
); | ||
|
||
CREATE TABLE event_log ( | ||
event_id INTEGER, | ||
machine_id TEXT, | ||
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | ||
event_type TEXT, -- e.g., "check_in", "undo_check_in" | ||
voter_id TEXT, -- voter_id of the voter involved in the event, if any | ||
event_data TEXT not null, -- JSON data for additional details associated with the event (id type used for check in, etc.) | ||
PRIMARY KEY (event_id, machine_id) | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { assert } from '@votingworks/basics'; | ||
import { Store } from './store'; | ||
import { EventType, VoterCheckInEvent } from './types'; | ||
|
||
const myMachineId = 'machine-1'; | ||
const otherMachineId = 'machine-2'; | ||
|
||
function createTestStore(): Store { | ||
return Store.memoryStore(myMachineId); | ||
} | ||
|
||
function createVoterCheckInEvent( | ||
eventId: number, | ||
machineId: string, | ||
voterId: string | ||
): VoterCheckInEvent { | ||
return { | ||
type: EventType.VoterCheckIn, | ||
eventId, | ||
machineId, | ||
timestamp: new Date().toISOString(), | ||
voterId, | ||
checkInData: { | ||
timestamp: new Date().toISOString(), | ||
identificationMethod: { | ||
type: 'photoId', | ||
state: 'nh', | ||
}, | ||
machineId, | ||
}, | ||
}; | ||
} | ||
|
||
test('getNewEvents returns events for unknown machines', () => { | ||
const store = createTestStore(); | ||
const event1 = createVoterCheckInEvent(1, myMachineId, 'voter-1'); | ||
const event2 = createVoterCheckInEvent(2, otherMachineId, 'voter-2'); | ||
|
||
store.saveEvent(event1); | ||
store.saveEvent(event2); | ||
|
||
const knownMachines: Record<string, number> = {}; | ||
const events = store.getNewEvents(knownMachines); | ||
|
||
assert(events.length === 2); | ||
expect(events).toEqual([event1, event2]); | ||
}); | ||
|
||
test('getNewEvents returns events for known machines with new events', () => { | ||
const store = createTestStore(); | ||
const event1 = createVoterCheckInEvent(1, myMachineId, 'voter-1'); | ||
const event2 = createVoterCheckInEvent(2, otherMachineId, 'voter-2'); | ||
const event3 = createVoterCheckInEvent(1, myMachineId, 'voter-3'); | ||
|
||
store.saveEvent(event1); | ||
store.saveEvent(event2); | ||
store.saveEvent(event3); | ||
|
||
const knownMachines: Record<string, number> = { | ||
[myMachineId]: 1, | ||
[otherMachineId]: 1, | ||
}; | ||
const events = store.getNewEvents(knownMachines); | ||
|
||
assert(events.length === 1); | ||
expect(events).toEqual([event2]); | ||
}); | ||
|
||
test('getNewEvents returns no events for known machines and unknown machines', () => { | ||
const store = createTestStore(); | ||
const event1 = createVoterCheckInEvent(1, myMachineId, 'voter-1'); | ||
const event2 = createVoterCheckInEvent(2, myMachineId, 'voter-2'); | ||
const event3 = createVoterCheckInEvent(3, myMachineId, 'voter-3'); | ||
const event4 = createVoterCheckInEvent(4, myMachineId, 'voter-4'); | ||
const event5 = createVoterCheckInEvent(5, myMachineId, 'voter-5'); | ||
const event6 = createVoterCheckInEvent(1, otherMachineId, 'voter-6'); | ||
const event7 = createVoterCheckInEvent(2, otherMachineId, 'voter-7'); | ||
|
||
store.saveEvent(event1); | ||
store.saveEvent(event2); | ||
store.saveEvent(event3); | ||
store.saveEvent(event4); | ||
store.saveEvent(event5); | ||
store.saveEvent(event6); | ||
store.saveEvent(event7); | ||
|
||
const knownMachines: Record<string, number> = { | ||
[myMachineId]: 3, | ||
'not-a-machine': 1, | ||
}; | ||
const events = store.getNewEvents(knownMachines); | ||
|
||
assert(events.length === 4); | ||
expect(events).toEqual([event6, event7, event4, event5]); | ||
}); |
Oops, something went wrong.