Enforce grouped NuGet search results (#21442)
Fixes #21434 Added tests to enforce this behaviour. Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
parent
cad9adeff4
commit
11d3677818
2 changed files with 72 additions and 37 deletions
|
@ -207,20 +207,13 @@ type SearchResultVersion struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSearchResultResponse(l *linkBuilder, totalHits int64, pds []*packages_model.PackageDescriptor) *SearchResultResponse {
|
func createSearchResultResponse(l *linkBuilder, totalHits int64, pds []*packages_model.PackageDescriptor) *SearchResultResponse {
|
||||||
|
grouped := make(map[string][]*packages_model.PackageDescriptor)
|
||||||
|
for _, pd := range pds {
|
||||||
|
grouped[pd.Package.Name] = append(grouped[pd.Package.Name], pd)
|
||||||
|
}
|
||||||
|
|
||||||
data := make([]*SearchResult, 0, len(pds))
|
data := make([]*SearchResult, 0, len(pds))
|
||||||
|
for _, group := range grouped {
|
||||||
if len(pds) > 0 {
|
|
||||||
groupID := pds[0].Package.Name
|
|
||||||
group := make([]*packages_model.PackageDescriptor, 0, 10)
|
|
||||||
|
|
||||||
for i := 0; i < len(pds); i++ {
|
|
||||||
if groupID != pds[i].Package.Name {
|
|
||||||
data = append(data, createSearchResult(l, group))
|
|
||||||
groupID = pds[i].Package.Name
|
|
||||||
group = group[:0]
|
|
||||||
}
|
|
||||||
group = append(group, pds[i])
|
|
||||||
}
|
|
||||||
data = append(data, createSearchResult(l, group))
|
data = append(data, createSearchResult(l, group))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -83,25 +84,29 @@ func TestPackageNuGet(t *testing.T) {
|
||||||
symbolFilename := "test.pdb"
|
symbolFilename := "test.pdb"
|
||||||
symbolID := "d910bb6948bd4c6cb40155bcf52c3c94"
|
symbolID := "d910bb6948bd4c6cb40155bcf52c3c94"
|
||||||
|
|
||||||
var buf bytes.Buffer
|
createPackage := func(id, version string) io.Reader {
|
||||||
archive := zip.NewWriter(&buf)
|
var buf bytes.Buffer
|
||||||
w, _ := archive.Create("package.nuspec")
|
archive := zip.NewWriter(&buf)
|
||||||
w.Write([]byte(`<?xml version="1.0" encoding="utf-8"?>
|
w, _ := archive.Create("package.nuspec")
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
w.Write([]byte(`<?xml version="1.0" encoding="utf-8"?>
|
||||||
<metadata>
|
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||||
<id>` + packageName + `</id>
|
<metadata>
|
||||||
<version>` + packageVersion + `</version>
|
<id>` + id + `</id>
|
||||||
<authors>` + packageAuthors + `</authors>
|
<version>` + version + `</version>
|
||||||
<description>` + packageDescription + `</description>
|
<authors>` + packageAuthors + `</authors>
|
||||||
<dependencies>
|
<description>` + packageDescription + `</description>
|
||||||
<group targetFramework=".NETStandard2.0">
|
<dependencies>
|
||||||
<dependency id="Microsoft.CSharp" version="4.5.0" />
|
<group targetFramework=".NETStandard2.0">
|
||||||
</group>
|
<dependency id="Microsoft.CSharp" version="4.5.0" />
|
||||||
</dependencies>
|
</group>
|
||||||
</metadata>
|
</dependencies>
|
||||||
</package>`))
|
</metadata>
|
||||||
archive.Close()
|
</package>`))
|
||||||
content := buf.Bytes()
|
archive.Close()
|
||||||
|
return &buf
|
||||||
|
}
|
||||||
|
|
||||||
|
content, _ := ioutil.ReadAll(createPackage(packageName, packageVersion))
|
||||||
|
|
||||||
url := fmt.Sprintf("/api/packages/%s/nuget", user.Name)
|
url := fmt.Sprintf("/api/packages/%s/nuget", user.Name)
|
||||||
|
|
||||||
|
@ -242,7 +247,7 @@ func TestPackageNuGet(t *testing.T) {
|
||||||
t.Run("SymbolPackage", func(t *testing.T) {
|
t.Run("SymbolPackage", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
createPackage := func(id, packageType string) io.Reader {
|
createSymbolPackage := func(id, packageType string) io.Reader {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
archive := zip.NewWriter(&buf)
|
archive := zip.NewWriter(&buf)
|
||||||
|
|
||||||
|
@ -268,15 +273,15 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
|
||||||
return &buf
|
return &buf
|
||||||
}
|
}
|
||||||
|
|
||||||
req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createPackage("unknown-package", "SymbolsPackage"))
|
req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage("unknown-package", "SymbolsPackage"))
|
||||||
req = AddBasicAuthHeader(req, user.Name)
|
req = AddBasicAuthHeader(req, user.Name)
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
MakeRequest(t, req, http.StatusNotFound)
|
||||||
|
|
||||||
req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createPackage(packageName, "DummyPackage"))
|
req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "DummyPackage"))
|
||||||
req = AddBasicAuthHeader(req, user.Name)
|
req = AddBasicAuthHeader(req, user.Name)
|
||||||
MakeRequest(t, req, http.StatusBadRequest)
|
MakeRequest(t, req, http.StatusBadRequest)
|
||||||
|
|
||||||
req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createPackage(packageName, "SymbolsPackage"))
|
req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "SymbolsPackage"))
|
||||||
req = AddBasicAuthHeader(req, user.Name)
|
req = AddBasicAuthHeader(req, user.Name)
|
||||||
MakeRequest(t, req, http.StatusCreated)
|
MakeRequest(t, req, http.StatusCreated)
|
||||||
|
|
||||||
|
@ -320,7 +325,7 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createPackage(packageName, "SymbolsPackage"))
|
req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "SymbolsPackage"))
|
||||||
req = AddBasicAuthHeader(req, user.Name)
|
req = AddBasicAuthHeader(req, user.Name)
|
||||||
MakeRequest(t, req, http.StatusConflict)
|
MakeRequest(t, req, http.StatusConflict)
|
||||||
})
|
})
|
||||||
|
@ -437,6 +442,43 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
|
||||||
assert.Equal(t, c.ExpectedTotal, result.TotalHits, "case %d: unexpected total hits", i)
|
assert.Equal(t, c.ExpectedTotal, result.TotalHits, "case %d: unexpected total hits", i)
|
||||||
assert.Len(t, result.Data, c.ExpectedResults, "case %d: unexpected result count", i)
|
assert.Len(t, result.Data, c.ExpectedResults, "case %d: unexpected result count", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.Run("EnforceGrouped", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
req := NewRequestWithBody(t, "PUT", url, createPackage(packageName+".dummy", "1.0.0"))
|
||||||
|
req = AddBasicAuthHeader(req, user.Name)
|
||||||
|
MakeRequest(t, req, http.StatusCreated)
|
||||||
|
|
||||||
|
req = NewRequestWithBody(t, "PUT", url, createPackage(packageName, "1.0.99"))
|
||||||
|
req = AddBasicAuthHeader(req, user.Name)
|
||||||
|
MakeRequest(t, req, http.StatusCreated)
|
||||||
|
|
||||||
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/query?q=%s", url, packageName))
|
||||||
|
req = AddBasicAuthHeader(req, user.Name)
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
var result nuget.SearchResultResponse
|
||||||
|
DecodeJSON(t, resp, &result)
|
||||||
|
|
||||||
|
assert.EqualValues(t, 3, result.TotalHits)
|
||||||
|
assert.Len(t, result.Data, 2)
|
||||||
|
for _, sr := range result.Data {
|
||||||
|
if sr.ID == packageName {
|
||||||
|
assert.Len(t, sr.Versions, 2)
|
||||||
|
} else {
|
||||||
|
assert.Len(t, sr.Versions, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s", url, packageName+".dummy", "1.0.0"))
|
||||||
|
req = AddBasicAuthHeader(req, user.Name)
|
||||||
|
MakeRequest(t, req, http.StatusNoContent)
|
||||||
|
|
||||||
|
req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s", url, packageName, "1.0.99"))
|
||||||
|
req = AddBasicAuthHeader(req, user.Name)
|
||||||
|
MakeRequest(t, req, http.StatusNoContent)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue