diff --git a/coral/src/app/layout/header/ProfileDropdown.test.tsx b/coral/src/app/layout/header/ProfileDropdown.test.tsx index 404256a0cf..f987586d9c 100644 --- a/coral/src/app/layout/header/ProfileDropdown.test.tsx +++ b/coral/src/app/layout/header/ProfileDropdown.test.tsx @@ -7,7 +7,6 @@ import { customRender } from "src/services/test-utils/render-with-wrappers"; const mockLogoutUser = logoutUser as jest.MockedFunction; const mockedNavigate = jest.fn(); const mockAuthUser = jest.fn(); -const mockIsFeatureFlagActive = jest.fn(); const mockToast = jest.fn(); const mockDismiss = jest.fn(); @@ -21,10 +20,6 @@ jest.mock("src/app/context-provider/AuthProvider", () => ({ useAuthContext: () => mockAuthUser(), })); -jest.mock("src/services/feature-flags/utils", () => ({ - isFeatureFlagActive: () => mockIsFeatureFlagActive(), -})); - jest.mock("@aivenio/aquarium", () => ({ ...jest.requireActual("@aivenio/aquarium"), useToastContext: () => [mockToast, mockDismiss], @@ -34,19 +29,16 @@ const menuItems = [ { angularPath: "/myProfile", path: "/user/profile", - behindFeatureFlag: true, name: "User profile", }, { angularPath: "/changePwd", path: "/user/change-password", - behindFeatureFlag: true, name: "Change password", }, { angularPath: "/tenantInfo", path: "/user/tenant-info", - behindFeatureFlag: true, name: "Tenant information", }, ]; @@ -63,7 +55,6 @@ describe("ProfileDropdown", () => { describe("renders all necessary elements when dropdown is closed", () => { beforeAll(() => { - mockIsFeatureFlagActive.mockReturnValue(false); mockAuthUser.mockReturnValue(testUser); customRender(, { memoryRouter: true }); }); @@ -89,7 +80,6 @@ describe("ProfileDropdown", () => { describe("renders all necessary elements when dropdown is open", () => { beforeAll(async () => { - mockIsFeatureFlagActive.mockReturnValue(false); mockAuthUser.mockReturnValue(testUser); customRender(, { memoryRouter: true }); const button = screen.getByRole("button", { name: "Open profile menu" }); @@ -125,9 +115,8 @@ describe("ProfileDropdown", () => { }); }); - describe("handles user choosing items from the menu when feature-flag for user information is disabled", () => { + describe("handles user choosing items from the menu", () => { beforeEach(() => { - mockIsFeatureFlagActive.mockReturnValue(false); mockAuthUser.mockReturnValue(testUser); Object.defineProperty(window, "location", { value: { @@ -145,7 +134,8 @@ describe("ProfileDropdown", () => { menuItems.forEach((item) => { const name = item.name; - const path = item.angularPath; + + const path = item.path; it(`navigates to "${path}" when user clicks "${name}"`, async () => { const button = screen.getByRole("button", { @@ -156,74 +146,13 @@ describe("ProfileDropdown", () => { const menuItem = screen.getByRole("menuitem", { name: name }); await user.click(menuItem); - // in tests it will start with http://localhost/ since that is the window.origin - expect(window.location.assign).toHaveBeenCalledWith( - `http://localhost${path}` - ); + expect(mockedNavigate).toHaveBeenCalledWith(path); }); }); }); - describe("handles user choosing items from the menu when feature-flag for user information is enabled", () => { - beforeEach(() => { - mockIsFeatureFlagActive.mockReturnValue(true); - mockAuthUser.mockReturnValue(testUser); - Object.defineProperty(window, "location", { - value: { - assign: jest.fn(), - }, - writable: true, - }); - customRender(, { memoryRouter: true }); - }); - - afterEach(() => { - jest.restoreAllMocks(); - cleanup(); - }); - - menuItems.forEach((item) => { - const name = item.name; - - if (item.behindFeatureFlag) { - const path = item.path; - - it(`navigates to "${path}" when user clicks "${name}"`, async () => { - const button = screen.getByRole("button", { - name: "Open profile menu", - }); - await user.click(button); - - const menuItem = screen.getByRole("menuitem", { name: name }); - await user.click(menuItem); - - expect(window.location.assign).not.toHaveBeenCalled(); - expect(mockedNavigate).toHaveBeenCalledWith("/user/profile"); - }); - } else { - const path = item.angularPath; - - it(`navigates to "${path}" when user clicks "${name}"`, async () => { - const button = screen.getByRole("button", { - name: "Open profile menu", - }); - await user.click(button); - - const menuItem = screen.getByRole("menuitem", { name: name }); - await user.click(menuItem); - - // in tests it will start with http://localhost/ since that is the window.origin - expect(window.location.assign).toHaveBeenCalledWith( - `http://localhost${path}` - ); - }); - } - }); - }); - describe("handles user sucessfully login out", () => { beforeEach(() => { - mockIsFeatureFlagActive.mockReturnValue(false); mockAuthUser.mockReturnValue(testUser); // calling '/logout` successfully will resolve in us // receiving a 401 error so this is mocking the real behavior @@ -286,7 +215,6 @@ describe("ProfileDropdown", () => { }); describe("handles error in logout process", () => { - mockIsFeatureFlagActive(false); mockAuthUser.mockReturnValue(testUser); const testError = { status: 500, diff --git a/coral/src/app/layout/header/ProfileDropdown.tsx b/coral/src/app/layout/header/ProfileDropdown.tsx index 3056c065c2..937444f86e 100644 --- a/coral/src/app/layout/header/ProfileDropdown.tsx +++ b/coral/src/app/layout/header/ProfileDropdown.tsx @@ -1,62 +1,48 @@ import { Box, DropdownMenu, - Typography, Icon, + Typography, useToastContext, Button, } from "@aivenio/aquarium"; -import user from "@aivenio/aquarium/dist/src/icons/user"; import logOut from "@aivenio/aquarium/dist/src/icons/logOut"; +import user from "@aivenio/aquarium/dist/src/icons/user"; +import { useNavigate } from "react-router-dom"; +import { useAuthContext } from "src/app/context-provider/AuthProvider"; import classes from "src/app/layout/header/ProfileDropdown.module.css"; import { logoutUser } from "src/domain/auth-user"; -import { useAuthContext } from "src/app/context-provider/AuthProvider"; -import { useNavigate } from "react-router-dom"; -import useFeatureFlag from "src/services/feature-flags/hook/useFeatureFlag"; -import { FeatureFlag } from "src/services/feature-flags/types"; type MenuItem = { angularPath: string; path: string; name: string; - behindFeatureFlag: boolean; }; const menuItems: MenuItem[] = [ { angularPath: "/myProfile", path: "/user/profile", - behindFeatureFlag: true, name: "User profile", }, { angularPath: "/changePwd", path: "/user/change-password", - behindFeatureFlag: true, name: "Change password", }, { angularPath: "/tenantInfo", path: "/user/tenant-info", - behindFeatureFlag: true, name: "Tenant information", }, ]; const LOGOUT_KEY = "logout"; function ProfileDropdown() { - const userInformationFeatureFlagEnabled = useFeatureFlag( - FeatureFlag.FEATURE_FLAG_USER_INFORMATION - ); - const navigate = useNavigate(); const authUser = useAuthContext(); const [toast, dismiss] = useToastContext(); - function navigateToAngular(path: string) { - window.location.assign(`${window.origin}${path}`); - } - function onDropdownClick(actionKey: React.Key) { if (actionKey === LOGOUT_KEY) { toast({ @@ -90,12 +76,7 @@ function ProfileDropdown() { return; } - if (selectedItem.behindFeatureFlag && userInformationFeatureFlagEnabled) { - navigate(selectedItem.path); - return; - } - - navigateToAngular(selectedItem.angularPath); + navigate(selectedItem.path); } } diff --git a/coral/src/app/layout/main-navigation/MainNavigation.test.tsx b/coral/src/app/layout/main-navigation/MainNavigation.test.tsx index 7c55337da8..0be1329908 100644 --- a/coral/src/app/layout/main-navigation/MainNavigation.test.tsx +++ b/coral/src/app/layout/main-navigation/MainNavigation.test.tsx @@ -72,15 +72,15 @@ const submenuItems = [ links: [ { name: "User profile", - linkTo: isFeatureFlagActiveMock() ? `/user/profile` : `/myProfile`, + linkTo: "/user/profile", }, { name: "Change password", - linkTo: "/changePwd", + linkTo: "/user/change-password", }, { name: "Tenant information", - linkTo: "/tenantInfo", + linkTo: "/user/tenant-info", }, ], }, @@ -176,53 +176,6 @@ describe("MainNavigation.tsx", () => { }); }); - describe("renders links to profile behind feature flag", () => { - afterEach(() => { - cleanup(); - jest.resetAllMocks(); - }); - - it("renders a link to the old UI when feature flag is false", async () => { - isFeatureFlagActiveMock.mockReturnValue(false); - customRender(, { - memoryRouter: true, - queryClient: true, - }); - - const button = screen.getByRole("button", { - name: new RegExp("User information", "i"), - }); - await userEvent.click(button); - const list = screen.getByRole("list", { - name: "User information submenu", - }); - - const link = within(list).getByRole("link", { name: "User profile" }); - expect(link).toBeVisible(); - expect(link).toHaveAttribute("href", "/myProfile"); - }); - - it("renders a link to the profile page when feature flag is true", async () => { - isFeatureFlagActiveMock.mockReturnValue(true); - customRender(, { - memoryRouter: true, - queryClient: true, - }); - - const button = screen.getByRole("button", { - name: new RegExp("User information", "i"), - }); - await userEvent.click(button); - const list = screen.getByRole("list", { - name: "User information submenu", - }); - - const link = within(list).getByRole("link", { name: "User profile" }); - expect(link).toBeVisible(); - expect(link).toHaveAttribute("href", "/user/profile"); - }); - }); - describe("renders links to cluster behind feature flag", () => { afterEach(() => { cleanup(); diff --git a/coral/src/app/layout/main-navigation/MainNavigation.tsx b/coral/src/app/layout/main-navigation/MainNavigation.tsx index 724df7c8c5..07fcc3b4bf 100644 --- a/coral/src/app/layout/main-navigation/MainNavigation.tsx +++ b/coral/src/app/layout/main-navigation/MainNavigation.tsx @@ -18,9 +18,6 @@ import { FeatureFlag } from "src/services/feature-flags/types"; function MainNavigation() { const { pathname } = useLocation(); - const userInformationFeatureFlagEnabled = useFeatureFlag( - FeatureFlag.FEATURE_FLAG_USER_INFORMATION - ); const clusterViewFeatureFlagIsEnabled = useFeatureFlag( FeatureFlag.FEATURE_FLAG_VIEW_CLUSTER @@ -137,29 +134,17 @@ function MainNavigation() { defaultExpanded={pathname.startsWith(Routes.USER_INFORMATION)} > diff --git a/coral/src/app/router.tsx b/coral/src/app/router.tsx index ae833322c4..9589aed548 100644 --- a/coral/src/app/router.tsx +++ b/coral/src/app/router.tsx @@ -10,10 +10,13 @@ import AclApprovalsPage from "src/app/pages/approvals/acls"; import ConnectorApprovalsPage from "src/app/pages/approvals/connectors"; import SchemaApprovalsPage from "src/app/pages/approvals/schemas"; import TopicApprovalsPage from "src/app/pages/approvals/topics"; +import { ClustersPage } from "src/app/pages/configuration/clusters"; import EnvironmentsPage from "src/app/pages/configuration/environments"; import KafkaEnvironmentsPage from "src/app/pages/configuration/environments/kafka"; import KafkaConnectEnvironmentsPage from "src/app/pages/configuration/environments/kafka-connect"; import SchemaRegistryEnvironmentsPage from "src/app/pages/configuration/environments/schema-registry"; +import { TeamsPage } from "src/app/pages/configuration/teams"; +import { UsersPage } from "src/app/pages/configuration/users"; import ConnectorsPage from "src/app/pages/connectors"; import { ConnectorDetailsPage } from "src/app/pages/connectors/details"; import ConnectorEditRequest from "src/app/pages/connectors/edit-request"; @@ -39,6 +42,9 @@ import TopicEditRequestPage from "src/app/pages/topics/edit-request"; import TopicPromotionRequestPage from "src/app/pages/topics/promotion-request"; import RequestTopic from "src/app/pages/topics/request"; import SchemaRequest from "src/app/pages/topics/schema-request"; +import { ChangePassword } from "src/app/pages/user-information/change-password"; +import { UserProfile } from "src/app/pages/user-information/profile"; +import { TenantInfo } from "src/app/pages/user-information/tenant-info"; import { APPROVALS_TAB_ID_INTO_PATH, ApprovalsTabEnum, @@ -55,12 +61,6 @@ import { import { getRouterBasename } from "src/config"; import { createRouteBehindFeatureFlag } from "src/services/feature-flags/route-utils"; import { FeatureFlag } from "src/services/feature-flags/types"; -import { TeamsPage } from "src/app/pages/configuration/teams"; -import { UsersPage } from "src/app/pages/configuration/users"; -import { UserProfile } from "src/app/pages/user-information/profile"; -import { ChangePassword } from "src/app/pages/user-information/change-password"; -import { TenantInfo } from "src/app/pages/user-information/tenant-info"; -import { ClustersPage } from "src/app/pages/configuration/clusters"; const routes: Array = [ { @@ -257,24 +257,18 @@ const routes: Array = [ { path: Routes.USER_INFORMATION, children: [ - createRouteBehindFeatureFlag({ + { path: Routes.USER_PROFILE, - featureFlag: FeatureFlag.FEATURE_FLAG_USER_INFORMATION, - redirectRouteWithoutFeatureFlag: Routes.TOPICS, element: , - }), - createRouteBehindFeatureFlag({ + }, + { path: Routes.USER_CHANGE_PASSWORD, - featureFlag: FeatureFlag.FEATURE_FLAG_USER_INFORMATION, - redirectRouteWithoutFeatureFlag: Routes.TOPICS, element: , - }), - createRouteBehindFeatureFlag({ + }, + { path: Routes.USER_TENANT_INFO, - featureFlag: FeatureFlag.FEATURE_FLAG_USER_INFORMATION, - redirectRouteWithoutFeatureFlag: Routes.TOPICS, element: , - }), + }, ], }, ], diff --git a/coral/src/services/feature-flags/types.ts b/coral/src/services/feature-flags/types.ts index 39857ce5c5..b043c183b2 100644 --- a/coral/src/services/feature-flags/types.ts +++ b/coral/src/services/feature-flags/types.ts @@ -1,5 +1,4 @@ enum FeatureFlag { - FEATURE_FLAG_USER_INFORMATION = "FEATURE_FLAG_USER_INFORMATION", FEATURE_FLAG_VIEW_CLUSTER = "FEATURE_FLAG_VIEW_CLUSTER", } diff --git a/coral/vite.config.ts b/coral/vite.config.ts index 5f265229c5..475e6b1c3b 100644 --- a/coral/vite.config.ts +++ b/coral/vite.config.ts @@ -138,9 +138,6 @@ export default defineConfig(({ mode }) => { "process.env": { ROUTER_BASENAME: getRouterBasename(environment), API_BASE_URL: getApiBaseUrl(environment), - FEATURE_FLAG_USER_INFORMATION: ["development", "remote-api"] - .includes(mode) - .toString(), FEATURE_FLAG_VIEW_CLUSTER: ["development", "remote-api"] .includes(mode) .toString(),