UNPKG

14.4 kBJavaScriptView Raw
1"use strict";
2var sinon = require('sinon');
3var chai = require('chai');
4var chaiAsPromised = require('chai-as-promised');
5var sinonChai = require('sinon-chai');
6var graphql_1 = require('graphql');
7var pubsub_1 = require('../pubsub');
8var validation_1 = require('../validation');
9chai.use(chaiAsPromised);
10chai.use(sinonChai);
11var expect = chai.expect;
12var assert = chai.assert;
13describe('PubSub', function () {
14 it('can subscribe and is called when events happen', function (done) {
15 var ps = new pubsub_1.PubSub();
16 ps.subscribe('a', function (payload) {
17 expect(payload).to.equals('test');
18 done();
19 }).then(function () {
20 var succeed = ps.publish('a', 'test');
21 expect(succeed).to.be.true;
22 });
23 });
24 it('can unsubscribe', function (done) {
25 var ps = new pubsub_1.PubSub();
26 ps.subscribe('a', function (payload) {
27 assert(false);
28 }).then(function (subId) {
29 ps.unsubscribe(subId);
30 var succeed = ps.publish('a', 'test');
31 expect(succeed).to.be.true;
32 done();
33 });
34 });
35});
36var schema = new graphql_1.GraphQLSchema({
37 query: new graphql_1.GraphQLObjectType({
38 name: 'Query',
39 fields: {
40 testString: {
41 type: graphql_1.GraphQLString,
42 resolve: function (_, args) {
43 return 'works';
44 },
45 },
46 },
47 }),
48 subscription: new graphql_1.GraphQLObjectType({
49 name: 'Subscription',
50 fields: {
51 testSubscription: {
52 type: graphql_1.GraphQLString,
53 resolve: function (root) {
54 return root;
55 },
56 },
57 testContext: {
58 type: graphql_1.GraphQLString,
59 resolve: function (rootValue, args, context) {
60 return context;
61 },
62 },
63 testFilter: {
64 type: graphql_1.GraphQLString,
65 resolve: function (root, _a) {
66 var filterBoolean = _a.filterBoolean;
67 return filterBoolean ? 'goodFilter' : 'badFilter';
68 },
69 args: {
70 filterBoolean: { type: graphql_1.GraphQLBoolean },
71 },
72 },
73 testFilterMulti: {
74 type: graphql_1.GraphQLString,
75 resolve: function (root, _a) {
76 var filterBoolean = _a.filterBoolean;
77 return filterBoolean ? 'goodFilter' : 'badFilter';
78 },
79 args: {
80 filterBoolean: { type: graphql_1.GraphQLBoolean },
81 a: { type: graphql_1.GraphQLString },
82 b: { type: graphql_1.GraphQLInt },
83 },
84 },
85 testChannelOptions: {
86 type: graphql_1.GraphQLString,
87 resolve: function (root) {
88 return root;
89 },
90 },
91 },
92 }),
93});
94describe('SubscriptionManager', function () {
95 var pubsub = new pubsub_1.PubSub();
96 var subManager = new pubsub_1.SubscriptionManager({
97 schema: schema,
98 setupFunctions: {
99 'testFilter': function (options, _a) {
100 var filterBoolean = _a.filterBoolean;
101 return {
102 'Filter1': {
103 filter: function (root) { return root.filterBoolean === filterBoolean; },
104 },
105 };
106 },
107 'testFilterMulti': function (options) {
108 return {
109 'Trigger1': {
110 filter: function () { return true; },
111 },
112 'Trigger2': {
113 filter: function () { return true; },
114 },
115 };
116 },
117 'testChannelOptions': function () {
118 return {
119 'Trigger1': {
120 channelOptions: {
121 foo: 'bar',
122 },
123 },
124 };
125 },
126 testContext: function (options) {
127 return {
128 contextTrigger: function (rootValue, context) {
129 return context === 'trigger';
130 },
131 };
132 },
133 },
134 pubsub: pubsub,
135 });
136 beforeEach(function () {
137 sinon.spy(pubsub, 'subscribe');
138 });
139 afterEach(function () {
140 sinon.restore(pubsub.subscribe);
141 });
142 it('throws an error if query is not valid', function () {
143 var query = 'query a{ testInt }';
144 var callback = function () { return null; };
145 return expect(subManager.subscribe({ query: query, operationName: 'a', callback: callback }))
146 .to.eventually.be.rejectedWith('Subscription query has validation errors');
147 });
148 it('rejects subscriptions with more than one root field', function () {
149 var query = 'subscription X{ a: testSubscription, b: testSubscription }';
150 var callback = function () { return null; };
151 return expect(subManager.subscribe({ query: query, operationName: 'X', callback: callback }))
152 .to.eventually.be.rejectedWith('Subscription query has validation errors');
153 });
154 it('can subscribe with a valid query and gets a subId back', function () {
155 var query = 'subscription X{ testSubscription }';
156 var callback = function () { return null; };
157 subManager.subscribe({ query: query, operationName: 'X', callback: callback }).then(function (subId) {
158 expect(subId).to.be.a('number');
159 subManager.unsubscribe(subId);
160 });
161 });
162 it('can subscribe with a valid query and get the root value', function (done) {
163 var query = 'subscription X{ testSubscription }';
164 var callback = function (err, payload) {
165 try {
166 expect(payload.data.testSubscription).to.equals('good');
167 }
168 catch (e) {
169 done(e);
170 return;
171 }
172 done();
173 };
174 subManager.subscribe({ query: query, operationName: 'X', callback: callback }).then(function (subId) {
175 subManager.publish('testSubscription', 'good');
176 subManager.unsubscribe(subId);
177 });
178 });
179 it('can use filter functions properly', function (done) {
180 var query = "subscription Filter1($filterBoolean: Boolean){\n testFilter(filterBoolean: $filterBoolean)\n }";
181 var callback = function (err, payload) {
182 try {
183 expect(payload.data.testFilter).to.equals('goodFilter');
184 }
185 catch (e) {
186 done(e);
187 return;
188 }
189 done();
190 };
191 subManager.subscribe({
192 query: query,
193 operationName: 'Filter1',
194 variables: { filterBoolean: true },
195 callback: callback,
196 }).then(function (subId) {
197 subManager.publish('Filter1', { filterBoolean: false });
198 subManager.publish('Filter1', { filterBoolean: true });
199 subManager.unsubscribe(subId);
200 });
201 });
202 it('can subscribe to more than one trigger', function (done) {
203 var triggerCount = 0;
204 var query = "subscription multiTrigger($filterBoolean: Boolean, $uga: String){\n testFilterMulti(filterBoolean: $filterBoolean, a: $uga, b: 66)\n }";
205 var callback = function (err, payload) {
206 try {
207 expect(payload.data.testFilterMulti).to.equals('goodFilter');
208 triggerCount++;
209 }
210 catch (e) {
211 done(e);
212 return;
213 }
214 if (triggerCount === 2) {
215 done();
216 }
217 };
218 subManager.subscribe({
219 query: query,
220 operationName: 'multiTrigger',
221 variables: { filterBoolean: true, uga: 'UGA' },
222 callback: callback,
223 }).then(function (subId) {
224 subManager.publish('NotATrigger', { filterBoolean: false });
225 subManager.publish('Trigger1', { filterBoolean: true });
226 subManager.publish('Trigger2', { filterBoolean: true });
227 subManager.unsubscribe(subId);
228 });
229 });
230 it('can subscribe to a trigger and pass options to PubSub using "channelOptions"', function (done) {
231 var query = 'subscription X{ testChannelOptions }';
232 subManager.subscribe({
233 query: query,
234 operationName: 'X',
235 callback: function () { return null; },
236 }).then(function () {
237 expect(pubsub.subscribe).to.have.been.calledOnce;
238 var expectedChannelOptions = {
239 foo: 'bar',
240 };
241 expect(pubsub.subscribe).to.have.been.calledWith(sinon.match.string, sinon.match.func, expectedChannelOptions);
242 done();
243 }).catch(function (err) {
244 done(err);
245 });
246 });
247 it('can unsubscribe', function (done) {
248 var query = 'subscription X{ testSubscription }';
249 var callback = function (err, payload) {
250 try {
251 assert(false);
252 }
253 catch (e) {
254 done(e);
255 return;
256 }
257 done();
258 };
259 subManager.subscribe({ query: query, operationName: 'X', callback: callback }).then(function (subId) {
260 subManager.unsubscribe(subId);
261 subManager.publish('testSubscription', 'bad');
262 setTimeout(done, 30);
263 });
264 });
265 it('throws an error when trying to unsubscribe from unknown id', function () {
266 expect(function () { return subManager.unsubscribe(123); })
267 .to.throw('undefined');
268 });
269 it('calls the error callback if there is an execution error', function (done) {
270 var query = "subscription X($uga: Boolean!){\n testSubscription @skip(if: $uga)\n }";
271 var callback = function (err, payload) {
272 try {
273 expect(payload).to.be.undefined;
274 expect(err.message).to.equals('Variable "$uga" of required type "Boolean!" was not provided.');
275 }
276 catch (e) {
277 done(e);
278 return;
279 }
280 done();
281 };
282 subManager.subscribe({ query: query, operationName: 'X', callback: callback }).then(function (subId) {
283 subManager.publish('testSubscription', 'good');
284 subManager.unsubscribe(subId);
285 });
286 });
287 it('calls context if it is a function', function (done) {
288 var query = "subscription TestContext { testContext }";
289 var callback = function (error, payload) {
290 expect(error).to.be.null;
291 expect(payload.data.testContext).to.eq('trigger');
292 done();
293 };
294 var context = function () {
295 return 'trigger';
296 };
297 subManager.subscribe({
298 query: query,
299 context: context,
300 operationName: 'TestContext',
301 variables: {},
302 callback: callback,
303 }).then(function (subId) {
304 subManager.publish('contextTrigger', 'ignored');
305 subManager.unsubscribe(subId);
306 });
307 });
308});
309var validationSchema = new graphql_1.GraphQLSchema({
310 query: new graphql_1.GraphQLObjectType({
311 name: 'Query',
312 fields: {
313 placeholder: { type: graphql_1.GraphQLString },
314 },
315 }),
316 subscription: new graphql_1.GraphQLObjectType({
317 name: 'Subscription',
318 fields: {
319 test1: { type: graphql_1.GraphQLString },
320 test2: { type: graphql_1.GraphQLString },
321 },
322 }),
323});
324describe('SubscriptionValidationRule', function () {
325 it('should allow a valid subscription', function () {
326 var sub = "subscription S1{\n test1\n }";
327 var errors = graphql_1.validate(validationSchema, graphql_1.parse(sub), [validation_1.subscriptionHasSingleRootField]);
328 expect(errors.length).to.equals(0);
329 });
330 it('should allow another valid subscription', function () {
331 var sub = "\n subscription S1{\n test1\n }\n subscription S2{\n test2\n }";
332 var errors = graphql_1.validate(validationSchema, graphql_1.parse(sub), [validation_1.subscriptionHasSingleRootField]);
333 expect(errors.length).to.equals(0);
334 });
335 it('should allow two valid subscription definitions', function () {
336 var sub = "subscription S2{\n test2\n }";
337 var errors = graphql_1.validate(validationSchema, graphql_1.parse(sub), [validation_1.subscriptionHasSingleRootField]);
338 expect(errors.length).to.equals(0);
339 });
340 it('should not allow two fields in the subscription', function () {
341 var sub = "subscription S3{\n test1\n test2\n }";
342 var errors = graphql_1.validate(validationSchema, graphql_1.parse(sub), [validation_1.subscriptionHasSingleRootField]);
343 expect(errors.length).to.equals(1);
344 expect(errors[0].message).to.equals('Subscription "S3" must have only one field.');
345 });
346 it('should not allow inline fragments', function () {
347 var sub = "subscription S4{\n ... on Subscription {\n test1\n }\n }";
348 var errors = graphql_1.validate(validationSchema, graphql_1.parse(sub), [validation_1.subscriptionHasSingleRootField]);
349 expect(errors.length).to.equals(1);
350 expect(errors[0].message).to.equals('Apollo subscriptions do not support fragments on the root field');
351 });
352 it('should not allow named fragments', function () {
353 var sub = "subscription S5{\n ...testFragment\n }\n\n fragment testFragment on Subscription{\n test2\n }";
354 var errors = graphql_1.validate(validationSchema, graphql_1.parse(sub), [validation_1.subscriptionHasSingleRootField]);
355 expect(errors.length).to.equals(1);
356 expect(errors[0].message).to.equals('Apollo subscriptions do not support fragments on the root field');
357 });
358});
359//# sourceMappingURL=tests.js.map
\No newline at end of file