🚩(frontend) integrate homepage feature flag
If the homepage feature flag is enabled, the homepage will be displayed.
This commit is contained in:
committed by
Manuel Raynaud
parent
67b69d05f7
commit
e9ab099ce0
@@ -8,6 +8,11 @@ and this project adheres to
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- 🚩 add homepage feature flag #861
|
||||||
|
|
||||||
|
|
||||||
## [3.1.0] - 2025-04-07
|
## [3.1.0] - 2025-04-07
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|||||||
@@ -1,5 +1,26 @@
|
|||||||
import { Page, expect } from '@playwright/test';
|
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 (
|
export const keyCloakSignIn = async (
|
||||||
page: Page,
|
page: Page,
|
||||||
browserName: string,
|
browserName: string,
|
||||||
|
|||||||
@@ -2,28 +2,7 @@ import path from 'path';
|
|||||||
|
|
||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
import { createDoc } from './common';
|
import { CONFIG, 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,
|
|
||||||
};
|
|
||||||
|
|
||||||
test.describe('Config', () => {
|
test.describe('Config', () => {
|
||||||
test('it checks the config api is called', async ({ page }) => {
|
test('it checks the config api is called', async ({ page }) => {
|
||||||
@@ -37,7 +16,7 @@ test.describe('Config', () => {
|
|||||||
const response = await responsePromise;
|
const response = await responsePromise;
|
||||||
expect(response.ok()).toBeTruthy();
|
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 ({
|
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')) {
|
if (request.method().includes('GET')) {
|
||||||
await route.fulfill({
|
await route.fulfill({
|
||||||
json: {
|
json: {
|
||||||
...config,
|
...CONFIG,
|
||||||
SENTRY_DSN: 'https://sentry.io/123',
|
SENTRY_DSN: 'https://sentry.io/123',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -121,7 +100,7 @@ test.describe('Config', () => {
|
|||||||
if (request.method().includes('GET')) {
|
if (request.method().includes('GET')) {
|
||||||
await route.fulfill({
|
await route.fulfill({
|
||||||
json: {
|
json: {
|
||||||
...config,
|
...CONFIG,
|
||||||
AI_FEATURE_ENABLED: false,
|
AI_FEATURE_ENABLED: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -152,7 +131,7 @@ test.describe('Config', () => {
|
|||||||
if (request.method().includes('GET')) {
|
if (request.method().includes('GET')) {
|
||||||
await route.fulfill({
|
await route.fulfill({
|
||||||
json: {
|
json: {
|
||||||
...config,
|
...CONFIG,
|
||||||
CRISP_WEBSITE_ID: '1234',
|
CRISP_WEBSITE_ID: '1234',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -174,7 +153,7 @@ test.describe('Config', () => {
|
|||||||
if (request.method().includes('GET')) {
|
if (request.method().includes('GET')) {
|
||||||
await route.fulfill({
|
await route.fulfill({
|
||||||
json: {
|
json: {
|
||||||
...config,
|
...CONFIG,
|
||||||
FRONTEND_CSS_URL: 'http://localhost:123465/css/style.css',
|
FRONTEND_CSS_URL: 'http://localhost:123465/css/style.css',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
|
import { CONFIG } from './common';
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
await page.goto('/docs/');
|
await page.goto('/docs/');
|
||||||
});
|
});
|
||||||
@@ -50,4 +52,27 @@ test.describe('Home page', () => {
|
|||||||
|
|
||||||
await expect(footer).toBeVisible();
|
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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,17 +5,18 @@ import { Theme } from '@/cunningham/';
|
|||||||
import { PostHogConf } from '@/services';
|
import { PostHogConf } from '@/services';
|
||||||
|
|
||||||
interface ConfigResponse {
|
interface ConfigResponse {
|
||||||
LANGUAGES: [string, string][];
|
AI_FEATURE_ENABLED?: boolean;
|
||||||
LANGUAGE_CODE: string;
|
|
||||||
ENVIRONMENT: string;
|
|
||||||
COLLABORATION_WS_URL?: string;
|
COLLABORATION_WS_URL?: string;
|
||||||
CRISP_WEBSITE_ID?: string;
|
CRISP_WEBSITE_ID?: string;
|
||||||
FRONTEND_THEME?: Theme;
|
ENVIRONMENT: string;
|
||||||
FRONTEND_CSS_URL?: string;
|
FRONTEND_CSS_URL?: string;
|
||||||
|
FRONTEND_HOMEPAGE_FEATURE_ENABLED?: boolean;
|
||||||
|
FRONTEND_THEME?: Theme;
|
||||||
|
LANGUAGES: [string, string][];
|
||||||
|
LANGUAGE_CODE: string;
|
||||||
MEDIA_BASE_URL?: string;
|
MEDIA_BASE_URL?: string;
|
||||||
POSTHOG_KEY?: PostHogConf;
|
POSTHOG_KEY?: PostHogConf;
|
||||||
SENTRY_DSN?: string;
|
SENTRY_DSN?: string;
|
||||||
AI_FEATURE_ENABLED?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getConfig = async (): Promise<ConfigResponse> => {
|
export const getConfig = async (): Promise<ConfigResponse> => {
|
||||||
|
|||||||
@@ -3,14 +3,16 @@ import { useRouter } from 'next/router';
|
|||||||
import { PropsWithChildren } from 'react';
|
import { PropsWithChildren } from 'react';
|
||||||
|
|
||||||
import { Box } from '@/components';
|
import { Box } from '@/components';
|
||||||
|
import { useConfig } from '@/core';
|
||||||
|
|
||||||
import { useAuth } from '../hooks';
|
import { useAuth } from '../hooks';
|
||||||
import { getAuthUrl } from '../utils';
|
import { getAuthUrl, gotoLogin } from '../utils';
|
||||||
|
|
||||||
export const Auth = ({ children }: PropsWithChildren) => {
|
export const Auth = ({ children }: PropsWithChildren) => {
|
||||||
const { isLoading, pathAllowed, isFetchedAfterMount, authenticated } =
|
const { isLoading, pathAllowed, isFetchedAfterMount, authenticated } =
|
||||||
useAuth();
|
useAuth();
|
||||||
const { replace, pathname } = useRouter();
|
const { replace, pathname } = useRouter();
|
||||||
|
const { data: config } = useConfig();
|
||||||
|
|
||||||
if (isLoading && !isFetchedAfterMount) {
|
if (isLoading && !isFetchedAfterMount) {
|
||||||
return (
|
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 the user is not authenticated and the path is not allowed, we redirect to the login page.
|
||||||
*/
|
*/
|
||||||
if (!authenticated && !pathAllowed) {
|
if (!authenticated && !pathAllowed) {
|
||||||
void replace('/login');
|
if (config?.FRONTEND_HOMEPAGE_FEATURE_ENABLED) {
|
||||||
|
void replace('/login');
|
||||||
|
} else {
|
||||||
|
gotoLogin();
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Box $height="100vh" $width="100vw" $align="center" $justify="center">
|
<Box $height="100vh" $width="100vw" $align="center" $justify="center">
|
||||||
<Loader />
|
<Loader />
|
||||||
|
|||||||
Reference in New Issue
Block a user