Skip to content

Commit

Permalink
feat: Expose only 1 method to initialize flags
Browse files Browse the repository at this point in the history
  • Loading branch information
ptbrowne committed Feb 6, 2020
1 parent d822f68 commit f5a65ec
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 45 deletions.
50 changes: 45 additions & 5 deletions packages/cozy-flags/src/flag.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand All @@ -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 {
Expand All @@ -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
* ```
* <div data-cozy="{{ .CozyData }}"></div>
*
* // not recommended but possible
* <div data-flags="{{ .Flags }}"></div>
* ````
*
* @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)
}
}

Expand All @@ -94,5 +133,6 @@ flag.reset = resetFlags
flag.enable = enable
flag.initializeFromRemote = initializeFromRemote
flag.initializeFromDOM = initializeFromDOM
flag.initialize = initialize

export default flag
91 changes: 51 additions & 40 deletions packages/cozy-flags/src/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -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' })
})
Expand Down

0 comments on commit f5a65ec

Please sign in to comment.