-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
Merge branch 'release/v0.5.0'
Showing
20 changed files
with
667 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
name: Build | ||
|
||
on: | ||
push: | ||
branches: | ||
- develop | ||
- master | ||
pull_request: | ||
|
||
jobs: | ||
|
||
go-legacy-test: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
go-version: [ '1.20', '1.21' ] | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Set up Go | ||
uses: actions/setup-go@v5 | ||
with: | ||
go-version: ${{ matrix.go-version }} | ||
- name: Go get | ||
run: go get -t ./... | ||
- name: Build | ||
run: go build -v ./... | ||
- name: Test | ||
run: go test -v ./... | ||
|
||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Set up Go | ||
uses: actions/setup-go@v5 | ||
with: | ||
go-version: '1.22.4' | ||
- name: Go get | ||
run: go get -t ./... | ||
- name: Build | ||
run: go build -v ./... | ||
- name: Test | ||
run: go test -v -covermode=atomic -coverprofile=cover.out -coverpkg=. ./... | ||
- name: Install goveralls | ||
run: go install github.com/mattn/goveralls@latest | ||
- name: Send coverage | ||
env: | ||
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
run: goveralls -coverprofile=cover.out -service=github | ||
|
||
lint: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Set up Go | ||
uses: actions/setup-go@v5 | ||
with: | ||
go-version: '1.22.4' | ||
- name: Install checks | ||
run: | | ||
go install honnef.co/go/tools/cmd/staticcheck@latest | ||
go install github.com/client9/misspell/cmd/misspell@latest | ||
- name: Go get | ||
run: go get -t ./... | ||
- name: Go vet | ||
run: go vet $(go list ./... | grep -v /vendor/) | ||
- name: Go mod | ||
run: go mod tidy; git diff --exit-code go.mod go.sum | ||
- name: Go fmt | ||
run: go fmt $(go list ./... | grep -v /vendor/); git diff --exit-code | ||
- name: Staticcheck | ||
run: staticcheck -checks all,-ST1000 ./... | ||
- name: Misspell | ||
run: misspell -error -locale US . |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
name: Release | ||
|
||
on: | ||
push: | ||
tags: | ||
- '*' | ||
|
||
# Make sure the GITHUB_TOKEN has permission to upload to our releases | ||
permissions: | ||
contents: write | ||
|
||
jobs: | ||
|
||
create_release: | ||
name: Create Release | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Check out the repo | ||
uses: actions/checkout@v4 | ||
- name: Create release draft | ||
id: create_release | ||
uses: actions/create-release@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
tag_name: ${{ github.ref }} | ||
release_name: Release ${{ github.ref_name }} | ||
body: | | ||
A new release | ||
draft: true | ||
prerelease: false |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,5 @@ | ||
#!/bin/bash -e | ||
# Run from directory above via ./scripts/cover.sh | ||
|
||
go test -covermode=atomic -coverprofile=./cover.out -coverpkg=. ./... | ||
|
||
# If we have an arg, assume travis run and push to coveralls. Otherwise launch browser results | ||
if [[ -n $1 ]]; then | ||
$HOME/gopath/bin/goveralls -coverprofile=cover.out -service travis-ci | ||
rm -rf ./cover.out | ||
else | ||
go tool cover -html=cover.out | ||
fi | ||
go test -v -covermode=atomic -coverprofile=./cover.out -coverpkg=. ./... | ||
go tool cover -html=cover.out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,4 @@ | ||
#!/bin/bash -e | ||
|
||
pushd /tmp > /dev/null | ||
go get -u github.com/mattn/goveralls | ||
go get -u honnef.co/go/tools/cmd/staticcheck | ||
go get -u golang.org/x/lint/golint | ||
go get -u github.com/client9/misspell/cmd/misspell | ||
popd > /dev/null | ||
go install honnef.co/go/tools/cmd/staticcheck@latest | ||
go install github.com/client9/misspell/cmd/misspell@latest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,327 @@ | ||
package test | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/jirenius/go-res" | ||
"github.com/jirenius/go-res/restest" | ||
) | ||
|
||
var metaTestTbl = []struct { | ||
Name string | ||
Status int | ||
Header map[string][]string | ||
ExpectedMeta interface{} | ||
}{ | ||
{ | ||
Name: "status code", | ||
Status: 402, | ||
ExpectedMeta: json.RawMessage(`{"status":402}`), | ||
}, | ||
{ | ||
Name: "single header", | ||
Header: map[string][]string{"Location": {"https://example.com"}}, | ||
ExpectedMeta: json.RawMessage(`{"header":{"Location":["https://example.com"]}}`), | ||
}, | ||
{ | ||
Name: "multiple headers", | ||
Header: map[string][]string{"Set-Cookie": {"foo=bar", "zoo=baz"}}, | ||
ExpectedMeta: json.RawMessage(`{"header":{"Set-Cookie":["foo=bar","zoo=baz"]}}`), | ||
}, | ||
{ | ||
Name: "status and header", | ||
Status: 303, | ||
Header: map[string][]string{"Location": {"https://example.com"}}, | ||
ExpectedMeta: json.RawMessage(`{"status":303,"header":{"Location":["https://example.com"]}}`), | ||
}, | ||
} | ||
|
||
// Test auth request with meta data and a successful response. | ||
func TestMeta_AuthRequestWithSuccessResponse_MetaInResponse(t *testing.T) { | ||
for _, k := range []struct { | ||
Name string | ||
Result interface{} | ||
}{ | ||
{Name: "nil result", Result: nil}, | ||
{Name: "custom result", Result: mock.Result}, | ||
} { | ||
for _, l := range metaTestTbl { | ||
runTest(t, func(s *res.Service) { | ||
s.Handle("model", res.Auth("method", func(r res.AuthRequest) { | ||
r.SetResponseStatus(l.Status) | ||
for k, v := range l.Header { | ||
r.ResponseHeader()[k] = v | ||
} | ||
r.OK(k.Result) | ||
})) | ||
}, func(s *restest.Session) { | ||
req := mock.DefaultRequest() | ||
req.IsHTTP = true | ||
s.Auth("test.model", "method", req). | ||
Response(). | ||
AssertPayload(map[string]interface{}{ | ||
"result": k.Result, | ||
"meta": l.ExpectedMeta, | ||
}) | ||
}, restest.WithTest(fmt.Sprintf("%s with %s", k.Name, l.Name))) | ||
} | ||
} | ||
} | ||
|
||
// Test auth request with meta data and an error response. | ||
func TestMeta_AuthRequestWithErrorResponse_MetaInResponse(t *testing.T) { | ||
for _, k := range []struct { | ||
Name string | ||
Respond func(r res.AuthRequest) | ||
ExpectedError error | ||
}{ | ||
{Name: "CustomError()", Respond: func(r res.AuthRequest) { r.Error(mock.CustomError) }, ExpectedError: mock.CustomError}, | ||
{Name: "NotFound()", Respond: func(r res.AuthRequest) { r.NotFound() }, ExpectedError: res.ErrNotFound}, | ||
{Name: "MethodNotFound()", Respond: func(r res.AuthRequest) { r.MethodNotFound() }, ExpectedError: res.ErrMethodNotFound}, | ||
{Name: `InvalidParams("")`, Respond: func(r res.AuthRequest) { r.InvalidParams("") }, ExpectedError: res.ErrInvalidParams}, | ||
{Name: `InvalidParams("foo")`, Respond: func(r res.AuthRequest) { r.InvalidParams("foo") }, ExpectedError: &res.Error{Code: res.CodeInvalidParams, Message: "foo"}}, | ||
{Name: `InvalidQuery("")`, Respond: func(r res.AuthRequest) { r.InvalidQuery("") }, ExpectedError: res.ErrInvalidQuery}, | ||
{Name: `InvalidQuery("foo")`, Respond: func(r res.AuthRequest) { r.InvalidQuery("foo") }, ExpectedError: &res.Error{Code: res.CodeInvalidQuery, Message: "foo"}}, | ||
} { | ||
for _, l := range metaTestTbl { | ||
runTest(t, func(s *res.Service) { | ||
s.Handle("model", res.Auth("method", func(r res.AuthRequest) { | ||
r.SetResponseStatus(l.Status) | ||
for k, v := range l.Header { | ||
r.ResponseHeader()[k] = v | ||
} | ||
k.Respond(r) | ||
})) | ||
}, func(s *restest.Session) { | ||
req := mock.DefaultRequest() | ||
req.IsHTTP = true | ||
s.Auth("test.model", "method", req). | ||
Response(). | ||
AssertPayload(map[string]interface{}{ | ||
"error": k.ExpectedError, | ||
"meta": l.ExpectedMeta, | ||
}) | ||
}, restest.WithTest(fmt.Sprintf("%s with %s", k.Name, l.Name))) | ||
} | ||
} | ||
} | ||
|
||
// Test auth request with meta data and a resource response. | ||
func TestMeta_AuthRequestWithResourceResponse_MetaInResponse(t *testing.T) { | ||
rid := "test.foo" | ||
for _, l := range metaTestTbl { | ||
runTest(t, func(s *res.Service) { | ||
s.Handle("model", res.Auth("method", func(r res.AuthRequest) { | ||
r.SetResponseStatus(l.Status) | ||
for k, v := range l.Header { | ||
r.ResponseHeader()[k] = v | ||
} | ||
r.Resource(rid) | ||
})) | ||
}, func(s *restest.Session) { | ||
req := mock.DefaultRequest() | ||
req.IsHTTP = true | ||
s.Auth("test.model", "method", req). | ||
Response(). | ||
AssertPayload(map[string]interface{}{ | ||
"resource": res.Ref(rid), | ||
"meta": l.ExpectedMeta, | ||
}) | ||
}, restest.WithTest(l.Name)) | ||
} | ||
} | ||
|
||
// Test call request with meta data and a successful response. | ||
func TestMeta_CallRequestWithSuccessResponse_MetaInResponse(t *testing.T) { | ||
for _, k := range []struct { | ||
Name string | ||
Result interface{} | ||
}{ | ||
{Name: "nil result", Result: nil}, | ||
{Name: "custom result", Result: mock.Result}, | ||
} { | ||
for _, l := range metaTestTbl { | ||
runTest(t, func(s *res.Service) { | ||
s.Handle("model", res.Call("method", func(r res.CallRequest) { | ||
r.SetResponseStatus(l.Status) | ||
for k, v := range l.Header { | ||
r.ResponseHeader()[k] = v | ||
} | ||
r.OK(k.Result) | ||
})) | ||
}, func(s *restest.Session) { | ||
req := mock.DefaultRequest() | ||
req.IsHTTP = true | ||
s.Call("test.model", "method", req). | ||
Response(). | ||
AssertPayload(map[string]interface{}{ | ||
"result": k.Result, | ||
"meta": l.ExpectedMeta, | ||
}) | ||
}, restest.WithTest(fmt.Sprintf("%s with %s", k.Name, l.Name))) | ||
} | ||
} | ||
} | ||
|
||
// Test call request with meta data and an error response. | ||
func TestMeta_CallRequestWithErrorResponse_MetaInResponse(t *testing.T) { | ||
for _, k := range []struct { | ||
Name string | ||
Respond func(r res.CallRequest) | ||
ExpectedError error | ||
}{ | ||
{Name: "CustomError()", Respond: func(r res.CallRequest) { r.Error(mock.CustomError) }, ExpectedError: mock.CustomError}, | ||
{Name: "NotFound()", Respond: func(r res.CallRequest) { r.NotFound() }, ExpectedError: res.ErrNotFound}, | ||
{Name: "MethodNotFound()", Respond: func(r res.CallRequest) { r.MethodNotFound() }, ExpectedError: res.ErrMethodNotFound}, | ||
{Name: `InvalidParams("")`, Respond: func(r res.CallRequest) { r.InvalidParams("") }, ExpectedError: res.ErrInvalidParams}, | ||
{Name: `InvalidParams("foo")`, Respond: func(r res.CallRequest) { r.InvalidParams("foo") }, ExpectedError: &res.Error{Code: res.CodeInvalidParams, Message: "foo"}}, | ||
{Name: `InvalidQuery("")`, Respond: func(r res.CallRequest) { r.InvalidQuery("") }, ExpectedError: res.ErrInvalidQuery}, | ||
{Name: `InvalidQuery("foo")`, Respond: func(r res.CallRequest) { r.InvalidQuery("foo") }, ExpectedError: &res.Error{Code: res.CodeInvalidQuery, Message: "foo"}}, | ||
} { | ||
for _, l := range metaTestTbl { | ||
runTest(t, func(s *res.Service) { | ||
s.Handle("model", res.Call("method", func(r res.CallRequest) { | ||
r.SetResponseStatus(l.Status) | ||
for k, v := range l.Header { | ||
r.ResponseHeader()[k] = v | ||
} | ||
r.Error(mock.CustomError) | ||
})) | ||
}, func(s *restest.Session) { | ||
req := mock.DefaultRequest() | ||
req.IsHTTP = true | ||
s.Call("test.model", "method", req). | ||
Response(). | ||
AssertPayload(map[string]interface{}{ | ||
"error": mock.CustomError, | ||
"meta": l.ExpectedMeta, | ||
}) | ||
}, restest.WithTest(fmt.Sprintf("%s with %s", k.Name, l.Name))) | ||
} | ||
} | ||
} | ||
|
||
// Test call request with meta data and a resource response. | ||
func TestMeta_CallRequestWithResourceResponse_MetaInResponse(t *testing.T) { | ||
rid := "test.foo" | ||
for _, l := range metaTestTbl { | ||
runTest(t, func(s *res.Service) { | ||
s.Handle("model", res.Call("method", func(r res.CallRequest) { | ||
r.SetResponseStatus(l.Status) | ||
for k, v := range l.Header { | ||
r.ResponseHeader()[k] = v | ||
} | ||
r.Resource(rid) | ||
})) | ||
}, func(s *restest.Session) { | ||
req := mock.DefaultRequest() | ||
req.IsHTTP = true | ||
s.Call("test.model", "method", req). | ||
Response(). | ||
AssertPayload(map[string]interface{}{ | ||
"resource": res.Ref(rid), | ||
"meta": l.ExpectedMeta, | ||
}) | ||
}, restest.WithTest(l.Name)) | ||
} | ||
} | ||
|
||
// Test access request with meta data and a successful response. | ||
func TestMeta_AccessRequestWithSuccessResponse_MetaInResponse(t *testing.T) { | ||
for _, k := range []struct { | ||
Name string | ||
Respond func(r res.AccessRequest) | ||
ExpectedResult interface{} | ||
}{ | ||
{Name: "AccessGranted()", Respond: func(r res.AccessRequest) { r.AccessGranted() }, ExpectedResult: json.RawMessage(`{"get":true,"call":"*"}`)}, | ||
{Name: `Access(true, "foo")`, Respond: func(r res.AccessRequest) { r.Access(true, "foo") }, ExpectedResult: json.RawMessage(`{"get":true,"call":"foo"}`)}, | ||
} { | ||
for _, l := range metaTestTbl { | ||
runTest(t, func(s *res.Service) { | ||
s.Handle("model", res.Access(func(r res.AccessRequest) { | ||
r.SetResponseStatus(l.Status) | ||
for k, v := range l.Header { | ||
r.ResponseHeader()[k] = v | ||
} | ||
k.Respond(r) | ||
})) | ||
}, func(s *restest.Session) { | ||
req := mock.DefaultRequest() | ||
req.IsHTTP = true | ||
s.Access("test.model", req). | ||
Response(). | ||
AssertPayload(map[string]interface{}{ | ||
"result": k.ExpectedResult, | ||
"meta": l.ExpectedMeta, | ||
}) | ||
}, restest.WithTest(fmt.Sprintf("%s with %s", k.Name, l.Name))) | ||
} | ||
} | ||
} | ||
|
||
// Test access request with meta data and an error response. | ||
func TestMeta_AccessRequestWithErrorResponse_MetaInResponse(t *testing.T) { | ||
for _, k := range []struct { | ||
Name string | ||
Respond func(r res.AccessRequest) | ||
ExpectedError error | ||
}{ | ||
{Name: "AccessDenied()", Respond: func(r res.AccessRequest) { r.AccessDenied() }, ExpectedError: res.ErrAccessDenied}, | ||
{Name: `Access(false, "")`, Respond: func(r res.AccessRequest) { r.Access(false, "") }, ExpectedError: res.ErrAccessDenied}, | ||
{Name: "CustomError()", Respond: func(r res.AccessRequest) { r.Error(mock.CustomError) }, ExpectedError: mock.CustomError}, | ||
{Name: "NotFound()", Respond: func(r res.AccessRequest) { r.NotFound() }, ExpectedError: res.ErrNotFound}, | ||
{Name: `InvalidQuery("")`, Respond: func(r res.AccessRequest) { r.InvalidQuery("") }, ExpectedError: res.ErrInvalidQuery}, | ||
{Name: `InvalidQuery("foo")`, Respond: func(r res.AccessRequest) { r.InvalidQuery("foo") }, ExpectedError: &res.Error{Code: res.CodeInvalidQuery, Message: "foo"}}, | ||
} { | ||
for _, l := range metaTestTbl { | ||
runTest(t, func(s *res.Service) { | ||
s.Handle("model", res.Access(func(r res.AccessRequest) { | ||
r.SetResponseStatus(l.Status) | ||
for k, v := range l.Header { | ||
r.ResponseHeader()[k] = v | ||
} | ||
k.Respond(r) | ||
})) | ||
}, func(s *restest.Session) { | ||
req := mock.DefaultRequest() | ||
req.IsHTTP = true | ||
s.Access("test.model", req). | ||
Response(). | ||
AssertPayload(map[string]interface{}{ | ||
"error": k.ExpectedError, | ||
"meta": l.ExpectedMeta, | ||
}) | ||
}, restest.WithTest(fmt.Sprintf("%s with %s", k.Name, l.Name))) | ||
} | ||
} | ||
} | ||
|
||
// Test using SetResponseStatus on call request, when IsHTTP is false, causes panic. | ||
func TestMeta_SetResponseStatusWhenIsHTTPIsFalse_Panics(t *testing.T) { | ||
runTest(t, func(s *res.Service) { | ||
s.Handle("model", res.Call("method", func(r res.CallRequest) { | ||
r.SetResponseStatus(402) | ||
r.OK(nil) | ||
})) | ||
}, func(s *restest.Session) { | ||
s.Call("test.model", "method", nil). | ||
Response(). | ||
AssertErrorCode(res.CodeInternalError) | ||
}) | ||
} | ||
|
||
// Test using ResponseHeader on call request, when IsHTTP is false, causes panic. | ||
func TestMeta_ResponseHeaderWhenIsHTTPIsFalse_Panics(t *testing.T) { | ||
runTest(t, func(s *res.Service) { | ||
s.Handle("model", res.Call("method", func(r res.CallRequest) { | ||
_ = r.ResponseHeader() | ||
r.OK(nil) | ||
})) | ||
}, func(s *restest.Session) { | ||
s.Call("test.model", "method", nil). | ||
Response(). | ||
AssertErrorCode(res.CodeInternalError) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters