11import { beforeEach , describe , expect , it , jest } from "bun:test"
22import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
33import type { BmClient } from "../bm-client.ts"
4+ import { NoteAlreadyExistsError } from "../bm-client.ts"
45import { registerWriteTool } from "./write-note.ts"
56
67describe ( "write tool" , ( ) => {
@@ -26,7 +27,7 @@ describe("write tool", () => {
2627 name : "write_note" ,
2728 label : "Write Note" ,
2829 description : expect . stringContaining (
29- "Create or update a note in the Basic Memory knowledge graph" ,
30+ "Create a note in the Basic Memory knowledge graph" ,
3031 ) ,
3132 parameters : expect . objectContaining ( {
3233 type : "object" ,
@@ -46,6 +47,9 @@ describe("write tool", () => {
4647 project : expect . objectContaining ( {
4748 type : "string" ,
4849 } ) ,
50+ overwrite : expect . objectContaining ( {
51+ type : "boolean" ,
52+ } ) ,
4953 } ) ,
5054 } ) ,
5155 execute : expect . any ( Function ) ,
@@ -88,6 +92,7 @@ describe("write tool", () => {
8892 "This is test content" ,
8993 "notes" ,
9094 undefined ,
95+ undefined ,
9196 )
9297
9398 expect ( result ) . toEqual ( {
@@ -128,6 +133,7 @@ describe("write tool", () => {
128133 "Root level note" ,
129134 "" ,
130135 undefined ,
136+ undefined ,
131137 )
132138 } )
133139
@@ -154,6 +160,7 @@ describe("write tool", () => {
154160 "Nested folder note" ,
155161 "projects/subfolder" ,
156162 undefined ,
163+ undefined ,
157164 )
158165 } )
159166
@@ -197,6 +204,7 @@ const code = "example";
197204 markdownContent ,
198205 "notes" ,
199206 undefined ,
207+ undefined ,
200208 )
201209 } )
202210
@@ -224,6 +232,7 @@ const code = "example";
224232 "Content" ,
225233 "notes" ,
226234 undefined ,
235+ undefined ,
227236 )
228237 } )
229238
@@ -253,6 +262,7 @@ const code = "example";
253262 unicodeContent ,
254263 "notes" ,
255264 undefined ,
265+ undefined ,
256266 )
257267 } )
258268
@@ -280,6 +290,7 @@ const code = "example";
280290 longContent ,
281291 "notes" ,
282292 undefined ,
293+ undefined ,
283294 )
284295 } )
285296
@@ -306,6 +317,7 @@ const code = "example";
306317 "" ,
307318 "notes" ,
308319 undefined ,
320+ undefined ,
309321 )
310322 } )
311323
@@ -329,9 +341,56 @@ const code = "example";
329341 "content" ,
330342 "notes" ,
331343 "other-project" ,
344+ undefined ,
332345 )
333346 } )
334347
348+ it ( "should pass overwrite=true to client.writeNote" , async ( ) => {
349+ ; ( mockClient . writeNote as jest . MockedFunction < any > ) . mockResolvedValue ( {
350+ title : "Note" ,
351+ permalink : "note" ,
352+ content : "content" ,
353+ file_path : "notes/note.md" ,
354+ action : "updated" ,
355+ } )
356+
357+ const result = await executeFunction ( "tool-call-id" , {
358+ title : "Note" ,
359+ content : "content" ,
360+ folder : "notes" ,
361+ overwrite : true ,
362+ } )
363+
364+ expect ( mockClient . writeNote ) . toHaveBeenCalledWith (
365+ "Note" ,
366+ "content" ,
367+ "notes" ,
368+ undefined ,
369+ true ,
370+ )
371+
372+ expect ( result . content [ 0 ] . text ) . toContain ( "Note saved: Note" )
373+ } )
374+
375+ it ( "should return helpful hint when note already exists" , async ( ) => {
376+ ; ( mockClient . writeNote as jest . MockedFunction < any > ) . mockRejectedValue (
377+ new NoteAlreadyExistsError ( "Existing Note" , "notes/existing-note" ) ,
378+ )
379+
380+ const result = await executeFunction ( "tool-call-id" , {
381+ title : "Existing Note" ,
382+ content : "New content" ,
383+ folder : "notes" ,
384+ } )
385+
386+ const text = result . content [ 0 ] . text
387+ expect ( text ) . toContain ( 'Note already exists: "Existing Note"' )
388+ expect ( text ) . toContain ( "notes/existing-note" )
389+ expect ( text ) . toContain ( "edit_note" )
390+ expect ( text ) . toContain ( "overwrite=true" )
391+ expect ( text ) . toContain ( "read_note" )
392+ } )
393+
335394 it ( "should handle write errors gracefully" , async ( ) => {
336395 const writeError = new Error ( "Failed to write note" )
337396 ; ( mockClient . writeNote as jest . MockedFunction < any > ) . mockRejectedValue (
@@ -385,6 +444,7 @@ Normal line
385444 formattedContent ,
386445 "notes" ,
387446 undefined ,
447+ undefined ,
388448 )
389449 } )
390450
@@ -412,6 +472,7 @@ Normal line
412472 "Content" ,
413473 "notes" ,
414474 undefined ,
475+ undefined ,
415476 )
416477 } )
417478
0 commit comments