@@ -1231,3 +1231,69 @@ func TestChatRoomShorthandFlag(t *testing.T) {
12311231 require .Len (t , envelope .Data , 1 )
12321232 assert .Equal (t , "Engineering" , envelope .Data [0 ]["title" ])
12331233}
1234+
1235+ // mockChatMessagesTransport captures the lines request and returns messages
1236+ // in desc order (as the API would with sort=created_at&direction=desc).
1237+ type mockChatMessagesTransport struct {
1238+ capturedQuery map [string ]string
1239+ }
1240+
1241+ func (t * mockChatMessagesTransport ) RoundTrip (req * http.Request ) (* http.Response , error ) {
1242+ header := make (http.Header )
1243+ header .Set ("Content-Type" , "application/json" )
1244+
1245+ var body string
1246+ switch {
1247+ case strings .Contains (req .URL .Path , "/projects.json" ):
1248+ body = `[{"id": 123, "name": "Test Project"}]`
1249+ case strings .Contains (req .URL .Path , "/projects/123" ):
1250+ body = `{"id": 123, "dock": [{"name": "chat", "id": 789, "enabled": true}]}`
1251+ case strings .Contains (req .URL .Path , "/lines.json" ):
1252+ t .capturedQuery = map [string ]string {
1253+ "sort" : req .URL .Query ().Get ("sort" ),
1254+ "direction" : req .URL .Query ().Get ("direction" ),
1255+ }
1256+ // Return 3 messages in desc order (newest first), as the API does
1257+ body = `[
1258+ {"id": 3, "content": "Third", "created_at": "2026-03-24T12:00:00Z", "status": "active", "visible_to_clients": false, "inherits_status": true, "type": "Chat::Lines::Text", "url": "https://example.com", "app_url": "https://example.com"},
1259+ {"id": 2, "content": "Second", "created_at": "2026-03-24T11:00:00Z", "status": "active", "visible_to_clients": false, "inherits_status": true, "type": "Chat::Lines::Text", "url": "https://example.com", "app_url": "https://example.com"},
1260+ {"id": 1, "content": "First", "created_at": "2026-03-24T10:00:00Z", "status": "active", "visible_to_clients": false, "inherits_status": true, "type": "Chat::Lines::Text", "url": "https://example.com", "app_url": "https://example.com"}
1261+ ]`
1262+ default :
1263+ body = `{}`
1264+ }
1265+
1266+ return & http.Response {
1267+ StatusCode : 200 ,
1268+ Body : io .NopCloser (strings .NewReader (body )),
1269+ Header : header ,
1270+ }, nil
1271+ }
1272+
1273+ // TestChatMessagesReturnsNewestInChronologicalOrder verifies that
1274+ // `chat messages` requests newest-first from the API (sort/direction params),
1275+ // respects --limit to truncate the result, and renders in chronological order.
1276+ func TestChatMessagesReturnsNewestInChronologicalOrder (t * testing.T ) {
1277+ transport := & mockChatMessagesTransport {}
1278+ app , buf := newTestAppWithTransport (t , transport )
1279+
1280+ cmd := NewChatCmd ()
1281+ // --limit 2: the mock returns 3 messages; only the 2 newest should appear
1282+ err := executeChatCommand (cmd , app , "messages" , "--room" , "789" , "--in" , "123" , "--limit" , "2" )
1283+ require .NoError (t , err )
1284+
1285+ // Verify sort params were sent to the API
1286+ assert .Equal (t , "created_at" , transport .capturedQuery ["sort" ])
1287+ assert .Equal (t , "desc" , transport .capturedQuery ["direction" ])
1288+
1289+ // Verify limit is respected (2 of 3 returned) and output is chronological
1290+ var envelope struct {
1291+ Data []struct {
1292+ ID int64 `json:"id"`
1293+ } `json:"data"`
1294+ }
1295+ require .NoError (t , json .Unmarshal (buf .Bytes (), & envelope ))
1296+ require .Len (t , envelope .Data , 2 , "should return only 2 messages per --limit" )
1297+ assert .Equal (t , int64 (2 ), envelope .Data [0 ].ID , "first displayed should be older of the two" )
1298+ assert .Equal (t , int64 (3 ), envelope .Data [1 ].ID , "last displayed should be newest" )
1299+ }
0 commit comments