Add test for IndexedDB

This commit is contained in:
Jerko Steiner 2019-12-02 22:29:42 -03:00
parent 951fbf52c7
commit d0f14f83f9
9 changed files with 229 additions and 0 deletions

View File

@ -0,0 +1 @@
require('fake-indexeddb/auto')

138
package-lock.json generated
View File

@ -2279,6 +2279,43 @@
"@types/yargs": "^12.0.9"
}
},
"@trust/keyto": {
"version": "0.3.7",
"resolved": "https://registry.npmjs.org/@trust/keyto/-/keyto-0.3.7.tgz",
"integrity": "sha512-t5kWWCTkPgg24JWVuCTPMx7l13F7YHdxBeJkT1vmoHjROgiOIEAN8eeY+iRmP1Hwsx+S7U55HyuqSsECr08a8A==",
"dev": true,
"requires": {
"asn1.js": "^5.0.1",
"base64url": "^3.0.1",
"elliptic": "^6.4.1"
},
"dependencies": {
"asn1.js": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.2.0.tgz",
"integrity": "sha512-Q7hnYGGNYbcmGrCPulXfkEw7oW7qjWeM4ZTALmgpuIcZLxyqqKYWxCZg2UBm8bklrnB4m2mGyJPWfoktdORD8A==",
"dev": true,
"requires": {
"bn.js": "^4.0.0",
"inherits": "^2.0.1",
"minimalistic-assert": "^1.0.0"
}
}
}
},
"@trust/webcrypto": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/@trust/webcrypto/-/webcrypto-0.9.2.tgz",
"integrity": "sha512-5iMAVcGYKhqLJGjefB1nzuQSqUJTru0nG4CytpBT/GGp1Piz/MVnj2jORdYf4JBYzggCIa8WZUr2rchP2Ngn/w==",
"dev": true,
"requires": {
"@trust/keyto": "^0.3.4",
"base64url": "^3.0.0",
"elliptic": "^6.4.0",
"node-rsa": "^0.4.0",
"text-encoding": "^0.6.1"
}
},
"@types/babel__core": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.2.tgz",
@ -3843,6 +3880,12 @@
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
"integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg="
},
"base64-arraybuffer-es6": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/base64-arraybuffer-es6/-/base64-arraybuffer-es6-0.5.0.tgz",
"integrity": "sha512-UCIPaDJrNNj5jG2ZL+nzJ7czvZV/ZYX6LaIRgfVU1k1edJOQg7dkbiSKzwHkNp6aHEHER/PhlFBrMYnlvJJQEw==",
"dev": true
},
"base64-js": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
@ -3854,6 +3897,12 @@
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
},
"base64url": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
"integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==",
"dev": true
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@ -6109,6 +6158,16 @@
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
"dev": true
},
"fake-indexeddb": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fake-indexeddb/-/fake-indexeddb-3.0.0.tgz",
"integrity": "sha512-VrnV9dJWlVWvd8hp9MMR+JS4RLC4ZmToSkuCg91ZwpYE5mSODb3n5VEaV62Hf3AusnbrPfwQhukU+rGZm5W8PQ==",
"dev": true,
"requires": {
"realistic-structured-clone": "^2.0.1",
"setimmediate": "^1.0.5"
}
},
"fast-deep-equal": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
@ -9922,6 +9981,23 @@
}
}
},
"node-rsa": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-0.4.2.tgz",
"integrity": "sha1-1jkXKewWqDDtWjgEKzFX0tXXJTA=",
"dev": true,
"requires": {
"asn1": "0.2.3"
},
"dependencies": {
"asn1": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
"dev": true
}
}
},
"node-sass": {
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.0.tgz",
@ -11279,6 +11355,26 @@
}
}
},
"realistic-structured-clone": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/realistic-structured-clone/-/realistic-structured-clone-2.0.2.tgz",
"integrity": "sha512-5IEvyfuMJ4tjQOuKKTFNvd+H9GSbE87IcendSBannE28PTrbolgaVg5DdEApRKhtze794iXqVUFKV60GLCNKEg==",
"dev": true,
"requires": {
"core-js": "^2.5.3",
"domexception": "^1.0.1",
"typeson": "^5.8.2",
"typeson-registry": "^1.0.0-alpha.20"
},
"dependencies": {
"core-js": {
"version": "2.6.10",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz",
"integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==",
"dev": true
}
}
},
"realpath-native": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz",
@ -11843,6 +11939,12 @@
}
}
},
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
"dev": true
},
"setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
@ -12774,6 +12876,12 @@
}
}
},
"text-encoding": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz",
"integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=",
"dev": true
},
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@ -13134,6 +13242,36 @@
"integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==",
"dev": true
},
"typeson": {
"version": "5.13.0",
"resolved": "https://registry.npmjs.org/typeson/-/typeson-5.13.0.tgz",
"integrity": "sha512-xcSaSt+hY/VcRYcqZuVkJwMjDXXJb4CZd51qDocpYw8waA314ygyOPlKhsGsw4qKuJ0tfLLUrxccrm+xvyS0AQ==",
"dev": true
},
"typeson-registry": {
"version": "1.0.0-alpha.29",
"resolved": "https://registry.npmjs.org/typeson-registry/-/typeson-registry-1.0.0-alpha.29.tgz",
"integrity": "sha512-DqRoIx0CtmBGXuumFk7ex5QE6JCWHNKry6D1psGUUB9uIPRrj/SCtuRAidZjLgieWpwn1EfrTFtG0IN2t//F8A==",
"dev": true,
"requires": {
"base64-arraybuffer-es6": "0.5.0",
"typeson": "5.13.0",
"whatwg-url": "7.0.0"
},
"dependencies": {
"whatwg-url": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz",
"integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==",
"dev": true,
"requires": {
"lodash.sortby": "^4.7.0",
"tr46": "^1.0.1",
"webidl-conversions": "^4.0.2"
}
}
}
},
"uglify-js": {
"version": "3.6.9",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.9.tgz",

View File

@ -61,6 +61,7 @@
"@babel/core": "^7.7.2",
"@babel/polyfill": "^7.7.0",
"@babel/preset-env": "^7.7.1",
"@trust/webcrypto": "^0.9.2",
"@types/classnames": "^2.2.9",
"@types/debug": "^4.1.5",
"@types/ejs": "^2.6.3",
@ -91,6 +92,7 @@
"eslint": "^6.6.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-react": "^7.16.0",
"fake-indexeddb": "^3.0.0",
"jest": "^24.9.0",
"loose-envify": "^1.4.0",
"node-sass": "^4.13.0",

View File

View File

@ -0,0 +1,46 @@
import { open, promisify } from './index'
describe('db', () => {
const TEST_DB = 'TEST_DB'
async function getError(promise: Promise<unknown>): Promise<Error> {
let error: Error
try {
await promise
} catch (err) {
error = err
}
expect(error!).toBeTruthy()
return error!
}
afterEach(async () => {
db && db.close()
await promisify(window.indexedDB.deleteDatabase(TEST_DB))
})
let db: IDBDatabase
describe('open', () => {
it('can use a custom upgrade function', async () => {
let called = false
db = await open(TEST_DB, 1, ev => {
called = true
})
expect(called).toBe(true)
})
it('opens a new database and upgrades it', async () => {
db = await open(TEST_DB, 1)
const tx = db.transaction('identities', 'readwrite')
const store = tx.objectStore('identities')
await promisify(store.put({id: 'test'}))
const value = await promisify(store.get('test'))
expect(value).toEqual({id: 'test'})
await promisify(tx)
})
})
})

2
src/client/db/index.ts Normal file
View File

@ -0,0 +1,2 @@
export { promisify } from './promisify'
export { open } from './open'

12
src/client/db/open.ts Normal file
View File

@ -0,0 +1,12 @@
import { promisify } from './promisify'
import { Upgrade, upgrade } from './upgrade'
export async function open(
name: string,
version: number,
doUpgrade: Upgrade = upgrade,
) {
const request = window.indexedDB.open(name, version)
request.onupgradeneeded = doUpgrade
return promisify(request)
}

View File

@ -0,0 +1,16 @@
export async function promisify(request: IDBTransaction): Promise<void>
export async function promisify<T>(request: IDBRequest<T>): Promise<T>
export async function promisify<T>(request: IDBRequest<T> | IDBTransaction) {
if ('oncomplete' in request) {
// this is a transaction
return new Promise<void>((resolve, reject) => {
request.oncomplete = () => resolve()
request.onerror = err => reject(err)
})
}
// this is an IDBRequest
return new Promise<T>((resolve, reject) => {
request.onsuccess = () => resolve(request.result)
request.onerror = err => reject(err)
})
}

12
src/client/db/upgrade.ts Normal file
View File

@ -0,0 +1,12 @@
export type Upgrade =
(this: IDBOpenDBRequest, event: IDBVersionChangeEvent) => void
export function upgrade(this: IDBOpenDBRequest, event: IDBVersionChangeEvent) {
const db = this.result
switch (event.oldVersion) {
case 0:
db.createObjectStore('identities', {
keyPath: 'id',
})
}
}