xmppify 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +1 -0
  7. data/app/assets/javascripts/xmpp/index.js +0 -0
  8. data/app/assets/javascripts/xmpp/scripts/checkplayer.js +12 -0
  9. data/app/assets/javascripts/xmpp/scripts/crossdomain.xml +7 -0
  10. data/app/assets/javascripts/xmpp/scripts/flXHR.js +2 -0
  11. data/app/assets/javascripts/xmpp/scripts/flXHR.swf +0 -0
  12. data/app/assets/javascripts/xmpp/scripts/flXHR.vbs +44 -0
  13. data/app/assets/javascripts/xmpp/scripts/flensed.js +12 -0
  14. data/app/assets/javascripts/xmpp/scripts/strophe.flxhr.js +31 -0
  15. data/app/assets/javascripts/xmpp/scripts/strophe.js +3538 -0
  16. data/app/assets/javascripts/xmpp/scripts/swfobject.js +5 -0
  17. data/app/assets/javascripts/xmpp/scripts/updateplayer.swf +0 -0
  18. data/app/assets/javascripts/xmpp/scripts/xmpp.js.coffee +386 -0
  19. data/app/assets/javascripts/xmpp/strophejs-plugins/LICENSE.txt +19 -0
  20. data/app/assets/javascripts/xmpp/strophejs-plugins/README.markdown +95 -0
  21. data/app/assets/javascripts/xmpp/strophejs-plugins/archive/README.markdown +14 -0
  22. data/app/assets/javascripts/xmpp/strophejs-plugins/archive/iso8601_support.js +32 -0
  23. data/app/assets/javascripts/xmpp/strophejs-plugins/archive/strophe.archive.js +88 -0
  24. data/app/assets/javascripts/xmpp/strophejs-plugins/caps/README.markdown +53 -0
  25. data/app/assets/javascripts/xmpp/strophejs-plugins/caps/sha1.js +202 -0
  26. data/app/assets/javascripts/xmpp/strophejs-plugins/caps/strophe.CAPS.coffee +153 -0
  27. data/app/assets/javascripts/xmpp/strophejs-plugins/caps/strophe.CAPS.js +88 -0
  28. data/app/assets/javascripts/xmpp/strophejs-plugins/caps/strophe.caps.jsonly.js +240 -0
  29. data/app/assets/javascripts/xmpp/strophejs-plugins/chatstates/strophe.chatstates.js +80 -0
  30. data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/README.markdown +47 -0
  31. data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/spec/GetUrlComamndSpec.js +66 -0
  32. data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/spec/strophe.cmds.spec.coffee +145 -0
  33. data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/spec/support/jasmine.json +16 -0
  34. data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/src/strophe.cmds.coffee +265 -0
  35. data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/src/strophe.cmds.js +403 -0
  36. data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/README.markdown +82 -0
  37. data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/spec/strophe.x.coffee +715 -0
  38. data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/src/strophe.x.coffee +443 -0
  39. data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/src/strophe.x.js +854 -0
  40. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/.gitignore +1 -0
  41. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/README.markdown +0 -0
  42. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/convert.js +13 -0
  43. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/jasmine.json +11 -0
  44. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/lib/strophe.disco.js +137 -0
  45. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/public/javascript/strophe.disco.js +137 -0
  46. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/01_querying_information.xml +6 -0
  47. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/02_result_set_for_information_request.xml +22 -0
  48. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/03_target_entity_does_not_exist.xml +10 -0
  49. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/04_service_unavailable.xml +11 -0
  50. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/09_querying_specific_jid_and_node_combination.xml +7 -0
  51. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/10_jid_and_node_result.xml +12 -0
  52. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/11_requesting_all_items.xml +6 -0
  53. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/12_result_set_for_all_items.xml +23 -0
  54. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/13_empty_result_set.xml +7 -0
  55. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/17_service_returns_nodes.xml +16 -0
  56. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/18_requesting_further_nodes.xml +7 -0
  57. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/24_jid_and_node_error.xml +11 -0
  58. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/DiscoNodeSpec.js +50 -0
  59. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/SpecHelper.js +51 -0
  60. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/Stanzas.js +0 -0
  61. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/strophe.disco.spec.helper.js +54 -0
  62. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/strophe.disco.spec.js +0 -0
  63. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/support/jasmine.json +13 -0
  64. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/strophe.disco.js +232 -0
  65. data/app/assets/javascripts/xmpp/strophejs-plugins/epic/public/javascript/jquery.epic.js +61 -0
  66. data/app/assets/javascripts/xmpp/strophejs-plugins/epic/spec/SpecHelper.js +9 -0
  67. data/app/assets/javascripts/xmpp/strophejs-plugins/epic/spec/jquery.epic.js +39 -0
  68. data/app/assets/javascripts/xmpp/strophejs-plugins/epic/spec/support/jasmine.json +22 -0
  69. data/app/assets/javascripts/xmpp/strophejs-plugins/iexdomain/iexdomain.js +36 -0
  70. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/README.markdown +117 -0
  71. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/buster.js +23 -0
  72. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/jid.coffee +64 -0
  73. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/jid.js +92 -0
  74. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/spec/browserSetup.coffee +1 -0
  75. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/spec/jid.spec.coffee +96 -0
  76. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/spec/strophe.joap.spec.coffee +461 -0
  77. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/strophe.joap.coffee +304 -0
  78. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/strophe.joap.js +522 -0
  79. data/app/assets/javascripts/xmpp/strophejs-plugins/mam/LICENSE.txt +19 -0
  80. data/app/assets/javascripts/xmpp/strophejs-plugins/mam/README.markdown +52 -0
  81. data/app/assets/javascripts/xmpp/strophejs-plugins/mam/strophe.mam.js +62 -0
  82. data/app/assets/javascripts/xmpp/strophejs-plugins/muc/LICENSE.txt +20 -0
  83. data/app/assets/javascripts/xmpp/strophejs-plugins/muc/strophe.muc.js +1003 -0
  84. data/app/assets/javascripts/xmpp/strophejs-plugins/ping/README.markdown +28 -0
  85. data/app/assets/javascripts/xmpp/strophejs-plugins/ping/strophe.ping.js +68 -0
  86. data/app/assets/javascripts/xmpp/strophejs-plugins/private/README.markdown +16 -0
  87. data/app/assets/javascripts/xmpp/strophejs-plugins/private/strophe.private.js +192 -0
  88. data/app/assets/javascripts/xmpp/strophejs-plugins/pubsub/strophe.pubsub.js +555 -0
  89. data/app/assets/javascripts/xmpp/strophejs-plugins/receipts/strophe.receipts.js +155 -0
  90. data/app/assets/javascripts/xmpp/strophejs-plugins/register/README.markdown +44 -0
  91. data/app/assets/javascripts/xmpp/strophejs-plugins/register/strophe.register.js +431 -0
  92. data/app/assets/javascripts/xmpp/strophejs-plugins/roster/public/javascript/strophe.roster.js +40 -0
  93. data/app/assets/javascripts/xmpp/strophejs-plugins/roster/spec/strophe.roster.spec.js +65 -0
  94. data/app/assets/javascripts/xmpp/strophejs-plugins/roster/spec/support/jasmine.json +15 -0
  95. data/app/assets/javascripts/xmpp/strophejs-plugins/roster/strophe.roster.js +438 -0
  96. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/.gitignore +6 -0
  97. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/README.md +113 -0
  98. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/buster.js +11 -0
  99. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/lib/strophe.js +4198 -0
  100. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/spec/strophe.rpc.spec.helper.js +38 -0
  101. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/spec/strophe.rpc.spec.js +262 -0
  102. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/strophe.rpc.js +464 -0
  103. data/app/assets/javascripts/xmpp/strophejs-plugins/rsm/strophe.rsm.js +52 -0
  104. data/app/assets/javascripts/xmpp/strophejs-plugins/serverdate/strophe.serverdate.js +58 -0
  105. data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/examples/index.html +17 -0
  106. data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/examples/strophevcard.js +0 -0
  107. data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/strophe.vcard.coffee +44 -0
  108. data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/strophe.vcard.js +66 -0
  109. data/app/assets/stylesheets/xmpp/index.css +0 -0
  110. data/app/controllers/omniauth_callbacks_controller.rb +15 -0
  111. data/app/controllers/ruby_bosh.rb +221 -0
  112. data/app/models/identity.rb +3 -0
  113. data/app/models/user.rb +40 -0
  114. data/bin/rails +8 -0
  115. data/db/migrate/20140329065635_create_users.rb +10 -0
  116. data/db/migrate/20140329070238_create_identities.rb +11 -0
  117. data/lib/xmppify/version.rb +3 -0
  118. data/lib/xmppify.rb +6 -0
  119. data/xmppify.gemspec +23 -0
  120. metadata +197 -0
