mirror of
https://github.com/kuhyx/todo-app.git
synced 2026-11-10 20:27:01 +01:00
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
file-length / file length <= 250 lines (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
release-apk / release (APK) (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
New optional note field created_by (kuhy|claude), stored like by/repo and omitted when unset so older builds stay wire-compatible. App UI stamps kuhy; MCP add_task and the CLI stamp claude. list/get/search output includes it. Human notes sort above Claude's; Claude notes are hidden behind a per-device eye toggle. CLI --backfill-created-by [--dry-run] classifies old notes by the node that wrote created_at, writing only the created_by field. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
86 lines
3.2 KiB
Dart
86 lines
3.2 KiB
Dart
// created_by through the CLI: stamping, output, and the backfill command.
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import 'cli_harness.dart';
|
|
|
|
void main() {
|
|
late CliHarness h;
|
|
setUp(() => h = CliHarness());
|
|
tearDown(() => h.dispose());
|
|
|
|
test('a CLI add is stamped claude, repo task or idea', () async {
|
|
final idea = await h.add('Plain idea');
|
|
final task = await h.add('Fix gate', ['--repo', 'kuhyx/todo']);
|
|
for (final id in [idea, task]) {
|
|
expect(await h.run(['--get', id, '--data-dir', h.dir('b')]), 0);
|
|
expect(h.out.toString(), contains('created_by: claude'));
|
|
}
|
|
expect(await h.run(['--list']), 0);
|
|
expect(
|
|
h.out.toString().trim().split('\n'),
|
|
everyElement(endsWith('\tclaude')),
|
|
);
|
|
});
|
|
|
|
test('a --new-note add is stamped claude', () async {
|
|
final id = await h.add('Own note', ['--repo', 'kuhyx/todo', '--new-note']);
|
|
expect(await h.run(['--get', id, '--data-dir', h.dir('b')]), 0);
|
|
expect(h.out.toString(), contains('created_by: claude'));
|
|
});
|
|
|
|
test('a peer note without created_by reads as kuhy', () async {
|
|
h.seedPeer([fixtureNote('peer-note-1', 'From the phone')]);
|
|
expect(await h.run(['--get', 'peer-note-1']), 0);
|
|
expect(h.out.toString(), contains('created_by: kuhy'));
|
|
expect(await h.run(['--list']), 0);
|
|
expect(h.out.toString(), endsWith('From the phone\tkuhy\n'));
|
|
});
|
|
|
|
group('--backfill-created-by', () {
|
|
void seed() {
|
|
final mcp = Directory('${h.env['XDG_DATA_HOME']}/todo-mcp')
|
|
..createSync(recursive: true);
|
|
File('${mcp.path}/node_id').writeAsStringSync('mcp-node\n');
|
|
h.seedPeer([
|
|
fixtureNote('mcp-note-0001', 'Make a text-free', repo: 'kuhyx/a'),
|
|
], node: 'mcp-node');
|
|
h.seedPeer([fixtureNote('idea-note-0001', 'My idea')], node: 'phone');
|
|
}
|
|
|
|
test('--dry-run lists the plan and writes nothing', () async {
|
|
seed();
|
|
expect(await h.run(['--backfill-created-by', '--dry-run']), 0);
|
|
final lines = h.out.toString().trim().split('\n');
|
|
expect(lines, contains('mcp-note\tclaude\tMake a text-free'));
|
|
expect(lines, contains('idea-not\tkuhy\tMy idea'));
|
|
expect(lines.last, 'dry run: claude 1, kuhy 1');
|
|
expect(h.db.methods, isNot(contains('PUT')), reason: 'nothing pushed');
|
|
});
|
|
|
|
test('a real run sets it once, pushes it, and is then a no-op', () async {
|
|
seed();
|
|
expect(await h.run(['--backfill-created-by']), 0);
|
|
expect(h.out.toString().trim().split('\n').last, 'set: claude 1, kuhy 1');
|
|
expect(
|
|
await h.run(['--get', 'mcp-note-0001', '--data-dir', h.dir('b')]),
|
|
0,
|
|
);
|
|
expect(h.out.toString(), contains('created_by: claude'));
|
|
expect(
|
|
await h.run(['--get', 'idea-note-0001', '--data-dir', h.dir('b')]),
|
|
0,
|
|
);
|
|
expect(h.out.toString(), contains('created_by: kuhy'));
|
|
expect(await h.run(['--backfill-created-by']), 0);
|
|
expect(h.out.toString().trim(), 'set: claude 0, kuhy 0');
|
|
});
|
|
|
|
test('--dry-run is refused without the backfill flag', () async {
|
|
expect(await h.run(['--dry-run']), 2);
|
|
expect(h.err.toString(), contains('--dry-run only applies'));
|
|
});
|
|
});
|
|
}
|