feat: complete API-driven projects with infrastructure and business acceptance
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"example.com/userService/internal/model"
|
||||
"git.yuntuo.hk/k2safe/go-omni/database"
|
||||
)
|
||||
|
||||
// This suite runs only against the disposable database created by verifyAPIWorkflow.
|
||||
func TestTransactions(t *testing.T) {
|
||||
if os.Getenv("USER_SERVICE_TEST_DATABASE") != "1" {
|
||||
t.Skip("isolated MySQL required")
|
||||
}
|
||||
cfg, err := database.ConfigFromEnv("")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
db, err := database.Open(context.Background(), cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
store := NewStore(db)
|
||||
for _, kind := range []string{"error", "panic", "cancel", "commit"} {
|
||||
t.Run(kind, func(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
email := kind + "@transaction.example"
|
||||
var recovered any
|
||||
func() {
|
||||
defer func() { recovered = recover() }()
|
||||
err = store.WithTx(ctx, func(r UserRepository, audit func(string, int64, string) error) error {
|
||||
u, e := r.Create(ctx, model.UserInput{Name: "Transaction", Email: email})
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
if e = audit("created", u.ID, "transactionCheck"); e != nil {
|
||||
return e
|
||||
}
|
||||
switch kind {
|
||||
case "error":
|
||||
return errors.New("rollback sentinel")
|
||||
case "panic":
|
||||
panic("rollback sentinel")
|
||||
case "cancel":
|
||||
cancel()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}()
|
||||
if kind == "panic" && recovered == nil {
|
||||
t.Fatal("panic lost")
|
||||
}
|
||||
if kind == "commit" && err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if kind != "commit" && kind != "panic" && err == nil {
|
||||
t.Fatal("failed transaction committed")
|
||||
}
|
||||
var count int
|
||||
if e := db.QueryRow("SELECT COUNT(*) FROM users WHERE email=?", email).Scan(&count); e != nil {
|
||||
t.Fatal(e)
|
||||
}
|
||||
want := 0
|
||||
if kind == "commit" {
|
||||
want = 1
|
||||
}
|
||||
if count != want {
|
||||
t.Fatalf("rows=%d want=%d", count, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
var audits int
|
||||
if err = db.QueryRow("SELECT COUNT(*) FROM user_audit WHERE request_id='transactionCheck'").Scan(&audits); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if audits != 1 {
|
||||
t.Fatalf("audit transaction mismatch: %d", audits)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user