Merge pull request #3950 from ywk253100/180105_ut

Add unit test for adding description of repository
This commit is contained in:
Daniel Jiang 2018-01-08 14:32:10 +08:00 committed by GitHub
commit 093e2bead2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 204 additions and 25 deletions

View File

@ -16,6 +16,7 @@ package api
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"os" "os"
@ -28,11 +29,18 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/vmware/harbor/src/common/dao" "github.com/vmware/harbor/src/common/dao"
common_http "github.com/vmware/harbor/src/common/http"
"github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/models"
) )
var ( var (
nonSysAdminID int64 nonSysAdminID, projAdminID, projDeveloperID, projGuestID int
// The following users/credentials are registered and assigned roles at the beginning of
// running testing and cleaned up at the end.
// Do not try to change the system and project roles that the users have during
// the testing. Creating a new one in your own case if needed.
// The project roles that the users have are for project library.
sysAdmin = &usrInfo{ sysAdmin = &usrInfo{
Name: "admin", Name: "admin",
Passwd: "Harbor12345", Passwd: "Harbor12345",
@ -41,6 +49,18 @@ var (
Name: "non_admin", Name: "non_admin",
Passwd: "Harbor12345", Passwd: "Harbor12345",
} }
projAdmin = &usrInfo{
Name: "proj_admin",
Passwd: "Harbor12345",
}
projDeveloper = &usrInfo{
Name: "proj_developer",
Passwd: "Harbor12345",
}
projGuest = &usrInfo{
Name: "proj_guest",
Passwd: "Harbor12345",
}
) )
type testingRequest struct { type testingRequest struct {
@ -113,22 +133,25 @@ func handle(r *testingRequest) (*httptest.ResponseRecorder, error) {
return resp, nil return resp, nil
} }
func handleAndParse(r *testingRequest, v interface{}) (*httptest.ResponseRecorder, error) { func handleAndParse(r *testingRequest, v interface{}) error {
req, err := newRequest(r) resp, err := handle(r)
if err != nil { if err != nil {
return nil, err return err
} }
resp := httptest.NewRecorder() data, err := ioutil.ReadAll(resp.Body)
beego.BeeApp.Handlers.ServeHTTP(resp, req) if err != nil {
return err
}
if resp.Code >= 200 && resp.Code <= 299 { if resp.Code >= 200 && resp.Code <= 299 {
if err := json.NewDecoder(resp.Body).Decode(v); err != nil { return json.Unmarshal(data, v)
return nil, err
}
} }
return resp, nil return &common_http.Error{
Code: resp.Code,
Message: string(data),
}
} }
func runCodeCheckingCases(t *testing.T, cases ...*codeCheckingCase) { func runCodeCheckingCases(t *testing.T, cases ...*codeCheckingCase) {
@ -179,17 +202,73 @@ func TestMain(m *testing.M) {
} }
func prepare() error { func prepare() error {
// register nonSysAdmin
id, err := dao.Register(models.User{ id, err := dao.Register(models.User{
Username: nonSysAdmin.Name, Username: nonSysAdmin.Name,
Password: nonSysAdmin.Passwd, Password: nonSysAdmin.Passwd,
Email: nonSysAdmin.Name + "@test.com",
}) })
if err != nil { if err != nil {
return err return err
} }
nonSysAdminID = id nonSysAdminID = int(id)
return nil
// register projAdmin and assign project admin role
id, err = dao.Register(models.User{
Username: projAdmin.Name,
Password: projAdmin.Passwd,
Email: projAdmin.Name + "@test.com",
})
if err != nil {
return err
}
projAdminID = int(id)
if err = dao.AddProjectMember(1, projAdminID, models.PROJECTADMIN); err != nil {
return err
} }
func clean() error { // register projDeveloper and assign project developer role
return dao.DeleteUser(int(nonSysAdminID)) id, err = dao.Register(models.User{
Username: projDeveloper.Name,
Password: projDeveloper.Passwd,
Email: projDeveloper.Name + "@test.com",
})
if err != nil {
return err
}
projDeveloperID = int(id)
if err = dao.AddProjectMember(1, projDeveloperID, models.DEVELOPER); err != nil {
return err
}
// register projGuest and assign project guest role
id, err = dao.Register(models.User{
Username: projGuest.Name,
Password: projGuest.Passwd,
Email: projGuest.Name + "@test.com",
})
if err != nil {
return err
}
projGuestID = int(id)
return dao.AddProjectMember(1, projGuestID, models.GUEST)
}
func clean() {
ids := []int{projAdminID, projDeveloperID, projGuestID}
for _, id := range ids {
if err := dao.DeleteProjectMember(1, id); err != nil {
fmt.Printf("failed to clean up member %d from project library: %v", id, err)
}
}
ids = append(ids, nonSysAdminID)
for _, id := range ids {
if err := dao.DeleteUser(id); err != nil {
fmt.Printf("failed to clean up user %d: %v \n", id, err)
}
}
} }

View File

@ -110,6 +110,7 @@ func init() {
beego.Router("/api/statistics", &StatisticAPI{}) beego.Router("/api/statistics", &StatisticAPI{})
beego.Router("/api/users/?:id", &UserAPI{}) beego.Router("/api/users/?:id", &UserAPI{})
beego.Router("/api/logs", &LogAPI{}) beego.Router("/api/logs", &LogAPI{})
beego.Router("/api/repositories/*", &RepositoryAPI{}, "put:Put")
beego.Router("/api/repositories/*/tags/:tag", &RepositoryAPI{}, "delete:Delete;get:GetTag") beego.Router("/api/repositories/*/tags/:tag", &RepositoryAPI{}, "delete:Delete;get:GetTag")
beego.Router("/api/repositories/*/tags", &RepositoryAPI{}, "get:GetTags") beego.Router("/api/repositories/*/tags", &RepositoryAPI{}, "get:GetTags")
beego.Router("/api/repositories/*/tags/:tag/manifest", &RepositoryAPI{}, "get:GetManifests") beego.Router("/api/repositories/*/tags/:tag/manifest", &RepositoryAPI{}, "get:GetManifests")

View File

@ -291,14 +291,13 @@ func TestRepPolicyAPIGet(t *testing.T) {
// 200 // 200
policy := &api_models.ReplicationPolicy{} policy := &api_models.ReplicationPolicy{}
resp, err := handleAndParse( err := handleAndParse(
&testingRequest{ &testingRequest{
method: http.MethodGet, method: http.MethodGet,
url: fmt.Sprintf("%s/%d", repPolicyAPIBasePath, policyID), url: fmt.Sprintf("%s/%d", repPolicyAPIBasePath, policyID),
credential: sysAdmin, credential: sysAdmin,
}, policy) }, policy)
require.Nil(t, err) require.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.Code)
assert.Equal(t, policyID, policy.ID) assert.Equal(t, policyID, policy.ID)
assert.Equal(t, policyName, policy.Name) assert.Equal(t, policyName, policy.Name)
} }
@ -354,7 +353,7 @@ func TestRepPolicyAPIList(t *testing.T) {
// 200 system admin // 200 system admin
policies := []*api_models.ReplicationPolicy{} policies := []*api_models.ReplicationPolicy{}
resp, err := handleAndParse( err = handleAndParse(
&testingRequest{ &testingRequest{
method: http.MethodGet, method: http.MethodGet,
url: repPolicyAPIBasePath, url: repPolicyAPIBasePath,
@ -368,14 +367,13 @@ func TestRepPolicyAPIList(t *testing.T) {
credential: sysAdmin, credential: sysAdmin,
}, &policies) }, &policies)
require.Nil(t, err) require.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.Code)
require.Equal(t, 1, len(policies)) require.Equal(t, 1, len(policies))
assert.Equal(t, policyID, policies[0].ID) assert.Equal(t, policyID, policies[0].ID)
assert.Equal(t, policyName, policies[0].Name) assert.Equal(t, policyName, policies[0].Name)
// 200 project admin // 200 project admin
policies = []*api_models.ReplicationPolicy{} policies = []*api_models.ReplicationPolicy{}
resp, err = handleAndParse( err = handleAndParse(
&testingRequest{ &testingRequest{
method: http.MethodGet, method: http.MethodGet,
url: repPolicyAPIBasePath, url: repPolicyAPIBasePath,
@ -392,14 +390,13 @@ func TestRepPolicyAPIList(t *testing.T) {
}, },
}, &policies) }, &policies)
require.Nil(t, err) require.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.Code)
require.Equal(t, 1, len(policies)) require.Equal(t, 1, len(policies))
assert.Equal(t, policyID, policies[0].ID) assert.Equal(t, policyID, policies[0].ID)
assert.Equal(t, policyName, policies[0].Name) assert.Equal(t, policyName, policies[0].Name)
// 200 project developer // 200 project developer
policies = []*api_models.ReplicationPolicy{} policies = []*api_models.ReplicationPolicy{}
resp, err = handleAndParse( err = handleAndParse(
&testingRequest{ &testingRequest{
method: http.MethodGet, method: http.MethodGet,
url: repPolicyAPIBasePath, url: repPolicyAPIBasePath,
@ -416,12 +413,11 @@ func TestRepPolicyAPIList(t *testing.T) {
}, },
}, &policies) }, &policies)
require.Nil(t, err) require.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.Code)
require.Equal(t, 0, len(policies)) require.Equal(t, 0, len(policies))
// 200 // 200
policies = []*api_models.ReplicationPolicy{} policies = []*api_models.ReplicationPolicy{}
resp, err = handleAndParse( err = handleAndParse(
&testingRequest{ &testingRequest{
method: http.MethodGet, method: http.MethodGet,
url: repPolicyAPIBasePath, url: repPolicyAPIBasePath,
@ -435,7 +431,6 @@ func TestRepPolicyAPIList(t *testing.T) {
credential: sysAdmin, credential: sysAdmin,
}, &policies) }, &policies)
require.Nil(t, err) require.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.Code)
require.Equal(t, 0, len(policies)) require.Equal(t, 0, len(policies))
} }

