Scert/backend/internal/httpapi/domain_initial_dns_test.go

66 lines
3.1 KiB
Go

package httpapi
import (
"encoding/json"
"fmt"
"net/http"
"testing"
"git.pcux.cn/xuans/Scert/backend/internal/domain"
"git.pcux.cn/xuans/Scert/backend/internal/repository"
)
func TestDomainInitialDNSAccountAtomicAPI(t *testing.T) {
f := newProjectMemberAPIFixture(t)
f.server.projectDomains = f.members
f.server.repository = repository.NewSQLDomainRepository(f.db)
account, err := f.members.CreateDNSAccount(t.Context(), "primary-super-admin", domain.DNSAccount{ID: "initial-account", Name: "初始账户", ProjectID: "default", Provider: "cloudflare", CredentialRef: "secret://dns/initial"})
if err != nil {
t.Fatal(err)
}
account, err = f.members.RecordDNSAccountVerification(t.Context(), "primary-super-admin", account.ID, account.Revision, true)
if err != nil {
t.Fatal(err)
}
for _, scenario := range []struct {
name, actor, provider, challenge, accountID string
revision int64
status int
}{
{"success", "primary-super-admin", "cloudflare", "dns-01", account.ID, account.Revision, http.StatusCreated},
{"old-version", "primary-super-admin", "cloudflare", "dns-01", account.ID, 1, http.StatusConflict},
{"wrong-provider", "primary-super-admin", "route53", "dns-01", account.ID, account.Revision, http.StatusUnprocessableEntity},
{"wrong-challenge", "primary-super-admin", "cloudflare", "http-01", account.ID, account.Revision, http.StatusBadRequest},
{"no-account", "primary-super-admin", "cloudflare", "dns-01", "", 2, http.StatusBadRequest},
{"no-permission", "viewer", "cloudflare", "dns-01", account.ID, account.Revision, http.StatusForbidden},
} {
t.Run(scenario.name, func(t *testing.T) {
name := scenario.name + ".example.test"
body := fmt.Sprintf(`{"name":%q,"certificate_type":"single","challenge_type":%q,"dns_provider":%q,"dns_account_id":%q,"dns_account_revision":%d}`, name, scenario.challenge, scenario.provider, scenario.accountID, scenario.revision)
response := serveUserRequest(f.server, f.cookies[scenario.actor], http.MethodPost, "/api/v1/domains", body)
if response.Code != scenario.status {
t.Fatal("创建接口状态错误", response.Code, response.Body.String())
}
if response.Code == http.StatusCreated {
var item domain.Domain
if err := json.Unmarshal(response.Body.Bytes(), &item); err != nil {
t.Fatal(err)
}
loaded, err := repository.NewSQLDomainRepository(f.db).GetByID(t.Context(), item.ID)
if err != nil || item.DNSBindingID == "" || item.DNSBindingID != loaded.DNSBindingID || loaded.DNSAccountID != account.ID {
t.Fatal("创建响应与原子绑定不符", err)
}
response = serveUserRequest(f.server, f.cookies[scenario.actor], http.MethodPut, "/api/v1/domains/"+item.ID, body)
if response.Code != http.StatusBadRequest {
t.Fatal("普通更新不能绕过绑定令牌", response.Code)
}
} else {
var count int
if err := f.db.QueryRowContext(t.Context(), `SELECT COUNT(*) FROM domains WHERE name = ?`, name).Scan(&count); err != nil || count != 0 {
t.Fatal("失败后遗留未绑定域名", err)
}
}
})
}
}