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
					
				| 
						 | 
				
			
			@ -207,20 +207,13 @@ type SearchResultVersion struct {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
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))
 | 
			
		||||
 | 
			
		||||
	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])
 | 
			
		||||
		}
 | 
			
		||||
	for _, group := range grouped {
 | 
			
		||||
		data = append(data, createSearchResult(l, group))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@ import (
 | 
			
		|||
	"encoding/xml"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/http/httptest"
 | 
			
		||||
	"testing"
 | 
			
		||||
| 
						 | 
				
			
			@ -83,14 +84,15 @@ func TestPackageNuGet(t *testing.T) {
 | 
			
		|||
	symbolFilename := "test.pdb"
 | 
			
		||||
	symbolID := "d910bb6948bd4c6cb40155bcf52c3c94"
 | 
			
		||||
 | 
			
		||||
	createPackage := func(id, version string) io.Reader {
 | 
			
		||||
		var buf bytes.Buffer
 | 
			
		||||
		archive := zip.NewWriter(&buf)
 | 
			
		||||
		w, _ := archive.Create("package.nuspec")
 | 
			
		||||
		w.Write([]byte(`<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
		<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
 | 
			
		||||
			<metadata>
 | 
			
		||||
		<id>` + packageName + `</id>
 | 
			
		||||
		<version>` + packageVersion + `</version>
 | 
			
		||||
				<id>` + id + `</id>
 | 
			
		||||
				<version>` + version + `</version>
 | 
			
		||||
				<authors>` + packageAuthors + `</authors>
 | 
			
		||||
				<description>` + packageDescription + `</description>
 | 
			
		||||
				<dependencies>
 | 
			
		||||
| 
						 | 
				
			
			@ -101,7 +103,10 @@ func TestPackageNuGet(t *testing.T) {
 | 
			
		|||
			</metadata>
 | 
			
		||||
		</package>`))
 | 
			
		||||
		archive.Close()
 | 
			
		||||
	content := buf.Bytes()
 | 
			
		||||
		return &buf
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	content, _ := ioutil.ReadAll(createPackage(packageName, packageVersion))
 | 
			
		||||
 | 
			
		||||
	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) {
 | 
			
		||||
			defer tests.PrintCurrentTest(t)()
 | 
			
		||||
 | 
			
		||||
			createPackage := func(id, packageType string) io.Reader {
 | 
			
		||||
			createSymbolPackage := func(id, packageType string) io.Reader {
 | 
			
		||||
				var buf bytes.Buffer
 | 
			
		||||
				archive := zip.NewWriter(&buf)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -268,15 +273,15 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
 | 
			
		|||
				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)
 | 
			
		||||
			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)
 | 
			
		||||
			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)
 | 
			
		||||
			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)
 | 
			
		||||
			MakeRequest(t, req, http.StatusConflict)
 | 
			
		||||
		})
 | 
			
		||||
| 
						 | 
				
			
			@ -437,6 +442,43 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
 | 
			
		|||
				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)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			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 New Issue