diff --git a/CHANGELOG.md b/CHANGELOG.md index 3738603c..f4f1a643 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ and this project adheres to ## [Unreleased] +## Added + +- 🚩 add homepage feature flag #861 + + ## [3.1.0] - 2025-04-07 ## Added diff --git a/src/frontend/apps/e2e/__tests__/app-impress/common.ts b/src/frontend/apps/e2e/__tests__/app-impress/common.ts index a6b55993..11ae0902 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/common.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/common.ts @@ -1,5 +1,26 @@ import { Page, expect } from '@playwright/test'; +export const CONFIG = { + AI_FEATURE_ENABLED: true, + CRISP_WEBSITE_ID: null, + COLLABORATION_WS_URL: 'ws://localhost:4444/collaboration/ws/', + ENVIRONMENT: 'development', + FRONTEND_CSS_URL: null, + FRONTEND_HOMEPAGE_FEATURE_ENABLED: true, + FRONTEND_FOOTER_FEATURE_ENABLED: true, + FRONTEND_THEME: 'default', + MEDIA_BASE_URL: 'http://localhost:8083', + LANGUAGES: [ + ['en-us', 'English'], + ['fr-fr', 'Français'], + ['de-de', 'Deutsch'], + ['nl-nl', 'Nederlands'], + ], + LANGUAGE_CODE: 'en-us', + POSTHOG_KEY: {}, + SENTRY_DSN: null, +}; + export const keyCloakSignIn = async ( page: Page, browserName: string, diff --git a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts index c2f3d3d1..90557aad 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts @@ -2,28 +2,7 @@ import path from 'path'; import { expect, test } from '@playwright/test'; -import { createDoc } from './common'; - -const config = { - AI_FEATURE_ENABLED: true, - CRISP_WEBSITE_ID: null, - COLLABORATION_WS_URL: 'ws://localhost:4444/collaboration/ws/', - ENVIRONMENT: 'development', - FRONTEND_CSS_URL: null, - FRONTEND_HOMEPAGE_FEATURE_ENABLED: true, - FRONTEND_FOOTER_FEATURE_ENABLED: true, - FRONTEND_THEME: 'default', - MEDIA_BASE_URL: 'http://localhost:8083', - LANGUAGES: [ - ['en-us', 'English'], - ['fr-fr', 'Français'], - ['de-de', 'Deutsch'], - ['nl-nl', 'Nederlands'], - ], - LANGUAGE_CODE: 'en-us', - POSTHOG_KEY: {}, - SENTRY_DSN: null, -}; +import { CONFIG, createDoc } from './common'; test.describe('Config', () => { test('it checks the config api is called', async ({ page }) => { @@ -37,7 +16,7 @@ test.describe('Config', () => { const response = await responsePromise; expect(response.ok()).toBeTruthy(); - expect(await response.json()).toStrictEqual(config); + expect(await response.json()).toStrictEqual(CONFIG); }); test('it checks that sentry is trying to init from config endpoint', async ({ @@ -48,7 +27,7 @@ test.describe('Config', () => { if (request.method().includes('GET')) { await route.fulfill({ json: { - ...config, + ...CONFIG, SENTRY_DSN: 'https://sentry.io/123', }, }); @@ -121,7 +100,7 @@ test.describe('Config', () => { if (request.method().includes('GET')) { await route.fulfill({ json: { - ...config, + ...CONFIG, AI_FEATURE_ENABLED: false, }, }); @@ -152,7 +131,7 @@ test.describe('Config', () => { if (request.method().includes('GET')) { await route.fulfill({ json: { - ...config, + ...CONFIG, CRISP_WEBSITE_ID: '1234', }, }); @@ -174,7 +153,7 @@ test.describe('Config', () => { if (request.method().includes('GET')) { await route.fulfill({ json: { - ...config, + ...CONFIG, FRONTEND_CSS_URL: 'http://localhost:123465/css/style.css', }, }); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts index 829b45e7..d2587929 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts @@ -1,5 +1,7 @@ import { expect, test } from '@playwright/test'; +import { CONFIG } from './common'; + test.beforeEach(async ({ page }) => { await page.goto('/docs/'); }); @@ -50,4 +52,27 @@ test.describe('Home page', () => { await expect(footer).toBeVisible(); }); + + test('it checks the homepage feature flag', async ({ page }) => { + await page.route('**/api/v1.0/config/', async (route) => { + const request = route.request(); + if (request.method().includes('GET')) { + await route.fulfill({ + json: { + ...CONFIG, + FRONTEND_HOMEPAGE_FEATURE_ENABLED: false, + }, + }); + } else { + await route.continue(); + } + }); + + await page.goto('/'); + + // Keyclock login page + await expect( + page.locator('.login-pf-page-header').getByText('impress'), + ).toBeVisible(); + }); }); diff --git a/src/frontend/apps/impress/src/core/config/api/useConfig.tsx b/src/frontend/apps/impress/src/core/config/api/useConfig.tsx index 65187ce0..aa364877 100644 --- a/src/frontend/apps/impress/src/core/config/api/useConfig.tsx +++ b/src/frontend/apps/impress/src/core/config/api/useConfig.tsx @@ -5,17 +5,18 @@ import { Theme } from '@/cunningham/'; import { PostHogConf } from '@/services'; interface ConfigResponse { - LANGUAGES: [string, string][]; - LANGUAGE_CODE: string; - ENVIRONMENT: string; + AI_FEATURE_ENABLED?: boolean; COLLABORATION_WS_URL?: string; CRISP_WEBSITE_ID?: string; - FRONTEND_THEME?: Theme; + ENVIRONMENT: string; FRONTEND_CSS_URL?: string; + FRONTEND_HOMEPAGE_FEATURE_ENABLED?: boolean; + FRONTEND_THEME?: Theme; + LANGUAGES: [string, string][]; + LANGUAGE_CODE: string; MEDIA_BASE_URL?: string; POSTHOG_KEY?: PostHogConf; SENTRY_DSN?: string; - AI_FEATURE_ENABLED?: boolean; } export const getConfig = async (): Promise => { diff --git a/src/frontend/apps/impress/src/features/auth/components/Auth.tsx b/src/frontend/apps/impress/src/features/auth/components/Auth.tsx index 7d47b9b1..87023c80 100644 --- a/src/frontend/apps/impress/src/features/auth/components/Auth.tsx +++ b/src/frontend/apps/impress/src/features/auth/components/Auth.tsx @@ -3,14 +3,16 @@ import { useRouter } from 'next/router'; import { PropsWithChildren } from 'react'; import { Box } from '@/components'; +import { useConfig } from '@/core'; import { useAuth } from '../hooks'; -import { getAuthUrl } from '../utils'; +import { getAuthUrl, gotoLogin } from '../utils'; export const Auth = ({ children }: PropsWithChildren) => { const { isLoading, pathAllowed, isFetchedAfterMount, authenticated } = useAuth(); const { replace, pathname } = useRouter(); + const { data: config } = useConfig(); if (isLoading && !isFetchedAfterMount) { return ( @@ -40,7 +42,11 @@ export const Auth = ({ children }: PropsWithChildren) => { * If the user is not authenticated and the path is not allowed, we redirect to the login page. */ if (!authenticated && !pathAllowed) { - void replace('/login'); + if (config?.FRONTEND_HOMEPAGE_FEATURE_ENABLED) { + void replace('/login'); + } else { + gotoLogin(); + } return (