1package xmpp 2 3import ( 4 "encoding/base64" 5 "encoding/xml" 6 "errors" 7 8 "github.com/coyim/coyim/xmpp/data" 9 10 . "gopkg.in/check.v1" 11) 12 13type FormsXMPPSuite struct{} 14 15var _ = Suite(&FormsXMPPSuite{}) 16 17func (s *FormsXMPPSuite) Test_processForm_returnsErrorFromCallback(c *C) { 18 e := errors.New("some kind of error") 19 f := &data.Form{} 20 _, err := processForm(f, nil, func(title, instructions string, fields []interface{}) error { 21 c.Assert(len(fields), Equals, 0) 22 return e 23 }) 24 25 c.Assert(err, Equals, e) 26} 27 28func (s *FormsXMPPSuite) Test_processForm_returnsEmptySubmitFormForEmptyForm(c *C) { 29 f := &data.Form{} 30 f2, err := processForm(f, nil, func(title, instructions string, fields []interface{}) error { 31 c.Assert(len(fields), Equals, 0) 32 return nil 33 }) 34 35 c.Assert(err, IsNil) 36 c.Assert(*f2, DeepEquals, data.Form{Type: "submit"}) 37} 38 39func (s *FormsXMPPSuite) Test_processForm_processButDoesNotReturnFixedFields(c *C) { 40 f := &data.Form{} 41 f.Fields = []data.FormFieldX{ 42 data.FormFieldX{ 43 Var: "hello_field1", 44 Label: "hello", 45 Type: "fixed", 46 Values: []string{"Something"}, 47 }, 48 //Malformed 49 data.FormFieldX{ 50 Var: "hello_field2", 51 Label: "hello2", 52 Type: "fixed", 53 }, 54 } 55 f2, err := processForm(f, nil, func(title, instructions string, fields []interface{}) error { 56 c.Assert(len(fields), Equals, 1) 57 c.Assert(fields[0], DeepEquals, &data.FixedFormField{ 58 FormField: data.FormField{ 59 Name: "hello_field1", 60 Label: "hello", 61 Type: "fixed", 62 }, 63 Text: "Something", 64 }) 65 return nil 66 }) 67 68 c.Assert(err, IsNil) 69 c.Assert(*f2, DeepEquals, data.Form{ 70 Type: "submit", 71 Fields: nil}) 72} 73 74func (s *FormsXMPPSuite) Test_processForm_returnsBooleanFields(c *C) { 75 f := &data.Form{} 76 f.Fields = []data.FormFieldX{ 77 data.FormFieldX{ 78 Var: "hello_field3", 79 Label: "hello3", 80 Type: "boolean", 81 }, 82 } 83 f2, err := processForm(f, nil, func(title, instructions string, fields []interface{}) error { 84 c.Assert(len(fields), Equals, 1) 85 c.Assert(fields[0], DeepEquals, &data.BooleanFormField{ 86 FormField: data.FormField{ 87 Name: "hello_field3", 88 Label: "hello3", 89 Type: "boolean", 90 }, 91 Result: false, 92 }) 93 94 return nil 95 }) 96 97 c.Assert(err, IsNil) 98 c.Assert(*f2, DeepEquals, data.Form{ 99 Type: "submit", 100 Fields: []data.FormFieldX{ 101 data.FormFieldX{ 102 Var: "hello_field3", 103 Values: []string{"false"}, 104 }}}, 105 ) 106} 107 108func (s *FormsXMPPSuite) Test_processForm_returnsMultiFields(c *C) { 109 f := &data.Form{} 110 f.Fields = []data.FormFieldX{ 111 data.FormFieldX{ 112 Var: "hello_field4", 113 Label: "hello4", 114 Type: "jid-multi", 115 }, 116 data.FormFieldX{ 117 Var: "hello_field5", 118 Label: "hello5", 119 Type: "text-multi", 120 }, 121 } 122 f2, err := processForm(f, nil, func(title, instructions string, fields []interface{}) error { 123 c.Assert(len(fields), Equals, 2) 124 125 c.Assert(fields[0], DeepEquals, &data.MultiTextFormField{ 126 FormField: data.FormField{ 127 Name: "hello_field4", 128 Label: "hello4", 129 Type: "jid-multi", 130 }, 131 }) 132 133 c.Assert(fields[1], DeepEquals, &data.MultiTextFormField{ 134 FormField: data.FormField{ 135 Name: "hello_field5", 136 Label: "hello5", 137 Type: "text-multi", 138 }, 139 }) 140 141 return nil 142 }) 143 144 c.Assert(err, IsNil) 145 c.Assert(*f2, DeepEquals, data.Form{ 146 Type: "submit", 147 Fields: []data.FormFieldX{ 148 data.FormFieldX{ 149 Var: "hello_field4", 150 }, 151 data.FormFieldX{ 152 Var: "hello_field5", 153 }, 154 }}) 155} 156 157func (s *FormsXMPPSuite) Test_processForm_returnsListSingle(c *C) { 158 f := &data.Form{} 159 f.Fields = []data.FormFieldX{ 160 data.FormFieldX{ 161 Var: "hello_field7", 162 Label: "hello7", 163 Type: "list-single", 164 Options: []data.FormFieldOptionX{ 165 data.FormFieldOptionX{Label: "One", Value: "Two"}, 166 data.FormFieldOptionX{Label: "Three", Value: "Four"}, 167 }, 168 169 Values: []string{"Four"}, 170 }, 171 } 172 f2, err := processForm(f, nil, func(title, instructions string, fields []interface{}) error { 173 c.Assert(len(fields), Equals, 1) 174 175 c.Assert(fields[0], DeepEquals, &data.SelectionFormField{ 176 FormField: data.FormField{ 177 Name: "hello_field7", 178 Label: "hello7", 179 Type: "list-single", 180 }, 181 Values: []string{"One", "Three"}, 182 Ids: []string{"Two", "Four"}, 183 Result: 1, 184 }) 185 186 return nil 187 }) 188 189 c.Assert(err, IsNil) 190 c.Assert(f2, DeepEquals, &data.Form{ 191 Type: "submit", 192 Fields: []data.FormFieldX{ 193 data.FormFieldX{ 194 Var: "hello_field7", 195 Values: []string{"Four"}, 196 }, 197 }}) 198} 199 200func (s *FormsXMPPSuite) Test_processForm_returnsListMulti(c *C) { 201 f := &data.Form{} 202 f.Fields = []data.FormFieldX{ 203 data.FormFieldX{ 204 Var: "hello_field1o7", 205 Label: "hello1o7", 206 Type: "list-multi", 207 Options: []data.FormFieldOptionX{ 208 data.FormFieldOptionX{Label: "One", Value: "Two"}, 209 data.FormFieldOptionX{Label: "Three", Value: "Four"}, 210 data.FormFieldOptionX{Label: "Five", Value: "Six"}, 211 data.FormFieldOptionX{Label: "Seven", Value: "Eight"}, 212 }, 213 214 Values: []string{"Six", "Two"}, 215 }, 216 } 217 f2, err := processForm(f, nil, func(title, instructions string, fields []interface{}) error { 218 c.Assert(len(fields), Equals, 1) 219 220 c.Assert(fields[0], DeepEquals, &data.MultiSelectionFormField{ 221 FormField: data.FormField{ 222 Name: "hello_field1o7", 223 Label: "hello1o7", 224 Type: "list-multi", 225 }, 226 Values: []string{"One", "Three", "Five", "Seven"}, 227 Ids: []string{"Two", "Four", "Six", "Eight"}, 228 Results: []int{0, 2}, 229 }) 230 231 return nil 232 }) 233 234 c.Assert(err, IsNil) 235 c.Assert(f2, DeepEquals, &data.Form{ 236 Type: "submit", 237 Fields: []data.FormFieldX{ 238 data.FormFieldX{ 239 Var: "hello_field1o7", 240 Values: []string{"Two", "Six"}, 241 }}}) 242} 243 244func (s *FormsXMPPSuite) Test_processForm_returnsHidden(c *C) { 245 f := &data.Form{} 246 f.Fields = []data.FormFieldX{ 247 data.FormFieldX{ 248 Var: "hello_field1o71", 249 Label: "hello1o71", 250 Type: "hidden", 251 Values: []string{"secret"}, 252 }, 253 } 254 f2, err := processForm(f, nil, func(title, instructions string, fields []interface{}) error { 255 c.Assert(len(fields), Equals, 0) 256 return nil 257 }) 258 259 c.Assert(err, IsNil) 260 c.Assert(*f2, DeepEquals, data.Form{ 261 Type: "submit", 262 Fields: []data.FormFieldX{ 263 data.FormFieldX{ 264 Var: "hello_field1o71", 265 Values: []string{"secret"}, 266 }}}) 267} 268 269func (s *FormsXMPPSuite) Test_processForm_returnsUnknown(c *C) { 270 f := &data.Form{} 271 f.Fields = []data.FormFieldX{ 272 data.FormFieldX{ 273 Var: "hello_field1o71", 274 Label: "hello1o71", 275 Type: "another-fancy-type", 276 }, 277 data.FormFieldX{ 278 Var: "hello_field1o73", 279 Label: "hello1o73", 280 Type: "another-fancy-type", 281 Values: []string{"another one"}, 282 }, 283 } 284 f2, err := processForm(f, nil, func(title, instructions string, fields []interface{}) error { 285 c.Assert(len(fields), Equals, 2) 286 287 c.Assert(fields[0], DeepEquals, &data.TextFormField{ 288 FormField: data.FormField{ 289 Label: "hello1o71", 290 Type: "another-fancy-type", 291 Name: "hello_field1o71", 292 }, 293 }) 294 295 c.Assert(fields[1], DeepEquals, &data.TextFormField{ 296 FormField: data.FormField{ 297 Label: "hello1o73", 298 Type: "another-fancy-type", 299 Name: "hello_field1o73", 300 }, 301 Default: "another one", 302 }) 303 304 //The UI should set the value, and it should be available on the submit form 305 fields[0].(*data.TextFormField).Result = "Value from UI" 306 307 return nil 308 }) 309 310 c.Assert(err, IsNil) 311 c.Assert(*f2, DeepEquals, data.Form{ 312 Type: "submit", 313 Fields: []data.FormFieldX{ 314 data.FormFieldX{ 315 Var: "hello_field1o71", 316 Values: []string{"Value from UI"}, 317 }, 318 data.FormFieldX{ 319 Var: "hello_field1o73", 320 Values: []string{""}, // Value is lost because the UI does not set anything. Expected. 321 }}}) 322} 323 324type testOtherFormType struct{} 325 326func (s *FormsXMPPSuite) Test_processForm_panicsWhenGivenAWeirdFormType(c *C) { 327 f := &data.Form{} 328 f.Fields = []data.FormFieldX{ 329 data.FormFieldX{ 330 Label: "hello1o71", 331 Type: "another-fancy-type", 332 }, 333 } 334 c.Assert(func() { 335 processForm(f, nil, func(title, instructions string, fields []interface{}) error { 336 fields[0] = testOtherFormType{} 337 return nil 338 }) 339 }, PanicMatches, "unknown field type in result from callback: xmpp.testOtherFormType") 340} 341 342func (s *FormsXMPPSuite) Test_processForm_setsAValidBooleanReturnValue(c *C) { 343 f := &data.Form{} 344 f.Fields = []data.FormFieldX{ 345 data.FormFieldX{ 346 Var: "hello_field1o71", 347 Label: "hello1o71", 348 Type: "boolean", 349 }, 350 } 351 f2, _ := processForm(f, nil, func(title, instructions string, fields []interface{}) error { 352 c.Assert(len(fields), Equals, 1) 353 fields[0].(*data.BooleanFormField).Result = true 354 return nil 355 }) 356 c.Assert(*f2, DeepEquals, data.Form{ 357 Type: "submit", 358 Fields: []data.FormFieldX{ 359 data.FormFieldX{ 360 XMLName: xml.Name{Space: "", Local: ""}, 361 Var: "hello_field1o71", 362 Values: []string{"true"}, 363 }}}) 364} 365 366func (s *FormsXMPPSuite) Test_processForm_returnsListMultiWithResults(c *C) { 367 f := &data.Form{} 368 f.Fields = []data.FormFieldX{ 369 data.FormFieldX{ 370 Var: "hello_field1o7", 371 Label: "hello1o7", 372 Type: "list-multi", 373 Options: []data.FormFieldOptionX{ 374 data.FormFieldOptionX{Label: "One", Value: "Two"}, 375 data.FormFieldOptionX{Label: "Three", Value: "Four"}, 376 }, 377 }, 378 } 379 f2, err := processForm(f, nil, func(title, instructions string, fields []interface{}) error { 380 c.Assert(len(fields), Equals, 1) 381 fields[0].(*data.MultiSelectionFormField).Results = []int{1} 382 return nil 383 }) 384 385 c.Assert(err, IsNil) 386 c.Assert(*f2, DeepEquals, data.Form{ 387 Type: "submit", 388 Fields: []data.FormFieldX{ 389 data.FormFieldX{ 390 Var: "hello_field1o7", 391 Values: []string{"Four"}, 392 }}}) 393} 394 395func (s *FormsXMPPSuite) Test_processForm_dealsWithMediaCorrectly(c *C) { 396 fooBarDecoded := []byte("hello world") 397 f := &data.Form{} 398 datas := []data.BobData{ 399 data.BobData{ 400 CID: "foobax", 401 Base64: ".....", 402 }, 403 data.BobData{ 404 CID: "foobar", 405 Base64: base64.StdEncoding.EncodeToString(fooBarDecoded), 406 }, 407 } 408 f.Fields = []data.FormFieldX{ 409 data.FormFieldX{ 410 Var: "hello1", 411 Label: "hello", 412 Type: "fixed", 413 Values: []string{"Something"}, 414 Media: []data.FormFieldMediaX{ 415 data.FormFieldMediaX{ 416 URIs: []data.MediaURIX{ 417 data.MediaURIX{ 418 MIMEType: "application/not-a-uri", 419 URI: "", 420 }, 421 data.MediaURIX{ 422 MIMEType: "application/not-a-cid-uri", 423 URI: "hello:world", 424 }, 425 data.MediaURIX{ 426 MIMEType: "application/valid-encoding", 427 URI: "cid:foobar", 428 }, 429 data.MediaURIX{ 430 MIMEType: "application/invalid-encoding", 431 URI: "cid:foobax", 432 }, 433 }, 434 }, 435 }, 436 }, 437 data.FormFieldX{ 438 Var: "hello2", 439 Label: "hello1o7", 440 Type: "hidden", 441 Media: []data.FormFieldMediaX{ 442 data.FormFieldMediaX{ 443 URIs: []data.MediaURIX{ 444 data.MediaURIX{ 445 MIMEType: "application/does-not-matter-because-it-is-ignored", 446 URI: "hello:world", 447 }, 448 data.MediaURIX{ 449 MIMEType: "application/does-not-matter-because-it-is-also-ignored", 450 URI: "cid:foobax", 451 }, 452 }, 453 }, 454 }, 455 }, 456 } 457 458 f2, err := processForm(f, datas, func(title, instructions string, fields []interface{}) error { 459 //NOTE: hidden fields are not passed to the callback so you can't have access to any media 460 //in hidden fields. 461 c.Assert(len(fields), Equals, 1) 462 c.Assert(fields[0], DeepEquals, &data.FixedFormField{ 463 FormField: data.FormField{ 464 Name: "hello1", 465 Label: "hello", 466 Type: "fixed", 467 Media: [][]data.Media{ 468 []data.Media{ 469 data.Media{ 470 MIMEType: "application/not-a-cid-uri", 471 URI: "hello:world", 472 }, 473 data.Media{ 474 MIMEType: "application/valid-encoding", 475 Data: fooBarDecoded, 476 }, 477 }}, 478 }, 479 Text: "Something", 480 }) 481 return nil 482 }) 483 484 c.Assert(err, IsNil) 485 c.Assert(*f2, DeepEquals, data.Form{ 486 Type: "submit", 487 Fields: []data.FormFieldX{ 488 data.FormFieldX{ 489 Var: "hello2", 490 }}}) 491} 492