refactor getting top repo API to return detail info

This commit is contained in:
Wenkai Yin 2017-03-10 14:35:17 +08:00
parent 39f786dbbc
commit fea1ae4e26
5 changed files with 99 additions and 83 deletions

View File

@ -103,10 +103,12 @@ func GetRepositoryByProjectName(name string) ([]*models.RepoRecord, error) {
}
//GetTopRepos returns the most popular repositories
func GetTopRepos(userID int, count int) ([]models.TopRepo, error) {
topRepos := []models.TopRepo{}
sql := `select r.name, r.pull_count from repository r
func GetTopRepos(userID int, count int) ([]*models.RepoRecord, error) {
sql :=
`select r.repository_id, r.name, r.owner_id,
r.project_id, r.description, r.pull_count,
r.star_count, r.creation_time, r.update_time
from repository r
inner join project p on r.project_id = p.project_id
where (
p.deleted = 0 and (
@ -122,18 +124,8 @@ func GetTopRepos(userID int, count int) ([]models.TopRepo, error) {
order by r.pull_count desc, r.name limit ?`
repositories := []*models.RepoRecord{}
_, err := GetOrmer().Raw(sql, userID, NonExistUserID, userID, userID, count).QueryRows(&repositories)
if err != nil {
return topRepos, err
}
for _, repository := range repositories {
topRepos = append(topRepos, models.TopRepo{
RepoName: repository.Name,
AccessCount: repository.PullCount,
})
}
return topRepos, nil
return repositories, err
}
// GetTotalOfRepositories ...

View File

@ -269,75 +269,28 @@ func TestGetTopRepos(t *testing.T) {
err = DeleteProject(deletedPublicProject.ProjectID)
require.NoError(err)
var topRepos []models.TopRepo
var topRepos []*models.RepoRecord
// anonymous should retrieve public non-deleted repositories
topRepos, err = GetTopRepos(NonExistUserID, 100)
require.NoError(err)
require.Len(topRepos, 1)
require.Equal(topRepos, []models.TopRepo{
models.TopRepo{
RepoName: repository.Name,
AccessCount: repository.PullCount,
},
})
require.Equal(topRepos[0].Name, repository.Name)
// admin should retrieve all repositories
topRepos, err = GetTopRepos(admin.UserID, 100)
require.NoError(err)
require.Len(topRepos, 4)
require.Equal(topRepos, []models.TopRepo{
models.TopRepo{
RepoName: repository3.Name,
AccessCount: repository3.PullCount,
},
models.TopRepo{
RepoName: repository2.Name,
AccessCount: repository2.PullCount,
},
models.TopRepo{
RepoName: repository1.Name,
AccessCount: repository1.PullCount,
},
models.TopRepo{
RepoName: repository.Name,
AccessCount: repository.PullCount,
},
})
// user should retrieve visible repositories
topRepos, err = GetTopRepos(user.UserID, 100)
require.NoError(err)
require.Len(topRepos, 2)
require.Equal(topRepos, []models.TopRepo{
models.TopRepo{
RepoName: repository3.Name,
AccessCount: repository3.PullCount,
},
models.TopRepo{
RepoName: repository.Name,
AccessCount: repository.PullCount,
},
})
// limit by count
topRepos, err = GetTopRepos(admin.UserID, 3)
require.NoError(err)
require.Len(topRepos, 3)
require.Equal(topRepos, []models.TopRepo{
models.TopRepo{
RepoName: repository3.Name,
AccessCount: repository3.PullCount,
},
models.TopRepo{
RepoName: repository2.Name,
AccessCount: repository2.PullCount,
},
models.TopRepo{
RepoName: repository1.Name,
AccessCount: repository1.PullCount,
},
})
}
func TestGetTotalOfRepositoriesByProject(t *testing.T) {

View File

@ -558,7 +558,8 @@ func (a testapi) GetReposManifests(authInfo usrInfo, repoName string, tag string
}
//Get public repositories which are accessed most
func (a testapi) GetReposTop(authInfo usrInfo, count string) (int, error) {
func (a testapi) GetReposTop(authInfo usrInfo, count,
detail string) (int, interface{}, error) {
_sling := sling.New().Get(a.basePath)
path := "/api/repositories/top"
@ -566,12 +567,36 @@ func (a testapi) GetReposTop(authInfo usrInfo, count string) (int, error) {
_sling = _sling.Path(path)
type QueryParams struct {
Count string `url:"count"`
Count string `url:"count"`
Detail string `url:"detail"`
}
_sling = _sling.QueryStruct(&QueryParams{Count: count})
httpStatusCode, _, err := request(_sling, jsonAcceptHeader, authInfo)
return httpStatusCode, err
_sling = _sling.QueryStruct(&QueryParams{
Count: count,
Detail: detail,
})
code, body, err := request(_sling, jsonAcceptHeader, authInfo)
if err != nil {
return 0, nil, err
}
if code != http.StatusOK {
return code, body, err
}
if detail == "true" || detail == "1" {
result := []*repoResp{}
if err = json.Unmarshal(body, &result); err != nil {
return 0, nil, err
}
return http.StatusOK, result, nil
}
result := []*models.TopRepo{}
if err = json.Unmarshal(body, &result); err != nil {
return 0, nil, err
}
return http.StatusOK, result, nil
}
//-------------------------Targets Test---------------------------------------//

View File

@ -139,6 +139,10 @@ func getRepositories(projectID int64, keyword string,
return result, nil
}
return populateTagsCount(repositories)
}
func populateTagsCount(repositories []*models.RepoRecord) ([]*repoResp, error) {
result := []*repoResp{}
for _, repository := range repositories {
repo := &repoResp{
@ -160,7 +164,6 @@ func getRepositories(projectID int64, keyword string,
repo.TagsCount = int64(len(tags))
result = append(result, repo)
}
return result, nil
}
@ -531,7 +534,30 @@ func (ra *RepositoryAPI) GetTopRepos() {
log.Errorf("failed to get top repos: %v", err)
ra.CustomAbort(http.StatusInternalServerError, "internal server error")
}
ra.Data["json"] = repos
detail := ra.GetString("detail") == "1" || ra.GetString("detail") == "true"
if !detail {
result := []*models.TopRepo{}
for _, repo := range repos {
result = append(result, &models.TopRepo{
RepoName: repo.Name,
AccessCount: repo.PullCount,
})
}
ra.Data["json"] = result
ra.ServeJSON()
return
}
result, err := populateTagsCount(repos)
if err != nil {
log.Errorf("failed to popultate tags count to repositories: %v", err)
ra.CustomAbort(http.StatusInternalServerError, "internal server error")
}
ra.Data["json"] = result
ra.ServeJSON()
}

View File

@ -5,6 +5,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/vmware/harbor/src/common/models"
)
func TestGetRepos(t *testing.T) {
@ -193,9 +194,6 @@ func TestGetReposManifests(t *testing.T) {
}
func TestGetReposTop(t *testing.T) {
var httpStatusCode int
var err error
var count string
assert := assert.New(t)
apiTest := newHarborAPI()
@ -203,24 +201,46 @@ func TestGetReposTop(t *testing.T) {
fmt.Println("Testing ReposTop Get API")
//-------------------case 1 : response code = 200------------------------//
fmt.Println("case 1 : response code = 200")
count = "1"
httpStatusCode, err = apiTest.GetReposTop(*admin, count)
count := "1"
detail := "false"
code, repos, err := apiTest.GetReposTop(*admin, count, detail)
if err != nil {
t.Error("Error whihle get reposTop to show the most popular public repositories ", err.Error())
t.Log(err)
t.Errorf("failed to get the most popular repositories: %v", err)
} else {
assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200")
assert.Equal(int(200), code, "response code should be 200")
if r, ok := repos.([]*models.TopRepo); ok {
assert.Equal(int(1), len(r), "the length should be 1")
assert.Equal(r[0].RepoName, "library/docker", "the name of repository should be library/docker")
} else {
t.Error("the repositories should in simple style as the detail is false")
}
}
//-------------------case 2 : response code = 400------------------------//
fmt.Println("case 2 : response code = 400,invalid count")
count = "cc"
httpStatusCode, err = apiTest.GetReposTop(*admin, count)
code, _, err = apiTest.GetReposTop(*admin, count, detail)
if err != nil {
t.Error("Error whihle get reposTop to show the most popular public repositories ", err.Error())
t.Log(err)
t.Errorf("failed to get the most popular repositories: %v", err)
} else {
assert.Equal(int(400), httpStatusCode, "httpStatusCode should be 400")
assert.Equal(int(400), code, "response code should be 400")
}
//-------------------case 3 : response code = 200------------------------//
fmt.Println("case 3 : response code = 200")
count = "1"
detail = "true"
code, repos, err = apiTest.GetReposTop(*admin, count, detail)
if err != nil {
t.Errorf("failed to get the most popular repositories: %v", err)
} else {
assert.Equal(int(200), code, "response code should be 200")
if r, ok := repos.([]*repoResp); ok {
assert.Equal(int(1), len(r), "the length should be 1")
assert.Equal(r[0].Name, "library/docker", "the name of repository should be library/docker")
} else {
t.Error("the repositories should in detail style as the detail is true")
}
}
fmt.Printf("\n")