pql: refetch ticket + decision sidebars when the workspace opens (T-352)
On a desktop launch the daemon's PqlClient boots with workDir set to the launch CWD (e.g. HOME), not the repo — swapIpcServer only rewires it once the project opens. The tickets and decisions panes fire their first pql fetch before that swap, so pql runs in the wrong directory against a stale/global pql.db and the pane errors (observed: "ticket_deps.blocker_record_id missing — pql.db is from an earlier schema"). A manual refresh worked because by then the workspace was open. This is a wrong-workDir timing issue, not db-busy, so the T-350 retry doesn't catch it. Both panes now re-fetch on ProjectOpened, which fires after the IPC server swaps to the project workRoot. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -546,6 +546,29 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('DecisionsView — workspace open triggers reload (T-352)', () {
|
||||
testWidgets('ProjectOpened triggers _refresh', (tester) async {
|
||||
// The first load can fire before the daemon's pql workDir is the repo; a
|
||||
// ProjectOpened (fired after the IPC server swaps) must re-fetch.
|
||||
int listCallCount = 0;
|
||||
f.ipc.stub('pql.decisions.sync', (_) async => _ok(const {}));
|
||||
f.ipc.stub('pql.decisions.list', (_) async {
|
||||
listCallCount++;
|
||||
return _ok({
|
||||
'decisions': [_decision(id: 'D-$listCallCount', title: 'open $listCallCount')],
|
||||
});
|
||||
});
|
||||
|
||||
await pumpView(tester);
|
||||
expect(listCallCount, 1);
|
||||
|
||||
f.services.events.emit(const ProjectOpened(path: '/repo'));
|
||||
await pumpAsync(tester);
|
||||
|
||||
expect(listCallCount, greaterThanOrEqualTo(2));
|
||||
});
|
||||
});
|
||||
|
||||
group('DecisionsView — concurrent refresh guard', () {
|
||||
testWidgets('second refresh while one is running sets _pendingRefresh', (tester) async {
|
||||
final Completer<IpcResponse> firstListCompleter = Completer();
|
||||
|
||||
@@ -137,6 +137,21 @@ void main() {
|
||||
expect(calls, greaterThan(before));
|
||||
});
|
||||
|
||||
testWidgets('refetches when the workspace opens (T-352)', (tester) async {
|
||||
// The first load can fire before the daemon's pql workDir is the repo; a
|
||||
// ProjectOpened (fired after the IPC server swaps) must re-fetch.
|
||||
var calls = 0;
|
||||
f.ipc.stub('pql.tickets.list', (_) async {
|
||||
calls++;
|
||||
return _list([_t('T-1', 'Thing', 'backlog')]);
|
||||
});
|
||||
await pumpView(tester);
|
||||
final before = calls;
|
||||
f.services.events.emit(const ProjectOpened(path: '/repo'));
|
||||
await pumpAsync(tester);
|
||||
expect(calls, greaterThan(before));
|
||||
});
|
||||
|
||||
// -- Type-filter chips (T-343) ------------------------------------------
|
||||
// The chips own one GestureDetector for both onTap (toggle) and onDoubleTap
|
||||
// (solo), so a single tap's onTap only fires after the ~300ms double-tap
|
||||
|
||||
Reference in New Issue
Block a user