MCPcopy Create free account
hub / github.com/coder/agentapi / Test_ErrorRemovesPartialMessage

Function Test_ErrorRemovesPartialMessage

x/acpio/acp_conversation_test.go:482–553  ·  view source on GitHub ↗
(t *testing.T)

Source from the content-addressed store, hash-verified

480}
481
482func Test_ErrorRemovesPartialMessage(t *testing.T) {
483 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
484 defer cancel()
485
486 mClock := quartz.NewMock(t)
487 mock := newMockAgentIO()
488 emitter := newMockEmitter()
489 // Block the write so we can simulate partial content before error
490 started, done := mock.BlockWrite()
491
492 conv := acpio.NewACPConversation(ctx, mock, nil, nil, emitter, mClock)
493 conv.Start(ctx)
494
495 // Send blocks, so run in a goroutine
496 errCh := make(chan error, 1)
497 go func() { errCh <- conv.Send(screentracker.MessagePartText{Content: "test"}) }()
498
499 // Wait for write to start
500 <-started
501
502 // Should have user message + placeholder agent message
503 messages := conv.Messages()
504 require.Len(t, messages, 2)
505 assert.Equal(t, screentracker.ConversationRoleUser, messages[0].Role)
506 assert.Equal(t, screentracker.ConversationRoleAgent, messages[1].Role)
507
508 // Simulate the agent streaming partial content before the error
509 mock.SimulateChunks("partial ", "response ", "content")
510
511 // Verify partial content is in the agent message
512 messages = conv.Messages()
513 require.Len(t, messages, 2)
514 assert.Equal(t, "partial response content", messages[1].Message)
515
516 // Now configure the mock to return an error and unblock
517 mock.mu.Lock()
518 mock.writeErr = assert.AnError
519 mock.mu.Unlock()
520 close(done)
521
522 // Send should return the error
523 require.ErrorIs(t, <-errCh, assert.AnError)
524
525 // The partial agent message should be removed on error.
526 // Only the user message should remain.
527 messages = conv.Messages()
528 require.Len(t, messages, 1, "partial agent message should be removed on error")
529 assert.Equal(t, screentracker.ConversationRoleUser, messages[0].Role)
530 assert.Equal(t, "test", messages[0].Message)
531
532 // First exchange allocated IDs 0 (user) and 1 (agent, now removed).
533 assert.Equal(t, 0, messages[0].Id)
534
535 // Send a second message — IDs must not reuse the removed agent message's ID (1).
536 mock.mu.Lock()
537 mock.writeErr = nil
538 mock.mu.Unlock()
539 started2, done2 := mock.BlockWrite()

Callers

nothing calls this directly

Calls 8

StartMethod · 0.95
SendMethod · 0.95
MessagesMethod · 0.95
NewACPConversationFunction · 0.92
newMockAgentIOFunction · 0.85
newMockEmitterFunction · 0.85
BlockWriteMethod · 0.80
SimulateChunksMethod · 0.80

Tested by

no test coverage detected