X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;ds=sidebyside;f=test-e2e%2Ffake-servers.js;fp=test-e2e%2Ffake-servers.js;h=0adff34edadff9d0a1ae7c61cde230a9e8f8d8c3;hb=9696c012e6b9a6c58904baa397ca0ebf78112316;hp=0000000000000000000000000000000000000000;hpb=f59e918f3aba3a218c94a252072801fc40527647;p=websub-hub diff --git a/test-e2e/fake-servers.js b/test-e2e/fake-servers.js new file mode 100644 index 0000000..0adff34 --- /dev/null +++ b/test-e2e/fake-servers.js @@ -0,0 +1,174 @@ +/* eslint-disable sonarjs/no-duplicate-string */ +'use strict'; + +/** + * For testing, this is a configurable endpoint server. + * + * Set how a subscriber id responds to a verification GET call + * PUT /subscriber/:id/verify?responseCode=xxx&matchChallenge=true + * Set how an id responds to a content delivery POST call + * PUT /subscriber/:id/content?responseCode=xxx + * Remove an id + * DELETE /subscriber/:id + * + * Set how a topic id returns + * PUT /topic/:id?statusCode=xxx&content=xxx&contentType=foo/bar + */ + +const http = require('http'); +const { Dingus, Enum, Errors } = require('@squeep/api-dingus'); + +const subscriberPort = process.env.FAKE_SUBSCRIBER_PORT || 9876; +const topicPort = process.env.FAKE_TOPIC_PORT || 9875; +const listenAddress = process.env.FAKE_LISTEN_ADDR || '127.0.0.1'; + +class TopicFake extends Dingus { + constructor() { + super(console, { + ignoreTrailingSlash: true, + }); + this.topicBehaviors = new Map(); + this.on(['GET'], '/topic/:id', this.getId.bind(this)); + + this.on(['PUT'], '/topic/:id', this.putId.bind(this)); + this.on(['DELETE'], '/topic/:id', this.deleteId.bind(this)); + } + + async getId(req, res, ctx) { + this.setResponseType(this.responseTypes, req, res, ctx); + const behavior = this.topicBehaviors.get(ctx.params.id); + if (!behavior) { + throw new Errors.ResponseError(Enum.ErrorResponse.NotFound); + } + if (behavior.contentType) { + res.setHeader(Enum.Header.ContentType, behavior.contentType); + } + res.setHeader('Link', behavior.selfLink + (behavior.hubLink ? `, ${behavior.hubLink}` : '')); + res.statusCode = behavior.statusCode; + res.end(behavior.content); + this.logger.info({ method: req.method, statusCode: res.statusCode }); + } + + async putId(req, res, ctx) { + const id = ctx.params.id; + this.setResponseType(this.responseTypes, req, res, ctx); + const behavior = { + statusCode: ctx.queryParams.statusCode || 200, + ...(ctx.queryParams.contentType && { contentType: ctx.queryParams.contentType }), + content: ctx.queryParams.content, + selfLink: `; rel="self"`, + ...(ctx.queryParams.hubUrl && { hubLink: `<${ctx.queryParams.hubUrl}>; rel="hub"` }), + }; + this.topicBehaviors.set(id, behavior); + res.statusCode = 200; + res.end(); + } + + async deleteId(req, res, ctx) { + this.setResponseType(this.responseTypes, req, res, ctx); + this.topicBehaviors.delete(ctx.params.id); + res.statusCode = 200; + res.end(); + } + +} // TopicFake + +class SubscriberFake extends Dingus { + constructor() { + super(console, { + ignoreTrailingSlash: true, + }); + this.verifyBehaviors = new Map(); + this.contentBehaviors = new Map(); + this.on(['GET'], '/subscriber/:id', this.getId.bind(this)); + this.on(['POST'], '/subscriber/:id', this.postId.bind(this)); + + this.on(['PUT'], '/subscriber/:id/verify', this.putVerify.bind(this)); + this.on(['PUT'], '/subscriber/:id/content', this.putContent.bind(this)); + this.on(['DELETE'], '/subscriber/:id', this.deleteId.bind(this)); + } + + // eslint-disable-next-line class-methods-use-this + parseBody() { + // do not parse, just ingest + } + + async getId(req, res, ctx) { + this.setResponseType(this.responseTypes, req, res, ctx); + const behavior = this.verifyBehaviors.get(ctx.params.id); + res.statusCode = behavior ? behavior.statusCode : 404; + const response = (behavior && behavior.matchChallenge) ? ctx.queryParams['hub.challenge'] : (behavior && behavior.response); + res.end(response); + this.logger.info({ method: req.method, statusCode: res.statusCode, matchChallenge: !!(behavior && behavior.matchChallenge) }); + } + + async postId(req, res, ctx) { + this.setResponseType(this.responseTypes, req, res, ctx); + await this.ingestBody(req, res, ctx); + const behavior = this.contentBehaviors.get(ctx.params.id); + res.statusCode = behavior ? behavior.statusCode : 404; + if (behavior) { + behavior.updated = new Date(); + behavior.content = ctx.rawBody; + } + res.end(); + this.logger.info({ content: behavior && behavior.content, method: req.method, statusCode: res.statusCode, matchChallenge: !!(behavior && behavior.matchChallenge) }); + } + + async putVerify(req, res, ctx) { + this.setResponseType(this.responseTypes, req, res, ctx); + const behavior = { + matchChallenge: ctx.queryParams.matchChallenge === 'true', + statusCode: ctx.queryParams.statusCode || 200, + }; + this.verifyBehaviors.set(ctx.params.id, behavior); + if (!this.contentBehaviors.get(ctx.params.id)) { + this.contentBehaviors.set(ctx.params.id, { + statusCode: 200, + }); + } + res.statusCode = 200; + res.end(); + } + + async putContent(req, res, ctx) { + this.setResponseType(this.responseTypes, req, res, ctx); + const behavior = { + statusCode: ctx.queryParams.statusCode || 200, + }; + this.contentBehaviors.set(ctx.params.id, behavior); + res.statusCode = 200; + res.end(); + } + + async deleteId(req, res, ctx) { + this.setResponseType(this.responseTypes, req, res, ctx); + this.contentBehaviors.delete(ctx.params.id); + this.verifyBehaviors.delete(ctx.params.id); + res.statusCode = 200; + res.end(); + } + +} // SubscriberFake + +const subscriberService = new SubscriberFake(); +http.createServer((req, res) => { + subscriberService.dispatch(req, res); +}).listen(subscriberPort, listenAddress, (err) => { + if (err) { + console.error(err); + throw err; + } + console.log(`Fake Subscriber Server started on ${listenAddress}:${subscriberPort}`); +}); + +const topicService = new TopicFake(); +http.createServer((req, res) => { + topicService.dispatch(req, res); +}).listen(topicPort, listenAddress, (err) => { + if (err) { + console.error(err); + throw err; + } + console.log(`Fake Topic Server started on ${listenAddress}:${topicPort}`); +});