batch_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package lfs
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "io"
  6. "net/http"
  7. "net/http/httptest"
  8. "testing"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/stretchr/testify/require"
  11. "github.com/flamego/flamego"
  12. "gogs.io/gogs/internal/conf"
  13. "gogs.io/gogs/internal/database"
  14. )
  15. func TestServeBatch(t *testing.T) {
  16. conf.SetMockServer(t, conf.ServerOpts{
  17. ExternalURL: "https://gogs.example.com/",
  18. })
  19. tests := []struct {
  20. name string
  21. body string
  22. mockStore func() *MockStore
  23. expStatusCode int
  24. expBody string
  25. }{
  26. {
  27. name: "unrecognized operation",
  28. body: `{"operation": "update"}`,
  29. expStatusCode: http.StatusBadRequest,
  30. expBody: `{"message": "Operation not recognized"}` + "\n",
  31. },
  32. {
  33. name: "upload: contains invalid oid",
  34. body: `{
  35. "operation": "upload",
  36. "objects": [
  37. {"oid": "bad_oid", "size": 123},
  38. {"oid": "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f", "size": 123}
  39. ]}`,
  40. expStatusCode: http.StatusOK,
  41. expBody: `{
  42. "transfer": "basic",
  43. "objects": [
  44. {"oid": "bad_oid", "size":123, "actions": {"error": {"code": 422, "message": "Object has invalid oid"}}},
  45. {
  46. "oid": "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f",
  47. "size": 123,
  48. "actions": {
  49. "upload": {
  50. "href": "https://gogs.example.com/owner/repo.git/info/lfs/objects/basic/ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f",
  51. "header": {"Content-Type": "application/octet-stream"}
  52. },
  53. "verify": {
  54. "href": "https://gogs.example.com/owner/repo.git/info/lfs/objects/basic/verify"
  55. }
  56. }
  57. }
  58. ]
  59. }` + "\n",
  60. },
  61. {
  62. name: "download: contains non-existent oid and mismatched size",
  63. body: `{
  64. "operation": "download",
  65. "objects": [
  66. {"oid": "bad_oid", "size": 123},
  67. {"oid": "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f", "size": 123},
  68. {"oid": "5cac0a318669fadfee734fb340a5f5b70b428ac57a9f4b109cb6e150b2ba7e57", "size": 456}
  69. ]}`,
  70. mockStore: func() *MockStore {
  71. mockStore := NewMockStore()
  72. mockStore.GetLFSObjectsByOIDsFunc.SetDefaultReturn(
  73. []*database.LFSObject{
  74. {
  75. OID: "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f",
  76. Size: 1234,
  77. }, {
  78. OID: "5cac0a318669fadfee734fb340a5f5b70b428ac57a9f4b109cb6e150b2ba7e57",
  79. Size: 456,
  80. },
  81. },
  82. nil,
  83. )
  84. return mockStore
  85. },
  86. expStatusCode: http.StatusOK,
  87. expBody: `{
  88. "transfer": "basic",
  89. "objects": [
  90. {"oid": "bad_oid", "size": 123, "actions": {"error": {"code": 404, "message": "Object does not exist"}}},
  91. {
  92. "oid": "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f",
  93. "size": 123,
  94. "actions": {"error": {"code": 422, "message": "Object size mismatch"}}
  95. },
  96. {
  97. "oid": "5cac0a318669fadfee734fb340a5f5b70b428ac57a9f4b109cb6e150b2ba7e57",
  98. "size": 456,
  99. "actions": {
  100. "download": {
  101. "href": "https://gogs.example.com/owner/repo.git/info/lfs/objects/basic/5cac0a318669fadfee734fb340a5f5b70b428ac57a9f4b109cb6e150b2ba7e57"
  102. }
  103. }
  104. }
  105. ]
  106. }` + "\n",
  107. },
  108. }
  109. for _, test := range tests {
  110. t.Run(test.name, func(t *testing.T) {
  111. mockStore := NewMockStore()
  112. if test.mockStore != nil {
  113. mockStore = test.mockStore()
  114. }
  115. m := macaron.New()
  116. m.Use(func(c *macaron.Context) {
  117. c.Map(&database.User{Name: "owner"})
  118. c.Map(&database.Repository{Name: "repo"})
  119. })
  120. m.Post("/", serveBatch(mockStore))
  121. r, err := http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(test.body))
  122. require.NoError(t, err)
  123. rr := httptest.NewRecorder()
  124. m.ServeHTTP(rr, r)
  125. resp := rr.Result()
  126. assert.Equal(t, test.expStatusCode, resp.StatusCode)
  127. body, err := io.ReadAll(resp.Body)
  128. require.NoError(t, err)
  129. var expBody bytes.Buffer
  130. err = json.Indent(&expBody, []byte(test.expBody), "", " ")
  131. require.NoError(t, err)
  132. var gotBody bytes.Buffer
  133. err = json.Indent(&gotBody, body, "", " ")
  134. require.NoError(t, err)
  135. assert.Equal(t, expBody.String(), gotBody.String())
  136. })
  137. }
  138. }