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  }