UNPKG

6.01 kBJavaScriptView Raw
1"use strict";
2import querystring from "querystring";
3
4module.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 // If we set a HTTP method property, let's assert that the correct
67 // one was used
68 if (this._httpMethod) {
69 let calledVerb = args[1];
70
71 // It may be a file POST
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 // If we were expecting a multipart post, make sure we got one
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 // Next up, let's check that the path we called is what we expected
99 let calledPath = args[0].path;
100 if (isFilePost) {
101 calledPath = args[0].url.split("nexmo.com")[1];
102 }
103
104 // We strip api_key and api_secret out of `path` so that our tests
105 // only look for specific parameters
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 // Make our assertion
117 // Next up, let's check that the path we called is what we expected
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 // Next up, let's check that the path we called is what we expected
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 }; // End of callback
167
168 // Make sure we have parameters to pass to the method
169 this._params = this._params || [];
170
171 // Add in our callback which resolves the promise we returned
172 this._params.push(callback);
173
174 // Stub our HTTPClient call so that we can capture it
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};