X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=test%2Fsrc%2Fcommunication.js;h=69f0453c6278859f7140dfffd3b37d525f5d070f;hb=refs%2Ftags%2Fv1.3.12;hp=ca5f34e92c536458171c18fa8cd4f78976a5bf11;hpb=9f9d3c81cc0960f03e6598258d36ad828058f65f;p=websub-hub
diff --git a/test/src/communication.js b/test/src/communication.js
index ca5f34e..69f0453 100644
--- a/test/src/communication.js
+++ b/test/src/communication.js
@@ -1,10 +1,7 @@
-/* eslint-env mocha */
-/* eslint-disable capitalized-comments, sonarjs/no-duplicate-string */
-
'use strict';
-const assert = require('assert');
-const sinon = require('sinon'); // eslint-disable-line node/no-unpublished-require
+const assert = require('node:assert');
+const sinon = require('sinon');
const Communication = require('../../src/communication');
const Config = require('../../config');
@@ -37,20 +34,23 @@ describe('Communication', function () {
communication = new Communication(stubLogger, stubDb, options);
});
- describe('Axios timing coverage', function () {
- const request = {};
- const response = {
- config: request,
- };
- it('tags request', function () {
- communication.axios.interceptors.request.handlers[0].fulfilled(request);
- assert(request.startTimestampMs);
+ describe('_init', function () {
+ it('covers', async function () {
+ await communication._init();
+ await communication._init();
+ assert(communication.Got);
+ assert(communication.got);
});
- it('tags response', function () {
- communication.axios.interceptors.response.handlers[0].fulfilled(response);
- assert(response.elapsedTimeMs);
+ });
+
+ describe('_onRetry', function () {
+ it('covers', function () {
+ const error = {};
+ const retryCount = 1;
+ communication._onRetry(error, retryCount);
+ assert(communication.logger.debug.called);
});
- }); // Axios timing coverage
+ });
describe('userAgentString', function () {
it('has default behavior', function () {
@@ -110,134 +110,8 @@ describe('Communication', function () {
it('hashes', function () {
const result = Communication.contentHash(content, algorithm);
assert.strictEqual(result, expected);
- })
- });
-
- describe('Axios Configurations', function () {
- let requestUrl, expectedUrl, topicUrl;
- beforeEach(function () {
- requestUrl = 'https://example.com/callback/?id=123';
- expectedUrl = 'https://example.com/callback/';
- topicUrl = 'http://example.com/blog/';
- });
- it('_axiosConfig', function () {
- const method = 'GET';
- const contentType = 'text/plain';
- const body = undefined;
- const params = {
- 'extra_parameter': 'foobar',
- };
- const expectedUrlObj = new URL('https://example.com/callback/?id=123&extra_parameter=foobar');
- const expected = {
- method,
- url: 'https://example.com/callback/',
- headers: {
- 'Content-Type': 'text/plain',
- },
- params: expectedUrlObj.searchParams,
- responseType: 'text',
- };
- const result = Communication._axiosConfig(method, requestUrl, body, params, {
- 'Content-Type': contentType,
- });
- delete result.transformResponse;
- assert.deepStrictEqual(result, expected);
- });
- it('_axiosConfig covers defaults', function () {
- const method = 'OPTIONS';
- const expectedUrlObj = new URL(requestUrl);
- const expected = {
- method,
- url: expectedUrl,
- headers: {},
- params: expectedUrlObj.searchParams,
- responseType: 'text',
- };
- const result = Communication._axiosConfig(method, requestUrl);
- delete result.transformResponse;
- assert.deepStrictEqual(result, expected);
- });
- it('covers null response transform', function () {
- const result = Communication._axiosConfig('GET', 'https://example.com/', undefined, {}, {});
- result.transformResponse[0]();
- });
- it('_intentVerifyAxiosConfig', function () {
- const mode = 'subscribe';
- const leaseSeconds = 864000;
- const challenge = 'abcxyz';
- const expectedUrlObj = new URL(`${requestUrl}&hub.mode=${mode}&hub.topic=${encodeURIComponent(topicUrl)}&hub.challenge=${challenge}&hub.lease_seconds=${leaseSeconds}`);
- const expected = {
- method: 'GET',
- url: expectedUrl,
- headers: {},
- params: expectedUrlObj.searchParams,
- responseType: 'text',
- };
- const result = Communication._intentVerifyAxiosConfig(requestUrl, topicUrl, mode, leaseSeconds, challenge);
- delete result.transformResponse;
- assert.deepStrictEqual(result, expected);
- });
- it('_intentDenyAxiosConfig', function () {
- const reason = 'something';
- const expectedUrlObj = new URL(`${requestUrl}&hub.mode=denied&hub.topic=${encodeURIComponent(topicUrl)}&hub.reason=${reason}`);
- const expected = {
- method: 'GET',
- url: expectedUrl,
- headers: {},
- params: expectedUrlObj.searchParams,
- responseType: 'text',
- };
- const result = Communication._intentDenyAxiosConfig(requestUrl, topicUrl, reason);
- delete result.transformResponse;
- assert.deepStrictEqual(result, expected);
- });
- it('_publisherValidationAxiosConfig', function () {
- const topic = {
- url: topicUrl,
- publisherValidationUrl: 'https://example.com/publisher/',
- };
- const verification = {
- callback: requestUrl,
- topic: topicUrl,
- };
- const expectedUrlObj = new URL(topic.publisherValidationUrl);
- const expected = {
- method: 'POST',
- url: topic.publisherValidationUrl,
- data: {
- callback: requestUrl,
- topic: topicUrl,
- },
- headers: {
- 'Content-Type': 'application/json',
- },
- params: expectedUrlObj.searchParams,
- responseType: 'text',
- };
- const result = Communication._publisherValidationAxiosConfig(topic, verification);
- delete result.transformResponse;
- assert.deepStrictEqual(result, expected);
- });
- it('_topicFetchAxiosConfig', function () {
- const topic = {
- url: topicUrl,
- contentType: 'text/plain',
- };
- const expectedUrlObj = new URL(topicUrl);
- const expected = {
- method: 'GET',
- url: topicUrl,
- params: expectedUrlObj.searchParams,
- headers: {
- Accept: 'text/plain, */*;q=0.9',
- },
- responseType: 'text',
- };
- const result = Communication._topicFetchAxiosConfig(topic);
- delete result.transformResponse;
- assert.deepStrictEqual(result, expected);
});
- }); // Axios Configurations
+ });
describe('verificationProcess', function () {
const challenge = 'a_challenge';
@@ -263,13 +137,13 @@ describe('Communication', function () {
sinon.stub(Communication, 'generateChallenge').resolves(challenge);
sinon.stub(communication, 'publisherValidate').resolves(true);
- sinon.stub(communication, 'axios').resolves({
- status: 200,
- statusText: 'OK',
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 200,
+ statusMessage: 'OK',
headers: {
'content-type': 'text/plain',
},
- data: challenge,
+ body: challenge,
});
communication.db.verificationGetById.resolves(verification);
@@ -312,7 +186,7 @@ describe('Communication', function () {
await communication.verificationProcess(dbCtx, callback, topicId, requestId);
assert(communication.db.verificationRelease.called);
- assert(!communication.axios.called);
+ assert(!communication.got.called);
});
it('denies subscription to deleted topic', async function () {
@@ -357,8 +231,8 @@ describe('Communication', function () {
});
it('handles request error', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').throws(new Error());
+ communication.got.restore();
+ sinon.stub(communication, 'got').rejects(new Error());
await communication.verificationProcess(dbCtx, callback, topicId, requestId);
@@ -366,9 +240,9 @@ describe('Communication', function () {
});
it('handles 500 response', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').resolves({
- status: 500,
+ communication.got.restore();
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 500,
});
await communication.verificationProcess(dbCtx, callback, topicId, requestId);
@@ -377,9 +251,9 @@ describe('Communication', function () {
});
it('handles non-200 response', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').resolves({
- status: 400,
+ communication.got.restore();
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 400,
});
await communication.verificationProcess(dbCtx, callback, topicId, requestId);
@@ -405,18 +279,35 @@ describe('Communication', function () {
assert(communication.db.verificationComplete.called);
});
+ it('unsubscription from deleted topic deletes topic', async function () {
+ communication.db.verificationGetById.restore();
+ verification.mode = 'unsubscribe';
+ sinon.stub(communication.db, 'verificationGetById').resolves(verification);
+ communication.db.topicGetById.restore();
+ sinon.stub(communication.db, 'topicGetById').resolves({
+ ...topic,
+ isDeleted: true,
+ });
+
+ await communication.verificationProcess(dbCtx, callback, topicId, requestId);
+
+ assert(communication.db.subscriptionDelete.called);
+ assert(communication.db.verificationComplete.called);
+ assert(communication.db.topicPendingDelete.called);
+ });
+
it('unsubscription denial succeeds', async function () {
communication.db.verificationGetById.restore();
verification.mode = 'unsubscribe';
sinon.stub(communication.db, 'verificationGetById').resolves(verification);
- communication.axios.restore();
- sinon.stub(communication, 'axios').resolves({
- status: 200,
- statusText: 'OK',
+ communication.got.restore();
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 200,
+ statusMessage: 'OK',
headers: {
'content-type': 'text/plain',
},
- data: 'not the challenge',
+ body: 'not the challenge',
});
await communication.verificationProcess(dbCtx, callback, topicId, requestId);
@@ -453,9 +344,9 @@ describe('Communication', function () {
httpRemoteAddr: '127.0.0.0',
};
- sinon.stub(communication, 'axios').resolves({
- status: 200,
- statusText: 'OK',
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 200,
+ statusMessage: 'OK',
headers: {
'content-type': 'application/json',
},
@@ -474,10 +365,10 @@ describe('Communication', function () {
});
it('succeeds with rejection', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').resolves({
- status: 400,
- statusText: 'Bad Request',
+ communication.got.restore();
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 400,
+ statusMessage: 'Bad Request',
headers: {
'content-type': 'application/json',
},
@@ -491,10 +382,10 @@ describe('Communication', function () {
});
it('defers on request server error', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').resolves({
- status: 502,
- statusText: 'Bad Gateway',
+ communication.got.restore();
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 502,
+ statusMessage: 'Bad Gateway',
headers: {
'content-type': 'text/plain',
},
@@ -506,8 +397,8 @@ describe('Communication', function () {
});
it('handles request error', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').throws(new Error());
+ communication.got.restore();
+ sinon.stub(communication, 'got').rejects(new Error());
const result = await communication.publisherValidate(dbCtx, topic, verification);
@@ -529,14 +420,16 @@ describe('Communication', function () {
requestId = '7d37ea20-4ef7-417e-a08d-c0ba71269ab1';
topicId = '234ec6fb-f1cd-4ac3-8ea9-29ed42ae0e21';
- sinon.stub(communication, 'axios').resolves({
- status: 200,
- statusText: 'OK',
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 200,
+ statusMessage: 'OK',
headers: {
'content-type': 'text/plain',
link: '; rel="hub"',
+ 'last-modified': 'Thu, 18 Nov 2021 20:34:35 GMT',
+ 'etag': '"9c104-1673e-5d1161636d742"',
},
- data: 'Jackdaws love my big sphinx of quartz.',
+ body: 'Jackdaws love my big sphinx of quartz.',
});
communication.db.topicGetById.resolves(topic);
@@ -561,12 +454,12 @@ describe('Communication', function () {
await communication.topicFetchProcess(dbCtx, topicId, requestId);
- assert(!communication.axios.called);
+ assert(!communication.got.called);
});
it('handles request error', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').throws(new Error());
+ communication.got.restore();
+ sinon.stub(communication, 'got').rejects(new Error());
await communication.topicFetchProcess(dbCtx, topicId, requestId);
@@ -574,10 +467,10 @@ describe('Communication', function () {
});
it('handles 500 response', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').resolves({
- status: 500,
- statusText: 'Internal Server Error',
+ communication.got.restore();
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 500,
+ statusMessage: 'Internal Server Error',
headers: {
'content-type': 'text/plain',
},
@@ -589,10 +482,10 @@ describe('Communication', function () {
});
it('handles bad response', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').resolves({
- status: 404,
- statusText: 'Not Found',
+ communication.got.restore();
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 404,
+ statusMessage: 'Not Found',
headers: {
'content-type': 'text/plain',
},
@@ -614,6 +507,20 @@ describe('Communication', function () {
assert(!communication.db.topicSetContent.called);
});
+ it('recognizes 304 response', async function () {
+ topic.httpLastModified = 'Thu, 18 Nov 2021 20:34:35 GMT';
+ topic.httpEtag = '"9c104-1673e-5d1161636d742"';
+ communication.db.topicGetById.resolves(topic);
+ communication.got.resolves({
+ statusCode: 304,
+ });
+
+ await communication.topicFetchProcess(dbCtx, topicId, requestId);
+
+ assert(communication.db.topicFetchComplete.called);
+ assert(!communication.db.topicSetContent.called);
+ });
+
it('updates content', async function () {
await communication.topicFetchProcess(dbCtx, topicId, requestId);
@@ -622,15 +529,15 @@ describe('Communication', function () {
});
it('updates content with lax link enforcement', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').resolves({
- status: 200,
- statusText: 'OK',
+ communication.got.restore();
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 200,
+ statusMessage: 'OK',
headers: {
'content-type': 'text/plain',
link: '; rel="hub"',
},
- data: 'Jackdaws love my big sphinx of quartz.',
+ body: 'Jackdaws love my big sphinx of quartz.',
});
communication.options.communication.strictTopicHubLink = false;
@@ -642,15 +549,15 @@ describe('Communication', function () {
});
it('deletes topic when hub relation unsatisfied', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').resolves({
- status: 200,
- statusText: 'OK',
+ communication.got.restore();
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 200,
+ statusMessage: 'OK',
headers: {
'content-type': 'text/plain',
link: '; rel="hub"',
},
- data: 'Jackdaws love my big sphinx of quartz.',
+ body: 'Jackdaws love my big sphinx of quartz.',
});
await communication.topicFetchProcess(dbCtx, topicId, requestId);
@@ -681,13 +588,13 @@ describe('Communication', function () {
signatureAlgorithm: 'sha512',
};
- sinon.stub(communication, 'axios').resolves({
- status: 200,
- statusText: 'OK',
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 200,
+ statusMessage: 'OK',
headers: {
'content-type': 'text/plain',
},
- data: 'Jackdaws love my big sphinx of quartz.',
+ body: 'Jackdaws love my big sphinx of quartz.',
});
communication.db.topicGetContentById.resolves(topic);
@@ -723,8 +630,8 @@ describe('Communication', function () {
});
it('handles request error', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').throws();
+ communication.got.restore();
+ sinon.stub(communication, 'got').throws();
await communication.subscriptionDeliveryProcess(dbCtx, subscriptionId, requestId);
@@ -732,10 +639,10 @@ describe('Communication', function () {
});
it('handles 5xx response', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').resolves({
- status: 500,
- statusText: 'Internal Server Error',
+ communication.got.restore();
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 500,
+ statusMessage: 'Internal Server Error',
headers: {
'content-type': 'text/plain',
},
@@ -747,10 +654,10 @@ describe('Communication', function () {
});
it('handles 4xx response', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').resolves({
- status: 404,
- statusText: 'Not Found',
+ communication.got.restore();
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 404,
+ statusMessage: 'Not Found',
headers: {
'content-type': 'text/plain',
},
@@ -762,10 +669,10 @@ describe('Communication', function () {
});
it('handles 410 response', async function () {
- communication.axios.restore();
- sinon.stub(communication, 'axios').resolves({
- status: 410,
- statusText: 'Gone',
+ communication.got.restore();
+ sinon.stub(communication, 'got').resolves({
+ statusCode: 410,
+ statusMessage: 'Gone',
headers: {
'content-type': 'text/plain',
},
@@ -799,14 +706,14 @@ describe('Communication', function () {
it('covers claim', async function () {
communication.db.topicFetchClaimById.resolves({
changes: 1,
- })
+ });
await communication.topicFetchClaimAndProcessById(dbCtx, topicId, requestId);
assert(communication.topicFetchProcess.called);
});
it('covers no claim', async function () {
communication.db.topicFetchClaimById.resolves({
changes: 0,
- })
+ });
await communication.topicFetchClaimAndProcessById(dbCtx, topicId, requestId);
assert(!communication.topicFetchProcess.called);
});
@@ -823,14 +730,14 @@ describe('Communication', function () {
it('covers claim', async function () {
communication.db.verificationClaimById.resolves({
changes: 1,
- })
+ });
await communication.verificationClaimAndProcessById(dbCtx, verificationId, requestId);
assert(communication.verificationProcess.called);
});
it('covers no claim', async function () {
communication.db.verificationClaimById.resolves({
changes: 0,
- })
+ });
await communication.verificationClaimAndProcessById(dbCtx, verificationId, requestId);
assert(!communication.verificationProcess.called);
});