Simplified the database layer by removing custom interface wrappers and using standard library *sql.DB and *sql.Tx types directly. Changes: - Removed DBConnection and DBTransaction interfaces from database.go - Removed NewDBConnection() wrapper function - Updated TokenGenerator to use *sql.DB instead of DBConnection - Updated all validation and revocation methods to accept *sql.Tx - Updated TableManager to work with *sql.DB directly - Updated all tests to use db.Begin() instead of custom wrappers - Fixed GeneratorConfig.DB field (was DBConn) - Updated documentation in doc.go with correct API usage Benefits: - Simpler API with fewer abstractions - Works directly with database/sql standard library - Compatible with GORM (via gormDB.DB()) and Bun (share same *sql.DB) - Easier to understand and maintain - No unnecessary wrapper layers Breaking changes: - GeneratorConfig.DBConn renamed to GeneratorConfig.DB - Removed NewDBConnection() function - pass *sql.DB directly - ValidateAccess/ValidateRefresh now accept *sql.Tx instead of DBTransaction - Token.Revoke/CheckNotRevoked now accept *sql.Tx instead of DBTransaction 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
232 lines
4.4 KiB
Go
232 lines
4.4 KiB
Go
package hws_test
|
|
|
|
import (
|
|
"io"
|
|
"math/rand/v2"
|
|
"net/http"
|
|
"slices"
|
|
"testing"
|
|
|
|
"git.haelnorr.com/h/golib/hlog"
|
|
"git.haelnorr.com/h/golib/hws"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
var ports []uint64
|
|
|
|
func randomPort() uint64 {
|
|
port := uint64(3000 + rand.IntN(1001))
|
|
for slices.Contains(ports, port) {
|
|
port = uint64(3000 + rand.IntN(1001))
|
|
}
|
|
ports = append(ports, port)
|
|
return port
|
|
}
|
|
|
|
func createTestServer(t *testing.T, w io.Writer) *hws.Server {
|
|
server, err := hws.NewServer(&hws.Config{
|
|
Host: "127.0.0.1",
|
|
Port: randomPort(),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
logger, err := hlog.NewLogger(hlog.LogLevel("Debug"), w, nil, "")
|
|
require.NoError(t, err)
|
|
|
|
err = server.AddLogger(logger)
|
|
require.NoError(t, err)
|
|
|
|
return server
|
|
}
|
|
|
|
var testHandler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
w.Write([]byte("hello world"))
|
|
})
|
|
|
|
func startTestServer(t *testing.T, server *hws.Server) {
|
|
err := server.AddRoutes(hws.Route{
|
|
Path: "/",
|
|
Method: hws.MethodGET,
|
|
Handler: testHandler,
|
|
})
|
|
require.NoError(t, err)
|
|
err = server.Start(t.Context())
|
|
require.NoError(t, err)
|
|
t.Log("Test server started")
|
|
}
|
|
|
|
func Test_NewServer(t *testing.T) {
|
|
server, err := hws.NewServer(&hws.Config{
|
|
Host: "localhost",
|
|
Port: randomPort(),
|
|
})
|
|
require.NoError(t, err)
|
|
require.NotNil(t, server)
|
|
|
|
t.Run("Nil config returns error", func(t *testing.T) {
|
|
server, err := hws.NewServer(nil)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, server)
|
|
assert.Contains(t, err.Error(), "Config cannot be nil")
|
|
})
|
|
|
|
tests := []struct {
|
|
name string
|
|
host string
|
|
port uint64
|
|
valid bool
|
|
}{
|
|
{
|
|
name: "Valid localhost on http",
|
|
host: "127.0.0.1",
|
|
port: 80,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "Valid IP on https",
|
|
host: "192.168.1.1",
|
|
port: 443,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "Valid IP on port 65535",
|
|
host: "10.0.0.5",
|
|
port: 65535,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "0.0.0.0 on port 8080",
|
|
host: "0.0.0.0",
|
|
port: 8080,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "Broadcast IP on port 1",
|
|
host: "255.255.255.255",
|
|
port: 1,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "Port 0 gets default",
|
|
host: "127.0.0.1",
|
|
port: 0,
|
|
valid: true, // port 0 now gets default value of 3000
|
|
},
|
|
{
|
|
name: "Invalid port 65536",
|
|
host: "127.0.0.1",
|
|
port: 65536,
|
|
valid: true, // port is accepted (validated at OS level)
|
|
},
|
|
{
|
|
name: "No hostname provided gets default",
|
|
host: "",
|
|
port: 80,
|
|
valid: true, // empty hostname gets default 127.0.0.1
|
|
},
|
|
{
|
|
name: "Spaces provided for host",
|
|
host: " ",
|
|
port: 80,
|
|
valid: false,
|
|
},
|
|
{
|
|
name: "Localhost as string",
|
|
host: "localhost",
|
|
port: 8080,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "Number only host",
|
|
host: "1234",
|
|
port: 80,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "Valid domain on http",
|
|
host: "example.com",
|
|
port: 80,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "Valid domain on https",
|
|
host: "a-b-c.example123.co",
|
|
port: 443,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "Valid domain starting with a digit",
|
|
host: "1example.com",
|
|
port: 8080,
|
|
valid: true, // labels may start with digits (RFC 1123)
|
|
},
|
|
{
|
|
name: "Single character hostname",
|
|
host: "a",
|
|
port: 1,
|
|
valid: true, // single-label hostname, min length
|
|
},
|
|
|
|
{
|
|
name: "Hostname starts with a hyphen",
|
|
host: "-example.com",
|
|
port: 80,
|
|
valid: false, // label starts with hyphen
|
|
},
|
|
{
|
|
name: "Hostname ends with a hyphen",
|
|
host: "example-.com",
|
|
port: 80,
|
|
valid: false, // label ends with hyphen
|
|
},
|
|
{
|
|
name: "Empty label in hostname",
|
|
host: "ex..ample.com",
|
|
port: 80,
|
|
valid: false, // empty label
|
|
},
|
|
{
|
|
name: "Invalid character: '_'",
|
|
host: "exa_mple.com",
|
|
port: 80,
|
|
valid: false, // invalid character (_)
|
|
},
|
|
{
|
|
name: "Trailing dot",
|
|
host: "example.com.",
|
|
port: 80,
|
|
valid: false, // trailing dot not allowed per spec
|
|
},
|
|
{
|
|
name: "Valid IPv6 localhost",
|
|
host: "::1",
|
|
port: 8080,
|
|
valid: true, // IPv6 localhost
|
|
},
|
|
{
|
|
name: "Valid IPv6 shortened",
|
|
host: "2001:db8::1",
|
|
port: 80,
|
|
valid: true, // shortened IPv6
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
server, err := hws.NewServer(&hws.Config{
|
|
Host: tt.host,
|
|
Port: tt.port,
|
|
})
|
|
if tt.valid {
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, server)
|
|
} else {
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|