@@ -0,0 +1,38 @@
1
+ var helper = (function() {
2
+ function receive(c,req) {
3
+ c._dataRecv(createRequest(req));
4
+ }
5
+
6
+ function spyon (obj, method, cb) {
7
+ sinon.stub(obj,method, function(res) {
8
+ cb.call(this,res);
9
+ });
10
+ }
11
+
12
+ function mockConnection() {
13
+ var c = new Strophe.Connection();
14
+ c.authenticated = true;
15
+ c.jid = 'n@d/r2';
16
+ c._processRequest = function() {};
17
+ c._changeConnectStatus(Strophe.Status.CONNECTED);
18
+ return c;
19
+ }
20
+
21
+ function createRequest(iq) {
22
+ iq = typeof iq.tree == "function" ? iq.tree() : iq;
23
+ var req = new Strophe.Request(iq, function() {});
24
+ req.getResponse = function() {
25
+ var env = new Strophe.Builder('env', {type: 'mock'}).tree();
26
+ env.appendChild(iq);
27
+ return env;
28
+ };
29
+ return req;
30
+ }
31
+
32
+ return {
33
+ createRequest: createRequest,
34
+ mockConnection: mockConnection,
35
+ receive: receive,
36
+ spyon: spyon
37
+ };
38
+ })();
@@ -0,0 +1,262 @@
1
+ buster.spec.expose()
2
+
3
+ var mockConnection = helper.mockConnection,
4
+ spyon = helper.spyon, receive = helper.receive;
5
+
6
+ describe("Strophe Jabber-RPC plugin", function() {
7
+
8
+ var connection, rpc;
9
+
10
+ beforeEach(function() {
11
+ connection = mockConnection();
12
+ rpc = connection.rpc;
13
+ });
14
+
15
+ describe("Whitelist filter", function() {
16
+
17
+ it("should be deactivated be default", function() {
18
+ expect(rpc._whitelistEnabled).toBeFalsy();
19
+ expect(rpc._jidInWhitelist("foo@bar/baz")).toBeTruthy();
20
+ expect(rpc._jidInWhitelist("random@guy")).toBeTruthy();
21
+ });
22
+
23
+ it("should filter out jids", function() {
24
+ rpc.addJidToWhiteList(["foo@bar/baz", "baz@foo/bar"]);
25
+
26
+ expect(rpc._whitelistEnabled).toBeTruthy();
27
+
28
+ expect(rpc._jidInWhitelist("foo@bar/baz")).toBeTruthy();
29
+ expect(rpc._jidInWhitelist("baz@foo/bar")).toBeTruthy();
30
+ expect(rpc._jidInWhitelist("random@guy")).toBeFalsy();
31
+
32
+ expect(rpc._jidInWhitelist(connection.jid)).toBeTruthy();
33
+ });
34
+
35
+ it("should allow to use a wildcard for the node", function() {
36
+ rpc.addJidToWhiteList("*@d");
37
+
38
+ expect(rpc._whitelistEnabled).toBeTruthy();
39
+
40
+ expect(rpc._jidInWhitelist("foo@d")).toBeTruthy();
41
+ expect(rpc._jidInWhitelist("bar@d/r")).toBeTruthy();
42
+ expect(rpc._jidInWhitelist("random@guy")).toBeFalsy();
43
+ });
44
+
45
+ it("should allow the use a wildcard for the domain", function() {
46
+ rpc.addJidToWhiteList("n@*");
47
+
48
+ expect(rpc._whitelistEnabled).toBeTruthy();
49
+
50
+ expect(rpc._jidInWhitelist("n@foo")).toBeTruthy();
51
+ expect(rpc._jidInWhitelist("n@bar/r")).toBeTruthy();
52
+ expect(rpc._jidInWhitelist("random@guy")).toBeFalsy();
53
+ });
54
+
55
+ it("should allow the filter *@*", function() {
56
+ rpc.addJidToWhiteList("*@*");
57
+
58
+ expect(rpc._whitelistEnabled).toBeFalsy();
59
+ });
60
+
61
+ });
62
+
63
+ describe("Send RPC", function() {
64
+
65
+ it("should send a request message", function() {
66
+ spyon(connection, "send", function(iq) {
67
+ expect(iq.getAttribute("type")).toEqual("set");
68
+ expect(iq.getAttribute("id")).toEqual("id123");
69
+ expect(iq.getAttribute("from")).toEqual(connection.jid);
70
+ expect(iq.getAttribute("to")).toEqual("foo@bar/baz");
71
+
72
+ var query = iq.firstChild;
73
+ expect(query.getAttribute("xmlns")).toEqual(Strophe.NS.RPC);
74
+
75
+ var methodcall = query.firstChild;
76
+ expect(methodcall.tagName).toEqual("methodCall");
77
+
78
+ var methodname = methodcall.firstChild;
79
+ expect(methodname.textContent).toEqual("ping");
80
+
81
+ var params = methodcall.getElementsByTagName("params")[0].getElementsByTagName("param");
82
+ expect(params.length).toEqual(2);
83
+
84
+ var string = params[0].firstChild.firstChild;
85
+ var object = params[1].firstChild.firstChild;
86
+
87
+ expect(string.tagName).toEqual("string");
88
+ expect(string.textContent).toEqual("foo");
89
+
90
+ expect(object.tagName).toEqual("struct");
91
+ var s = new XMLSerializer();
92
+ expect(s.serializeToString(object)).toEqual(
93
+ "<struct>" +
94
+ "<member>" +
95
+ "<name>a</name><value><string>bar</string></value>" +
96
+ "</member>" +
97
+ "<member>" +
98
+ "<name>b</name><value><string>baz</string></value>" +
99
+ "</member>" +
100
+ "</struct>"
101
+ );
102
+ });
103
+ rpc.sendRequest("id123", "foo@bar/baz", "ping", ["foo", {a:"bar", b:"baz"}]);
104
+ });
105
+
106
+ it("should send a response message", function() {
107
+ spyon(connection, "send", function(iq) {
108
+ expect(iq.getAttribute("type")).toEqual("result");
109
+ expect(iq.getAttribute("id")).toEqual("id321");
110
+ expect(iq.getAttribute("from")).toEqual(connection.jid);
111
+ expect(iq.getAttribute("to")).toEqual("foo@bar/baz");
112
+
113
+ var query = iq.firstChild;
114
+ expect(query.getAttribute("xmlns")).toEqual(Strophe.NS.RPC);
115
+
116
+ var methodresponse = query.firstChild;
117
+ expect(methodresponse.tagName).toEqual("methodResponse");
118
+
119
+ var string = methodresponse.getElementsByTagName("params")[0]
120
+ .getElementsByTagName("param")[0]
121
+ .getElementsByTagName("value")[0]
122
+ .firstChild;
123
+ expect(string.tagName).toEqual("string");
124
+ expect(string.textContent).toEqual("pong");
125
+ });
126
+ rpc.sendResponse("id321", "foo@bar/baz", "pong");
127
+ });
128
+
129
+ it("should send an error message", function() {
130
+ spyon(connection, "send", function(iq) {
131
+ expect(iq.getAttribute("type")).toEqual("result");
132
+ expect(iq.getAttribute("id")).toEqual("id231");
133
+ expect(iq.getAttribute("from")).toEqual(connection.jid);
134
+ expect(iq.getAttribute("to")).toEqual("foo@bar/baz");
135
+
136
+ var query = iq.firstChild;
137
+ expect(query.getAttribute("xmlns")).toEqual(Strophe.NS.RPC);
138
+
139
+ var methodresponse = query.firstChild;
140
+ expect(methodresponse.tagName).toEqual("methodResponse");
141
+
142
+ var object = methodresponse.getElementsByTagName("fault")[0]
143
+ .getElementsByTagName("value")[0]
144
+ .firstChild;
145
+ expect(object.tagName).toEqual("struct");
146
+ var s = new XMLSerializer();
147
+ expect(s.serializeToString(object)).toEqual(
148
+ "<struct>" +
149
+ "<member>" +
150
+ "<name>faultCode</name><value><i4>-30021</i4></value>" +
151
+ "</member>" +
152
+ "<member>" +
153
+ "<name>faultString</name><value><string>error message</string></value>" +
154
+ "</member>" +
155
+ "</struct>"
156
+ );
157
+ });
158
+ rpc.sendError("id231", "foo@bar/baz", -30021 ,"error message");
159
+ });
160
+
161
+ describe("Handlers", function() {
162
+
163
+ var handler;
164
+
165
+ beforeEach(function() {
166
+ handler = sinon.spy();
167
+ });
168
+
169
+ it("should be possible to add a request handler", function() {
170
+ rpc.addRequestHandler(handler);
171
+ var iq = $iq({type: "set", id: "123", from: "foo@bar", to: connection.jid})
172
+ .c("query", {xmlns: Strophe.NS.RPC})
173
+ .c("methodCall")
174
+ .c("methodName").t("pong")
175
+ .up()
176
+ .c("params")
177
+ .c("param")
178
+ .c("value")
179
+ .c("string").t("foo")
180
+ .up().up().up()
181
+ .c("param")
182
+ .c("value")
183
+ .c("i4").t("-32");
184
+ receive(connection, iq);
185
+ expect(handler).toHaveBeenCalledWith("123", "foo@bar", "pong", ["foo", -32]);
186
+ });
187
+
188
+ it("should be possible to add a response handler", function() {
189
+ rpc.addResponseHandler(handler);
190
+ iq = $iq({ type: "result", id: "id123", from: "foo@bar/baz", to: connection.jid })
191
+ .c("query", {xmlns: Strophe.NS.RPC})
192
+ .c("methodResponse")
193
+ .c("params")
194
+ .c("param")
195
+ .c("value")
196
+ .c("string").t("foo");
197
+ receive(connection, iq);
198
+ expect(handler).toHaveBeenCalledWith("id123", "foo@bar/baz", "foo", false);
199
+ });
200
+
201
+ it("should be possible to parse a fault response", function() {
202
+ rpc.addResponseHandler(handler);
203
+ var iq =$iq({type: "result", id: "123", from: "foo@bar", to: connection.jid})
204
+ .c("query", {xmlns: Strophe.NS.RPC})
205
+ .c("methodResponse")
206
+ .c("fault")
207
+ .c("value")
208
+ .c("struct")
209
+ .c("member")
210
+ .c("name").t("faultString")
211
+ .up()
212
+ .c("value")
213
+ .c("string").t("parsererror");
214
+ receive(connection, iq);
215
+ expect(handler).toHaveBeenCalledWith("123", "foo@bar", {faultString:"parsererror"}, true)
216
+ });
217
+
218
+ });
219
+
220
+ describe("Forbidden access", function() {
221
+
222
+ beforeEach(function() {
223
+ rpc.addJidToWhiteList(["*@jabber.org", "*@localhost"]);
224
+ });
225
+
226
+ it("should send forbidden access to the wrong nodes", function() {
227
+ var handler = function() {};
228
+ rpc.addHandlers(handler, handler);
229
+ spyon(connection, "send", function(iq) {
230
+ expect(iq.getAttribute("type")).toEqual("error");
231
+ expect(iq.getAttribute("id")).toEqual("123");
232
+ expect(iq.getAttribute("from")).toEqual(connection.jid);
233
+ expect(iq.getAttribute("to")).toEqual("foo@bar");
234
+
235
+ var error = iq.firstChild;
236
+ expect(error.tagName).toEqual("error");
237
+ expect(error.getAttribute("code")).toEqual("403");
238
+ expect(error.getAttribute("type")).toEqual("auth");
239
+
240
+ var forbidden = error.firstChild;
241
+ expect(forbidden.tagName).toEqual("forbidden");
242
+ expect(forbidden.getAttribute("xmlns")).toEqual(Strophe.NS.STANZAS);
243
+ });
244
+
245
+ var iq = $iq({type: "set", id: "123", from: "foo@bar", to: connection.jid})
246
+ .c("query", {xmlns: Strophe.NS.RPC});
247
+ receive(connection, iq);
248
+ });
249
+
250
+ it("should NOT send forbidden access to the right nodes", function() {
251
+ spyon(connection, "send");
252
+ var iq = $iq({type: "set", id: "123", from: "foo@jabber.org", to: connection.jid})
253
+ .c("query", {xmlns: Strophe.NS.RPC});
254
+ receive(connection, iq);
255
+ expect(connection.send).not.toHaveBeenCalled();
256
+ });
257
+
258
+ });
259
+
260
+ });
261
+
262
+ });