]> git.proxmox.com Git - extjs.git/blame - extjs/packages/core/test/specs/direct/RemotingProvider.js
add extjs 6.0.1 sources
[extjs.git] / extjs / packages / core / test / specs / direct / RemotingProvider.js
CommitLineData
6527f429
DM
1describe("Ext.direct.RemotingProvider", function() {\r
2 var RP = Ext.direct.RemotingProvider,\r
3 provider,\r
4 \r
5 api = {\r
6 actions: {\r
7 "TestAction": [{\r
8 len: 1,\r
9 name: "echo"\r
10 },{\r
11 len: 1,\r
12 name: "directFail"\r
13 }, {\r
14 name: 'directForm',\r
15 formHandler: true\r
16 }, {\r
17 len: 1,\r
18 name: 'directMetaNamed',\r
19 metadata: {\r
20 params: [],\r
21 strict: false\r
22 }\r
23 }, {\r
24 len: 1,\r
25 name: 'directMetaOrdered',\r
26 metadata: {\r
27 len: 2\r
28 }\r
29 }, {\r
30 name: 'directMetaFormNamed',\r
31 formHandler: true,\r
32 metadata: {\r
33 params: [],\r
34 strict: false\r
35 }\r
36 }, {\r
37 name: 'directMetaFormOrdered',\r
38 formHandler: true,\r
39 metadata: {\r
40 len: 2\r
41 }\r
42 }],\r
43 \r
44 "TestAction.Foo": [{\r
45 len: 0,\r
46 name: "foo"\r
47 }],\r
48 \r
49 "TestAction.Foo.Bar": [{\r
50 len: 0,\r
51 name: "bar"\r
52 }],\r
53 \r
54 "TestAction.Foo.Bar.Baz": [{\r
55 len: 0,\r
56 name: "baz"\r
57 }],\r
58 \r
59 "TestAction.Foo.Qux": [{\r
60 len: 0,\r
61 name: "qux"\r
62 }]\r
63 },\r
64 \r
65 namespace: "Direct.foo.bar",\r
66 type: "remoting",\r
67 url: "/router",\r
68 id: "foo"\r
69 },\r
70 \r
71 directMethods = {\r
72 echo: function(value) {\r
73 return value;\r
74 },\r
75 \r
76 directFail: function(value) {\r
77 return {\r
78 type: 'exception'\r
79 };\r
80 },\r
81 \r
82 directForm: function(form) {\r
83 return {\r
84 success: true,\r
85 data: form\r
86 };\r
87 },\r
88 \r
89 directMetaNamed: function(data, metadata) {\r
90 return {\r
91 data: data,\r
92 metadata: metadata\r
93 }\r
94 },\r
95 \r
96 directMetaOrdered: function(data, metadata) {\r
97 return {\r
98 data: data,\r
99 metadata: metadata\r
100 }\r
101 },\r
102 \r
103 directMetaFormNamed: function(form, metadata) {\r
104 return {\r
105 success: true,\r
106 data: form,\r
107 metadata: metadata\r
108 }\r
109 },\r
110 \r
111 directMetaFormOrdered: function(form, metadata) {\r
112 return {\r
113 success: true,\r
114 data: form,\r
115 metadata: metadata\r
116 }\r
117 },\r
118 \r
119 foo: function() {\r
120 return 'foo';\r
121 },\r
122 \r
123 bar: function() {\r
124 return 'bar';\r
125 },\r
126 \r
127 baz: function() {\r
128 return 'baz';\r
129 },\r
130 \r
131 qux: function() {\r
132 return 'qux';\r
133 }\r
134 };\r
135 \r
136 // This simulation stub is *asynchronous*\r
137 function simulateDirectRequest(options) {\r
138 var callback = options.callback,\r
139 scope = options.scope,\r
140 transaction = options.transaction,\r
141 isForm = options.form !== undefined,\r
142 isUpload = options.isUpload,\r
143 arg = {},\r
144 data, tid, action, method, arg, fn, success,\r
145 result, response, xhr, opt, metadata;\r
146 \r
147 if (isForm) {\r
148 data = options.params;\r
149 tid = data.extTID;\r
150 action = data.extAction;\r
151 method = data.extMethod;\r
152 metadata = data.extMetadata;\r
153 \r
154 // Collect the input field values\r
155 Ext.fly(options.form).select('input').each(function(el, c, idx) { \r
156 this[el.dom.name] = el.dom.value;\r
157 }, arg);\r
158 arg = [arg];\r
159 }\r
160 else {\r
161 data = options.jsonData;\r
162 tid = data.tid;\r
163 action = data.action;\r
164 method = data.method;\r
165 arg = data.data || [];\r
166 metadata = data.metadata;\r
167 }\r
168 \r
169 fn = directMethods[method];\r
170 \r
171 // TODO Come up with something less hacky\r
172 if (/^directMeta/.test(method)) {\r
173 arg.push(metadata);\r
174 }\r
175 \r
176 if (options.timeout === 666) {\r
177 response = {\r
178 type: 'exception',\r
179 tid: tid,\r
180 message: "Can't connect to the server"\r
181 };\r
182 \r
183 success = false;\r
184 }\r
185 else {\r
186 try {\r
187 result = fn.apply({}, arg);\r
188 response = {\r
189 type: 'rpc',\r
190 tid: tid,\r
191 action: action,\r
192 method: method,\r
193 result: result\r
194 };\r
195 }\r
196 catch (e) {\r
197 // Direct exception handling here\r
198 response = {\r
199 type: 'exception',\r
200 tid: tid,\r
201 message: e.toString(),\r
202 where: 'internal'\r
203 };\r
204 }\r
205 \r
206 // Success only means *communication* success\r
207 success = true;\r
208 }\r
209 \r
210 xhr = {\r
211 responseText: Ext.encode(response)\r
212 };\r
213 \r
214 opt = {\r
215 transaction: transaction\r
216 };\r
217 \r
218 Ext.callback(callback, scope, [opt, success, xhr], 1);\r
219 }\r
220 \r
221 beforeEach(function() {\r
222 provider = new RP(api);\r
223 });\r
224 \r
225 afterEach(function() {\r
226 if (provider) {\r
227 provider.destroy();\r
228 }\r
229 \r
230 Ext.direct.Manager.clearAllMethods();\r
231 \r
232 provider = null;\r
233 \r
234 try {\r
235 delete window.Direct;\r
236 }\r
237 catch (e) {\r
238 window.Direct = undefined;\r
239 }\r
240 });\r
241 \r
242 describe("handles namespaces:", function() {\r
243 var ns;\r
244 \r
245 it("creates namespace for itself if passed a string", function() {\r
246 expect(Direct.foo.bar).toBeDefined();\r
247 });\r
248 \r
249 it("doesn't create nested objects until it's connected", function() {\r
250 expect(Direct.foo.bar).toEqual({});\r
251 });\r
252 \r
253 describe("creates nested namespaces after it's connected:", function() {\r
254 beforeEach(function() {\r
255 provider.connect();\r
256 ns = Direct.foo.bar;\r
257 });\r
258 \r
259 it("creates TestAction", function() {\r
260 expect(ns.TestAction).toBeDefined();\r
261 });\r
262 \r
263 it("creates TestAction.Foo", function() {\r
264 expect(ns.TestAction.Foo).toBeDefined();\r
265 });\r
266 \r
267 it("creates TestAction.Foo.Bar", function() {\r
268 expect(ns.TestAction.Foo.Bar).toBeDefined();\r
269 });\r
270 \r
271 it("creates TestAction.Foo.Bar.Baz", function() {\r
272 expect(ns.TestAction.Foo.Bar.Baz).toBeDefined();\r
273 });\r
274 \r
275 it("creates TestAction.Foo.Qux", function() {\r
276 expect(ns.TestAction.Foo.Qux).toBeDefined();\r
277 });\r
278 });\r
279 \r
280 describe("handles nested namespaces the old way:", function() {\r
281 beforeEach(function() {\r
282 provider.disableNestedActions = true;\r
283 provider.connect();\r
284 ns = Direct.foo.bar;\r
285 });\r
286 \r
287 it("creates TestAction", function() {\r
288 expect(ns.TestAction).toBeDefined();\r
289 });\r
290 \r
291 it("creates TestAction.Foo", function() {\r
292 expect(ns['TestAction.Foo']).toBeDefined();\r
293 // AND\r
294 expect(ns.TestAction.Foo).not.toBeDefined();\r
295 });\r
296 \r
297 it("creates TestAction.Foo.Bar", function() {\r
298 expect(ns['TestAction.Foo.Bar']).toBeDefined();\r
299 });\r
300 \r
301 it("creates TestAction.Foo.Bar.Baz", function() {\r
302 expect(ns['TestAction.Foo.Bar.Baz']).toBeDefined();\r
303 });\r
304 \r
305 it("creates TestAction.Foo.Qux", function() {\r
306 expect(ns['TestAction.Foo.Qux']).toBeDefined();\r
307 });\r
308 });\r
309 });\r
310 \r
311 describe("handles remoting methods:", function() {\r
312 var ns;\r
313 \r
314 function checkFn(fn) {\r
315 expect( Ext.isFunction(fn) ).toBeTruthy();\r
316 };\r
317 \r
318 beforeEach(function() {\r
319 provider.connect();\r
320 ns = Direct.foo.bar;\r
321 });\r
322 \r
323 it("has Foo.foo", function() {\r
324 checkFn(ns.TestAction.Foo.foo);\r
325 });\r
326 \r
327 it("has Foo.Bar.bar", function() {\r
328 checkFn(ns.TestAction.Foo.Bar.bar);\r
329 });\r
330 \r
331 it("has Foo.Bar.Baz.baz", function() {\r
332 checkFn(ns.TestAction.Foo.Bar.Baz.baz);\r
333 });\r
334 \r
335 it("has Foo.Qux.qux", function() {\r
336 checkFn(ns.TestAction.Foo.Qux.qux);\r
337 });\r
338 });\r
339\r
340 describe("runs remoting methods:", function() {\r
341 var ns, echo, options, handler;\r
342 \r
343 function echoStatus(result, event) {\r
344 this.echo = event.status;\r
345 }\r
346 \r
347 function echoResult(result, event) {\r
348 if (event.status) {\r
349 this.echo = result;\r
350 }\r
351 }\r
352 \r
353 function echoFormResult(request, result) {\r
354 this.echo = result.result;\r
355 }\r
356 \r
357 function echoResultAndOptions(result, event, success, options) {\r
358 if (success) {\r
359 this.echo = result;\r
360 this.options = options;\r
361 }\r
362 }\r
363 \r
364 function returnFalse() {\r
365 return false;\r
366 }\r
367 \r
368 function checkEcho() {\r
369 return Ext.isDefined(this.echo);\r
370 }\r
371 \r
372 function checkHandler() {\r
373 return !!handler.callCount;\r
374 }\r
375 \r
376 function waitForEcho(fn, desc, timeout) {\r
377 fn = fn || checkEcho;\r
378 desc = desc || 'callback never fired';\r
379 timeout = timeout != null ? timeout : 100;\r
380 \r
381 waitsFor(fn, desc, timeout);\r
382 }\r
383 \r
384 function expectEcho(want) {\r
385 runs(function() {\r
386 expect(this.echo).toEqual(want);\r
387 });\r
388 }\r
389 \r
390 beforeEach(function() {\r
391 echo = undefined;\r
392 options = undefined;\r
393 \r
394 spyOn(Ext.Ajax, 'request').andCallFake(simulateDirectRequest);\r
395 \r
396 provider.connect();\r
397 ns = Direct.foo.bar;\r
398 \r
399 handler = jasmine.createSpy('event handler');\r
400 });\r
401 \r
402 afterEach(function() {\r
403 handler = undefined;\r
404 });\r
405 \r
406 describe("handles call mechanics", function() {\r
407 describe("call batching", function() {\r
408 afterEach(function() {\r
409 // Transactions in this suite have no chance of finishing,\r
410 // so we clean them up manually\r
411 if (provider.callTask) {\r
412 provider.callTask.cancel();\r
413 }\r
414 \r
415 Ext.direct.Manager.transactions.clear();\r
416 });\r
417 \r
418 it("should batch calls within specified enableBuffer timeout", function() {\r
419 var options, baseTid;\r
420 \r
421 runs(function() {\r
422 Ext.Ajax.request.andCallFake(function(opt) {\r
423 options = opt;\r
424 });\r
425\r
426 baseTid = Ext.direct.Transaction.TRANSACTION_ID;\r
427 \r
428 ns.TestAction.echo('foo', Ext.emptyFn);\r
429 ns.TestAction.echo('bar', Ext.emptyFn);\r
430 });\r
431 \r
432 waitsFor(function() { return !!options }, 'options never modified', 20);\r
433 \r
434 runs(function() {\r
435 expect(options.jsonData).toEqual([{\r
436 action: 'TestAction',\r
437 method: 'echo',\r
438 type: 'rpc',\r
439 tid: baseTid + 1,\r
440 data: ['foo']\r
441 }, {\r
442 action: 'TestAction',\r
443 method: 'echo',\r
444 type: 'rpc',\r
445 tid: baseTid + 2,\r
446 data: ['bar']\r
447 }]);\r
448 });\r
449 });\r
450 \r
451 it("should run calls with specified timeout w/o batching", function() {\r
452 var options = [],\r
453 baseTid;\r
454 \r
455 runs(function() {\r
456 Ext.Ajax.request.andCallFake(function(opt) {\r
457 options.push(opt);\r
458 });\r
459\r
460 provider.enableBuffer = 200;\r
461 baseTid = Ext.direct.Transaction.TRANSACTION_ID;\r
462 \r
463 ns.TestAction.echo('baz', Ext.emptyFn);\r
464 ns.TestAction.echo('qux', Ext.emptyFn, this, { timeout: 1 });\r
465 });\r
466 \r
467 waitsFor(function() { return !!options }, 'options never modified', 20);\r
468 \r
469 runs(function() {\r
470 expect(options.length).toBe(1);\r
471 // AND\r
472 expect(options[0].jsonData).toEqual({\r
473 action: 'TestAction',\r
474 method: 'echo',\r
475 type: 'rpc',\r
476 tid: baseTid + 2,\r
477 data: ['qux']\r
478 });\r
479 });\r
480 });\r
481 \r
482 it("should run calls instantly with disableBatching", function() {\r
483 var options = [],\r
484 baseTid;\r
485 \r
486 runs(function() {\r
487 Ext.Ajax.request.andCallFake(function(opt) {\r
488 options.push(opt);\r
489 });\r
490\r
491 provider.enableBuffer = 200;\r
492 baseTid = Ext.direct.Transaction.TRANSACTION_ID;\r
493 \r
494 ns.TestAction.echo('baz', Ext.emptyFn);\r
495 \r
496 ns.TestAction.echo.$directCfg.method.disableBatching = true;\r
497 ns.TestAction.echo('qux', Ext.emptyFn);\r
498 });\r
499 \r
500 waitsFor(function() { return !!options }, 'options never modified', 20);\r
501 \r
502 runs(function() {\r
503 expect(options.length).toBe(1);\r
504 // AND\r
505 expect(options[0].jsonData).toEqual({\r
506 action: 'TestAction',\r
507 method: 'echo',\r
508 type: 'rpc',\r
509 tid: baseTid + 2,\r
510 data: ['qux']\r
511 });\r
512 });\r
513 });\r
514 \r
515 it("should run calls instantly with enableBuffer = false", function() {\r
516 var option, baseTid;\r
517 \r
518 Ext.Ajax.request.andCallFake(function(opt) {\r
519 options = opt;\r
520 });\r
521 \r
522 provider.enableBuffer = false;\r
523 baseTid = Ext.direct.Transaction.TRANSACTION_ID;\r
524 \r
525 ns.TestAction.echo('fred', Ext.emptyFn);\r
526 \r
527 expect(options.jsonData).toEqual({\r
528 action: 'TestAction',\r
529 method: 'echo',\r
530 type: 'rpc',\r
531 tid: baseTid + 1,\r
532 data: ['fred']\r
533 });\r
534 });\r
535 \r
536 describe("bufferLimit", function() {\r
537 var options, baseTid;\r
538 \r
539 beforeEach(function() {\r
540 options = [];\r
541 \r
542 Ext.Ajax.request.andCallFake(function(opt) {\r
543 options.push(opt);\r
544 });\r
545 \r
546 provider.enableBuffer = 200;\r
547 provider.bufferLimit = 3;\r
548 \r
549 baseTid = Ext.direct.Transaction.TRANSACTION_ID;\r
550 });\r
551 \r
552 it("should batch calls up to bufferLimit", function() {\r
553 runs(function() {\r
554 ns.TestAction.echo('fee', Ext.emptyFn);\r
555 ns.TestAction.echo('fie', Ext.emptyFn);\r
556 ns.TestAction.echo('foe', Ext.emptyFn);\r
557 ns.TestAction.echo('foo', Ext.emptyFn);\r
558 });\r
559 \r
560 waitsFor(function() {\r
561 return !!options.length;\r
562 }, 'options never modified', 20);\r
563 \r
564 runs(function() {\r
565 expect(options.length).toBe(1);\r
566 \r
567 expect(options[0].jsonData).toEqual([{\r
568 action: 'TestAction',\r
569 method: 'echo',\r
570 type: 'rpc',\r
571 tid: baseTid + 1,\r
572 data: ['fee']\r
573 }, {\r
574 action: 'TestAction',\r
575 method: 'echo',\r
576 type: 'rpc',\r
577 tid: baseTid + 2,\r
578 data: ['fie']\r
579 }, {\r
580 action: 'TestAction',\r
581 method: 'echo',\r
582 type: 'rpc',\r
583 tid: baseTid + 3,\r
584 data: ['foe']\r
585 }]);\r
586 });\r
587 });\r
588 \r
589 it("should make 2 batched requests for 6 calls", function() {\r
590 runs(function() {\r
591 ns.TestAction.echo('frobbe', Ext.emptyFn);\r
592 ns.TestAction.echo('throbbe', Ext.emptyFn);\r
593 ns.TestAction.echo('gurgle', Ext.emptyFn);\r
594 ns.TestAction.echo('bonzo', Ext.emptyFn);\r
595 ns.TestAction.echo('mymse', Ext.emptyFn);\r
596 ns.TestAction.echo('splurge', Ext.emptyFn);\r
597 });\r
598 \r
599 waitsFor(function() {\r
600 return !!options.length;\r
601 }, 'options never modified', 20);\r
602 \r
603 runs(function() {\r
604 expect(options.length).toBe(2);\r
605 \r
606 expect(options[0].jsonData).toEqual([{\r
607 action: 'TestAction',\r
608 method: 'echo',\r
609 type: 'rpc',\r
610 tid: baseTid + 1,\r
611 data: ['frobbe']\r
612 }, {\r
613 action: 'TestAction',\r
614 method: 'echo',\r
615 type: 'rpc',\r
616 tid: baseTid + 2,\r
617 data: ['throbbe']\r
618 }, {\r
619 action: 'TestAction',\r
620 method: 'echo',\r
621 type: 'rpc',\r
622 tid: baseTid + 3,\r
623 data: ['gurgle']\r
624 }]);\r
625 \r
626 expect(options[1].jsonData).toEqual([{\r
627 action: 'TestAction',\r
628 method: 'echo',\r
629 type: 'rpc',\r
630 tid: baseTid + 4,\r
631 data: ['bonzo']\r
632 }, {\r
633 action: 'TestAction',\r
634 method: 'echo',\r
635 type: 'rpc',\r
636 tid: baseTid + 5,\r
637 data: ['mymse']\r
638 }, {\r
639 action: 'TestAction',\r
640 method: 'echo',\r
641 type: 'rpc',\r
642 tid: baseTid + 6,\r
643 data: ['splurge']\r
644 }]);\r
645 });\r
646 });\r
647 \r
648 it("should make 3 batched requests for 7 calls", function() {\r
649 runs(function() {\r
650 ns.TestAction.echo('Grumpy', Ext.emptyFn);\r
651 ns.TestAction.echo('Sleepy', Ext.emptyFn);\r
652 ns.TestAction.echo('Dopey', Ext.emptyFn);\r
653 ns.TestAction.echo('Bashful', Ext.emptyFn);\r
654 ns.TestAction.echo('Sneezy', Ext.emptyFn);\r
655 ns.TestAction.echo('Happy', Ext.emptyFn);\r
656 ns.TestAction.echo('Doc', Ext.emptyFn);\r
657 });\r
658 \r
659 waitsFor(function() {\r
660 return options.length === 3;\r
661 }, '3 Ajax requests', 300);\r
662 \r
663 runs(function() {\r
664 expect(options.length).toBe(3);\r
665 \r
666 expect(options[0].jsonData).toEqual([{\r
667 action: 'TestAction',\r
668 method: 'echo',\r
669 type: 'rpc',\r
670 tid: baseTid + 1,\r
671 data: ['Grumpy']\r
672 }, {\r
673 action: 'TestAction',\r
674 method: 'echo',\r
675 type: 'rpc',\r
676 tid: baseTid + 2,\r
677 data: ['Sleepy']\r
678 }, {\r
679 action: 'TestAction',\r
680 method: 'echo',\r
681 type: 'rpc',\r
682 tid: baseTid + 3,\r
683 data: ['Dopey']\r
684 }]);\r
685 \r
686 expect(options[1].jsonData).toEqual([{\r
687 action: 'TestAction',\r
688 method: 'echo',\r
689 type: 'rpc',\r
690 tid: baseTid + 4,\r
691 data: ['Bashful']\r
692 }, {\r
693 action: 'TestAction',\r
694 method: 'echo',\r
695 type: 'rpc',\r
696 tid: baseTid + 5,\r
697 data: ['Sneezy']\r
698 }, {\r
699 action: 'TestAction',\r
700 method: 'echo',\r
701 type: 'rpc',\r
702 tid: baseTid + 6,\r
703 data: ['Happy']\r
704 }]);\r
705 \r
706 expect(options[2].jsonData).toEqual({\r
707 action: 'TestAction',\r
708 method: 'echo',\r
709 type: 'rpc',\r
710 tid: baseTid + 7,\r
711 data: ['Doc']\r
712 });\r
713 });\r
714 });\r
715 });\r
716 });\r
717 \r
718 describe("call related events", function() {\r
719 it("fires 'beforecall' event", function() {\r
720 runs(function() {\r
721 provider.on('beforecall', handler);\r
722 \r
723 ns.TestAction.echo('fred', Ext.emptyFn);\r
724 });\r
725 \r
726 waitsFor(checkHandler, 'event handler never fired', 20);\r
727 \r
728 runs(function() {\r
729 expect(handler).toHaveBeenCalled();\r
730 });\r
731\r
732 waits(35);\r
733 });\r
734 \r
735 it("fires 'call' event", function() {\r
736 runs(function() {\r
737 provider.on('call', handler);\r
738 \r
739 ns.TestAction.echo('plugh', Ext.emptyFn);\r
740 });\r
741 \r
742 waitsFor(checkHandler, 'event handler never fired', 20);\r
743 \r
744 runs(function() {\r
745 expect(handler).toHaveBeenCalled();\r
746 });\r
747 \r
748 waits(35);\r
749 });\r
750 \r
751 it("cancels request when 'beforecall' handler returns false", function() {\r
752 runs(function() {\r
753 handler.andCallFake(returnFalse);\r
754 \r
755 provider.on('beforecall', handler);\r
756 \r
757 ns.TestAction.echo('mymse', Ext.emptyFn);\r
758 });\r
759 \r
760 waitsFor(checkHandler, 'event handler never fired', 200);\r
761 \r
762 // Additional timeout for callbacks to queue and fire\r
763 waits(20);\r
764 \r
765 runs(function() {\r
766 expect(options).toBeUndefined();\r
767 });\r
768\r
769 waits(35);\r
770 });\r
771 });\r
772 });\r
773 \r
774 describe("with connection failed", function() {\r
775 it("retries failed transactions", function() {\r
776 var proto = Ext.direct.Transaction.prototype;\r
777 \r
778 runs(function() {\r
779 spyOn(proto, 'retry').andCallThrough();\r
780 \r
781 ns.TestAction.echo('foo', Ext.emptyFn, this, { timeout: 666 });\r
782 });\r
783 \r
784 waitsFor(function() {\r
785 return proto.retry.callCount === 1;\r
786 }, 'transaction.retry() never called', 200);\r
787 \r
788 runs(function() {\r
789 expect(proto.retry).toHaveBeenCalled();\r
790 });\r
791 });\r
792 \r
793 it("fires exception when retry count is exceeded", function() {\r
794 runs(function() {\r
795 provider.on('data', handler);\r
796 \r
797 ns.TestAction.echo('bar', Ext.emptyFn, this, { timeout: 666 });\r
798 });\r
799 \r
800 waitsFor(checkHandler, 'event handler never fired', 200);\r
801 \r
802 runs(function() {\r
803 expect(handler).toHaveBeenCalled();\r
804 });\r
805 });\r
806 \r
807 describe("handles callback:", function() {\r
808 it("fires 'beforecallback' event", function() {\r
809 runs(function() {\r
810 provider.on('beforecallback', handler);\r
811 \r
812 ns.TestAction.echo('baz', Ext.emptyFn, this, { timeout: 666 });\r
813 });\r
814 \r
815 waitsFor(checkHandler, 'event handler never fired', 200);\r
816 \r
817 runs(function() {\r
818 expect(handler).toHaveBeenCalled();\r
819 });\r
820 });\r
821 \r
822 it("cancels callback when 'beforecallback' handler returns false", function() {\r
823 var cb = jasmine.createSpy('callback');\r
824 \r
825 runs(function() {\r
826 handler.andCallFake(returnFalse);\r
827 \r
828 provider.on('beforecallback', handler);\r
829 \r
830 ns.TestAction.echo('qux', cb, this, { timeout: 666 });\r
831 });\r
832 \r
833 waitsFor(checkHandler, 'event handler never fired', 200);\r
834 \r
835 // Additional timeout for callback to be handled\r
836 waits(20);\r
837 \r
838 runs(function() {\r
839 expect(handler).toHaveBeenCalled();\r
840 // AND\r
841 expect(cb).not.toHaveBeenCalled();\r
842 });\r
843 });\r
844 \r
845 it("fires callback when retry count is exceeded", function() {\r
846 runs(function() {\r
847 ns.TestAction.echo('plugh', echoStatus, this, { timeout: 666 });\r
848 });\r
849 \r
850 waitsFor(checkEcho, 'callback never fired', 200);\r
851 \r
852 runs(function() {\r
853 expect(this.echo).toBe(false);\r
854 });\r
855 });\r
856 });\r
857 });\r
858 \r
859 describe("successfully connected:", function() {\r
860 it("fires 'data' event", function() {\r
861 runs(function() {\r
862 provider.on('data', handler);\r
863 \r
864 ns.TestAction.echo('foo', echoResult, this);\r
865 });\r
866 \r
867 waitForEcho();\r
868 \r
869 runs(function() {\r
870 expect(handler).toHaveBeenCalled();\r
871 });\r
872 });\r
873 \r
874 describe("handles callback:", function() {\r
875 it("fires 'beforecallback' event", function() {\r
876 runs(function() {\r
877 provider.on('beforecallback', handler);\r
878 \r
879 ns.TestAction.echo('foo', echoResult, this);\r
880 });\r
881 \r
882 waitsFor(checkEcho, 'event handler never fired', 100);\r
883 \r
884 runs(function() {\r
885 expect(handler).toHaveBeenCalled();\r
886 });\r
887 });\r
888 \r
889 it("cancels callback when 'beforecallback' handler returns false", function() {\r
890 var cb = jasmine.createSpy('callback');\r
891 \r
892 runs(function() {\r
893 handler.andCallFake(returnFalse);\r
894 \r
895 provider.on('beforecallback', handler);\r
896 \r
897 ns.TestAction.echo('bar', cb, this);\r
898 });\r
899 \r
900 waitsFor(checkHandler, 'event handler never fired', 100);\r
901 \r
902 // Additional timeout for callback to be handled\r
903 waits(20);\r
904 \r
905 runs(function() {\r
906 expect(handler).toHaveBeenCalled();\r
907 // AND\r
908 expect(cb).not.toHaveBeenCalled();\r
909 });\r
910 });\r
911 \r
912 it('runs w/o additional options', function() {\r
913 runs(function() {\r
914 ns.TestAction.echo('foo', echoResult, this);\r
915 });\r
916 \r
917 waitForEcho();\r
918 \r
919 expectEcho('foo');\r
920 });\r
921 \r
922 it('runs w/ additional options', function() {\r
923 runs(function() {\r
924 ns.TestAction.echo('bar', echoResultAndOptions, this, {\r
925 victory: 'Huzzah!'\r
926 });\r
927 });\r
928 \r
929 waitForEcho();\r
930 \r
931 runs(function() {\r
932 expect(this.echo).toEqual('bar');\r
933 expect(this.options).toBeDefined();\r
934 expect(this.options.victory).toEqual('Huzzah!');\r
935 });\r
936 });\r
937 \r
938 it('runs in nested namespaces', function() {\r
939 runs(function() {\r
940 ns.TestAction.Foo.foo(echoResult, this);\r
941 });\r
942 \r
943 waitForEcho();\r
944 \r
945 expectEcho('foo');\r
946 });\r
947 \r
948 it('runs in deeply nested namespaces', function() {\r
949 runs(function() {\r
950 ns.TestAction.Foo.Bar.bar(echoResult, this);\r
951 });\r
952 \r
953 waitForEcho();\r
954 \r
955 expectEcho('bar');\r
956 });\r
957 \r
958 it('runs in really truly deeply nested namespaces', function() {\r
959 runs(function() {\r
960 ns.TestAction.Foo.Bar.Baz.baz(echoResult, this);\r
961 });\r
962 \r
963 waitForEcho();\r
964 \r
965 expectEcho('baz');\r
966 });\r
967 });\r
968 \r
969 describe("metadata", function() {\r
970 it("will pass named metadata", function() {\r
971 runs(function() {\r
972 ns.TestAction.directMetaNamed('foo', echoResult, this, {\r
973 metadata: {\r
974 bleh: 'blah'\r
975 }\r
976 });\r
977 });\r
978 \r
979 waitForEcho();\r
980 \r
981 expectEcho({ data: 'foo', metadata: { bleh: 'blah' } });\r
982 });\r
983 \r
984 it("will pass ordered metadata", function() {\r
985 runs(function() {\r
986 ns.TestAction.directMetaOrdered('bar', echoResult, this, {\r
987 metadata: ['blerg', 'blam', 'frob']\r
988 });\r
989 });\r
990 \r
991 waitForEcho();\r
992 \r
993 // Metadata len === 2, so 3rd argument should be cut off\r
994 expectEcho({ data: 'bar', metadata: ['blerg', 'blam'] });\r
995 });\r
996 })\r
997 });\r
998 \r
999 (Ext.toolkit === 'classic' ? describe : xdescribe)("form calls:", function() {\r
1000 var form;\r
1001 \r
1002 function createForm(config) {\r
1003 config = Ext.apply({\r
1004 xtype: 'form',\r
1005 renderTo: document.body,\r
1006 width: 300,\r
1007 height: 200,\r
1008 layout: 'form',\r
1009 \r
1010 api: {\r
1011 submit: 'TestAction.directForm'\r
1012 },\r
1013 \r
1014 items: [{\r
1015 xtype: 'hiddenfield',\r
1016 name: 'hidden_foo',\r
1017 value: 'hide the sacred foo from infoodels!'\r
1018 }, {\r
1019 xtype: 'textfield',\r
1020 name: 'overt_foo',\r
1021 value: 'behold the false, deceitful overt foo'\r
1022 }]\r
1023 }, config);\r
1024 \r
1025 form = Ext.widget(config);\r
1026 }\r
1027 \r
1028 beforeEach(function() {\r
1029 createForm();\r
1030 });\r
1031 \r
1032 afterEach(function() {\r
1033 if (form) {\r
1034 form.destroy();\r
1035 }\r
1036 });\r
1037 \r
1038 describe("submit", function() {\r
1039 it("should pass field values to direct fn", function() {\r
1040 runs(function() {\r
1041 form.submit({\r
1042 success: echoFormResult,\r
1043 scope: this\r
1044 });\r
1045 });\r
1046 \r
1047 // Callbacks are a bit slow but 2 sec is enough\r
1048 waitsFor(checkEcho, 'callback that never fired', 2000);\r
1049 \r
1050 runs(function() {\r
1051 expect(this.echo).toEqual({\r
1052 success: true,\r
1053 data: {\r
1054 hidden_foo: 'hide the sacred foo from infoodels!',\r
1055 overt_foo: 'behold the false, deceitful overt foo'\r
1056 }\r
1057 });\r
1058 });\r
1059 });\r
1060 \r
1061 it("should pass extra params to direct fn", function() {\r
1062 runs(function() {\r
1063 form.submit({\r
1064 params: {\r
1065 simple_foo: 'barf!'\r
1066 },\r
1067 success: echoFormResult,\r
1068 scope: this\r
1069 });\r
1070 });\r
1071 \r
1072 waitsFor(checkEcho, 'callback that never fired', 2000);\r
1073 \r
1074 runs(function() {\r
1075 expect(this.echo).toEqual({\r
1076 success: true,\r
1077 data: {\r
1078 hidden_foo: 'hide the sacred foo from infoodels!',\r
1079 overt_foo: 'behold the false, deceitful overt foo',\r
1080 simple_foo: 'barf!'\r
1081 }\r
1082 });\r
1083 });\r
1084 });\r
1085 \r
1086 it("should pass form baseParams to direct fn", function() {\r
1087 runs(function() {\r
1088 form.getForm().baseParams = {\r
1089 MEGA_FOO: 'ALL YOUR FOO ARE BELONG TO US!'\r
1090 };\r
1091 \r
1092 form.submit({\r
1093 success: echoFormResult,\r
1094 scope: this\r
1095 });\r
1096 });\r
1097 \r
1098 waitsFor(checkEcho, 'callback that never fired', 2000);\r
1099 \r
1100 runs(function() {\r
1101 expect(this.echo).toEqual({\r
1102 success: true,\r
1103 data: {\r
1104 hidden_foo: 'hide the sacred foo from infoodels!',\r
1105 overt_foo: 'behold the false, deceitful overt foo',\r
1106 MEGA_FOO: 'ALL YOUR FOO ARE BELONG TO US!'\r
1107 }\r
1108 });\r
1109 });\r
1110 });\r
1111 \r
1112 it("should pass named metadata", function() {\r
1113 runs(function() {\r
1114 form.getForm().api.submit = 'TestAction.directMetaFormNamed';\r
1115 \r
1116 form.getForm().metadata = {\r
1117 foo: 'bargh!'\r
1118 };\r
1119 \r
1120 form.submit({\r
1121 success: echoFormResult,\r
1122 scope: this\r
1123 });\r
1124 });\r
1125 \r
1126 waitsFor(checkEcho, 'callback that never fired', 2000);\r
1127 \r
1128 runs(function() {\r
1129 expect(this.echo).toEqual({\r
1130 success: true,\r
1131 data: {\r
1132 hidden_foo: 'hide the sacred foo from infoodels!',\r
1133 overt_foo: 'behold the false, deceitful overt foo'\r
1134 },\r
1135 \r
1136 // JSONified!\r
1137 metadata: '{"foo":"bargh!"}'\r
1138 });\r
1139 });\r
1140 });\r
1141 \r
1142 it("should pass ordered metadata", function() {\r
1143 runs(function() {\r
1144 form.getForm().api.submit = 'TestAction.directMetaFormOrdered';\r
1145 \r
1146 form.getForm().metadata = ['bram', 'blam', 'qux?'];\r
1147 \r
1148 form.submit({\r
1149 success: echoFormResult,\r
1150 scope: this\r
1151 });\r
1152 });\r
1153 \r
1154 waitsFor(checkEcho, 'callback that never fired', 2000);\r
1155 \r
1156 runs(function() {\r
1157 expect(this.echo).toEqual({\r
1158 success: true,\r
1159 data: {\r
1160 hidden_foo: 'hide the sacred foo from infoodels!',\r
1161 overt_foo: 'behold the false, deceitful overt foo'\r
1162 },\r
1163 \r
1164 // JSONified!\r
1165 metadata: '["bram","blam"]'\r
1166 });\r
1167 });\r
1168 });\r
1169 });\r
1170 });\r
1171 });\r
1172});\r