Skip to content

Commit

Permalink
Merge pull request tokopedia#141 from pojlter/add_result_code
Browse files Browse the repository at this point in the history
feat: add response code
  • Loading branch information
jekiapp authored Dec 18, 2023
2 parents cc0d60d + a907d3c commit 2d242b4
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 7 deletions.
1 change: 1 addition & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ Stub Format is JSON text format. It has a skeleton as follows:
// put result fields here
},
"error":"<error message>" // Optional. if you want to return error instead.
"code":"<response code>" // Optional. Grpc response code. if code !=0 return error instead.
}
}
```
Expand Down
12 changes: 12 additions & 0 deletions example/simple/client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,16 @@ func main() {
log.Fatalf("error from grpc: %v", err)
}
log.Printf("Greeting: %s (return code %d)", r.Message, r.ReturnCode)
name = "error"
r, err = c.SayHello(context.Background(), &pb.Request{Name: name})
if err == nil {
log.Fatalf("Expected error, but return %d", r.ReturnCode)
}
log.Printf("Greeting error: %s", err)
name = "error_code"
r, err = c.SayHello(context.Background(), &pb.Request{Name: name})
if err == nil {
log.Fatalf("Expected error, but return %d", r.ReturnCode)
}
log.Printf("Greeting error: %s", err)
}
25 changes: 25 additions & 0 deletions example/simple/stub/simple.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,30 @@
"return_code": 1
}
}
},
{
"service": "Gripmock",
"method": "SayHello",
"input": {
"equals": {
"name": "error"
}
},
"output": {
"error": "test_error"
}
},
{
"service": "Gripmock",
"method": "SayHello",
"input": {
"equals": {
"name": "error_code"
}
},
"output": {
"error": "test_error_code",
"code": 3
}
}
]
13 changes: 11 additions & 2 deletions protoc-gen-gripmock/server.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"github.com/golang/protobuf/jsonpb"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/grpc/reflection"
"google.golang.org/protobuf/runtime/protoiface"
)
Expand Down Expand Up @@ -144,6 +146,7 @@ type payload struct {
type response struct {
Data interface{} `json:"data"`
Error string `json:"error"`
Code *codes.Code `json:"code,omitempty"`
}

func findStub(service, method string, in, out protoiface.MessageV1) error {
Expand Down Expand Up @@ -174,8 +177,14 @@ func findStub(service, method string, in, out protoiface.MessageV1) error {
return fmt.Errorf("decoding json response %v",err)
}

if respRPC.Error != "" {
return fmt.Errorf(respRPC.Error)
if respRPC.Error != "" || respRPC.Code != nil {
if respRPC.Code == nil {
abortedCode := codes.Aborted
respRPC.Code = &abortedCode
}
if *respRPC.Code != codes.OK {
return status.Error(*respRPC.Code, respRPC.Error)
}
}

data, _ := json.Marshal(respRPC.Data)
Expand Down
12 changes: 7 additions & 5 deletions stub/stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package stub
import (
"encoding/json"
"fmt"
"google.golang.org/grpc/codes"
"io/ioutil"
"log"
"net/http"
"strings"

"github.com/go-chi/chi"
)

Expand Down Expand Up @@ -62,6 +63,7 @@ type Input struct {
type Output struct {
Data map[string]interface{} `json:"data"`
Error string `json:"error"`
Code *codes.Code `json:"code,omitempty"`
}

func addStub(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -106,7 +108,7 @@ func validateStub(stub *Stub) error {
if stub.Method == "" {
return fmt.Errorf("Method name can't be emtpy")
}

// due to golang implementation
// method name must capital
stub.Method = strings.Title(stub.Method)
Expand All @@ -124,7 +126,7 @@ func validateStub(stub *Stub) error {

// TODO: validate all input case

if stub.Output.Error == "" && stub.Output.Data == nil {
if stub.Output.Error == "" && stub.Output.Data == nil && stub.Output.Code == nil {
return fmt.Errorf("Output can't be empty")
}
return nil
Expand All @@ -143,11 +145,11 @@ func handleFindStub(w http.ResponseWriter, r *http.Request) {
responseError(err, w)
return
}

// due to golang implementation
// method name must capital
stub.Method = strings.Title(stub.Method)

output, err := findStub(stub)
if err != nil {
log.Println(err)
Expand Down
96 changes: 96 additions & 0 deletions stub/stub_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,102 @@ func TestStub(t *testing.T) {
handler: addStub,
expect: `Success add stub`,
},
{
name: "add error stub with result code contains",
mock: func() *http.Request {
payload := `{
"service": "ErrorStabWithCode",
"method":"TestMethod",
"input":{
"contains":{
"key": "value",
"greetings": {
"hola": "mundo",
"merhaba": "dunya"
},
"cities": ["Istanbul", "Jakarta"]
}
},
"output":{
"error":"error msg",
"code": 3
}
}`
return httptest.NewRequest("POST", "/add", bytes.NewReader([]byte(payload)))
},
handler: addStub,
expect: `Success add stub`,
},
{
name: "find error stub with result code contains",
mock: func() *http.Request {
payload := `{
"service": "ErrorStabWithCode",
"method":"TestMethod",
"data":{
"key": "value",
"anotherKey": "anotherValue",
"greetings": {
"hola": "mundo",
"merhaba": "dunya",
"hello": "world"
},
"cities": ["Istanbul", "Jakarta", "Winterfell"]
}
}`
return httptest.NewRequest("GET", "/find", bytes.NewReader([]byte(payload)))
},
handler: handleFindStub,
expect: "{\"data\":null,\"error\":\"error msg\",\"code\":3}\n",
},

{
name: "add error stub without result code contains",
mock: func() *http.Request {
payload := `{
"service": "ErrorStab",
"method":"TestMethod",
"input":{
"contains":{
"key": "value",
"greetings": {
"hola": "mundo",
"merhaba": "dunya"
},
"cities": ["Istanbul", "Jakarta"]
}
},
"output":{
"error":"error msg"
}
}`
return httptest.NewRequest("POST", "/add", bytes.NewReader([]byte(payload)))
},
handler: addStub,
expect: `Success add stub`,
},
{
name: "find error stub without result code contains",
mock: func() *http.Request {
payload := `{
"service": "ErrorStab",
"method":"TestMethod",
"data":{
"key": "value",
"anotherKey": "anotherValue",
"greetings": {
"hola": "mundo",
"merhaba": "dunya",
"hello": "world"
},
"cities": ["Istanbul", "Jakarta", "Winterfell"]
}
}`
return httptest.NewRequest("GET", "/find", bytes.NewReader([]byte(payload)))
},
handler: handleFindStub,
expect: "{\"data\":null,\"error\":\"error msg\"}\n",
},
{
name: "find nested stub contains",
mock: func() *http.Request {
Expand Down

0 comments on commit 2d242b4

Please sign in to comment.