diff --git a/client/a8c-for-agencies/sections/partner-directory/lib/lead-matching-visibility.ts b/client/a8c-for-agencies/sections/partner-directory/lib/lead-matching-visibility.ts index 0b1e0c79978f..2a93ac945168 100644 --- a/client/a8c-for-agencies/sections/partner-directory/lib/lead-matching-visibility.ts +++ b/client/a8c-for-agencies/sections/partner-directory/lib/lead-matching-visibility.ts @@ -3,6 +3,14 @@ import { isEnabled } from '@automattic/calypso-config'; export const A4A_PARTNER_DIRECTORY_LEAD_MATCHING_FEATURE_FLAG = 'a4a-partner-directory-lead-matching'; +export const A4A_PARTNER_DIRECTORY_LEAD_MATCHING_PILOT_AGENCY_IDS = new Set( [ + 232667176, 251102500, 234036126, 234278359, 232640028, +] ); + +export const isLeadMatchingPilotAgency = ( agencyId?: number ) => + typeof agencyId === 'number' && + A4A_PARTNER_DIRECTORY_LEAD_MATCHING_PILOT_AGENCY_IDS.has( agencyId ); + export const isLeadMatchingSectionEnabled = () => isEnabled( A4A_PARTNER_DIRECTORY_LEAD_MATCHING_FEATURE_FLAG ); diff --git a/client/a8c-for-agencies/sections/partner-directory/lib/test/lead-matching-visibility.test.ts b/client/a8c-for-agencies/sections/partner-directory/lib/test/lead-matching-visibility.test.ts new file mode 100644 index 000000000000..318519501fa2 --- /dev/null +++ b/client/a8c-for-agencies/sections/partner-directory/lib/test/lead-matching-visibility.test.ts @@ -0,0 +1,38 @@ +jest.mock( '@automattic/calypso-config', () => ( { + isEnabled: jest.fn(), +} ) ); + +import { isEnabled } from '@automattic/calypso-config'; +import { + A4A_PARTNER_DIRECTORY_LEAD_MATCHING_PILOT_AGENCY_IDS, + isLeadMatchingPilotAgency, + isLeadMatchingSectionEnabled, +} from '../lead-matching-visibility'; + +const mockedIsEnabled = isEnabled as jest.MockedFunction< typeof isEnabled >; + +describe( 'lead matching visibility', () => { + beforeEach( () => { + mockedIsEnabled.mockReset(); + } ); + + it( 'returns true when the global feature flag is enabled', () => { + mockedIsEnabled.mockReturnValue( true ); + + expect( isLeadMatchingSectionEnabled() ).toBe( true ); + } ); + + it( 'returns true for pilot agencies', () => { + for ( const agencyId of A4A_PARTNER_DIRECTORY_LEAD_MATCHING_PILOT_AGENCY_IDS ) { + expect( isLeadMatchingPilotAgency( agencyId ) ).toBe( true ); + } + } ); + + it( 'returns false for non-pilot agencies', () => { + mockedIsEnabled.mockReturnValue( false ); + + expect( isLeadMatchingPilotAgency( 123 ) ).toBe( false ); + expect( isLeadMatchingPilotAgency() ).toBe( false ); + expect( isLeadMatchingSectionEnabled() ).toBe( false ); + } ); +} ); diff --git a/client/state/a8c-for-agencies/agency/actions.ts b/client/state/a8c-for-agencies/agency/actions.ts index c279aadc47d2..1de30d1653a5 100644 --- a/client/state/a8c-for-agencies/agency/actions.ts +++ b/client/state/a8c-for-agencies/agency/actions.ts @@ -2,6 +2,10 @@ import config from '@automattic/calypso-config'; import { translate } from 'i18n-calypso'; // Required for modular state. import 'calypso/state/a8c-for-agencies/init'; +import { + A4A_PARTNER_DIRECTORY_LEAD_MATCHING_FEATURE_FLAG, + A4A_PARTNER_DIRECTORY_LEAD_MATCHING_PILOT_AGENCY_IDS, +} from 'calypso/a8c-for-agencies/sections/partner-directory/lib/lead-matching-visibility'; import { errorNotice } from 'calypso/state/notices/actions'; import { NoticeActionOptions } from 'calypso/state/notices/types'; import { APIError, Agency, AgencyThunkAction, UserBillingType } from '../types'; @@ -152,6 +156,13 @@ export function receiveAgencies( agencies: Agency[] ): AgencyThunkAction { if ( ! config.isEnabled( 'a4a-partner-directory' ) && newAgency.partner_directory.allowed ) { config.enable( 'a4a-partner-directory' ); } + + if ( + ! config.isEnabled( A4A_PARTNER_DIRECTORY_LEAD_MATCHING_FEATURE_FLAG ) && + A4A_PARTNER_DIRECTORY_LEAD_MATCHING_PILOT_AGENCY_IDS.has( newAgency.id ) + ) { + config.enable( A4A_PARTNER_DIRECTORY_LEAD_MATCHING_FEATURE_FLAG ); + } } }; } diff --git a/client/state/a8c-for-agencies/agency/test/actions.ts b/client/state/a8c-for-agencies/agency/test/actions.ts index 1e35f74dee9e..bfb9bc418742 100644 --- a/client/state/a8c-for-agencies/agency/test/actions.ts +++ b/client/state/a8c-for-agencies/agency/test/actions.ts @@ -1,11 +1,44 @@ +jest.mock( '@automattic/calypso-config', () => { + const isEnabled = jest.fn(); + const enable = jest.fn(); + + return { + __esModule: true, + default: { + isEnabled, + enable, + }, + isEnabled, + enable, + }; +} ); + +jest.mock( + 'calypso/a8c-for-agencies/sections/partner-directory/lib/lead-matching-visibility', + () => ( { + A4A_PARTNER_DIRECTORY_LEAD_MATCHING_FEATURE_FLAG: 'a4a-partner-directory-lead-matching', + A4A_PARTNER_DIRECTORY_LEAD_MATCHING_PILOT_AGENCY_IDS: new Set( [ + 232667176, 251102500, 234036126, 234278359, 232640028, + ] ), + } ) +); + +import config from '@automattic/calypso-config'; +import { A4A_PARTNER_DIRECTORY_LEAD_MATCHING_FEATURE_FLAG } from 'calypso/a8c-for-agencies/sections/partner-directory/lib/lead-matching-visibility'; import { JETPACK_CURRENT_AGENCY_UPDATE } from '../action-types'; -import { updateActiveAgencyAvailability, updateActiveAgencyLeadMatching } from '../actions'; +import { + receiveAgencies, + updateActiveAgencyAvailability, + updateActiveAgencyLeadMatching, +} from '../actions'; import type { A4AStore, Agency } from '../../types'; import type { AgencyLeadMatchingProfile, LeadMatchingDetails, } from 'calypso/a8c-for-agencies/sections/partner-directory/types'; +const mockedConfig = config as jest.Mocked< typeof config >; + const createLeadMatchingDraft = ( overrides: Partial< LeadMatchingDetails > = {} ): LeadMatchingDetails => ( { @@ -179,6 +212,12 @@ const isCurrentAgencyUpdateAction = ( action: unknown ): action is CurrentAgency 'activeAgency' in action; describe( 'a8c-for-agencies agency actions', () => { + beforeEach( () => { + mockedConfig.isEnabled.mockReset(); + mockedConfig.enable.mockReset(); + mockedConfig.isEnabled.mockReturnValue( false ); + } ); + describe( '#updateActiveAgencyLeadMatching()', () => { test( 'merges draft updates against the latest active agency state', () => { let state = createState( @@ -299,4 +338,54 @@ describe( 'a8c-for-agencies agency actions', () => { ).toBe( false ); } ); } ); + + describe( '#receiveAgencies()', () => { + test( 'enables the lead matching feature flag for pilot agencies', () => { + let state = createState( createAgency() ); + const getState = () => state; + const dispatch: jest.Mock = jest.fn( ( actionOrThunk: unknown ) => { + if ( typeof actionOrThunk === 'function' ) { + return actionOrThunk( dispatch, getState, undefined ); + } + + if ( isCurrentAgencyUpdateAction( actionOrThunk ) ) { + state = { + ...state, + a8cForAgencies: { + ...state.a8cForAgencies, + agencies: { + ...state.a8cForAgencies.agencies, + activeAgency: actionOrThunk.activeAgency, + }, + }, + }; + } + + return actionOrThunk; + } ); + + receiveAgencies( [ createAgency( { id: 232667176 } ) ] )( dispatch, getState, undefined ); + + expect( mockedConfig.enable ).toHaveBeenCalledWith( + A4A_PARTNER_DIRECTORY_LEAD_MATCHING_FEATURE_FLAG + ); + } ); + + test( 'does not enable the lead matching feature flag for non-pilot agencies', () => { + const getState = () => createState( createAgency() ); + const dispatch: jest.Mock = jest.fn( ( actionOrThunk: unknown ) => { + if ( typeof actionOrThunk === 'function' ) { + return actionOrThunk( dispatch, getState, undefined ); + } + + return actionOrThunk; + } ); + + receiveAgencies( [ createAgency( { id: 123 } ) ] )( dispatch, getState, undefined ); + + expect( mockedConfig.enable ).not.toHaveBeenCalledWith( + A4A_PARTNER_DIRECTORY_LEAD_MATCHING_FEATURE_FLAG + ); + } ); + } ); } );