Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

twitch-webhook

Package Overview
Dependencies
Maintainers
2
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

twitch-webhook - npm Package Compare versions

Comparing version 1.1.1 to 1.1.2

1

.eslintrc.json

@@ -7,2 +7,3 @@ {

"plugins": ["mocha"],
"extends": "standard",
"rules": {

@@ -9,0 +10,0 @@ "mocha/no-exclusive-tests": "error"

9

package.json
{
"name": "twitch-webhook",
"version": "1.1.1",
"version": "1.1.2",
"description": "A Node JS library for new Twitch Helix API Webhooks",

@@ -42,3 +42,8 @@ "main": "src/index.js",

"coveralls": "^3.0.0",
"eslint-config-standard": "^11.0.0-beta.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-mocha": "^4.11.0",
"eslint-plugin-node": "^5.2.1",
"eslint-plugin-promise": "^3.6.0",
"eslint-plugin-standard": "^3.0.1",
"istanbul": "^0.4.5",

@@ -59,2 +64,2 @@ "jsdoc": "^3.5.5",

}
}
}
'use strict'
/**
* Twitch error
* Base error
*
* @extends Error
*/
class FatalError extends Error {
class BaseError extends Error {}
/**
* Library error
*
* @extends BaseError
*/
class FatalError extends BaseError {
/**
* Constructs an instance of FatalError
*
* @param {string|Error} error
* @param {string|Error} error - Error or error message
*/

@@ -25,2 +34,3 @@ constructor (error) {

* Access error
*
* @extends FatalError

@@ -30,7 +40,8 @@ */

/**
* Constructs an instance of RequestDenied
*
* @param {Object} response
* @param {Object} response - Response
*/
constructor (response) {
super(`Invalid response status code ${response.statusCode}`)
super(response)

@@ -41,5 +52,24 @@ this.response = response

/**
* Webhook error
*
* @extends BaseError
*/
class WebhookError extends BaseError {
/**
* Constructs an instance of FatalError
*
* @param {string} message - Error message
*/
constructor (message) {
super(message)
Error.captureStackTrace(this)
}
}
module.exports = {
BaseError,
FatalError,
RequestDenied
RequestDenied,
WebhookError
}

@@ -55,3 +55,3 @@ const errors = require('./errors')

}
this._options.listen = options.listen || {}

@@ -64,3 +64,8 @@ this._options.listen.host = options.listen.host || '0.0.0.0'

this._apiUrl = options.baseApiUrl || 'https://api.twitch.tv/helix/'
if (this._apiUrl.substr(-1) !== '/') {
this._apiUrl += '/'
}
this._hubUrl = this._apiUrl + 'webhooks/hub'
this._apiPathname = url.parse(this._apiUrl).pathname

@@ -121,10 +126,4 @@ this._secrets = {}

return new Promise((resolve, reject) => {
this._server.close(err => {
if (err) {
return reject(err)
}
return resolve()
})
return new Promise(resolve => {
this._server.close(() => resolve())
})

@@ -174,3 +173,3 @@ }

if (this._options.secret) {
let secret = crypto
const secret = crypto
.createHmac('sha256', this._options.secret)

@@ -244,3 +243,3 @@ .update(topic)

delete this._secrets[queries['hub.topic']] // Yes, it's needed by design
case "subscribe": // eslint-disable-line
case 'subscribe': // eslint-disable-line no-fallthrough
response.writeHead(200, { 'Content-Type': 'text/plain' })

@@ -290,4 +289,6 @@ response.end(queries['hub.challenge'])

const endpoint = links && links.self && links.self.url
const topic = endpoint && url.parse(endpoint, true).pathname.replace('/helix/', '')
const topic = endpoint && url.parse(endpoint, true).pathname.replace(this._apiPathname, '')
if (!endpoint || !topic) {
this.emit('webhook-error', new errors.WebhookError('Topic is missing or incorrect'))
response.writeHead(202, { 'Content-Type': 'text/plain' })

@@ -304,3 +305,4 @@ response.end()

if (!signature) {
if (!signature || !this._secrets[endpoint]) {
this.emit('webhook-error', new errors.WebhookError('"x-hub-signature" is missing'))
response.writeHead(202, { 'Content-Type': 'text/plain' })

@@ -319,2 +321,3 @@ response.end()

body = ''
this.emit('webhook-error', new errors.WebhookError('Request is very large'))
response.writeHead(202, { 'Content-Type': 'text/plain' })

@@ -331,2 +334,3 @@ response.end()

} catch (err) {
this.emit('webhook-error', new errors.WebhookError('JSON is malformed'))
response.writeHead(202, { 'Content-Type': 'text/plain' })

@@ -338,11 +342,9 @@ response.end()

if (this._options.secret) {
let storedSign
if (this._secrets[endpoint]) {
storedSign = crypto
.createHmac('sha256', this._secrets[endpoint])
.update(body)
.digest('hex')
}
let storedSign = crypto
.createHmac('sha256', this._secrets[endpoint])
.update(body)
.digest('hex')
if (storedSign !== signature) {
this.emit('webhook-error', new errors.WebhookError('"x-hub-signature" is incorrect'))
response.writeHead(202, { 'Content-Type': 'text/plain' })

@@ -349,0 +351,0 @@ response.end()

const assert = require('assert')
const http = require('http')
const request = require('request-promise')

@@ -9,3 +10,3 @@ const errors = require('request-promise/errors')

return request(requestOptions);
return request(requestOptions)
}

@@ -39,3 +40,3 @@

.finally(status => {
if (status == false) {
if (status === false) {
throw new Error('cannot start listening if "autoStart" is false')

@@ -46,2 +47,22 @@ }

let requests = []
function startMockedServer (port) {
const server = http.createServer((request, response) => {
requests.push(request.url)
response.writeHead(202, { 'Content-Type': 'text/plain' })
response.end()
})
server.unref()
return new Promise((resolve, reject) => {
server.on('error', reject).listen(port, resolve)
})
}
function checkRequestToMockedServer (callback) {
if (requests.findIndex(callback) === -1) {
throw new Error('request does not exist')
}
}
module.exports = {

@@ -51,3 +72,5 @@ sendRequest,

hasStartedListening,
hasStoppedListening
hasStoppedListening,
startMockedServer,
checkRequestToMockedServer
}

@@ -6,18 +6,26 @@ const TwitchWebhook = require('../src/index')

const Promise = require('bluebird')
const request = require('request-promise')
const crypto = require('crypto')
const url = require('url')
const client_id = process.env.CLIENT_ID
const clientId = process.env.CLIENT_ID
if (!client_id) {
if (!clientId) {
throw new Error('Twitch Client ID not provided')
}
const port = process.env.PORT || 9108
const freePort = port + 1
const callback = process.env.CALLBACK || 'https://216.58.210.174/' // Google IP :)
let defaultPort = process.env.PORT || 9108
const webhookPort = defaultPort++
const testPort = defaultPort++
const securePort = defaultPort++
const apiPort = defaultPort++
const offlinePort = defaultPort++
const timeout = 10 * 1000
const secret = 'test secret :)'
const callback = process.env.CALLBACK || 'https://216.58.210.174/'
describe('TwitchWebhook', () => {
let twitchWebhook
let testWebhook
let secureWebhook
let offlineWebhook

@@ -27,23 +35,53 @@

twitchWebhook = new TwitchWebhook({
client_id,
client_id: clientId,
callback,
listen: {
host: '127.0.0.1',
port
}
port: webhookPort
},
lease_seconds: 0
})
offlineWebhook = new TwitchWebhook({
client_id,
client_id: clientId,
callback,
listen: {
host: '127.0.0.1',
port: freePort,
port: offlinePort,
autoStart: false
}
},
lease_seconds: 0
})
})
before(() => {
return helpers.startMockedServer(apiPort)
.then(() => {
testWebhook = new TwitchWebhook({
client_id: clientId,
callback,
listen: {
host: '127.0.0.1',
port: testPort
},
baseApiUrl: `http://127.0.0.1:${apiPort}/`
})
secureWebhook = new TwitchWebhook({
client_id: clientId,
callback,
secret,
listen: {
host: '127.0.0.1',
port: securePort
},
baseApiUrl: `http://127.0.0.1:${apiPort}/`
})
})
})
it('should contain errors', (done) => {
assert(twitchWebhook.errors instanceof Object);
assert(twitchWebhook.errors instanceof Object)
assert(twitchWebhook.errors.FatalError === errors.FatalError)
assert(twitchWebhook.errors.RequestDenied === errors.RequestDenied)
done()

@@ -54,6 +92,9 @@ })

try {
let testWebhook = new TwitchWebhook();
new TwitchWebhook({ // eslint-disable-line no-new
listen: false
})
done(new Error('expected error'))
} catch (err) {
assert(err instanceof errors.FatalError);
assert(err instanceof errors.FatalError)
assert(err.message === 'Twitch Client ID not provided!')
done()

@@ -65,8 +106,10 @@ }

try {
let testWebhook = new TwitchWebhook({
client_id
});
new TwitchWebhook({ // eslint-disable-line no-new
client_id: clientId,
listen: false
})
done(new Error('expected error'))
} catch (err) {
assert(err instanceof errors.FatalError);
assert(err instanceof errors.FatalError)
assert(err.message === 'Callback URL not provided!')
done()

@@ -76,13 +119,69 @@ }

it('should automaticaly start listening by default', () => {
assert.equal(twitchWebhook.isListening(), true)
return helpers.hasStartedListening(`http://127.0.0.1:${port}`)
assert(twitchWebhook.isListening())
return helpers.hasStartedListening(`http://127.0.0.1:${webhookPort}`)
})
it('should not automaticaly start listening if "autoStart" is false', () => {
assert.equal(offlineWebhook.isListening(), false)
return helpers.hasStoppedListening(`http://127.0.0.1:${freePort}`)
assert(offlineWebhook.isListening() === false)
return helpers.hasStoppedListening(`http://127.0.0.1:${offlinePort}`)
})
it('should set "host" and "post" if one of them is undefined', (done) => {
const tempWebhook = new TwitchWebhook({
client_id: clientId,
callback,
lease_seconds: 0
})
tempWebhook.on('listening', () => {
helpers.hasStartedListening(`http://0.0.0.0:8443/`)
.then(() => done())
.catch(done)
.finally(() => tempWebhook.close())
})
})
it('should add trailing slash to base url of api if it does not exist', () => {
const tempWebhook = new TwitchWebhook({
client_id: clientId,
callback,
lease_seconds: 0,
baseApiUrl: `http://127.0.0.1:${apiPort}`
})
tempWebhook.subscribe('test')
.catch((err) => {
throw new Error('unexpected error in #subscribe: ' + err.message)
})
.then(() => {
helpers.checkRequestToMockedServer((element) => {
const params = url.parse(element, true).query
return params['hub.topic'] === `http://127.0.0.1:${apiPort}/test`
})
})
.finally(() => tempWebhook.close())
})
it('should add trailing slash to callback if it does not exist', () => {
const tempWebhook = new TwitchWebhook({
client_id: clientId,
callback: `http://127.0.0.1:${offlinePort}`,
lease_seconds: 0,
baseApiUrl: `http://127.0.0.1:${apiPort}`
})
tempWebhook.subscribe('test')
.catch((err) => {
throw new Error('unexpected error in #subscribe: ' + err.message)
})
.then(() => {
helpers.checkRequestToMockedServer((element) => {
const params = url.parse(element, true).query
return params['hub.callback'] === `http://127.0.0.1:${offlinePort}/`
})
})
.finally(() => tempWebhook.close())
})
describe('webhook', () => {

@@ -93,3 +192,3 @@ describe('GET method', () => {

{
url: `http://127.0.0.1:${port}`
url: `http://127.0.0.1:${testPort}`
},

@@ -100,10 +199,8 @@ 400

it('returns 200 response code if request with denied status was received', () => {
it('returns 200 response code if "hub.mode" query is "denied"', () => {
return helpers.checkResponseCode(
{
url: `http://127.0.0.1:${port}`,
url: `http://127.0.0.1:${testPort}`,
qs: {
'hub.mode': 'denied',
'hub.topic': 'https://api.twitch.tv/helix/users/follows?to_id=1337',
'hub.reason': 'unauthorized'
'hub.mode': 'denied'
}

@@ -115,24 +212,23 @@ },

it('returns 200 response code and "hub.challenge" if the subscribe or unsubscribe request was received', () => {
it('returns 200 response code and "hub.challenge" if "hub.mode" query is "subscribe" or "unsubscribe"', () => {
const modes = ['subscribe', 'unsubscribe']
const challenge = 'HzSGH_h04Cgl6VbDJm7IyXSNSlrhaLvBi9eft3bw'
return Promise.each(modes, mode => {
return helpers
.checkResponseCode(
return helpers.checkResponseCode(
{
url: `http://127.0.0.1:${port}`,
url: `http://127.0.0.1:${testPort}`,
qs: {
'hub.mode': mode,
'hub.topic': 'https://api.twitch.tv/helix/users/follows?to_id=1337',
'hub.lease_seconds': 864000,
'hub.challenge': 'HzSGH_h04Cgl6VbDJm7IyXSNSlrhaLvBi9eft3bw'
'hub.challenge': challenge
}
},
200
)
.then(response => {
if (!response.body) {
throw new Error('expected "hub.challenge"')
}
})
200
).then(response => {
if (!response.body) {
throw new Error('expected "hub.challenge"')
}
assert(response.body, challenge)
})
})

@@ -143,10 +239,7 @@ })

describe('POST method', () => {
it('returns 202 response code if data is very large', () => {
const largeText = '0'.repeat(1e7)
it('returns 202 response code if topic is missing', () => {
return helpers.checkResponseCode(
{
url: `http://127.0.0.1:${port}`,
method: 'POST',
body: largeText
url: `http://127.0.0.1:${testPort}`,
method: 'POST'
},

@@ -157,8 +250,10 @@ 202

it('returns 202 response code if json is malformed', () => {
it('returns 202 response code if topic is incorrect', () => {
return helpers.checkResponseCode(
{
url: `http://127.0.0.1:${port}`,
url: `http://127.0.0.1:${testPort}`,
method: 'POST',
body: 'text,'
headers: {
link: `<http://127.0.0.1:${apiPort}/>; rel="self"`
}
},

@@ -169,7 +264,13 @@ 202

it('returns 202 error code if topic is missing', () => {
it('returns 202 response code if request is very large', () => {
const largeText = '0'.repeat(1e7)
return helpers.checkResponseCode(
{
url: `http://127.0.0.1:${port}`,
method: 'POST'
url: `http://127.0.0.1:${testPort}`,
method: 'POST',
headers: {
link: `<http://127.0.0.1:${apiPort}/test?param=value>; rel="self"`
},
body: largeText
},

@@ -180,10 +281,11 @@ 202

it('returns 202 error code if topic is incorrect', () => {
it('returns 202 response code if json is malformed', () => {
return helpers.checkResponseCode(
{
url: `http://127.0.0.1:${port}`,
url: `http://127.0.0.1:${testPort}`,
method: 'POST',
headers: {
link: '<https://api.twitch.tv/helix/>; rel="self"'
}
link: `<http://127.0.0.1:${apiPort}/test?param=value>; rel="self"`
},
body: 'text,'
},

@@ -197,6 +299,6 @@ 202

{
url: `http://127.0.0.1:${port}`,
url: `http://127.0.0.1:${testPort}`,
method: 'POST',
headers: {
link: '<https://api.twitch.tv/helix/users/follows?to_id=1337>; rel="self"'
link: `<http://127.0.0.1:${apiPort}/test?param=value>; rel="self"`
},

@@ -208,2 +310,68 @@ json: {}

})
describe('secret support', () => {
it('returns 202 response code if "x-hub-signature" header is missing', () => {
return helpers.checkResponseCode(
{
url: `http://127.0.0.1:${securePort}`,
method: 'POST',
headers: {
link: `<http://127.0.0.1:${apiPort}/test?param=value>; rel="self"`
}
},
202
)
})
it('returns 202 response code if "x-hub-signature" header is incorrect', () => {
return helpers.checkResponseCode(
{
url: `http://127.0.0.1:${securePort}`,
method: 'POST',
headers: {
link: `<http://127.0.0.1:${apiPort}/test?param=value>; rel="self"`,
'x-hub-signature': 'sha256=text'
},
json: {}
},
202
)
})
it('returns 200 response code if everything is ok', () => {
// first step
const storedSign = crypto
.createHmac('sha256', secret)
.update(`http://127.0.0.1:${apiPort}/test?param=value`)
.digest('hex')
// second step
const body = JSON.stringify({
test: true
})
const signature = crypto
.createHmac('sha256', storedSign)
.update(body)
.digest('hex')
return secureWebhook.subscribe('test', {
param: 'value'
}).catch((err) => {
throw new Error('unexpected error in #subscribe: ' + err.message)
}).then(() => {
return helpers.checkResponseCode(
{
url: `http://127.0.0.1:${securePort}`,
method: 'POST',
headers: {
link: `<http://127.0.0.1:${apiPort}/test?param=value>; rel="self"`,
'x-hub-signature': 'sha256=' + signature
},
body
},
200
)
})
})
})
})

@@ -217,3 +385,3 @@

{
url: `http://127.0.0.1:${port}`,
url: `http://127.0.0.1:${testPort}`,
method

@@ -229,73 +397,195 @@ },

it('emits "denied" event if request with denied status was received', (done) => {
twitchWebhook.once(
'denied',
() => done()
)
helpers.sendRequest(
{
url: `http://127.0.0.1:${port}`,
qs: {
'hub.mode': 'denied',
'hub.topic': 'https://api.twitch.tv/helix/users/follows?to_id=1337',
'hub.reason': 'unauthorized'
}
}
);
let query = {
'hub.mode': 'denied'
}
testWebhook.once('denied', (obj) => {
assert(typeof obj === 'object')
assert.deepEqual(obj, query)
done()
})
helpers.sendRequest({
url: `http://127.0.0.1:${testPort}`,
qs: query
})
})
it('emits "subscribe" event if the subscribe request was received', (done) => {
twitchWebhook.once(
'subscribe',
() => done()
)
helpers.sendRequest(
{
url: `http://127.0.0.1:${port}`,
qs: {
'hub.mode': 'subscribe',
'hub.topic': 'https://api.twitch.tv/helix/users/follows?to_id=1337',
'hub.lease_seconds': 864000,
'hub.challenge': 'HzSGH_h04Cgl6VbDJm7IyXSNSlrhaLvBi9eft3bw'
}
}
);
let query = {
'hub.mode': 'subscribe',
'hub.challenge': 'HzSGH_h04Cgl6VbDJm7IyXSNSlrhaLvBi9eft3bw'
}
testWebhook.once('subscribe', (obj) => {
assert(typeof obj === 'object')
assert.deepEqual(obj, query)
done()
})
helpers.sendRequest({
url: `http://127.0.0.1:${testPort}`,
qs: query
})
})
it('emits "unsubscribe" event if the unsubscribe request was received', (done) => {
twitchWebhook.once(
'unsubscribe',
() => done()
)
helpers.sendRequest(
{
url: `http://127.0.0.1:${port}`,
qs: {
'hub.mode': 'unsubscribe',
'hub.topic': 'https://api.twitch.tv/helix/users/follows?to_id=1337',
'hub.lease_seconds': 864000,
'hub.challenge': 'HzSGH_h04Cgl6VbDJm7IyXSNSlrhaLvBi9eft3bw'
}
}
);
let query = {
'hub.mode': 'unsubscribe',
'hub.challenge': 'HzSGH_h04Cgl6VbDJm7IyXSNSlrhaLvBi9eft3bw'
}
testWebhook.once('unsubscribe', (obj) => {
assert(typeof obj === 'object')
assert.deepEqual(obj, query)
done()
})
helpers.sendRequest({
url: `http://127.0.0.1:${testPort}`,
qs: query
})
})
it('emits "*" event if request with topic was received', (done) => {
twitchWebhook.once(
'*',
() => done()
)
const body = {
test: true
}
testWebhook.once('*', (obj) => {
assert(typeof obj === 'object')
assert(obj.topic === 'test')
assert(obj.endpoint === `http://127.0.0.1:${apiPort}/test?param=value`)
assert.deepEqual(obj.event, body)
done()
})
helpers.sendRequest(
{
url: `http://127.0.0.1:${port}`,
helpers.sendRequest({
url: `http://127.0.0.1:${testPort}`,
method: 'POST',
headers: {
link: `<http://127.0.0.1:${apiPort}/test?param=value>; rel="self"`
},
json: body
})
})
it('emits event with the topic name if request with topic was received', (done) => {
const body = {
test: true
}
testWebhook.once('test', (obj) => {
assert(typeof obj === 'object')
assert(obj.topic === 'test')
assert(obj.endpoint === `http://127.0.0.1:${apiPort}/test?param=value`)
assert.deepEqual(obj.event, body)
done()
})
helpers.sendRequest({
url: `http://127.0.0.1:${testPort}`,
method: 'POST',
headers: {
link: `<http://127.0.0.1:${apiPort}/test?param=value>; rel="self"`
},
json: body
})
})
describe('emits "webhook-error" event if incorrect request was received', () => {
it('should emit if topic is missing', (done) => {
testWebhook.once('webhook-error', (err) => {
assert(err instanceof errors.WebhookError)
assert(err.message === 'Topic is missing or incorrect')
done()
})
helpers.sendRequest({
url: `http://127.0.0.1:${testPort}`,
method: 'POST'
})
})
it('should emit if topic is incorrect', (done) => {
testWebhook.once('webhook-error', (err) => {
assert(err instanceof errors.WebhookError)
assert(err.message === 'Topic is missing or incorrect')
done()
})
helpers.sendRequest({
url: `http://127.0.0.1:${testPort}`,
method: 'POST',
headers: {
link: '<https://api.twitch.tv/helix/test>; rel="self"'
link: `<http://127.0.0.1:${apiPort}/>; rel="self"`
}
})
})
it('should emit if request is very large', (done) => {
const largeText = '0'.repeat(1e7)
testWebhook.once('webhook-error', (err) => {
assert(err instanceof errors.WebhookError)
assert(err.message === 'Request is very large')
done()
})
helpers.sendRequest({
url: `http://127.0.0.1:${testPort}`,
method: 'POST',
headers: {
link: `<http://127.0.0.1:${apiPort}/test?param=value>; rel="self"`
},
json: {}
}
)
body: largeText
})
})
it('should emit if json is malformed', (done) => {
testWebhook.once('webhook-error', (err) => {
assert(err instanceof errors.WebhookError)
assert(err.message === 'JSON is malformed')
done()
})
helpers.sendRequest({
url: `http://127.0.0.1:${testPort}`,
method: 'POST',
headers: {
link: `<http://127.0.0.1:${apiPort}/test?param=value>; rel="self"`
},
body: 'text,'
})
})
describe('secret support', () => {
it('should emit if "x-hub-signature" header is missing', (done) => {
secureWebhook.once('webhook-error', (err) => {
assert(err instanceof errors.WebhookError)
assert(err.message === '"x-hub-signature" is missing')
done()
})
helpers.sendRequest({
url: `http://127.0.0.1:${securePort}`,
method: 'POST',
headers: {
link: `<http://127.0.0.1:${apiPort}/test?param=value>; rel="self"`
}
})
})
it('should emit if "x-hub-signature" header is incorrect', (done) => {
secureWebhook.once('webhook-error', (err) => {
assert(err instanceof errors.WebhookError)
assert(err.message === '"x-hub-signature" is incorrect')
done()
})
helpers.sendRequest({
url: `http://127.0.0.1:${securePort}`,
method: 'POST',
headers: {
link: `<http://127.0.0.1:${apiPort}/test?param=value>; rel="self"`,
'x-hub-signature': 'sha256=text'
},
json: {}
})
})
})
})

@@ -311,22 +601,12 @@ })

helpers.sendRequest(
{
url: `http://127.0.0.1:${port}`,
method: 'POST',
headers: {
link: '<https://api.twitch.tv/helix/users/follows?to_id=1337>; rel="self"'
},
json: {
id: "436c70bb-a52f-4a6a-b4cc-6c57bc2ad227",
topic: "https://api.twitch.tv/helix/users/follows?to_id=1337",
type: "create",
data: {
from_id: 1336,
to_id: 1337
},
timestamp: "2017-08-07T13:52:14.403795077Z"
}
helpers.sendRequest({
url: `http://127.0.0.1:${webhookPort}`,
method: 'POST',
headers: {
link: '<https://api.twitch.tv/helix/users/follows?to_id=1337>; rel="self"'
},
200
)
json: {
timestamp: '2017-08-07T13:52:14.403795077Z'
}
})
})

@@ -339,30 +619,21 @@

}
done()
})
helpers.sendRequest(
{
url: `http://127.0.0.1:${port}`,
method: 'POST',
headers: {
link: '<https://api.twitch.tv/helix/streams?user_id=5678>; rel="self"'
},
json: {
data: [{
id: '0123456789',
user_id: 5678,
game_id: 21779,
community_ids: [],
type: 'live',
title: 'Best Stream Ever',
'viewer_count': 417,
'started_at': '2017-12-01T10:09:45Z',
language: 'en',
'thumbnail_url': 'https://link/to/thumbnail.jpg',
}]
}
helpers.sendRequest({
url: `http://127.0.0.1:${webhookPort}`,
method: 'POST',
headers: {
link: '<https://api.twitch.tv/helix/streams?user_id=5678>; rel="self"'
},
json: {
data: [{
'started_at': '2017-12-01T10:09:45Z'
}, {
'started_at': '2017-12-02T11:49:47Z'
}]
}
)
})
})
})
})

@@ -374,4 +645,5 @@

it('should throw FatalError if the listener is already running', () => {
return twitchWebhook.listen(freePort).catch(err => {
return twitchWebhook.listen(offlinePort).catch(err => {
assert(err instanceof errors.FatalError)
assert(err.message === 'Listening is already started')
})

@@ -385,3 +657,3 @@ })

it('starts listening with options', () => {
return offlineWebhook.listen(freePort)
return offlineWebhook.listen(offlinePort)
})

@@ -394,9 +666,9 @@ })

it('returns true if listening is started', () => {
assert.equal(twitchWebhook.isListening(), true)
return helpers.hasStartedListening(`http://127.0.0.1:${port}`)
assert(twitchWebhook.isListening())
return helpers.hasStartedListening(`http://127.0.0.1:${webhookPort}`)
})
it('returns false if listening is not started', () => {
assert.equal(offlineWebhook.isListening(), false)
return helpers.hasStoppedListening(`http://127.0.0.1:${freePort}`)
assert(offlineWebhook.isListening() === false)
return helpers.hasStoppedListening(`http://127.0.0.1:${offlinePort}`)
})

@@ -411,2 +683,3 @@ })

assert(err instanceof errors.RequestDenied)
assert(typeof err.response === 'object')
})

@@ -444,2 +717,3 @@ })

assert(err instanceof errors.RequestDenied)
assert(typeof err.response === 'object')
})

@@ -453,6 +727,2 @@ })

user_id: 123
}).then(() => {
return twitchWebhook.unsubscribe('streams', {
user_id: 123
})
})

@@ -466,6 +736,2 @@ })

user_id: 123
}).then(() => {
return twitchWebhook.unsubscribe('https://api.twitch.tv/helix/streams', {
user_id: 123
})
})

@@ -477,11 +743,29 @@ })

return twitchWebhook.subscribe('streams?user_id=123').then(() => {
return twitchWebhook.unsubscribe('streams?user_id=123')
})
return twitchWebhook.subscribe('streams?user_id=123')
})
})
after(() => {
return twitchWebhook.close()
after(function () {
if (twitchWebhook) {
return twitchWebhook.close()
} else {
this.skip()
}
})
after(function () {
if (secureWebhook) {
return secureWebhook.close()
} else {
this.skip()
}
})
after(function () {
if (testWebhook) {
return testWebhook.close()
} else {
this.skip()
}
})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc