diff --git a/contentcuration/contentcuration/frontend/shared/vuex/session/index.js b/contentcuration/contentcuration/frontend/shared/vuex/session/index.js index d89a56e6d5..b0a2b10a05 100644 --- a/contentcuration/contentcuration/frontend/shared/vuex/session/index.js +++ b/contentcuration/contentcuration/frontend/shared/vuex/session/index.js @@ -6,6 +6,7 @@ import { Session, User } from 'shared/data/resources'; import { forceServerSync } from 'shared/data/serverSync'; import translator from 'shared/translator'; import { applyMods } from 'shared/data/applyRemoteChanges'; +import { FeatureFlagKeys } from 'shared/constants'; function langCode(language) { // Turns a Django language name (en-gb) into an ISO language code (en-GB) @@ -94,6 +95,12 @@ export default { return getters.isAdmin || Boolean(getters.featureFlags[flag]); }; }, + isAIFeatureEnabled(state, getters) { + if (getters.loggedIn) { + return getters.hasFeatureEnabled(FeatureFlagKeys.ai_feature); + } + return false; + }, }, actions: { saveSession(context, currentUser) { diff --git a/contentcuration/contentcuration/frontend/shared/vuex/session/index.spec.js b/contentcuration/contentcuration/frontend/shared/vuex/session/index.spec.js new file mode 100644 index 0000000000..ef7e7308f3 --- /dev/null +++ b/contentcuration/contentcuration/frontend/shared/vuex/session/index.spec.js @@ -0,0 +1,84 @@ +import vuexSessionModule from './index.js'; +import { FeatureFlagKeys } from 'shared/constants'; + +describe('session module feature flag related getters', () => { + let state; + beforeEach(() => { + state = { + currentUser: { + feature_flags: { + true_flag: true, + false_flag: false, + }, + }, + }; + state.currentUser.feature_flags[FeatureFlagKeys.ai_feature] = true; + }); + + describe('featureFlags', () => { + let getters; + beforeEach(() => { + getters = { + featureFlags: vuexSessionModule.getters.featureFlags, + }; + }); + it('should return feature flags from current user', () => { + const result = getters.featureFlags(state); + expect(result).toEqual(state.currentUser.feature_flags); + }); + + it('should return empty object if no feature flags set', () => { + state.currentUser = {}; + const result = getters.featureFlags(state); + expect(result).toEqual({}); + }); + }); + + describe('hasFeatureEnabled', () => { + let getters; + beforeEach(() => { + getters = { + featureFlags: state.currentUser.feature_flags, + hasFeatureEnabled: vuexSessionModule.getters.hasFeatureEnabled, + }; + }); + it('for admin user returns true even when the flag value is false', () => { + getters.isAdmin = true; + expect(getters.hasFeatureEnabled(state, getters)('true_flag')).toBe(true); + expect(getters.hasFeatureEnabled(state, getters)('false_flag')).toBe(true); + }); + + it('returns flag value for non-admin user', () => { + getters.isAdmin = false; + expect(getters.hasFeatureEnabled(state, getters)('true_flag')).toBe(true); + expect(getters.hasFeatureEnabled(state, getters)('false_flag')).toBe(false); + }); + }); + + describe('isAIFeatureEnabled', () => { + let getters; + beforeEach(() => { + getters = { + loggedIn: true, + hasFeatureEnabled: vuexSessionModule.getters.hasFeatureEnabled(state, { + featureFlags: vuexSessionModule.getters.featureFlags(state), + isAdmin: false, + }), + isAIFeatureEnabled: vuexSessionModule.getters.isAIFeatureEnabled, + }; + }); + it('should return false if not logged in', () => { + getters.loggedIn = false; + expect(getters.isAIFeatureEnabled(state, getters)).toBe(false); + }); + + it('should return true if logged in and ai feature flag is true', () => { + expect(getters.isAIFeatureEnabled(state, getters)).toBe(true); + }); + + it('should return false if logged in and ai feature flag is false', () => { + state.currentUser.feature_flags[FeatureFlagKeys.ai_feature] = false; + expect(getters.isAIFeatureEnabled(state, getters)).toBe(false); + }); + }); +});