@@ -52,6 +52,76 @@ func TestBDD_Preview_EnterOpensFullscreen(t *testing.T) {
5252 assert .Equal (t , viewEmailReader , m .view )
5353}
5454
55+ // BDD: As a user, after selecting an email, Tab cycles focus to the preview pane.
56+ func TestBDD_Preview_TabCyclesToPreview (t * testing.T ) {
57+ m := setupDashboardWithEmails (t )
58+
59+ // Given: I've selected an email so preview is showing
60+ email := fastmail.Email {ID : "e1" , Subject : "Hello" , Body : "World" ,
61+ From : fastmail.EmailAddress {Name : "Alice" , Email : "alice@test.com" }}
62+ er := newEmailReaderModel (email )
63+ er .isPreview = true
64+ er .setSize (80 , 15 )
65+ m .emailReader = & er
66+ m .panes .focus = PaneEmailList
67+
68+ // When: I press Tab
69+ m , _ = applyUpdate (m , tea.KeyMsg {Type : tea .KeyTab })
70+
71+ // Then: focus moves to PanePreview (not past it)
72+ assert .Equal (t , PanePreview , m .panes .focus )
73+ }
74+
75+ // BDD: As a user, when preview pane is focused, keys route to the email reader
76+ // (not the email list). Pressing 'j' should NOT move the email list cursor.
77+ func TestBDD_Preview_KeysRouteToReader (t * testing.T ) {
78+ m := setupDashboardWithEmails (t )
79+
80+ // Given: preview is showing with a loaded email and focus is on preview
81+ email := fastmail.Email {ID : "e1" , Subject : "Hello" , Body : "Long email body\n \n \n \n \n \n \n \n \n \n \n \n Bottom" ,
82+ From : fastmail.EmailAddress {Name : "Alice" , Email : "alice@test.com" }}
83+ er := newEmailReaderModel (email )
84+ er .isPreview = true
85+ er .setSize (80 , 10 )
86+ // Simulate body loaded so viewport is initialized
87+ er , _ = er .update (emailBodyLoadedMsg {email : email })
88+ m .emailReader = & er
89+ m .panes .focus = PanePreview
90+
91+ // Record email list cursor before keypress
92+ cursorBefore := m .emailList .list .Index ()
93+
94+ // When: I press 'j' (which scrolls in reader, moves cursor in list)
95+ m , _ = applyUpdate (m , tea.KeyMsg {Type : tea .KeyRunes , Runes : []rune ("j" )})
96+
97+ // Then: the email list cursor should NOT have moved (key went to reader, not list)
98+ assert .Equal (t , cursorBefore , m .emailList .list .Index (),
99+ "j should route to email reader when preview is focused, not move the email list cursor" )
100+ }
101+
102+ // BDD: As a user, pressing 'q' with preview focused dismisses the preview, not quits.
103+ func TestBDD_Preview_QDismissesPreview (t * testing.T ) {
104+ m := setupDashboardWithEmails (t )
105+
106+ // Given: preview is showing and focused
107+ email := fastmail.Email {ID : "e1" , Subject : "Hello" }
108+ er := newEmailReaderModel (email )
109+ er .isPreview = true
110+ er .setSize (80 , 10 )
111+ m .emailReader = & er
112+ m .panes .focus = PanePreview
113+
114+ // When: I press 'q'
115+ m , _ = applyUpdate (m , tea.KeyMsg {Type : tea .KeyRunes , Runes : []rune ("q" )})
116+
117+ // Then: the app should NOT quit
118+ assert .False (t , m .quit , "q should dismiss preview, not quit the app" )
119+ // And: preview should be cleared
120+ assert .Nil (t , m .emailReader )
121+ // And: focus should move back to email list
122+ assert .Equal (t , PaneEmailList , m .panes .focus )
123+ }
124+
55125func setupDashboardWithEmails (t * testing.T ) Model {
56126 t .Helper ()
57127 m := New (nil )
0 commit comments