Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ describe('MessageInput', () => {
});
});

it('uploads the recording on completion and schedules submit when multiple async messages disabled', async () => {
it('uploads and sends the recording on completion when multiple async messages disabled', async () => {
// Auto-emit makes MediaRecorderMock.stop() trigger `dataavailable` like a real browser.
MediaRecorderMock.autoEmitDataOnStop = true;
const {
Expand All @@ -380,9 +380,14 @@ describe('MessageInput', () => {
});
// Mock getAppSettings so the SDK's upload config check doesn't make a real network request
vi.spyOn(client, 'getAppSettings').mockResolvedValue(fromPartial({}));
// Differs from the local preview URL, so the assertion below proves the upload's URL is sent.
const uploadedFileURL = 'https://cdn.example.com/recording.wav';
const uploadFileSpy = vi
.spyOn(channel, 'uploadFile')
.mockResolvedValue(fromPartial({ file: fileObjectURL }));
.mockResolvedValue(fromPartial({ file: uploadedFileURL }));
const sendMessageSpy = vi
.spyOn(channel, 'sendMessage')
.mockResolvedValue(fromPartial({}));
await renderComponent({
channelStateCtx: { channel },
chatCtx: { client },
Expand All @@ -399,6 +404,17 @@ describe('MessageInput', () => {
await waitFor(() => {
expect(uploadFileSpy).toHaveBeenCalledTimes(1);
});
await waitFor(() => {
expect(sendMessageSpy).toHaveBeenCalledTimes(1);
});
// The recording is sent as its uploaded attachment, without its local metadata.
const sentAttachments = sendMessageSpy.mock.calls[0][0].message.attachments ?? [];
expect(sentAttachments).toHaveLength(1);
expect(sentAttachments[0]).toMatchObject({
asset_url: uploadedFileURL,
type: 'voiceRecording',
});
expect(sentAttachments[0]).not.toHaveProperty('localMetadata');
});

it('uploads but does not submit message on recording completion and multiple async messages enabled', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export class MediaRecorderController {
)}`; // The extension is needed for desktop Safari to play the asset.
};

makeVoiceRecording = async () => {
makeVoiceRecording = async (): Promise<LocalVoiceRecordingAttachment | undefined> => {
if (this.recordingUri) URL.revokeObjectURL(this.recordingUri);

if (!this.recordedData.length) return;
Expand Down Expand Up @@ -186,10 +186,11 @@ export class MediaRecorderController {
localMetadata: {
file,
id: nanoid(),
uploadState: 'pending',
},
title: file.name,
type: RecordingAttachmentType.VOICE_RECORDING,
} as LocalVoiceRecordingAttachment;
};
};

handleErrorEvent = (e: Event) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,7 @@ describe('MediaRecorderController', () => {
localMetadata: {
file: recordedFile,
id: nanoidMockValue,
uploadState: 'pending',
},
title: recordedFile.name,
type: RecordingAttachmentType.VOICE_RECORDING,
Expand Down Expand Up @@ -745,6 +746,7 @@ describe('MediaRecorderController', () => {
localMetadata: {
file: recordedFile,
id: nanoidMockValue,
uploadState: 'pending',
},
title: recordedFile.name,
type: RecordingAttachmentType.VOICE_RECORDING,
Expand Down Expand Up @@ -787,6 +789,7 @@ describe('MediaRecorderController', () => {
localMetadata: {
file: recordedFile,
id: nanoidMockValue,
uploadState: 'pending',
},
title: recordedFile.name,
type: RecordingAttachmentType.VOICE_RECORDING,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,17 @@ status['state'] = defaultMockPermissionState;
query: vi.fn().mockResolvedValue(status),
};

// A recording as `MediaRecorderController.stop()` builds it: a voice recording with its file and local id.
// A recording as `MediaRecorderController.stop()` builds it: a voice recording with its file, local id
// and a pending upload.
const generateLocalVoiceRecording = () =>
({
...generateVoiceRecordingAttachment(),
localMetadata: {
file: new File(['audio'], 'recording.aac', { type: 'audio/aac' }),
id: 'recording-local-id',
uploadState: 'pending',
},
}) as unknown as LocalVoiceRecordingAttachment;
}) as LocalVoiceRecordingAttachment;

// Stands in for a successful `uploadFile()`, which adds the attachment to the composer.
const mockUploadFileAddingTheAttachment = (attachmentManager: AttachmentManager) =>
Expand Down
1 change: 1 addition & 0 deletions src/mock-builders/generator/attachment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const generateLocalFileUploadAttachmentData = (
) => ({
localMetadata: {
...generateLocalAttachmentData().localMetadata,
uploadState: 'pending',
...overrides,
file: generateFile(overrides?.file ?? {}),
},
Expand Down
Loading