mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-19 04:40:32 -05:00
4c427c92c0
Introduce a connection manager (state machine, listeners, offline handling, token/server binding) with timer start/stop reconciliation helpers. Refactor app.js to use it and extend the first-run wizard (welcome + server + token). Add node:test coverage for the manager, timer operations, and an /api/v1/info integration harness. Rebuild renderer bundle for packaging. Bump desktop toolchain (electron, electron-builder, esbuild) and Python package version to 5.3.2 in setup.py.
56 lines
1.5 KiB
JavaScript
56 lines
1.5 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert');
|
|
const {
|
|
startTimerWithReconcile,
|
|
stopTimerWithReconcile,
|
|
} = require('../src/renderer/js/connection/timer_operations');
|
|
|
|
test('startTimerWithReconcile reconciles when start times out but timer is active', async () => {
|
|
const timer = {
|
|
id: 1,
|
|
start_time: new Date().toISOString(),
|
|
project: { name: 'Proj' },
|
|
};
|
|
const api = {
|
|
async startTimer() {
|
|
const e = new Error('aborted');
|
|
e.code = 'ECONNABORTED';
|
|
throw e;
|
|
},
|
|
async getTimerStatus() {
|
|
return { data: { active: true, timer } };
|
|
},
|
|
};
|
|
|
|
const r = await startTimerWithReconcile(api, { projectId: 1, taskId: null, notes: null });
|
|
assert.strictEqual(r._reconciled, true);
|
|
assert.strictEqual(r.data.timer.id, 1);
|
|
});
|
|
|
|
test('stopTimerWithReconcile treats no_active_timer as reconciled', async () => {
|
|
const api = {
|
|
async stopTimer() {
|
|
const e = new Error('bad');
|
|
e.response = { status: 400, data: { error_code: 'no_active_timer' } };
|
|
throw e;
|
|
},
|
|
};
|
|
const r = await stopTimerWithReconcile(api);
|
|
assert.strictEqual(r._reconciled, true);
|
|
});
|
|
|
|
test('stopTimerWithReconcile reconciles when stop ambiguous and timer already stopped', async () => {
|
|
const api = {
|
|
async stopTimer() {
|
|
const e = new Error('timeout');
|
|
e.code = 'ECONNABORTED';
|
|
throw e;
|
|
},
|
|
async getTimerStatus() {
|
|
return { data: { active: false } };
|
|
},
|
|
};
|
|
const r = await stopTimerWithReconcile(api);
|
|
assert.strictEqual(r._reconciled, true);
|
|
});
|