fix(handlers/channels_test): use RowError() to trigger rows.Err() in List test
The previous approach of adding a second row with matching columns does
not trigger rows.Err() in sqlmock v1.5.2. rows.Err() is only set
when RowError(n, err) or SetError(err) is called explicitly.
Use RowError(0, errors.New("connection lost")) instead — this causes
Scan() to fail on row 0 and sets rows.Err() so the handler's new
rows.Err() check is exercised by the test.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
76609f4129
commit
740d3cbd42
@ -7,6 +7,7 @@ import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@ -1013,6 +1014,54 @@ func TestChannelHandler_Webhook_Discord_InvalidSig_Returns401(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestChannelHandler_List_RowsErr_LogsError verifies that when the row iterator
|
||||
// returns an error after the last row (mid-stream DB error), rows.Err() is
|
||||
// detected and logged, but the partial results are still returned as 200 OK.
|
||||
// This is the fix for the missing rows.Err() check in List().
|
||||
func TestChannelHandler_List_RowsErr_LogsError(t *testing.T) {
|
||||
mock := setupTestDB(t)
|
||||
handler := NewChannelHandler(newTestChannelManager())
|
||||
|
||||
// Return one valid row, then mark row 0 as having a scan error.
|
||||
// RowError(n, err) causes Scan() to fail on row n, and sets rows.Err()
|
||||
// to the error. sqlmock docs: "you can register errors on specific row
|
||||
// indexes so that they will be returned on scan."
|
||||
rows := sqlmock.NewRows([]string{
|
||||
"id", "workspace_id", "channel_type", "channel_config", "enabled",
|
||||
"allowed_users", "last_message_at", "message_count", "created_at", "updated_at",
|
||||
}).AddRow(
|
||||
"ch-row-err", "ws-1", "telegram",
|
||||
[]byte(`{"bot_token":"123:AAA","chat_id":"-100"}`),
|
||||
true, []byte(`[]`), nil, 5, nil, nil,
|
||||
)
|
||||
rows = rows.RowError(0, errors.New("connection lost"))
|
||||
|
||||
mock.ExpectQuery("SELECT .* FROM workspace_channels WHERE workspace_id").
|
||||
WithArgs("ws-1").
|
||||
WillReturnRows(rows)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request, _ = http.NewRequest("GET", "/workspaces/ws-1/channels", nil)
|
||||
c.Params = gin.Params{{Key: "id", Value: "ws-1"}}
|
||||
|
||||
handler.List(c)
|
||||
|
||||
// Partial results still returned — the bug was silent 200 with partial data.
|
||||
if w.Code != 200 {
|
||||
t.Errorf("expected 200 (partial results on rows.Err), got %d: %s", w.Code, w.Body.String())
|
||||
}
|
||||
// The rows.Err() is logged, not surfaced to the client (non-fatal).
|
||||
var result []map[string]interface{}
|
||||
json.Unmarshal(w.Body.Bytes(), &result)
|
||||
if len(result) == 0 {
|
||||
t.Error("expected at least partial results despite rows.Err")
|
||||
}
|
||||
if err := mock.ExpectationsWereMet(); err != nil {
|
||||
t.Errorf("sqlmock expectations not met: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestChannelHandler_Webhook_Discord_ValidSig_PingAccepted verifies that a
|
||||
// correctly signed Discord PING (type=1) passes the signature gate and the
|
||||
// handler returns 200 (PING returns nil msg → "ignored" status).
|
||||
|
||||
Loading…
Reference in New Issue
Block a user