github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/api/api_test.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); 2 // you may not use this file except in compliance with the License. 3 // You may obtain a copy of the License at 4 // 5 // https://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, 9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 // See the License for the specific language governing permissions and 11 // limitations under the License. 12 // 13 // Original source: github.com/micro/go-micro/v3/api/api_test.go 14 15 package api_test 16 17 import ( 18 "bytes" 19 "encoding/json" 20 "net/http" 21 "strings" 22 "testing" 23 24 "github.com/golang/protobuf/proto" 25 go_api "github.com/tickoalcantara12/micro/v3/proto/api" 26 "github.com/tickoalcantara12/micro/v3/service/api" 27 ) 28 29 func TestEncoding(t *testing.T) { 30 testData := []*api.Endpoint{ 31 nil, 32 { 33 Name: "Foo.Bar", 34 Description: "A test endpoint", 35 Handler: "meta", 36 Host: []string{"foo.com"}, 37 Method: []string{"GET"}, 38 Path: []string{"/test"}, 39 }, 40 } 41 42 compare := func(expect, got []string) bool { 43 // no data to compare, return true 44 if len(expect) == 0 && len(got) == 0 { 45 return true 46 } 47 // no data expected but got some return false 48 if len(expect) == 0 && len(got) > 0 { 49 return false 50 } 51 52 // compare expected with what we got 53 for _, e := range expect { 54 var seen bool 55 for _, g := range got { 56 if e == g { 57 seen = true 58 break 59 } 60 } 61 if !seen { 62 return false 63 } 64 } 65 66 // we're done, return true 67 return true 68 } 69 70 for _, d := range testData { 71 // encode 72 e := api.Encode(d) 73 // decode 74 de := api.Decode(e) 75 76 // nil endpoint returns nil 77 if d == nil { 78 if e != nil { 79 t.Fatalf("expected nil got %v", e) 80 } 81 if de != nil { 82 t.Fatalf("expected nil got %v", de) 83 } 84 85 continue 86 } 87 88 // check encoded map 89 name := e["endpoint"] 90 desc := e["description"] 91 method := strings.Split(e["method"], ",") 92 path := strings.Split(e["path"], ",") 93 host := strings.Split(e["host"], ",") 94 handler := e["handler"] 95 96 if name != d.Name { 97 t.Fatalf("expected %v got %v", d.Name, name) 98 } 99 if desc != d.Description { 100 t.Fatalf("expected %v got %v", d.Description, desc) 101 } 102 if handler != d.Handler { 103 t.Fatalf("expected %v got %v", d.Handler, handler) 104 } 105 if ok := compare(d.Method, method); !ok { 106 t.Fatalf("expected %v got %v", d.Method, method) 107 } 108 if ok := compare(d.Path, path); !ok { 109 t.Fatalf("expected %v got %v", d.Path, path) 110 } 111 if ok := compare(d.Host, host); !ok { 112 t.Fatalf("expected %v got %v", d.Host, host) 113 } 114 115 if de.Name != d.Name { 116 t.Fatalf("expected %v got %v", d.Name, de.Name) 117 } 118 if de.Description != d.Description { 119 t.Fatalf("expected %v got %v", d.Description, de.Description) 120 } 121 if de.Handler != d.Handler { 122 t.Fatalf("expected %v got %v", d.Handler, de.Handler) 123 } 124 if ok := compare(d.Method, de.Method); !ok { 125 t.Fatalf("expected %v got %v", d.Method, de.Method) 126 } 127 if ok := compare(d.Path, de.Path); !ok { 128 t.Fatalf("expected %v got %v", d.Path, de.Path) 129 } 130 if ok := compare(d.Host, de.Host); !ok { 131 t.Fatalf("expected %v got %v", d.Host, de.Host) 132 } 133 } 134 } 135 136 func TestValidate(t *testing.T) { 137 epPcre := &api.Endpoint{ 138 Name: "Foo.Bar", 139 Description: "A test endpoint", 140 Handler: "meta", 141 Host: []string{"foo.com"}, 142 Method: []string{"GET"}, 143 Path: []string{"^/test/?$"}, 144 } 145 if err := api.Validate(epPcre); err != nil { 146 t.Fatal(err) 147 } 148 149 epGpath := &api.Endpoint{ 150 Name: "Foo.Bar", 151 Description: "A test endpoint", 152 Handler: "meta", 153 Host: []string{"foo.com"}, 154 Method: []string{"GET"}, 155 Path: []string{"/test/{id}"}, 156 } 157 if err := api.Validate(epGpath); err != nil { 158 t.Fatal(err) 159 } 160 161 epPcreInvalid := &api.Endpoint{ 162 Name: "Foo.Bar", 163 Description: "A test endpoint", 164 Handler: "meta", 165 Host: []string{"foo.com"}, 166 Method: []string{"GET"}, 167 Path: []string{"/test/?$"}, 168 } 169 if err := api.Validate(epPcreInvalid); err == nil { 170 t.Fatalf("invalid pcre %v", epPcreInvalid.Path[0]) 171 } 172 173 } 174 175 func TestRequestPayloadFromRequest(t *testing.T) { 176 177 // our test event so that we can validate serialising / deserializing of true protos works 178 protoEvent := go_api.Event{ 179 Name: "Test", 180 } 181 182 protoBytes, err := proto.Marshal(&protoEvent) 183 if err != nil { 184 t.Fatal("Failed to marshal proto", err) 185 } 186 187 jsonBytes, err := json.Marshal(protoEvent) 188 if err != nil { 189 t.Fatal("Failed to marshal proto to JSON ", err) 190 } 191 192 jsonUrlBytes := []byte(`{"key1":"val1","key2":"val2","name":"Test"}`) 193 194 t.Run("extracting a json from a POST request with url params", func(t *testing.T) { 195 r, err := http.NewRequest("POST", "http://localhost/my/path?key1=val1&key2=val2", bytes.NewReader(jsonBytes)) 196 if err != nil { 197 t.Fatalf("Failed to created http.Request: %v", err) 198 } 199 200 extByte, err := api.RequestPayload(r) 201 if err != nil { 202 t.Fatalf("Failed to extract payload from request: %v", err) 203 } 204 if string(extByte) != string(jsonUrlBytes) { 205 t.Fatalf("Expected %v and %v to match", string(extByte), jsonUrlBytes) 206 } 207 }) 208 209 t.Run("extracting a proto from a POST request", func(t *testing.T) { 210 r, err := http.NewRequest("POST", "http://localhost/my/path", bytes.NewReader(protoBytes)) 211 if err != nil { 212 t.Fatalf("Failed to created http.Request: %v", err) 213 } 214 215 extByte, err := api.RequestPayload(r) 216 if err != nil { 217 t.Fatalf("Failed to extract payload from request: %v", err) 218 } 219 if string(extByte) != string(protoBytes) { 220 t.Fatalf("Expected %v and %v to match", string(extByte), string(protoBytes)) 221 } 222 }) 223 224 t.Run("extracting JSON from a POST request", func(t *testing.T) { 225 r, err := http.NewRequest("POST", "http://localhost/my/path", bytes.NewReader(jsonBytes)) 226 if err != nil { 227 t.Fatalf("Failed to created http.Request: %v", err) 228 } 229 230 extByte, err := api.RequestPayload(r) 231 if err != nil { 232 t.Fatalf("Failed to extract payload from request: %v", err) 233 } 234 if string(extByte) != string(jsonBytes) { 235 t.Fatalf("Expected %v and %v to match", string(extByte), string(jsonBytes)) 236 } 237 }) 238 239 t.Run("extracting params from a GET request", func(t *testing.T) { 240 241 r, err := http.NewRequest("GET", "http://localhost/my/path", nil) 242 if err != nil { 243 t.Fatalf("Failed to created http.Request: %v", err) 244 } 245 246 q := r.URL.Query() 247 q.Add("name", "Test") 248 r.URL.RawQuery = q.Encode() 249 250 extByte, err := api.RequestPayload(r) 251 if err != nil { 252 t.Fatalf("Failed to extract payload from request: %v", err) 253 } 254 if string(extByte) != string(jsonBytes) { 255 t.Fatalf("Expected %v and %v to match", string(extByte), string(jsonBytes)) 256 } 257 }) 258 259 t.Run("GET request with no params", func(t *testing.T) { 260 261 r, err := http.NewRequest("GET", "http://localhost/my/path", nil) 262 if err != nil { 263 t.Fatalf("Failed to created http.Request: %v", err) 264 } 265 266 extByte, err := api.RequestPayload(r) 267 if err != nil { 268 t.Fatalf("Failed to extract payload from request: %v", err) 269 } 270 if string(extByte) != "" { 271 t.Fatalf("Expected %v and %v to match", string(extByte), "") 272 } 273 }) 274 }