-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ARCO-202: Adding unit test for callerback sender
- Loading branch information
1 parent
dd704e1
commit 12c73f3
Showing
1 changed file
with
176 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
package callbacker_test | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"github.com/bitcoin-sv/arc/internal/callbacker" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
"log/slog" | ||
"net/http" | ||
"net/http/httptest" | ||
"sync" | ||
"testing" | ||
) | ||
|
||
func TestCallbackSender_Send(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
responseStatus int | ||
expectedSuccess bool | ||
expectedRetries int | ||
}{ | ||
{ | ||
name: "success - callback sent", | ||
responseStatus: http.StatusOK, | ||
expectedSuccess: true, | ||
expectedRetries: 1, | ||
}, | ||
} | ||
|
||
for _, tc := range tests { | ||
t.Run(tc.name, func(t *testing.T) { | ||
// Given | ||
retries := 0 | ||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
w.WriteHeader(tc.responseStatus) | ||
retries++ | ||
})) | ||
defer server.Close() | ||
logger := slog.New(slog.NewTextHandler(new(bytes.Buffer), nil)) | ||
sender, err := callbacker.NewSender(server.Client(), logger) | ||
require.NoError(t, err) | ||
defer sender.GracefulStop() | ||
|
||
// When | ||
success := sender.Send(server.URL, "test-token", &callbacker.Callback{TxID: "1234", TxStatus: "SEEN_ON_NETWORK"}) | ||
|
||
// Then | ||
require.Equal(t, tc.expectedSuccess, success) | ||
require.Equal(t, tc.expectedRetries, retries) | ||
}) | ||
} | ||
} | ||
|
||
func TestCallbackSender_GracefulStop(t *testing.T) { | ||
// Given | ||
logger := slog.New(slog.NewTextHandler(new(bytes.Buffer), nil)) | ||
sender, err := callbacker.NewSender(http.DefaultClient, logger) | ||
require.NoError(t, err) | ||
|
||
// When: Call GracefulStop twice to ensure it handles double stop gracefully | ||
sender.GracefulStop() | ||
sender.GracefulStop() | ||
|
||
// Then: Assert that sender is disposed | ||
err = sender.Health() | ||
require.EqualError(t, err, "callbacker is disposed already") | ||
} | ||
|
||
func TestCallbackSender_Health(t *testing.T) { | ||
// Given | ||
logger := slog.New(slog.NewTextHandler(new(bytes.Buffer), nil)) | ||
sender, err := callbacker.NewSender(http.DefaultClient, logger) | ||
require.NoError(t, err) | ||
|
||
// When: Test Health on active sender | ||
err = sender.Health() | ||
|
||
// Then: Expect no error when sender is active | ||
require.NoError(t, err) | ||
|
||
// When: Stop sender and check Health error | ||
sender.GracefulStop() | ||
err = sender.Health() | ||
|
||
// Then: Expect error indicating the sender is disposed | ||
require.EqualError(t, err, "callbacker is disposed already") | ||
} | ||
|
||
func TestCallbackSender_SendBatch(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
url string | ||
token string | ||
dtos []*callbacker.Callback | ||
responseStatus int | ||
expectedSuccess bool | ||
}{ | ||
{ | ||
name: "success - batch sent", | ||
url: "/batch", | ||
token: "test-token", | ||
dtos: []*callbacker.Callback{{TxID: "1234", TxStatus: "SEEN_ON_NETWORK"}, {TxID: "5678", TxStatus: "MINED"}}, | ||
responseStatus: http.StatusOK, | ||
expectedSuccess: true, | ||
}, | ||
} | ||
|
||
for _, tc := range tests { | ||
t.Run(tc.name, func(t *testing.T) { | ||
// Given | ||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
require.Equal(t, "Bearer "+tc.token, r.Header.Get("Authorization")) | ||
|
||
var batch callbacker.BatchCallback | ||
err := json.NewDecoder(r.Body).Decode(&batch) | ||
require.NoError(t, err) | ||
require.Equal(t, len(tc.dtos), batch.Count) | ||
|
||
w.WriteHeader(tc.responseStatus) | ||
})) | ||
defer server.Close() | ||
|
||
logger := slog.New(slog.NewTextHandler(new(bytes.Buffer), nil)) | ||
sender, err := callbacker.NewSender(server.Client(), logger) | ||
require.NoError(t, err) | ||
defer sender.GracefulStop() | ||
|
||
// When | ||
success := sender.SendBatch(server.URL+tc.url, tc.token, tc.dtos) | ||
|
||
// Then | ||
require.Equal(t, tc.expectedSuccess, success) | ||
}) | ||
} | ||
} | ||
|
||
func TestCallbackSender_Send_WithRetries(t *testing.T) { | ||
// Given | ||
client := &http.Client{} | ||
logger := slog.New(slog.NewJSONHandler(bytes.NewBuffer([]byte{}), nil)) | ||
sender, _ := callbacker.NewSender(client, logger) | ||
|
||
retryCount := 0 | ||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
retryCount++ | ||
if retryCount < 3 { | ||
w.WriteHeader(http.StatusInternalServerError) | ||
return | ||
} | ||
w.WriteHeader(http.StatusOK) | ||
})) | ||
defer server.Close() | ||
|
||
// When | ||
callback := &callbacker.Callback{TxID: "test-txid", TxStatus: "SEEN_ON_NETWORK"} | ||
ok := sender.Send(server.URL, "test-token", callback) | ||
|
||
// Then | ||
assert.True(t, ok) | ||
} | ||
|
||
var ( | ||
once sync.Once | ||
Check failure on line 164 in internal/callbacker/sender_test.go GitHub Actions / Golangci-lint
|
||
testSender *callbacker.CallbackSender | ||
Check failure on line 165 in internal/callbacker/sender_test.go GitHub Actions / Golangci-lint
|
||
) | ||
|
||
func getTestSender(t *testing.T) *callbacker.CallbackSender { | ||
Check failure on line 168 in internal/callbacker/sender_test.go GitHub Actions / Golangci-lint
|
||
var err error | ||
once.Do(func() { | ||
logger := slog.New(slog.NewTextHandler(new(bytes.Buffer), nil)) | ||
testSender, err = callbacker.NewSender(http.DefaultClient, logger) | ||
}) | ||
require.NoError(t, err) | ||
return testSender | ||
} |