347 lines
11 KiB
Go
347 lines
11 KiB
Go
|
|
package client
|
||
|
|
|
||
|
|
import (
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"forge.redroom.link/yves/meowlib"
|
||
|
|
"github.com/stretchr/testify/assert"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Helper function to create a test server list with sample servers
|
||
|
|
func createTestServerList(t *testing.T) *ServerList {
|
||
|
|
sl := &ServerList{
|
||
|
|
Name: "TestServerList",
|
||
|
|
Servers: []*Server{},
|
||
|
|
}
|
||
|
|
|
||
|
|
// Create servers with different public keys
|
||
|
|
for i := 0; i < 5; i++ {
|
||
|
|
srv, err := CreateServerFromUrl("https://server" + string(rune('0'+i)) + ".example.com/meow")
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("Failed to create server: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Generate unique public keys for testing
|
||
|
|
kp, err := meowlib.NewKeyPair()
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("Failed to create keypair: %v", err)
|
||
|
|
}
|
||
|
|
srv.PublicKey = kp.Public
|
||
|
|
srv.Name = "Server" + string(rune('0'+i))
|
||
|
|
|
||
|
|
sl.Servers = append(sl.Servers, srv)
|
||
|
|
}
|
||
|
|
|
||
|
|
return sl
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestServerList_FilterByIdxs(t *testing.T) {
|
||
|
|
sl := createTestServerList(t)
|
||
|
|
|
||
|
|
t.Run("Filter with valid indices", func(t *testing.T) {
|
||
|
|
indices := []int{0, 2, 4}
|
||
|
|
filtered, err := sl.FilterByIdxs(indices)
|
||
|
|
|
||
|
|
assert.NoError(t, err, "FilterByIdxs should not return error for valid indices")
|
||
|
|
assert.NotNil(t, filtered, "Filtered list should not be nil")
|
||
|
|
assert.Equal(t, 3, len(filtered.Servers), "Should have 3 servers after filtering")
|
||
|
|
|
||
|
|
// Verify the filtered servers are correct
|
||
|
|
assert.Equal(t, sl.Servers[0], filtered.Servers[0])
|
||
|
|
assert.Equal(t, sl.Servers[2], filtered.Servers[1])
|
||
|
|
assert.Equal(t, sl.Servers[4], filtered.Servers[2])
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Filter with single index", func(t *testing.T) {
|
||
|
|
indices := []int{1}
|
||
|
|
filtered, err := sl.FilterByIdxs(indices)
|
||
|
|
|
||
|
|
assert.NoError(t, err, "FilterByIdxs should not return error for valid single index")
|
||
|
|
assert.NotNil(t, filtered, "Filtered list should not be nil")
|
||
|
|
assert.Equal(t, 1, len(filtered.Servers), "Should have 1 server after filtering")
|
||
|
|
assert.Equal(t, sl.Servers[1], filtered.Servers[0])
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Filter with empty indices", func(t *testing.T) {
|
||
|
|
indices := []int{}
|
||
|
|
filtered, err := sl.FilterByIdxs(indices)
|
||
|
|
|
||
|
|
assert.NoError(t, err, "FilterByIdxs should not return error for empty indices")
|
||
|
|
assert.NotNil(t, filtered, "Filtered list should not be nil")
|
||
|
|
assert.Equal(t, 0, len(filtered.Servers), "Should have 0 servers after filtering with empty indices")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Filter with out of range index", func(t *testing.T) {
|
||
|
|
indices := []int{0, 10}
|
||
|
|
filtered, err := sl.FilterByIdxs(indices)
|
||
|
|
|
||
|
|
assert.Error(t, err, "FilterByIdxs should return error for out of range index")
|
||
|
|
assert.Nil(t, filtered, "Filtered list should be nil on error")
|
||
|
|
assert.Contains(t, err.Error(), "out of range", "Error message should mention out of range")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Filter with negative index", func(t *testing.T) {
|
||
|
|
indices := []int{-1}
|
||
|
|
filtered, err := sl.FilterByIdxs(indices)
|
||
|
|
|
||
|
|
assert.Error(t, err, "FilterByIdxs should return error for negative index")
|
||
|
|
assert.Nil(t, filtered, "Filtered list should be nil on error")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Filter with duplicate indices", func(t *testing.T) {
|
||
|
|
indices := []int{1, 1, 2}
|
||
|
|
filtered, err := sl.FilterByIdxs(indices)
|
||
|
|
|
||
|
|
assert.NoError(t, err, "FilterByIdxs should not return error for duplicate indices")
|
||
|
|
assert.NotNil(t, filtered, "Filtered list should not be nil")
|
||
|
|
// Note: duplicates will result in duplicate servers in the list
|
||
|
|
assert.Equal(t, 3, len(filtered.Servers), "Should have 3 servers (including duplicate)")
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestServerList_FilterByIdxs_EmptyList(t *testing.T) {
|
||
|
|
sl := &ServerList{
|
||
|
|
Name: "EmptyList",
|
||
|
|
Servers: []*Server{},
|
||
|
|
}
|
||
|
|
|
||
|
|
t.Run("Filter empty list with indices", func(t *testing.T) {
|
||
|
|
indices := []int{0}
|
||
|
|
filtered, err := sl.FilterByIdxs(indices)
|
||
|
|
|
||
|
|
assert.Error(t, err, "FilterByIdxs should return error when trying to filter empty list")
|
||
|
|
assert.Nil(t, filtered, "Filtered list should be nil on error")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Filter empty list with empty indices", func(t *testing.T) {
|
||
|
|
indices := []int{}
|
||
|
|
filtered, err := sl.FilterByIdxs(indices)
|
||
|
|
|
||
|
|
assert.NoError(t, err, "FilterByIdxs should not return error for empty indices on empty list")
|
||
|
|
assert.NotNil(t, filtered, "Filtered list should not be nil")
|
||
|
|
assert.Equal(t, 0, len(filtered.Servers), "Should have 0 servers")
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestServerList_GetServerByIdx(t *testing.T) {
|
||
|
|
sl := createTestServerList(t)
|
||
|
|
|
||
|
|
t.Run("Get server with valid index", func(t *testing.T) {
|
||
|
|
server, err := sl.GetServerByIdx(2)
|
||
|
|
|
||
|
|
assert.NoError(t, err, "GetServerByIdx should not return error for valid index")
|
||
|
|
assert.NotNil(t, server, "Server should not be nil")
|
||
|
|
assert.Equal(t, sl.Servers[2], server, "Should return the correct server")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Get first server", func(t *testing.T) {
|
||
|
|
server, err := sl.GetServerByIdx(0)
|
||
|
|
|
||
|
|
assert.NoError(t, err, "GetServerByIdx should not return error for index 0")
|
||
|
|
assert.NotNil(t, server, "Server should not be nil")
|
||
|
|
assert.Equal(t, sl.Servers[0], server, "Should return the first server")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Get last server", func(t *testing.T) {
|
||
|
|
lastIdx := len(sl.Servers) - 1
|
||
|
|
server, err := sl.GetServerByIdx(lastIdx)
|
||
|
|
|
||
|
|
assert.NoError(t, err, "GetServerByIdx should not return error for last index")
|
||
|
|
assert.NotNil(t, server, "Server should not be nil")
|
||
|
|
assert.Equal(t, sl.Servers[lastIdx], server, "Should return the last server")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Get server with out of range index", func(t *testing.T) {
|
||
|
|
server, err := sl.GetServerByIdx(100)
|
||
|
|
|
||
|
|
assert.Error(t, err, "GetServerByIdx should return error for out of range index")
|
||
|
|
assert.Nil(t, server, "Server should be nil on error")
|
||
|
|
assert.Contains(t, err.Error(), "out of range", "Error message should mention out of range")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Get server with negative index", func(t *testing.T) {
|
||
|
|
server, err := sl.GetServerByIdx(-1)
|
||
|
|
|
||
|
|
assert.Error(t, err, "GetServerByIdx should return error for negative index")
|
||
|
|
assert.Nil(t, server, "Server should be nil on error")
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestServerList_GetServerByIdx_EmptyList(t *testing.T) {
|
||
|
|
sl := &ServerList{
|
||
|
|
Name: "EmptyList",
|
||
|
|
Servers: []*Server{},
|
||
|
|
}
|
||
|
|
|
||
|
|
t.Run("Get server from empty list", func(t *testing.T) {
|
||
|
|
server, err := sl.GetServerByIdx(0)
|
||
|
|
|
||
|
|
assert.Error(t, err, "GetServerByIdx should return error on empty list")
|
||
|
|
assert.Nil(t, server, "Server should be nil on error")
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestServerList_GetServerByPubkey(t *testing.T) {
|
||
|
|
sl := createTestServerList(t)
|
||
|
|
|
||
|
|
t.Run("Get server with existing public key", func(t *testing.T) {
|
||
|
|
// Use the public key from the second server
|
||
|
|
targetPubkey := sl.Servers[1].PublicKey
|
||
|
|
|
||
|
|
server := sl.GetServerByPubkey(targetPubkey)
|
||
|
|
|
||
|
|
assert.NotNil(t, server, "Server should not be nil when public key exists")
|
||
|
|
assert.Equal(t, targetPubkey, server.PublicKey, "Should return server with matching public key")
|
||
|
|
assert.Equal(t, sl.Servers[1], server, "Should return the correct server")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Get server with non-existent public key", func(t *testing.T) {
|
||
|
|
server := sl.GetServerByPubkey("nonexistent-pubkey-12345")
|
||
|
|
|
||
|
|
assert.Nil(t, server, "Server should be nil when public key doesn't exist")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Get server with empty public key", func(t *testing.T) {
|
||
|
|
server := sl.GetServerByPubkey("")
|
||
|
|
|
||
|
|
assert.Nil(t, server, "Server should be nil when searching for empty public key")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Get first matching server", func(t *testing.T) {
|
||
|
|
// Add a duplicate public key
|
||
|
|
duplicatePubkey := sl.Servers[0].PublicKey
|
||
|
|
newServer, err := CreateServerFromUrl("https://duplicate.example.com/meow")
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("Failed to create server: %v", err)
|
||
|
|
}
|
||
|
|
newServer.PublicKey = duplicatePubkey
|
||
|
|
sl.Servers = append(sl.Servers, newServer)
|
||
|
|
|
||
|
|
server := sl.GetServerByPubkey(duplicatePubkey)
|
||
|
|
|
||
|
|
assert.NotNil(t, server, "Server should not be nil")
|
||
|
|
assert.Equal(t, duplicatePubkey, server.PublicKey)
|
||
|
|
// Should return the first match
|
||
|
|
assert.Equal(t, sl.Servers[0], server, "Should return the first matching server")
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestServerList_GetServerByPubkey_EmptyList(t *testing.T) {
|
||
|
|
sl := &ServerList{
|
||
|
|
Name: "EmptyList",
|
||
|
|
Servers: []*Server{},
|
||
|
|
}
|
||
|
|
|
||
|
|
t.Run("Get server from empty list", func(t *testing.T) {
|
||
|
|
server := sl.GetServerByPubkey("any-pubkey")
|
||
|
|
|
||
|
|
assert.Nil(t, server, "Server should be nil when searching in empty list")
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestServerList_AddUrls(t *testing.T) {
|
||
|
|
t.Run("Add valid URLs", func(t *testing.T) {
|
||
|
|
sl := &ServerList{
|
||
|
|
Name: "TestList",
|
||
|
|
Servers: []*Server{},
|
||
|
|
}
|
||
|
|
|
||
|
|
urls := []string{
|
||
|
|
"https://server1.example.com/meow",
|
||
|
|
"https://server2.example.com/meow",
|
||
|
|
"https://server3.example.com/meow",
|
||
|
|
}
|
||
|
|
|
||
|
|
err := sl.AddUrls(urls)
|
||
|
|
|
||
|
|
assert.NoError(t, err, "AddUrls should not return error for valid URLs")
|
||
|
|
assert.Equal(t, 3, len(sl.Servers), "Should have 3 servers after adding URLs")
|
||
|
|
|
||
|
|
// Verify each server was created correctly
|
||
|
|
for i, url := range urls {
|
||
|
|
assert.Equal(t, url, sl.Servers[i].Url, "Server URL should match")
|
||
|
|
assert.NotNil(t, sl.Servers[i].UserKp, "Server should have UserKp")
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Add empty URLs list", func(t *testing.T) {
|
||
|
|
sl := &ServerList{
|
||
|
|
Name: "TestList",
|
||
|
|
Servers: []*Server{},
|
||
|
|
}
|
||
|
|
|
||
|
|
urls := []string{}
|
||
|
|
err := sl.AddUrls(urls)
|
||
|
|
|
||
|
|
assert.NoError(t, err, "AddUrls should not return error for empty list")
|
||
|
|
assert.Equal(t, 0, len(sl.Servers), "Should have 0 servers after adding empty list")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Add URLs to existing list", func(t *testing.T) {
|
||
|
|
sl := createTestServerList(t)
|
||
|
|
initialCount := len(sl.Servers)
|
||
|
|
|
||
|
|
urls := []string{
|
||
|
|
"https://newserver1.example.com/meow",
|
||
|
|
"https://newserver2.example.com/meow",
|
||
|
|
}
|
||
|
|
|
||
|
|
err := sl.AddUrls(urls)
|
||
|
|
|
||
|
|
assert.NoError(t, err, "AddUrls should not return error")
|
||
|
|
assert.Equal(t, initialCount+2, len(sl.Servers), "Should have added 2 servers to existing list")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Add single URL", func(t *testing.T) {
|
||
|
|
sl := &ServerList{
|
||
|
|
Name: "TestList",
|
||
|
|
Servers: []*Server{},
|
||
|
|
}
|
||
|
|
|
||
|
|
urls := []string{"https://single.example.com/meow"}
|
||
|
|
err := sl.AddUrls(urls)
|
||
|
|
|
||
|
|
assert.NoError(t, err, "AddUrls should not return error for single URL")
|
||
|
|
assert.Equal(t, 1, len(sl.Servers), "Should have 1 server after adding single URL")
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestServerList_AddUrls_NilList(t *testing.T) {
|
||
|
|
t.Run("Add URLs to nil server list", func(t *testing.T) {
|
||
|
|
sl := &ServerList{
|
||
|
|
Name: "TestList",
|
||
|
|
Servers: nil, // Explicitly nil
|
||
|
|
}
|
||
|
|
|
||
|
|
urls := []string{"https://server.example.com/meow"}
|
||
|
|
err := sl.AddUrls(urls)
|
||
|
|
|
||
|
|
assert.NoError(t, err, "AddUrls should not return error even with nil Servers slice")
|
||
|
|
assert.NotNil(t, sl.Servers, "Servers slice should be initialized")
|
||
|
|
assert.Equal(t, 1, len(sl.Servers), "Should have 1 server after adding URL")
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test the ServerList struct itself
|
||
|
|
func TestServerList_Structure(t *testing.T) {
|
||
|
|
t.Run("Create empty server list", func(t *testing.T) {
|
||
|
|
sl := &ServerList{
|
||
|
|
Name: "TestList",
|
||
|
|
Servers: []*Server{},
|
||
|
|
}
|
||
|
|
|
||
|
|
assert.NotNil(t, sl, "ServerList should not be nil")
|
||
|
|
assert.Equal(t, "TestList", sl.Name, "Name should be set correctly")
|
||
|
|
assert.NotNil(t, sl.Servers, "Servers slice should not be nil")
|
||
|
|
assert.Equal(t, 0, len(sl.Servers), "Servers slice should be empty")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Create server list with name", func(t *testing.T) {
|
||
|
|
sl := &ServerList{
|
||
|
|
Name: "MyMessageServers",
|
||
|
|
}
|
||
|
|
|
||
|
|
assert.Equal(t, "MyMessageServers", sl.Name)
|
||
|
|
})
|
||
|
|
}
|