From f5a65ecef41cac7350b6377637025d412a715e2c Mon Sep 17 00:00:00 2001 From: Patrick Browne Date: Thu, 6 Feb 2020 13:10:28 +0100 Subject: [PATCH] feat: Expose only 1 method to initialize flags --- packages/cozy-flags/src/flag.js | 50 ++++++++++++++++-- packages/cozy-flags/src/tests.js | 91 ++++++++++++++++++-------------- 2 files changed, 96 insertions(+), 45 deletions(-) diff --git a/packages/cozy-flags/src/flag.js b/packages/cozy-flags/src/flag.js index c4810069a6..a4dd1ad01c 100644 --- a/packages/cozy-flags/src/flag.js +++ b/packages/cozy-flags/src/flag.js @@ -51,6 +51,13 @@ export const enable = flagsToEnable => { } } +/** + * Initializes flags from the remote endpoint serving instance flags + * + * @private + * @see https://docs.cozy.io/en/cozy-stack/settings/#get-settingsflags + * @param {CozyClient} client + */ export const initializeFromRemote = async client => { const { data: { attributes } @@ -59,6 +66,9 @@ export const initializeFromRemote = async client => { } export const getTemplateData = attr => { + if (typeof document === 'undefined') { + return null + } const allDataNode = document.querySelector('[data-cozy]') const attrNode = document.querySelector(`[data-${attr}]`) try { @@ -77,14 +87,43 @@ export const getTemplateData = attr => { } } -export const initializeFromDOM = client => { +/** + * Initialize from the template data injected by cozy-stack into the DOM + * + * @private + * @see https://docs.cozy.io/en/cozy-stack/client-app-dev/#good-practices-for-your-application + * + * @returns {Boolean} - False is DOM initialization could not be completed, true otherwise + */ +export const initializeFromDOM = async () => { const domData = getTemplateData('flags') if (!domData) { - console.warn('no dom daa') - return + return false } - for (const [flagName, flagValue] of Object.entries(domData)) { - flag(flagName, flagValue) + enable(domData) + return true +} + +/** + * Initialize flags from DOM if possible, otherwise from remote endpoint + * + * @example + * + * Flags can be taken from the flags injected by the stack + * ``` + *
+ * + * // not recommended but possible + *
+ * ```` + * + * @param {CozyClient} client - A CozyClient + * @return {Promise} Resolves when flags have been initialized + */ +export const initialize = async client => { + const domRes = await initializeFromDOM() + if (domRes == false) { + await initializeFromRemote(client) } } @@ -94,5 +133,6 @@ flag.reset = resetFlags flag.enable = enable flag.initializeFromRemote = initializeFromRemote flag.initializeFromDOM = initializeFromDOM +flag.initialize = initialize export default flag diff --git a/packages/cozy-flags/src/tests.js b/packages/cozy-flags/src/tests.js index cd67528960..bdc6d84093 100644 --- a/packages/cozy-flags/src/tests.js +++ b/packages/cozy-flags/src/tests.js @@ -56,52 +56,63 @@ export default function testFlagAPI(flag) { }) }) - if (typeof document !== 'undefined') { - describe('initializeFromDOM', () => { - it('should initialize from DOM', async () => { - const body = document.body - const div = document.createElement('div') - div.dataset.cozy = JSON.stringify({ - flags: { - has_feature1: true, - has_feature2: false, - number_of_foos: 10, - bar_config: { qux: 'quux' } - } - }) - body.appendChild(div) + describe('initialization', () => { + const remoteFlags = { + has_feature1: true, + has_feature2: false, + number_of_foos: 10, + bar_config: { qux: 'quux' }, + from_remote: true + } + const flagRemoteResponse = { + data: { + type: 'io.cozy.settings', + id: 'io.cozy.settings.flags', + attributes: remoteFlags, + links: { + self: '/settings/flags' + } + } + } - await flag.initializeFromDOM() - expect(flag('has_feature1')).toBe(true) - expect(flag('has_feature2')).toBe(false) - expect(flag('number_of_foos')).toBe(10) - expect(flag('bar_config')).toEqual({ qux: 'quux' }) - }) - }) - } + const domFlags = { + has_feature1: true, + has_feature2: false, + number_of_foos: 10, + bar_config: { qux: 'quux' }, + from_remote: false + } - describe('initializeFromRemote', () => { - it('should initialize from the remote stack', async () => { + const setup = () => { const client = new CozyClient({}) - const flagResponseFixture = { - data: { - type: 'io.cozy.settings', - id: 'io.cozy.settings.flags', - attributes: { - has_feature1: true, - has_feature2: false, - number_of_foos: 10, - bar_config: { qux: 'quux' } - }, - links: { - self: '/settings/flags' - } + client.stackClient.fetchJSON = jest.fn(() => flagRemoteResponse) + return { client } + } + + if (typeof document !== 'undefined') { + it('should initialize from DOM', async () => { + let div + try { + div = document.createElement('div') + div.dataset.cozy = JSON.stringify({ flags: domFlags }) + document.body.appendChild(div) + await flag.initialize() + expect(flag('has_feature1')).toBe(true) + expect(flag('has_feature2')).toBe(false) + expect(flag('number_of_foos')).toBe(10) + expect(flag('bar_config')).toEqual({ qux: 'quux' }) + } finally { + document.body.removeChild(div) } - } - client.stackClient.fetchJSON = jest.fn(() => flagResponseFixture) - await flag.initializeFromRemote(client) + }) + } + + it('should initialize from the remote stack', async () => { + const { client } = setup() + await flag.initialize(client) expect(flag('has_feature1')).toBe(true) expect(flag('has_feature2')).toBe(false) + expect(flag('from_remote')).toBe(true) expect(flag('number_of_foos')).toBe(10) expect(flag('bar_config')).toEqual({ qux: 'quux' }) })