对接
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
const (
|
||||
baseURL = "http://127.0.0.1:18080"
|
||||
wsURL = "ws://127.0.0.1:18080/ws"
|
||||
outputDir = ".tmp-live-acceptance"
|
||||
adminPassword = "LocalAdmin_2026!"
|
||||
userPassword = "LocalAccept_2026!"
|
||||
)
|
||||
|
||||
type apiClient struct {
|
||||
http *http.Client
|
||||
token string
|
||||
}
|
||||
|
||||
type envelope struct {
|
||||
Code int `json:"code"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
type account struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
ID uint `json:"id"`
|
||||
}
|
||||
|
||||
type fixtures struct {
|
||||
BaseURL string `json:"baseUrl"`
|
||||
Database string `json:"database"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
Admin account `json:"admin"`
|
||||
Anchor account `json:"anchor"`
|
||||
Viewer account `json:"viewer"`
|
||||
Other account `json:"other"`
|
||||
CategoryID uint `json:"categoryId"`
|
||||
RoomID uint `json:"roomId"`
|
||||
ReplayID uint `json:"replayRoomId"`
|
||||
DisabledID uint `json:"disabledRoomId"`
|
||||
BrowserID uint `json:"browserRoomId,omitempty"`
|
||||
GiftID uint `json:"giftId"`
|
||||
Checks []string `json:"setupChecks"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
if len(os.Args) != 2 {
|
||||
log.Fatal("usage: go run ./tmp/live_acceptance <setup|verify|publisher|mock-payment|browser-room>")
|
||||
}
|
||||
var err error
|
||||
switch os.Args[1] {
|
||||
case "setup":
|
||||
err = setup()
|
||||
case "verify":
|
||||
err = verify()
|
||||
case "publisher":
|
||||
err = holdPublisher()
|
||||
case "mock-payment":
|
||||
err = serveMockPayments()
|
||||
case "browser-room":
|
||||
err = setupBrowserRoom()
|
||||
default:
|
||||
err = errors.New("unknown command")
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func newClient() *apiClient {
|
||||
jar, _ := cookiejar.New(nil)
|
||||
return &apiClient{http: &http.Client{Jar: jar, Timeout: 30 * time.Second}}
|
||||
}
|
||||
|
||||
func (c *apiClient) call(method, path string, body, out any) error {
|
||||
var reader io.Reader
|
||||
if body != nil {
|
||||
data, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reader = bytes.NewReader(data)
|
||||
}
|
||||
req, err := http.NewRequest(method, baseURL+path, reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
if c.token != "" {
|
||||
req.Header.Set("x-token", c.token)
|
||||
}
|
||||
response, err := c.http.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
var result envelope
|
||||
if err = json.NewDecoder(response.Body).Decode(&result); err != nil {
|
||||
return fmt.Errorf("%s %s status=%d: %w", method, path, response.StatusCode, err)
|
||||
}
|
||||
if result.Code != 0 || response.StatusCode >= 400 {
|
||||
return fmt.Errorf("%s %s status=%d code=%d: %s", method, path, response.StatusCode, result.Code, result.Msg)
|
||||
}
|
||||
if out != nil {
|
||||
return json.Unmarshal(result.Data, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func login(user account, admin bool) (*apiClient, error) {
|
||||
c := newClient()
|
||||
path := "/live/client/auth/login"
|
||||
if admin {
|
||||
path = "/base/login"
|
||||
}
|
||||
var result struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
if err := c.call("POST", path, map[string]any{"username": user.Username, "password": user.Password}, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if result.Token == "" {
|
||||
return nil, errors.New("login returned no token")
|
||||
}
|
||||
c.token = result.Token
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func readFixtures() (*fixtures, error) {
|
||||
raw, err := os.ReadFile(filepath.Join(outputDir, "fixtures.json"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var f fixtures
|
||||
if err = json.Unmarshal(raw, &f); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
absolute, err := filepath.Abs(filepath.Join(outputDir, "acceptance.db"))
|
||||
if err != nil || f.Database != absolute || f.BaseURL != baseURL {
|
||||
return nil, errors.New("fixture points outside the isolated acceptance environment")
|
||||
}
|
||||
return &f, nil
|
||||
}
|
||||
|
||||
func saveJSON(name string, value any) error {
|
||||
data, err := json.MarshalIndent(value, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(filepath.Join(outputDir, name), append(data, '\n'), 0600)
|
||||
}
|
||||
|
||||
func must(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func check(condition bool, format string, args ...any) {
|
||||
if !condition {
|
||||
panic(fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
func roomPath(id uint) string { return fmt.Sprintf("/live/rooms/%d", id) }
|
||||
|
||||
func adminRoomPath(id uint) string { return fmt.Sprintf("/live/admin/rooms/%d", id) }
|
||||
|
||||
func makeRoom(name string, categoryID, anchorID uint, replay string, enabled bool) dto.LiveRoomRequest {
|
||||
return dto.LiveRoomRequest{
|
||||
Name: name, CategoryID: categoryID, AnchorUserID: anchorID,
|
||||
CoverURL: "/uploads/acceptance-cover.jpg", Intro: "Local isolated acceptance room",
|
||||
ReplayURL: replay, Enabled: enabled,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user