]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | describe("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 |