feat: initial Netts energy orchestrator
This commit is contained in:
185
internal/netts/client_test.go
Normal file
185
internal/netts/client_test.go
Normal file
@@ -0,0 +1,185 @@
|
||||
package netts
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
appconfig "github.com/D36u99er/bc-netts-energy/internal/config"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
func TestClientAnalyzeUSDT(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/apiv2/usdt/analyze":
|
||||
assert.Equal(t, http.MethodPost, r.Method)
|
||||
assert.Equal(t, "test-key", r.Header.Get("X-API-KEY"))
|
||||
_, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{
|
||||
"code": 0,
|
||||
"msg": "ok",
|
||||
"data": {
|
||||
"transfer_details": {
|
||||
"sender_address": "TFrom",
|
||||
"receiver_address": "TTo",
|
||||
"usdt_amount": "10.00",
|
||||
"recommended_energy": 131000,
|
||||
"energy_needed": 131000,
|
||||
"bandwidth_needed": 350,
|
||||
"cost_breakdown": {
|
||||
"energy_cost": "3.5",
|
||||
"bandwidth_cost": "1.0",
|
||||
"total_cost_trx": "4.5"
|
||||
},
|
||||
"savings_analysis": {
|
||||
"vs_direct_burn": "20.0",
|
||||
"vs_staking": "5.0",
|
||||
"savings_percentage": 80.5
|
||||
}
|
||||
}
|
||||
}
|
||||
}`))
|
||||
default:
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := newTestClient(server, t)
|
||||
|
||||
resp, err := client.AnalyzeUSDT(context.Background(), AnalyzeUSDTRequest{
|
||||
Sender: "TFrom",
|
||||
Receiver: "TTo",
|
||||
Amount: "10.00",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 131000, resp.TransferDetails.RecommendedEnergy)
|
||||
assert.Equal(t, 131000, resp.TransferDetails.EnergyNeeded)
|
||||
assert.InDelta(t, 80.5, resp.TransferDetails.SavingsAnalysis.SavingsPercentage, 0.01)
|
||||
}
|
||||
|
||||
func TestClientGetAddressStatus(t *testing.T) {
|
||||
calls := 0
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/apiv2/time/status/TExists":
|
||||
if calls == 0 {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{
|
||||
"code": 0,
|
||||
"msg": "ok",
|
||||
"data": {
|
||||
"address": "TExists",
|
||||
"mode": "normal",
|
||||
"status": "active",
|
||||
"cycles_remaining": 2,
|
||||
"open_orders": 0,
|
||||
"expiry_time": 1700000000
|
||||
}
|
||||
}`))
|
||||
}
|
||||
calls++
|
||||
case "/apiv2/time/status/TMissing":
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{
|
||||
"code": -1,
|
||||
"msg": "Address not found in Host Mode",
|
||||
"data": null
|
||||
}`))
|
||||
default:
|
||||
t.Fatalf("unexpected path %s", r.URL.Path)
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := newTestClient(server, t)
|
||||
|
||||
status, err := client.GetAddressStatus(context.Background(), "TExists")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 2, status.CyclesRemaining)
|
||||
|
||||
_, err = client.GetAddressStatus(context.Background(), "TMissing")
|
||||
require.Error(t, err)
|
||||
assert.ErrorIs(t, err, ErrAddressNotFound)
|
||||
}
|
||||
|
||||
func TestClientMutations(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/apiv2/time/add":
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{
|
||||
"code": 0,
|
||||
"msg": "Address added",
|
||||
"data": {
|
||||
"address": "TAdded",
|
||||
"callback_url": "https://callback",
|
||||
"timestamp": "2024-01-01T00:00:00Z"
|
||||
}
|
||||
}`))
|
||||
case "/apiv2/time/order":
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{
|
||||
"code": 0,
|
||||
"msg": "ok",
|
||||
"data": {
|
||||
"address": "TAdded",
|
||||
"cycles_purchased": 5,
|
||||
"total_cycles": 8,
|
||||
"previous_cycles": 3,
|
||||
"total_cost": 10.5,
|
||||
"price_per_cycle": 2.1,
|
||||
"order_id": "ORD-1",
|
||||
"transaction_hash": "hash",
|
||||
"payment_method": "account_balance",
|
||||
"balance_after": 100.5,
|
||||
"next_delegation_time": 1700000000,
|
||||
"expiry_time": 1700100000,
|
||||
"status": "confirmed"
|
||||
}
|
||||
}`))
|
||||
default:
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := newTestClient(server, t)
|
||||
|
||||
addResp, err := client.AddHostAddress(context.Background(), "TAdded", "https://callback")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "TAdded", addResp.Address)
|
||||
|
||||
orderResp, err := client.OrderCycles(context.Background(), "TAdded", 5)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 5, orderResp.CyclesPurchased)
|
||||
assert.Equal(t, "ORD-1", orderResp.OrderID)
|
||||
}
|
||||
|
||||
func newTestClient(server *httptest.Server, t *testing.T) *Client {
|
||||
t.Helper()
|
||||
|
||||
cfg := appconfig.NettsConfig{
|
||||
APIKey: "test-key",
|
||||
BaseURL: server.URL,
|
||||
HTTPTimeout: appconfig.Duration(5 * time.Second),
|
||||
Retry: appconfig.Retry{
|
||||
MaxAttempts: 1,
|
||||
},
|
||||
}
|
||||
|
||||
logger := slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{Level: slog.LevelDebug}))
|
||||
httpClient := server.Client()
|
||||
|
||||
return New(cfg, logger, httpClient)
|
||||
}
|
||||
Reference in New Issue
Block a user