import MockAdapter from 'axios-mock-adapter'; import ViberClient from '../ViberClient'; import * as ViberTypes from '../ViberTypes'; const { EventType } = ViberTypes; const AUTH_TOKEN = '445da6az1s345z78-dazcczb2542zv51a-e0vc5fva17480im9'; const RECEIVER = '1234567890'; const SENDER = { name: 'John McClane', avatar: 'http://avatar.example.com', }; const createMock = (): { client: ViberClient; mock: MockAdapter } => { const client = new ViberClient({ accessToken: AUTH_TOKEN, sender: SENDER, }); const mock = new MockAdapter(client.axios); return { client, mock }; }; describe('webhooks', () => { describe('#setWebhook', () => { it('should response eventTypes was set', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', eventTypes: [ 'delivered', 'seen', 'failed', 'subscribed', 'unsubscribed', 'conversation_started', ], }; mock .onPost('/set_webhook', { url: 'https://4a16faff.ngrok.io/' }) .reply(200, reply); const res = await client.setWebhook('https://4a16faff.ngrok.io/'); expect(res).toEqual(reply); }); it('should work with custom event types', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', eventTypes: ['delivered', 'seen', 'conversation_started'], }; mock .onPost('/set_webhook', { url: 'https://4a16faff.ngrok.io/', event_types: ['delivered', 'seen', 'conversation_started'], }) .reply(200, reply); const res = await client.setWebhook('https://4a16faff.ngrok.io/', [ EventType.Delivered, EventType.Seen, EventType.ConversationStarted, ]); expect(res).toEqual(reply); }); }); describe('#removeWebhook', () => { it('should remove subscribed webhook', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', }; mock.onPost('/set_webhook', { url: '' }).reply(200, reply); const res = await client.removeWebhook(); expect(res).toEqual(reply); }); }); }); describe('send message', () => { describe('#sendMessage', () => { it('should call viber api', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'text', text: 'Hello', }) .reply(200, reply); const res = await client.sendMessage(RECEIVER, { type: 'text', text: 'Hello', }); expect(res).toEqual(reply); }); }); describe('#sendText', () => { it('should call viber api', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'text', text: 'Hello', }) .reply(200, reply); const res = await client.sendText(RECEIVER, 'Hello'); expect(res).toEqual(reply); }); }); describe('#sendPicture', () => { it('should call viber api', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'picture', text: 'Photo description', media: 'http://www.images.com/img.jpg', thumbnail: 'http://www.images.com/thumb.jpg', }) .reply(200, reply); const res = await client.sendPicture(RECEIVER, { text: 'Photo description', media: 'http://www.images.com/img.jpg', thumbnail: 'http://www.images.com/thumb.jpg', }); expect(res).toEqual(reply); }); }); describe('#sendVideo', () => { it('should call viber api', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'video', media: 'http://www.images.com/video.mp4', size: 10000, thumbnail: 'http://www.images.com/thumb.jpg', duration: 10, }) .reply(200, reply); const res = await client.sendVideo(RECEIVER, { media: 'http://www.images.com/video.mp4', size: 10000, thumbnail: 'http://www.images.com/thumb.jpg', duration: 10, }); expect(res).toEqual(reply); }); }); describe('#sendFile', () => { it('should call viber api', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'file', media: 'http://www.images.com/file.doc', size: 10000, file_name: 'name_of_file.doc', }) .reply(200, reply); const res = await client.sendFile(RECEIVER, { media: 'http://www.images.com/file.doc', size: 10000, fileName: 'name_of_file.doc', }); expect(res).toEqual(reply); }); it('should support snakecase', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'file', media: 'http://www.images.com/file.doc', size: 10000, file_name: 'name_of_file.doc', }) .reply(200, reply); const res = await client.sendFile(RECEIVER, { media: 'http://www.images.com/file.doc', size: 10000, // @ts-expect-error file_name: 'name_of_file.doc', }); expect(res).toEqual(reply); }); }); describe('#sendContact', () => { it('should call viber api', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'contact', contact: { name: 'Itamar', phone_number: '+972511123123', }, }) .reply(200, reply); const res = await client.sendContact(RECEIVER, { name: 'Itamar', phoneNumber: '+972511123123', }); expect(res).toEqual(reply); }); it('should support snakecase', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'contact', contact: { name: 'Itamar', phone_number: '+972511123123', }, }) .reply(200, reply); const res = await client.sendContact(RECEIVER, { name: 'Itamar', // @ts-expect-error phone_number: '+972511123123', }); expect(res).toEqual(reply); }); }); describe('#sendLocation', () => { it('should call viber api', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'location', location: { lat: '37.7898', lon: '-122.3942', }, }) .reply(200, reply); const res = await client.sendLocation(RECEIVER, { lat: '37.7898', lon: '-122.3942', }); expect(res).toEqual(reply); }); }); describe('#sendURL', () => { it('should call viber api', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'url', media: 'http://developers.viber.com', }) .reply(200, reply); const res = await client.sendURL(RECEIVER, 'http://developers.viber.com'); expect(res).toEqual(reply); }); }); describe('#sendSticker', () => { it('should call viber api', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'sticker', sticker_id: 46105, }) .reply(200, reply); const res = await client.sendSticker(RECEIVER, 46105); expect(res).toEqual(reply); }); }); describe('#sendCarouselContent', () => { it('should call viber api', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; const richMedia = { type: 'rich_media', buttonsGroupColumns: 6, buttonsGroupRows: 7, bgColor: '#FFFFFF', buttons: [ { columns: 6, rows: 3, actionType: 'open-url', actionBody: 'https://www.google.com', image: 'http://html-test:8080/myweb/guy/assets/imageRMsmall2.png', }, { columns: 6, rows: 2, text: 'Headphones with Microphone, On-ear Wired earphones
Sound Intone
$17.99', actionType: 'open-url', actionBody: 'https://www.google.com', textSize: 'medium', textVAlign: 'middle', textHAlign: 'left', }, { columns: 6, rows: 1, actionType: 'reply', actionBody: 'https://www.google.com', text: 'Buy', textSize: 'large', textVAlign: 'middle', textHAlign: 'middle', image: 'https://s14.postimg.org/4mmt4rw1t/Button.png', }, { columns: 6, rows: 1, actionType: 'reply', actionBody: 'https://www.google.com', text: 'MORE DETAILS', textSize: 'small', textVAlign: 'middle', textHAlign: 'middle', }, { columns: 6, rows: 3, ActionType: 'open-url', ActionBody: 'https://www.google.com', Image: 'https://s16.postimg.org/wi8jx20wl/image_RMsmall2.png', }, { columns: 6, rows: 2, text: "Hanes Men's Humor Graphic T-Shirt
Hanes
$10.99", actionType: 'open-url', actionBody: 'https://www.google.com', textSize: 'medium', textVAlign: 'middle', textHAlign: 'left', }, { columns: 6, rows: 1, actionType: 'reply', actionBody: 'https://www.google.com', text: 'Buy', textSize: 'large', textVAlign: 'middle', textHAlign: 'middle', image: 'https://s14.postimg.org/4mmt4rw1t/Button.png', }, { columns: 6, rows: 1, actionType: 'reply', actionBody: 'https://www.google.com', text: 'MORE DETAILS', textSize: 'small', textVAlign: 'middle', textHAlign: 'middle', }, ], }; const pascalcaseRichMedia = { Type: 'rich_media', ButtonsGroupColumns: 6, ButtonsGroupRows: 7, BgColor: '#FFFFFF', Buttons: [ { Columns: 6, Rows: 3, ActionType: 'open-url', ActionBody: 'https://www.google.com', Image: 'http://html-test:8080/myweb/guy/assets/imageRMsmall2.png', }, { Columns: 6, Rows: 2, Text: 'Headphones with Microphone, On-ear Wired earphones
Sound Intone
$17.99', ActionType: 'open-url', ActionBody: 'https://www.google.com', TextSize: 'medium', TextVAlign: 'middle', TextHAlign: 'left', }, { Columns: 6, Rows: 1, ActionType: 'reply', ActionBody: 'https://www.google.com', Text: 'Buy', TextSize: 'large', TextVAlign: 'middle', TextHAlign: 'middle', Image: 'https://s14.postimg.org/4mmt4rw1t/Button.png', }, { Columns: 6, Rows: 1, ActionType: 'reply', ActionBody: 'https://www.google.com', Text: 'MORE DETAILS', TextSize: 'small', TextVAlign: 'middle', TextHAlign: 'middle', }, { Columns: 6, Rows: 3, ActionType: 'open-url', ActionBody: 'https://www.google.com', Image: 'https://s16.postimg.org/wi8jx20wl/image_RMsmall2.png', }, { Columns: 6, Rows: 2, Text: "Hanes Men's Humor Graphic T-Shirt
Hanes
$10.99", ActionType: 'open-url', ActionBody: 'https://www.google.com', TextSize: 'medium', TextVAlign: 'middle', TextHAlign: 'left', }, { Columns: 6, Rows: 1, ActionType: 'reply', ActionBody: 'https://www.google.com', Text: 'Buy', TextSize: 'large', TextVAlign: 'middle', TextHAlign: 'middle', Image: 'https://s14.postimg.org/4mmt4rw1t/Button.png', }, { Columns: 6, Rows: 1, ActionType: 'reply', ActionBody: 'https://www.google.com', Text: 'MORE DETAILS', TextSize: 'small', TextVAlign: 'middle', TextHAlign: 'middle', }, ], }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'rich_media', min_api_version: 2, rich_media: pascalcaseRichMedia, }) .reply(200, reply); const res = await client.sendCarouselContent(RECEIVER, richMedia); expect(res).toEqual(reply); }); it('should support pascalcase', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; const richMedia = { Type: 'rich_media', ButtonsGroupColumns: 6, ButtonsGroupRows: 7, BgColor: '#FFFFFF', Buttons: [ { Columns: 6, Rows: 3, ActionType: 'open-url', ActionBody: 'https://www.google.com', Image: 'http://html-test:8080/myweb/guy/assets/imageRMsmall2.png', }, { Columns: 6, Rows: 2, Text: 'Headphones with Microphone, On-ear Wired earphones
Sound Intone
$17.99', ActionType: 'open-url', ActionBody: 'https://www.google.com', TextSize: 'medium', TextVAlign: 'middle', TextHAlign: 'left', }, { Columns: 6, Rows: 1, ActionType: 'reply', ActionBody: 'https://www.google.com', Text: 'Buy', TextSize: 'large', TextVAlign: 'middle', TextHAlign: 'middle', Image: 'https://s14.postimg.org/4mmt4rw1t/Button.png', }, { Columns: 6, Rows: 1, ActionType: 'reply', ActionBody: 'https://www.google.com', Text: 'MORE DETAILS', TextSize: 'small', TextVAlign: 'middle', TextHAlign: 'middle', }, { Columns: 6, Rows: 3, ActionType: 'open-url', ActionBody: 'https://www.google.com', Image: 'https://s16.postimg.org/wi8jx20wl/image_RMsmall2.png', }, { Columns: 6, Rows: 2, Text: "Hanes Men's Humor Graphic T-Shirt
Hanes
$10.99", ActionType: 'open-url', ActionBody: 'https://www.google.com', TextSize: 'medium', TextVAlign: 'middle', TextHAlign: 'left', }, { Columns: 6, Rows: 1, ActionType: 'reply', ActionBody: 'https://www.google.com', Text: 'Buy', TextSize: 'large', TextVAlign: 'middle', TextHAlign: 'middle', Image: 'https://s14.postimg.org/4mmt4rw1t/Button.png', }, { Columns: 6, Rows: 1, ActionType: 'reply', ActionBody: 'https://www.google.com', Text: 'MORE DETAILS', TextSize: 'small', TextVAlign: 'middle', TextHAlign: 'middle', }, ], }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'rich_media', min_api_version: 2, rich_media: richMedia, }) .reply(200, reply); // @ts-expect-error const res = await client.sendCarouselContent(RECEIVER, richMedia); expect(res).toEqual(reply); }); }); }); describe('keyboards', () => { it('should work with message api', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; const keyboard = { type: 'keyboard', defaultHeight: true, buttons: [ { actionType: 'reply', actionBody: 'reply to me', text: 'Key text', textSize: 'regular', }, ], }; const pascalcaseKeyboard = { Type: 'keyboard', DefaultHeight: true, Buttons: [ { ActionType: 'reply', ActionBody: 'reply to me', Text: 'Key text', TextSize: 'regular', }, ], }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'text', text: 'Hello', keyboard: pascalcaseKeyboard, }) .reply(200, reply); const res = await client.sendText(RECEIVER, 'Hello', { keyboard, }); expect(res).toEqual(reply); }); it('should support pascalcase', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', messageToken: 5098034272017990000, }; const keyboard = { Type: 'keyboard', DefaultHeight: true, Buttons: [ { ActionType: 'reply', ActionBody: 'reply to me', Text: 'Key text', TextSize: 'regular', }, ], }; mock .onPost(`/send_message`, { receiver: RECEIVER, sender: { name: 'John McClane', avatar: 'http://avatar.example.com', }, type: 'text', text: 'Hello', keyboard, }) .reply(200, reply); const res = await client.sendText(RECEIVER, 'Hello', { // @ts-expect-error keyboard, }); expect(res).toEqual(reply); }); }); describe('get account info', () => { describe('#getAccountInfo', () => { it('should call viber api', async () => { const { client, mock } = createMock(); const reply = { status: 0, statusMessage: 'ok', id: 'pa:75346594275468546724', name: 'account name', uri: 'accountUri', icon: 'http://example.com', background: 'http://example.com', category: 'category', subcategory: 'sub category', location: { lon: 0.1, lat: 0.2, }, country: 'UK', webhook: 'https://my.site.com', eventTypes: ['delivered', 'seen'], subscribersCount: 35, members: [ { id: '01234567890A=', name: 'my name', avatar: 'http://example.com', role: 'admin', }, ], }; mock.onPost(`/get_account_info`, {}).reply(200, reply); const res = await client.getAccountInfo(); expect(res).toEqual(reply); }); }); }); describe('get user details', () => { describe('#getUserDetails', () => { it('should call viber api', async () => { const { client, mock } = createMock(); const user = { id: '01234567890A=', name: 'John McClane', avatar: 'http://avatar.example.com', country: 'UK', language: 'en', primaryDeviceOs: 'android 7.1', apiVersion: 1, viberVersion: '6.5.0', mcc: 1, mnc: 1, deviceType: 'iPhone9,4', }; const reply = { status: 0, status_message: 'ok', message_token: 4912661846655238145, user, }; mock .onPost(`/get_user_details`, { id: '01234567890A=', }) .reply(200, reply); const res = await client.getUserDetails('01234567890A='); expect(res).toEqual(user); }); }); }); describe('get online', () => { describe('#getOnlineStatus', () => { it('should call viber api', async () => { const { client, mock } = createMock(); const users = [ { id: '01234567890=', onlineStatus: 0, onlineStatusMessage: 'online', }, { id: '01234567891=', onlineStatus: 1, onlineStatusMessage: 'offline', lastOnline: 1457764197627, }, { id: '01234567893=', onlineStatus: 3, onlineStatusMessage: 'tryLater', }, ]; const reply = { status: 0, status_message: 'ok', users, }; mock .onPost(`/get_online`, { ids: ['01234567890=', '01234567891=', '01234567893='], }) .reply(200, reply); const res = await client.getOnlineStatus([ '01234567890=', '01234567891=', '01234567893=', ]); expect(res).toEqual(users); }); }); });