go.uber.org/yarpc@v1.72.1/api/transport/header_test.go (about) 1 // Copyright (c) 2022 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package transport 22 23 import ( 24 "testing" 25 26 "github.com/stretchr/testify/assert" 27 ) 28 29 func TestNewHeaders(t *testing.T) { 30 tests := []struct { 31 headers map[string]string 32 matches map[string]string 33 failures []string 34 }{ 35 { 36 nil, 37 map[string]string{}, 38 []string{"foo"}, 39 }, 40 { 41 map[string]string{ 42 "Foo": "Bar", 43 "Baz": "qux", 44 }, 45 map[string]string{ 46 "foo": "Bar", 47 "Foo": "Bar", 48 "FOO": "Bar", 49 "baz": "qux", 50 "Baz": "qux", 51 "BaZ": "qux", 52 }, 53 []string{"bar"}, 54 }, 55 { 56 map[string]string{ 57 "foo": "bar", 58 "baz": "", 59 }, 60 map[string]string{ 61 "foo": "bar", 62 "baz": "", 63 "Baz": "", 64 }, 65 []string{"qux"}, 66 }, 67 } 68 69 for _, tt := range tests { 70 headers := HeadersFromMap(tt.headers) 71 for k, v := range tt.matches { 72 vg, ok := headers.Get(k) 73 assert.True(t, ok, "expected true for %q", k) 74 assert.Equal(t, v, vg, "value mismatch for %q", k) 75 } 76 for _, k := range tt.failures { 77 v, ok := headers.Get(k) 78 assert.False(t, ok, "expected false for %q", k) 79 assert.Equal(t, "", v, "expected empty string for %q", k) 80 } 81 } 82 } 83 84 func TestItemsAndOriginalItems(t *testing.T) { 85 type headers struct { 86 key, val string 87 } 88 tests := []struct { 89 msg string 90 toDeleteKey string 91 headers []headers 92 preDeletionItems map[string]string 93 postDeletionItems map[string]string 94 preDeletionOriginalItems map[string]string 95 postDeletionOriginalItems map[string]string 96 }{ 97 { 98 msg: "delete lowercase/canonical key", 99 toDeleteKey: "other-header", 100 headers: []headers{ 101 {"foo-BAR-BaZ", "foo-bar-baz"}, 102 {"Foo-bAr-baZ", "FOO-BAR-BAZ"}, 103 {"other-header", "other-value"}, 104 }, 105 preDeletionItems: map[string]string{ 106 "foo-bar-baz": "FOO-BAR-BAZ", 107 "other-header": "other-value", 108 }, 109 postDeletionItems: map[string]string{ 110 "foo-bar-baz": "FOO-BAR-BAZ", 111 }, 112 preDeletionOriginalItems: map[string]string{ 113 "foo-BAR-BaZ": "foo-bar-baz", 114 "Foo-bAr-baZ": "FOO-BAR-BAZ", 115 "other-header": "other-value", 116 }, 117 postDeletionOriginalItems: map[string]string{ 118 "foo-BAR-BaZ": "foo-bar-baz", 119 "Foo-bAr-baZ": "FOO-BAR-BAZ", 120 }, 121 }, 122 { 123 msg: "delete non-canonical key that does not exist in originalItem", 124 toDeleteKey: "fOo-BAR-Baz", 125 headers: []headers{ 126 {"foo-BAR-BaZ", "foo-bar-baz"}, 127 {"Foo-bAr-baZ", "FOO-BAR-BAZ"}, 128 {"other-header", "other-value"}, 129 }, 130 preDeletionItems: map[string]string{ 131 "foo-bar-baz": "FOO-BAR-BAZ", 132 "other-header": "other-value", 133 }, 134 postDeletionItems: map[string]string{ 135 "other-header": "other-value", 136 }, 137 preDeletionOriginalItems: map[string]string{ 138 "foo-BAR-BaZ": "foo-bar-baz", 139 "Foo-bAr-baZ": "FOO-BAR-BAZ", 140 "other-header": "other-value", 141 }, 142 postDeletionOriginalItems: map[string]string{ 143 "foo-BAR-BaZ": "foo-bar-baz", 144 "Foo-bAr-baZ": "FOO-BAR-BAZ", 145 "other-header": "other-value", 146 }, 147 }, 148 { 149 msg: "delete non-canonical key that also exists in originalItem", 150 toDeleteKey: "foo-BAR-BaZ", 151 headers: []headers{ 152 {"foo-BAR-BaZ", "foo-bar-baz"}, 153 {"Foo-bAr-baZ", "FOO-BAR-BAZ"}, 154 {"other-header", "other-value"}, 155 }, 156 preDeletionItems: map[string]string{ 157 "foo-bar-baz": "FOO-BAR-BAZ", 158 "other-header": "other-value", 159 }, 160 postDeletionItems: map[string]string{ 161 "other-header": "other-value", 162 }, 163 preDeletionOriginalItems: map[string]string{ 164 "foo-BAR-BaZ": "foo-bar-baz", 165 "Foo-bAr-baZ": "FOO-BAR-BAZ", 166 "other-header": "other-value", 167 }, 168 postDeletionOriginalItems: map[string]string{ 169 "Foo-bAr-baZ": "FOO-BAR-BAZ", 170 "other-header": "other-value", 171 }, 172 }, 173 } 174 175 for _, tt := range tests { 176 t.Run(tt.msg, func(t *testing.T) { 177 header := NewHeaders() 178 for _, v := range tt.headers { 179 header = header.With(v.key, v.val) 180 } 181 182 assert.Equal(t, tt.preDeletionItems, header.Items()) 183 assert.Equal(t, tt.preDeletionOriginalItems, header.OriginalItems()) 184 185 header.Del(tt.toDeleteKey) 186 assert.Equal(t, tt.postDeletionItems, header.Items()) 187 assert.Equal(t, tt.postDeletionOriginalItems, header.OriginalItems()) 188 }) 189 } 190 }