All checks were successful
ci/woodpecker/push/billing_fees Pipeline was successful
ci/woodpecker/push/bff Pipeline was successful
ci/woodpecker/push/db Pipeline was successful
ci/woodpecker/push/chain_gateway Pipeline was successful
ci/woodpecker/push/fx_ingestor Pipeline was successful
ci/woodpecker/push/fx_oracle Pipeline was successful
ci/woodpecker/push/frontend Pipeline was successful
ci/woodpecker/push/nats Pipeline was successful
ci/woodpecker/push/ledger Pipeline was successful
ci/woodpecker/push/notification Pipeline was successful
ci/woodpecker/push/payments_orchestrator Pipeline was successful
215 lines
6.3 KiB
Go
215 lines
6.3 KiB
Go
package accountapiimp_test
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/tech/sendico/pkg/model"
|
|
"github.com/tech/sendico/server/interface/api/srequest"
|
|
"github.com/testcontainers/testcontainers-go"
|
|
"github.com/testcontainers/testcontainers-go/modules/mongodb"
|
|
"github.com/testcontainers/testcontainers-go/wait"
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
)
|
|
|
|
// Helper function to create string pointers
|
|
func stringPtr(s string) *string {
|
|
return &s
|
|
}
|
|
|
|
// TestSignupRequestSerialization tests JSON marshaling/unmarshaling with real MongoDB
|
|
func TestSignupRequestSerialization(t *testing.T) {
|
|
if os.Getenv("RUN_DOCKER_TESTS") == "" {
|
|
t.Skip("skipping: docker-dependent integration test (set RUN_DOCKER_TESTS=1 to enable)")
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
|
defer cancel()
|
|
|
|
mongoContainer, err := mongodb.Run(ctx,
|
|
"mongo:latest",
|
|
mongodb.WithUsername("root"),
|
|
mongodb.WithPassword("password"),
|
|
testcontainers.WithWaitStrategy(wait.ForLog("Waiting for connections")),
|
|
)
|
|
require.NoError(t, err, "failed to start MongoDB container")
|
|
defer func() {
|
|
err := mongoContainer.Terminate(ctx)
|
|
require.NoError(t, err, "failed to terminate MongoDB container")
|
|
}()
|
|
|
|
mongoURI, err := mongoContainer.ConnectionString(ctx)
|
|
require.NoError(t, err, "failed to get MongoDB connection string")
|
|
|
|
clientOptions := options.Client().ApplyURI(mongoURI)
|
|
client, err := mongo.Connect(ctx, clientOptions)
|
|
require.NoError(t, err, "failed to connect to MongoDB")
|
|
defer func() {
|
|
err := client.Disconnect(ctx)
|
|
require.NoError(t, err, "failed to disconnect from MongoDB")
|
|
}()
|
|
|
|
db := client.Database("test_signup")
|
|
collection := db.Collection("signup_requests")
|
|
|
|
t.Run("StoreAndRetrieveSignupRequest", func(t *testing.T) {
|
|
signupRequest := srequest.Signup{
|
|
Account: model.AccountData{
|
|
LoginData: model.LoginData{
|
|
UserDataBase: model.UserDataBase{
|
|
Login: "test@example.com",
|
|
},
|
|
Password: "TestPassword123!",
|
|
},
|
|
Describable: model.Describable{
|
|
Name: "Test User",
|
|
},
|
|
},
|
|
Organization: model.Describable{
|
|
Name: "Test Organization",
|
|
},
|
|
OrganizationTimeZone: "UTC",
|
|
OwnerRole: model.Describable{
|
|
Name: "Owner",
|
|
},
|
|
}
|
|
|
|
// Store in MongoDB
|
|
result, err := collection.InsertOne(ctx, signupRequest)
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, result.InsertedID)
|
|
|
|
// Retrieve from MongoDB
|
|
var retrieved srequest.Signup
|
|
err = collection.FindOne(ctx, map[string]interface{}{"_id": result.InsertedID}).Decode(&retrieved)
|
|
require.NoError(t, err)
|
|
|
|
// Verify data integrity
|
|
assert.Equal(t, signupRequest.Account.Login, retrieved.Account.Login)
|
|
assert.Equal(t, signupRequest.Account.Name, retrieved.Account.Name)
|
|
assert.Equal(t, signupRequest.Organization.Name, retrieved.Organization.Name)
|
|
assert.Equal(t, signupRequest.OrganizationTimeZone, retrieved.OrganizationTimeZone)
|
|
|
|
})
|
|
}
|
|
|
|
// TestSignupHTTPSerialization tests HTTP request/response serialization
|
|
func TestSignupHTTPSerialization(t *testing.T) {
|
|
signupRequest := srequest.Signup{
|
|
Account: model.AccountData{
|
|
LoginData: model.LoginData{
|
|
UserDataBase: model.UserDataBase{
|
|
Login: "test@example.com",
|
|
},
|
|
Password: "TestPassword123!",
|
|
},
|
|
Describable: model.Describable{
|
|
Name: "Test User",
|
|
},
|
|
},
|
|
Organization: model.Describable{
|
|
Name: "Test Organization",
|
|
},
|
|
OrganizationTimeZone: "UTC",
|
|
OwnerRole: model.Describable{
|
|
Name: "Owner",
|
|
},
|
|
}
|
|
|
|
t.Run("ValidJSONRequest", func(t *testing.T) {
|
|
// Serialize to JSON
|
|
reqBody, err := json.Marshal(signupRequest)
|
|
require.NoError(t, err)
|
|
|
|
// Create HTTP request
|
|
req := httptest.NewRequest(http.MethodPost, "/signup", bytes.NewBuffer(reqBody))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
// Parse the request body
|
|
var parsedRequest srequest.Signup
|
|
err = json.NewDecoder(req.Body).Decode(&parsedRequest)
|
|
require.NoError(t, err)
|
|
|
|
// Verify parsing
|
|
assert.Equal(t, signupRequest.Account.Login, parsedRequest.Account.Login)
|
|
assert.Equal(t, signupRequest.Account.Name, parsedRequest.Account.Name)
|
|
assert.Equal(t, signupRequest.Organization.Name, parsedRequest.Organization.Name)
|
|
})
|
|
|
|
t.Run("UnicodeCharacters", func(t *testing.T) {
|
|
unicodeRequest := signupRequest
|
|
unicodeRequest.Account.Name = "Test 用户 Üser"
|
|
unicodeRequest.Organization.Name = "测试 Organization"
|
|
|
|
// Serialize to JSON
|
|
reqBody, err := json.Marshal(unicodeRequest)
|
|
require.NoError(t, err)
|
|
|
|
// Parse back
|
|
var parsedRequest srequest.Signup
|
|
err = json.Unmarshal(reqBody, &parsedRequest)
|
|
require.NoError(t, err)
|
|
|
|
// Verify unicode characters are preserved
|
|
assert.Equal(t, "Test 用户 Üser", parsedRequest.Account.Name)
|
|
assert.Equal(t, "测试 Organization", parsedRequest.Organization.Name)
|
|
})
|
|
|
|
t.Run("InvalidJSONRequest", func(t *testing.T) {
|
|
invalidJSON := `{"account": {"login": "test@example.com", "password": "invalid json structure`
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/signup", bytes.NewBufferString(invalidJSON))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
var parsedRequest srequest.Signup
|
|
err := json.NewDecoder(req.Body).Decode(&parsedRequest)
|
|
assert.Error(t, err, "Should fail to parse invalid JSON")
|
|
})
|
|
}
|
|
|
|
// TestAccountDataConversion tests conversion between request and model types
|
|
func TestAccountDataConversion(t *testing.T) {
|
|
accountData := model.AccountData{
|
|
LoginData: model.LoginData{
|
|
UserDataBase: model.UserDataBase{
|
|
Login: "test@example.com",
|
|
},
|
|
Password: "TestPassword123!",
|
|
},
|
|
Describable: model.Describable{
|
|
Name: "Test User",
|
|
},
|
|
}
|
|
|
|
t.Run("ToAccount", func(t *testing.T) {
|
|
account := accountData.ToAccount()
|
|
|
|
assert.Equal(t, accountData.Login, account.Login)
|
|
assert.Equal(t, accountData.Password, account.Password)
|
|
assert.Equal(t, accountData.Name, account.Name)
|
|
|
|
// Verify the account has proper structure
|
|
assert.NotNil(t, account)
|
|
assert.IsType(t, &model.Account{}, account)
|
|
})
|
|
|
|
t.Run("PasswordHandling", func(t *testing.T) {
|
|
account := accountData.ToAccount()
|
|
|
|
// Original password should be preserved before validation
|
|
assert.Equal(t, "TestPassword123!", account.Password)
|
|
|
|
// Verify password is not empty
|
|
assert.NotEmpty(t, account.Password)
|
|
})
|
|
}
|