package protocol import ( "bytes" "encoding/json" "io" "io/ioutil" "net/http" "net/url" "testing" "github.com/fnproject/fn/api/models" ) type RequestData struct { A string `json:"a"` } func setupRequest(data interface{}) *callInfoImpl { req := &http.Request{ Method: http.MethodPost, URL: &url.URL{ Scheme: "http", Host: "localhost:8080", Path: "/v1/apps", RawQuery: "something=something&etc=etc", }, ProtoMajor: 1, ProtoMinor: 1, Header: http.Header{ "Host": []string{"localhost:8080"}, "User-Agent": []string{"curl/7.51.0"}, "Content-Type": []string{"application/json"}, }, Host: "localhost:8080", } var buf bytes.Buffer if data != nil { _ = json.NewEncoder(&buf).Encode(data) } req.Body = ioutil.NopCloser(&buf) call := &models.Call{Type: "sync"} // fixup URL in models.Call call.URL = req.URL.String() ci := &callInfoImpl{call, req} return ci } func TestJSONProtocolwriteJSONInputRequestBasicFields(t *testing.T) { ci := setupRequest(nil) r, w := io.Pipe() proto := JSONProtocol{w, r} go func() { err := proto.writeJSONToContainer(ci) if err != nil { t.Error(err.Error()) } w.Close() }() incomingReq := &jsonIn{} bb := new(bytes.Buffer) _, err := bb.ReadFrom(r) if err != nil { t.Error(err.Error()) } err = json.Unmarshal(bb.Bytes(), incomingReq) if err != nil { t.Error(err.Error()) } if incomingReq.CallID != ci.CallID() { t.Errorf("Request CallID assertion mismatch: expected: %s, got %s", ci.CallID(), incomingReq.CallID) } if incomingReq.ContentType != ci.ContentType() { t.Errorf("Request ContentType assertion mismatch: expected: %s, got %s", ci.ContentType(), incomingReq.ContentType) } if incomingReq.Type != ci.CallType() { t.Errorf("Request CallType assertion mismatch: expected: %s, got %s", ci.CallType(), incomingReq.Type) } if incomingReq.Deadline != ci.Deadline().String() { t.Errorf("Request Deadline assertion mismatch: expected: %s, got %s", ci.Deadline(), incomingReq.Deadline) } } func TestJSONProtocolwriteJSONInputRequestWithData(t *testing.T) { rDataBefore := RequestData{A: "a"} ci := setupRequest(rDataBefore) r, w := io.Pipe() proto := JSONProtocol{w, r} go func() { err := proto.writeJSONToContainer(ci) if err != nil { t.Error(err.Error()) } w.Close() }() incomingReq := &jsonIn{} bb := new(bytes.Buffer) _, err := bb.ReadFrom(r) if err != nil { t.Error(err.Error()) } err = json.Unmarshal(bb.Bytes(), incomingReq) if err != nil { t.Error(err.Error()) } rDataAfter := new(RequestData) err = json.Unmarshal([]byte(incomingReq.Body), &rDataAfter) if err != nil { t.Error(err.Error()) } if rDataBefore.A != rDataAfter.A { t.Errorf("Request data assertion mismatch: expected: %s, got %s", rDataBefore.A, rDataAfter.A) } if incomingReq.Protocol.Type != ci.ProtocolType() { t.Errorf("Call protocol type assertion mismatch: expected: %s, got %s", ci.ProtocolType(), incomingReq.Protocol.Type) } if incomingReq.Protocol.Method != ci.Method() { t.Errorf("Call protocol method assertion mismatch: expected: %s, got %s", ci.Method(), incomingReq.Protocol.Method) } if incomingReq.Protocol.RequestURL != ci.RequestURL() { t.Errorf("Call protocol request URL assertion mismatch: expected: %s, got %s", ci.RequestURL(), incomingReq.Protocol.RequestURL) } } func TestJSONProtocolwriteJSONInputRequestWithoutData(t *testing.T) { ci := setupRequest(nil) r, w := io.Pipe() proto := JSONProtocol{w, r} go func() { err := proto.writeJSONToContainer(ci) if err != nil { t.Error(err.Error()) } w.Close() }() incomingReq := &jsonIn{} bb := new(bytes.Buffer) _, err := bb.ReadFrom(r) if err != nil { t.Error(err.Error()) } err = json.Unmarshal(bb.Bytes(), incomingReq) if err != nil { t.Error(err.Error()) } if incomingReq.Body != "" { t.Errorf("Request body assertion mismatch: expected: %s, got %s", "", incomingReq.Body) } if !models.Headers(ci.req.Header).Equals(models.Headers(incomingReq.Protocol.Headers)) { t.Errorf("Request headers assertion mismatch: expected: %s, got %s", ci.req.Header, incomingReq.Protocol.Headers) } if incomingReq.Protocol.Type != ci.ProtocolType() { t.Errorf("Call protocol type assertion mismatch: expected: %s, got %s", ci.ProtocolType(), incomingReq.Protocol.Type) } if incomingReq.Protocol.Method != ci.Method() { t.Errorf("Call protocol method assertion mismatch: expected: %s, got %s", ci.Method(), incomingReq.Protocol.Method) } if incomingReq.Protocol.RequestURL != ci.RequestURL() { t.Errorf("Call protocol request URL assertion mismatch: expected: %s, got %s", ci.RequestURL(), incomingReq.Protocol.RequestURL) } } func TestJSONProtocolwriteJSONInputRequestWithQuery(t *testing.T) { ci := setupRequest(nil) r, w := io.Pipe() proto := JSONProtocol{w, r} go func() { err := proto.writeJSONToContainer(ci) if err != nil { t.Error(err.Error()) } w.Close() }() incomingReq := &jsonIn{} bb := new(bytes.Buffer) _, err := bb.ReadFrom(r) if err != nil { t.Error(err.Error()) } err = json.Unmarshal(bb.Bytes(), incomingReq) if err != nil { t.Error(err.Error()) } if incomingReq.Protocol.RequestURL != ci.call.URL { t.Errorf("Request URL does not match protocol URL: expected: %s, got %s", ci.call.URL, incomingReq.Protocol.RequestURL) } }