Skip to content

Commit

Permalink
add request.pathVariables, allowing regexp against path variables
Browse files Browse the repository at this point in the history
  • Loading branch information
jcdietrich committed Apr 16, 2024
1 parent 34f5f5c commit 5cef129
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 1 deletion.
9 changes: 8 additions & 1 deletion pkg/match/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var (
ErrCookiesNotMatch = errors.New("Cookies not match")
ErrScenarioNotMatch = errors.New("Scenario state not match")
ErrPathNotMatch = errors.New("Path not match")
ErrPathVariablesNotMatch = errors.New("Path variables not match")
)

func NewTester(comparator *payload.Comparator, scenario ScenearioStorer) *Request {
Expand Down Expand Up @@ -190,9 +191,15 @@ func (mm Request) Match(req *mock.Request, mock *mock.Definition, scenarioAware
return false, fmt.Errorf("Fragment not match. Actual: %s, Expected: %s", req.Fragment, mock.Request.Fragment)
}

if !glob.Glob(mock.Request.Path, req.Path) && route.Match(req.Path) == nil {
var pathMatch = route.Match(req.Path)

if !glob.Glob(mock.Request.Path, req.Path) && pathMatch == nil {
return false, fmt.Errorf("%w Actual: %s, Expected: %s", ErrPathNotMatch, req.Path, mock.Request.Path)
}

if pathMatch != nil && mock.Request.PathVariables != nil && !route.MatchPathVariables(pathMatch, mock.Request.PathVariables) {
return false, fmt.Errorf("%w Actual: %s Expected: %v", ErrPathVariablesNotMatch, mock.Request.PathVariables, pathMatch.Params)
}

if !mm.mockIncludesMethod(req.Method, &mock.Request) {
return false, fmt.Errorf("Method not match. Actual: %s, Expected: %s", req.Method, mock.Request.Method)
Expand Down
33 changes: 33 additions & 0 deletions pkg/match/request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,39 @@ func TestPathVars(t *testing.T) {
}
}

func TestPathVariables(t *testing.T) {
req := mock.Request{}
req.Path = "/a/b/c"

m := mock.Definition{}
m.Request.Path = "/a/:b/:c"
m.Request.PathVariables = map[string]string{
"b": "[a-z]",
"c": "[a-z]",
}

mm := Request{}

// match
if b, err := mm.Match(&req, &m, true); !b {
t.Error(err)
}

// not match
req.Path = "a/b/3"

if b, err := mm.Match(&req, &m, true); b {
t.Error(err)
}

// not present
req.Path = "a/b"

if b, err := mm.Match(&req, &m, true); b {
t.Error(err)
}
}

func TestPathGlob(t *testing.T) {
req := mock.Request{}
req.Path = "/a/b/c"
Expand Down
3 changes: 3 additions & 0 deletions pkg/mock/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ type Values map[string][]string

type Cookies map[string]string

type PathValues map[string]string

type HttpHeaders struct {
Headers Values `json:"headers"`
Cookies Cookies `json:"cookies"`
Expand All @@ -22,6 +24,7 @@ type Request struct {
Port string `json:"port"`
Method string `json:"method"`
Path string `json:"path"`
PathVariables PathValues `json:"pathVariables"`
QueryStringParameters Values `json:"queryStringParameters"`
Fragment string `json:"fragment"`
HttpHeaders
Expand Down
25 changes: 25 additions & 0 deletions pkg/route/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import (
"fmt"
"regexp"
"strings"
"github.com/jmartin82/mmock/v3/internal/config/logger"
)

var log = logger.Log

type Route struct {
Keys []string
Regex *regexp.Regexp
Expand Down Expand Up @@ -40,6 +43,28 @@ func (route *Route) Match(url string) *Match {
return &Match{route.Params(url), route.Pattern}
}

func (route *Route) MatchPathVariables(match *Match, patterns map[string]string) bool{
for key, value := range match.Params {

pattern, exists := patterns[key]

if !exists {
log.Debugf("pathVariable %v isn't in request", key)
return false
}

log.Debugf("comparing pathVariable %v that has a value of %v against pattern %v", key, value, pattern)
matched, err := regexp.MatchString(pattern, value)

if !matched || err != nil {
log.Debugf("PathVariable %v with a value of %v either doesn't match %v or %v", key, value, pattern, err)
return false
}
}

return true
}

func NewRoute(pattern string) *Route {
regex, keys := pathToRegex(pattern)
return &Route{keys, regex, pattern}
Expand Down

0 comments on commit 5cef129

Please sign in to comment.