- make test 自动拉起并等待 PostgreSQL 就绪;测试用临时 schema 隔离,不污染开发库 - 新增 make test-db / lint / fmt - 修复 testdb.withSearchPath:原实现用 url.Values.Encode() 重编码整个查询串, 把 TimeZone=Asia/Shanghai 变成 Asia%2FShanghai,pgx 原样传给服务端后报 "unknown time zone Asia%2FShanghai",导致数据库起来后集成测试依然全挂。 改为只追加 search_path,并补测试锁定该行为。
52 lines
1.8 KiB
Go
52 lines
1.8 KiB
Go
package testdb
|
|
|
|
import (
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// TestWithSearchPathKeepsOriginalQuery 防止回归:曾经用 url.Values.Encode() 重编码整个查询串,
|
|
// 把 TimeZone=Asia/Shanghai 变成 Asia%2FShanghai,导致所有集成测试报
|
|
// "unknown time zone Asia%2FShanghai" 而连不上数据库。
|
|
func TestWithSearchPathKeepsOriginalQuery(t *testing.T) {
|
|
const dsn = "postgres://affiliate:pw@127.0.0.1:15432/affiliate_dash?sslmode=disable&TimeZone=Asia/Shanghai"
|
|
|
|
got := withSearchPath(dsn, "test_123")
|
|
|
|
if strings.Contains(got, "%2F") {
|
|
t.Fatalf("search_path 追加不应改写已有查询参数,实际得到 %q", got)
|
|
}
|
|
if !strings.Contains(got, "TimeZone=Asia/Shanghai") {
|
|
t.Fatalf("原查询参数必须原样保留,实际得到 %q", got)
|
|
}
|
|
|
|
parsed, err := url.Parse(got)
|
|
if err != nil {
|
|
t.Fatalf("结果不是合法 URL: %v", err)
|
|
}
|
|
if gotSchema := parsed.Query().Get("search_path"); gotSchema != "test_123" {
|
|
t.Fatalf("search_path 期望 test_123,实际 %q", gotSchema)
|
|
}
|
|
if gotSSL := parsed.Query().Get("sslmode"); gotSSL != "disable" {
|
|
t.Fatalf("sslmode 期望 disable,实际 %q", gotSSL)
|
|
}
|
|
}
|
|
|
|
func TestWithSearchPathWithoutQueryString(t *testing.T) {
|
|
got := withSearchPath("postgres://affiliate:pw@127.0.0.1:15432/affiliate_dash", "test_9")
|
|
|
|
if !strings.Contains(got, "?search_path=test_9") {
|
|
t.Fatalf("无查询串时应以 ? 开头追加,实际得到 %q", got)
|
|
}
|
|
}
|
|
|
|
// TestWithSearchPathKeywordValueForm keyword/value 形式(非 URL)走空格拼接分支。
|
|
func TestWithSearchPathKeywordValueForm(t *testing.T) {
|
|
got := withSearchPath("host=127.0.0.1 user=affiliate", "test_7")
|
|
|
|
if got != "host=127.0.0.1 user=affiliate search_path=test_7" {
|
|
t.Fatalf("keyword/value 形式拼接结果不符,实际得到 %q", got)
|
|
}
|
|
}
|