fix: fix getEmojiByShortcode, add tests
This commit is contained in:
parent
4904e85bd2
commit
44d4398d24
|
@ -1,6 +1,5 @@
|
|||
module.exports = {
|
||||
testMatch: [
|
||||
'<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}',
|
||||
'<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}'
|
||||
],
|
||||
transform: {
|
||||
|
|
|
@ -10,7 +10,7 @@ import { versionsAndTestEmoji } from './bin/versionsAndTestEmoji'
|
|||
const dev = process.env.NODE_ENV !== 'production'
|
||||
const svelte = dev ? hotSvelte : mainSvelte
|
||||
|
||||
// Build Database.js and Picker.js as separate modules at build times so that they are properly tree-shakeable.
|
||||
// Build Database.test.js and Picker.js as separate modules at build times so that they are properly tree-shakeable.
|
||||
// Most of this has to happen because customElements.define() has side effects
|
||||
const baseConfig = {
|
||||
plugins: [
|
||||
|
@ -44,7 +44,7 @@ const entryPoints = [
|
|||
output: './picker.js'
|
||||
},
|
||||
{
|
||||
input: './src/database/Database.js',
|
||||
input: './src/database/Database.test.js',
|
||||
output: './database.js'
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,80 +1,15 @@
|
|||
import Database from '../Database'
|
||||
import allEmoji from 'emojibase-data/en/data.json'
|
||||
import { pick } from 'lodash-es'
|
||||
import frEmoji from 'emojibase-data/fr/data.json'
|
||||
import {
|
||||
basicAfterEach, basicBeforeEach, ALL_EMOJI, ALL_EMOJI_MISCONFIGURED_ETAG,
|
||||
ALL_EMOJI_NO_ETAG, truncatedEmoji, truncateEmoji
|
||||
} from './shared'
|
||||
|
||||
const { Response } = fetch
|
||||
|
||||
function truncateEmoji (allEmoji) {
|
||||
// just take the first few emoji from each category, or else it takes forever to insert
|
||||
// into fake-indexeddb: https://github.com/dumbmatter/fakeIndexedDB/issues/44
|
||||
const groupsToEmojis = new Map()
|
||||
for (const emoji of allEmoji) {
|
||||
let emojis = groupsToEmojis.get(emoji.group)
|
||||
if (!emojis) {
|
||||
emojis = []
|
||||
groupsToEmojis.set(emoji.group, emojis)
|
||||
}
|
||||
if (emojis.length < 20) {
|
||||
emojis.push(emoji)
|
||||
}
|
||||
}
|
||||
return [...groupsToEmojis.values()].flat()
|
||||
}
|
||||
|
||||
const truncatedEmoji = truncateEmoji(allEmoji)
|
||||
|
||||
const ALL_EMOJI = 'http://localhost/emoji.json'
|
||||
const ALL_EMOJI_NO_ETAG = 'http://localhost/emoji-no-etag.json'
|
||||
const ALL_EMOJI_MISCONFIGURED_ETAG = 'http://localhost/emoji-misconfigured-etag.json'
|
||||
|
||||
beforeEach(() => {
|
||||
fetch
|
||||
.get(ALL_EMOJI, () => new Response(JSON.stringify(truncatedEmoji), {
|
||||
headers: { ETag: 'W/xxx' }
|
||||
}))
|
||||
.head(ALL_EMOJI, () => new Response(null, {
|
||||
headers: { ETag: 'W/xxx' }
|
||||
}))
|
||||
.get(ALL_EMOJI_NO_ETAG, truncatedEmoji)
|
||||
.head(ALL_EMOJI_NO_ETAG, () => new Response(null))
|
||||
.get(ALL_EMOJI_MISCONFIGURED_ETAG, () => new Response(JSON.stringify(truncatedEmoji), {
|
||||
headers: { ETag: 'W/xxx' }
|
||||
}))
|
||||
.head(ALL_EMOJI_MISCONFIGURED_ETAG, () => new Response(null))
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
fetch.mockClear()
|
||||
fetch.reset()
|
||||
})
|
||||
|
||||
describe('fetch tests', () => {
|
||||
test('make sure fetch-mock-jest is working correctly', async () => {
|
||||
expect(fetch).toHaveBeenCalledTimes(0)
|
||||
const resp = await fetch(ALL_EMOJI)
|
||||
expect(resp.headers.get('etag')).toBe('W/xxx')
|
||||
expect(await (resp).json()).toStrictEqual(truncatedEmoji)
|
||||
expect(fetch).toHaveBeenCalledTimes(1)
|
||||
expect(fetch).toHaveBeenLastCalledWith(ALL_EMOJI, undefined)
|
||||
})
|
||||
|
||||
test('make sure fetch-mock-jest is working correctly 2', async () => {
|
||||
expect(fetch).toHaveBeenCalledTimes(0)
|
||||
const resp = await fetch(ALL_EMOJI_NO_ETAG)
|
||||
expect(resp.headers.get('etag')).toBeFalsy()
|
||||
expect(await (resp).json()).toStrictEqual(truncatedEmoji)
|
||||
expect(fetch).toHaveBeenCalledTimes(1)
|
||||
expect(fetch).toHaveBeenLastCalledWith(ALL_EMOJI_NO_ETAG, undefined)
|
||||
})
|
||||
|
||||
test('make sure fetch-mock-jest is working correctly 3', async () => {
|
||||
expect(fetch).toHaveBeenCalledTimes(0)
|
||||
const resp = await fetch(ALL_EMOJI, { method: 'HEAD' })
|
||||
expect(resp.headers.get('etag')).toBe('W/xxx')
|
||||
expect(fetch).toHaveBeenCalledTimes(1)
|
||||
expect(fetch).toHaveBeenLastCalledWith(ALL_EMOJI, { method: 'HEAD' })
|
||||
})
|
||||
})
|
||||
beforeEach(basicBeforeEach)
|
||||
afterEach(basicAfterEach)
|
||||
|
||||
describe('database tests', () => {
|
||||
test('basic emoji database test', async () => {
|
||||
|
@ -248,64 +183,57 @@ describe('database tests', () => {
|
|||
await db.delete()
|
||||
})
|
||||
|
||||
test('getEmojiBySearchQuery', async () => {
|
||||
const db = new Database({ dataSource: ALL_EMOJI })
|
||||
test('URL change causes an update', async () => {
|
||||
const dataSource = 'http://localhost/will-change.json'
|
||||
const dataSource2 = 'http://localhost/will-change2.json'
|
||||
|
||||
// first time - data is v1
|
||||
fetch.get(dataSource, () => new Response(JSON.stringify(truncatedEmoji), { headers: { ETag: 'W/xxx' } }))
|
||||
fetch.head(dataSource, () => new Response(null, { headers: { ETag: 'W/xxx' } }))
|
||||
|
||||
let db = new Database({ dataSource })
|
||||
await db.ready()
|
||||
const search = async query => (await db.getEmojiBySearchQuery(query)).map(_ => pick(_, ['annotation', 'order']))
|
||||
expect(await search('face')).toStrictEqual([
|
||||
{ annotation: 'grinning face', order: 1 },
|
||||
{ annotation: 'grinning face with big eyes', order: 2 },
|
||||
{ annotation: 'grinning face with smiling eyes', order: 3 },
|
||||
{ annotation: 'beaming face with smiling eyes', order: 4 },
|
||||
{ annotation: 'grinning squinting face', order: 5 },
|
||||
{ annotation: 'grinning face with sweat', order: 6 },
|
||||
{ annotation: 'rolling on the floor laughing', order: 7 },
|
||||
{ annotation: 'face with tears of joy', order: 8 },
|
||||
{ annotation: 'slightly smiling face', order: 9 },
|
||||
{ annotation: 'upside-down face', order: 10 },
|
||||
{ annotation: 'winking face', order: 11 },
|
||||
{ annotation: 'smiling face with smiling eyes', order: 12 },
|
||||
{ annotation: 'smiling face with halo', order: 13 },
|
||||
{ annotation: 'smiling face with hearts', order: 14 },
|
||||
{ annotation: 'smiling face with heart-eyes', order: 15 },
|
||||
{ annotation: 'star-struck', order: 16 },
|
||||
{ annotation: 'face blowing a kiss', order: 17 },
|
||||
{ annotation: 'kissing face', order: 18 },
|
||||
{ annotation: 'smiling face', order: 20 },
|
||||
{ annotation: 'kissing face with closed eyes', order: 21 },
|
||||
{ annotation: 'monkey face', order: 2657 },
|
||||
{ annotation: 'dog face', order: 2661 },
|
||||
{ annotation: 'wolf', order: 2666 },
|
||||
{ annotation: 'fox', order: 2667 },
|
||||
{ annotation: 'cat face', order: 2669 },
|
||||
{ annotation: 'lion', order: 2672 },
|
||||
{ annotation: 'tiger face', order: 2673 },
|
||||
{ annotation: 'horse face', order: 2676 }
|
||||
])
|
||||
expect(await search('monk')).toStrictEqual([
|
||||
{ annotation: 'monkey face', order: 2657 },
|
||||
{ annotation: 'monkey', order: 2658 }
|
||||
])
|
||||
expect(await search('monkey')).toStrictEqual([
|
||||
{ annotation: 'monkey face', order: 2657 },
|
||||
{ annotation: 'monkey', order: 2658 }
|
||||
])
|
||||
expect(await search('monkey')).toStrictEqual([
|
||||
{ annotation: 'monkey face', order: 2657 },
|
||||
{ annotation: 'monkey', order: 2658 }
|
||||
])
|
||||
expect(await search('MoNkEy')).toStrictEqual([
|
||||
{ annotation: 'monkey face', order: 2657 },
|
||||
{ annotation: 'monkey', order: 2658 }
|
||||
])
|
||||
expect(await search('monkey fac')).toStrictEqual([
|
||||
{ annotation: 'monkey face', order: 2657 }
|
||||
])
|
||||
expect(await search('face monk')).toStrictEqual([
|
||||
{ annotation: 'monkey face', order: 2657 }
|
||||
])
|
||||
expect(await search('monkey facee')).toStrictEqual([])
|
||||
expect(await search('monk face')).toStrictEqual([])
|
||||
expect(fetch).toHaveBeenCalledTimes(1)
|
||||
expect(fetch).toHaveBeenLastCalledWith(dataSource, undefined)
|
||||
|
||||
expect((await db.getEmojiByShortcode('rofl')).annotation).toBe('rolling on the floor laughing')
|
||||
expect(await db.getEmojiByShortcode('weary_cat')).toBeFalsy()
|
||||
|
||||
await db.close()
|
||||
|
||||
const changedEmoji = JSON.parse(JSON.stringify(truncatedEmoji))
|
||||
const roflIndex = allEmoji.findIndex(_ => _.annotation === 'rolling on the floor laughing')
|
||||
changedEmoji[roflIndex] = allEmoji.find(_ => _.annotation === 'pineapple') // replace rofl
|
||||
|
||||
// second time - update, data is v2
|
||||
fetch.mockClear()
|
||||
fetch.reset()
|
||||
fetch.get(dataSource2, () => new Response(JSON.stringify(changedEmoji), { headers: { ETag: 'W/yyy' } }))
|
||||
fetch.head(dataSource2, () => new Response(null, { headers: { ETag: 'W/yyy' } }))
|
||||
|
||||
db = new Database({ dataSource: dataSource2 })
|
||||
await db.ready()
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
expect(fetch).toHaveBeenCalledTimes(2)
|
||||
expect(fetch).toHaveBeenLastCalledWith(dataSource2, undefined)
|
||||
expect(fetch).toHaveBeenNthCalledWith(1, dataSource2, { method: 'HEAD' })
|
||||
expect((await db.getEmojiByShortcode('rofl'))).toBeFalsy()
|
||||
expect((await db.getEmojiByShortcode('pineapple')).annotation).toBe('pineapple')
|
||||
|
||||
// third time - no update, data is v2
|
||||
fetch.mockClear()
|
||||
fetch.reset()
|
||||
fetch.get(dataSource2, () => new Response(JSON.stringify(changedEmoji), { headers: { ETag: 'W/yyy' } }))
|
||||
fetch.head(dataSource2, () => new Response(null, { headers: { ETag: 'W/yyy' } }))
|
||||
|
||||
db = new Database({ dataSource: dataSource2 })
|
||||
await db.ready()
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
expect(fetch).toHaveBeenCalledTimes(1)
|
||||
expect(fetch).toHaveBeenLastCalledWith(dataSource2, { method: 'HEAD' })
|
||||
expect((await db.getEmojiByShortcode('rofl'))).toBeFalsy()
|
||||
expect((await db.getEmojiByShortcode('pineapple')).annotation).toBe('pineapple')
|
||||
|
||||
await db.delete()
|
||||
})
|
||||
|
||||
|
@ -342,8 +270,46 @@ describe('database tests', () => {
|
|||
await db.delete()
|
||||
})
|
||||
|
||||
// test - race conditions opening two DBs with same name at same time ?
|
||||
// test - URL changed
|
||||
// test - are shortcodes unique?
|
||||
// test - separate languages
|
||||
test('multiple databases, close one', async () => {
|
||||
const db1 = new Database({ dataSource: ALL_EMOJI })
|
||||
const db2 = new Database({ dataSource: ALL_EMOJI })
|
||||
await db1.close()
|
||||
await expect(() => db1.getEmojiByGroup(1)).rejects.toThrow()
|
||||
await expect(() => db2.getEmojiByGroup(1)).rejects.toThrow()
|
||||
const db3 = new Database({ dataSource: ALL_EMOJI })
|
||||
await db3.ready()
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
await db3.delete()
|
||||
})
|
||||
|
||||
test('multiple databases, delete one', async () => {
|
||||
const db1 = new Database({ dataSource: ALL_EMOJI })
|
||||
const db2 = new Database({ dataSource: ALL_EMOJI })
|
||||
await db1.delete()
|
||||
await expect(() => db1.getEmojiByGroup(1)).rejects.toThrow()
|
||||
await expect(() => db2.getEmojiByGroup(1)).rejects.toThrow()
|
||||
})
|
||||
|
||||
test('multiple databases in multiple locales', async () => {
|
||||
const truncatedFrEmoji = truncateEmoji(frEmoji)
|
||||
const dataSourceFr = 'http://localhost/fr.json'
|
||||
|
||||
fetch.get(dataSourceFr, () => new Response(JSON.stringify(truncatedFrEmoji), { headers: { ETag: 'W/zzz' } }))
|
||||
fetch.head(dataSourceFr, () => new Response(null, { headers: { ETag: 'W/zzz' } }))
|
||||
|
||||
const en = new Database({ dataSource: ALL_EMOJI })
|
||||
const fr = new Database({ dataSource: dataSourceFr, locale: 'fr' })
|
||||
|
||||
expect((await en.getEmojiBySearchQuery('monkey face')).map(_ => _.annotation)).toStrictEqual(['monkey face'])
|
||||
expect((await fr.getEmojiBySearchQuery('tête singe')).map(_ => _.annotation)).toStrictEqual(['tête de singe'])
|
||||
|
||||
await en.delete()
|
||||
|
||||
// deleting en has no impact on fr
|
||||
await expect(() => en.getEmojiBySearchQuery('monkey face')).rejects.toThrow()
|
||||
expect((await fr.getEmojiBySearchQuery('tête singe')).map(_ => _.annotation)).toStrictEqual(['tête de singe'])
|
||||
|
||||
await en.delete()
|
||||
await fr.delete()
|
||||
})
|
||||
})
|
|
@ -0,0 +1,32 @@
|
|||
import { ALL_EMOJI, ALL_EMOJI_NO_ETAG, basicAfterEach, basicBeforeEach, truncatedEmoji } from './shared'
|
||||
|
||||
beforeEach(basicBeforeEach)
|
||||
afterEach(basicAfterEach)
|
||||
|
||||
describe('basic fetch tests', () => {
|
||||
test('make sure fetch-mock-jest is working correctly', async () => {
|
||||
expect(fetch).toHaveBeenCalledTimes(0)
|
||||
const resp = await fetch(ALL_EMOJI)
|
||||
expect(resp.headers.get('etag')).toBe('W/xxx')
|
||||
expect(await (resp).json()).toStrictEqual(truncatedEmoji)
|
||||
expect(fetch).toHaveBeenCalledTimes(1)
|
||||
expect(fetch).toHaveBeenLastCalledWith(ALL_EMOJI, undefined)
|
||||
})
|
||||
|
||||
test('make sure fetch-mock-jest is working correctly 2', async () => {
|
||||
expect(fetch).toHaveBeenCalledTimes(0)
|
||||
const resp = await fetch(ALL_EMOJI_NO_ETAG)
|
||||
expect(resp.headers.get('etag')).toBeFalsy()
|
||||
expect(await (resp).json()).toStrictEqual(truncatedEmoji)
|
||||
expect(fetch).toHaveBeenCalledTimes(1)
|
||||
expect(fetch).toHaveBeenLastCalledWith(ALL_EMOJI_NO_ETAG, undefined)
|
||||
})
|
||||
|
||||
test('make sure fetch-mock-jest is working correctly 3', async () => {
|
||||
expect(fetch).toHaveBeenCalledTimes(0)
|
||||
const resp = await fetch(ALL_EMOJI, { method: 'HEAD' })
|
||||
expect(resp.headers.get('etag')).toBe('W/xxx')
|
||||
expect(fetch).toHaveBeenCalledTimes(1)
|
||||
expect(fetch).toHaveBeenLastCalledWith(ALL_EMOJI, { method: 'HEAD' })
|
||||
})
|
||||
})
|
|
@ -0,0 +1,69 @@
|
|||
import Database from '../Database'
|
||||
import { pick } from 'lodash-es'
|
||||
import { basicAfterEach, basicBeforeEach, ALL_EMOJI } from './shared'
|
||||
|
||||
beforeEach(basicBeforeEach)
|
||||
afterEach(basicAfterEach)
|
||||
|
||||
describe('getEmojiBySearchQuery', () => {
|
||||
test('basic searches', async () => {
|
||||
const db = new Database({ dataSource: ALL_EMOJI })
|
||||
await db.ready()
|
||||
const search = async query => (await db.getEmojiBySearchQuery(query)).map(_ => pick(_, ['annotation', 'order']))
|
||||
expect(await search('face')).toStrictEqual([
|
||||
{ annotation: 'grinning face', order: 1 },
|
||||
{ annotation: 'grinning face with big eyes', order: 2 },
|
||||
{ annotation: 'grinning face with smiling eyes', order: 3 },
|
||||
{ annotation: 'beaming face with smiling eyes', order: 4 },
|
||||
{ annotation: 'grinning squinting face', order: 5 },
|
||||
{ annotation: 'grinning face with sweat', order: 6 },
|
||||
{ annotation: 'rolling on the floor laughing', order: 7 },
|
||||
{ annotation: 'face with tears of joy', order: 8 },
|
||||
{ annotation: 'slightly smiling face', order: 9 },
|
||||
{ annotation: 'upside-down face', order: 10 },
|
||||
{ annotation: 'winking face', order: 11 },
|
||||
{ annotation: 'smiling face with smiling eyes', order: 12 },
|
||||
{ annotation: 'smiling face with halo', order: 13 },
|
||||
{ annotation: 'smiling face with hearts', order: 14 },
|
||||
{ annotation: 'smiling face with heart-eyes', order: 15 },
|
||||
{ annotation: 'star-struck', order: 16 },
|
||||
{ annotation: 'face blowing a kiss', order: 17 },
|
||||
{ annotation: 'kissing face', order: 18 },
|
||||
{ annotation: 'smiling face', order: 20 },
|
||||
{ annotation: 'kissing face with closed eyes', order: 21 },
|
||||
{ annotation: 'monkey face', order: 2657 },
|
||||
{ annotation: 'dog face', order: 2661 },
|
||||
{ annotation: 'wolf', order: 2666 },
|
||||
{ annotation: 'fox', order: 2667 },
|
||||
{ annotation: 'cat face', order: 2669 },
|
||||
{ annotation: 'lion', order: 2672 },
|
||||
{ annotation: 'tiger face', order: 2673 },
|
||||
{ annotation: 'horse face', order: 2676 }
|
||||
])
|
||||
expect(await search('monk')).toStrictEqual([
|
||||
{ annotation: 'monkey face', order: 2657 },
|
||||
{ annotation: 'monkey', order: 2658 }
|
||||
])
|
||||
expect(await search('monkey')).toStrictEqual([
|
||||
{ annotation: 'monkey face', order: 2657 },
|
||||
{ annotation: 'monkey', order: 2658 }
|
||||
])
|
||||
expect(await search('monkey')).toStrictEqual([
|
||||
{ annotation: 'monkey face', order: 2657 },
|
||||
{ annotation: 'monkey', order: 2658 }
|
||||
])
|
||||
expect(await search('MoNkEy')).toStrictEqual([
|
||||
{ annotation: 'monkey face', order: 2657 },
|
||||
{ annotation: 'monkey', order: 2658 }
|
||||
])
|
||||
expect(await search('monkey fac')).toStrictEqual([
|
||||
{ annotation: 'monkey face', order: 2657 }
|
||||
])
|
||||
expect(await search('face monk')).toStrictEqual([
|
||||
{ annotation: 'monkey face', order: 2657 }
|
||||
])
|
||||
expect(await search('monkey facee')).toStrictEqual([])
|
||||
expect(await search('monk face')).toStrictEqual([])
|
||||
await db.delete()
|
||||
})
|
||||
})
|
|
@ -0,0 +1,20 @@
|
|||
import { ALL_EMOJI, basicAfterEach, basicBeforeEach } from './shared'
|
||||
import Database from '../Database'
|
||||
|
||||
beforeEach(basicBeforeEach)
|
||||
afterEach(basicAfterEach)
|
||||
|
||||
describe('getEmojiByShortcode', () => {
|
||||
test('basic test', async () => {
|
||||
const db = new Database({ dataSource: ALL_EMOJI })
|
||||
expect((await db.getEmojiByShortcode('monkey')).annotation).toEqual('monkey')
|
||||
expect((await db.getEmojiByShortcode('monkey_face')).annotation).toEqual('monkey face')
|
||||
expect((await db.getEmojiByShortcode('MONKEY')).annotation).toEqual('monkey')
|
||||
expect((await db.getEmojiByShortcode('MONKEY_FACE')).annotation).toEqual('monkey face')
|
||||
|
||||
expect((await db.getEmojiByShortcode('face monkey'))).toBe(null)
|
||||
expect((await db.getEmojiByShortcode('monk'))).toBe(null)
|
||||
expect((await db.getEmojiByShortcode(':monkey_face:'))).toBe(null)
|
||||
await db.delete()
|
||||
})
|
||||
})
|
|
@ -0,0 +1,47 @@
|
|||
import allEmoji from 'emojibase-data/en/data.json'
|
||||
|
||||
const { Response } = fetch
|
||||
|
||||
export function truncateEmoji (allEmoji) {
|
||||
// just take the first few emoji from each category, or else it takes forever to insert
|
||||
// into fake-indexeddb: https://github.com/dumbmatter/fakeIndexedDB/issues/44
|
||||
const groupsToEmojis = new Map()
|
||||
for (const emoji of allEmoji) {
|
||||
let emojis = groupsToEmojis.get(emoji.group)
|
||||
if (!emojis) {
|
||||
emojis = []
|
||||
groupsToEmojis.set(emoji.group, emojis)
|
||||
}
|
||||
if (emojis.length < 20) {
|
||||
emojis.push(emoji)
|
||||
}
|
||||
}
|
||||
return [...groupsToEmojis.values()].flat()
|
||||
}
|
||||
|
||||
export const truncatedEmoji = truncateEmoji(allEmoji)
|
||||
|
||||
export const ALL_EMOJI = 'http://localhost/emoji.json'
|
||||
export const ALL_EMOJI_NO_ETAG = 'http://localhost/emoji-no-etag.json'
|
||||
export const ALL_EMOJI_MISCONFIGURED_ETAG = 'http://localhost/emoji-misconfigured-etag.json'
|
||||
|
||||
export function basicBeforeEach () {
|
||||
fetch
|
||||
.get(ALL_EMOJI, () => new Response(JSON.stringify(truncatedEmoji), {
|
||||
headers: { ETag: 'W/xxx' }
|
||||
}))
|
||||
.head(ALL_EMOJI, () => new Response(null, {
|
||||
headers: { ETag: 'W/xxx' }
|
||||
}))
|
||||
.get(ALL_EMOJI_NO_ETAG, truncatedEmoji)
|
||||
.head(ALL_EMOJI_NO_ETAG, () => new Response(null))
|
||||
.get(ALL_EMOJI_MISCONFIGURED_ETAG, () => new Response(JSON.stringify(truncatedEmoji), {
|
||||
headers: { ETag: 'W/xxx' }
|
||||
}))
|
||||
.head(ALL_EMOJI_MISCONFIGURED_ETAG, () => new Response(null))
|
||||
}
|
||||
|
||||
export function basicAfterEach () {
|
||||
fetch.mockClear()
|
||||
fetch.reset()
|
||||
}
|
|
@ -126,16 +126,11 @@ export async function getEmojiBySearchQuery (db, query) {
|
|||
}
|
||||
|
||||
export async function getEmojiByShortcode (db, shortcode) {
|
||||
shortcode = shortcode.toLowerCase()
|
||||
return dbPromise(db, STORE_EMOJI, MODE_READONLY, (emojiStore, cb) => {
|
||||
const range = IDBKeyRange.only(shortcode)
|
||||
emojiStore.index(INDEX_TOKENS).getAll(range).onsuccess = e => {
|
||||
// of course, we could add an extra index just for shortcodes, but it seems
|
||||
// simpler to just re-use the existing tokens index and filter in-memory
|
||||
const results = e.target.result.filter(emoji => emoji.shortcodes.includes(shortcode))
|
||||
cb(results[0])
|
||||
}
|
||||
})
|
||||
const emojis = await getEmojiBySearchQuery(db, shortcode)
|
||||
return emojis.filter(_ => {
|
||||
const lowerShortcodes = _.shortcodes.map(_ => _.toLowerCase())
|
||||
return lowerShortcodes.includes(shortcode.toLowerCase())
|
||||
})[0] || null
|
||||
}
|
||||
|
||||
export async function getEmojiByUnicode (db, unicode) {
|
||||
|
|
|
@ -7,8 +7,8 @@ export function transformEmojiBaseData (emojiBaseData) {
|
|||
const res = emojiBaseData.map(({ annotation, emoticon, group, order, shortcodes, tags, emoji, version }) => {
|
||||
const tokens = [...new Set(
|
||||
[
|
||||
...shortcodes.map(extractTokens).flat(),
|
||||
...tags.map(extractTokens).flat(),
|
||||
...(shortcodes || []).map(extractTokens).flat(),
|
||||
...(tags || []).map(extractTokens).flat(),
|
||||
...extractTokens(annotation),
|
||||
emoticon
|
||||
]
|
||||
|
|
|
@ -46,6 +46,10 @@ export default class Database {
|
|||
|
||||
/**
|
||||
* Return a single emoji matching the shortcode, or null if not found.
|
||||
*
|
||||
* The colons around the shortcode should not be included when querying, e.g.
|
||||
* use "slight_smile", not ":slight_smile:". Uppercase versus lowercase
|
||||
* does not matter.
|
||||
* @param shortcode
|
||||
*/
|
||||
getEmojiByShortcode(shortcode: string): Promise<Emoji | null> {
|
||||
|
|
Loading…
Reference in New Issue