go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/grpc/prpc/accepts_test.go (about) 1 // Copyright 2016 The LUCI 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 prpc 16 17 import ( 18 "net/http" 19 "testing" 20 21 . "github.com/smartystreets/goconvey/convey" 22 . "go.chromium.org/luci/common/testing/assertions" 23 ) 24 25 func TestAccept(t *testing.T) { 26 t.Parallel() 27 28 Convey("parseAccept", t, func() { 29 test := func(value string, expectedErr any, expectedTypes ...acceptItem) { 30 Convey("mediaType="+value, func() { 31 actual, err := parseAccept(value) 32 So(err, ShouldErrLike, expectedErr) 33 So(actual, ShouldResemble, accept(expectedTypes)) 34 }) 35 } 36 test("", nil) 37 qf1 := func(value string) acceptItem { 38 return acceptItem{ 39 Value: value, 40 QualityFactor: 1.0, 41 } 42 } 43 44 test("text/html", nil, 45 qf1("text/html"), 46 ) 47 48 test("text/html; level=1", nil, 49 qf1("text/html; level=1"), 50 ) 51 test("TEXT/HTML; LEVEL=1", nil, 52 qf1("TEXT/HTML; LEVEL=1"), 53 ) 54 55 test("text/html, application/json", nil, 56 qf1("text/html"), 57 qf1("application/json"), 58 ) 59 60 test("text/html; level=1, application/json", nil, 61 qf1("text/html; level=1"), 62 qf1("application/json"), 63 ) 64 65 test("text/html; level=1, application/json; foo=bar", nil, 66 qf1("text/html; level=1"), 67 qf1("application/json; foo=bar"), 68 ) 69 70 test("text/html; level=1; q=0.5", nil, 71 acceptItem{ 72 Value: "text/html; level=1", 73 QualityFactor: 0.5, 74 }, 75 ) 76 test("text/html; level=1; q=0.5; a=1", nil, 77 acceptItem{ 78 Value: "text/html; level=1", 79 QualityFactor: 0.5, 80 }, 81 ) 82 test("TEXT/HTML; LEVEL=1; Q=0.5", nil, 83 acceptItem{ 84 Value: "TEXT/HTML; LEVEL=1", 85 QualityFactor: 0.5, 86 }, 87 ) 88 test("text/html; level=1; q=0.5, application/json", nil, 89 acceptItem{ 90 Value: "text/html; level=1", 91 QualityFactor: 0.5, 92 }, 93 qf1("application/json"), 94 ) 95 test("text/html; level=1; q=0.5, application/json; a=b", nil, 96 acceptItem{ 97 Value: "text/html; level=1", 98 QualityFactor: 0.5, 99 }, 100 qf1("application/json; a=b"), 101 ) 102 test("text/html; level=1; q=0.5, */*; q=0.1", nil, 103 acceptItem{ 104 Value: "text/html; level=1", 105 QualityFactor: 0.5, 106 }, 107 acceptItem{ 108 Value: "*/*", 109 QualityFactor: 0.1, 110 }, 111 ) 112 test("text/html; level=1; q=0.5, */*; x=3;q=0.1; y=5", nil, 113 acceptItem{ 114 Value: "text/html; level=1", 115 QualityFactor: 0.5, 116 }, 117 acceptItem{ 118 Value: "*/*; x=3", 119 QualityFactor: 0.1, 120 }, 121 ) 122 test("text/html;q=q", "q parameter: expected a floating-point number") 123 }) 124 125 Convey("qParamSplit", t, func() { 126 test := func(item, mediaType, qValue string) { 127 Convey(item, func() { 128 actualMediaType, actualQValue := qParamSplit(item) 129 So(actualMediaType, ShouldEqual, mediaType) 130 So(actualQValue, ShouldEqual, qValue) 131 }) 132 } 133 134 test("", "", "") 135 test("a/b", "a/b", "") 136 137 test("a/b;mtp1=1", "a/b;mtp1=1", "") 138 test("a/b;q=1", "a/b", "1") 139 test("a/b; q=1", "a/b", "1") 140 test("a/b;mtp1=1;q=1", "a/b;mtp1=1", "1") 141 test("a/b;mtp1=1;q=1;", "a/b;mtp1=1", "1") 142 test("a/b;mtp1=1; q=1", "a/b;mtp1=1", "1") 143 test("a/b;mtp1=1;q =1", "a/b;mtp1=1", "1") 144 test("a/b;mtp1=1;q =1", "a/b;mtp1=1", "1") 145 test("a/b;mtp1=1;q= 1", "a/b;mtp1=1", "1") 146 test("a/b;mtp1=1;q=1 ", "a/b;mtp1=1", "1") 147 148 test("a/b;mtp1=1;Q=1", "a/b;mtp1=1", "1") 149 150 test("a/b;mtp1=1;q=1.0", "a/b;mtp1=1", "1.0") 151 test("a/b;mtp1=1;q=1.0;", "a/b;mtp1=1", "1.0") 152 153 test("a/b;mtp1=1; q = foo", "a/b;mtp1=1", "foo") 154 155 test("a/b;c=q", "a/b;c=q", "") 156 test("a/b;mtp1=1; q", "a/b;mtp1=1; q", "") 157 test("a/b;mtp1=1; q=", "a/b;mtp1=1; q=", "") 158 }) 159 } 160 161 func TestAcceptContentEncoding(t *testing.T) { 162 t.Parallel() 163 Convey("Accept-Encoding", t, func() { 164 h := http.Header{} 165 Convey(`Empty`, func() { 166 ok, err := acceptsGZipResponse(h) 167 So(err, ShouldBeNil) 168 So(ok, ShouldBeFalse) 169 }) 170 171 Convey(`gzip`, func() { 172 h.Set("Accept-Encoding", "gzip") 173 ok, err := acceptsGZipResponse(h) 174 So(err, ShouldBeNil) 175 So(ok, ShouldBeTrue) 176 }) 177 178 Convey(`multiple values`, func() { 179 h.Add("Accept-Encoding", "gzip, deflate, br") 180 ok, err := acceptsGZipResponse(h) 181 So(err, ShouldBeNil) 182 So(ok, ShouldBeTrue) 183 }) 184 185 Convey(`invalid input`, func() { 186 h.Add("Accept-Encoding", "gzip; q=a, deflate, br") 187 _, err := acceptsGZipResponse(h) 188 So(err, ShouldErrLike, "q parameter: expected a floating-point number") 189 }) 190 }) 191 }