setup_test.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package integration_test
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. "mime/multipart"
  9. "net/http"
  10. "net/http/httptest"
  11. "os"
  12. "strings"
  13. "testing"
  14. "time"
  15. "github.com/qor5/admin/presets"
  16. "github.com/qor5/admin/presets/gorm2op"
  17. "github.com/qor5/admin/worker"
  18. integration "github.com/qor5/admin/worker/integration_test"
  19. . "github.com/qor5/ui/vuetify"
  20. "github.com/qor5/web"
  21. h "github.com/theplant/htmlgo"
  22. "gorm.io/driver/postgres"
  23. "gorm.io/gorm"
  24. )
  25. var (
  26. db *gorm.DB
  27. pb *presets.Builder
  28. )
  29. func TestMain(m *testing.M) {
  30. var err error
  31. db, err = gorm.Open(postgres.Open(os.Getenv("DBURL")), &gorm.Config{})
  32. if err != nil {
  33. panic(err)
  34. }
  35. pb = presets.New().
  36. DataOperator(gorm2op.DataOperator(db))
  37. wb := worker.NewWithQueue(db, integration.Que)
  38. wb.Configure(pb)
  39. addJobs(wb)
  40. wb.Listen()
  41. os.Exit(m.Run())
  42. }
  43. func addJobs(w *worker.Builder) {
  44. w.NewJob("noArgJob").
  45. Handler(func(ctx context.Context, job worker.QorJobInterface) error {
  46. job.AddLog("hoho1")
  47. job.AddLog("hoho2")
  48. job.AddLog("hoho3")
  49. return nil
  50. })
  51. w.NewJob("progressTextJob").
  52. Handler(func(ctx context.Context, job worker.QorJobInterface) error {
  53. job.AddLog("hoho1")
  54. job.AddLog("hoho2")
  55. job.AddLog("hoho3")
  56. job.SetProgressText(`<a href="https://www.google.com">Download users</a>`)
  57. return nil
  58. })
  59. type ArgJobResource struct {
  60. F1 string
  61. F2 int
  62. F3 bool
  63. }
  64. ajb := w.NewJob("argJob").
  65. Resource(&ArgJobResource{}).
  66. Handler(func(ctx context.Context, job worker.QorJobInterface) error {
  67. jobInfo, _ := job.GetJobInfo()
  68. job.AddLog(fmt.Sprintf("Argument %#+v", jobInfo.Argument))
  69. return nil
  70. })
  71. ajb.GetResourceBuilder().Editing().Field("F1").ComponentFunc(func(obj interface{}, field *presets.FieldContext, ctx *web.EventContext) h.HTMLComponent {
  72. var vErr web.ValidationErrors
  73. if ve, ok := ctx.Flash.(*web.ValidationErrors); ok {
  74. vErr = *ve
  75. }
  76. return VTextField().FieldName(field.Name).Label(field.Label).Value(field.Value(obj)).ErrorMessages(vErr.GetFieldErrors(field.Name)...)
  77. }).SetterFunc(func(obj interface{}, field *presets.FieldContext, ctx *web.EventContext) (err error) {
  78. v := ctx.R.FormValue("F1")
  79. obj.(*ArgJobResource).F1 = v
  80. if v == "aaa" {
  81. return errors.New("cannot be aaa")
  82. }
  83. return nil
  84. })
  85. w.NewJob("longRunningJob").
  86. Handler(func(ctx context.Context, job worker.QorJobInterface) error {
  87. for i := 1; i <= 5; i++ {
  88. select {
  89. case <-ctx.Done():
  90. job.AddLog("job aborted")
  91. return nil
  92. default:
  93. job.AddLog(fmt.Sprintf("%v", i))
  94. job.SetProgress(uint(i * 20))
  95. time.Sleep(time.Second)
  96. }
  97. }
  98. return nil
  99. })
  100. type ScheduleJobResource struct {
  101. F1 string
  102. worker.Schedule
  103. }
  104. w.NewJob("scheduleJob").
  105. Resource(&ScheduleJobResource{}).
  106. Handler(func(ctx context.Context, job worker.QorJobInterface) error {
  107. jobInfo, _ := job.GetJobInfo()
  108. job.AddLog(fmt.Sprintf("%#+v", jobInfo.Argument))
  109. return nil
  110. })
  111. w.NewJob("errorJob").
  112. Handler(func(ctx context.Context, job worker.QorJobInterface) error {
  113. job.AddLog("=====perform error job")
  114. return errors.New("imError")
  115. })
  116. w.NewJob("panicJob").
  117. Handler(func(ctx context.Context, job worker.QorJobInterface) error {
  118. job.AddLog("=====perform panic job")
  119. panic("letsPanic")
  120. })
  121. }
  122. func cleanData() {
  123. err := db.Exec(`
  124. delete from qor_jobs;
  125. delete from qor_job_instances;
  126. delete from qor_job_logs;
  127. `).Error
  128. if err != nil {
  129. panic(err)
  130. }
  131. }
  132. func mustParseEventResponse(b []byte) web.EventResponse {
  133. r := web.EventResponse{}
  134. if err := json.Unmarshal(b, &r); err != nil {
  135. panic(err)
  136. }
  137. return r
  138. }
  139. func mustCreateJob(form map[string]string) {
  140. rBody := bytes.NewBuffer(nil)
  141. mw := multipart.NewWriter(rBody)
  142. for k, v := range form {
  143. mw.WriteField(k, v)
  144. }
  145. mw.Close()
  146. r := httptest.NewRequest(http.MethodPost, "/workers?__execute_event__=presets_Update", rBody)
  147. r.Header.Add("Content-Type", fmt.Sprintf("multipart/form-data; boundary=%s", mw.Boundary()))
  148. w := httptest.NewRecorder()
  149. pb.ServeHTTP(w, r)
  150. body := w.Body.String()
  151. if !strings.Contains(body, "success") {
  152. panic("create job failed")
  153. }
  154. }
  155. func mustGetFirstJob() *worker.QorJob {
  156. r := &worker.QorJob{}
  157. if err := db.First(r).Error; err != nil {
  158. panic(err)
  159. }
  160. return r
  161. }