Merge PR #250: 2017, Major Changes
See https://github.com/yagop/node-telegram-bot-api/pull/250 for details on this PR!experimental
commit
ce4dff78fa
@ -1,10 +1,18 @@ |
|||||||
Running the tests: |
Running the tests: |
||||||
|
|
||||||
```bash |
```bash |
||||||
|
# Token to be used |
||||||
export TEST_TELEGRAM_TOKEN=<YOUR_BOT_TOKEN> |
export TEST_TELEGRAM_TOKEN=<YOUR_BOT_TOKEN> |
||||||
|
|
||||||
# User Id which you want to send the messages. |
# User Id which you want to send the messages. |
||||||
export TEST_USER_ID=<USER_ID> |
export TEST_USER_ID=<USER_ID> |
||||||
|
|
||||||
# Group Id which to use in some of the tests, e.g. for TelegramBot#getChat() |
# Group Id which to use in some of the tests, e.g. for TelegramBot#getChat() |
||||||
export TEST_GROUP_ID=<GROUP_ID> |
export TEST_GROUP_ID=<GROUP_ID> |
||||||
|
|
||||||
|
# Game short name which to use in some of the tests, e.g. TelegramBot#sendGame() |
||||||
|
export TEST_GAME_SHORT_NAME=<GAME_SHORT_NAME> |
||||||
|
|
||||||
|
# Run tests |
||||||
npm run test |
npm run test |
||||||
``` |
``` |
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
Binary file not shown.
Binary file not shown.
@ -1,673 +0,0 @@ |
|||||||
const TelegramPolling = require('../lib/telegramPolling'); |
|
||||||
const Telegram = require('../lib/telegram'); |
|
||||||
const Promise = require('bluebird'); |
|
||||||
const request = require('request-promise'); |
|
||||||
const assert = require('assert'); |
|
||||||
const fs = require('fs'); |
|
||||||
const is = require('is'); |
|
||||||
|
|
||||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; |
|
||||||
const TOKEN = process.env.TEST_TELEGRAM_TOKEN; |
|
||||||
if (!TOKEN) { |
|
||||||
throw new Error('Bot token not provided'); |
|
||||||
} |
|
||||||
|
|
||||||
// Telegram service if not User Id
|
|
||||||
const USERID = process.env.TEST_USER_ID || 777000; |
|
||||||
const GROUPID = process.env.TEST_GROUP_ID || -1001075450562; |
|
||||||
|
|
||||||
describe('Telegram', function telegramSuite() { |
|
||||||
describe('#setWebHook', function setWebHookSuite() { |
|
||||||
it('should set a webHook', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
// Google IP ¯\_(ツ)_/¯
|
|
||||||
return bot |
|
||||||
.setWebHook('216.58.210.174') |
|
||||||
.then(resp => { |
|
||||||
assert.equal(resp, true); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should set a webHook with certificate', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const cert = `${__dirname}/../examples/crt.pem`; |
|
||||||
return bot |
|
||||||
.setWebHook('216.58.210.174', cert) |
|
||||||
.then(resp => { |
|
||||||
assert.equal(resp, true); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should delete the webHook', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
return bot |
|
||||||
.setWebHook('') |
|
||||||
.then(resp => { |
|
||||||
assert.equal(resp, true); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#WebHook', function WebHookSuite() { |
|
||||||
it('should reject request if same token not provided', function test() { |
|
||||||
const bot = new Telegram(TOKEN, { webHook: true }); |
|
||||||
|
|
||||||
return request({ |
|
||||||
url: 'http://localhost:8443/NOT_REAL_TOKEN', |
|
||||||
method: 'POST', |
|
||||||
simple: false, |
|
||||||
resolveWithFullResponse: true |
|
||||||
}).then(response => { |
|
||||||
assert.notEqual(response.statusCode, 200); |
|
||||||
bot._WebHook._webServer.close(); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should reject request if authorized but not a POST', function test() { |
|
||||||
const bot = new Telegram(TOKEN, { webHook: true }); |
|
||||||
return request({ |
|
||||||
url: `http://localhost:8443/bot${TOKEN}`, |
|
||||||
method: 'GET', |
|
||||||
simple: false, |
|
||||||
resolveWithFullResponse: true |
|
||||||
}) |
|
||||||
.then(response => { |
|
||||||
assert.notEqual(response.statusCode, 200); |
|
||||||
bot._WebHook._webServer.close(); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should emit a `message` on HTTP WebHook', function test(done) { |
|
||||||
const bot = new Telegram(TOKEN, { webHook: true }); |
|
||||||
bot.on('message', () => { |
|
||||||
bot._WebHook._webServer.close(); |
|
||||||
done(); |
|
||||||
}); |
|
||||||
|
|
||||||
const url = `http://localhost:8443/bot${TOKEN}`; |
|
||||||
request({ |
|
||||||
url, |
|
||||||
method: 'POST', |
|
||||||
json: true, |
|
||||||
headers: { |
|
||||||
'content-type': 'application/json', |
|
||||||
}, |
|
||||||
body: { update_id: 0, message: { text: 'test' } } |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should emit a `message` on HTTPS WebHook', function test(done) { |
|
||||||
const opts = { |
|
||||||
webHook: { |
|
||||||
port: 8443, |
|
||||||
key: `${__dirname}/../examples/key.pem`, |
|
||||||
cert: `${__dirname}/../examples/crt.pem` |
|
||||||
} |
|
||||||
}; |
|
||||||
const bot = new Telegram(TOKEN, opts); |
|
||||||
bot.on('message', () => { |
|
||||||
bot._WebHook._webServer.close(); |
|
||||||
done(); |
|
||||||
}); |
|
||||||
const url = `https://localhost:8443/bot${TOKEN}`; |
|
||||||
request({ |
|
||||||
url, |
|
||||||
method: 'POST', |
|
||||||
json: true, |
|
||||||
headers: { |
|
||||||
'content-type': 'application/json', |
|
||||||
}, |
|
||||||
rejectUnhauthorized: false, |
|
||||||
body: { update_id: 0, message: { text: 'test' } } |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#getMe', function getMeSuite() { |
|
||||||
it('should return an User object', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
return bot.getMe().then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#getChat', function getChatSuite() { |
|
||||||
it('should return a Chat object', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
return bot.getChat(USERID).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#getChatAdministrators', function getChatAdministratorsSuite() { |
|
||||||
it('should return an Array', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
return bot.getChatAdministrators(GROUPID).then(resp => { |
|
||||||
assert.ok(Array.isArray(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#getChatMembersCount', function getChatMembersCountSuite() { |
|
||||||
it('should return an Integer', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
return bot.getChatMembersCount(GROUPID).then(resp => { |
|
||||||
assert.ok(Number.isInteger(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#getChatMember', function getChatMemberSuite() { |
|
||||||
it('should return a ChatMember', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
return bot.getChatMember(GROUPID, USERID).then(resp => { |
|
||||||
assert.ok(is.object(resp.user)); |
|
||||||
assert.ok(is.string(resp.status)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#getUpdates', function getUpdatesSuite() { |
|
||||||
it('should return an Array', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
return bot.getUpdates().then(resp => { |
|
||||||
assert.equal(Array.isArray(resp), true); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#sendMessage', function sendMessageSuite() { |
|
||||||
it('should send a message', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
return bot.sendMessage(USERID, 'test').then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#forwardMessage', function forwardMessageSuite() { |
|
||||||
it('should forward a message', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
return bot.sendMessage(USERID, 'test').then(resp => { |
|
||||||
const messageId = resp.message_id; |
|
||||||
return bot.forwardMessage(USERID, USERID, messageId) |
|
||||||
.then(forwarded => { |
|
||||||
assert.ok(is.object(forwarded)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#_formatSendData', function _formatSendData() { |
|
||||||
it('should handle buffer path from fs.readStream', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
let photo; |
|
||||||
try { |
|
||||||
photo = fs.createReadStream(Buffer.from(`${__dirname}/bot.gif`)); |
|
||||||
} catch(ex) { |
|
||||||
// Older Node.js versions do not support passing a Buffer
|
|
||||||
// representation of the path to fs.createReadStream()
|
|
||||||
if (ex instanceof TypeError) return; |
|
||||||
} |
|
||||||
return bot.sendPhoto(USERID, photo).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#sendPhoto', function sendPhotoSuite() { |
|
||||||
let photoId; |
|
||||||
it('should send a photo from file', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const photo = `${__dirname}/bot.gif`; |
|
||||||
return bot.sendPhoto(USERID, photo).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
photoId = resp.photo[0].file_id; |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a photo from id', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
// Send the same photo as before
|
|
||||||
const photo = photoId; |
|
||||||
return bot.sendPhoto(USERID, photo).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a photo from fs.readStream', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const photo = fs.createReadStream(`${__dirname}/bot.gif`); |
|
||||||
return bot.sendPhoto(USERID, photo).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a photo from request Stream', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const photo = request('https://telegram.org/img/t_logo.png'); |
|
||||||
return bot.sendPhoto(USERID, photo).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a photo from a Buffer', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const photo = fs.readFileSync(`${__dirname}/bot.gif`); |
|
||||||
return bot.sendPhoto(USERID, photo).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a photo along with reply_markup', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const photo = fs.readFileSync(`${__dirname}/bot.gif`); |
|
||||||
return bot.sendPhoto(USERID, photo, { |
|
||||||
reply_markup: { |
|
||||||
hide_keyboard: true |
|
||||||
} |
|
||||||
}).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#sendChatAction', function sendChatActionSuite() { |
|
||||||
it('should send a chat action', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const action = 'typing'; |
|
||||||
return bot.sendChatAction(USERID, action).then(resp => { |
|
||||||
assert.equal(resp, true); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#editMessageText', function editMessageTextSuite() { |
|
||||||
it('should edit a message sent by the bot', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
return bot.sendMessage(USERID, 'test').then(resp => { |
|
||||||
assert.equal(resp.text, 'test'); |
|
||||||
const opts = { |
|
||||||
chat_id: USERID, |
|
||||||
message_id: resp.message_id |
|
||||||
}; |
|
||||||
return bot.editMessageText('edit test', opts).then(msg => { |
|
||||||
assert.equal(msg.text, 'edit test'); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#editMessageCaption', function editMessageCaptionSuite() { |
|
||||||
it('should edit a caption sent by the bot', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const photo = `${__dirname}/bot.gif`; |
|
||||||
const options = { caption: 'test caption' }; |
|
||||||
return bot.sendPhoto(USERID, photo, options).then(resp => { |
|
||||||
assert.equal(resp.caption, 'test caption'); |
|
||||||
const opts = { |
|
||||||
chat_id: USERID, |
|
||||||
message_id: resp.message_id |
|
||||||
}; |
|
||||||
return bot.editMessageCaption('new test caption', opts).then(msg => { |
|
||||||
assert.equal(msg.caption, 'new test caption'); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#editMessageReplyMarkup', function editMessageReplyMarkupSuite() { |
|
||||||
it('should edit previously-set reply markup', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
return bot.sendMessage(USERID, 'test').then(resp => { |
|
||||||
const replyMarkup = JSON.stringify({ |
|
||||||
inline_keyboard: [[{ |
|
||||||
text: 'Test button', |
|
||||||
callback_data: 'test' |
|
||||||
}]] |
|
||||||
}); |
|
||||||
const opts = { |
|
||||||
chat_id: USERID, |
|
||||||
message_id: resp.message_id |
|
||||||
}; |
|
||||||
return bot.editMessageReplyMarkup(replyMarkup, opts).then(msg => { |
|
||||||
// Keyboard markup is not returned, do a simple object check
|
|
||||||
assert.ok(is.object(msg)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#sendAudio', function sendAudioSuite() { |
|
||||||
it('should send an OGG audio', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const audio = request('https://upload.wikimedia.org/wikipedia/commons/c/c8/Example.ogg'); |
|
||||||
return bot.sendAudio(USERID, audio).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#sendDocument', function sendDocumentSuite() { |
|
||||||
let documentId; |
|
||||||
it('should send a document from file', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const document = `${__dirname}/bot.gif`; |
|
||||||
return bot.sendDocument(USERID, document).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
documentId = resp.document.file_id; |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a document from id', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
// Send the same photo as before
|
|
||||||
const document = documentId; |
|
||||||
return bot.sendDocument(USERID, document).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a document from fs.readStream', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const document = fs.createReadStream(`${__dirname}/bot.gif`); |
|
||||||
return bot.sendDocument(USERID, document).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a document from request Stream', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const document = request('https://telegram.org/img/t_logo.png'); |
|
||||||
return bot.sendDocument(USERID, document).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a document from a Buffer', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const document = fs.readFileSync(`${__dirname}/bot.gif`); |
|
||||||
return bot.sendDocument(USERID, document).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#sendSticker', function sendStickerSuite() { |
|
||||||
let stickerId; |
|
||||||
it('should send a sticker from file', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const sticker = `${__dirname}/sticker.webp`; |
|
||||||
return bot.sendSticker(USERID, sticker).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
stickerId = resp.sticker.file_id; |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a sticker from id', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
// Send the same photo as before
|
|
||||||
return bot.sendSticker(USERID, stickerId).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a sticker from fs.readStream', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const sticker = fs.createReadStream(`${__dirname}/sticker.webp`); |
|
||||||
return bot.sendSticker(USERID, sticker).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a sticker from request Stream', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const sticker = request('https://www.gstatic.com/webp/gallery3/1_webp_ll.webp'); |
|
||||||
return bot.sendSticker(USERID, sticker).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a sticker from a Buffer', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const sticker = fs.readFileSync(`${__dirname}/sticker.webp`); |
|
||||||
return bot.sendDocument(USERID, sticker).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#sendVideo', function sendVideoSuite() { |
|
||||||
let videoId; |
|
||||||
it('should send a video from file', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const video = `${__dirname}/video.mp4`; |
|
||||||
return bot.sendVideo(USERID, video).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
videoId = resp.video.file_id; |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a video from id', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
// Send the same photo as before
|
|
||||||
return bot.sendVideo(USERID, videoId).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a video from fs.readStream', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const video = fs.createReadStream(`${__dirname}/video.mp4`); |
|
||||||
return bot.sendVideo(USERID, video).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a video from request Stream', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const sticker = request('http://techslides.com/demos/sample-videos/small.mp4'); |
|
||||||
return bot.sendVideo(USERID, sticker).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should send a video from a Buffer', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const video = fs.readFileSync(`${__dirname}/video.mp4`); |
|
||||||
return bot.sendVideo(USERID, video).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#sendVoice', function sendVoiceSuite() { |
|
||||||
it('should send an OGG audio as voice', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const voice = request('https://upload.wikimedia.org/wikipedia/commons/c/c8/Example.ogg'); |
|
||||||
return bot.sendVoice(USERID, voice).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#getUserProfilePhotos', function getUserProfilePhotosSuite() { |
|
||||||
it('should get user profile photos', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
return bot.getUserProfilePhotos(USERID).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
assert.ok(is.number(resp.total_count)); |
|
||||||
assert.ok(is.array(resp.photos)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#sendLocation', function sendLocationSuite() { |
|
||||||
it('should send a location', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const lat = 47.5351072; |
|
||||||
const long = -52.7508537; |
|
||||||
return bot.sendLocation(USERID, lat, long).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
assert.ok(is.object(resp.location)); |
|
||||||
assert.ok(is.number(resp.location.latitude)); |
|
||||||
assert.ok(is.number(resp.location.longitude)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#sendVenue', function sendVenueSuite() { |
|
||||||
it('should send a venue', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const lat = 47.5351072; |
|
||||||
const long = -52.7508537; |
|
||||||
const title = `The Village Shopping Centre`; |
|
||||||
const address = `430 Topsail Rd,St. John's, NL A1E 4N1, Canada`; |
|
||||||
return bot.sendVenue(USERID, lat, long, title, address).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
assert.ok(is.object(resp.venue)); |
|
||||||
assert.ok(is.object(resp.venue.location)); |
|
||||||
assert.ok(is.number(resp.venue.location.latitude)); |
|
||||||
assert.ok(is.number(resp.venue.location.longitude)); |
|
||||||
assert.ok(is.string(resp.venue.title)); |
|
||||||
assert.ok(is.string(resp.venue.address)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#getFile', function getFileSuite() { |
|
||||||
let fileId; |
|
||||||
|
|
||||||
// To get a file we have to send any file first
|
|
||||||
it('should send a photo from file', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const photo = `${__dirname}/bot.gif`; |
|
||||||
return bot.sendPhoto(USERID, photo).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
fileId = resp.photo[0].file_id; |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should get a file', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
|
|
||||||
return bot |
|
||||||
.getFile(fileId) |
|
||||||
.then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
assert.ok(is.string(resp.file_path)); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#getFileLink', function getFileLinkSuite() { |
|
||||||
let fileId; |
|
||||||
|
|
||||||
// To get a file we have to send any file first
|
|
||||||
it('should send a photo from file', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const photo = `${__dirname}/bot.gif`; |
|
||||||
return bot.sendPhoto(USERID, photo).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
fileId = resp.photo[0].file_id; |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should get a file link', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
|
|
||||||
return bot |
|
||||||
.getFileLink(fileId) |
|
||||||
.then(fileURI => { |
|
||||||
assert.ok(is.string(fileURI)); |
|
||||||
assert.equal(fileURI.indexOf('https'), 0); |
|
||||||
// TODO: validate URL with some library or regexp
|
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#downloadFile', function downloadFileSuite() { |
|
||||||
const downloadPath = __dirname; |
|
||||||
|
|
||||||
it('should download a file', function test() { |
|
||||||
const bot = new Telegram(TOKEN); |
|
||||||
const photo = `${__dirname}/bot.gif`; |
|
||||||
|
|
||||||
// Send a file to get the ID
|
|
||||||
return bot.sendPhoto(USERID, photo).then(resp => { |
|
||||||
assert.ok(is.object(resp)); |
|
||||||
const fileId = resp.photo[0].file_id; |
|
||||||
|
|
||||||
return bot |
|
||||||
.downloadFile(fileId, downloadPath) |
|
||||||
.then(filePath => { |
|
||||||
assert.ok(is.string(filePath)); |
|
||||||
assert.ok(fs.existsSync(filePath)); |
|
||||||
fs.unlinkSync(filePath); // Delete file after test
|
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should call `onText` callback on match', function test(done) { |
|
||||||
const bot = new Telegram(TOKEN, { webHook: true }); |
|
||||||
bot.onText(/\/echo (.+)/, (msg, match) => { |
|
||||||
bot._WebHook._webServer.close(); |
|
||||||
assert.equal(match[1], 'ECHO ALOHA'); |
|
||||||
done(); |
|
||||||
}); |
|
||||||
const url = `http://localhost:8443/bot${TOKEN}`; |
|
||||||
request({ |
|
||||||
url, |
|
||||||
method: 'POST', |
|
||||||
json: true, |
|
||||||
headers: { |
|
||||||
'content-type': 'application/json', |
|
||||||
}, |
|
||||||
body: { update_id: 0, message: { text: '/echo ECHO ALOHA' } } |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); // End Telegram
|
|
||||||
|
|
||||||
describe('#TelegramBotPolling', function TelegramBotPollingSuite() { |
|
||||||
|
|
||||||
it('should call the callback on polling', function test(done) { |
|
||||||
const opts = { interval: 100, timeout: 1 }; |
|
||||||
const polling = new TelegramPolling(TOKEN, opts, (msg) => { |
|
||||||
if (msg.update_id === 10) { |
|
||||||
polling.stopPolling().then(() => { |
|
||||||
done(); |
|
||||||
}); |
|
||||||
} |
|
||||||
}); |
|
||||||
// The second time _getUpdates is called it will return a message
|
|
||||||
// Really dirty but it works
|
|
||||||
polling._getUpdates = () => { |
|
||||||
return new Promise.resolve([{ update_id: 10, message: {} }]); |
|
||||||
}; |
|
||||||
}); |
|
||||||
|
|
||||||
describe('#stopPolling', function stopPollingSuite() { |
|
||||||
it('should stop polling after last poll request', function test(done) { |
|
||||||
const opts = { interval: 200, timeout: 0.5 }; |
|
||||||
const polling = new TelegramPolling(TOKEN, opts, (msg) => { |
|
||||||
// error if message received as only one poll will complete and there should be no more because of stopPolling
|
|
||||||
done(msg); |
|
||||||
}); |
|
||||||
polling.stopPolling() |
|
||||||
.then(() => { |
|
||||||
setInterval(() => { |
|
||||||
done(); |
|
||||||
}, 1000); |
|
||||||
}).catch(done); |
|
||||||
// The second time _getUpdates is called it will return a message
|
|
||||||
// Really dirty but it works
|
|
||||||
polling._getUpdates = () => { |
|
||||||
return new Promise.resolve([{ update_id: 11, message: {} }]); |
|
||||||
}; |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
}); |
|
||||||
@ -1 +1,3 @@ |
|||||||
--require babel-register |
--reporter spec |
||||||
|
--require babel-register |
||||||
|
--timeout 30000 |
||||||
|
|||||||
@ -0,0 +1,878 @@ |
|||||||
|
const Telegram = require('../lib/telegram'); |
||||||
|
const Promise = require('bluebird'); |
||||||
|
const request = require('request-promise'); |
||||||
|
const assert = require('assert'); |
||||||
|
const fs = require('fs'); |
||||||
|
const os = require('os'); |
||||||
|
const path = require('path'); |
||||||
|
const is = require('is'); |
||||||
|
const utils = require('./utils'); |
||||||
|
|
||||||
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; |
||||||
|
const TOKEN = process.env.TEST_TELEGRAM_TOKEN; |
||||||
|
if (!TOKEN) { |
||||||
|
throw new Error('Bot token not provided'); |
||||||
|
} |
||||||
|
|
||||||
|
// Telegram service if not User Id
|
||||||
|
const USERID = process.env.TEST_USER_ID || 777000; |
||||||
|
const GROUPID = process.env.TEST_GROUP_ID || -1001075450562; |
||||||
|
const GAME_SHORT_NAME = process.env.TEST_GAME_SHORT_NAME || 'medusalab_test'; |
||||||
|
const timeout = 60 * 1000; |
||||||
|
const staticPort = 8091; |
||||||
|
const pollingPort = 8092; |
||||||
|
const webHookPort = 8093; |
||||||
|
const pollingPort2 = 8094; |
||||||
|
const webHookPort2 = 8095; |
||||||
|
const staticUrl = `http://127.0.0.1:${staticPort}`; |
||||||
|
let FILE_ID; |
||||||
|
let GAME_CHAT_ID; |
||||||
|
let GAME_MSG_ID; |
||||||
|
|
||||||
|
before(function beforeAll() { |
||||||
|
utils.startStaticServer(staticPort); |
||||||
|
return utils.startMockServer(pollingPort) |
||||||
|
.then(() => { |
||||||
|
return utils.startMockServer(pollingPort2); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('Telegram', function telegramSuite() { |
||||||
|
let bot; |
||||||
|
let testbot; |
||||||
|
let botPolling; |
||||||
|
let botWebHook; |
||||||
|
|
||||||
|
before(function beforeAll() { |
||||||
|
this.timeout(timeout); |
||||||
|
bot = new Telegram(TOKEN); |
||||||
|
testbot = new Telegram(TOKEN, { |
||||||
|
baseApiUrl: `http://127.0.0.1:${pollingPort}`, |
||||||
|
polling: { |
||||||
|
autoStart: false, |
||||||
|
}, |
||||||
|
webHook: { |
||||||
|
autoOpen: false, |
||||||
|
port: webHookPort, |
||||||
|
}, |
||||||
|
}); |
||||||
|
botPolling = new Telegram(TOKEN, { |
||||||
|
baseApiUrl: `http://127.0.0.1:${pollingPort2}`, |
||||||
|
polling: true, |
||||||
|
}); |
||||||
|
botWebHook = new Telegram(TOKEN, { |
||||||
|
webHook: { |
||||||
|
port: webHookPort2, |
||||||
|
}, |
||||||
|
}); |
||||||
|
|
||||||
|
utils.handleRatelimit(bot, 'sendPhoto', this); |
||||||
|
utils.handleRatelimit(bot, 'sendMessage', this); |
||||||
|
utils.handleRatelimit(bot, 'sendGame', this); |
||||||
|
return bot.sendPhoto(USERID, `${__dirname}/data/photo.gif`).then(resp => { |
||||||
|
FILE_ID = resp.photo[0].file_id; |
||||||
|
return bot.sendMessage(USERID, 'chat'); |
||||||
|
}).then(resp => { |
||||||
|
GAME_CHAT_ID = resp.chat.id; |
||||||
|
return bot.sendGame(USERID, GAME_SHORT_NAME); |
||||||
|
}).then(resp => { |
||||||
|
GAME_MSG_ID = resp.message_id; |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('automatically starts polling', function test() { |
||||||
|
assert.equal(botPolling.isPolling(), true); |
||||||
|
return utils.isPollingMockServer(pollingPort2); |
||||||
|
}); |
||||||
|
|
||||||
|
it('automatically opens webhook', function test() { |
||||||
|
assert.equal(botWebHook.hasOpenWebHook(), true); |
||||||
|
return utils.hasOpenWebHook(webHookPort2); |
||||||
|
}); |
||||||
|
|
||||||
|
it('does not automatically poll if "autoStart" is false', function test() { |
||||||
|
assert.equal(testbot.isPolling(), false); |
||||||
|
return utils.isPollingMockServer(pollingPort, true); |
||||||
|
}); |
||||||
|
|
||||||
|
it('does not automatically open webhook if "autoOpen" is false', function test() { |
||||||
|
assert.equal(testbot.hasOpenWebHook(), false); |
||||||
|
return utils.hasOpenWebHook(webHookPort, true); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('Events', function eventsSuite() { |
||||||
|
it('(polling) emits "message" on receiving message', function test(done) { |
||||||
|
botPolling.once('message', () => { |
||||||
|
return done(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('(webhook) emits "message" on receiving message', function test(done) { |
||||||
|
botWebHook.once('message', () => { |
||||||
|
return done(); |
||||||
|
}); |
||||||
|
utils.sendWebHookMessage(webHookPort2, TOKEN); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('WebHook', function webHookSuite() { |
||||||
|
it('returns 401 error if token is wrong', function test(done) { |
||||||
|
utils.sendWebHookMessage(webHookPort2, 'wrong-token').catch(resp => { |
||||||
|
assert.equal(resp.statusCode, 401); |
||||||
|
return done(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('only accepts POST method', function test() { |
||||||
|
const methods = ['GET', 'PUT', 'DELETE', 'OPTIONS']; |
||||||
|
return Promise.each(methods, (method) => { |
||||||
|
return utils.sendWebHookMessage(webHookPort2, TOKEN, { |
||||||
|
method, |
||||||
|
}).then(() => { |
||||||
|
throw new Error(`expected error with webhook ${method} request`); |
||||||
|
}).catch(resp => { |
||||||
|
if (!resp.statusCode) throw resp; |
||||||
|
if (resp.statusCode !== 418) throw new Error(`unexpected error: ${resp.body}`); |
||||||
|
}); |
||||||
|
}); // Promise.each
|
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#initPolling', function initPollingSuite() { |
||||||
|
it('initiates polling', function test() { |
||||||
|
testbot.initPolling(); |
||||||
|
return utils.isPollingMockServer(pollingPort); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#isPolling', function isPollingSuite() { |
||||||
|
it('returns true if bot is polling', function test() { |
||||||
|
assert.equal(testbot.isPolling(), true); |
||||||
|
return utils.isPollingMockServer(pollingPort); |
||||||
|
}); |
||||||
|
it('returns false if bot is not polling', function test() { |
||||||
|
return testbot.stopPolling().then(() => { |
||||||
|
assert.equal(testbot.isPolling(), false); |
||||||
|
utils.clearPollingCheck(pollingPort); |
||||||
|
return utils.isPollingMockServer(pollingPort, true); |
||||||
|
}); |
||||||
|
}); |
||||||
|
after(function after() { |
||||||
|
return testbot.initPolling(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#stopPolling', function stopPollingSuite() { |
||||||
|
it('stops polling by bot', function test() { |
||||||
|
return testbot.stopPolling().then(() => { |
||||||
|
utils.clearPollingCheck(pollingPort); |
||||||
|
return utils.isPollingMockServer(pollingPort, true); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#openWebHook', function openWebHookSuite() { |
||||||
|
it('opens webhook', function test() { |
||||||
|
testbot.openWebHook(); |
||||||
|
return utils.hasOpenWebHook(webHookPort); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#hasOpenWebHook', function hasOpenWebHookSuite() { |
||||||
|
it('returns true if webhook is opened', function test() { |
||||||
|
assert.equal(testbot.hasOpenWebHook(), true); |
||||||
|
return utils.hasOpenWebHook(webHookPort); |
||||||
|
}); |
||||||
|
it('returns false if webhook is closed', function test() { |
||||||
|
testbot.closeWebHook().then(() => { |
||||||
|
assert.equal(testbot.hasOpenWebHook(), false); |
||||||
|
return utils.hasOpenWebHook(webHookPort, true); |
||||||
|
}); |
||||||
|
}); |
||||||
|
after(function after() { |
||||||
|
return testbot.openWebHook(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#closeWebHook', function closeWebHookSuite() { |
||||||
|
it('closes webhook', function test() { |
||||||
|
testbot.closeWebHook().then(() => { |
||||||
|
return utils.hasOpenWebHook(webHookPort, true); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#getMe', function getMeSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'getMe', this); |
||||||
|
}); |
||||||
|
it('should return an User object', function test() { |
||||||
|
return bot.getMe().then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.number(resp.id)); |
||||||
|
assert.ok(is.string(resp.first_name)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#setWebHook', function setWebHookSuite() { |
||||||
|
const ip = '216.58.210.174'; |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'setWebHook', this); |
||||||
|
}); |
||||||
|
it('should set a webHook', function test() { |
||||||
|
// Google IP ¯\_(ツ)_/¯
|
||||||
|
return bot |
||||||
|
.setWebHook(ip) |
||||||
|
.then(resp => { |
||||||
|
assert.equal(resp, true); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should set a webHook with certificate', function test() { |
||||||
|
const cert = `${__dirname}/../examples/crt.pem`; |
||||||
|
return bot |
||||||
|
.setWebHook(ip, cert) |
||||||
|
.then(resp => { |
||||||
|
assert.equal(resp, true); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should delete the webHook', function test() { |
||||||
|
return bot |
||||||
|
.setWebHook('') |
||||||
|
.then(resp => { |
||||||
|
assert.equal(resp, true); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#getUpdates', function getUpdatesSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'getUpdates', this); |
||||||
|
}); |
||||||
|
it('should return an Array', function test() { |
||||||
|
return bot.getUpdates().then(resp => { |
||||||
|
assert.equal(Array.isArray(resp), true); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#sendMessage', function sendMessageSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendMessage', this); |
||||||
|
}); |
||||||
|
it('should send a message', function test() { |
||||||
|
return bot.sendMessage(USERID, 'test').then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.number(resp.message_id)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe.skip('#answerInlineQuery', function answerInlineQuerySuite() {}); |
||||||
|
|
||||||
|
describe('#forwardMessage', function forwardMessageSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendMessage', this); |
||||||
|
utils.handleRatelimit(bot, 'forwardMessage', this); |
||||||
|
}); |
||||||
|
it('should forward a message', function test() { |
||||||
|
return bot.sendMessage(USERID, 'test').then(resp => { |
||||||
|
const messageId = resp.message_id; |
||||||
|
return bot.forwardMessage(USERID, USERID, messageId) |
||||||
|
.then(forwarded => { |
||||||
|
assert.ok(is.object(forwarded)); |
||||||
|
assert.ok(is.number(forwarded.message_id)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#sendPhoto', function sendPhotoSuite() { |
||||||
|
let photoId; |
||||||
|
this.timeout(timeout); |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendPhoto', this); |
||||||
|
}); |
||||||
|
it('should send a photo from file', function test() { |
||||||
|
const photo = `${__dirname}/data/photo.gif`; |
||||||
|
return bot.sendPhoto(USERID, photo).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.array(resp.photo)); |
||||||
|
photoId = resp.photo[0].file_id; |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a photo from id', function test() { |
||||||
|
// Send the same photo as before
|
||||||
|
const photo = photoId; |
||||||
|
return bot.sendPhoto(USERID, photo).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.array(resp.photo)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a photo from fs.readStream', function test() { |
||||||
|
const photo = fs.createReadStream(`${__dirname}/data/photo.gif`); |
||||||
|
return bot.sendPhoto(USERID, photo).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.array(resp.photo)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a photo from request Stream', function test() { |
||||||
|
const photo = request(`${staticUrl}/photo.gif`); |
||||||
|
return bot.sendPhoto(USERID, photo).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.array(resp.photo)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a photo from a Buffer', function test() { |
||||||
|
const photo = fs.readFileSync(`${__dirname}/data/photo.gif`); |
||||||
|
return bot.sendPhoto(USERID, photo).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.array(resp.photo)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#sendAudio', function sendAudioSuite() { |
||||||
|
let audioId; |
||||||
|
this.timeout(timeout); |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendAudio', this); |
||||||
|
}); |
||||||
|
it('should send an MP3 audio', function test() { |
||||||
|
const audio = `${__dirname}/data/audio.mp3`; |
||||||
|
return bot.sendAudio(USERID, audio).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.audio)); |
||||||
|
audioId = resp.audio.file_id; |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send an audio from id', function test() { |
||||||
|
// Send the same audio as before
|
||||||
|
const audio = audioId; |
||||||
|
return bot.sendAudio(USERID, audio).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.audio)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send an audio from fs.readStream', function test() { |
||||||
|
const audio = fs.createReadStream(`${__dirname}/data/audio.mp3`); |
||||||
|
return bot.sendAudio(USERID, audio).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.audio)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send an audio from request Stream', function test() { |
||||||
|
const audio = request(`${staticUrl}/audio.mp3`); |
||||||
|
return bot.sendAudio(USERID, audio).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.audio)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send an audio from a Buffer', function test() { |
||||||
|
const audio = fs.readFileSync(`${__dirname}/data/audio.mp3`); |
||||||
|
return bot.sendAudio(USERID, audio).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.audio)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#sendDocument', function sendDocumentSuite() { |
||||||
|
let documentId; |
||||||
|
this.timeout(timeout); |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendDocument', this); |
||||||
|
}); |
||||||
|
it('should send a document from file', function test() { |
||||||
|
const document = `${__dirname}/data/photo.gif`; |
||||||
|
return bot.sendDocument(USERID, document).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.document)); |
||||||
|
documentId = resp.document.file_id; |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a document from id', function test() { |
||||||
|
// Send the same document as before
|
||||||
|
const document = documentId; |
||||||
|
return bot.sendDocument(USERID, document).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.document)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a document from fs.readStream', function test() { |
||||||
|
const document = fs.createReadStream(`${__dirname}/data/photo.gif`); |
||||||
|
return bot.sendDocument(USERID, document).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.document)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a document from request Stream', function test() { |
||||||
|
const document = request(`${staticUrl}/photo.gif`); |
||||||
|
return bot.sendDocument(USERID, document).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.document)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a document from a Buffer', function test() { |
||||||
|
const document = fs.readFileSync(`${__dirname}/data/photo.gif`); |
||||||
|
return bot.sendDocument(USERID, document).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.document)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#sendSticker', function sendStickerSuite() { |
||||||
|
let stickerId; |
||||||
|
this.timeout(timeout); |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendSticker', this); |
||||||
|
}); |
||||||
|
it('should send a sticker from file', function test() { |
||||||
|
const sticker = `${__dirname}/data/sticker.webp`; |
||||||
|
return bot.sendSticker(USERID, sticker).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.sticker)); |
||||||
|
stickerId = resp.sticker.file_id; |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a sticker from id', function test() { |
||||||
|
// Send the same photo as before
|
||||||
|
return bot.sendSticker(USERID, stickerId).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.sticker)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a sticker from fs.readStream', function test() { |
||||||
|
const sticker = fs.createReadStream(`${__dirname}/data/sticker.webp`); |
||||||
|
return bot.sendSticker(USERID, sticker).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.sticker)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a sticker from request Stream', function test() { |
||||||
|
const sticker = request(`${staticUrl}/sticker.webp`); |
||||||
|
return bot.sendSticker(USERID, sticker).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.sticker)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a sticker from a Buffer', function test() { |
||||||
|
const sticker = fs.readFileSync(`${__dirname}/data/sticker.webp`); |
||||||
|
return bot.sendSticker(USERID, sticker).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.sticker)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#sendVideo', function sendVideoSuite() { |
||||||
|
let videoId; |
||||||
|
this.timeout(timeout); |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendVideo', this); |
||||||
|
}); |
||||||
|
it('should send a video from file', function test() { |
||||||
|
const video = `${__dirname}/data/video.mp4`; |
||||||
|
return bot.sendVideo(USERID, video).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.video)); |
||||||
|
videoId = resp.video.file_id; |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a video from id', function test() { |
||||||
|
// Send the same video as before
|
||||||
|
return bot.sendVideo(USERID, videoId).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.video)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a video from fs.readStream', function test() { |
||||||
|
const video = fs.createReadStream(`${__dirname}/data/video.mp4`); |
||||||
|
return bot.sendVideo(USERID, video).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.video)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a video from request Stream', function test() { |
||||||
|
const video = request(`${staticUrl}/video.mp4`); |
||||||
|
return bot.sendVideo(USERID, video).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.video)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a video from a Buffer', function test() { |
||||||
|
const video = fs.readFileSync(`${__dirname}/data/video.mp4`); |
||||||
|
return bot.sendVideo(USERID, video).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.video)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#sendVoice', function sendVoiceSuite() { |
||||||
|
let voiceId; |
||||||
|
this.timeout(timeout); |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendVoice', this); |
||||||
|
}); |
||||||
|
it('should send a voice from file', function test() { |
||||||
|
const voice = `${__dirname}/data/voice.ogg`; |
||||||
|
return bot.sendVoice(USERID, voice).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.voice)); |
||||||
|
voiceId = resp.voice.file_id; |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a voice from id', function test() { |
||||||
|
// Send the same voice as before
|
||||||
|
return bot.sendVoice(USERID, voiceId).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.voice)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a voice from fs.readStream', function test() { |
||||||
|
const voice = fs.createReadStream(`${__dirname}/data/voice.ogg`); |
||||||
|
return bot.sendVoice(USERID, voice).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.voice)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a voice from request Stream', function test() { |
||||||
|
const voice = request(`${staticUrl}/voice.ogg`); |
||||||
|
return bot.sendVoice(USERID, voice).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.voice)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should send a voice from a Buffer', function test() { |
||||||
|
const voice = fs.readFileSync(`${__dirname}/data/voice.ogg`); |
||||||
|
return bot.sendVoice(USERID, voice).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.voice)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#sendChatAction', function sendChatActionSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendChatAction', this); |
||||||
|
}); |
||||||
|
it('should send a chat action', function test() { |
||||||
|
const action = 'typing'; |
||||||
|
return bot.sendChatAction(USERID, action).then(resp => { |
||||||
|
assert.equal(resp, true); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe.skip('#kickChatMember', function kickChatMemberSuite() {}); |
||||||
|
|
||||||
|
describe.skip('#unbanChatMember', function unbanChatMemberSuite() {}); |
||||||
|
|
||||||
|
describe.skip('#answerCallbackQuery', function answerCallbackQuerySuite() {}); |
||||||
|
|
||||||
|
describe('#editMessageText', function editMessageTextSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendMessage', this); |
||||||
|
utils.handleRatelimit(bot, 'editMessageText', this); |
||||||
|
}); |
||||||
|
it('should edit a message sent by the bot', function test() { |
||||||
|
return bot.sendMessage(USERID, 'test').then(resp => { |
||||||
|
assert.equal(resp.text, 'test'); |
||||||
|
const opts = { |
||||||
|
chat_id: USERID, |
||||||
|
message_id: resp.message_id |
||||||
|
}; |
||||||
|
return bot.editMessageText('edit test', opts).then(msg => { |
||||||
|
assert.equal(msg.text, 'edit test'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#editMessageCaption', function editMessageCaptionSuite() { |
||||||
|
this.timeout(timeout); |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendPhoto', this); |
||||||
|
utils.handleRatelimit(bot, 'editMessageCaption', this); |
||||||
|
}); |
||||||
|
it('should edit a caption sent by the bot', function test() { |
||||||
|
const photo = `${__dirname}/data/photo.gif`; |
||||||
|
const options = { caption: 'test caption' }; |
||||||
|
return bot.sendPhoto(USERID, photo, options).then(resp => { |
||||||
|
assert.equal(resp.caption, 'test caption'); |
||||||
|
const opts = { |
||||||
|
chat_id: USERID, |
||||||
|
message_id: resp.message_id |
||||||
|
}; |
||||||
|
return bot.editMessageCaption('new test caption', opts).then(msg => { |
||||||
|
assert.equal(msg.caption, 'new test caption'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#editMessageReplyMarkup', function editMessageReplyMarkupSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendMessage', this); |
||||||
|
utils.handleRatelimit(bot, 'editMessageReplyMarkup', this); |
||||||
|
}); |
||||||
|
it('should edit previously-set reply markup', function test() { |
||||||
|
return bot.sendMessage(USERID, 'test').then(resp => { |
||||||
|
const replyMarkup = JSON.stringify({ |
||||||
|
inline_keyboard: [[{ |
||||||
|
text: 'Test button', |
||||||
|
callback_data: 'test' |
||||||
|
}]] |
||||||
|
}); |
||||||
|
const opts = { |
||||||
|
chat_id: USERID, |
||||||
|
message_id: resp.message_id |
||||||
|
}; |
||||||
|
return bot.editMessageReplyMarkup(replyMarkup, opts).then(msg => { |
||||||
|
// Keyboard markup is not returned, do a simple object check
|
||||||
|
assert.ok(is.object(msg)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#getUserProfilePhotos', function getUserProfilePhotosSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'getUserProfilePhotos', this); |
||||||
|
}); |
||||||
|
it('should get user profile photos', function test() { |
||||||
|
return bot.getUserProfilePhotos(USERID).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.number(resp.total_count)); |
||||||
|
assert.ok(is.array(resp.photos)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#sendLocation', function sendLocationSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendLocation', this); |
||||||
|
}); |
||||||
|
it('should send a location', function test() { |
||||||
|
const lat = 47.5351072; |
||||||
|
const long = -52.7508537; |
||||||
|
return bot.sendLocation(USERID, lat, long).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.location)); |
||||||
|
assert.ok(is.number(resp.location.latitude)); |
||||||
|
assert.ok(is.number(resp.location.longitude)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#sendVenue', function sendVenueSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendVenue', this); |
||||||
|
}); |
||||||
|
it('should send a venue', function test() { |
||||||
|
const lat = 47.5351072; |
||||||
|
const long = -52.7508537; |
||||||
|
const title = 'The Village Shopping Centre'; |
||||||
|
const address = '430 Topsail Rd,St. John\'s, NL A1E 4N1, Canada'; |
||||||
|
return bot.sendVenue(USERID, lat, long, title, address).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.venue)); |
||||||
|
assert.ok(is.object(resp.venue.location)); |
||||||
|
assert.ok(is.number(resp.venue.location.latitude)); |
||||||
|
assert.ok(is.number(resp.venue.location.longitude)); |
||||||
|
assert.ok(is.string(resp.venue.title)); |
||||||
|
assert.ok(is.string(resp.venue.address)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
// NOTE: We are skipping TelegramBot#sendContact() as the
|
||||||
|
// corresponding rate-limits enforced by the Telegram servers
|
||||||
|
// are too strict! During our initial tests, we were required
|
||||||
|
// to retry after ~72000 secs (1200 mins / 20 hrs).
|
||||||
|
// We surely can NOT wait for that much time during testing
|
||||||
|
// (or in most practical cases for that matter!)
|
||||||
|
describe.skip('#sendContact', function sendContactSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendContact', this); |
||||||
|
}); |
||||||
|
it('should send a contact', function test() { |
||||||
|
const phoneNumber = '+1(000)000-000'; |
||||||
|
const firstName = 'John Doe'; |
||||||
|
return bot.sendContact(USERID, phoneNumber, firstName).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.contact)); |
||||||
|
assert.ok(is.string(resp.contact.phone_number)); |
||||||
|
assert.ok(is.string(resp.contact.first_name)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#getFile', function getFileSuite() { |
||||||
|
this.timeout(timeout); |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'getFile', this); |
||||||
|
}); |
||||||
|
it('should get a file', function test() { |
||||||
|
return bot.getFile(FILE_ID) |
||||||
|
.then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.string(resp.file_path)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#getFileLink', function getFileLinkSuite() { |
||||||
|
this.timeout(timeout); |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'getFileLink', this); |
||||||
|
}); |
||||||
|
it('should get a file link', function test() { |
||||||
|
return bot.getFileLink(FILE_ID) |
||||||
|
.then(fileURI => { |
||||||
|
assert.ok(is.string(fileURI)); |
||||||
|
assert.ok(/https?:\/\/.*\/file\/bot.*\/.*/.test(fileURI)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#downloadFile', function downloadFileSuite() { |
||||||
|
const downloadPath = os.tmpdir(); |
||||||
|
this.timeout(timeout); |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'downloadFile', this); |
||||||
|
}); |
||||||
|
it('should download a file', function test() { |
||||||
|
return bot.downloadFile(FILE_ID, downloadPath) |
||||||
|
.then(filePath => { |
||||||
|
assert.ok(is.string(filePath)); |
||||||
|
assert.equal(path.dirname(filePath), downloadPath); |
||||||
|
assert.ok(fs.existsSync(filePath)); |
||||||
|
fs.unlinkSync(filePath); // Delete file after test
|
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#onText', function onTextSuite() { |
||||||
|
it('should call `onText` callback on match', function test(done) { |
||||||
|
botWebHook.onText(/\/onText (.+)/, (msg, match) => { |
||||||
|
assert.equal(match[1], 'ECHO ALOHA'); |
||||||
|
return done(); |
||||||
|
}); |
||||||
|
utils.sendWebHookMessage(webHookPort2, TOKEN, { |
||||||
|
message: { text: '/onText ECHO ALOHA' }, |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe.skip('#onReplyToMessage', function onReplyToMessageSuite() {}); |
||||||
|
|
||||||
|
describe('#getChat', function getChatSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'getChat', this); |
||||||
|
}); |
||||||
|
it('should return a Chat object', function test() { |
||||||
|
return bot.getChat(USERID).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#getChatAdministrators', function getChatAdministratorsSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'getChatAdministrators', this); |
||||||
|
}); |
||||||
|
it('should return an Array', function test() { |
||||||
|
return bot.getChatAdministrators(GROUPID).then(resp => { |
||||||
|
assert.ok(Array.isArray(resp)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#getChatMembersCount', function getChatMembersCountSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'getChatMembersCount', this); |
||||||
|
}); |
||||||
|
it('should return an Integer', function test() { |
||||||
|
return bot.getChatMembersCount(GROUPID).then(resp => { |
||||||
|
assert.ok(Number.isInteger(resp)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#getChatMember', function getChatMemberSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'getChatMember', this); |
||||||
|
}); |
||||||
|
it('should return a ChatMember', function test() { |
||||||
|
return bot.getChatMember(GROUPID, USERID).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.user)); |
||||||
|
assert.ok(is.string(resp.status)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe.skip('#leaveChat', function leaveChatSuite() {}); |
||||||
|
|
||||||
|
describe('#sendGame', function sendGameSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'sendGame', this); |
||||||
|
}); |
||||||
|
it('should send a Game', function test() { |
||||||
|
return bot.sendGame(USERID, GAME_SHORT_NAME).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.object(resp.game)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#setGameScore', function setGameScoreSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'setGameScore', this); |
||||||
|
}); |
||||||
|
it('should set GameScore', function test() { |
||||||
|
const score = Math.floor(Math.random() * 1000); |
||||||
|
const opts = { |
||||||
|
chat_id: GAME_CHAT_ID, |
||||||
|
message_id: GAME_MSG_ID, |
||||||
|
force: true |
||||||
|
}; |
||||||
|
return bot.setGameScore(USERID, score, opts).then(resp => { |
||||||
|
assert.ok(is.object(resp) || is.boolean(resp)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#getGameHighScores', function getGameHighScoresSuite() { |
||||||
|
before(function before() { |
||||||
|
utils.handleRatelimit(bot, 'getGameHighScores', this); |
||||||
|
}); |
||||||
|
it('should get GameHighScores', function test() { |
||||||
|
const opts = { |
||||||
|
chat_id: GAME_CHAT_ID, |
||||||
|
message_id: GAME_MSG_ID, |
||||||
|
}; |
||||||
|
return bot.getGameHighScores(USERID, opts).then(resp => { |
||||||
|
assert.ok(is.array(resp)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#_formatSendData', function _formatSendDataSuite() { |
||||||
|
it('should handle buffer path from fs.readStream', function test() { |
||||||
|
let photo; |
||||||
|
try { |
||||||
|
photo = fs.createReadStream(Buffer.from(`${__dirname}/data/photo.gif`)); |
||||||
|
} catch (ex) { |
||||||
|
// Older Node.js versions do not support passing a Buffer
|
||||||
|
// representation of the path to fs.createReadStream()
|
||||||
|
if (ex instanceof TypeError) return Promise.resolve(); |
||||||
|
} |
||||||
|
return bot.sendPhoto(USERID, photo).then(resp => { |
||||||
|
assert.ok(is.object(resp)); |
||||||
|
assert.ok(is.array(resp.photo)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); // End Telegram
|
||||||
@ -0,0 +1,190 @@ |
|||||||
|
/* eslint-disable no-use-before-define */ |
||||||
|
exports = module.exports = { |
||||||
|
/** |
||||||
|
* Clear polling check, so that 'isPollingMockServer()' returns false |
||||||
|
* if the bot stopped polling the mock server. |
||||||
|
* @param {Number} port |
||||||
|
*/ |
||||||
|
clearPollingCheck, |
||||||
|
/** |
||||||
|
* Redefine a bot method to allow us to ignore 429 (rate-limit) errors |
||||||
|
* @param {TelegramBot} bot |
||||||
|
* @param {String} methodName |
||||||
|
* @param {Suite} suite From mocha |
||||||
|
* @return {TelegramBot} |
||||||
|
*/ |
||||||
|
handleRatelimit, |
||||||
|
/** |
||||||
|
* Return true if a webhook has been opened at the specified port. |
||||||
|
* Otherwise throw an error. |
||||||
|
* @param {Number} port |
||||||
|
* @param {Boolean} [reverse] Throw error when it should have returned true (and vice versa) |
||||||
|
* @return {Promise} |
||||||
|
*/ |
||||||
|
hasOpenWebHook, |
||||||
|
/** |
||||||
|
* Return true if the mock server is being polled by a bot. |
||||||
|
* Otherwise throw an error. |
||||||
|
* @param {Number} port |
||||||
|
* @param {Boolean} [reverse] Throw error when it should have returned true (and vice versa) |
||||||
|
* @return {Promise} |
||||||
|
*/ |
||||||
|
isPollingMockServer, |
||||||
|
/** |
||||||
|
* Send a message to the webhook at the specified port. |
||||||
|
* @param {Number} port |
||||||
|
* @param {String} token |
||||||
|
* @param {Object} [options] |
||||||
|
* @param {String} [options.method=POST] Method to use |
||||||
|
* @param {Object} [options.message] Message to send. Default to a generic text message |
||||||
|
* @return {Promise} |
||||||
|
*/ |
||||||
|
sendWebHookMessage, |
||||||
|
/** |
||||||
|
* Start a mock server at the specified port. |
||||||
|
* @param {Number} port |
||||||
|
* @return {Promise} |
||||||
|
*/ |
||||||
|
startMockServer, |
||||||
|
/** |
||||||
|
* Start the static server, serving files in './data' |
||||||
|
* @param {Number} port |
||||||
|
*/ |
||||||
|
startStaticServer, |
||||||
|
}; |
||||||
|
/* eslint-enable no-use-before-define */ |
||||||
|
|
||||||
|
|
||||||
|
const assert = require('assert'); |
||||||
|
const http = require('http'); |
||||||
|
const Promise = require('bluebird'); |
||||||
|
const request = require('request-promise'); |
||||||
|
const statics = require('node-static'); |
||||||
|
|
||||||
|
const servers = {}; |
||||||
|
|
||||||
|
|
||||||
|
function startMockServer(port) { |
||||||
|
assert.ok(port); |
||||||
|
const server = http.Server((req, res) => { |
||||||
|
servers[port].polling = true; |
||||||
|
return res.end(JSON.stringify({ |
||||||
|
ok: true, |
||||||
|
result: [{ |
||||||
|
update_id: 0, |
||||||
|
message: { text: 'test' }, |
||||||
|
}], |
||||||
|
})); |
||||||
|
}); |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
servers[port] = { server, polling: false }; |
||||||
|
server.on('error', reject).listen(port, resolve); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
function startStaticServer(port) { |
||||||
|
const fileServer = new statics.Server(`${__dirname}/data`); |
||||||
|
http.Server((req, res) => { |
||||||
|
req.addListener('end', () => { |
||||||
|
fileServer.serve(req, res); |
||||||
|
}).resume(); |
||||||
|
}).listen(port); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
function isPollingMockServer(port, reverse) { |
||||||
|
assert.ok(port); |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
// process.nextTick() does not wait until a poll request
|
||||||
|
// is complete!
|
||||||
|
setTimeout(() => { |
||||||
|
let polling = servers[port] && servers[port].polling; |
||||||
|
if (reverse) polling = !polling; |
||||||
|
if (polling) return resolve(true); |
||||||
|
return reject(new Error('polling-check failed')); |
||||||
|
}, 1000); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
function clearPollingCheck(port) { |
||||||
|
assert.ok(port); |
||||||
|
if (servers[port]) servers[port].polling = false; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
function hasOpenWebHook(port, reverse) { |
||||||
|
assert.ok(port); |
||||||
|
const error = new Error('open-webhook-check failed'); |
||||||
|
let connected = false; |
||||||
|
return request.get(`http://127.0.0.1:${port}`) |
||||||
|
.then(() => { |
||||||
|
connected = true; |
||||||
|
}).catch(e => { |
||||||
|
if (e.statusCode < 500) connected = true; |
||||||
|
}).finally(() => { |
||||||
|
if (reverse) { |
||||||
|
if (connected) throw error; |
||||||
|
return; |
||||||
|
} |
||||||
|
if (!connected) throw error; |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
function sendWebHookMessage(port, token, options = {}) { |
||||||
|
assert.ok(port); |
||||||
|
assert.ok(token); |
||||||
|
const url = `http://127.0.0.1:${port}/bot${token}`; |
||||||
|
return request({ |
||||||
|
url, |
||||||
|
method: options.method || 'POST', |
||||||
|
body: { |
||||||
|
update_id: 1, |
||||||
|
message: options.message || { text: 'test' } |
||||||
|
}, |
||||||
|
json: true, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
function handleRatelimit(bot, methodName, suite) { |
||||||
|
const backupMethodName = `__${methodName}`; |
||||||
|
if (!bot[backupMethodName]) bot[backupMethodName] = bot[methodName]; |
||||||
|
|
||||||
|
const maxRetries = 3; |
||||||
|
const addSecs = 5; |
||||||
|
const method = bot[backupMethodName]; |
||||||
|
assert.equal(typeof method, 'function'); |
||||||
|
|
||||||
|
bot[methodName] = (...args) => { |
||||||
|
let retry = 0; |
||||||
|
function exec() { |
||||||
|
return method.call(bot, ...args) |
||||||
|
.catch(error => { |
||||||
|
if (!error.response || error.response.statusCode !== 429) { |
||||||
|
throw error; |
||||||
|
} |
||||||
|
retry++; |
||||||
|
if (retry > maxRetries) { |
||||||
|
throw error; |
||||||
|
} |
||||||
|
if (typeof error.response.body === 'string') { |
||||||
|
error.response.body = JSON.parse(error.response.body); |
||||||
|
} |
||||||
|
const retrySecs = error.response.body.parameters.retry_after; |
||||||
|
const timeout = (1000 * retrySecs) + (1000 * addSecs); |
||||||
|
console.error('tests: Handling rate-limit error. Retrying after %d secs', timeout / 1000); // eslint-disable-line no-console
|
||||||
|
suite.timeout(timeout * 2); |
||||||
|
return new Promise(function timeoutPromise(resolve, reject) { |
||||||
|
setTimeout(function execTimeout() { |
||||||
|
return exec().then(resolve).catch(reject); |
||||||
|
}, timeout); |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
return exec(); |
||||||
|
}; |
||||||
|
return bot; |
||||||
|
} |
||||||
Binary file not shown.
Loading…
Reference in new issue