You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

api_packages_npm_test.go 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package integrations
  5. import (
  6. "encoding/base64"
  7. "fmt"
  8. "net/http"
  9. "net/url"
  10. "strings"
  11. "testing"
  12. "code.gitea.io/gitea/models/db"
  13. "code.gitea.io/gitea/models/packages"
  14. "code.gitea.io/gitea/models/unittest"
  15. user_model "code.gitea.io/gitea/models/user"
  16. "code.gitea.io/gitea/modules/packages/npm"
  17. "code.gitea.io/gitea/modules/setting"
  18. "github.com/stretchr/testify/assert"
  19. )
  20. func TestPackageNpm(t *testing.T) {
  21. defer prepareTestEnv(t)()
  22. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
  23. token := fmt.Sprintf("Bearer %s", getTokenForLoggedInUser(t, loginUser(t, user.Name)))
  24. packageName := "@scope/test-package"
  25. packageVersion := "1.0.1-pre"
  26. packageTag := "latest"
  27. packageTag2 := "release"
  28. packageAuthor := "KN4CK3R"
  29. packageDescription := "Test Description"
  30. data := "H4sIAAAAAAAA/ytITM5OTE/VL4DQelnF+XkMVAYGBgZmJiYK2MRBwNDcSIHB2NTMwNDQzMwAqA7IMDUxA9LUdgg2UFpcklgEdAql5kD8ogCnhwio5lJQUMpLzE1VslJQcihOzi9I1S9JLS7RhSYIJR2QgrLUouLM/DyQGkM9Az1D3YIiqExKanFyUWZBCVQ2BKhVwQVJDKwosbQkI78IJO/tZ+LsbRykxFXLNdA+HwWjYBSMgpENACgAbtAACAAA"
  31. upload := `{
  32. "_id": "` + packageName + `",
  33. "name": "` + packageName + `",
  34. "description": "` + packageDescription + `",
  35. "dist-tags": {
  36. "` + packageTag + `": "` + packageVersion + `"
  37. },
  38. "versions": {
  39. "` + packageVersion + `": {
  40. "name": "` + packageName + `",
  41. "version": "` + packageVersion + `",
  42. "description": "` + packageDescription + `",
  43. "author": {
  44. "name": "` + packageAuthor + `"
  45. },
  46. "dist": {
  47. "integrity": "sha512-yA4FJsVhetynGfOC1jFf79BuS+jrHbm0fhh+aHzCQkOaOBXKf9oBnC4a6DnLLnEsHQDRLYd00cwj8sCXpC+wIg==",
  48. "shasum": "aaa7eaf852a948b0aa05afeda35b1badca155d90"
  49. }
  50. }
  51. },
  52. "_attachments": {
  53. "` + packageName + `-` + packageVersion + `.tgz": {
  54. "data": "` + data + `"
  55. }
  56. }
  57. }`
  58. root := fmt.Sprintf("/api/packages/%s/npm/%s", user.Name, url.QueryEscape(packageName))
  59. tagsRoot := fmt.Sprintf("/api/packages/%s/npm/-/package/%s/dist-tags", user.Name, url.QueryEscape(packageName))
  60. filename := fmt.Sprintf("%s-%s.tgz", strings.Split(packageName, "/")[1], packageVersion)
  61. t.Run("Upload", func(t *testing.T) {
  62. defer PrintCurrentTest(t)()
  63. req := NewRequestWithBody(t, "PUT", root, strings.NewReader(upload))
  64. req = addTokenAuthHeader(req, token)
  65. MakeRequest(t, req, http.StatusCreated)
  66. pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm)
  67. assert.NoError(t, err)
  68. assert.Len(t, pvs, 1)
  69. pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0])
  70. assert.NoError(t, err)
  71. assert.NotNil(t, pd.SemVer)
  72. assert.IsType(t, &npm.Metadata{}, pd.Metadata)
  73. assert.Equal(t, packageName, pd.Package.Name)
  74. assert.Equal(t, packageVersion, pd.Version.Version)
  75. assert.Len(t, pd.Properties, 1)
  76. assert.Equal(t, npm.TagProperty, pd.Properties[0].Name)
  77. assert.Equal(t, packageTag, pd.Properties[0].Value)
  78. pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID)
  79. assert.NoError(t, err)
  80. assert.Len(t, pfs, 1)
  81. assert.Equal(t, filename, pfs[0].Name)
  82. assert.True(t, pfs[0].IsLead)
  83. pb, err := packages.GetBlobByID(db.DefaultContext, pfs[0].BlobID)
  84. assert.NoError(t, err)
  85. assert.Equal(t, int64(192), pb.Size)
  86. })
  87. t.Run("UploadExists", func(t *testing.T) {
  88. defer PrintCurrentTest(t)()
  89. req := NewRequestWithBody(t, "PUT", root, strings.NewReader(upload))
  90. req = addTokenAuthHeader(req, token)
  91. MakeRequest(t, req, http.StatusBadRequest)
  92. })
  93. t.Run("Download", func(t *testing.T) {
  94. defer PrintCurrentTest(t)()
  95. req := NewRequest(t, "GET", fmt.Sprintf("%s/-/%s/%s", root, packageVersion, filename))
  96. req = addTokenAuthHeader(req, token)
  97. resp := MakeRequest(t, req, http.StatusOK)
  98. b, _ := base64.StdEncoding.DecodeString(data)
  99. assert.Equal(t, b, resp.Body.Bytes())
  100. pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm)
  101. assert.NoError(t, err)
  102. assert.Len(t, pvs, 1)
  103. assert.Equal(t, int64(1), pvs[0].DownloadCount)
  104. })
  105. t.Run("PackageMetadata", func(t *testing.T) {
  106. defer PrintCurrentTest(t)()
  107. req := NewRequest(t, "GET", fmt.Sprintf("/api/packages/%s/npm/%s", user.Name, "does-not-exist"))
  108. req = addTokenAuthHeader(req, token)
  109. MakeRequest(t, req, http.StatusNotFound)
  110. req = NewRequest(t, "GET", root)
  111. req = addTokenAuthHeader(req, token)
  112. resp := MakeRequest(t, req, http.StatusOK)
  113. var result npm.PackageMetadata
  114. DecodeJSON(t, resp, &result)
  115. assert.Equal(t, packageName, result.ID)
  116. assert.Equal(t, packageName, result.Name)
  117. assert.Equal(t, packageDescription, result.Description)
  118. assert.Contains(t, result.DistTags, packageTag)
  119. assert.Equal(t, packageVersion, result.DistTags[packageTag])
  120. assert.Equal(t, packageAuthor, result.Author.Name)
  121. assert.Contains(t, result.Versions, packageVersion)
  122. pmv := result.Versions[packageVersion]
  123. assert.Equal(t, fmt.Sprintf("%s@%s", packageName, packageVersion), pmv.ID)
  124. assert.Equal(t, packageName, pmv.Name)
  125. assert.Equal(t, packageDescription, pmv.Description)
  126. assert.Equal(t, packageAuthor, pmv.Author.Name)
  127. assert.Equal(t, "sha512-yA4FJsVhetynGfOC1jFf79BuS+jrHbm0fhh+aHzCQkOaOBXKf9oBnC4a6DnLLnEsHQDRLYd00cwj8sCXpC+wIg==", pmv.Dist.Integrity)
  128. assert.Equal(t, "aaa7eaf852a948b0aa05afeda35b1badca155d90", pmv.Dist.Shasum)
  129. assert.Equal(t, fmt.Sprintf("%s%s/-/%s/%s", setting.AppURL, root[1:], packageVersion, filename), pmv.Dist.Tarball)
  130. })
  131. t.Run("AddTag", func(t *testing.T) {
  132. defer PrintCurrentTest(t)()
  133. test := func(t *testing.T, status int, tag, version string) {
  134. req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/%s", tagsRoot, tag), strings.NewReader(`"`+version+`"`))
  135. req = addTokenAuthHeader(req, token)
  136. MakeRequest(t, req, status)
  137. }
  138. test(t, http.StatusBadRequest, "1.0", packageVersion)
  139. test(t, http.StatusBadRequest, "v1.0", packageVersion)
  140. test(t, http.StatusNotFound, packageTag2, "1.2")
  141. test(t, http.StatusOK, packageTag, packageVersion)
  142. test(t, http.StatusOK, packageTag2, packageVersion)
  143. })
  144. t.Run("ListTags", func(t *testing.T) {
  145. defer PrintCurrentTest(t)()
  146. req := NewRequest(t, "GET", tagsRoot)
  147. req = addTokenAuthHeader(req, token)
  148. resp := MakeRequest(t, req, http.StatusOK)
  149. var result map[string]string
  150. DecodeJSON(t, resp, &result)
  151. assert.Len(t, result, 2)
  152. assert.Contains(t, result, packageTag)
  153. assert.Equal(t, packageVersion, result[packageTag])
  154. assert.Contains(t, result, packageTag2)
  155. assert.Equal(t, packageVersion, result[packageTag2])
  156. })
  157. t.Run("PackageMetadataDistTags", func(t *testing.T) {
  158. defer PrintCurrentTest(t)()
  159. req := NewRequest(t, "GET", root)
  160. req = addTokenAuthHeader(req, token)
  161. resp := MakeRequest(t, req, http.StatusOK)
  162. var result npm.PackageMetadata
  163. DecodeJSON(t, resp, &result)
  164. assert.Len(t, result.DistTags, 2)
  165. assert.Contains(t, result.DistTags, packageTag)
  166. assert.Equal(t, packageVersion, result.DistTags[packageTag])
  167. assert.Contains(t, result.DistTags, packageTag2)
  168. assert.Equal(t, packageVersion, result.DistTags[packageTag2])
  169. })
  170. t.Run("DeleteTag", func(t *testing.T) {
  171. defer PrintCurrentTest(t)()
  172. test := func(t *testing.T, status int, tag string) {
  173. req := NewRequest(t, "DELETE", fmt.Sprintf("%s/%s", tagsRoot, tag))
  174. req = addTokenAuthHeader(req, token)
  175. MakeRequest(t, req, status)
  176. }
  177. test(t, http.StatusBadRequest, "v1.0")
  178. test(t, http.StatusBadRequest, "1.0")
  179. test(t, http.StatusOK, "dummy")
  180. test(t, http.StatusOK, packageTag2)
  181. })
  182. }