-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
271 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* Creates ButtonOptions for the paginator | ||
* | ||
* @param totalPages total amount of pages. Array.length is a good way to return this one. | ||
* @param currentPage current page. Has to be between [1..totalPages] | ||
* @return returns the ButtonOptions | ||
*/ | ||
function paginationOptions(totalPages, currentPage) { | ||
// Numbers have to be within | ||
// currentPage in [1..totalPages] | ||
const totalPagesFixed = Math.ceil(totalPages) | ||
const currentPageFixed = Math.max(1, Math.min(totalPagesFixed, Math.floor(currentPage))) | ||
|
||
const buttons = {} | ||
if (!isFinite(totalPagesFixed) || !isFinite(currentPage) || totalPagesFixed < 2) { | ||
return buttons | ||
} | ||
|
||
const before = currentPageFixed - 1 | ||
const after = currentPageFixed + 1 | ||
|
||
if (currentPageFixed > 1) { | ||
if (before > 1) { | ||
buttons[1] = '⏪ 1' | ||
} | ||
|
||
buttons[before] = '◀️ ' + before | ||
} | ||
|
||
buttons[currentPageFixed] = String(currentPageFixed) | ||
|
||
if (currentPageFixed < totalPagesFixed) { | ||
buttons[after] = '▶️ ' + after | ||
|
||
if (after < totalPagesFixed) { | ||
buttons[totalPagesFixed] = '⏩ ' + totalPagesFixed | ||
} | ||
} | ||
|
||
return buttons | ||
} | ||
|
||
module.exports = { | ||
paginationOptions | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import test from 'ava' | ||
import {paginationOptions} from './pagination' | ||
|
||
function keysCorrectMacro(t, totalPages, currentPage, expectedArr) { | ||
const result = paginationOptions(totalPages, currentPage) | ||
const keys = Object.keys(result).map(o => Number(o)) | ||
t.deepEqual(keys, expectedArr) | ||
} | ||
|
||
test('two pages on first page', keysCorrectMacro, 2, 1, [1, 2]) | ||
test('two pages on second page', keysCorrectMacro, 2, 1, [1, 2]) | ||
test('five pages on first page', keysCorrectMacro, 5, 1, [1, 2, 5]) | ||
test('five pages on second page', keysCorrectMacro, 5, 2, [1, 2, 3, 5]) | ||
test('five pages on third page', keysCorrectMacro, 5, 3, [1, 2, 3, 4, 5]) | ||
test('five pages on fourth page', keysCorrectMacro, 5, 4, [1, 3, 4, 5]) | ||
test('five pages on fifth page', keysCorrectMacro, 5, 5, [1, 4, 5]) | ||
test('go big', keysCorrectMacro, 200, 100, [1, 99, 100, 101, 200]) | ||
test('one page is ommited', keysCorrectMacro, 1, 1, []) | ||
test('NaN pages is ommited', keysCorrectMacro, NaN, 1, []) | ||
test('currentPage NaN is ommited', keysCorrectMacro, 5, NaN, []) | ||
test('currentPage greater than totalPages is max page', keysCorrectMacro, 10, 15, [1, 9, 10]) | ||
|
||
// When there are 19 items / 2 per page there are... 9.5 pages -> 10 | ||
test('when totalPages is float use ceil', keysCorrectMacro, 9.5, 10, [1, 9, 10]) | ||
|
||
test('five pages all buttons', t => { | ||
const result = paginationOptions(5, 3) | ||
t.deepEqual(result, { | ||
1: '⏪ 1', | ||
2: '◀️ 2', | ||
3: '3', | ||
4: '▶️ 4', | ||
5: '⏩ 5' | ||
}) | ||
}) | ||
|
||
test('three pages are with +/-1 buttons and not first/last buttons', t => { | ||
const result = paginationOptions(3, 2) | ||
t.deepEqual(result, { | ||
1: '◀️ 1', | ||
2: '2', | ||
3: '▶️ 3' | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import test from 'ava' | ||
import Telegraf from 'telegraf' | ||
|
||
import TelegrafInlineMenu from '../inline-menu' | ||
import {emojiTrue, emojiFalse} from '../prefix' | ||
|
||
test('creates menu', async t => { | ||
const menu = new TelegrafInlineMenu('foo') | ||
menu.pagination('c', { | ||
getCurrentPage: () => 1, | ||
getTotalPages: () => 2 | ||
}) | ||
|
||
const bot = new Telegraf() | ||
bot.use(menu.init({actionCode: 'a'})) | ||
|
||
bot.context.answerCbQuery = () => Promise.resolve() | ||
bot.context.editMessageText = (text, extra) => { | ||
t.deepEqual(extra.reply_markup.inline_keyboard, [[ | ||
{ | ||
text: '1', | ||
callback_data: 'a:c-1' | ||
}, { | ||
text: '▶️ 2', | ||
callback_data: 'a:c-2' | ||
} | ||
]]) | ||
return Promise.resolve() | ||
} | ||
|
||
await bot.handleUpdate({callback_query: {data: 'a'}}) | ||
}) | ||
|
||
test('no pagination with 1 page', async t => { | ||
const menu = new TelegrafInlineMenu('foo') | ||
menu.pagination('c', { | ||
getCurrentPage: () => 1, | ||
getTotalPages: () => 1 | ||
}) | ||
|
||
const bot = new Telegraf() | ||
bot.use(menu.init({actionCode: 'a'})) | ||
|
||
bot.context.answerCbQuery = () => Promise.resolve() | ||
bot.context.editMessageText = (text, extra) => { | ||
t.falsy(extra.reply_markup.inline_keyboard) | ||
return Promise.resolve() | ||
} | ||
|
||
await bot.handleUpdate({callback_query: {data: 'a'}}) | ||
}) | ||
|
||
test('creates menu with async methods', async t => { | ||
const menu = new TelegrafInlineMenu('foo') | ||
menu.pagination('c', { | ||
getCurrentPage: () => Promise.resolve(1), | ||
getTotalPages: () => Promise.resolve(2) | ||
}) | ||
|
||
const bot = new Telegraf() | ||
bot.use(menu.init({actionCode: 'a'})) | ||
|
||
bot.context.answerCbQuery = () => Promise.resolve() | ||
bot.context.editMessageText = (text, extra) => { | ||
t.deepEqual(extra.reply_markup.inline_keyboard, [[ | ||
{ | ||
text: '1', | ||
callback_data: 'a:c-1' | ||
}, { | ||
text: '▶️ 2', | ||
callback_data: 'a:c-2' | ||
} | ||
]]) | ||
return Promise.resolve() | ||
} | ||
|
||
await bot.handleUpdate({callback_query: {data: 'a'}}) | ||
}) | ||
|
||
test('sets page', async t => { | ||
t.plan(1) | ||
const menu = new TelegrafInlineMenu('foo') | ||
menu.pagination('c', { | ||
setPage: (ctx, page) => Promise.resolve(t.is(page, 2)), | ||
getCurrentPage: () => 1, | ||
getTotalPages: () => 2 | ||
}) | ||
|
||
const bot = new Telegraf() | ||
bot.use(menu.init({actionCode: 'a'})) | ||
|
||
bot.context.answerCbQuery = () => Promise.resolve() | ||
bot.context.editMessageText = () => Promise.resolve() | ||
|
||
await bot.handleUpdate({callback_query: {data: 'a:c-2'}}) | ||
}) | ||
|
||
test('sets page not outside of range', async t => { | ||
t.plan(2) | ||
const menu = new TelegrafInlineMenu('foo') | ||
menu.pagination('c', { | ||
setPage: (ctx, page) => Promise.resolve(t.true(page >= 1 && page <= 2)), | ||
getCurrentPage: () => 1, | ||
getTotalPages: () => 2 | ||
}) | ||
|
||
const bot = new Telegraf() | ||
bot.use(menu.init({actionCode: 'a'})) | ||
|
||
bot.context.answerCbQuery = () => Promise.resolve() | ||
bot.context.editMessageText = () => Promise.resolve() | ||
|
||
await bot.handleUpdate({callback_query: {data: 'a:c-0'}}) | ||
await bot.handleUpdate({callback_query: {data: 'a:c-3'}}) | ||
}) | ||
|
||
test('sets page 1 when input is bad', async t => { | ||
t.plan(1) | ||
const menu = new TelegrafInlineMenu('foo') | ||
menu.pagination('c', { | ||
setPage: (ctx, page) => Promise.resolve(t.is(page, 1)), | ||
getCurrentPage: () => 'foo', | ||
getTotalPages: () => 'bar' | ||
}) | ||
|
||
const bot = new Telegraf() | ||
bot.use(menu.init({actionCode: 'a'})) | ||
|
||
bot.context.answerCbQuery = () => Promise.resolve() | ||
bot.context.editMessageText = () => Promise.resolve() | ||
|
||
await bot.handleUpdate({callback_query: {data: 'a:c-5'}}) | ||
}) | ||
|
||
test('require additionalArgs', t => { | ||
const menu = new TelegrafInlineMenu('foo') | ||
t.throws(() => { | ||
menu.pagination('c') | ||
}, /Cannot.+undefined/) | ||
}) |