cuelang.org/go@v0.10.1/pkg/tool/http/http_test.go (about) 1 // Copyright 2020 CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package http 16 17 import ( 18 "encoding/pem" 19 "fmt" 20 "net/http" 21 "net/http/httptest" 22 "strings" 23 "testing" 24 25 "cuelang.org/go/cue" 26 "cuelang.org/go/cue/parser" 27 "cuelang.org/go/internal/task" 28 "cuelang.org/go/internal/value" 29 "cuelang.org/go/pkg/internal" 30 ) 31 32 func newTLSServer() *httptest.Server { 33 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 34 resp := `{"foo": "bar"}` 35 w.Write([]byte(resp)) 36 })) 37 return server 38 } 39 40 func parse(t *testing.T, kind, expr string) cue.Value { 41 t.Helper() 42 43 x, err := parser.ParseExpr("test", expr) 44 if err != nil { 45 t.Fatal(err) 46 } 47 v := internal.NewContext().BuildExpr(x) 48 if err := v.Err(); err != nil { 49 t.Fatal(err) 50 } 51 return value.UnifyBuiltin(v, kind) 52 } 53 54 func TestTLS(t *testing.T) { 55 s := newTLSServer() 56 t.Cleanup(s.Close) 57 58 v1 := parse(t, "tool/http.Get", fmt.Sprintf(`{url: "%s"}`, s.URL)) 59 _, err := (*httpCmd).Run(nil, &task.Context{Obj: v1}) 60 if err == nil { 61 t.Fatal("http call should have failed") 62 } 63 64 v2 := parse(t, "tool/http.Get", fmt.Sprintf(`{url: "%s", tls: verify: false}`, s.URL)) 65 _, err = (*httpCmd).Run(nil, &task.Context{Obj: v2}) 66 if err != nil { 67 t.Fatal(err) 68 } 69 70 publicKeyBlock := pem.Block{ 71 Type: "PUBLIC KEY", 72 Bytes: s.Certificate().Raw, 73 } 74 publicKeyPem := pem.EncodeToMemory(&publicKeyBlock) 75 76 v3 := parse(t, "tool/http.Get", fmt.Sprintf(` 77 { 78 url: "%s" 79 tls: caCert: ''' 80 %s 81 ''' 82 }`, s.URL, publicKeyPem)) 83 84 _, err = (*httpCmd).Run(nil, &task.Context{Obj: v3}) 85 if err != nil { 86 t.Fatal(err) 87 } 88 } 89 90 func TestParseHeaders(t *testing.T) { 91 req := ` 92 header: { 93 "Accept-Language": "en,nl" 94 } 95 trailer: { 96 "Accept-Language": "en,nl" 97 User: "foo" 98 } 99 ` 100 testCases := []struct { 101 req string 102 field string 103 out string 104 }{{ 105 field: "header", 106 out: "nil", 107 }, { 108 req: req, 109 field: "non-exist", 110 out: "nil", 111 }, { 112 req: req, 113 field: "header", 114 out: "Accept-Language: en,nl\r\n", 115 }, { 116 req: req, 117 field: "trailer", 118 out: "Accept-Language: en,nl\r\nUser: foo\r\n", 119 }, { 120 req: ` 121 header: { 122 "1": 'a' 123 } 124 `, 125 field: "header", 126 out: "header.\"1\": cannot use value 'a' (type bytes) as string", 127 }, { 128 req: ` 129 header: 1 130 `, 131 field: "header", 132 out: "header: cannot use value 1 (type int) as struct", 133 }} 134 for _, tc := range testCases { 135 t.Run("", func(t *testing.T) { 136 ctx := internal.NewContext() 137 v := ctx.CompileString(tc.req, cue.Filename("http headers")) 138 if err := v.Err(); err != nil { 139 t.Fatal(err) 140 } 141 142 h, err := parseHeaders(v, tc.field) 143 144 b := &strings.Builder{} 145 switch { 146 case err != nil: 147 fmt.Fprint(b, err) 148 case h == nil: 149 b.WriteString("nil") 150 default: 151 _ = h.Write(b) 152 } 153 154 got := b.String() 155 if got != tc.out { 156 t.Errorf("got %q; want %q", got, tc.out) 157 } 158 }) 159 } 160 }