@@ -131,3 +131,188 @@ async def test_clears_input_after_filtering_and_selecting(self, app):
131131
132132 assert text_area .text == ""
133133 app .mock_actions .save .assert_called_once ()
134+
135+
136+ class TestUserInputHistory :
137+ @pytest .fixture
138+ def app (self ):
139+ return UserInputApp ()
140+
141+ async def test_up_arrow_on_empty_history_does_nothing (self , app ):
142+ async with app .run_test () as pilot :
143+ user_input = app .query_one (UserInput )
144+ text_area = user_input .query_one (TextArea )
145+
146+ await pilot .press ("up" )
147+
148+ assert text_area .text == ""
149+ assert user_input .history_index is None
150+
151+ async def test_up_arrow_loads_last_message (self , app ):
152+ async with app .run_test () as pilot :
153+ user_input = app .query_one (UserInput )
154+ text_area = user_input .query_one (TextArea )
155+
156+ text_area .insert ("first message" )
157+ await pilot .press ("enter" )
158+
159+ await pilot .press ("up" )
160+
161+ assert text_area .text == "first message"
162+ assert user_input .history_index == 0
163+
164+ async def test_up_arrow_twice_loads_older_messages (self , app ):
165+ async with app .run_test () as pilot :
166+ user_input = app .query_one (UserInput )
167+ text_area = user_input .query_one (TextArea )
168+
169+ text_area .insert ("first message" )
170+ await pilot .press ("enter" )
171+
172+ text_area .insert ("second message" )
173+ await pilot .press ("enter" )
174+
175+ await pilot .press ("up" )
176+ assert text_area .text == "second message"
177+ assert user_input .history_index == 1
178+
179+ await pilot .press ("up" )
180+ assert text_area .text == "first message"
181+ assert user_input .history_index == 0
182+
183+ async def test_up_arrow_at_oldest_does_nothing (self , app ):
184+ async with app .run_test () as pilot :
185+ user_input = app .query_one (UserInput )
186+ text_area = user_input .query_one (TextArea )
187+
188+ text_area .insert ("only message" )
189+ await pilot .press ("enter" )
190+
191+ await pilot .press ("up" )
192+ await pilot .press ("up" )
193+
194+ assert text_area .text == "only message"
195+ assert user_input .history_index == 0
196+
197+ async def test_down_arrow_navigates_forward (self , app ):
198+ async with app .run_test () as pilot :
199+ user_input = app .query_one (UserInput )
200+ text_area = user_input .query_one (TextArea )
201+
202+ text_area .insert ("first message" )
203+ await pilot .press ("enter" )
204+
205+ text_area .insert ("second message" )
206+ await pilot .press ("enter" )
207+
208+ await pilot .press ("up" )
209+ await pilot .press ("up" )
210+ assert text_area .text == "first message"
211+
212+ await pilot .press ("down" )
213+ assert text_area .text == "second message"
214+ assert user_input .history_index == 1
215+
216+ async def test_down_arrow_at_present_does_nothing (self , app ):
217+ async with app .run_test () as pilot :
218+ user_input = app .query_one (UserInput )
219+ text_area = user_input .query_one (TextArea )
220+
221+ text_area .insert ("test message" )
222+ await pilot .press ("enter" )
223+
224+ await pilot .press ("down" )
225+
226+ assert text_area .text == ""
227+ assert user_input .history_index is None
228+
229+ async def test_down_arrow_from_history_restores_draft (self , app ):
230+ async with app .run_test () as pilot :
231+ user_input = app .query_one (UserInput )
232+ text_area = user_input .query_one (TextArea )
233+
234+ text_area .insert ("first message" )
235+ await pilot .press ("enter" )
236+
237+ text_area .insert ("my draft" )
238+ await pilot .press ("up" )
239+ assert text_area .text == "first message"
240+
241+ await pilot .press ("down" )
242+ assert text_area .text == "my draft"
243+ assert user_input .history_index is None
244+
245+ async def test_empty_draft_preserved (self , app ):
246+ async with app .run_test () as pilot :
247+ user_input = app .query_one (UserInput )
248+ text_area = user_input .query_one (TextArea )
249+
250+ text_area .insert ("first message" )
251+ await pilot .press ("enter" )
252+
253+ await pilot .press ("up" )
254+ assert text_area .text == "first message"
255+
256+ await pilot .press ("down" )
257+ assert text_area .text == ""
258+ assert user_input .history_index is None
259+
260+ async def test_submit_adds_to_history (self , app ):
261+ async with app .run_test () as pilot :
262+ user_input = app .query_one (UserInput )
263+ text_area = user_input .query_one (TextArea )
264+
265+ text_area .insert ("test message" )
266+ await pilot .press ("enter" )
267+
268+ assert len (user_input .message_history ) == 1
269+ assert user_input .message_history [0 ] == "test message"
270+
271+ async def test_submit_resets_history_state (self , app ):
272+ async with app .run_test () as pilot :
273+ user_input = app .query_one (UserInput )
274+ text_area = user_input .query_one (TextArea )
275+
276+ text_area .insert ("first message" )
277+ await pilot .press ("enter" )
278+
279+ await pilot .press ("up" )
280+ assert user_input .history_index == 0
281+
282+ text_area .clear ()
283+ text_area .insert ("second message" )
284+ await pilot .press ("enter" )
285+
286+ assert user_input .history_index is None
287+ assert user_input .draft_message == ""
288+
289+ async def test_multiline_message_in_history (self , app ):
290+ async with app .run_test () as pilot :
291+ user_input = app .query_one (UserInput )
292+ text_area = user_input .query_one (TextArea )
293+
294+ text_area .insert ("line1" )
295+ await pilot .press ("ctrl+j" )
296+ text_area .insert ("line2" )
297+ await pilot .press ("enter" )
298+
299+ await pilot .press ("up" )
300+
301+ assert "line1\n line2" in text_area .text
302+
303+ async def test_history_with_slash_menu_open (self , app ):
304+ async with app .run_test () as pilot :
305+ user_input = app .query_one (UserInput )
306+ text_area = user_input .query_one (TextArea )
307+ menu = user_input .query_one (SlashCommandMenu )
308+
309+ text_area .insert ("test message" )
310+ await pilot .press ("enter" )
311+
312+ await pilot .press ("/" )
313+ assert menu .is_visible is True
314+
315+ await pilot .press ("up" )
316+
317+ assert text_area .text == ""
318+ assert user_input .history_index is None
0 commit comments