View File

@ -19,6 +19,7 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func TestGetRepos(t *testing.T) { func TestGetRepos(t *testing.T) {
@ -223,3 +224,106 @@ func TestPopulateAuthor(t *testing.T) {
populateAuthor(detail) populateAuthor(detail)
assert.Equal(t, maintainer, detail.Author) assert.Equal(t, maintainer, detail.Author)
} }
func TestPutOfRepository(t *testing.T) {
base := "/api/repositories/"
desc := struct {
Description string `json:"description"`
}{
Description: "description_for_test",
}
cases := []*codeCheckingCase{
// 404
&codeCheckingCase{
request: &testingRequest{
method: http.MethodPut,
url: base + "non_exist_repository",
bodyJSON: desc,
},
code: http.StatusNotFound,
},
// 401
&codeCheckingCase{
request: &testingRequest{
method: http.MethodPut,
url: base + "library/hello-world",
bodyJSON: desc,
},
code: http.StatusUnauthorized,
},
// 403 non-member
&codeCheckingCase{
request: &testingRequest{
method: http.MethodPut,
url: base + "library/hello-world",
bodyJSON: desc,
credential: nonSysAdmin,
},
code: http.StatusForbidden,
},
// 403 project guest
&codeCheckingCase{
request: &testingRequest{
method: http.MethodPut,
url: base + "library/hello-world",
bodyJSON: desc,
credential: projGuest,
},
code: http.StatusForbidden,
},
// 200 project developer
&codeCheckingCase{
request: &testingRequest{
method: http.MethodPut,
url: base + "library/hello-world",
bodyJSON: desc,
credential: projDeveloper,
},
code: http.StatusOK,
},
// 200 project admin
&codeCheckingCase{
request: &testingRequest{
method: http.MethodPut,
url: base + "library/hello-world",
bodyJSON: desc,
credential: projAdmin,
},
code: http.StatusOK,
},
// 200 system admin
&codeCheckingCase{
request: &testingRequest{
method: http.MethodPut,
url: base + "library/hello-world",
bodyJSON: desc,
credential: sysAdmin,
},
code: http.StatusOK,
},
}
runCodeCheckingCases(t, cases...)
// verify that the description is changed
repositories := []*repoResp{}
err := handleAndParse(&testingRequest{
method: http.MethodGet,
url: base,
queryStruct: struct {
ProjectID int64 `url:"project_id"`
}{
ProjectID: 1,
},
}, &repositories)
require.Nil(t, err)
var repository *repoResp
for _, repo := range repositories {
if repo.Name == "library/hello-world" {
repository = repo
break
}
}
require.NotNil(t, repository)
assert.Equal(t, desc.Description, repository.Description)
}