1 | "use strict";
|
2 | import querystring from "querystring";
|
3 |
|
4 | module.exports = function(chai, utils) {
|
5 | utils.addChainableMethod(chai.Assertion.prototype, "call", function() {});
|
6 |
|
7 | utils.addProperty(chai.Assertion.prototype, "get", function() {
|
8 | this._httpMethod = "GET";
|
9 | });
|
10 |
|
11 | utils.addProperty(chai.Assertion.prototype, "post", function() {
|
12 | this._httpMethod = "POST";
|
13 | });
|
14 |
|
15 | utils.addProperty(chai.Assertion.prototype, "postFile", function() {
|
16 | this._httpMethod = "POST";
|
17 | this._isMultipartPost = true;
|
18 | });
|
19 |
|
20 | utils.addProperty(chai.Assertion.prototype, "put", function() {
|
21 | this._httpMethod = "PUT";
|
22 | });
|
23 |
|
24 | utils.addProperty(chai.Assertion.prototype, "delete", function() {
|
25 | this._httpMethod = "DELETE";
|
26 | });
|
27 |
|
28 | utils.addChainableMethod(chai.Assertion.prototype, "method", function(
|
29 | method
|
30 | ) {
|
31 | this._classMethod = method;
|
32 | });
|
33 | utils.addChainableMethod(chai.Assertion.prototype, "withParams", function() {
|
34 | this._params = Array.prototype.slice.call(arguments);
|
35 | });
|
36 | utils.addChainableMethod(
|
37 | chai.Assertion.prototype,
|
38 | "withJsonBody",
|
39 | function() {
|
40 | this._expectedHeaders = this._expectedHeaders || {};
|
41 | this._expectedHeaders["Content-Type"] = "application/json";
|
42 | this._expectedJsonBody = JSON.stringify(
|
43 | Array.prototype.slice.call(arguments)[0]
|
44 | );
|
45 | }
|
46 | );
|
47 |
|
48 | utils.addMethod(chai.Assertion.prototype, "url", function(url) {
|
49 | let spy;
|
50 |
|
51 | return new Promise(resolve => {
|
52 | const callback = (err, data) => {
|
53 | if (!spy.args) {
|
54 | throw new Error("This assertion should only be used on Sinon spies");
|
55 | }
|
56 | if (!spy.args[0]) {
|
57 | throw new Error(
|
58 | "Spy was never called; cannot access arguments to check URL"
|
59 | );
|
60 | }
|
61 |
|
62 | let args = spy.args[0];
|
63 |
|
64 | const isFilePost = args[0].formData ? true : false;
|
65 |
|
66 |
|
67 |
|
68 | if (this._httpMethod) {
|
69 | let calledVerb = args[1];
|
70 |
|
71 |
|
72 | if (isFilePost) {
|
73 | calledVerb = "POST";
|
74 | }
|
75 |
|
76 | const verb = new chai.Assertion(calledVerb.toUpperCase());
|
77 | verb.assert(
|
78 | verb._obj === this._httpMethod,
|
79 | "expected HTTP verb #{this} to match '" + this._httpMethod + "'",
|
80 | "expected HTTP verb #{this} to not match '" + this._httpMethod + "'"
|
81 | );
|
82 | }
|
83 |
|
84 |
|
85 | if (this._multipartPost) {
|
86 | const classMethod = new chai.Assertion(this._classMethod);
|
87 | classMethod.assert(
|
88 | classMethod._obj === "postFile",
|
89 | "expected HTTPClient method called #{this} to match '" +
|
90 | this._httpMethod +
|
91 | "'",
|
92 | "expected HTTPClient method called #{this} to not match '" +
|
93 | this._httpMethod +
|
94 | "'"
|
95 | );
|
96 | }
|
97 |
|
98 |
|
99 | let calledPath = args[0].path;
|
100 | if (isFilePost) {
|
101 | calledPath = args[0].url.split("nexmo.com")[1];
|
102 | }
|
103 |
|
104 |
|
105 |
|
106 | var qs = calledPath.split("?");
|
107 | var qsParts = querystring.parse(qs[1]);
|
108 | delete qsParts["api_key"];
|
109 | delete qsParts["api_secret"];
|
110 |
|
111 | calledPath = qs[0];
|
112 | if (Object.keys(qsParts).length) {
|
113 | calledPath += "?" + querystring.stringify(qsParts);
|
114 | }
|
115 |
|
116 |
|
117 |
|
118 | const path = new chai.Assertion(calledPath);
|
119 | path.assert(
|
120 | path._obj === url,
|
121 | "expected url #{this} to match '" + url + "'",
|
122 | "expected url #{this} to not match '" + url + "'"
|
123 | );
|
124 |
|
125 |
|
126 | if (this._expectedJsonBody) {
|
127 | let requestBody = args[0].body;
|
128 | const body = new chai.Assertion(requestBody);
|
129 | body.assert(
|
130 | body._obj === this._expectedJsonBody,
|
131 | "expected body #{this} to match '" + this._expectedJsonBody + "'",
|
132 | "expected body #{this} to not match '" +
|
133 | this._expectedJsonBody +
|
134 | "'"
|
135 | );
|
136 | }
|
137 |
|
138 | if (
|
139 | this._expectedHeaders &&
|
140 | Object.keys(this._expectedHeaders).length
|
141 | ) {
|
142 | let requestHeaders = args[0].headers;
|
143 | for (let headerName in requestHeaders) {
|
144 | let header = new chai.Assertion(requestHeaders[headerName]);
|
145 | header.assert(
|
146 | header._obj === requestHeaders[headerName],
|
147 | "expected header " +
|
148 | headerName +
|
149 | " (" +
|
150 | requestHeaders[headerName] +
|
151 | ") to match '" +
|
152 | this._expectedHeaders[headerName] +
|
153 | "'",
|
154 | "expected header " +
|
155 | headerName +
|
156 | " (" +
|
157 | requestHeaders[headerName] +
|
158 | ") to not match '" +
|
159 | this._expectedHeaders[headerName] +
|
160 | "'"
|
161 | );
|
162 | }
|
163 | }
|
164 |
|
165 | return resolve(data);
|
166 | };
|
167 |
|
168 |
|
169 | this._params = this._params || [];
|
170 |
|
171 |
|
172 | this._params.push(callback);
|
173 |
|
174 |
|
175 | this._httpClient = this._obj.options.rest || this._obj.options.api;
|
176 |
|
177 | if (this._isMultipartPost) {
|
178 | spy = this._httpClient.requestLib.post;
|
179 | } else {
|
180 | spy = this._httpClient.request;
|
181 | }
|
182 |
|
183 | spy.yields(null, {});
|
184 |
|
185 | let m = this._obj[this._classMethod];
|
186 | m.apply(this._obj, this._params);
|
187 | });
|
188 | });
|
189 | };
|