From 918cee251495cbb02180b779ee74f8f68ea6c35e Mon Sep 17 00:00:00 2001 From: Jonathan Ho Date: Mon, 6 Mar 2023 14:48:16 -0800 Subject: [PATCH] test(utils): increase coverage (part 1) (#2795) * close test(utils): more test for Collection.ts #2793 * fix: after each not defined * close test(utils): more test for base64.ts #2796 * close test(utils): more test for casing.ts #2797 * test(utils): remove dev code * close #2799 * fix #2800 * close #2823 * test(utils): fix site move * close #2826 * refactor(utils): remove redundant if * close #2827 * close #2828 --- packages/utils/src/bucket.ts | 2 +- packages/utils/src/casing.ts | 5 +- packages/utils/src/images.ts | 4 +- packages/utils/tests/base64.spec.ts | 13 + packages/utils/tests/casting.spec.ts | 44 +++- packages/utils/tests/collection.spec.ts | 298 ++++++++++++++--------- packages/utils/tests/images.spec.ts | 175 +++++++++++++ packages/utils/tests/token.spec.ts | 2 +- packages/utils/tests/typeguards.spec.ts | 61 +++++ packages/utils/tests/urlToBase64.spec.ts | 2 +- packages/utils/tests/utils.spec.ts | 42 ++-- 11 files changed, 511 insertions(+), 137 deletions(-) create mode 100644 packages/utils/tests/images.spec.ts create mode 100644 packages/utils/tests/typeguards.spec.ts diff --git a/packages/utils/src/bucket.ts b/packages/utils/src/bucket.ts index b9dde3c9c..3326805b0 100644 --- a/packages/utils/src/bucket.ts +++ b/packages/utils/src/bucket.ts @@ -107,7 +107,7 @@ export function nextRefill(bucket: LeakyBucket): number { // Since this bucket is lazy update the tokens before calculating the next refill. updateTokens(bucket) - return performance.now() - bucket.lastRefill + bucket.refillInterval + return bucket.refillInterval - performance.now() + bucket.lastRefill } export async function acquire(bucket: LeakyBucket, amount: number, highPriority = false): Promise { diff --git a/packages/utils/src/casing.ts b/packages/utils/src/casing.ts index 6ae619c82..46b6bfddd 100644 --- a/packages/utils/src/casing.ts +++ b/packages/utils/src/casing.ts @@ -9,7 +9,7 @@ export function camelize (object: T): Camelize { const obj = {} as Camelize ;(Object.keys(object) as Array).forEach((key) => { // @ts-expect-error js hack - ;(obj[typeof key === 'string' ? snakeToCamelCase(key) : key] as Camelize<(T & object)[keyof T]>) = camelize(object[key]) + ;(obj[snakeToCamelCase(key)] as Camelize<(T & object)[keyof T]>) = camelize(object[key]) }) return obj } @@ -25,8 +25,7 @@ export function snakelize (object: T): Snakelize { const obj = {} as Snakelize ;(Object.keys(object) as Array).forEach((key) => { // @ts-expect-error js hack - - ;(obj[typeof key === 'string' ? camelToSnakeCase(key) : key] as Snakelize<(T & object)[keyof T]>) = snakelize(object[key]) + ;(obj[camelToSnakeCase(key)] as Snakelize<(T & object)[keyof T]>) = snakelize(object[key]) }) return obj } diff --git a/packages/utils/src/images.ts b/packages/utils/src/images.ts index 6ecc7854c..18fec0e7d 100644 --- a/packages/utils/src/images.ts +++ b/packages/utils/src/images.ts @@ -37,7 +37,7 @@ export function avatarUrl( ): string { return options?.avatar ? formatImageUrl( - `https://cdn.discordapp.com/avatars/${userId}/${typeof options?.avatar === 'string' ? options.avatar : iconBigintToHash(options?.avatar)}`, + `https://cdn.discordapp.com/avatars/${userId}/${typeof options.avatar === 'string' ? options.avatar : iconBigintToHash(options.avatar)}`, options?.size ?? 128, options?.format, ) @@ -125,7 +125,7 @@ export function guildSplashUrl( * @returns The link to the resource. */ export function getWidgetImageUrl(guildId: BigString, options?: GetGuildWidgetImageQuery): string { - let url = `https://cdn.discordapp.com/guilds/${guildId}/widget.png` + let url = `https://discordapp.com/api/guilds/${guildId}/widget.png` if (options?.style) { url += `?style=${options.style}` diff --git a/packages/utils/tests/base64.spec.ts b/packages/utils/tests/base64.spec.ts index d5aa67f0d..42e75f591 100644 --- a/packages/utils/tests/base64.spec.ts +++ b/packages/utils/tests/base64.spec.ts @@ -10,15 +10,28 @@ describe('base64.ts', () => { }) it('can encode Uint8Array to base64', () => { expect(encode(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173, 162]))).to.be.equal('TWFuINCB8KStog==') + expect(encode(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173]))).to.be.equal('TWFuINCB8KSt') + expect(encode(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173, 162, 63]))).to.be.equal('TWFuINCB8KStoj8=') }) it('can encode Buffer to base64', () => { expect(encode(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173, 162]))).to.be.equal('TWFuINCB8KStog==') + expect(encode(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173]))).to.be.equal('TWFuINCB8KSt') + expect(encode(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173, 162, 63]))).to.be.equal('TWFuINCB8KStoj8=') }) }) describe('decode', () => { it('can dencode string to Uint8Array', () => { expect(new TextDecoder().decode(decode('TWFuINCB8KStog=='))).to.be.equal('Man Ё𤭢') + expect(new TextDecoder().decode(decode('TWFuINCB8KSt'))).to.be.equal('Man Ё\ufffd') + expect(new TextDecoder().decode(decode('TWFuINCB8KStoj8='))).to.be.equal('Man Ё𤭢?') + }) + + it('will throw an error with invalid string', () => { + expect(() => decode('=adw')).to.throw('Unable to parse base64 string.') + expect(() => decode('a')).to.throw('Unable to parse base64 string.') + expect(() => decode('$avs')).to.throw('Unable to parse base64 string.') + expect(() => decode('~daw')).to.throw('Unable to parse base64 string.') }) }) diff --git a/packages/utils/tests/casting.spec.ts b/packages/utils/tests/casting.spec.ts index ae4c085eb..fe137e5c1 100644 --- a/packages/utils/tests/casting.spec.ts +++ b/packages/utils/tests/casting.spec.ts @@ -1,6 +1,6 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { camelize, snakeToCamelCase } from '../src/casing.js' +import { camelize, snakelize, snakeToCamelCase } from '../src/casing.js' describe('casting.ts', () => { describe('camelize function', () => { @@ -44,4 +44,46 @@ describe('casting.ts', () => { }) }) }) + + describe('snakelize function', () => { + it('will convert snake case object to camel case object', () => { + expect( + snakelize({ + testAxByCz: 'dummy_dx_ey_fz', + testgxhyiz: 'dummyjxkylz', + 32: 'adw_dw', + }), + ).to.deep.equal({ + test_ax_by_cz: 'dummy_dx_ey_fz', + testgxhyiz: 'dummyjxkylz', + 32: 'adw_dw', + }) + }) + + it('will convert array of snake case object to camel case object', () => { + expect( + snakelize([ + { + testAxByCz: 'dummy_dx_ey_fz', + }, + { + testGxHyIz: 'dummy_jx_ky_lz', + }, + ]), + ).to.deep.equal([ + { + test_ax_by_cz: 'dummy_dx_ey_fz', + }, + { + test_gx_hy_iz: 'dummy_jx_ky_lz', + }, + ]) + }) + + describe('snakeToCamelCase function', () => { + it('will convert string snake case to camel case', () => { + expect(snakeToCamelCase('sd_sd')).to.equal('sdSd') + }) + }) + }) }) diff --git a/packages/utils/tests/collection.spec.ts b/packages/utils/tests/collection.spec.ts index 53f032597..85bf0ff67 100644 --- a/packages/utils/tests/collection.spec.ts +++ b/packages/utils/tests/collection.spec.ts @@ -1,142 +1,220 @@ import { expect } from 'chai' -import { beforeEach, describe, it } from 'mocha' +import { afterEach, beforeEach, describe, it } from 'mocha' import sinon from 'sinon' import { Collection } from '../src/Collection.js' describe('collection.ts', () => { - let collection: Collection - - beforeEach(() => { - collection = new Collection() + afterEach(() => { + sinon.restore() }) - it('[collection] collection values to array', () => { - const testCollection = new Collection([ - ['best', 'tri'], - ['proficient', 'yui'], - ]) - expect(testCollection.array()).to.be.deep.equal(['tri', 'yui']) - }) + describe('Collection class', () => { + let collection: Collection - it('[collection] get a random value', () => { - const testCollection = new Collection([['best', 'tri']]) - - expect(testCollection.random() ?? '').to.be.oneOf(['best', 'tri']) - expect(collection.random()).to.be.undefined - }) - - describe('', () => { beforeEach(() => { - collection.set('best developer', 'triformine') + collection = new Collection([ + ['best', 'tri'], + ['proficient', 'yui'], + ]) }) - it('[collection] Set a value without maxSize', () => { - expect(collection.size).to.be.equal(1) - expect(collection.get('best developer')).to.be.equal('triformine') + + describe('.array() method', () => { + it('will return values as array', () => { + expect(collection.array()).to.be.deep.equal(['tri', 'yui']) + }) }) - describe('', () => { + + describe('.random() method', () => { + it('will get a random value', () => { + expect(collection.random() ?? '').to.be.oneOf(['tri', 'yui']) + expect(new Collection().random()).to.be.undefined + }) + }) + + describe('.set() method', () => { + describe('without maxSize', () => { + it('will set a value', () => { + collection.set('best developer', 'triformine') + + expect(collection.size).to.be.equal(3) + expect(collection.get('best developer')).to.be.equal('triformine') + }) + }) + + describe('with maxSize', () => { + const maxSize = 2 + + beforeEach(() => { + collection = new Collection([], { + maxSize, + }) + }) + + it('will set a value when not over max size', () => { + collection.set('foo', 'bar') + collection.set('me', 'you') + + expect(collection.size).to.be.equal(2) + }) + + it('will not set a value when over max size', () => { + collection.set('foo', 'bar') + collection.set('me', 'you') + expect(collection.size).to.be.equal(2) + + collection.set('this', 'not') + expect(collection.size).to.be.equal(2) + }) + }) + }) + + describe('.forceSet() method', () => { + const maxSize = 2 + beforeEach(() => { - collection.set('deno', 'yes') - }) - it('[collection] get the value of the first element', () => { - expect(collection.first()).to.be.equal('triformine') + collection = new Collection( + [ + ['foo', 'bar'], + ['me', 'you'], + ], + { maxSize }, + ) }) - it('[collection] get the value of the last element', () => { - expect(collection.last()).to.be.equal('yes') + it('will ignore maxSize and set a value ', () => { + collection.forceSet('this', 'not') + + expect(collection.size).to.be.equal(3) }) }) - }) - describe('[collection] Create a collection with maxSize', () => { - const maxSize = 2 - - const maxCollection = new Collection([], { - maxSize, - }) - - expect(maxCollection).to.exist - expect(maxCollection.maxSize).to.exist - expect(maxCollection.maxSize).to.be.equal(maxSize) - - describe('[collection] Test if maxSize works properly', () => { - maxCollection.set('foo', 'bar') - maxCollection.set('me', 'you') - - expect(maxCollection.size).to.be.equal(2) - - maxCollection.set('this', 'not') - - expect(maxCollection.size).to.be.equal(2) - - it('[collection] Test if forceSet ignore maxSize', () => { - maxCollection.forceSet('this', 'not') - - expect(maxCollection.size).to.be.equal(3) + describe('.first() method', () => { + it('will get the value of the first element', () => { + expect(collection.first()).to.be.equal('tri') }) }) - }) - const testCollection = new Collection([ - ['a', 1], - ['b', 2], - ['c', 3], - ]) + describe('.last() method', () => { + it('get the value of the last element', () => { + expect(collection.last()).to.be.equal('yui') + }) + }) - it('[collection] find by key or value', () => { - expect(testCollection.find((v, k) => v === 2)).to.be.equal(2) - expect(testCollection.find((v, k) => k === 'b')).to.be.equal(2) - }) + const testCollection = new Collection([ + ['a', 1], + ['b', 2], + ['c', 3], + ]) - it('[collection] filter by key or value', () => { - expect(testCollection.filter((v, k) => v === 3).size).to.be.equal(1) - expect(testCollection.filter((v, k) => k === 'd').size).to.be.equal(0) - }) + describe('.find() method', () => { + it('will find value by value', () => { + expect(collection.find((v, k) => v === 'tri')).to.be.equal('tri') + expect(collection.find((v, k) => v === 'skillz')).to.be.undefined + }) - it('[collection] map', () => { - expect(testCollection.map((k, v) => `${v}${k}`)).to.be.deep.equal(['a1', 'b2', 'c3']) - }) + it('will find value by key', () => { + expect(collection.find((v, k) => k === 'proficient')).to.be.equal('yui') + expect(collection.find((v, k) => k === 'skillz')).to.be.undefined + }) + }) - it('[collection] some', () => { - expect(testCollection.some((v, _) => v === 1)).to.be.equal(true) - expect(testCollection.some((v, _) => v === 4)).to.be.equal(false) - }) + describe('.filter() method', () => { + it('will filter by key', () => { + expect(collection.filter((v, k) => v === 'yui').array()).to.deep.equal(['yui']) + expect(collection.filter((v, k) => v === 'skillz').array()).to.deep.equal([]) + }) + it('will filter by key', () => { + expect(collection.filter((v, k) => k === 'best').array()).to.deep.equal(['tri']) + expect(collection.filter((v, k) => k === 'skillz').array()).to.deep.equal([]) + }) + }) - it('[collection] every', () => { - expect(testCollection.every((v, _) => v !== 0)).to.be.equal(true) - expect(testCollection.every((v, _) => v === 1)).to.be.equal(false) - }) + it('map', () => { + expect(testCollection.map((k, v) => `${v}${k}`)).to.be.deep.equal(['a1', 'b2', 'c3']) + }) - it('[collection] reduce', () => { - expect(testCollection.reduce((acc, val) => acc + val, 0)).to.be.equal(6) - }) + it('some', () => { + expect(testCollection.some((v, _) => v === 1)).to.be.equal(true) + expect(testCollection.some((v, _) => v === 4)).to.be.equal(false) + }) - it('[collection] start sweeper', async () => { - const clock = sinon.useFakeTimers() - const sweeperCollection = new Collection( - [ - ['a', 1], - ['b', 2], - ], - { - sweeper: { - filter: (v, _) => v === 1, - interval: 50, - }, - }, - ) + it('every', () => { + expect(testCollection.every((v, _) => v !== 0)).to.be.equal(true) + expect(testCollection.every((v, _) => v === 1)).to.be.equal(false) + }) - try { - await clock.tickAsync(49) - expect(sweeperCollection.size).to.be.equal(2) - await clock.tickAsync(1) - expect(sweeperCollection.size).to.be.equal(1) - } catch (err) { - sweeperCollection.stopSweeper() + it('reduce', () => { + expect(testCollection.reduce((acc, val) => acc + val, 0)).to.be.equal(6) + }) - throw err - } + describe('sweeper', () => { + let clock: sinon.SinonFakeTimers - sweeperCollection.stopSweeper() - clock.restore() + beforeEach(() => { + clock = sinon.useFakeTimers() + }) + + afterEach(() => { + clock.restore() + }) + + it('start sweeper', async () => { + const sweeperCollection = new Collection( + [ + ['a', 1], + ['b', 2], + ], + { + sweeper: { + filter: (v, _) => v === 1, + interval: 50, + }, + }, + ) + + try { + await clock.tickAsync(49) + expect(sweeperCollection.size).to.be.equal(2) + await clock.tickAsync(1) + expect(sweeperCollection.size).to.be.equal(1) + } catch (err) { + sweeperCollection.stopSweeper() + + throw err + } + + sweeperCollection.stopSweeper() + }) + + describe('.changeSweeperInterval() method', () => { + it('will call startSweeper with new interval', () => { + collection.startSweeper({ filter: () => false, interval: 1000 }) + collection.changeSweeperInterval(20000) + expect(collection.sweeper?.interval).to.equal(20000) + }) + + it('will not startsweeper if not started', () => { + collection.changeSweeperInterval(20000) + expect(collection.sweeper).to.undefined + }) + }) + + describe('.changeSweeperFilter() method', () => { + it('will call startSweeper with new interval', () => { + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + const newFilter = () => true + collection.startSweeper({ filter: () => false, interval: 1000 }) + collection.changeSweeperFilter(newFilter) + expect(collection.sweeper?.filter).to.equal(newFilter) + }) + + it('will not startsweeper if not started', () => { + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + const newFilter = () => true + collection.changeSweeperFilter(newFilter) + expect(collection.sweeper).to.undefined + }) + }) + }) }) }) diff --git a/packages/utils/tests/images.spec.ts b/packages/utils/tests/images.spec.ts new file mode 100644 index 000000000..ea0bfb43c --- /dev/null +++ b/packages/utils/tests/images.spec.ts @@ -0,0 +1,175 @@ +import { expect } from 'chai' +import { describe, it } from 'mocha' +import { avatarUrl, emojiUrl, formatImageUrl, getWidgetImageUrl, guildBannerUrl, guildIconUrl, guildSplashUrl } from '../src/images.js' + +describe('images.ts', () => { + describe('formatImageUrl function', () => { + it('will return formated url with default size 128 and jpg', () => { + expect(formatImageUrl('https://skillz.is.pro/image')).to.be.equal('https://skillz.is.pro/image.jpg?size=128') + }) + + it('will return formated url with given size', () => { + expect(formatImageUrl('https://skillz.is.pro/image', 1024)).to.be.equal('https://skillz.is.pro/image.jpg?size=1024') + }) + + it('will return formated url with given size and format', () => { + expect(formatImageUrl('https://skillz.is.pro/image', 1024, 'gif')).to.be.equal('https://skillz.is.pro/image.gif?size=1024') + }) + + it('will return formated url with default size and format', () => { + expect(formatImageUrl('https://skillz.is.pro/image', undefined, 'gif')).to.be.equal('https://skillz.is.pro/image.gif?size=128') + }) + + describe('without format', () => { + it('will use gif if a_ is found', () => { + expect(formatImageUrl('https://cdn.discordapp.com/avatars/568505543511259840/a_482491d6dcf12e12746ccd3148f0c646')).to.be.equal( + 'https://cdn.discordapp.com/avatars/568505543511259840/a_482491d6dcf12e12746ccd3148f0c646.gif?size=128', + ) + }) + + it('will use jpg if no a_ is found', () => { + expect(formatImageUrl('https://cdn.discordapp.com/avatars/568505543511259840/482491d6dcf12e12746ccd3148f0c646')).to.be.equal( + 'https://cdn.discordapp.com/avatars/568505543511259840/482491d6dcf12e12746ccd3148f0c646.jpg?size=128', + ) + }) + }) + }) + + describe('emojiUrl function', () => { + it('can format emoji url with png as default ext', () => { + expect(emojiUrl('1079823706743918622')).to.equal('https://cdn.discordapp.com/emojis/1079823706743918622.png') + }) + + it('can format emoji url with gif as ext', () => { + expect(emojiUrl('1079584570661404724', true)).to.equal('https://cdn.discordapp.com/emojis/1079584570661404724.gif') + }) + }) + + describe('avatarUrl function', () => { + it('will return the url for given avatar icon hash', () => { + expect( + avatarUrl('207324334904049664', '9130', { + avatar: 'db26a6fb924c985f66b79364cf5797b7', + }), + ).to.equal('https://cdn.discordapp.com/avatars/207324334904049664/db26a6fb924c985f66b79364cf5797b7.jpg?size=128') + }) + + it('will return the url for given avatar icon bigint', () => { + expect( + avatarUrl('207324334904049664', '9130', { + avatar: 4034407661299384404326332419647968090039n, + }), + ).to.equal('https://cdn.discordapp.com/avatars/207324334904049664/db26a6fb924c985f66b79364cf5797b7.jpg?size=128') + }) + + it('will return the url for default avatar', () => { + expect( + avatarUrl('207324334904049664', '9130', { + avatar: undefined, + }), + ).to.equal('https://cdn.discordapp.com/embed/avatars/0.png') + }) + }) + + describe('guildBannerUrl function', () => { + it("will return the url for given guild's banner's icon hash", () => { + expect(guildBannerUrl('785384884197392384', { banner: '2fc0f64acd7a326e0c93c123db02eb1d' })).to.equal( + 'https://cdn.discordapp.com/banners/785384884197392384/2fc0f64acd7a326e0c93c123db02eb1d.jpg?size=128', + ) + }) + + it("will return the url for given guild's banner's icon big int", () => { + expect(guildBannerUrl('785384884197392384', { banner: 3806581668328291509506503737571885116189n })).to.equal( + 'https://cdn.discordapp.com/banners/785384884197392384/2fc0f64acd7a326e0c93c123db02eb1d.jpg?size=128', + ) + }) + + it("will return the url for given guild's banner with format", () => { + expect(guildBannerUrl('785384884197392384', { banner: '2fc0f64acd7a326e0c93c123db02eb1d', format: 'webp' })).to.equal( + 'https://cdn.discordapp.com/banners/785384884197392384/2fc0f64acd7a326e0c93c123db02eb1d.webp?size=128', + ) + }) + + it("will return the url for given guild's banner with size", () => { + expect(guildBannerUrl('785384884197392384', { banner: '2fc0f64acd7a326e0c93c123db02eb1d', size: 256 })).to.equal( + 'https://cdn.discordapp.com/banners/785384884197392384/2fc0f64acd7a326e0c93c123db02eb1d.jpg?size=256', + ) + }) + + it('will return undefined without given banner', () => { + expect(guildBannerUrl('785384884197392384', {})).to.equal(undefined) + }) + }) + + describe('guildIconUrl function', () => { + it("will return the url for given guild's icon's icon hash", () => { + expect(guildIconUrl('785384884197392384', '7cb67c989d54d824239b2bb4270955b1')).to.equal( + 'https://cdn.discordapp.com/icons/785384884197392384/7cb67c989d54d824239b2bb4270955b1.jpg?size=128', + ) + }) + + it("will return the url for given guild's icon's icon big int", () => { + expect(guildIconUrl('785384884197392384', 3908877832746069276949504774836813649329n)).to.equal( + 'https://cdn.discordapp.com/icons/785384884197392384/7cb67c989d54d824239b2bb4270955b1.jpg?size=128', + ) + }) + + it("will return the url for given guild's icon with format", () => { + expect(guildIconUrl('785384884197392384', '7cb67c989d54d824239b2bb4270955b1', { format: 'webp' })).to.equal( + 'https://cdn.discordapp.com/icons/785384884197392384/7cb67c989d54d824239b2bb4270955b1.webp?size=128', + ) + }) + + it("will return the url for given guild's icon with size", () => { + expect(guildIconUrl('785384884197392384', '7cb67c989d54d824239b2bb4270955b1', { size: 256 })).to.equal( + 'https://cdn.discordapp.com/icons/785384884197392384/7cb67c989d54d824239b2bb4270955b1.jpg?size=256', + ) + }) + + it('will return undefined without given icon', () => { + expect(guildIconUrl('785384884197392384', undefined)).to.equal(undefined) + }) + }) + + describe('guildSplashUrl function', () => { + it("will return the url for given guild's splash's icon big hash", () => { + expect(guildSplashUrl('785384884197392384', '207961ff6c41f119874e10efc602858c')).to.equal( + 'https://cdn.discordapp.com/splashes/785384884197392384/207961ff6c41f119874e10efc602858c.jpg?size=128', + ) + }) + + it("will return the url for given guild's splash's icon big int", () => { + expect(guildSplashUrl('785384884197392384', 3786271587545740215322752847582515594636n)).to.equal( + 'https://cdn.discordapp.com/splashes/785384884197392384/207961ff6c41f119874e10efc602858c.jpg?size=128', + ) + }) + + it("will return the url for given guild's splash with format", () => { + expect(guildSplashUrl('785384884197392384', '207961ff6c41f119874e10efc602858c', { format: 'webp' })).to.equal( + 'https://cdn.discordapp.com/splashes/785384884197392384/207961ff6c41f119874e10efc602858c.webp?size=128', + ) + }) + + it("will return the url for given guild's splash with size", () => { + expect(guildSplashUrl('785384884197392384', '207961ff6c41f119874e10efc602858c', { size: 2048 })).to.equal( + 'https://cdn.discordapp.com/splashes/785384884197392384/207961ff6c41f119874e10efc602858c.jpg?size=2048', + ) + }) + + it('will return undefined without given icon', () => { + expect(guildSplashUrl('785384884197392384', undefined)).to.equal(undefined) + }) + }) + + describe('getWidgetImageUrl function', () => { + it("will return the url for given guild's widget", () => { + expect(getWidgetImageUrl('785384884197392384')).to.equal('https://discordapp.com/api/guilds/785384884197392384/widget.png') + }) + + it("will return the url for given guild's widget with the style", () => { + expect(getWidgetImageUrl('785384884197392384', { style: 'banner2' })).to.equal( + 'https://discordapp.com/api/guilds/785384884197392384/widget.png?style=banner2', + ) + }) + }) +}) diff --git a/packages/utils/tests/token.spec.ts b/packages/utils/tests/token.spec.ts index 8f8f50bcc..6952da579 100644 --- a/packages/utils/tests/token.spec.ts +++ b/packages/utils/tests/token.spec.ts @@ -14,7 +14,7 @@ describe('token.ts', () => { }) it('Will throw when token is undefined.', () => { - expect(() => removeTokenPrefix(undefined)).to.throw + expect(() => removeTokenPrefix(undefined)).to.throw() }) }) diff --git a/packages/utils/tests/typeguards.spec.ts b/packages/utils/tests/typeguards.spec.ts new file mode 100644 index 000000000..eefb4d124 --- /dev/null +++ b/packages/utils/tests/typeguards.spec.ts @@ -0,0 +1,61 @@ +import { expect } from 'chai' +import { describe, it } from 'mocha' +import { isGetMessagesAfter, isGetMessagesAround, isGetMessagesBefore, isGetMessagesLimit } from '../src/typeguards.js' + +describe('typeguard.ts', () => { + describe('isGetMessagesAfter function', () => { + it('will return true if has after', () => { + expect( + isGetMessagesAfter({ + after: '684146387468463', + }), + ).equal(true) + }) + + it("will return false if don't has after", () => { + expect(isGetMessagesAfter({})).equal(false) + }) + }) + + describe('isGetMessagesBefore function', () => { + it('will return true if has after', () => { + expect( + isGetMessagesBefore({ + before: '684146387468463', + }), + ).equal(true) + }) + + it("will return false if don't has after", () => { + expect(isGetMessagesBefore({})).equal(false) + }) + }) + + describe('isGetMessagesAround function', () => { + it('will return true if has after', () => { + expect( + isGetMessagesAround({ + around: '684146387468463', + }), + ).equal(true) + }) + + it("will return false if don't has after", () => { + expect(isGetMessagesAround({})).equal(false) + }) + }) + + describe('isGetMessagesAfter function', () => { + it('will return true if has after', () => { + expect( + isGetMessagesLimit({ + limit: 54, + }), + ).equal(true) + }) + + it("will return false if don't has after", () => { + expect(isGetMessagesLimit({})).equal(false) + }) + }) +}) diff --git a/packages/utils/tests/urlToBase64.spec.ts b/packages/utils/tests/urlToBase64.spec.ts index a5603fd7b..854f0c297 100644 --- a/packages/utils/tests/urlToBase64.spec.ts +++ b/packages/utils/tests/urlToBase64.spec.ts @@ -5,7 +5,7 @@ import { urlToBase64 } from '../src/urlToBase64.js' describe('urlToBase64.ts', () => { describe('urlToBase64 function', () => { it('Will convert a png image to base64', async () => { - expect(await urlToBase64('https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png')).equal( + expect(await urlToBase64('https://raw.githubusercontent.com/discordeno/discordeno/main/website/static/img/logo.png')).equal( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAABgWlDQ1BzUkdCIElFQzYxOTY2LTIuMQAAKJF1kbtLA0EQhz/jE41E0MLC4hC1UokRgjYWEV+gFjGCr+ZyuSRCHsfdiYitYCsoiDa+Cv0LtBWsBUFRBLGysFa0UTnnkkCCmFlm59vf7gy7s+CJpLS0VeWHdMY2w2MhZW5+Qal9wYuPOmpoUDXLmJoZjVDWPu+pcONtj1ur/Ll/rSGmWxpU1AkPaYZpC48LT67ahss7wi1aUo0Jnwl3m3JB4TtXj+b51eVEnr9dNiPhYfA0CSuJEo6WsJY008LycjrSqRWtcB/3JV49MzsjsV28DYswY4RQmGCEYYL0MShzkB4C9MqKMvn+XP40WcnVZDZYw2SZBElsukVdkeq6xLjouowUa27///bVivcH8tW9Iah+dpz3Tqjdhp8tx/k6cpyfY6h8gstMMT97CAMfom8VtY4D8G3A+VVRi+7CxSa0PhqqqeakSnFPPA5vp9A4D803UL+Y71lhn5MHiKzLV13D3j50yXnf0i8CP2e4cpk0JAAAAjdQTFRFTFuRAwQGPUp1cojZBAUIYHS5BAQHUGCZDhEbVGWhHiM4LjdXHyY8BwkOZnvEP0t4JCxFQk9+BgcLRlSFKTFObYPRMTteSViMJi1IMz5iDQ8YUWGbKzRSRVOFW22uCAoPLDVVY3e+FBgmND5jFxwsTV2ULzhaU2SfGyAzMDlbV2mnHiU6XnCzEhYjIilBDRAaU2OeBQYKXXCyaoDLRlSGNT9lN0NqTl2VbILPRFGBLTZVZXrCNkFnCQsSCw0VGR4vMTtdDRAZJSxHaH3GOkVuGB0uOURtcIfXAQECWWuqCAkPQE17R1WIP0x5PElzVmekJi5JISg/S1qQLjdYHCI2SViLb4bVWmysZHi/TVyTBgcMR1aIT2CYFRkoboTSUmOdQ1GAMjxgboTRDA4WKjNQSFeKDxIdan/KGR8xcYjYSFaJW26uAQIDLjhZBwgNYXW6IypDAgIDZ3zFXnG0ZXnBBQYJLTZWVWaiJy9KERQgX3K1EBMfZnrDOkZvFxssAAAAAgMEKDBNHSM4RFKCMjxfN0JpEhUiX3K2IilCSlmOIypEQ1B/ExclHCE1O0dyconaT1+XYna8ISc+YHO3Yna7O0ZwSlmNOENra4DMPkp2PUl0HiQ5ICY9b4XUGBwtXG+wWGqpWGmobIHOXG6vNUBmCgwSFhoqFRopJCtEVmilGh8yGyE0UWKcQEx5NkFoT1+YYnW7KTJPOUVuS1qPZ3zGQU59cIbVCAoQJS1IaX7JTl6VWmyryUUmFNn9TgAAAL10Uk5T//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8Am0SEJgAAAAlwSFlzAAALEwAACxMBAJqcGAAAIABJREFUeJztnYmfFTW2x4FjC6g0oiyytLLIMIDoTCMjiiyDSqFsigjiE6QHASMiIjiA4FxoltYRPQiMwAhCA8JDcVzoBlH+uJeqJFVJKpWlbt3u8fN5P5buW1W3btX3nqROTk6SPrf/X97q09sXQFXzU29fZi/D8qT0X4Ost2CV4dTrxHoDVn2gehFYT8OqBlQvAetJWNWC6gVgPQarMaR6llfPwGokqR7k1QOwGk+qp3g1HFZPoeoJXI2F1ZOkeoBXI2H1PKoG42ocrLBb3NevT2fTnf/lvBoFK/T++iIg3mE/5q677xnUq7gaAiuUVCwkhPS1H7ITEe71PV8j7qsBsMqgqtVuEMD77IcMpMY31P+M1d9Z5bDKoarVZiLAQ/ZDrlFYb4acs+p7qxpWWVa1TZTEKPshoxFxTNhZq725amGVRlWr7QUgG+2H9KewxgaettLbqxJWaVCxxiGSI/ZDjlJYdwefuMIbrA5WSUhCTQDwsP2Q1fSBGQ6rQlyVwSpFSNJF6hf80X5IHwD8Q5lzV3WPFcEqcwuqplCz+cp+yHVAMq/c2au5y2pglbsDRdcorJfsh7xCnwEHy56/itusAlbZ61c0kcKabz9kA3XFRpb+gAputAJYpS9f0dsU1n77IY/TOmtCHR/R+7AKLmzQX57YFnQn62jj0OFxttAH5tNBJ9XU27CKrutBxDlBNzKYEJhsP+RJCus/QSfV1auwii/rGcQ1QfexgDakHRXSpxTWyaCT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', ) }) diff --git a/packages/utils/tests/utils.spec.ts b/packages/utils/tests/utils.spec.ts index 3fa2682ed..c278f3321 100644 --- a/packages/utils/tests/utils.spec.ts +++ b/packages/utils/tests/utils.spec.ts @@ -1,8 +1,7 @@ import { expect } from 'chai' import { afterEach, beforeEach, describe, it } from 'mocha' import sinon from 'sinon' -import { delay } from '../src/utils.js' -import { formatImageUrl } from '../src/images.js' +import { delay, hasProperty } from '../src/utils.js' describe('utils.ts', () => { let clock: sinon.SinonFakeTimers @@ -16,22 +15,29 @@ describe('utils.ts', () => { clock.restore() }) - it('will', async () => { - let delayEnded = false - delay(31).then(() => { - delayEnded = true + describe('delay function', () => { + it('will delay/sleep for given time', async () => { + let delayEnded = false + delay(31).then(() => { + delayEnded = true + }) + expect(delayEnded).to.be.false + await clock.tickAsync(30) + expect(delayEnded).to.be.false + await clock.tickAsync(31) + expect(delayEnded).to.be.true + }) + }) + + describe('hasProperty funciton', async () => { + const obj = { prop: 'lts372005' } + + it('will return true if it does have property', () => { + expect(hasProperty(obj, 'prop')).equal(true) + }) + + it('will return false if it does not have property', () => { + expect(hasProperty(obj, 'lts372005')).equal(false) }) - expect(delayEnded).to.be.false - await clock.tickAsync(30) - expect(delayEnded).to.be.false - await clock.tickAsync(31) - expect(delayEnded).to.be.true }) }) - -it('[utils] format image url', () => { - expect(formatImageUrl('https://skillz.is.pro')).to.be.equal('https://skillz.is.pro.jpg?size=128') - expect(formatImageUrl('https://skillz.is.pro', 1024)).to.be.equal('https://skillz.is.pro.jpg?size=1024') - expect(formatImageUrl('https://skillz.is.pro', 1024, 'gif')).to.be.equal('https://skillz.is.pro.gif?size=1024') - expect(formatImageUrl('https://skillz.is.pro', undefined, 'gif')).to.be.equal('https://skillz.is.pro.gif?size=128') -})