harness-drone/handler/api/acl/repo_test.go
2019-02-19 15:56:41 -08:00

205 lines
5.7 KiB
Go

// Copyright 2019 Drone.IO Inc. All rights reserved.
// Use of this source code is governed by the Drone Non-Commercial License
// that can be found in the LICENSE file.
package acl
import (
"context"
"database/sql"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/drone/drone/handler/api/request"
"github.com/drone/drone/mock"
"github.com/drone/drone/core"
"github.com/go-chi/chi"
"github.com/golang/mock/gomock"
)
// this unit test ensures that the http request returns a
// 401 unauthorized if the session does not exist, and the
// repository is not found.
func TestInjectRepository_RepoNotFound_Guest(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
repos := mock.NewMockRepositoryStore(controller)
repos.EXPECT().FindName(gomock.Any(), "octocat", "hello-world").Return(nil, sql.ErrNoRows)
c := new(chi.Context)
c.URLParams.Add("owner", "octocat")
c.URLParams.Add("name", "hello-world")
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/", nil)
r = r.WithContext(
context.WithValue(r.Context(), chi.RouteCtxKey, c),
)
next := http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
t.Fail()
})
InjectRepository(nil, repos, nil)(next).ServeHTTP(w, r)
if got, want := w.Code, http.StatusUnauthorized; want != got {
t.Errorf("Want response code %d, got %d", want, got)
}
}
// this unit test ensures that the http request returns a
// 404 not found if the session does exist, but the
// repository is not found.
func TestInjectRepository_RepoNotFound_User(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
repos := mock.NewMockRepositoryStore(controller)
repos.EXPECT().FindName(gomock.Any(), "octocat", "hello-world").Return(nil, sql.ErrNoRows)
c := new(chi.Context)
c.URLParams.Add("owner", "octocat")
c.URLParams.Add("name", "hello-world")
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/", nil)
r = r.WithContext(
context.WithValue(
request.WithUser(r.Context(), &core.User{}),
chi.RouteCtxKey, c),
)
next := http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
t.Fail()
})
InjectRepository(nil, repos, nil)(next).ServeHTTP(w, r)
if got, want := w.Code, 404; want != got {
t.Errorf("Want response code %d, got %d", want, got)
}
}
// this unit test ensures that the middleware function
// invokes the next handler in the chain if the repository
// is found, but no user session exists.
func TestInjectRepository_RepoFound_Guest(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
repos := mock.NewMockRepositoryStore(controller)
repos.EXPECT().FindName(gomock.Any(), "octocat", "hello-world").Return(&core.Repository{}, nil)
c := new(chi.Context)
c.URLParams.Add("owner", "octocat")
c.URLParams.Add("name", "hello-world")
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/", nil)
r = r.WithContext(
context.WithValue(
r.Context(),
chi.RouteCtxKey, c),
)
invoked := false
next := http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
invoked = true
})
InjectRepository(nil, repos, nil)(next).ServeHTTP(w, r)
if !invoked {
t.Errorf("Expect middleware invoked")
}
}
// this unit test ensures that the middleware function
// invokes the next handler and stores the permissions
// in the context if found.
func TestInjectRepository_PermsFound(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
mockUser := &core.User{ID: 1}
mockRepo := &core.Repository{UID: "1"}
mockPerm := &core.Perm{Synced: time.Now().Unix()}
repos := mock.NewMockRepositoryStore(controller)
repos.EXPECT().FindName(gomock.Any(), "octocat", "hello-world").Return(mockRepo, nil)
perms := mock.NewMockPermStore(controller)
perms.EXPECT().Find(gomock.Any(), mockRepo.UID, mockUser.ID).Return(mockPerm, nil)
c := new(chi.Context)
c.URLParams.Add("owner", "octocat")
c.URLParams.Add("name", "hello-world")
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/", nil)
r = r.WithContext(
context.WithValue(
request.WithUser(r.Context(), mockUser),
chi.RouteCtxKey, c),
)
invoked := false
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
invoked = true
_, ok := request.PermFrom(r.Context())
if !ok {
t.Errorf("Expect perm from context")
}
})
InjectRepository(nil, repos, perms)(next).ServeHTTP(w, r)
if !invoked {
t.Errorf("Expect middleware invoked")
}
}
// this unit test ensures that the middleware function
// invokes the next handler even if the permissions are
// not found. It is the responsibility to downstream
// middleware and handlers to decide if the request
// should be rejected.
func TestInjectRepository_PermsNotFound(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
mockUser := &core.User{ID: 1}
mockRepo := &core.Repository{UID: "1"}
repos := mock.NewMockRepositoryStore(controller)
repos.EXPECT().FindName(gomock.Any(), "octocat", "hello-world").Return(mockRepo, nil)
perms := mock.NewMockPermStore(controller)
perms.EXPECT().Find(gomock.Any(), mockRepo.UID, mockUser.ID).Return(nil, sql.ErrNoRows)
c := new(chi.Context)
c.URLParams.Add("owner", "octocat")
c.URLParams.Add("name", "hello-world")
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/", nil)
r = r.WithContext(
context.WithValue(
request.WithUser(r.Context(), mockUser),
chi.RouteCtxKey, c),
)
invoked := false
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
invoked = true
_, ok := request.PermFrom(r.Context())
if ok {
t.Errorf("Expect nil perm from context")
}
})
InjectRepository(nil, repos, perms)(next).ServeHTTP(w, r)
if !invoked {
t.Errorf("Expect middleware invoked")
}
}