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_nuget_test.go 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package integration
  4. import (
  5. "archive/zip"
  6. "bytes"
  7. "encoding/base64"
  8. "encoding/xml"
  9. "fmt"
  10. "io"
  11. "io/ioutil"
  12. "net/http"
  13. "net/http/httptest"
  14. "testing"
  15. "time"
  16. "code.gitea.io/gitea/models/db"
  17. "code.gitea.io/gitea/models/packages"
  18. "code.gitea.io/gitea/models/unittest"
  19. user_model "code.gitea.io/gitea/models/user"
  20. nuget_module "code.gitea.io/gitea/modules/packages/nuget"
  21. "code.gitea.io/gitea/modules/setting"
  22. "code.gitea.io/gitea/modules/structs"
  23. "code.gitea.io/gitea/routers/api/packages/nuget"
  24. "code.gitea.io/gitea/tests"
  25. "github.com/stretchr/testify/assert"
  26. )
  27. func addNuGetAPIKeyHeader(request *http.Request, token string) *http.Request {
  28. request.Header.Set("X-NuGet-ApiKey", token)
  29. return request
  30. }
  31. func decodeXML(t testing.TB, resp *httptest.ResponseRecorder, v interface{}) {
  32. t.Helper()
  33. assert.NoError(t, xml.NewDecoder(resp.Body).Decode(v))
  34. }
  35. func TestPackageNuGet(t *testing.T) {
  36. defer tests.PrepareTestEnv(t)()
  37. type FeedEntryProperties struct {
  38. Version string `xml:"Version"`
  39. NormalizedVersion string `xml:"NormalizedVersion"`
  40. Authors string `xml:"Authors"`
  41. Dependencies string `xml:"Dependencies"`
  42. Description string `xml:"Description"`
  43. VersionDownloadCount nuget.TypedValue[int64] `xml:"VersionDownloadCount"`
  44. DownloadCount nuget.TypedValue[int64] `xml:"DownloadCount"`
  45. PackageSize nuget.TypedValue[int64] `xml:"PackageSize"`
  46. Created nuget.TypedValue[time.Time] `xml:"Created"`
  47. LastUpdated nuget.TypedValue[time.Time] `xml:"LastUpdated"`
  48. Published nuget.TypedValue[time.Time] `xml:"Published"`
  49. ProjectURL string `xml:"ProjectUrl,omitempty"`
  50. ReleaseNotes string `xml:"ReleaseNotes,omitempty"`
  51. RequireLicenseAcceptance nuget.TypedValue[bool] `xml:"RequireLicenseAcceptance"`
  52. Title string `xml:"Title"`
  53. }
  54. type FeedEntry struct {
  55. XMLName xml.Name `xml:"entry"`
  56. Properties *FeedEntryProperties `xml:"properties"`
  57. Content string `xml:",innerxml"`
  58. }
  59. type FeedResponse struct {
  60. XMLName xml.Name `xml:"feed"`
  61. Entries []*FeedEntry `xml:"entry"`
  62. Count int64 `xml:"count"`
  63. }
  64. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  65. token := getUserToken(t, user.Name)
  66. packageName := "test.package"
  67. packageVersion := "1.0.3"
  68. packageAuthors := "KN4CK3R"
  69. packageDescription := "Gitea Test Package"
  70. symbolFilename := "test.pdb"
  71. symbolID := "d910bb6948bd4c6cb40155bcf52c3c94"
  72. createPackage := func(id, version string) io.Reader {
  73. var buf bytes.Buffer
  74. archive := zip.NewWriter(&buf)
  75. w, _ := archive.Create("package.nuspec")
  76. w.Write([]byte(`<?xml version="1.0" encoding="utf-8"?>
  77. <package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
  78. <metadata>
  79. <id>` + id + `</id>
  80. <version>` + version + `</version>
  81. <authors>` + packageAuthors + `</authors>
  82. <description>` + packageDescription + `</description>
  83. <dependencies>
  84. <group targetFramework=".NETStandard2.0">
  85. <dependency id="Microsoft.CSharp" version="4.5.0" />
  86. </group>
  87. </dependencies>
  88. </metadata>
  89. </package>`))
  90. archive.Close()
  91. return &buf
  92. }
  93. content, _ := ioutil.ReadAll(createPackage(packageName, packageVersion))
  94. url := fmt.Sprintf("/api/packages/%s/nuget", user.Name)
  95. t.Run("ServiceIndex", func(t *testing.T) {
  96. defer tests.PrintCurrentTest(t)()
  97. t.Run("v2", func(t *testing.T) {
  98. defer tests.PrintCurrentTest(t)()
  99. privateUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Visibility: structs.VisibleTypePrivate})
  100. cases := []struct {
  101. Owner string
  102. UseBasicAuth bool
  103. UseTokenAuth bool
  104. }{
  105. {privateUser.Name, false, false},
  106. {privateUser.Name, true, false},
  107. {privateUser.Name, false, true},
  108. {user.Name, false, false},
  109. {user.Name, true, false},
  110. {user.Name, false, true},
  111. }
  112. for _, c := range cases {
  113. url := fmt.Sprintf("/api/packages/%s/nuget", c.Owner)
  114. req := NewRequest(t, "GET", url)
  115. if c.UseBasicAuth {
  116. req = AddBasicAuthHeader(req, user.Name)
  117. } else if c.UseTokenAuth {
  118. req = addNuGetAPIKeyHeader(req, token)
  119. }
  120. resp := MakeRequest(t, req, http.StatusOK)
  121. var result nuget.ServiceIndexResponseV2
  122. decodeXML(t, resp, &result)
  123. assert.Equal(t, setting.AppURL+url[1:], result.Base)
  124. assert.Equal(t, "Packages", result.Workspace.Collection.Href)
  125. }
  126. })
  127. t.Run("v3", func(t *testing.T) {
  128. defer tests.PrintCurrentTest(t)()
  129. privateUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Visibility: structs.VisibleTypePrivate})
  130. cases := []struct {
  131. Owner string
  132. UseBasicAuth bool
  133. UseTokenAuth bool
  134. }{
  135. {privateUser.Name, false, false},
  136. {privateUser.Name, true, false},
  137. {privateUser.Name, false, true},
  138. {user.Name, false, false},
  139. {user.Name, true, false},
  140. {user.Name, false, true},
  141. }
  142. for _, c := range cases {
  143. url := fmt.Sprintf("/api/packages/%s/nuget", c.Owner)
  144. req := NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url))
  145. if c.UseBasicAuth {
  146. req = AddBasicAuthHeader(req, user.Name)
  147. } else if c.UseTokenAuth {
  148. req = addNuGetAPIKeyHeader(req, token)
  149. }
  150. resp := MakeRequest(t, req, http.StatusOK)
  151. var result nuget.ServiceIndexResponseV3
  152. DecodeJSON(t, resp, &result)
  153. assert.Equal(t, "3.0.0", result.Version)
  154. assert.NotEmpty(t, result.Resources)
  155. root := setting.AppURL + url[1:]
  156. for _, r := range result.Resources {
  157. switch r.Type {
  158. case "SearchQueryService":
  159. fallthrough
  160. case "SearchQueryService/3.0.0-beta":
  161. fallthrough
  162. case "SearchQueryService/3.0.0-rc":
  163. assert.Equal(t, root+"/query", r.ID)
  164. case "RegistrationsBaseUrl":
  165. fallthrough
  166. case "RegistrationsBaseUrl/3.0.0-beta":
  167. fallthrough
  168. case "RegistrationsBaseUrl/3.0.0-rc":
  169. assert.Equal(t, root+"/registration", r.ID)
  170. case "PackageBaseAddress/3.0.0":
  171. assert.Equal(t, root+"/package", r.ID)
  172. case "PackagePublish/2.0.0":
  173. assert.Equal(t, root, r.ID)
  174. }
  175. }
  176. }
  177. })
  178. })
  179. t.Run("Upload", func(t *testing.T) {
  180. t.Run("DependencyPackage", func(t *testing.T) {
  181. defer tests.PrintCurrentTest(t)()
  182. req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content))
  183. req = AddBasicAuthHeader(req, user.Name)
  184. MakeRequest(t, req, http.StatusCreated)
  185. pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNuGet)
  186. assert.NoError(t, err)
  187. assert.Len(t, pvs, 1)
  188. pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0])
  189. assert.NoError(t, err)
  190. assert.NotNil(t, pd.SemVer)
  191. assert.IsType(t, &nuget_module.Metadata{}, pd.Metadata)
  192. assert.Equal(t, packageName, pd.Package.Name)
  193. assert.Equal(t, packageVersion, pd.Version.Version)
  194. pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID)
  195. assert.NoError(t, err)
  196. assert.Len(t, pfs, 1)
  197. assert.Equal(t, fmt.Sprintf("%s.%s.nupkg", packageName, packageVersion), pfs[0].Name)
  198. assert.True(t, pfs[0].IsLead)
  199. pb, err := packages.GetBlobByID(db.DefaultContext, pfs[0].BlobID)
  200. assert.NoError(t, err)
  201. assert.Equal(t, int64(len(content)), pb.Size)
  202. req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content))
  203. req = AddBasicAuthHeader(req, user.Name)
  204. MakeRequest(t, req, http.StatusConflict)
  205. })
  206. t.Run("SymbolPackage", func(t *testing.T) {
  207. defer tests.PrintCurrentTest(t)()
  208. createSymbolPackage := func(id, packageType string) io.Reader {
  209. var buf bytes.Buffer
  210. archive := zip.NewWriter(&buf)
  211. w, _ := archive.Create("package.nuspec")
  212. w.Write([]byte(`<?xml version="1.0" encoding="utf-8"?>
  213. <package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
  214. <metadata>
  215. <id>` + id + `</id>
  216. <version>` + packageVersion + `</version>
  217. <authors>` + packageAuthors + `</authors>
  218. <description>` + packageDescription + `</description>
  219. <packageTypes><packageType name="` + packageType + `" /></packageTypes>
  220. </metadata>
  221. </package>`))
  222. w, _ = archive.Create(symbolFilename)
  223. b, _ := base64.StdEncoding.DecodeString(`QlNKQgEAAQAAAAAADAAAAFBEQiB2MS4wAAAAAAAABgB8AAAAWAAAACNQZGIAAAAA1AAAAAgBAAAj
  224. fgAA3AEAAAQAAAAjU3RyaW5ncwAAAADgAQAABAAAACNVUwDkAQAAMAAAACNHVUlEAAAAFAIAACgB
  225. AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
  226. w.Write(b)
  227. archive.Close()
  228. return &buf
  229. }
  230. req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage("unknown-package", "SymbolsPackage"))
  231. req = AddBasicAuthHeader(req, user.Name)
  232. MakeRequest(t, req, http.StatusNotFound)
  233. req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "DummyPackage"))
  234. req = AddBasicAuthHeader(req, user.Name)
  235. MakeRequest(t, req, http.StatusBadRequest)
  236. req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "SymbolsPackage"))
  237. req = AddBasicAuthHeader(req, user.Name)
  238. MakeRequest(t, req, http.StatusCreated)
  239. pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNuGet)
  240. assert.NoError(t, err)
  241. assert.Len(t, pvs, 1)
  242. pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0])
  243. assert.NoError(t, err)
  244. assert.NotNil(t, pd.SemVer)
  245. assert.IsType(t, &nuget_module.Metadata{}, pd.Metadata)
  246. assert.Equal(t, packageName, pd.Package.Name)
  247. assert.Equal(t, packageVersion, pd.Version.Version)
  248. pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID)
  249. assert.NoError(t, err)
  250. assert.Len(t, pfs, 3)
  251. for _, pf := range pfs {
  252. switch pf.Name {
  253. case fmt.Sprintf("%s.%s.nupkg", packageName, packageVersion):
  254. case fmt.Sprintf("%s.%s.snupkg", packageName, packageVersion):
  255. assert.False(t, pf.IsLead)
  256. pb, err := packages.GetBlobByID(db.DefaultContext, pf.BlobID)
  257. assert.NoError(t, err)
  258. assert.Equal(t, int64(616), pb.Size)
  259. case symbolFilename:
  260. assert.False(t, pf.IsLead)
  261. pb, err := packages.GetBlobByID(db.DefaultContext, pf.BlobID)
  262. assert.NoError(t, err)
  263. assert.Equal(t, int64(160), pb.Size)
  264. pps, err := packages.GetProperties(db.DefaultContext, packages.PropertyTypeFile, pf.ID)
  265. assert.NoError(t, err)
  266. assert.Len(t, pps, 1)
  267. assert.Equal(t, nuget_module.PropertySymbolID, pps[0].Name)
  268. assert.Equal(t, symbolID, pps[0].Value)
  269. default:
  270. assert.Fail(t, "unexpected file: %v", pf.Name)
  271. }
  272. }
  273. req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "SymbolsPackage"))
  274. req = AddBasicAuthHeader(req, user.Name)
  275. MakeRequest(t, req, http.StatusConflict)
  276. })
  277. })
  278. t.Run("Download", func(t *testing.T) {
  279. defer tests.PrintCurrentTest(t)()
  280. checkDownloadCount := func(count int64) {
  281. pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNuGet)
  282. assert.NoError(t, err)
  283. assert.Len(t, pvs, 1)
  284. assert.Equal(t, count, pvs[0].DownloadCount)
  285. }
  286. checkDownloadCount(0)
  287. req := NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/%s/%s.%s.nupkg", url, packageName, packageVersion, packageName, packageVersion))
  288. req = AddBasicAuthHeader(req, user.Name)
  289. resp := MakeRequest(t, req, http.StatusOK)
  290. assert.Equal(t, content, resp.Body.Bytes())
  291. checkDownloadCount(1)
  292. req = NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/%s/%s.%s.snupkg", url, packageName, packageVersion, packageName, packageVersion))
  293. req = AddBasicAuthHeader(req, user.Name)
  294. MakeRequest(t, req, http.StatusOK)
  295. checkDownloadCount(1)
  296. t.Run("Symbol", func(t *testing.T) {
  297. defer tests.PrintCurrentTest(t)()
  298. req := NewRequest(t, "GET", fmt.Sprintf("%s/symbols/%s/%sFFFFFFFF/gitea.pdb", url, symbolFilename, symbolID))
  299. MakeRequest(t, req, http.StatusBadRequest)
  300. req = NewRequest(t, "GET", fmt.Sprintf("%s/symbols/%s/%sFFFFFFFF/%s", url, symbolFilename, "00000000000000000000000000000000", symbolFilename))
  301. req = AddBasicAuthHeader(req, user.Name)
  302. MakeRequest(t, req, http.StatusNotFound)
  303. req = NewRequest(t, "GET", fmt.Sprintf("%s/symbols/%s/%sFFFFffff/%s", url, symbolFilename, symbolID, symbolFilename))
  304. req = AddBasicAuthHeader(req, user.Name)
  305. MakeRequest(t, req, http.StatusOK)
  306. checkDownloadCount(1)
  307. })
  308. })
  309. t.Run("SearchService", func(t *testing.T) {
  310. defer tests.PrintCurrentTest(t)()
  311. cases := []struct {
  312. Query string
  313. Skip int
  314. Take int
  315. ExpectedTotal int64
  316. ExpectedResults int
  317. }{
  318. {"", 0, 0, 1, 1},
  319. {"", 0, 10, 1, 1},
  320. {"gitea", 0, 10, 0, 0},
  321. {"test", 0, 10, 1, 1},
  322. {"test", 1, 10, 1, 0},
  323. }
  324. t.Run("v2", func(t *testing.T) {
  325. defer tests.PrintCurrentTest(t)()
  326. t.Run("Search()", func(t *testing.T) {
  327. defer tests.PrintCurrentTest(t)()
  328. for i, c := range cases {
  329. req := NewRequest(t, "GET", fmt.Sprintf("%s/Search()?searchTerm='%s'&skip=%d&take=%d", url, c.Query, c.Skip, c.Take))
  330. req = AddBasicAuthHeader(req, user.Name)
  331. resp := MakeRequest(t, req, http.StatusOK)
  332. var result FeedResponse
  333. decodeXML(t, resp, &result)
  334. assert.Equal(t, c.ExpectedTotal, result.Count, "case %d: unexpected total hits", i)
  335. assert.Len(t, result.Entries, c.ExpectedResults, "case %d: unexpected result count", i)
  336. }
  337. })
  338. t.Run("Packages()", func(t *testing.T) {
  339. defer tests.PrintCurrentTest(t)()
  340. for i, c := range cases {
  341. req := NewRequest(t, "GET", fmt.Sprintf("%s/Search()?$filter=substringof('%s',tolower(Id))&$skip=%d&$top=%d", url, c.Query, c.Skip, c.Take))
  342. req = AddBasicAuthHeader(req, user.Name)
  343. resp := MakeRequest(t, req, http.StatusOK)
  344. var result FeedResponse
  345. decodeXML(t, resp, &result)
  346. assert.Equal(t, c.ExpectedTotal, result.Count, "case %d: unexpected total hits", i)
  347. assert.Len(t, result.Entries, c.ExpectedResults, "case %d: unexpected result count", i)
  348. }
  349. })
  350. })
  351. t.Run("v3", func(t *testing.T) {
  352. defer tests.PrintCurrentTest(t)()
  353. for i, c := range cases {
  354. req := NewRequest(t, "GET", fmt.Sprintf("%s/query?q=%s&skip=%d&take=%d", url, c.Query, c.Skip, c.Take))
  355. req = AddBasicAuthHeader(req, user.Name)
  356. resp := MakeRequest(t, req, http.StatusOK)
  357. var result nuget.SearchResultResponse
  358. DecodeJSON(t, resp, &result)
  359. assert.Equal(t, c.ExpectedTotal, result.TotalHits, "case %d: unexpected total hits", i)
  360. assert.Len(t, result.Data, c.ExpectedResults, "case %d: unexpected result count", i)
  361. }
  362. t.Run("EnforceGrouped", func(t *testing.T) {
  363. defer tests.PrintCurrentTest(t)()
  364. req := NewRequestWithBody(t, "PUT", url, createPackage(packageName+".dummy", "1.0.0"))
  365. req = AddBasicAuthHeader(req, user.Name)
  366. MakeRequest(t, req, http.StatusCreated)
  367. req = NewRequestWithBody(t, "PUT", url, createPackage(packageName, "1.0.99"))
  368. req = AddBasicAuthHeader(req, user.Name)
  369. MakeRequest(t, req, http.StatusCreated)
  370. req = NewRequest(t, "GET", fmt.Sprintf("%s/query?q=%s", url, packageName))
  371. req = AddBasicAuthHeader(req, user.Name)
  372. resp := MakeRequest(t, req, http.StatusOK)
  373. var result nuget.SearchResultResponse
  374. DecodeJSON(t, resp, &result)
  375. assert.EqualValues(t, 3, result.TotalHits)
  376. assert.Len(t, result.Data, 2)
  377. for _, sr := range result.Data {
  378. if sr.ID == packageName {
  379. assert.Len(t, sr.Versions, 2)
  380. } else {
  381. assert.Len(t, sr.Versions, 1)
  382. }
  383. }
  384. req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s", url, packageName+".dummy", "1.0.0"))
  385. req = AddBasicAuthHeader(req, user.Name)
  386. MakeRequest(t, req, http.StatusNoContent)
  387. req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s", url, packageName, "1.0.99"))
  388. req = AddBasicAuthHeader(req, user.Name)
  389. MakeRequest(t, req, http.StatusNoContent)
  390. })
  391. })
  392. })
  393. t.Run("RegistrationService", func(t *testing.T) {
  394. indexURL := fmt.Sprintf("%s%s/registration/%s/index.json", setting.AppURL, url[1:], packageName)
  395. leafURL := fmt.Sprintf("%s%s/registration/%s/%s.json", setting.AppURL, url[1:], packageName, packageVersion)
  396. contentURL := fmt.Sprintf("%s%s/package/%s/%s/%s.%s.nupkg", setting.AppURL, url[1:], packageName, packageVersion, packageName, packageVersion)
  397. t.Run("RegistrationIndex", func(t *testing.T) {
  398. defer tests.PrintCurrentTest(t)()
  399. req := NewRequest(t, "GET", fmt.Sprintf("%s/registration/%s/index.json", url, packageName))
  400. req = AddBasicAuthHeader(req, user.Name)
  401. resp := MakeRequest(t, req, http.StatusOK)
  402. var result nuget.RegistrationIndexResponse
  403. DecodeJSON(t, resp, &result)
  404. assert.Equal(t, indexURL, result.RegistrationIndexURL)
  405. assert.Equal(t, 1, result.Count)
  406. assert.Len(t, result.Pages, 1)
  407. assert.Equal(t, indexURL, result.Pages[0].RegistrationPageURL)
  408. assert.Equal(t, packageVersion, result.Pages[0].Lower)
  409. assert.Equal(t, packageVersion, result.Pages[0].Upper)
  410. assert.Equal(t, 1, result.Pages[0].Count)
  411. assert.Len(t, result.Pages[0].Items, 1)
  412. assert.Equal(t, packageName, result.Pages[0].Items[0].CatalogEntry.ID)
  413. assert.Equal(t, packageVersion, result.Pages[0].Items[0].CatalogEntry.Version)
  414. assert.Equal(t, packageAuthors, result.Pages[0].Items[0].CatalogEntry.Authors)
  415. assert.Equal(t, packageDescription, result.Pages[0].Items[0].CatalogEntry.Description)
  416. assert.Equal(t, leafURL, result.Pages[0].Items[0].CatalogEntry.CatalogLeafURL)
  417. assert.Equal(t, contentURL, result.Pages[0].Items[0].CatalogEntry.PackageContentURL)
  418. })
  419. t.Run("RegistrationLeaf", func(t *testing.T) {
  420. defer tests.PrintCurrentTest(t)()
  421. t.Run("v2", func(t *testing.T) {
  422. defer tests.PrintCurrentTest(t)()
  423. req := NewRequest(t, "GET", fmt.Sprintf("%s/Packages(Id='%s',Version='%s')", url, packageName, packageVersion))
  424. req = AddBasicAuthHeader(req, user.Name)
  425. resp := MakeRequest(t, req, http.StatusOK)
  426. var result FeedEntry
  427. decodeXML(t, resp, &result)
  428. assert.Equal(t, packageName, result.Properties.Title)
  429. assert.Equal(t, packageVersion, result.Properties.Version)
  430. assert.Equal(t, packageAuthors, result.Properties.Authors)
  431. assert.Equal(t, packageDescription, result.Properties.Description)
  432. assert.Equal(t, "Microsoft.CSharp:4.5.0:.NETStandard2.0", result.Properties.Dependencies)
  433. })
  434. t.Run("v3", func(t *testing.T) {
  435. defer tests.PrintCurrentTest(t)()
  436. req := NewRequest(t, "GET", fmt.Sprintf("%s/registration/%s/%s.json", url, packageName, packageVersion))
  437. req = AddBasicAuthHeader(req, user.Name)
  438. resp := MakeRequest(t, req, http.StatusOK)
  439. var result nuget.RegistrationLeafResponse
  440. DecodeJSON(t, resp, &result)
  441. assert.Equal(t, leafURL, result.RegistrationLeafURL)
  442. assert.Equal(t, contentURL, result.PackageContentURL)
  443. assert.Equal(t, indexURL, result.RegistrationIndexURL)
  444. })
  445. })
  446. })
  447. t.Run("PackageService", func(t *testing.T) {
  448. defer tests.PrintCurrentTest(t)()
  449. t.Run("v2", func(t *testing.T) {
  450. defer tests.PrintCurrentTest(t)()
  451. req := NewRequest(t, "GET", fmt.Sprintf("%s/FindPackagesById()?id='%s'", url, packageName))
  452. req = AddBasicAuthHeader(req, user.Name)
  453. resp := MakeRequest(t, req, http.StatusOK)
  454. var result FeedResponse
  455. decodeXML(t, resp, &result)
  456. assert.Len(t, result.Entries, 1)
  457. assert.Equal(t, packageVersion, result.Entries[0].Properties.Version)
  458. })
  459. t.Run("v3", func(t *testing.T) {
  460. defer tests.PrintCurrentTest(t)()
  461. req := NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/index.json", url, packageName))
  462. req = AddBasicAuthHeader(req, user.Name)
  463. resp := MakeRequest(t, req, http.StatusOK)
  464. var result nuget.PackageVersionsResponse
  465. DecodeJSON(t, resp, &result)
  466. assert.Len(t, result.Versions, 1)
  467. assert.Equal(t, packageVersion, result.Versions[0])
  468. })
  469. })
  470. t.Run("Delete", func(t *testing.T) {
  471. defer tests.PrintCurrentTest(t)()
  472. req := NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s", url, packageName, packageVersion))
  473. req = AddBasicAuthHeader(req, user.Name)
  474. MakeRequest(t, req, http.StatusNoContent)
  475. pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNuGet)
  476. assert.NoError(t, err)
  477. assert.Empty(t, pvs)
  478. })
  479. t.Run("DownloadNotExists", func(t *testing.T) {
  480. defer tests.PrintCurrentTest(t)()
  481. req := NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/%s/%s.%s.nupkg", url, packageName, packageVersion, packageName, packageVersion))
  482. req = AddBasicAuthHeader(req, user.Name)
  483. MakeRequest(t, req, http.StatusNotFound)
  484. req = NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/%s/%s.%s.snupkg", url, packageName, packageVersion, packageName, packageVersion))
  485. req = AddBasicAuthHeader(req, user.Name)
  486. MakeRequest(t, req, http.StatusNotFound)
  487. })
  488. t.Run("DeleteNotExists", func(t *testing.T) {
  489. defer tests.PrintCurrentTest(t)()
  490. req := NewRequest(t, "DELETE", fmt.Sprintf("%s/package/%s/%s", url, packageName, packageVersion))
  491. req = AddBasicAuthHeader(req, user.Name)
  492. MakeRequest(t, req, http.StatusNotFound)
  493. })
  494. }