email_view_test.go

  1package tui
  2
  3import (
  4	"testing"
  5	"time"
  6
  7	tea "charm.land/bubbletea/v2"
  8	"github.com/floatpane/matcha/fetcher"
  9)
 10
 11func TestEmailViewUpdate(t *testing.T) {
 12	emailWithAttachments := fetcher.Email{
 13		From:    "test@example.com",
 14		Subject: "Test Email with Attachments",
 15		Body:    "This is the body.",
 16		Date:    time.Now(),
 17		Attachments: []fetcher.Attachment{
 18			{Filename: "attachment1.txt", Data: []byte("attachment1")},
 19			{Filename: "attachment2.txt", Data: []byte("attachment2")},
 20		},
 21	}
 22
 23	emailWithoutAttachments := fetcher.Email{
 24		From:    "test@example.com",
 25		Subject: "Test Email without Attachments",
 26		Body:    "This is the body.",
 27		Date:    time.Now(),
 28	}
 29
 30	t.Run("Focus on attachments", func(t *testing.T) {
 31		emailView := NewEmailView(emailWithAttachments, 0, 80, 24, MailboxInbox, false)
 32		if emailView.focusOnAttachments {
 33			t.Error("focusOnAttachments should be initially false")
 34		}
 35
 36		// Tab to focus on attachments
 37		model, _ := emailView.Update(tea.KeyPressMsg{Code: tea.KeyTab})
 38		emailView = model.(*EmailView)
 39
 40		if !emailView.focusOnAttachments {
 41			t.Error("focusOnAttachments should be true after tabbing")
 42		}
 43
 44		// Tab back to body
 45		model, _ = emailView.Update(tea.KeyPressMsg{Code: tea.KeyTab})
 46		emailView = model.(*EmailView)
 47		if emailView.focusOnAttachments {
 48			t.Error("focusOnAttachments should be false after tabbing again")
 49		}
 50	})
 51
 52	t.Run("No focus on attachments when there are none", func(t *testing.T) {
 53		emailView := NewEmailView(emailWithoutAttachments, 0, 80, 24, MailboxInbox, false)
 54		if emailView.focusOnAttachments {
 55			t.Error("focusOnAttachments should be initially false")
 56		}
 57		// Tab
 58		model, _ := emailView.Update(tea.KeyPressMsg{Code: tea.KeyTab})
 59		emailView = model.(*EmailView)
 60		if emailView.focusOnAttachments {
 61			t.Error("focusOnAttachments should remain false when there are no attachments")
 62		}
 63	})
 64
 65	t.Run("Navigate attachments", func(t *testing.T) {
 66		emailView := NewEmailView(emailWithAttachments, 0, 80, 24, MailboxInbox, false)
 67		// Focus on attachments
 68		model, _ := emailView.Update(tea.KeyPressMsg{Code: tea.KeyTab})
 69		emailView = model.(*EmailView)
 70
 71		if emailView.attachmentCursor != 0 {
 72			t.Errorf("Initial attachmentCursor should be 0, got %d", emailView.attachmentCursor)
 73		}
 74
 75		// Move down
 76		model, _ = emailView.Update(tea.KeyPressMsg{Code: tea.KeyDown})
 77		emailView = model.(*EmailView)
 78		if emailView.attachmentCursor != 1 {
 79			t.Errorf("After one down arrow, attachmentCursor should be 1, got %d", emailView.attachmentCursor)
 80		}
 81
 82		// Move down again (should wrap to the first attachment)
 83		model, _ = emailView.Update(tea.KeyPressMsg{Code: tea.KeyDown})
 84		emailView = model.(*EmailView)
 85		if emailView.attachmentCursor != 0 {
 86			t.Errorf("attachmentCursor should wrap to the start of the list, got %d", emailView.attachmentCursor)
 87		}
 88
 89		// Move up (should wrap to the last attachment)
 90		model, _ = emailView.Update(tea.KeyPressMsg{Code: tea.KeyUp})
 91		emailView = model.(*EmailView)
 92		if emailView.attachmentCursor != 1 {
 93			t.Errorf("After one up arrow from the first item, attachmentCursor should be 1, got %d", emailView.attachmentCursor)
 94		}
 95	})
 96
 97	t.Run("Attachment navigation does not scroll body", func(t *testing.T) {
 98		emailView := NewEmailView(emailWithAttachments, 0, 80, 24, MailboxInbox, false)
 99		emailView.viewport.SetHeight(2)
100		emailView.viewport.SetContent("line 1\nline 2\nline 3\nline 4\nline 5\n")
101		emailView.viewport.SetYOffset(1)
102
103		model, _ := emailView.Update(tea.KeyPressMsg{Code: tea.KeyTab})
104		emailView = model.(*EmailView)
105		if !emailView.focusOnAttachments {
106			t.Fatal("focusOnAttachments should be true after tabbing")
107		}
108
109		before := emailView.viewport.YOffset()
110		model, _ = emailView.Update(tea.KeyPressMsg{Code: tea.KeyDown})
111		emailView = model.(*EmailView)
112		if got := emailView.viewport.YOffset(); got != before {
113			t.Fatalf("attachment navigation should not scroll the email body, got offset %d want %d", got, before)
114		}
115	})
116
117	t.Run("Download attachment", func(t *testing.T) {
118		emailView := NewEmailView(emailWithAttachments, 0, 80, 24, MailboxInbox, false)
119		// Focus on attachments
120		model, _ := emailView.Update(tea.KeyPressMsg{Code: tea.KeyTab})
121		emailView = model.(*EmailView)
122
123		// Move to the second attachment
124		model, _ = emailView.Update(tea.KeyPressMsg{Code: tea.KeyDown})
125		emailView = model.(*EmailView)
126
127		// Press enter
128		_, cmd := emailView.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
129		if cmd == nil {
130			t.Fatal("Expected a command, but got nil")
131		}
132
133		msg := cmd()
134		downloadMsg, ok := msg.(DownloadAttachmentMsg)
135		if !ok {
136			t.Fatalf("Expected a DownloadAttachmentMsg, but got %T", msg)
137		}
138		if downloadMsg.Filename != "attachment2.txt" {
139			t.Errorf("Expected to download 'attachment2.txt', but got '%s'", downloadMsg.Filename)
140		}
141		if downloadMsg.Mailbox != MailboxInbox {
142			t.Errorf("Expected mailbox to be MailboxInbox, got %s", downloadMsg.Mailbox)
143		}
144	})
145
146	t.Run("Reply to email", func(t *testing.T) {
147		emailView := NewEmailView(emailWithAttachments, 0, 80, 24, MailboxInbox, false)
148
149		_, cmd := emailView.Update(tea.KeyPressMsg{Code: 'r', Text: "r"})
150		if cmd == nil {
151			t.Fatal("Expected a command, but got nil")
152		}
153
154		msg := cmd()
155		replyMsg, ok := msg.(ReplyToEmailMsg)
156		if !ok {
157			t.Fatalf("Expected a ReplyToEmailMsg, but got %T", msg)
158		}
159		if replyMsg.Email.Subject != emailWithAttachments.Subject {
160			t.Errorf("Expected reply to have subject '%s', but got '%s'", emailWithAttachments.Subject, replyMsg.Email.Subject)
161		}
162	})
163}