update dependencies, devDependencies, copyright
[websub-hub] / test-e2e / fake-servers-client.js
1 'use strict';
2
3 /**
4 * Wrapper interface for controlling fake-servers.
5 */
6
7 class FakeClient {
8 constructor(host, subscriberPort, topicPort) {
9 this.logger = console;
10 this.host = host;
11 this.subscriberPort = subscriberPort;
12 this.topicPort = topicPort;
13 this.Got = undefined;
14 this.got = this._init.bind(this);
15 }
16
17 async _init(...args) {
18 if (!this.Got) {
19 // eslint-disable-next-line
20 this.Got = await import('got');
21 this.got = this.Got.got.extend({
22 headers: {
23 'User-Agent': 'FakeClient',
24 },
25 responseType: 'text',
26 });
27 }
28 if (args.length) {
29 return this.got(...args);
30 }
31 }
32
33 topicUrl(id) {
34 return `http://${this.host}:${this.topicPort}/topic/${id}`;
35 }
36
37 subscriberUrl(id, extra = '') {
38 return `http://${this.host}:${this.subscriberPort}/subscriber/${id}${extra}`;
39 }
40
41 static _requestConfig(method, url, params = {}, headers = {}, body = undefined) {
42 const gotConfig = {
43 method,
44 url: new URL(url),
45 headers,
46 ...(body && { body }),
47 };
48 Object.entries(params).forEach(([k, v]) => gotConfig.url.searchParams.set(k, v));
49 return gotConfig;
50 }
51
52 static _formData(obj) {
53 return Object.entries(obj)
54 .map((entry) => entry.map(encodeURIComponent).join('='))
55 .join('&')
56 ;
57 }
58
59 async subscribe(hubUrl, subscriberId, topicId, postData = {}) {
60 const topicUrl = this.topicUrl(topicId);
61 const subscriberUrl = this.subscriberUrl(subscriberId);
62 const data = FakeClient._formData({
63 'hub.callback': subscriberUrl,
64 'hub.mode': 'subscribe',
65 'hub.topic': topicUrl,
66 'hub.lease_seconds': 60,
67 'hub.secret': 'sharedSecret',
68 ...postData,
69 });
70 const config = FakeClient._requestConfig('POST', hubUrl, {}, {
71 'Content-Type': 'application/x-www-form-urlencoded',
72 }, data);
73 try {
74 return await this.got(config);
75 } catch (error) {
76 this.logger.error('subscribe', error, config);
77 throw error;
78 }
79 }
80
81 /**
82 * Set the behavior for a topic id.
83 * @param {String} id
84 * @param {Object} behavior
85 * @param {Number} behavior.statusCode
86 * @param {String} behavior.content
87 * @param {String} behavior.contentType
88 * @param {String} behavior.hubUrl
89 */
90 async topicSet(id, behavior = {}) {
91 const defaultBehavior = {
92 statusCode: 200,
93 content: 'some content',
94 contentType: 'text/plain',
95 };
96 const url = this.topicUrl(id);
97 const config = FakeClient._requestConfig('PUT', url, {
98 ...defaultBehavior,
99 ...behavior,
100 });
101 try {
102 return await this.got(config);
103 } catch (error) {
104 this.logger.error('topicSet', error, config);
105 throw error;
106 }
107 }
108
109 /**
110 * Remove a topic id.
111 * @param {String} id
112 */
113 async topicDelete(id) {
114 const url = this.topicUrl(id);
115 const config = FakeClient._requestConfig('DELETE', url);
116 try {
117 return await this.got(config);
118 } catch (error) {
119 this.logger.error('topicDelete', error, config);
120 throw error;
121 }
122 }
123
124 /**
125 * Set the behavior for a subscriber id verify response.
126 * @param {String} id
127 * @param {Object} behavior
128 * @param {Number} behavior.statusCode
129 * @param {Boolean} behavior.matchChallenge
130 */
131 async subscriberSetVerify(id, behavior = {}) {
132 const defaultBehavior = {
133 statusCode: 200,
134 matchChallenge: true,
135 };
136 const url = this.subscriberUrl(id, '/verify');
137 const config = FakeClient._requestConfig('PUT', url, {
138 ...defaultBehavior,
139 ...behavior,
140 });
141 try {
142 return await this.got(config);
143 } catch (error) {
144 this.logger.error('subscriberSetVerify', error, config);
145 throw error;
146 }
147 }
148
149 /**
150 * Set the behavior for a subscriber id content-update response.
151 * @param {String} id
152 * @param {Object} behavior
153 * @param {Number} behavior.statusCode
154 */
155 async subscriberSetContent(id, behavior = {}) {
156 const defaultBehavior = {
157 statusCode: 200,
158 };
159 const url = this.subscriberUrl(id, '/content');
160 const config = FakeClient._requestConfig('PUT', url, {
161 ...defaultBehavior,
162 ...behavior,
163 });
164 try {
165 return await this.got(config);
166 } catch (error) {
167 this.logger.error('subscriberSetContent', error, config);
168 throw error;
169 }
170 }
171
172 /**
173 * Removes a topic id.
174 * @param {String} id
175 */
176 async subscriberDelete(id) {
177 const url = this.subscriberUrl(id);
178 const config = FakeClient._requestConfig('DELETE', url);
179 try {
180 return await this.got(config);
181 } catch (error) {
182 this.logger.error('subscriberDelete', error, config);
183 throw error;
184 }
185 }
186
187 } // FakeClient
188
189 module.exports = FakeClient;