@@ -16,7 +16,10 @@ class MessageComposerView_Tests: StreamChatTestCase {
1616 override func setUp( ) {
1717 super. setUp ( )
1818 let utils = Utils (
19- messageListConfig: MessageListConfig ( becomesFirstResponderOnOpen: true ) ,
19+ messageListConfig: MessageListConfig (
20+ becomesFirstResponderOnOpen: true ,
21+ draftMessagesEnabled: true
22+ ) ,
2023 composerConfig: ComposerConfig ( isVoiceRecordingEnabled: true )
2124 )
2225 streamChat = StreamChat ( chatClient: chatClient, utils: utils)
@@ -439,4 +442,151 @@ class MessageComposerView_Tests: StreamChatTestCase {
439442 streamChat? . appearance. colors. staticColorText = . black
440443 AssertSnapshot ( view, variants: . onlyUserInterfaceStyles, size: size, suffix: " themed " )
441444 }
445+
446+ // MARK: - Drafts
447+
448+ // Note: For some reason the text is not rendered in the composer,
449+ // Maybe it's because of the `UITextView` that is used in the `InputTextView`.
450+ // Either way, the test of the content is covered.
451+
452+ func test_composerView_draftWithImageAttachment( ) throws {
453+ let size = CGSize ( width: defaultScreenSize. width, height: 200 )
454+ let mockDraftMessage = DraftMessage . mock (
455+ attachments: [
456+ . dummy(
457+ type: . image,
458+ payload: try JSONEncoder ( ) . encode (
459+ ImageAttachmentPayload (
460+ title: nil ,
461+ imageRemoteURL: TestImages . yoda. url,
462+ file: . init( type: . jpeg, size: 10 , mimeType: nil )
463+ )
464+ )
465+ ) ,
466+ . dummy(
467+ type: . image,
468+ payload: try JSONEncoder ( ) . encode (
469+ ImageAttachmentPayload (
470+ title: nil ,
471+ imageRemoteURL: TestImages . chewbacca. url,
472+ file: . init( type: . jpeg, size: 10 , mimeType: nil )
473+ )
474+ )
475+ )
476+ ]
477+ )
478+
479+ let view = makeComposerView ( with: mockDraftMessage)
480+ . frame ( width: size. width, height: size. height)
481+
482+ AssertSnapshot ( view, variants: [ . defaultLight] , size: size)
483+ }
484+
485+ func test_composerView_draftWithVideoAttachment( ) throws {
486+ let size = CGSize ( width: defaultScreenSize. width, height: 200 )
487+ let mockDraftMessage = DraftMessage . mock (
488+ attachments: [
489+ . dummy(
490+ type: . video,
491+ payload: try JSONEncoder ( ) . encode (
492+ VideoAttachmentPayload (
493+ title: nil ,
494+ videoRemoteURL: TestImages . yoda. url,
495+ thumbnailURL: TestImages . yoda. url,
496+ file: . init( type: . mov, size: 10 , mimeType: nil ) ,
497+ extraData: nil
498+ )
499+ )
500+ )
501+ ]
502+ )
503+
504+ let view = makeComposerView ( with: mockDraftMessage)
505+ . frame ( width: size. width, height: size. height)
506+
507+ AssertSnapshot ( view, variants: [ . defaultLight] , size: size)
508+ }
509+
510+ func test_composerView_draftWithFileAttachment( ) throws {
511+ let size = CGSize ( width: defaultScreenSize. width, height: 200 )
512+ let mockDraftMessage = DraftMessage . mock (
513+ attachments: [
514+ . dummy(
515+ type: . file,
516+ payload: try JSONEncoder ( ) . encode (
517+ FileAttachmentPayload (
518+ title: " Test " ,
519+ assetRemoteURL: . localYodaQuote,
520+ file: . init( type: . txt, size: 10 , mimeType: nil ) ,
521+ extraData: nil
522+ )
523+ )
524+ )
525+ ]
526+ )
527+ let view = makeComposerView ( with: mockDraftMessage)
528+ . frame ( width: size. width, height: size. height)
529+
530+ AssertSnapshot ( view, variants: [ . defaultLight] , size: size)
531+ }
532+
533+ func test_composerView_draftWithVoiceRecordingAttachment( ) throws {
534+ let url : URL = URL ( fileURLWithPath: " /tmp/ \( UUID ( ) . uuidString) " )
535+ let duration : TimeInterval = 100
536+ let waveformData : [ Float ] = . init( repeating: 0.5 , count: 10 )
537+ try Data ( count: 1024 ) . write ( to: url)
538+ defer { try ? FileManager . default. removeItem ( at: url) }
539+
540+ let size = CGSize ( width: defaultScreenSize. width, height: 200 )
541+ let mockDraftMessage = DraftMessage . mock (
542+ attachments: [
543+ . dummy(
544+ type: . voiceRecording,
545+ payload: try JSONEncoder ( ) . encode (
546+ VoiceRecordingAttachmentPayload (
547+ title: " Audio " ,
548+ voiceRecordingRemoteURL: url,
549+ file: . init( type: . aac, size: 120 , mimeType: " audio/aac " ) ,
550+ duration: duration,
551+ waveformData: waveformData,
552+ extraData: nil
553+ )
554+ )
555+ )
556+ ]
557+ )
558+ let view = makeComposerView ( with: mockDraftMessage)
559+ . frame ( width: size. width, height: size. height)
560+
561+ AssertSnapshot ( view, variants: [ . defaultLight] , size: size)
562+ }
563+
564+ func test_composerView_draftWithCommand( ) throws {
565+ let size = CGSize ( width: defaultScreenSize. width, height: 100 )
566+ let mockDraftMessage = DraftMessage . mock (
567+ text: " /giphy test "
568+ )
569+
570+ let view = makeComposerView ( with: mockDraftMessage)
571+ . frame ( width: size. width, height: size. height)
572+
573+ AssertSnapshot ( view, variants: [ . defaultLight] , size: size)
574+ }
575+
576+ private func makeComposerView( with draftMessage: DraftMessage ) -> some View {
577+ let factory = DefaultViewFactory . shared
578+ let channelController = ChatChannelTestHelpers . makeChannelController ( chatClient: chatClient)
579+ let viewModel = MessageComposerViewModel ( channelController: channelController, messageController: nil )
580+ viewModel. fillDraftMessage ( draftMessage)
581+
582+ var quotedMessage : ChatMessage ?
583+ return MessageComposerView (
584+ viewFactory: factory,
585+ viewModel: viewModel,
586+ channelController: channelController,
587+ quotedMessage: . init( get: { quotedMessage } , set: { quotedMessage = $0 } ) ,
588+ editedMessage: . constant( nil ) ,
589+ onMessageSent: { }
590+ )
591+ }
442592}
0 commit comments