Files
sdk/prompts/validations_test.go

1574 lines
32 KiB
Go

// Copyright (C) 2025, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
//go:build skip
package prompts
import (
"os"
"path/filepath"
"testing"
"time"
"github.com/luxfi/constants"
"github.com/luxfi/genesis/pkg/genesis"
"github.com/luxfi/ids"
"github.com/luxfi/sdk/models"
"github.com/stretchr/testify/require"
)
func TestValidateEmail(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid email",
input: "[email protected]",
wantErr: false,
},
{
name: "valid email with subdomain",
input: "[email protected]",
wantErr: false,
},
{
name: "invalid email - no @",
input: "testexample.com",
wantErr: true,
},
{
name: "invalid email - no domain",
input: "test@",
wantErr: true,
},
{
name: "invalid email - no local part",
input: "@example.com",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateEmail(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidatePositiveBigInt(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid positive integer",
input: "123",
wantErr: false,
},
{
name: "zero is valid",
input: "0",
wantErr: false,
},
{
name: "large positive number",
input: "999999999999999999999999999999",
wantErr: false,
},
{
name: "negative number",
input: "-1",
wantErr: true,
},
{
name: "invalid format",
input: "abc",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
{
name: "float number",
input: "123.45",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validatePositiveBigInt(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateMainnetStakingDuration(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid duration within range",
input: "720h", // 30 days
wantErr: false,
},
{
name: "minimum duration",
input: genesis.MainnetParams.MinStakeDuration.String(),
wantErr: false,
},
{
name: "maximum duration",
input: genesis.MainnetParams.MaxStakeDuration.String(),
wantErr: false,
},
{
name: "duration too short",
input: "1h",
wantErr: true,
},
{
name: "duration too long",
input: "9600h", // 400 days
wantErr: true,
},
{
name: "invalid duration format",
input: "invalid",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateStakingDuration(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateMainnetL1StakingDuration(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid duration",
input: "720h", // 30 days
wantErr: false,
},
{
name: "minimum L1 duration - 24h",
input: "24h",
wantErr: false,
},
{
name: "maximum duration",
input: genesis.MainnetParams.MaxStakeDuration.String(),
wantErr: false,
},
{
name: "duration too short - less than 24h",
input: "12h",
wantErr: true,
},
{
name: "duration too long",
input: "9600h", // 400 days
wantErr: true,
},
{
name: "invalid format",
input: "invalid",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateStakingDuration(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateTestnetStakingDuration(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid duration within range",
input: "720h", // 30 days
wantErr: false,
},
{
name: "minimum duration",
input: genesis.TestnetParams.MinStakeDuration.String(),
wantErr: false,
},
{
name: "maximum duration",
input: genesis.TestnetParams.MaxStakeDuration.String(),
wantErr: false,
},
{
name: "duration too short",
input: "1h",
wantErr: true,
},
{
name: "duration too long",
input: "9600h", // 400 days
wantErr: true,
},
{
name: "invalid duration format",
input: "invalid",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateStakingDuration(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateDuration(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid duration - hours",
input: "24h",
wantErr: false,
},
{
name: "valid duration - minutes",
input: "30m",
wantErr: false,
},
{
name: "valid duration - seconds",
input: "45s",
wantErr: false,
},
{
name: "valid duration - days",
input: "168h", // 7 days
wantErr: false,
},
{
name: "valid duration - complex",
input: "1h30m45s",
wantErr: false,
},
{
name: "invalid duration format",
input: "invalid",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
{
name: "just number without unit",
input: "123",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateStakingDuration(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateTime(t *testing.T) {
// Create test times with sufficient buffer for processing delays
now := time.Now().UTC()
// Use a much larger buffer to account for test execution time
futureTime := now.Add(constants.StakingStartLeadTime + time.Hour)
pastTime := now.Add(-time.Hour)
closeTime := now.Add(constants.StakingStartLeadTime - time.Minute)
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid time well beyond lead time boundary",
input: futureTime.Format(constants.TimeParseLayout),
wantErr: false,
},
{
name: "time too close to now",
input: closeTime.Format(constants.TimeParseLayout),
wantErr: true,
},
{
name: "past time",
input: pastTime.Format(constants.TimeParseLayout),
wantErr: true,
},
{
name: "invalid time format",
input: "invalid-time",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
{
name: "wrong format",
input: "2023-12-25 15:30:00",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateTime(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateNodeID(t *testing.T) {
// Generate a valid node ID for testing
validNodeID := ids.GenerateTestNodeID()
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid node ID",
input: validNodeID.String(),
wantErr: false,
},
{
name: "invalid node ID - too short",
input: "invalid",
wantErr: true,
},
{
name: "invalid node ID - wrong format",
input: "NodeID-InvalidFormat123",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
{
name: "invalid characters",
input: "NodeID-@#$%^&*()",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateNodeID(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateAddress(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid ethereum address",
input: "0x742d35Cc1634C0532925a3b8D400bbCFcc09FbbF",
wantErr: false,
},
{
name: "valid address all lowercase",
input: "0x742d35cc1634c0532925a3b8d400bbcfcc09fbbf",
wantErr: false, // Go-ethereum accepts all lowercase
},
{
name: "invalid address - no 0x prefix",
input: "742d35Cc1634C0532925a3b8D400bbcFcc09FbbF",
wantErr: false, // go-ethereum IsHexAddress accepts this
},
{
name: "invalid address - too short",
input: "0x742d35Cc",
wantErr: true,
},
{
name: "invalid address - too long",
input: "0x742d35Cc1634C0532925a3b8D400bbcFcc09FbbF1234",
wantErr: true,
},
{
name: "invalid address - invalid characters",
input: "0x742d35Cc1634C0532925a3b8D400bbcFcc09FbbG",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateAddress(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateAddresses(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "single valid address",
input: "0x742d35Cc1634C0532925a3b8D400bbcFcc09FbbF",
wantErr: false,
},
{
name: "multiple valid addresses",
input: "0x742d35Cc1634C0532925a3b8D400bbcFcc09FbbF,0x8ba1f109551bD432803012645Hac136c",
wantErr: true, // second address is invalid
},
{
name: "multiple valid addresses with spaces",
input: "0x742d35Cc1634C0532925a3b8D400bbcFcc09FbbF, 0x8ba1f109551bd432803012645eac136c108ba132",
wantErr: false,
},
{
name: "empty address in list",
input: "0x742d35Cc1634C0532925a3b8D400bbcFcc09FbbF,,0x8ba1f109551bD432803012645Hac136c108Ba132",
wantErr: true,
},
{
name: "invalid address in list",
input: "0x742d35Cc1634C0532925a3b8D400bbcFcc09FbbF,invalid,0x8ba1f109551bD432803012645Hac136c108Ba132",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateAddress(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateExistingFilepath(t *testing.T) {
// Create a temporary file for testing
tmpFile, err := os.CreateTemp("", "test_file_*.txt")
require.NoError(t, err)
defer os.Remove(tmpFile.Name())
err = tmpFile.Close()
require.NoError(t, err)
// Create a temporary directory for testing
tmpDir, err := os.MkdirTemp("", "test_dir_*")
require.NoError(t, err)
defer os.RemoveAll(tmpDir)
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "existing file",
input: tmpFile.Name(),
wantErr: false,
},
{
name: "non-existing file",
input: "/path/to/nonexistent/file.txt",
wantErr: true,
},
{
name: "directory instead of file",
input: tmpDir,
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateExistingFilepath(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateBiggerThanZero(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid positive number",
input: "123",
wantErr: false,
},
{
name: "valid decimal number",
input: "1",
wantErr: false,
},
{
name: "hex number",
input: "0xFF",
wantErr: false,
},
{
name: "octal number",
input: "0755",
wantErr: false,
},
{
name: "zero value",
input: "0",
wantErr: true,
},
{
name: "negative number",
input: "-1",
wantErr: true,
},
{
name: "invalid format",
input: "abc",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
{
name: "float number",
input: "12.34",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateBiggerThanZero(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateURLFormat(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid HTTP URL",
input: "http://example.com",
wantErr: false,
},
{
name: "valid HTTPS URL",
input: "https://example.com",
wantErr: false,
},
{
name: "valid URL with path",
input: "https://example.com/path/to/resource",
wantErr: false,
},
{
name: "valid URL with query params",
input: "https://example.com/path?param=value",
wantErr: false,
},
{
name: "valid URL with port",
input: "https://example.com:8080",
wantErr: false,
},
{
name: "invalid URL - no scheme",
input: "example.com",
wantErr: true,
},
{
name: "invalid URL - malformed",
input: "http://[::1",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
{
name: "invalid URL - spaces",
input: "https://exa mple.com",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateURLFormat(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidatePChainAddress(t *testing.T) {
tests := []struct {
name string
input string
expectedHRP string
wantErr bool
}{
{
name: "valid P-Chain address - ewoq test address",
input: "P-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p",
expectedHRP: "custom",
wantErr: false,
},
{
name: "valid address format but not P-Chain - X-Chain ewoq",
input: "X-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p",
expectedHRP: "",
wantErr: true, // Parse succeeds but chainID != "P"
},
{
name: "invalid Testnet P-Chain address - bad checksum",
input: "P-testnet1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhqhmp5",
expectedHRP: "",
wantErr: true, // This will fail checksum validation
},
{
name: "invalid Mainnet P-Chain address - bad checksum",
input: "P-lux1x459sj0ssm4tdrn372f7fhqx7p4pkj9hh8a74w",
expectedHRP: "",
wantErr: true, // This will fail checksum validation
},
{
name: "invalid Local P-Chain address - bad checksum",
input: "P-local1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhcz8r9x",
expectedHRP: "",
wantErr: true, // This will fail checksum validation
},
{
name: "invalid - not P-Chain (X-Chain prefix)",
input: "X-testnet1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhqhmp5",
expectedHRP: "",
wantErr: true,
},
{
name: "invalid - not P-Chain (C-Chain prefix)",
input: "C-testnet1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhqhmp5",
expectedHRP: "",
wantErr: true,
},
{
name: "invalid - unknown chain prefix",
input: "Z-testnet1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhqhmp5",
expectedHRP: "",
wantErr: true,
},
{
name: "invalid - no chain prefix",
input: "testnet1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhqhmp5",
expectedHRP: "",
wantErr: true,
},
{
name: "invalid - malformed address",
input: "P-invalid-address",
expectedHRP: "",
wantErr: true,
},
{
name: "empty string",
input: "",
expectedHRP: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
hrp, err := validatePChainAddress(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
require.Equal(t, tt.expectedHRP, hrp)
}
})
}
}
func TestValidatePChainTestnetAddress(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid P-Chain address with Testnet HRP",
input: "P-test18jma8ppw3nhx5r4ap8clazz0dps7rv5u6wmu4t",
wantErr: false, // Parse succeeds and HRP == "test"
},
{
name: "valid P-Chain address but wrong HRP - custom",
input: "P-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p",
wantErr: true, // Parse succeeds but HRP != "test"
},
{
name: "invalid Testnet P-Chain address - bad checksum",
input: "P-test1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhqhmp5",
wantErr: true, // This will fail checksum validation
},
{
name: "invalid - Mainnet address",
input: "P-lux1x459sj0ssm4tdrn372f7fhqx7p4pkj9hh8a74w",
wantErr: true,
},
{
name: "invalid - Local address",
input: "P-local1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhcz8r9x",
wantErr: true,
},
{
name: "invalid - not P-Chain",
input: "X-testnet1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhqhmp5",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validatePChainTestnetAddress(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidatePChainMainAddress(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid P-Chain address with Mainnet HRP",
input: "P-lux18jma8ppw3nhx5r4ap8clazz0dps7rv5ukulre5",
wantErr: false, // Parse succeeds and HRP == "lux"
},
{
name: "valid P-Chain address but wrong HRP - custom",
input: "P-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p",
wantErr: true, // Parse succeeds but HRP != "lux"
},
{
name: "invalid Mainnet P-Chain address - bad checksum",
input: "P-lux1x459sj0ssm4tdrn372f7fhqx7p4pkj9hh8a74w",
wantErr: true, // This will fail checksum validation
},
{
name: "invalid - Testnet address",
input: "P-testnet1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhqhmp5",
wantErr: true,
},
{
name: "invalid - Local address",
input: "P-local1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhcz8r9x",
wantErr: true,
},
{
name: "invalid - not P-Chain",
input: "X-lux1x459sj0ssm4tdrn372f7fhqx7p4pkj9hh8a74w",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validatePChainMainAddress(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidatePChainLocalAddress(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid P-Chain address with custom HRP",
input: "P-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p",
wantErr: false,
},
{
name: "invalid P-Chain address - unsupported HRP",
input: "P-lux18jma8ppw3nhx5r4ap8clazz0dps7rv5ukulre5",
wantErr: true, // HRP is neither local nor fallback
},
{
name: "invalid Local P-Chain address - bad checksum",
input: "P-local1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhcz8r9x",
wantErr: true, // This will fail checksum validation
},
{
name: "invalid Custom P-Chain address - bad checksum",
input: "P-custom1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhcwfmrp",
wantErr: true, // This will fail checksum validation
},
{
name: "invalid - Testnet address",
input: "P-testnet1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhqhmp5",
wantErr: true,
},
{
name: "invalid - Mainnet address",
input: "P-lux1x459sj0ssm4tdrn372f7fhqx7p4pkj9hh8a74w",
wantErr: true,
},
{
name: "invalid - not P-Chain",
input: "X-local1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhcz8r9x",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validatePChainLocalAddress(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestGetPChainValidationFunc(t *testing.T) {
tests := []struct {
name string
network models.Network
validAddr string
invalidAddr string
}{
{
name: "Testnet network",
network: models.NewTestnetNetwork(),
validAddr: "P-testnet1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhqhmp5",
invalidAddr: "P-lux1x459sj0ssm4tdrn372f7fhqx7p4pkj9hh8a74w",
},
{
name: "Mainnet network",
network: models.NewMainnetNetwork(),
validAddr: "P-lux1x459sj0ssm4tdrn372f7fhqx7p4pkj9hh8a74w",
invalidAddr: "P-testnet1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhqhmp5",
},
{
name: "Local network",
network: models.NewLocalNetwork(),
validAddr: "P-local1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhcz8r9x",
invalidAddr: "P-testnet1x459sj0ssm4tdrn372f7fhqx7p4pkj9hhqhmp5",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
validator := getPChainValidationFunc(tt.network)
// Test "valid" address - most fail due to bad checksum
err := validator(tt.validAddr)
require.Error(t, err) // Test addresses have bad checksums
// Test invalid address
err = validator(tt.invalidAddr)
require.Error(t, err)
})
}
}
func TestValidateID(t *testing.T) {
// Generate a valid ID for testing
validID := ids.GenerateTestID()
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid ID",
input: validID.String(),
wantErr: false,
},
{
name: "invalid ID - too short",
input: "invalid",
wantErr: true,
},
{
name: "invalid ID - wrong format",
input: "invalidID123",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
{
name: "invalid characters",
input: "2Z4UuXuKg@#$%^&*()",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateID(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateNewFilepath(t *testing.T) {
// Create a temporary file that exists
tmpFile, err := os.CreateTemp("", "existing_file_*.txt")
require.NoError(t, err)
defer os.Remove(tmpFile.Name())
err = tmpFile.Close()
require.NoError(t, err)
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "new file path (doesn't exist)",
input: "/tmp/new_file_that_doesnt_exist.txt",
wantErr: false,
},
{
name: "existing file",
input: tmpFile.Name(),
wantErr: true,
},
{
name: "new file in temp directory",
input: filepath.Join(os.TempDir(), "new_test_file.txt"),
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateNewFilepath(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateHexa(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "valid hex string",
input: "0x123abc",
wantErr: false,
},
{
name: "valid hex string - uppercase",
input: "0x123ABC",
wantErr: false,
},
{
name: "valid hex string - mixed case",
input: "0x123aBc",
wantErr: false,
},
{
name: "valid hex string - long",
input: "0x123456789abcdef0123456789abcdef012345678",
wantErr: false,
},
{
name: "invalid - no 0x prefix",
input: "123abc",
wantErr: true,
},
{
name: "invalid - wrong prefix",
input: "1x123abc",
wantErr: true,
},
{
name: "invalid - only prefix",
input: "0x",
wantErr: true,
},
{
name: "invalid - non-hex characters",
input: "0x123xyz",
wantErr: true,
},
{
name: "empty string",
input: "",
wantErr: true,
},
{
name: "invalid - spaces",
input: "0x123 abc",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateHexa(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
// func TestValidateRepoBranch(t *testing.T) {
// tests := []struct {
// name string
// repo string
// branch string
// wantErr bool
// }{
// {
// name: "valid repo and branch - lux-cli main",
// repo: "https://github.com/luxfi/cli",
// branch: "main",
// wantErr: false,
// },
// {
// name: "valid repo but non-existent branch",
// repo: "https://github.com/luxfi/cli",
// branch: "nonexistent-branch-12345",
// wantErr: true,
// },
// {
// name: "non-existent repo",
// repo: "https://github.com/nonexistent-org/nonexistent-repo",
// branch: "main",
// wantErr: true,
// },
// {
// name: "invalid repo URL",
// repo: "not-a-repo-url",
// branch: "main",
// wantErr: true,
// },
// {
// name: "empty repo",
// repo: "",
// branch: "main",
// wantErr: true,
// },
// {
// name: "empty branch",
// repo: "https://github.com/luxfi/cli",
// branch: "",
// wantErr: true,
// },
// }
//
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// err := ValidateRepoBranch(tt.repo, tt.branch)
// if tt.wantErr {
// require.Error(t, err)
// } else {
// require.NoError(t, err)
// }
// })
// }
// }
// func TestValidateRepoFile(t *testing.T) {
// tests := []struct {
// name string
// repo string
// branch string
// file string
// wantErr bool
// }{
// {
// name: "valid repo, branch, and file",
// repo: "https://github.com/luxfi/cli",
// branch: "main",
// file: "README.md",
// wantErr: false,
// },
// {
// name: "valid repo and branch but non-existent file",
// repo: "https://github.com/luxfi/cli",
// branch: "main",
// file: "nonexistent-file.txt",
// wantErr: true,
// },
// {
// name: "valid repo but non-existent branch",
// repo: "https://github.com/luxfi/cli",
// branch: "nonexistent-branch",
// file: "README.md",
// wantErr: true,
// },
// {
// name: "non-existent repo",
// repo: "https://github.com/nonexistent-org/nonexistent-repo",
// branch: "main",
// file: "README.md",
// wantErr: true,
// },
// {
// name: "invalid repo URL",
// repo: "not-a-repo-url",
// branch: "main",
// file: "README.md",
// wantErr: true,
// },
// {
// name: "empty repo",
// repo: "",
// branch: "main",
// file: "README.md",
// wantErr: true,
// },
// {
// name: "empty branch",
// repo: "https://github.com/luxfi/cli",
// branch: "",
// file: "README.md",
// wantErr: true,
// },
// {
// name: "empty file - GitHub handles gracefully",
// repo: "https://github.com/luxfi/cli",
// branch: "main",
// file: "",
// wantErr: false, // GitHub redirects empty file to branch view
// },
// {
// name: "file in subdirectory",
// repo: "https://github.com/luxfi/cli",
// branch: "main",
// file: "cmd/root.go",
// wantErr: false,
// },
// }
//
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// err := ValidateRepoFile(tt.repo, tt.branch, tt.file)
// if tt.wantErr {
// require.Error(t, err)
// } else {
// require.NoError(t, err)
// }
// })
// }
// }
// func TestValidateWeightFunc(t *testing.T) {
// tests := []struct {
// name string
// input string
// wantErr bool
// }{
// {
// name: "valid weight within range",
// input: "50",
// wantErr: false,
// },
// {
// name: "minimum valid weight",
// input: "1",
// wantErr: false,
// },
// {
// name: "large valid weight",
// input: "100",
// wantErr: false,
// },
// {
// name: "very large weight",
// input: "1000",
// wantErr: false,
// },
// {
// name: "zero weight - below minimum",
// input: "0",
// wantErr: true,
// },
// {
// name: "negative weight - invalid format",
// input: "-1",
// wantErr: true,
// },
// {
// name: "invalid format - letters",
// input: "abc",
// wantErr: true,
// },
// {
// name: "invalid format - float",
// input: "50.5",
// wantErr: true,
// },
// {
// name: "empty string",
// input: "",
// wantErr: true,
// },
// {
// name: "invalid format - mixed",
// input: "50abc",
// wantErr: true,
// },
// }
//
// // Test without extra validation
// t.Run("without extra validation", func(t *testing.T) {
// validator := validateWeightFunc(nil)
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// err := validator(tt.input)
// if tt.wantErr {
// require.Error(t, err)
// } else {
// require.NoError(t, err)
// }
// })
// }
// })
//
// // Test with extra validation that always passes
// t.Run("with extra validation that passes", func(t *testing.T) {
// extraValidation := func(uint64) error {
// return nil // Always pass
// }
// validator := validateWeightFunc(extraValidation)
//
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// err := validator(tt.input)
// if tt.wantErr {
// require.Error(t, err)
// } else {
// require.NoError(t, err)
// }
// })
// }
// })
//
// // Test with extra validation that fails for values > 100
// t.Run("with extra validation max 100", func(t *testing.T) {
// extraValidation := func(val uint64) error {
// if val > 100 {
// return fmt.Errorf("weight must not exceed 100")
// }
// return nil
// }
// validator := validateWeightFunc(extraValidation)
//
// // Test cases specific to this extra validation
// extraTests := []struct {
// name string
// input string
// wantErr bool
// }{
// {
// name: "weight within extra limit",
// input: "50",
// wantErr: false,
// },
// {
// name: "weight at extra limit",
// input: "100",
// wantErr: false,
// },
// {
// name: "weight above extra limit",
// input: "150",
// wantErr: true,
// },
// {
// name: "large weight above extra limit",
// input: "1000",
// wantErr: true,
// },
// }
//
// for _, tt := range extraTests {
// t.Run(tt.name, func(t *testing.T) {
// err := validator(tt.input)
// if tt.wantErr {
// require.Error(t, err)
// require.Contains(t, err.Error(), "must not exceed 100")
// } else {
// require.NoError(t, err)
// }
// })
// }
// })
//
// // Test with extra validation that fails for even numbers
// t.Run("with extra validation odd numbers only", func(t *testing.T) {
// extraValidation := func(val uint64) error {
// if val%2 == 0 {
// return fmt.Errorf("weight must be an odd number")
// }
// return nil
// }
// validator := validateWeightFunc(extraValidation)
//
// // Test cases specific to this extra validation
// extraTests := []struct {
// name string
// input string
// wantErr bool
// }{
// {
// name: "odd number",
// input: "1",
// wantErr: false,
// },
// {
// name: "another odd number",
// input: "99",
// wantErr: false,
// },
// {
// name: "even number",
// input: "2",
// wantErr: true,
// },
// {
// name: "another even number",
// input: "100",
// wantErr: true,
// },
// }
//
// for _, tt := range extraTests {
// t.Run(tt.name, func(t *testing.T) {
// err := validator(tt.input)
// if tt.wantErr {
// require.Error(t, err)
// require.Contains(t, err.Error(), "must be an odd number")
// } else {
// require.NoError(t, err)
// }
// })
// }
// })
// }
func TestValidatePositiveInt(t *testing.T) {
tests := []struct {
name string
input int
wantErr bool
}{
{
name: "positive integer",
input: 1,
wantErr: false,
},
{
name: "large positive integer",
input: 1000000,
wantErr: false,
},
{
name: "zero",
input: 0,
wantErr: true,
},
{
name: "negative integer",
input: -1,
wantErr: true,
},
{
name: "large negative integer",
input: -1000000,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidatePositiveInt(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}