From 37b4af1f95333e320d92ead300d2deaba5e6e95b Mon Sep 17 00:00:00 2001 From: Puneet Lath Date: Thu, 10 Sep 2026 14:25:00 -0400 Subject: [PATCH 1/3] Remove custom agent beta gates --- src/CONST/index.ts | 1 - src/components/AIFeaturesPromoModal.tsx | 46 ++++++++----------- .../ProductMarketingWindowManager.tsx | 2 - src/pages/settings/Agents/AgentsPage.tsx | 14 +----- .../settings/useSettingsNavigationMenuData.ts | 4 +- .../rules/AgentRules/AddAgentRulePage.tsx | 2 - .../rules/AgentRules/EditAgentRulePage.tsx | 2 - src/pages/workspace/rules/PolicyRulesPage.tsx | 15 +++--- .../workspace/rules/PolicyRulesPageRevamp.tsx | 17 +++---- src/pages/workspace/rules/RulesNewPage.tsx | 23 ++++------ .../workspace/rules/tabs/RulesGeneralTab.tsx | 5 +- 11 files changed, 43 insertions(+), 88 deletions(-) diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 99e10fce0562..2c85dceb654b 100644 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -1074,7 +1074,6 @@ const CONST = { BETAS: { ALL: 'all', ASAP_SUBMIT: 'asapSubmit', - CUSTOM_AGENT: 'customAgent', DEFAULT_ROOMS: 'defaultRooms', PREVENT_SPOTNANA_TRAVEL: 'preventSpotnanaTravel', REPORT_FIELDS_FEATURE: 'reportFieldsFeature', diff --git a/src/components/AIFeaturesPromoModal.tsx b/src/components/AIFeaturesPromoModal.tsx index ae7de9beb61e..0a5448814613 100644 --- a/src/components/AIFeaturesPromoModal.tsx +++ b/src/components/AIFeaturesPromoModal.tsx @@ -1,5 +1,4 @@ import useLocalize from '@hooks/useLocalize'; -import usePermissions from '@hooks/usePermissions'; import useThemeStyles from '@hooks/useThemeStyles'; import {dismissProductTraining} from '@libs/actions/Welcome'; @@ -21,9 +20,6 @@ import Text from './Text'; function AIFeaturesPromoModal() { const {translate} = useLocalize(); const styles = useThemeStyles(); - const {isBetaEnabled} = usePermissions(); - const canUseCustomAgent = isBetaEnabled(CONST.BETAS.CUSTOM_AGENT); - const customAgentPromoTitle = ( {translate('aiFeaturesPromoModal.customAgents.title')} @@ -98,32 +94,28 @@ function AIFeaturesPromoModal() { - - {canUseCustomAgent ? translate('common.next') : translate('aiFeaturesPromoModal.confirmText')} - + {translate('common.next')} + + + + + + + + {subtitle} + {customAgentPromoTitle} + {translate('aiFeaturesPromoModal.customAgents.description')} + + + + {translate('aiFeaturesPromoModal.confirmText')} - {canUseCustomAgent && ( - - - - - {subtitle} - {customAgentPromoTitle} - {translate('aiFeaturesPromoModal.customAgents.description')} - - - - {translate('aiFeaturesPromoModal.confirmText')} - - - - )} ); diff --git a/src/components/ProductMarketingWindow/ProductMarketingWindowManager.tsx b/src/components/ProductMarketingWindow/ProductMarketingWindowManager.tsx index c821c9557dd2..36a494480114 100644 --- a/src/components/ProductMarketingWindow/ProductMarketingWindowManager.tsx +++ b/src/components/ProductMarketingWindow/ProductMarketingWindowManager.tsx @@ -91,7 +91,6 @@ function ProductMarketingWindowManager({topmostRouteName}: ProductMarketingWindo const illustrationNames = announcement ? [announcement.admin.visual, announcement.member?.visual].flatMap((visual) => (visual?.type === 'illustration' ? [visual.name] : [])) : []; const illustrations = useMemoizedLazyIllustrations(illustrationNames); const variant = getProductMarketingAnnouncementVariant(announcement, !!targetAdminPolicyID, lastDismissedMarketingWindow); - const isMemberVariantUnavailable = variant === announcement?.member && !isBetaEnabled(CONST.BETAS.CUSTOM_AGENT); const isVendorMatchingBetaEnabled = isBetaEnabled(CONST.BETAS.VENDOR_MATCHING); const shouldPrefetchTargetPolicyConnections = isVendorMatchingBetaEnabled && !!targetAdminPolicyID && targetAdminPolicyID !== activePolicyID; const {isFetchNeeded, isLoadingFetchedFlag, hasBeenFetched} = usePolicyConnectionsPrefetch(targetAdminPolicy, shouldPrefetchTargetPolicyConnections); @@ -120,7 +119,6 @@ function ProductMarketingWindowManager({topmostRouteName}: ProductMarketingWindo if ( !announcement || !variant || - isMemberVariantUnavailable || isLoading || isProductMarketingWindowCovered || isAnonymousSession || diff --git a/src/pages/settings/Agents/AgentsPage.tsx b/src/pages/settings/Agents/AgentsPage.tsx index d170f1f65008..b46fb66312e2 100644 --- a/src/pages/settings/Agents/AgentsPage.tsx +++ b/src/pages/settings/Agents/AgentsPage.tsx @@ -20,7 +20,6 @@ import useLocalize from '@hooks/useLocalize'; import useMobileSelectionMode from '@hooks/useMobileSelectionMode'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; -import usePermissions from '@hooks/usePermissions'; import usePrevious from '@hooks/usePrevious'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useRuleBotGuardModal from '@hooks/useRuleBotGuardModal'; @@ -34,8 +33,6 @@ import {getRuleBotEnforcedPolicy} from '@libs/AgentRulesUtils'; import {getLatestError} from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; -import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; - import {clearAgentDeleteError, clearAgentError, clearAgentUpdateError, deleteAgent, openAgentsPage} from '@userActions/Agent'; import CONST from '@src/CONST'; @@ -56,8 +53,6 @@ function AgentsPage() { const icons = useMemoizedLazyExpensifyIcons(['Plus', 'Trashcan']); const chatWithAgent = useChatWithAgent(); const switchToDelegator = useSwitchToDelegator(); - const {isBetaEnabled} = usePermissions(); - const isCustomAgentEnabled = isBetaEnabled(CONST.BETAS.CUSTOM_AGENT); const {showConfirmModal} = useConfirmModal(); const showRuleBotGuardModal = useRuleBotGuardModal(); const [selectedAgents, setSelectedAgents] = useState([]); @@ -70,11 +65,8 @@ function AgentsPage() { const canSelectMultiple = shouldUseNarrowLayout ? isMobileSelectionModeEnabled : true; useEffect(() => { - if (!isCustomAgentEnabled) { - return; - } openAgentsPage(); - }, [isCustomAgentEnabled]); + }, []); const handleErrorClose = (pendingAction: PendingAction | null | undefined, accountID: number) => { if (pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { @@ -249,10 +241,6 @@ function AgentsPage() { ); - if (!isCustomAgentEnabled) { - return ; - } - return ( item.screenName === SCREENS.SETTINGS.RULES.ROOT); accountItems.splice(rulesIndex + 1, 0, { translationKey: 'agentsPage.title', diff --git a/src/pages/workspace/rules/AgentRules/AddAgentRulePage.tsx b/src/pages/workspace/rules/AgentRules/AddAgentRulePage.tsx index aa9c147ef652..c5f861b66cc3 100644 --- a/src/pages/workspace/rules/AgentRules/AddAgentRulePage.tsx +++ b/src/pages/workspace/rules/AgentRules/AddAgentRulePage.tsx @@ -67,7 +67,6 @@ function AddAgentRulePage({ const styles = useThemeStyles(); const {isOffline} = useNetwork(); const {isBetaEnabled} = usePermissions(); - const isCustomAgentEnabled = isBetaEnabled(CONST.BETAS.CUSTOM_AGENT); const isRulesRevampEnabled = isBetaEnabled(CONST.BETAS.RULES_REVAMP); const policy = usePolicy(policyID); const linkPressedRef = useRef(false); @@ -208,7 +207,6 @@ function AddAgentRulePage({ return ( diff --git a/src/pages/workspace/rules/AgentRules/EditAgentRulePage.tsx b/src/pages/workspace/rules/AgentRules/EditAgentRulePage.tsx index 502600c7e509..b9833f65a596 100644 --- a/src/pages/workspace/rules/AgentRules/EditAgentRulePage.tsx +++ b/src/pages/workspace/rules/AgentRules/EditAgentRulePage.tsx @@ -46,7 +46,6 @@ function EditAgentRulePage({ const {translate} = useLocalize(); const styles = useThemeStyles(); const {isBetaEnabled} = usePermissions(); - const isCustomAgentEnabled = isBetaEnabled(CONST.BETAS.CUSTOM_AGENT); const isRulesRevampEnabled = isBetaEnabled(CONST.BETAS.RULES_REVAMP); const shouldUseExpandedRevampFormLayout = useShouldUseExpandedRevampFormLayout(); const policy = usePolicy(policyID); @@ -105,7 +104,6 @@ function EditAgentRulePage({ return ( diff --git a/src/pages/workspace/rules/PolicyRulesPage.tsx b/src/pages/workspace/rules/PolicyRulesPage.tsx index a402ab2ec1c1..ff35b622d31b 100644 --- a/src/pages/workspace/rules/PolicyRulesPage.tsx +++ b/src/pages/workspace/rules/PolicyRulesPage.tsx @@ -58,7 +58,6 @@ function PolicyRulesPage(props: PolicyRulesPageProps) { const {canWrite: canWriteRules, showReadOnlyModal, withReadOnlyFallback} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.RULES); const {isBetaEnabled} = usePermissions(); const isRulesRevampEnabled = isBetaEnabled(CONST.BETAS.RULES_REVAMP); - const isCustomAgentBetaEnabled = isBetaEnabled(CONST.BETAS.CUSTOM_AGENT); const [isAgentsRulesBannerDismissed = false] = useOnyx(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING, {selector: agentsRulesBannerDismissedSelector}); const fetchRules = useCallback(() => { @@ -115,7 +114,7 @@ function PolicyRulesPage(props: PolicyRulesPageProps) { > {shouldDisplayButtonsInSeparateLine && {headerButtons}} - {isCustomAgentBetaEnabled && !isAgentsRulesBannerDismissed && ( + {!isAgentsRulesBannerDismissed && ( )} - {isCustomAgentBetaEnabled && ( - - )} + diff --git a/src/pages/workspace/rules/PolicyRulesPageRevamp.tsx b/src/pages/workspace/rules/PolicyRulesPageRevamp.tsx index 3e19ff97d7f2..97248687edbc 100644 --- a/src/pages/workspace/rules/PolicyRulesPageRevamp.tsx +++ b/src/pages/workspace/rules/PolicyRulesPageRevamp.tsx @@ -85,7 +85,6 @@ function PolicyRulesPageRevamp({route}: PolicyRulesPageRevampProps) { const {canWrite: canWriteRules, showReadOnlyModal} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.RULES); const {isBetaEnabled} = usePermissions(); const isRulesRevampEnabled = isBetaEnabled(CONST.BETAS.RULES_REVAMP); - const isCustomAgentBetaEnabled = isBetaEnabled(CONST.BETAS.CUSTOM_AGENT); const isMobileSelectionModeEnabled = useMobileSelectionMode(); const shouldDisplayButtonsInSeparateLine = useShouldDisplayButtonsInSeparateLine(); const [isAgentsRulesBannerDismissed = false] = useOnyx(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING, {selector: agentsRulesBannerDismissedSelector}); @@ -93,7 +92,7 @@ function PolicyRulesPageRevamp({route}: PolicyRulesPageRevampProps) { const [lastSelectedTab] = useOnyx(`${ONYXKEYS.COLLECTION.SELECTED_TAB}${CONST.TAB.RULES_TAB_TYPE}`); const lastSelectedTabStr = lastSelectedTab as string | undefined; const resolvedTab: RulesTab = lastSelectedTabStr && isRulesTab(lastSelectedTabStr) ? lastSelectedTabStr : RULES_TAB.GENERAL; - const activeTab: RulesTab = resolvedTab === RULES_TAB.AGENTS && !isCustomAgentBetaEnabled ? RULES_TAB.GENERAL : resolvedTab; + const activeTab = resolvedTab; const [selectedRuleKeysByTab, setSelectedRuleKeysByTab] = useState>>({}); const {showConfirmModal} = useConfirmModal(); @@ -240,15 +239,11 @@ function PolicyRulesPageRevamp({route}: PolicyRulesPageRevampProps) { title: translate('workspace.rules.tabs.flagForReview'), icon: icons.Flag, }, - ...(isCustomAgentBetaEnabled - ? [ - { - key: RULES_TAB.AGENTS, - title: translate('workspace.rules.tabs.agents'), - icon: icons.Bot, - }, - ] - : []), + { + key: RULES_TAB.AGENTS, + title: translate('workspace.rules.tabs.agents'), + icon: icons.Bot, + }, ]; const rulesUpgradeAlias = CONST.UPGRADE_FEATURE_INTRO_MAPPING.rules.alias; diff --git a/src/pages/workspace/rules/RulesNewPage.tsx b/src/pages/workspace/rules/RulesNewPage.tsx index c9a8fa2f8c73..4112c1778ec2 100644 --- a/src/pages/workspace/rules/RulesNewPage.tsx +++ b/src/pages/workspace/rules/RulesNewPage.tsx @@ -47,7 +47,6 @@ function RulesNewPage({route}: RulesNewPageProps) { const styles = useThemeStyles(); const {isBetaEnabled} = usePermissions(); const isRulesRevampEnabled = isBetaEnabled(CONST.BETAS.RULES_REVAMP); - const isCustomAgentBetaEnabled = isBetaEnabled(CONST.BETAS.CUSTOM_AGENT); const illustrations = useMemoizedLazyIllustrations(['CardReaderAlt', 'Flag', 'CheckboxText', 'ReportReceipt', 'AiBot']); const isCategoryScopedCreate = route.name === SCREENS.WORKSPACE.DYNAMIC_CATEGORY_RULES_NEW || !!categoryName; @@ -96,19 +95,15 @@ function RulesNewPage({route}: RulesNewPageProps) { sentryLabel: CONST.SENTRY_LABEL.WORKSPACE.RULES.NEW_RULE_MENU_ITEM_APPLY_EXPENSE_DEFAULTS, isWorkspaceOnly: true, }, - ...(isCustomAgentBetaEnabled - ? [ - { - key: 'createAgentRule', - icon: illustrations.AiBot, - title: translate('workspace.rules.newRule.createAgentRule'), - description: translate('workspace.rules.newRule.createAgentRuleDescription'), - onPress: () => Navigation.navigate(ROUTES.RULES_AGENT_NEW.getRoute(policyID)), - sentryLabel: CONST.SENTRY_LABEL.WORKSPACE.RULES.NEW_RULE_MENU_ITEM_CREATE_AGENT_RULE, - isWorkspaceOnly: true, - } satisfies NewRuleOption, - ] - : []), + { + key: 'createAgentRule', + icon: illustrations.AiBot, + title: translate('workspace.rules.newRule.createAgentRule'), + description: translate('workspace.rules.newRule.createAgentRuleDescription'), + onPress: () => Navigation.navigate(ROUTES.RULES_AGENT_NEW.getRoute(policyID)), + sentryLabel: CONST.SENTRY_LABEL.WORKSPACE.RULES.NEW_RULE_MENU_ITEM_CREATE_AGENT_RULE, + isWorkspaceOnly: true, + }, ]; const visibleNewRuleOptions = isCategoryScopedCreate ? newRuleOptions.filter((option) => !option.isWorkspaceOnly) : newRuleOptions; diff --git a/src/pages/workspace/rules/tabs/RulesGeneralTab.tsx b/src/pages/workspace/rules/tabs/RulesGeneralTab.tsx index 894e27ba7d38..7639cdb97bf5 100644 --- a/src/pages/workspace/rules/tabs/RulesGeneralTab.tsx +++ b/src/pages/workspace/rules/tabs/RulesGeneralTab.tsx @@ -2,7 +2,6 @@ import AgentPromotionalBanner from '@components/AgentPromotionalBanner'; import ScrollView from '@components/ScrollView'; import useLocalize from '@hooks/useLocalize'; -import usePermissions from '@hooks/usePermissions'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -29,8 +28,6 @@ function RulesGeneralTab({policyID, canWriteRules, isAgentsRulesBannerDismissed, const {translate} = useLocalize(); const styles = useThemeStyles(); const {shouldUseNarrowLayout} = useResponsiveLayout(); - const {isBetaEnabled} = usePermissions(); - const isCustomAgentBetaEnabled = isBetaEnabled(CONST.BETAS.CUSTOM_AGENT); // The tab owns the scroll so the selector scrolls with the content, matching the table tabs where it is the list's // header. The page's buttons sit above this and stay pinned. @@ -47,7 +44,7 @@ function RulesGeneralTab({policyID, canWriteRules, isAgentsRulesBannerDismissed, policyID={policyID} canWriteRules={canWriteRules} /> - {isCustomAgentBetaEnabled && !isAgentsRulesBannerDismissed && ( + {!isAgentsRulesBannerDismissed && ( Date: Thu, 10 Sep 2026 14:25:12 -0400 Subject: [PATCH 2/3] Update custom agent availability tests --- tests/ui/AgentsPromoBannersTest.tsx | 20 ++-------- tests/ui/InitialSettingsPageTest.tsx | 13 +------ tests/unit/ProductMarketingWindowTest.tsx | 41 +------------------- tests/unit/pages/settings/AgentsPageTest.tsx | 31 +-------------- 4 files changed, 8 insertions(+), 97 deletions(-) diff --git a/tests/ui/AgentsPromoBannersTest.tsx b/tests/ui/AgentsPromoBannersTest.tsx index 488783fde0d7..602188705d31 100644 --- a/tests/ui/AgentsPromoBannersTest.tsx +++ b/tests/ui/AgentsPromoBannersTest.tsx @@ -109,7 +109,7 @@ const renderRulesPage = () => , ); -async function setupOnyxBaseline({withCustomAgentBeta}: {withCustomAgentBeta: boolean}) { +async function setupOnyxBaseline() { await Onyx.clear(); await Onyx.set(ONYXKEYS.HAS_LOADED_APP, true); await Onyx.set(ONYXKEYS.IS_LOADING_REPORT_DATA, false); @@ -118,9 +118,6 @@ async function setupOnyxBaseline({withCustomAgentBeta}: {withCustomAgentBeta: bo [USER_ACCOUNT_ID]: buildPersonalDetails(USER_EMAIL, USER_ACCOUNT_ID, 'Admin'), }); await Onyx.merge(ONYXKEYS.SESSION, {email: USER_EMAIL, accountID: USER_ACCOUNT_ID}); - if (withCustomAgentBeta) { - await Onyx.set(ONYXKEYS.BETAS, [CONST.BETAS.CUSTOM_AGENT]); - } } describe('Agents promo banners', () => { @@ -136,9 +133,9 @@ describe('Agents promo banners', () => { }); }); - it('renders agentsRulesBanner above IndividualExpenseRulesSection when customAgent beta is active, and hides it after dismissal', async () => { + it('renders agentsRulesBanner above IndividualExpenseRulesSection and hides it after dismissal', async () => { await act(async () => { - await setupOnyxBaseline({withCustomAgentBeta: true}); + await setupOnyxBaseline(); await waitForBatchedUpdatesWithAct(); }); @@ -159,15 +156,4 @@ describe('Agents promo banners', () => { expect(screen.queryByText(en.workspace.rules.agentsPromoBanner.subtitle)).toBeNull(); }); - - it('does not render the agents rules banner when customAgent beta is inactive', async () => { - await act(async () => { - await setupOnyxBaseline({withCustomAgentBeta: false}); - await waitForBatchedUpdatesWithAct(); - }); - - renderRulesPage(); - await waitForBatchedUpdatesWithAct(); - expect(screen.queryByText(en.workspace.rules.agentsPromoBanner.subtitle)).toBeNull(); - }); }); diff --git a/tests/ui/InitialSettingsPageTest.tsx b/tests/ui/InitialSettingsPageTest.tsx index 30dd05544ea9..be7eb2e1edbf 100644 --- a/tests/ui/InitialSettingsPageTest.tsx +++ b/tests/ui/InitialSettingsPageTest.tsx @@ -8,7 +8,6 @@ import OnyxListItemProvider from '@components/OnyxListItemProvider'; import ScrollView from '@components/ScrollView'; import {CurrentReportIDContextProvider} from '@hooks/useCurrentReportID'; -import usePermissions from '@hooks/usePermissions'; import useSubscriptionPlan from '@hooks/useSubscriptionPlan'; import {navigationRef} from '@libs/Navigation/Navigation'; @@ -70,8 +69,6 @@ jest.mock('@libs/Navigation/helpers/useIsSidebarRouteActive', () => jest.fn(() = jest.mock('@hooks/useSubscriptionPlan', () => jest.fn(() => null)); -jest.mock('@hooks/usePermissions', () => jest.fn(() => ({isBetaEnabled: () => false}))); - jest.mock('@components/AccountSwitcher', () => { function MockAccountSwitcher() { return null; @@ -131,7 +128,6 @@ jest.mock('@components/MenuItem', () => { ); }); -const mockUsePermissions = jest.mocked(usePermissions); const mockUseSubscriptionPlan = jest.mocked(useSubscriptionPlan); const Stack = createPlatformStackNavigator(); @@ -173,7 +169,6 @@ describe('InitialSettingsPage - agent account', () => { await Onyx.clear(); await waitForBatchedUpdatesWithAct(); jest.clearAllMocks(); - mockUsePermissions.mockImplementation(() => ({isBetaEnabled: () => false})); mockUseSubscriptionPlan.mockImplementation(() => null); }); @@ -311,7 +306,6 @@ describe('InitialSettingsPage - agent account', () => { it('preserves dynamic menu decorations and general menu ordering', async () => { mockUseSubscriptionPlan.mockReturnValue(CONST.POLICY.TYPE.CORPORATE); - mockUsePermissions.mockReturnValue({isBetaEnabled: (beta: string) => beta === CONST.BETAS.CUSTOM_AGENT}); await setupUser('user@expensify.com'); const policy = createRandomPolicy(accountID, CONST.POLICY.TYPE.CORPORATE); @@ -363,8 +357,7 @@ describe('InitialSettingsPage - agent account', () => { }); }); - it('hides Agents for agent account when CUSTOM_AGENT beta is enabled', async () => { - mockUsePermissions.mockReturnValue({isBetaEnabled: (beta: string) => beta === CONST.BETAS.CUSTOM_AGENT}); + it('hides Agents for agent account', async () => { await setupUser('testbot_123@expensify.ai', true); renderPage(); @@ -375,8 +368,7 @@ describe('InitialSettingsPage - agent account', () => { }); }); - it('shows Agents for non-agent account when CUSTOM_AGENT beta is enabled', async () => { - mockUsePermissions.mockReturnValue({isBetaEnabled: (beta: string) => beta === CONST.BETAS.CUSTOM_AGENT}); + it('shows Agents for non-agent account', async () => { await setupUser('user@expensify.com'); renderPage(); @@ -408,7 +400,6 @@ describe('InitialSettingsPage - scrolling', () => { }); it('should emit a scrolling event so anchored tooltips can follow or hide', async () => { - mockUsePermissions.mockImplementation(() => ({isBetaEnabled: () => false})); mockUseSubscriptionPlan.mockImplementation(() => null); await TestHelper.signInWithTestUser(accountID, 'user@expensify.com'); await act(async () => { diff --git a/tests/unit/ProductMarketingWindowTest.tsx b/tests/unit/ProductMarketingWindowTest.tsx index d07594a7a73b..d9576b3adc7f 100644 --- a/tests/unit/ProductMarketingWindowTest.tsx +++ b/tests/unit/ProductMarketingWindowTest.tsx @@ -144,17 +144,7 @@ const renderManager = (topmostRouteName?: string, theme: ThemePreferenceWithoutS , ); -async function setupOnyxBaseline({ - isAdmin, - activePolicyID = POLICY_ID, - initializeBetas = true, - initializeOnboarding = true, -}: { - isAdmin: boolean; - activePolicyID?: string; - initializeBetas?: boolean; - initializeOnboarding?: boolean; -}) { +async function setupOnyxBaseline({isAdmin, activePolicyID = POLICY_ID, initializeOnboarding = true}: {isAdmin: boolean; activePolicyID?: string; initializeOnboarding?: boolean}) { await Onyx.clear(); await Onyx.set(ONYXKEYS.IS_LOADING_APP, false); if (initializeOnboarding) { @@ -167,9 +157,7 @@ async function setupOnyxBaseline({ email: USER_EMAIL, accountID: USER_ACCOUNT_ID, }); - if (initializeBetas) { - await Onyx.set(ONYXKEYS.BETAS, []); - } + await Onyx.set(ONYXKEYS.BETAS, []); if (isAdmin) { await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, buildAdminPolicy()); await Onyx.set(ONYXKEYS.NVP_ACTIVE_POLICY_ID, activePolicyID); @@ -229,9 +217,6 @@ describe('ProductMarketingWindowManager', () => { await act(async () => { await setupOnyxBaseline({isAdmin}); await Onyx.set(ONYXKEYS.NVP_ONBOARDING, {hasCompletedGuidedSetupFlow: false}); - if (!isAdmin) { - await Onyx.set(ONYXKEYS.BETAS, [CONST.BETAS.CUSTOM_AGENT]); - } await waitForBatchedUpdatesWithAct(); }); @@ -290,7 +275,6 @@ describe('ProductMarketingWindowManager', () => { }); await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, null); await Onyx.set(ONYXKEYS.NVP_ACTIVE_POLICY_ID, null); - await Onyx.set(ONYXKEYS.BETAS, [CONST.BETAS.CUSTOM_AGENT]); await waitForBatchedUpdatesWithAct(); }); @@ -378,7 +362,6 @@ describe('ProductMarketingWindowManager', () => { it('shows the member variant for a user without an admin role on any workspace', async () => { await act(async () => { await setupOnyxBaseline({isAdmin: false}); - await Onyx.set(ONYXKEYS.BETAS, [CONST.BETAS.CUSTOM_AGENT]); await waitForBatchedUpdatesWithAct(); }); @@ -390,25 +373,6 @@ describe('ProductMarketingWindowManager', () => { expect(screen.UNSAFE_getByType(Image).props.source).toBe(August2026PromoEmployeesImage); }); - it('does not show the member variant until the Custom Agent beta is available', async () => { - await act(async () => { - await setupOnyxBaseline({isAdmin: false, initializeBetas: false}); - await waitForBatchedUpdatesWithAct(); - }); - - renderManager(); - await waitForBatchedUpdatesWithAct(); - - expect(screen.queryByText(memberHeading)).toBeNull(); - - await act(async () => { - await Onyx.set(ONYXKEYS.BETAS, [CONST.BETAS.CUSTOM_AGENT]); - await waitForBatchedUpdatesWithAct(); - }); - - expect(screen.getByText(memberHeading)).toBeTruthy(); - }); - it('shows the admin variant when the user administers at least one active workspace', async () => { await act(async () => { await setupOnyxBaseline({isAdmin: true}); @@ -927,7 +891,6 @@ describe('ProductMarketingWindowManager', () => { it('routes the member CTA to the new Agents page', async () => { await act(async () => { await setupOnyxBaseline({isAdmin: false}); - await Onyx.set(ONYXKEYS.BETAS, [CONST.BETAS.CUSTOM_AGENT]); await waitForBatchedUpdatesWithAct(); }); diff --git a/tests/unit/pages/settings/AgentsPageTest.tsx b/tests/unit/pages/settings/AgentsPageTest.tsx index 77fc918fcbf6..14cb59efbea3 100644 --- a/tests/unit/pages/settings/AgentsPageTest.tsx +++ b/tests/unit/pages/settings/AgentsPageTest.tsx @@ -3,7 +3,6 @@ import {render, screen} from '@testing-library/react-native'; import {usePersonalDetails} from '@components/OnyxListItemProvider'; import useOnyx from '@hooks/useOnyx'; -import usePermissions from '@hooks/usePermissions'; import AgentsPage from '@pages/settings/Agents/AgentsPage'; @@ -19,8 +18,6 @@ jest.mock('@userActions/Agent', () => ({ openAgentsPage: jest.fn(), })); -jest.mock('@hooks/usePermissions', () => jest.fn(() => ({isBetaEnabled: () => true}))); - jest.mock('@hooks/useLocalize', () => jest.fn(() => ({ translate: (key: string) => key, @@ -141,14 +138,6 @@ jest.mock('@components/RenderHTML', () => { return MockRenderHTML; }); -jest.mock('@pages/ErrorPage/NotFoundPage', () => { - function MockNotFoundPage() { - return 'NotFoundPage'; - } - return MockNotFoundPage; -}); - -const mockUsePermissions = jest.mocked(usePermissions); const mockOpenAgentsPage = jest.mocked(openAgentsPage); const mockUseOnyx = jest.mocked(useOnyx); const mockUsePersonalDetails = jest.mocked(usePersonalDetails); @@ -156,41 +145,23 @@ const mockUsePersonalDetails = jest.mocked(usePersonalDetails); describe('AgentsPage', () => { beforeEach(() => { jest.clearAllMocks(); - mockUsePermissions.mockReturnValue({isBetaEnabled: () => true}); mockUseOnyx.mockReturnValue([undefined, {status: 'loaded'}]); mockUsePersonalDetails.mockReturnValue({}); }); - it('renders page content when customAgent beta is enabled', () => { + it('renders page content', () => { const {toJSON} = render(); const output = JSON.stringify(toJSON()); - expect(output).not.toContain('NotFoundPage'); expect(output).toContain('agentsPage.title'); }); - it('renders NotFoundPage when customAgent beta is disabled', () => { - mockUsePermissions.mockReturnValue({isBetaEnabled: () => false}); - - const {toJSON} = render(); - - expect(JSON.stringify(toJSON())).toContain('NotFoundPage'); - }); - it('calls openAgentsPage on mount', () => { render(); expect(mockOpenAgentsPage).toHaveBeenCalledTimes(1); }); - it('does not call openAgentsPage when beta is disabled', () => { - mockUsePermissions.mockReturnValue({isBetaEnabled: () => false}); - - render(); - - expect(mockOpenAgentsPage).not.toHaveBeenCalled(); - }); - it('shows empty state when no agents exist', () => { mockUseOnyx.mockReturnValue([undefined, {status: 'loaded'}]); From 6745460056c211267aa511e36112559b2ee2dc32 Mon Sep 17 00:00:00 2001 From: Puneet Lath Date: Thu, 10 Sep 2026 14:34:40 -0400 Subject: [PATCH 3/3] Update default settings menu expectation --- tests/ui/InitialSettingsPageTest.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/InitialSettingsPageTest.tsx b/tests/ui/InitialSettingsPageTest.tsx index be7eb2e1edbf..a5cef1a0dfff 100644 --- a/tests/ui/InitialSettingsPageTest.tsx +++ b/tests/ui/InitialSettingsPageTest.tsx @@ -232,6 +232,7 @@ describe('InitialSettingsPage - agent account', () => { 'Profile', 'Wallet', 'Expense rules', + 'Agents', 'Preferences', 'Copilot', 'Security',