-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add chrome.storage api mocks for storybook use (#141)
- Loading branch information
Showing
1 changed file
with
138 additions
and
16 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,146 @@ | ||
import type { Preview } from '@storybook/react'; | ||
import ExtensionRoot from '@views/components/common/ExtensionRoot/ExtensionRoot'; | ||
import React from 'react'; | ||
import ExtensionRoot from 'src/views/components/common/ExtensionRoot/ExtensionRoot'; | ||
|
||
const preview: Preview = { | ||
parameters: { | ||
actions: { argTypesRegex: '^on[A-Z].*' }, | ||
controls: { | ||
matchers: { | ||
color: /(background|color)$/i, | ||
date: /Date$/i, | ||
}, | ||
parameters: { | ||
actions: { argTypesRegex: '^on[A-Z].*' }, | ||
controls: { | ||
matchers: { | ||
color: /(background|color)$/i, | ||
date: /Date$/i, | ||
}, | ||
}, | ||
}, | ||
}, | ||
decorators: [ | ||
Story => ( | ||
<ExtensionRoot> | ||
<Story /> | ||
</ExtensionRoot> | ||
), | ||
], | ||
decorators: [ | ||
Story => ( | ||
<React.StrictMode> | ||
<ExtensionRoot> | ||
<Story /> | ||
</ExtensionRoot> | ||
</React.StrictMode> | ||
), | ||
], | ||
}; | ||
|
||
let localData = {}; | ||
type ListenerFunction = ( | ||
changes: { [key: string]: chrome.storage.StorageChange }, | ||
areaName: chrome.storage.AreaName | ||
) => void; | ||
const localDataListeners = new Map< | ||
ListenerFunction, // key to remove listener | ||
(changes: { [key: string]: chrome.storage.StorageChange }) => void | ||
>(); | ||
|
||
// mock chrome api | ||
globalThis.chrome = { | ||
storage: { | ||
local: { | ||
/** | ||
* Removes all items from storage. | ||
* @param callback Optional. | ||
* Callback on success, or on failure (in which case runtime.lastError will be set). | ||
*/ | ||
async clear() { | ||
localData = {}; | ||
}, | ||
/** | ||
* Gets one or more items from storage. | ||
* @param keys A single key to get, list of keys to get, or a dictionary specifying default values. | ||
* An empty list or object will return an empty result object. Pass in null to get the entire contents of storage. | ||
* @return A Promise that resolves with an object containing items | ||
*/ | ||
async get(keys?: string | string[] | { [key: string]: any } | null) { | ||
if (keys === null) { | ||
return localData; | ||
} | ||
if (Array.isArray(keys)) { | ||
return keys.reduce((acc, key) => { | ||
acc[key] = localData[key]; | ||
return acc; | ||
}, {} as string); // funny types | ||
} | ||
if (typeof keys === 'string') { | ||
return { [keys]: localData[keys] }; | ||
} | ||
return keys; | ||
}, | ||
/** | ||
* Gets the amount of space (in bytes) being used by one or more items. | ||
* @param keys Optional. A single key or list of keys to get the total usage for. An empty list will return 0. Pass in null to get the total usage of all of storage. | ||
* @param callback Callback with the amount of space being used by storage, or on failure (in which case runtime.lastError will be set). | ||
* Parameter bytesInUse: Amount of space being used in storage, in bytes. | ||
*/ | ||
async getBytesInUse() { | ||
return 0; | ||
}, | ||
/** | ||
* Removes one or more items from storage. | ||
* @param keys A single key or a list of keys for items to remove. | ||
* @param callback Optional. | ||
* Callback on success, or on failure (in which case runtime.lastError will be set). | ||
*/ | ||
async remove(keys: string | string[]) { | ||
if (Array.isArray(keys)) { | ||
keys.forEach(key => { | ||
for (const listener of localDataListeners.values()) { | ||
listener({ [key]: { oldValue: localData[key], newValue: undefined } }); | ||
} | ||
|
||
delete localData[key]; | ||
}); | ||
} else { | ||
for (const listener of localDataListeners.values()) { | ||
listener({ [keys]: { oldValue: localData[keys], newValue: undefined } }); | ||
} | ||
|
||
delete localData[keys]; | ||
} | ||
}, | ||
/** | ||
* Sets multiple items. | ||
* @param items An object which gives each key/value pair to update storage with. Any other key/value pairs in storage will not be affected. | ||
* Primitive values such as numbers will serialize as expected. Values with a typeof "object" and "function" will typically serialize to {}, with the exception of Array (serializes as expected), Date, and Regex (serialize using their String representation). | ||
* @param callback Optional. | ||
* Callback on success, or on failure (in which case runtime.lastError will be set). | ||
*/ | ||
async set(items: { [key: string]: any }) { | ||
for (const key in items) { | ||
const oldValue = localData[key]; | ||
localData[key] = JSON.parse(JSON.stringify(items[key])); | ||
|
||
for (const listener of localDataListeners.values()) { | ||
listener({ [key]: { oldValue: oldValue, newValue: localData[key] } }); | ||
} | ||
} | ||
}, | ||
}, | ||
onChanged: { | ||
/** | ||
* Registers an event listener callback to an event. | ||
* @param callback Called when an event occurs. The parameters of this function depend on the type of event. | ||
*/ | ||
addListener( | ||
listener: ( | ||
changes: { [key: string]: chrome.storage.StorageChange }, | ||
areaName: chrome.storage.AreaName | ||
) => void | ||
) { | ||
localDataListeners.set(listener, (changes: { [key: string]: chrome.storage.StorageChange }) => { | ||
listener(changes, 'local'); | ||
}); | ||
}, | ||
|
||
/** | ||
* Deregisters an event listener callback from an event. | ||
* @param callback Listener that shall be unregistered. | ||
*/ | ||
removeListener(listener: ListenerFunction) { | ||
localDataListeners.delete(listener); | ||
}, | ||
}, | ||
}, | ||
} as typeof chrome; | ||
|
||
export default preview; |