test(ai): pin the queue-updated event that now follows stream-error on the failure path (#22500)

## Rationale

main's `server-test` is red: 4 error-path tests in
`stream-agent-chat.job.spec.ts` fail. #22494 made the stream failure
path publish `queue-updated` **after** the terminal `stream-error` (so
background tabs refetch the persisted partial transcript), but these
specs still asserted `stream-error` is the *last* published event.
Classic squash-merge semantic conflict — #22494's branch predated the
spec assertions, both were green in isolation.

## Why this is the right fix (not patching a symptom)

The job behavior is the intended one from #22494; the specs encode the
old contract. Rather than loosening the assertions to "a stream-error
was published somewhere", this pins the full intended terminal sequence
— `stream-error` followed by `queue-updated` — so the convergence event
itself is now regression-tested on all four failure paths (mid-stream
provider error, setup rejection, persistence failure, missing
workspace).

## Impact

Unblocks `server-test` / `ci-server-status-check` for every open PR
(including #22498, which is needed to fix the dev-cluster migration
incident). Test-only change.

https://claude.ai/code/session_01Lyi6zTema2FMVVh8MD6c38

---
_Generated by [Claude
Code](https://claude.ai/code/session_01Lyi6zTema2FMVVh8MD6c38)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22500?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
This commit is contained in:
Félix Malfait
2026-07-02 23:32:49 +02:00
committed by GitHub
parent f00b6ae185
commit 5057f14df9
@@ -230,11 +230,14 @@ describe('StreamAgentChatJob', () => {
);
expect(chunkEvents).toHaveLength(TEXT_CHUNKS.length);
expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({
expect(publishedEvents[publishedEvents.length - 2]).toMatchObject({
type: 'stream-error',
code: 'STREAM_EXECUTION_FAILED',
message: 'provider exploded',
});
expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({
type: 'queue-updated',
});
expect(publishedEvents.map((event) => event.type)).not.toContain(
'message-persisted',
);
@@ -264,10 +267,13 @@ describe('StreamAgentChatJob', () => {
'model resolution failed',
);
expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({
expect(publishedEvents[publishedEvents.length - 2]).toMatchObject({
type: 'stream-error',
message: 'model resolution failed',
});
expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({
type: 'queue-updated',
});
expect(threadRepository.update).toHaveBeenCalledWith(
'workspace-id',
{ id: 'thread-id', activeStreamId: 'stream-id' },
@@ -287,9 +293,12 @@ describe('StreamAgentChatJob', () => {
);
expect(chunkEvents).toHaveLength(TEXT_CHUNKS.length);
expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({
expect(publishedEvents[publishedEvents.length - 2]).toMatchObject({
type: 'stream-error',
});
expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({
type: 'queue-updated',
});
expect(publishedEvents.map((event) => event.type)).not.toContain(
'message-persisted',
);
@@ -304,10 +313,13 @@ describe('StreamAgentChatJob', () => {
code: AiExceptionCode.WORKSPACE_NOT_FOUND,
});
expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({
expect(publishedEvents[publishedEvents.length - 2]).toMatchObject({
type: 'stream-error',
code: AiExceptionCode.WORKSPACE_NOT_FOUND,
});
expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({
type: 'queue-updated',
});
expect(threadRepository.update).toHaveBeenCalledWith(
'workspace-id',
{ id: 'thread-id' },