import 'package:flutter_test/flutter_test.dart'; import 'package:life_helper/ai/tools/catalog_tools.dart'; import 'package:life_helper/ai/tools/tool_envelope.dart'; import '_tool_test_helpers.dart'; void main() { group('search_catalog', () { test('전체 검색 (인자 없음)', () async { final ctx = await bootstrapToolDeps(); addTearDown(() => ctx.db.close()); final r = await searchCatalogTool.handler({}, ctx.deps); expect(r, isA()); final data = (r as ToolOk).data; expect(data['count'], greaterThan(0)); // stub 3 items: protocol + break + diet expect(data['count'], 3); final items = data['items'] as List; expect(items.first.containsKey('id'), true); expect(items.first.containsKey('summary'), true); }); test('카테고리 필터', () async { final ctx = await bootstrapToolDeps(); addTearDown(() => ctx.db.close()); final r = await searchCatalogTool .handler({'category': 'breakHabit'}, ctx.deps); expect(r, isA()); final items = ((r as ToolOk).data['items'] as List); expect(items.length, 1); expect((items.first as Map)['category'], 'breakHabit'); }); test('잘못된 카테고리 → validation 에러', () async { final ctx = await bootstrapToolDeps(); addTearDown(() => ctx.db.close()); final r = await searchCatalogTool .handler({'category': 'no_such'}, ctx.deps); expect(r, isA()); expect((r as ToolErr).code, 'validation'); }); test('limit 범위 검증', () async { final ctx = await bootstrapToolDeps(); addTearDown(() => ctx.db.close()); final r = await searchCatalogTool.handler({'limit': 99}, ctx.deps); expect(r, isA()); expect((r as ToolErr).code, 'validation'); }); }); group('query_protocol', () { test('정상 조회 → kind 분기', () async { final ctx = await bootstrapToolDeps(); addTearDown(() => ctx.db.close()); final r = await queryProtocolTool .handler({'id': 'morning_sunlight'}, ctx.deps); expect(r, isA()); final data = (r as ToolOk).data; expect(data['kind'], 'protocol'); expect(data['what'], isNotNull); }); test('break 항목 → kind=break', () async { final ctx = await bootstrapToolDeps(); addTearDown(() => ctx.db.close()); final r = await queryProtocolTool.handler({'id': 'alcohol'}, ctx.deps); expect(r, isA()); expect((r as ToolOk).data['kind'], 'break'); }); test('미존재 id → not_found', () async { final ctx = await bootstrapToolDeps(); addTearDown(() => ctx.db.close()); final r = await queryProtocolTool.handler({'id': 'no_such'}, ctx.deps); expect(r, isA()); expect((r as ToolErr).code, 'not_found'); }); }); }