github.com/openfga/openfga@v1.5.4-rc1/internal/condition/types/types_test.go (about) 1 package types 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/require" 9 ) 10 11 func TestPrimitives(t *testing.T) { 12 var tests = []struct { 13 name string 14 paramType ParameterType 15 input any 16 output any 17 expectedError error 18 repr string 19 }{ 20 { 21 name: "valid_any", 22 paramType: AnyParamType, 23 input: "hello", 24 output: "hello", 25 repr: "any", 26 }, 27 { 28 name: "valid_bool", 29 paramType: BoolParamType, 30 input: true, 31 output: true, 32 repr: "bool", 33 }, 34 { 35 name: "valid_int", 36 paramType: IntParamType, 37 input: int64(10), 38 output: int64(10), 39 repr: "int", 40 }, 41 { 42 name: "invalid_int_to_string", 43 paramType: StringParamType, 44 input: int64(10), 45 output: nil, 46 repr: "string", 47 expectedError: fmt.Errorf( 48 "expected type value 'string', but found 'int64'", 49 ), 50 }, 51 { 52 name: "valid_uint", 53 paramType: UIntParamType, 54 input: uint64(10), 55 output: uint64(10), 56 repr: "uint", 57 }, 58 { 59 name: "valid_double", 60 paramType: DoubleParamType, 61 input: 10.5, 62 output: float64(10.5), 63 repr: "double", 64 }, 65 { 66 name: "valid_double_to_uint", 67 paramType: UIntParamType, 68 input: float64(10.0), 69 output: uint64(10), 70 repr: "uint", 71 }, 72 { 73 name: "valid_double_to_int", 74 paramType: IntParamType, 75 input: float64(10.0), 76 output: int64(10), 77 repr: "int", 78 }, 79 { 80 name: "invalid_double_to_uint", 81 paramType: UIntParamType, 82 input: float64(10.5), 83 output: nil, 84 repr: "uint", 85 expectedError: fmt.Errorf( 86 "expected a uint value, but found numeric value '10.5'", 87 ), 88 }, 89 { 90 name: "invalid_negative_double_to_uint", 91 paramType: UIntParamType, 92 input: float64(-10.5), 93 output: nil, 94 repr: "uint", 95 expectedError: fmt.Errorf( 96 "expected a uint value, but found numeric value '-10.5'", 97 ), 98 }, 99 { 100 name: "invalid_double_to_int", 101 paramType: IntParamType, 102 input: float64(10.5), 103 output: nil, 104 repr: "int", 105 expectedError: fmt.Errorf( 106 "expected an int value, but found numeric value '10.5'", 107 ), 108 }, 109 { 110 name: "valid_string", 111 paramType: StringParamType, 112 input: "hello", 113 output: "hello", 114 repr: "string", 115 }, 116 { 117 name: "valid_string_to_int", 118 paramType: IntParamType, 119 input: "10", 120 output: int64(10), 121 repr: "int", 122 }, 123 { 124 name: "invalid_string_to_bool", 125 paramType: BoolParamType, 126 input: "hello", 127 output: nil, 128 repr: "bool", 129 expectedError: fmt.Errorf( 130 "expected type value 'bool', but found 'string'", 131 ), 132 }, 133 { 134 name: "invalid_string_to_double", 135 paramType: DoubleParamType, 136 input: "invalid", 137 output: nil, 138 repr: "double", 139 expectedError: fmt.Errorf( 140 "expected a float64 value, but found invalid string value 'invalid'", 141 ), 142 }, 143 { 144 name: "valid_duration", 145 paramType: DurationParamType, 146 input: "1h", 147 output: 1 * time.Hour, 148 repr: "duration", 149 }, 150 { 151 name: "invalid_duration", 152 paramType: DurationParamType, 153 input: "2sm", 154 output: nil, 155 repr: "duration", 156 expectedError: fmt.Errorf( 157 "expected a valid duration string, but found: '2sm'", 158 ), 159 }, 160 { 161 name: "valid_timestamp", 162 paramType: TimestampParamType, 163 input: "1972-01-01T10:00:20.021Z", 164 output: time.Date(1972, time.January, 1, 10, 0, 20, 21000000, time.UTC), 165 repr: "timestamp", 166 }, 167 { 168 name: "invalid_timestamp", 169 paramType: TimestampParamType, 170 input: "2023-0914", 171 output: nil, 172 repr: "timestamp", 173 expectedError: fmt.Errorf( 174 "expected RFC 3339 formatted timestamp string, but found '2023-0914'", 175 ), 176 }, 177 { 178 name: "valid_ipaddress", 179 paramType: IPAddressType, 180 input: "127.0.0.1", 181 output: mustParseIPAddress("127.0.0.1"), 182 repr: "ipaddress", 183 }, 184 { 185 name: "invalid_ipaddress", 186 paramType: IPAddressType, 187 input: "invalid", 188 output: nil, 189 repr: "ipaddress", 190 expectedError: fmt.Errorf( 191 "expected a well-formed IP address, but found: 'invalid'", 192 ), 193 }, 194 { 195 name: "valid_map_string", 196 paramType: mustMapParamType(StringParamType), 197 input: map[string]any{"hello": "world"}, 198 output: map[string]any{"hello": "world"}, 199 repr: "TYPE_NAME_MAP<string>", 200 }, 201 { 202 name: "invalid_map", 203 paramType: mustMapParamType(StringParamType), 204 input: map[int]any{123: "world"}, 205 expectedError: fmt.Errorf( 206 "map requires a map, found: map[int]interface {}", 207 ), 208 repr: "TYPE_NAME_MAP<string>", 209 }, 210 { 211 name: "invalid_map_string", 212 paramType: mustMapParamType(StringParamType), 213 input: map[string]any{"hello": 1}, 214 expectedError: fmt.Errorf( 215 "found an invalid value for key 'hello': expected type value 'string', but found 'int'", 216 ), 217 repr: "TYPE_NAME_MAP<string>", 218 }, 219 { 220 name: "valid_list_string", 221 paramType: mustListParamType(StringParamType), 222 input: []any{"hello", "world"}, 223 output: []any{"hello", "world"}, 224 repr: "TYPE_NAME_LIST<string>", 225 }, 226 { 227 name: "invalid_list", 228 paramType: mustListParamType(StringParamType), 229 input: "hello", 230 expectedError: fmt.Errorf( 231 "list requires a list, found: string", 232 ), 233 repr: "TYPE_NAME_LIST<string>", 234 }, 235 { 236 name: "invalid_list_string", 237 paramType: mustListParamType(StringParamType), 238 input: []any{"hello", 1}, 239 expectedError: fmt.Errorf( 240 "found an invalid list item at index `1`: expected type value 'string', but found 'int'", 241 ), 242 repr: "TYPE_NAME_LIST<string>", 243 }, 244 } 245 246 for _, test := range tests { 247 t.Run(test.name, func(t *testing.T) { 248 converted, err := test.paramType.ConvertValue(test.input) 249 250 if test.expectedError != nil { 251 require.Error(t, err) 252 require.EqualError(t, err, test.expectedError.Error()) 253 } else { 254 require.NoError(t, err) 255 } 256 257 require.Equal(t, test.output, converted) 258 require.Equal(t, test.repr, test.paramType.String()) 259 }) 260 } 261 } 262 263 func mustParseIPAddress(ip string) IPAddress { 264 addr, err := ParseIPAddress(ip) 265 if err != nil { 266 panic(err) 267 } 268 269 return addr 270 } 271 272 func mustMapParamType(genericTypes ...ParameterType) ParameterType { 273 paramType, err := MapParamType(genericTypes...) 274 if err != nil { 275 panic(err) 276 } 277 return paramType 278 } 279 280 func mustListParamType(genericTypes ...ParameterType) ParameterType { 281 paramType, err := ListParamType(genericTypes...) 282 if err != nil { 283 panic(err) 284 } 285 return paramType 286 }