mirror of
https://github.com/dstotijn/hetty.git
synced 2025-07-01 18:47:29 -04:00
Add initial tests for reqlog
package
This commit is contained in:
@ -20,7 +20,7 @@ import (
|
|||||||
|
|
||||||
type Resolver struct {
|
type Resolver struct {
|
||||||
RequestLogService *reqlog.Service
|
RequestLogService *reqlog.Service
|
||||||
ProjectService *proj.Service
|
ProjectService proj.Service
|
||||||
ScopeService *scope.Scope
|
ScopeService *scope.Scope
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,17 @@ type (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Service is used for managing projects.
|
// Service is used for managing projects.
|
||||||
type Service struct {
|
type Service interface {
|
||||||
|
Open(ctx context.Context, name string) (Project, error)
|
||||||
|
Close() error
|
||||||
|
Delete(name string) error
|
||||||
|
ActiveProject() (Project, error)
|
||||||
|
Projects() ([]Project, error)
|
||||||
|
OnProjectOpen(fn OnProjectOpenFn)
|
||||||
|
OnProjectClose(fn OnProjectCloseFn)
|
||||||
|
}
|
||||||
|
|
||||||
|
type service struct {
|
||||||
repo Repository
|
repo Repository
|
||||||
activeProject string
|
activeProject string
|
||||||
onProjectOpenFns []OnProjectOpenFn
|
onProjectOpenFns []OnProjectOpenFn
|
||||||
@ -37,14 +47,14 @@ var (
|
|||||||
var nameRegexp = regexp.MustCompile(`^[\w\d\s]+$`)
|
var nameRegexp = regexp.MustCompile(`^[\w\d\s]+$`)
|
||||||
|
|
||||||
// NewService returns a new Service.
|
// NewService returns a new Service.
|
||||||
func NewService(repo Repository) (*Service, error) {
|
func NewService(repo Repository) (Service, error) {
|
||||||
return &Service{
|
return &service{
|
||||||
repo: repo,
|
repo: repo,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the currently open project database (if there is one).
|
// Close closes the currently open project database (if there is one).
|
||||||
func (svc *Service) Close() error {
|
func (svc *service) Close() error {
|
||||||
svc.mu.Lock()
|
svc.mu.Lock()
|
||||||
defer svc.mu.Unlock()
|
defer svc.mu.Unlock()
|
||||||
|
|
||||||
@ -62,7 +72,7 @@ func (svc *Service) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete removes a project database file from disk (if there is one).
|
// Delete removes a project database file from disk (if there is one).
|
||||||
func (svc *Service) Delete(name string) error {
|
func (svc *service) Delete(name string) error {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return errors.New("proj: name cannot be empty")
|
return errors.New("proj: name cannot be empty")
|
||||||
}
|
}
|
||||||
@ -80,7 +90,7 @@ func (svc *Service) Delete(name string) error {
|
|||||||
|
|
||||||
// Open opens a database identified with `name`. If a database with this
|
// Open opens a database identified with `name`. If a database with this
|
||||||
// identifier doesn't exist yet, it will be automatically created.
|
// identifier doesn't exist yet, it will be automatically created.
|
||||||
func (svc *Service) Open(ctx context.Context, name string) (Project, error) {
|
func (svc *service) Open(ctx context.Context, name string) (Project, error) {
|
||||||
if !nameRegexp.MatchString(name) {
|
if !nameRegexp.MatchString(name) {
|
||||||
return Project{}, ErrInvalidName
|
return Project{}, ErrInvalidName
|
||||||
}
|
}
|
||||||
@ -105,7 +115,7 @@ func (svc *Service) Open(ctx context.Context, name string) (Project, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) ActiveProject() (Project, error) {
|
func (svc *service) ActiveProject() (Project, error) {
|
||||||
activeProject := svc.activeProject
|
activeProject := svc.activeProject
|
||||||
if activeProject == "" {
|
if activeProject == "" {
|
||||||
return Project{}, ErrNoProject
|
return Project{}, ErrNoProject
|
||||||
@ -116,7 +126,7 @@ func (svc *Service) ActiveProject() (Project, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) Projects() ([]Project, error) {
|
func (svc *service) Projects() ([]Project, error) {
|
||||||
projects, err := svc.repo.Projects()
|
projects, err := svc.repo.Projects()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("proj: could not get projects: %w", err)
|
return nil, fmt.Errorf("proj: could not get projects: %w", err)
|
||||||
@ -125,21 +135,21 @@ func (svc *Service) Projects() ([]Project, error) {
|
|||||||
return projects, nil
|
return projects, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) OnProjectOpen(fn OnProjectOpenFn) {
|
func (svc *service) OnProjectOpen(fn OnProjectOpenFn) {
|
||||||
svc.mu.Lock()
|
svc.mu.Lock()
|
||||||
defer svc.mu.Unlock()
|
defer svc.mu.Unlock()
|
||||||
|
|
||||||
svc.onProjectOpenFns = append(svc.onProjectOpenFns, fn)
|
svc.onProjectOpenFns = append(svc.onProjectOpenFns, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) OnProjectClose(fn OnProjectCloseFn) {
|
func (svc *service) OnProjectClose(fn OnProjectCloseFn) {
|
||||||
svc.mu.Lock()
|
svc.mu.Lock()
|
||||||
defer svc.mu.Unlock()
|
defer svc.mu.Unlock()
|
||||||
|
|
||||||
svc.onProjectCloseFns = append(svc.onProjectCloseFns, fn)
|
svc.onProjectCloseFns = append(svc.onProjectCloseFns, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) emitProjectOpened() {
|
func (svc *service) emitProjectOpened() {
|
||||||
for _, fn := range svc.onProjectOpenFns {
|
for _, fn := range svc.onProjectOpenFns {
|
||||||
if err := fn(svc.activeProject); err != nil {
|
if err := fn(svc.activeProject); err != nil {
|
||||||
log.Printf("[ERROR] Could not execute onProjectOpen function: %v", err)
|
log.Printf("[ERROR] Could not execute onProjectOpen function: %v", err)
|
||||||
@ -147,7 +157,7 @@ func (svc *Service) emitProjectOpened() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) emitProjectClosed(name string) {
|
func (svc *service) emitProjectClosed(name string) {
|
||||||
for _, fn := range svc.onProjectCloseFns {
|
for _, fn := range svc.onProjectCloseFns {
|
||||||
if err := fn(name); err != nil {
|
if err := fn(name); err != nil {
|
||||||
log.Printf("[ERROR] Could not execute onProjectClose function: %v", err)
|
log.Printf("[ERROR] Could not execute onProjectClose function: %v", err)
|
||||||
|
318
pkg/reqlog/proj_mock_test.go
Normal file
318
pkg/reqlog/proj_mock_test.go
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
// Code generated by moq; DO NOT EDIT.
|
||||||
|
// github.com/matryer/moq
|
||||||
|
|
||||||
|
package reqlog_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/dstotijn/hetty/pkg/proj"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ensure, that ProjServiceMock does implement proj.Service.
|
||||||
|
// If this is not the case, regenerate this file with moq.
|
||||||
|
var _ proj.Service = &ProjServiceMock{}
|
||||||
|
|
||||||
|
// ProjServiceMock is a mock implementation of proj.Service.
|
||||||
|
//
|
||||||
|
// func TestSomethingThatUsesService(t *testing.T) {
|
||||||
|
//
|
||||||
|
// // make and configure a mocked proj.Service
|
||||||
|
// mockedService := &ProjServiceMock{
|
||||||
|
// ActiveProjectFunc: func() (proj.Project, error) {
|
||||||
|
// panic("mock out the ActiveProject method")
|
||||||
|
// },
|
||||||
|
// CloseFunc: func() error {
|
||||||
|
// panic("mock out the Close method")
|
||||||
|
// },
|
||||||
|
// DeleteFunc: func(name string) error {
|
||||||
|
// panic("mock out the Delete method")
|
||||||
|
// },
|
||||||
|
// OnProjectCloseFunc: func(fn proj.OnProjectCloseFn) {
|
||||||
|
// panic("mock out the OnProjectClose method")
|
||||||
|
// },
|
||||||
|
// OnProjectOpenFunc: func(fn proj.OnProjectOpenFn) {
|
||||||
|
// panic("mock out the OnProjectOpen method")
|
||||||
|
// },
|
||||||
|
// OpenFunc: func(ctx context.Context, name string) (proj.Project, error) {
|
||||||
|
// panic("mock out the Open method")
|
||||||
|
// },
|
||||||
|
// ProjectsFunc: func() ([]proj.Project, error) {
|
||||||
|
// panic("mock out the Projects method")
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // use mockedService in code that requires proj.Service
|
||||||
|
// // and then make assertions.
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
type ProjServiceMock struct {
|
||||||
|
// ActiveProjectFunc mocks the ActiveProject method.
|
||||||
|
ActiveProjectFunc func() (proj.Project, error)
|
||||||
|
|
||||||
|
// CloseFunc mocks the Close method.
|
||||||
|
CloseFunc func() error
|
||||||
|
|
||||||
|
// DeleteFunc mocks the Delete method.
|
||||||
|
DeleteFunc func(name string) error
|
||||||
|
|
||||||
|
// OnProjectCloseFunc mocks the OnProjectClose method.
|
||||||
|
OnProjectCloseFunc func(fn proj.OnProjectCloseFn)
|
||||||
|
|
||||||
|
// OnProjectOpenFunc mocks the OnProjectOpen method.
|
||||||
|
OnProjectOpenFunc func(fn proj.OnProjectOpenFn)
|
||||||
|
|
||||||
|
// OpenFunc mocks the Open method.
|
||||||
|
OpenFunc func(ctx context.Context, name string) (proj.Project, error)
|
||||||
|
|
||||||
|
// ProjectsFunc mocks the Projects method.
|
||||||
|
ProjectsFunc func() ([]proj.Project, error)
|
||||||
|
|
||||||
|
// calls tracks calls to the methods.
|
||||||
|
calls struct {
|
||||||
|
// ActiveProject holds details about calls to the ActiveProject method.
|
||||||
|
ActiveProject []struct {
|
||||||
|
}
|
||||||
|
// Close holds details about calls to the Close method.
|
||||||
|
Close []struct {
|
||||||
|
}
|
||||||
|
// Delete holds details about calls to the Delete method.
|
||||||
|
Delete []struct {
|
||||||
|
// Name is the name argument value.
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
// OnProjectClose holds details about calls to the OnProjectClose method.
|
||||||
|
OnProjectClose []struct {
|
||||||
|
// Fn is the fn argument value.
|
||||||
|
Fn proj.OnProjectCloseFn
|
||||||
|
}
|
||||||
|
// OnProjectOpen holds details about calls to the OnProjectOpen method.
|
||||||
|
OnProjectOpen []struct {
|
||||||
|
// Fn is the fn argument value.
|
||||||
|
Fn proj.OnProjectOpenFn
|
||||||
|
}
|
||||||
|
// Open holds details about calls to the Open method.
|
||||||
|
Open []struct {
|
||||||
|
// Ctx is the ctx argument value.
|
||||||
|
Ctx context.Context
|
||||||
|
// Name is the name argument value.
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
// Projects holds details about calls to the Projects method.
|
||||||
|
Projects []struct {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lockActiveProject sync.RWMutex
|
||||||
|
lockClose sync.RWMutex
|
||||||
|
lockDelete sync.RWMutex
|
||||||
|
lockOnProjectClose sync.RWMutex
|
||||||
|
lockOnProjectOpen sync.RWMutex
|
||||||
|
lockOpen sync.RWMutex
|
||||||
|
lockProjects sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActiveProject calls ActiveProjectFunc.
|
||||||
|
func (mock *ProjServiceMock) ActiveProject() (proj.Project, error) {
|
||||||
|
if mock.ActiveProjectFunc == nil {
|
||||||
|
panic("ProjServiceMock.ActiveProjectFunc: method is nil but Service.ActiveProject was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
}{}
|
||||||
|
mock.lockActiveProject.Lock()
|
||||||
|
mock.calls.ActiveProject = append(mock.calls.ActiveProject, callInfo)
|
||||||
|
mock.lockActiveProject.Unlock()
|
||||||
|
return mock.ActiveProjectFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActiveProjectCalls gets all the calls that were made to ActiveProject.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedService.ActiveProjectCalls())
|
||||||
|
func (mock *ProjServiceMock) ActiveProjectCalls() []struct {
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
}
|
||||||
|
mock.lockActiveProject.RLock()
|
||||||
|
calls = mock.calls.ActiveProject
|
||||||
|
mock.lockActiveProject.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close calls CloseFunc.
|
||||||
|
func (mock *ProjServiceMock) Close() error {
|
||||||
|
if mock.CloseFunc == nil {
|
||||||
|
panic("ProjServiceMock.CloseFunc: method is nil but Service.Close was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
}{}
|
||||||
|
mock.lockClose.Lock()
|
||||||
|
mock.calls.Close = append(mock.calls.Close, callInfo)
|
||||||
|
mock.lockClose.Unlock()
|
||||||
|
return mock.CloseFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseCalls gets all the calls that were made to Close.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedService.CloseCalls())
|
||||||
|
func (mock *ProjServiceMock) CloseCalls() []struct {
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
}
|
||||||
|
mock.lockClose.RLock()
|
||||||
|
calls = mock.calls.Close
|
||||||
|
mock.lockClose.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete calls DeleteFunc.
|
||||||
|
func (mock *ProjServiceMock) Delete(name string) error {
|
||||||
|
if mock.DeleteFunc == nil {
|
||||||
|
panic("ProjServiceMock.DeleteFunc: method is nil but Service.Delete was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
Name string
|
||||||
|
}{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
mock.lockDelete.Lock()
|
||||||
|
mock.calls.Delete = append(mock.calls.Delete, callInfo)
|
||||||
|
mock.lockDelete.Unlock()
|
||||||
|
return mock.DeleteFunc(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteCalls gets all the calls that were made to Delete.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedService.DeleteCalls())
|
||||||
|
func (mock *ProjServiceMock) DeleteCalls() []struct {
|
||||||
|
Name string
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
mock.lockDelete.RLock()
|
||||||
|
calls = mock.calls.Delete
|
||||||
|
mock.lockDelete.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnProjectClose calls OnProjectCloseFunc.
|
||||||
|
func (mock *ProjServiceMock) OnProjectClose(fn proj.OnProjectCloseFn) {
|
||||||
|
if mock.OnProjectCloseFunc == nil {
|
||||||
|
panic("ProjServiceMock.OnProjectCloseFunc: method is nil but Service.OnProjectClose was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
Fn proj.OnProjectCloseFn
|
||||||
|
}{
|
||||||
|
Fn: fn,
|
||||||
|
}
|
||||||
|
mock.lockOnProjectClose.Lock()
|
||||||
|
mock.calls.OnProjectClose = append(mock.calls.OnProjectClose, callInfo)
|
||||||
|
mock.lockOnProjectClose.Unlock()
|
||||||
|
mock.OnProjectCloseFunc(fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnProjectCloseCalls gets all the calls that were made to OnProjectClose.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedService.OnProjectCloseCalls())
|
||||||
|
func (mock *ProjServiceMock) OnProjectCloseCalls() []struct {
|
||||||
|
Fn proj.OnProjectCloseFn
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
Fn proj.OnProjectCloseFn
|
||||||
|
}
|
||||||
|
mock.lockOnProjectClose.RLock()
|
||||||
|
calls = mock.calls.OnProjectClose
|
||||||
|
mock.lockOnProjectClose.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnProjectOpen calls OnProjectOpenFunc.
|
||||||
|
func (mock *ProjServiceMock) OnProjectOpen(fn proj.OnProjectOpenFn) {
|
||||||
|
if mock.OnProjectOpenFunc == nil {
|
||||||
|
panic("ProjServiceMock.OnProjectOpenFunc: method is nil but Service.OnProjectOpen was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
Fn proj.OnProjectOpenFn
|
||||||
|
}{
|
||||||
|
Fn: fn,
|
||||||
|
}
|
||||||
|
mock.lockOnProjectOpen.Lock()
|
||||||
|
mock.calls.OnProjectOpen = append(mock.calls.OnProjectOpen, callInfo)
|
||||||
|
mock.lockOnProjectOpen.Unlock()
|
||||||
|
mock.OnProjectOpenFunc(fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnProjectOpenCalls gets all the calls that were made to OnProjectOpen.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedService.OnProjectOpenCalls())
|
||||||
|
func (mock *ProjServiceMock) OnProjectOpenCalls() []struct {
|
||||||
|
Fn proj.OnProjectOpenFn
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
Fn proj.OnProjectOpenFn
|
||||||
|
}
|
||||||
|
mock.lockOnProjectOpen.RLock()
|
||||||
|
calls = mock.calls.OnProjectOpen
|
||||||
|
mock.lockOnProjectOpen.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open calls OpenFunc.
|
||||||
|
func (mock *ProjServiceMock) Open(ctx context.Context, name string) (proj.Project, error) {
|
||||||
|
if mock.OpenFunc == nil {
|
||||||
|
panic("ProjServiceMock.OpenFunc: method is nil but Service.Open was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Name string
|
||||||
|
}{
|
||||||
|
Ctx: ctx,
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
mock.lockOpen.Lock()
|
||||||
|
mock.calls.Open = append(mock.calls.Open, callInfo)
|
||||||
|
mock.lockOpen.Unlock()
|
||||||
|
return mock.OpenFunc(ctx, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenCalls gets all the calls that were made to Open.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedService.OpenCalls())
|
||||||
|
func (mock *ProjServiceMock) OpenCalls() []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Name string
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
mock.lockOpen.RLock()
|
||||||
|
calls = mock.calls.Open
|
||||||
|
mock.lockOpen.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// Projects calls ProjectsFunc.
|
||||||
|
func (mock *ProjServiceMock) Projects() ([]proj.Project, error) {
|
||||||
|
if mock.ProjectsFunc == nil {
|
||||||
|
panic("ProjServiceMock.ProjectsFunc: method is nil but Service.Projects was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
}{}
|
||||||
|
mock.lockProjects.Lock()
|
||||||
|
mock.calls.Projects = append(mock.calls.Projects, callInfo)
|
||||||
|
mock.lockProjects.Unlock()
|
||||||
|
return mock.ProjectsFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProjectsCalls gets all the calls that were made to Projects.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedService.ProjectsCalls())
|
||||||
|
func (mock *ProjServiceMock) ProjectsCalls() []struct {
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
}
|
||||||
|
mock.lockProjects.RLock()
|
||||||
|
calls = mock.calls.Projects
|
||||||
|
mock.lockProjects.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
420
pkg/reqlog/repo_mock_test.go
Normal file
420
pkg/reqlog/repo_mock_test.go
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
// Code generated by moq; DO NOT EDIT.
|
||||||
|
// github.com/matryer/moq
|
||||||
|
|
||||||
|
package reqlog_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/dstotijn/hetty/pkg/reqlog"
|
||||||
|
"github.com/dstotijn/hetty/pkg/scope"
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ensure, that RepoMock does implement reqlog.Repository.
|
||||||
|
// If this is not the case, regenerate this file with moq.
|
||||||
|
var _ reqlog.Repository = &RepoMock{}
|
||||||
|
|
||||||
|
// RepoMock is a mock implementation of reqlog.Repository.
|
||||||
|
//
|
||||||
|
// func TestSomethingThatUsesRepository(t *testing.T) {
|
||||||
|
//
|
||||||
|
// // make and configure a mocked reqlog.Repository
|
||||||
|
// mockedRepository := &RepoMock{
|
||||||
|
// AddRequestLogFunc: func(ctx context.Context, req http.Request, body []byte, timestamp time.Time) (*reqlog.Request, error) {
|
||||||
|
// panic("mock out the AddRequestLog method")
|
||||||
|
// },
|
||||||
|
// AddResponseLogFunc: func(ctx context.Context, reqID int64, res http.Response, body []byte, timestamp time.Time) (*reqlog.Response, error) {
|
||||||
|
// panic("mock out the AddResponseLog method")
|
||||||
|
// },
|
||||||
|
// ClearRequestLogsFunc: func(ctx context.Context) error {
|
||||||
|
// panic("mock out the ClearRequestLogs method")
|
||||||
|
// },
|
||||||
|
// FindRequestLogByIDFunc: func(ctx context.Context, id int64) (reqlog.Request, error) {
|
||||||
|
// panic("mock out the FindRequestLogByID method")
|
||||||
|
// },
|
||||||
|
// FindRequestLogsFunc: func(ctx context.Context, filter reqlog.FindRequestsFilter, scopeMoqParam *scope.Scope) ([]reqlog.Request, error) {
|
||||||
|
// panic("mock out the FindRequestLogs method")
|
||||||
|
// },
|
||||||
|
// FindSettingsByModuleFunc: func(ctx context.Context, module string, settings interface{}) error {
|
||||||
|
// panic("mock out the FindSettingsByModule method")
|
||||||
|
// },
|
||||||
|
// UpsertSettingsFunc: func(ctx context.Context, module string, settings interface{}) error {
|
||||||
|
// panic("mock out the UpsertSettings method")
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // use mockedRepository in code that requires reqlog.Repository
|
||||||
|
// // and then make assertions.
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
type RepoMock struct {
|
||||||
|
// AddRequestLogFunc mocks the AddRequestLog method.
|
||||||
|
AddRequestLogFunc func(ctx context.Context, req http.Request, body []byte, timestamp time.Time) (*reqlog.Request, error)
|
||||||
|
|
||||||
|
// AddResponseLogFunc mocks the AddResponseLog method.
|
||||||
|
AddResponseLogFunc func(ctx context.Context, reqID int64, res http.Response, body []byte, timestamp time.Time) (*reqlog.Response, error)
|
||||||
|
|
||||||
|
// ClearRequestLogsFunc mocks the ClearRequestLogs method.
|
||||||
|
ClearRequestLogsFunc func(ctx context.Context) error
|
||||||
|
|
||||||
|
// FindRequestLogByIDFunc mocks the FindRequestLogByID method.
|
||||||
|
FindRequestLogByIDFunc func(ctx context.Context, id int64) (reqlog.Request, error)
|
||||||
|
|
||||||
|
// FindRequestLogsFunc mocks the FindRequestLogs method.
|
||||||
|
FindRequestLogsFunc func(ctx context.Context, filter reqlog.FindRequestsFilter, scopeMoqParam *scope.Scope) ([]reqlog.Request, error)
|
||||||
|
|
||||||
|
// FindSettingsByModuleFunc mocks the FindSettingsByModule method.
|
||||||
|
FindSettingsByModuleFunc func(ctx context.Context, module string, settings interface{}) error
|
||||||
|
|
||||||
|
// UpsertSettingsFunc mocks the UpsertSettings method.
|
||||||
|
UpsertSettingsFunc func(ctx context.Context, module string, settings interface{}) error
|
||||||
|
|
||||||
|
// calls tracks calls to the methods.
|
||||||
|
calls struct {
|
||||||
|
// AddRequestLog holds details about calls to the AddRequestLog method.
|
||||||
|
AddRequestLog []struct {
|
||||||
|
// Ctx is the ctx argument value.
|
||||||
|
Ctx context.Context
|
||||||
|
// Req is the req argument value.
|
||||||
|
Req http.Request
|
||||||
|
// Body is the body argument value.
|
||||||
|
Body []byte
|
||||||
|
// Timestamp is the timestamp argument value.
|
||||||
|
Timestamp time.Time
|
||||||
|
}
|
||||||
|
// AddResponseLog holds details about calls to the AddResponseLog method.
|
||||||
|
AddResponseLog []struct {
|
||||||
|
// Ctx is the ctx argument value.
|
||||||
|
Ctx context.Context
|
||||||
|
// ReqID is the reqID argument value.
|
||||||
|
ReqID int64
|
||||||
|
// Res is the res argument value.
|
||||||
|
Res http.Response
|
||||||
|
// Body is the body argument value.
|
||||||
|
Body []byte
|
||||||
|
// Timestamp is the timestamp argument value.
|
||||||
|
Timestamp time.Time
|
||||||
|
}
|
||||||
|
// ClearRequestLogs holds details about calls to the ClearRequestLogs method.
|
||||||
|
ClearRequestLogs []struct {
|
||||||
|
// Ctx is the ctx argument value.
|
||||||
|
Ctx context.Context
|
||||||
|
}
|
||||||
|
// FindRequestLogByID holds details about calls to the FindRequestLogByID method.
|
||||||
|
FindRequestLogByID []struct {
|
||||||
|
// Ctx is the ctx argument value.
|
||||||
|
Ctx context.Context
|
||||||
|
// ID is the id argument value.
|
||||||
|
ID int64
|
||||||
|
}
|
||||||
|
// FindRequestLogs holds details about calls to the FindRequestLogs method.
|
||||||
|
FindRequestLogs []struct {
|
||||||
|
// Ctx is the ctx argument value.
|
||||||
|
Ctx context.Context
|
||||||
|
// Filter is the filter argument value.
|
||||||
|
Filter reqlog.FindRequestsFilter
|
||||||
|
// ScopeMoqParam is the scopeMoqParam argument value.
|
||||||
|
ScopeMoqParam *scope.Scope
|
||||||
|
}
|
||||||
|
// FindSettingsByModule holds details about calls to the FindSettingsByModule method.
|
||||||
|
FindSettingsByModule []struct {
|
||||||
|
// Ctx is the ctx argument value.
|
||||||
|
Ctx context.Context
|
||||||
|
// Module is the module argument value.
|
||||||
|
Module string
|
||||||
|
// Settings is the settings argument value.
|
||||||
|
Settings interface{}
|
||||||
|
}
|
||||||
|
// UpsertSettings holds details about calls to the UpsertSettings method.
|
||||||
|
UpsertSettings []struct {
|
||||||
|
// Ctx is the ctx argument value.
|
||||||
|
Ctx context.Context
|
||||||
|
// Module is the module argument value.
|
||||||
|
Module string
|
||||||
|
// Settings is the settings argument value.
|
||||||
|
Settings interface{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lockAddRequestLog sync.RWMutex
|
||||||
|
lockAddResponseLog sync.RWMutex
|
||||||
|
lockClearRequestLogs sync.RWMutex
|
||||||
|
lockFindRequestLogByID sync.RWMutex
|
||||||
|
lockFindRequestLogs sync.RWMutex
|
||||||
|
lockFindSettingsByModule sync.RWMutex
|
||||||
|
lockUpsertSettings sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddRequestLog calls AddRequestLogFunc.
|
||||||
|
func (mock *RepoMock) AddRequestLog(ctx context.Context, req http.Request, body []byte, timestamp time.Time) (*reqlog.Request, error) {
|
||||||
|
if mock.AddRequestLogFunc == nil {
|
||||||
|
panic("RepoMock.AddRequestLogFunc: method is nil but Repository.AddRequestLog was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Req http.Request
|
||||||
|
Body []byte
|
||||||
|
Timestamp time.Time
|
||||||
|
}{
|
||||||
|
Ctx: ctx,
|
||||||
|
Req: req,
|
||||||
|
Body: body,
|
||||||
|
Timestamp: timestamp,
|
||||||
|
}
|
||||||
|
mock.lockAddRequestLog.Lock()
|
||||||
|
mock.calls.AddRequestLog = append(mock.calls.AddRequestLog, callInfo)
|
||||||
|
mock.lockAddRequestLog.Unlock()
|
||||||
|
return mock.AddRequestLogFunc(ctx, req, body, timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddRequestLogCalls gets all the calls that were made to AddRequestLog.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedRepository.AddRequestLogCalls())
|
||||||
|
func (mock *RepoMock) AddRequestLogCalls() []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Req http.Request
|
||||||
|
Body []byte
|
||||||
|
Timestamp time.Time
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Req http.Request
|
||||||
|
Body []byte
|
||||||
|
Timestamp time.Time
|
||||||
|
}
|
||||||
|
mock.lockAddRequestLog.RLock()
|
||||||
|
calls = mock.calls.AddRequestLog
|
||||||
|
mock.lockAddRequestLog.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddResponseLog calls AddResponseLogFunc.
|
||||||
|
func (mock *RepoMock) AddResponseLog(ctx context.Context, reqID int64, res http.Response, body []byte, timestamp time.Time) (*reqlog.Response, error) {
|
||||||
|
if mock.AddResponseLogFunc == nil {
|
||||||
|
panic("RepoMock.AddResponseLogFunc: method is nil but Repository.AddResponseLog was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
Ctx context.Context
|
||||||
|
ReqID int64
|
||||||
|
Res http.Response
|
||||||
|
Body []byte
|
||||||
|
Timestamp time.Time
|
||||||
|
}{
|
||||||
|
Ctx: ctx,
|
||||||
|
ReqID: reqID,
|
||||||
|
Res: res,
|
||||||
|
Body: body,
|
||||||
|
Timestamp: timestamp,
|
||||||
|
}
|
||||||
|
mock.lockAddResponseLog.Lock()
|
||||||
|
mock.calls.AddResponseLog = append(mock.calls.AddResponseLog, callInfo)
|
||||||
|
mock.lockAddResponseLog.Unlock()
|
||||||
|
return mock.AddResponseLogFunc(ctx, reqID, res, body, timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddResponseLogCalls gets all the calls that were made to AddResponseLog.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedRepository.AddResponseLogCalls())
|
||||||
|
func (mock *RepoMock) AddResponseLogCalls() []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
ReqID int64
|
||||||
|
Res http.Response
|
||||||
|
Body []byte
|
||||||
|
Timestamp time.Time
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
ReqID int64
|
||||||
|
Res http.Response
|
||||||
|
Body []byte
|
||||||
|
Timestamp time.Time
|
||||||
|
}
|
||||||
|
mock.lockAddResponseLog.RLock()
|
||||||
|
calls = mock.calls.AddResponseLog
|
||||||
|
mock.lockAddResponseLog.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearRequestLogs calls ClearRequestLogsFunc.
|
||||||
|
func (mock *RepoMock) ClearRequestLogs(ctx context.Context) error {
|
||||||
|
if mock.ClearRequestLogsFunc == nil {
|
||||||
|
panic("RepoMock.ClearRequestLogsFunc: method is nil but Repository.ClearRequestLogs was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
Ctx context.Context
|
||||||
|
}{
|
||||||
|
Ctx: ctx,
|
||||||
|
}
|
||||||
|
mock.lockClearRequestLogs.Lock()
|
||||||
|
mock.calls.ClearRequestLogs = append(mock.calls.ClearRequestLogs, callInfo)
|
||||||
|
mock.lockClearRequestLogs.Unlock()
|
||||||
|
return mock.ClearRequestLogsFunc(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearRequestLogsCalls gets all the calls that were made to ClearRequestLogs.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedRepository.ClearRequestLogsCalls())
|
||||||
|
func (mock *RepoMock) ClearRequestLogsCalls() []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
}
|
||||||
|
mock.lockClearRequestLogs.RLock()
|
||||||
|
calls = mock.calls.ClearRequestLogs
|
||||||
|
mock.lockClearRequestLogs.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindRequestLogByID calls FindRequestLogByIDFunc.
|
||||||
|
func (mock *RepoMock) FindRequestLogByID(ctx context.Context, id int64) (reqlog.Request, error) {
|
||||||
|
if mock.FindRequestLogByIDFunc == nil {
|
||||||
|
panic("RepoMock.FindRequestLogByIDFunc: method is nil but Repository.FindRequestLogByID was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
Ctx context.Context
|
||||||
|
ID int64
|
||||||
|
}{
|
||||||
|
Ctx: ctx,
|
||||||
|
ID: id,
|
||||||
|
}
|
||||||
|
mock.lockFindRequestLogByID.Lock()
|
||||||
|
mock.calls.FindRequestLogByID = append(mock.calls.FindRequestLogByID, callInfo)
|
||||||
|
mock.lockFindRequestLogByID.Unlock()
|
||||||
|
return mock.FindRequestLogByIDFunc(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindRequestLogByIDCalls gets all the calls that were made to FindRequestLogByID.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedRepository.FindRequestLogByIDCalls())
|
||||||
|
func (mock *RepoMock) FindRequestLogByIDCalls() []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
ID int64
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
ID int64
|
||||||
|
}
|
||||||
|
mock.lockFindRequestLogByID.RLock()
|
||||||
|
calls = mock.calls.FindRequestLogByID
|
||||||
|
mock.lockFindRequestLogByID.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindRequestLogs calls FindRequestLogsFunc.
|
||||||
|
func (mock *RepoMock) FindRequestLogs(ctx context.Context, filter reqlog.FindRequestsFilter, scopeMoqParam *scope.Scope) ([]reqlog.Request, error) {
|
||||||
|
if mock.FindRequestLogsFunc == nil {
|
||||||
|
panic("RepoMock.FindRequestLogsFunc: method is nil but Repository.FindRequestLogs was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Filter reqlog.FindRequestsFilter
|
||||||
|
ScopeMoqParam *scope.Scope
|
||||||
|
}{
|
||||||
|
Ctx: ctx,
|
||||||
|
Filter: filter,
|
||||||
|
ScopeMoqParam: scopeMoqParam,
|
||||||
|
}
|
||||||
|
mock.lockFindRequestLogs.Lock()
|
||||||
|
mock.calls.FindRequestLogs = append(mock.calls.FindRequestLogs, callInfo)
|
||||||
|
mock.lockFindRequestLogs.Unlock()
|
||||||
|
return mock.FindRequestLogsFunc(ctx, filter, scopeMoqParam)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindRequestLogsCalls gets all the calls that were made to FindRequestLogs.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedRepository.FindRequestLogsCalls())
|
||||||
|
func (mock *RepoMock) FindRequestLogsCalls() []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Filter reqlog.FindRequestsFilter
|
||||||
|
ScopeMoqParam *scope.Scope
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Filter reqlog.FindRequestsFilter
|
||||||
|
ScopeMoqParam *scope.Scope
|
||||||
|
}
|
||||||
|
mock.lockFindRequestLogs.RLock()
|
||||||
|
calls = mock.calls.FindRequestLogs
|
||||||
|
mock.lockFindRequestLogs.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindSettingsByModule calls FindSettingsByModuleFunc.
|
||||||
|
func (mock *RepoMock) FindSettingsByModule(ctx context.Context, module string, settings interface{}) error {
|
||||||
|
if mock.FindSettingsByModuleFunc == nil {
|
||||||
|
panic("RepoMock.FindSettingsByModuleFunc: method is nil but Repository.FindSettingsByModule was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Module string
|
||||||
|
Settings interface{}
|
||||||
|
}{
|
||||||
|
Ctx: ctx,
|
||||||
|
Module: module,
|
||||||
|
Settings: settings,
|
||||||
|
}
|
||||||
|
mock.lockFindSettingsByModule.Lock()
|
||||||
|
mock.calls.FindSettingsByModule = append(mock.calls.FindSettingsByModule, callInfo)
|
||||||
|
mock.lockFindSettingsByModule.Unlock()
|
||||||
|
return mock.FindSettingsByModuleFunc(ctx, module, settings)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindSettingsByModuleCalls gets all the calls that were made to FindSettingsByModule.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedRepository.FindSettingsByModuleCalls())
|
||||||
|
func (mock *RepoMock) FindSettingsByModuleCalls() []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Module string
|
||||||
|
Settings interface{}
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Module string
|
||||||
|
Settings interface{}
|
||||||
|
}
|
||||||
|
mock.lockFindSettingsByModule.RLock()
|
||||||
|
calls = mock.calls.FindSettingsByModule
|
||||||
|
mock.lockFindSettingsByModule.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpsertSettings calls UpsertSettingsFunc.
|
||||||
|
func (mock *RepoMock) UpsertSettings(ctx context.Context, module string, settings interface{}) error {
|
||||||
|
if mock.UpsertSettingsFunc == nil {
|
||||||
|
panic("RepoMock.UpsertSettingsFunc: method is nil but Repository.UpsertSettings was just called")
|
||||||
|
}
|
||||||
|
callInfo := struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Module string
|
||||||
|
Settings interface{}
|
||||||
|
}{
|
||||||
|
Ctx: ctx,
|
||||||
|
Module: module,
|
||||||
|
Settings: settings,
|
||||||
|
}
|
||||||
|
mock.lockUpsertSettings.Lock()
|
||||||
|
mock.calls.UpsertSettings = append(mock.calls.UpsertSettings, callInfo)
|
||||||
|
mock.lockUpsertSettings.Unlock()
|
||||||
|
return mock.UpsertSettingsFunc(ctx, module, settings)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpsertSettingsCalls gets all the calls that were made to UpsertSettings.
|
||||||
|
// Check the length with:
|
||||||
|
// len(mockedRepository.UpsertSettingsCalls())
|
||||||
|
func (mock *RepoMock) UpsertSettingsCalls() []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Module string
|
||||||
|
Settings interface{}
|
||||||
|
} {
|
||||||
|
var calls []struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Module string
|
||||||
|
Settings interface{}
|
||||||
|
}
|
||||||
|
mock.lockUpsertSettings.RLock()
|
||||||
|
calls = mock.calls.UpsertSettings
|
||||||
|
mock.lockUpsertSettings.RUnlock()
|
||||||
|
return calls
|
||||||
|
}
|
@ -59,7 +59,7 @@ type FindRequestsFilter struct {
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
Scope *scope.Scope
|
Scope *scope.Scope
|
||||||
Repository Repository
|
Repository Repository
|
||||||
ProjectService *proj.Service
|
ProjectService proj.Service
|
||||||
BypassOutOfScopeRequests bool
|
BypassOutOfScopeRequests bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ func NewService(cfg Config) *Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cfg.ProjectService.OnProjectOpen(func(_ string) error {
|
cfg.ProjectService.OnProjectOpen(func(_ string) error {
|
||||||
err := svc.loadSettings()
|
err := svc.repo.FindSettingsByModule(context.Background(), moduleName, svc)
|
||||||
if errors.Is(err, proj.ErrNoSettings) {
|
if errors.Is(err, proj.ErrNoSettings) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -82,7 +82,8 @@ func NewService(cfg Config) *Service {
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
cfg.ProjectService.OnProjectClose(func(_ string) error {
|
cfg.ProjectService.OnProjectClose(func(_ string) error {
|
||||||
svc.unloadSettings()
|
svc.BypassOutOfScopeRequests = false
|
||||||
|
svc.FindReqsFilter = FindRequestsFilter{}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -252,12 +253,3 @@ func (f *FindRequestsFilter) UnmarshalJSON(b []byte) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) loadSettings() error {
|
|
||||||
return svc.repo.FindSettingsByModule(context.Background(), moduleName, svc)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) unloadSettings() {
|
|
||||||
svc.BypassOutOfScopeRequests = false
|
|
||||||
svc.FindReqsFilter = FindRequestsFilter{}
|
|
||||||
}
|
|
||||||
|
193
pkg/reqlog/reqlog_test.go
Normal file
193
pkg/reqlog/reqlog_test.go
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
package reqlog_test
|
||||||
|
|
||||||
|
//go:generate moq -out proj_mock_test.go -pkg reqlog_test ../proj Service:ProjServiceMock
|
||||||
|
//go:generate moq -out repo_mock_test.go -pkg reqlog_test . Repository:RepoMock
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/dstotijn/hetty/pkg/proj"
|
||||||
|
"github.com/dstotijn/hetty/pkg/proxy"
|
||||||
|
"github.com/dstotijn/hetty/pkg/reqlog"
|
||||||
|
)
|
||||||
|
|
||||||
|
//nolint:paralleltest
|
||||||
|
func TestNewService(t *testing.T) {
|
||||||
|
projSvcMock := &ProjServiceMock{
|
||||||
|
OnProjectOpenFunc: func(fn proj.OnProjectOpenFn) {},
|
||||||
|
OnProjectCloseFunc: func(fn proj.OnProjectCloseFn) {},
|
||||||
|
}
|
||||||
|
repoMock := &RepoMock{
|
||||||
|
FindSettingsByModuleFunc: func(_ context.Context, _ string, _ interface{}) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
svc := reqlog.NewService(reqlog.Config{
|
||||||
|
ProjectService: projSvcMock,
|
||||||
|
Repository: repoMock,
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("registered handlers for project open and close", func(t *testing.T) {
|
||||||
|
got := len(projSvcMock.OnProjectOpenCalls())
|
||||||
|
if exp := 1; exp != got {
|
||||||
|
t.Fatalf("incorrect `proj.Service.OnProjectOpen` calls (expected: %v, got: %v)", exp, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
got = len(projSvcMock.OnProjectCloseCalls())
|
||||||
|
if exp := 1; exp != got {
|
||||||
|
t.Fatalf("incorrect `proj.Service.OnProjectClose` calls (expected: %v, got: %v)", exp, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("calls handler when project is opened", func(t *testing.T) {
|
||||||
|
// Mock opening a project.
|
||||||
|
err := projSvcMock.OnProjectOpenCalls()[0].Fn("foobar")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error (expected: nil, got: %v)", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that settings were fetched from repository, with `svc` as the
|
||||||
|
// destination.
|
||||||
|
got := len(repoMock.FindSettingsByModuleCalls())
|
||||||
|
if exp := 1; exp != got {
|
||||||
|
t.Fatalf("incorrect `proj.Service.OnProjectOpen` calls (expected: %v, got: %v)", exp, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
findSettingsByModuleCall := repoMock.FindSettingsByModuleCalls()[0]
|
||||||
|
expModule := "reqlog"
|
||||||
|
expSettings := svc
|
||||||
|
|
||||||
|
if expModule != findSettingsByModuleCall.Module {
|
||||||
|
t.Fatalf("incorrect `module` argument for `proj.Service.OnProjectOpen` (expected: %v, got: %v)",
|
||||||
|
expModule, findSettingsByModuleCall.Module)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expSettings != findSettingsByModuleCall.Settings {
|
||||||
|
t.Fatalf("incorrect `settings` argument for `proj.Service.OnProjectOpen` (expected: %v, got: %v)",
|
||||||
|
expModule, findSettingsByModuleCall.Settings)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("calls handler when project is closed", func(t *testing.T) {
|
||||||
|
// Mock updating service settings.
|
||||||
|
svc.BypassOutOfScopeRequests = true
|
||||||
|
svc.FindReqsFilter = reqlog.FindRequestsFilter{OnlyInScope: true}
|
||||||
|
|
||||||
|
// Mock closing a project.
|
||||||
|
err := projSvcMock.OnProjectCloseCalls()[0].Fn("foobar")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error (expected: nil, got: %v)", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that settings were set to defaults on project close.
|
||||||
|
expBypassOutOfScopeReqs := false
|
||||||
|
expFindReqsFilter := reqlog.FindRequestsFilter{}
|
||||||
|
|
||||||
|
if expBypassOutOfScopeReqs != svc.BypassOutOfScopeRequests {
|
||||||
|
t.Fatalf("incorrect `Service.BypassOutOfScopeRequests` value (expected: %v, got: %v)",
|
||||||
|
expBypassOutOfScopeReqs, svc.BypassOutOfScopeRequests)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expFindReqsFilter != svc.FindReqsFilter {
|
||||||
|
t.Fatalf("incorrect `Service.FindReqsFilter` value (expected: %v, got: %v)",
|
||||||
|
expFindReqsFilter, svc.FindReqsFilter)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:paralleltest
|
||||||
|
func TestRequestModifier(t *testing.T) {
|
||||||
|
projSvcMock := &ProjServiceMock{
|
||||||
|
OnProjectOpenFunc: func(fn proj.OnProjectOpenFn) {},
|
||||||
|
OnProjectCloseFunc: func(fn proj.OnProjectCloseFn) {},
|
||||||
|
}
|
||||||
|
repoMock := &RepoMock{
|
||||||
|
AddRequestLogFunc: func(_ context.Context, _ http.Request, _ []byte, _ time.Time) (*reqlog.Request, error) {
|
||||||
|
return &reqlog.Request{}, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
svc := reqlog.NewService(reqlog.Config{
|
||||||
|
ProjectService: projSvcMock,
|
||||||
|
Repository: repoMock,
|
||||||
|
})
|
||||||
|
|
||||||
|
next := func(req *http.Request) {
|
||||||
|
req.Body = ioutil.NopCloser(strings.NewReader("modified body"))
|
||||||
|
}
|
||||||
|
reqModFn := svc.RequestModifier(next)
|
||||||
|
req := httptest.NewRequest("GET", "https://example.com/", strings.NewReader("bar"))
|
||||||
|
|
||||||
|
reqModFn(req)
|
||||||
|
|
||||||
|
t.Run("request log was stored in repository", func(t *testing.T) {
|
||||||
|
got := len(repoMock.AddRequestLogCalls())
|
||||||
|
if exp := 1; exp != got {
|
||||||
|
t.Fatalf("incorrect `proj.Service.AddRequestLog` calls (expected: %v, got: %v)", exp, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("ran next modifier first, before calling repository", func(t *testing.T) {
|
||||||
|
got := repoMock.AddRequestLogCalls()[0].Body
|
||||||
|
if exp := "modified body"; exp != string(got) {
|
||||||
|
t.Fatalf("incorrect `body` argument for `Repository.AddRequestLogCalls` (expected: %v, got: %v)", exp, string(got))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:paralleltest
|
||||||
|
func TestResponseModifier(t *testing.T) {
|
||||||
|
projSvcMock := &ProjServiceMock{
|
||||||
|
OnProjectOpenFunc: func(fn proj.OnProjectOpenFn) {},
|
||||||
|
OnProjectCloseFunc: func(fn proj.OnProjectCloseFn) {},
|
||||||
|
}
|
||||||
|
repoMock := &RepoMock{
|
||||||
|
AddResponseLogFunc: func(_ context.Context, _ int64, _ http.Response,
|
||||||
|
_ []byte, _ time.Time) (*reqlog.Response, error) {
|
||||||
|
return &reqlog.Response{}, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
svc := reqlog.NewService(reqlog.Config{
|
||||||
|
ProjectService: projSvcMock,
|
||||||
|
Repository: repoMock,
|
||||||
|
})
|
||||||
|
|
||||||
|
next := func(res *http.Response) error {
|
||||||
|
res.Body = ioutil.NopCloser(strings.NewReader("modified body"))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
resModFn := svc.ResponseModifier(next)
|
||||||
|
|
||||||
|
req := httptest.NewRequest("GET", "https://example.com/", strings.NewReader("bar"))
|
||||||
|
req = req.WithContext(context.WithValue(req.Context(), proxy.ReqIDKey, int64(42)))
|
||||||
|
|
||||||
|
res := &http.Response{
|
||||||
|
Request: req,
|
||||||
|
Body: ioutil.NopCloser(strings.NewReader("bar")),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := resModFn(res); err != nil {
|
||||||
|
t.Fatalf("unexpected error (expected: nil, got: %v)", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("request log was stored in repository", func(t *testing.T) {
|
||||||
|
// Dirty (but simple) wait for other goroutine to finish calling repository.
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
got := len(repoMock.AddResponseLogCalls())
|
||||||
|
if exp := 1; exp != got {
|
||||||
|
t.Fatalf("incorrect `proj.Service.AddResponseLog` calls (expected: %v, got: %v)", exp, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("ran next modifier first, before calling repository", func(t *testing.T) {
|
||||||
|
got := repoMock.AddResponseLogCalls()[0].Body
|
||||||
|
if exp := "modified body"; exp != string(got) {
|
||||||
|
t.Fatalf("incorrect `body` argument for `Repository.AddResponseLogCalls` (expected: %v, got: %v)", exp, string(got))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
@ -32,7 +32,7 @@ type Header struct {
|
|||||||
Value *regexp.Regexp
|
Value *regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(repo Repository, projService *proj.Service) *Scope {
|
func New(repo Repository, projService proj.Service) *Scope {
|
||||||
s := &Scope{
|
s := &Scope{
|
||||||
repo: repo,
|
repo: repo,
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user