Skip to content

Commit aa8300b

Browse files
authored
feat(contractor-onboarding) - show eor card when only cm is available (#766)
* feat(contractor-onboarding) - show eor card when only cm is available * simplify * format
1 parent d3332fd commit aa8300b

3 files changed

Lines changed: 96 additions & 4 deletions

File tree

src/common/api/fixtures/contractors-subscriptions.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,3 +253,57 @@ export const mockCOROnlyResponse = {
253253
},
254254
],
255255
};
256+
257+
export const mockCMOnlyResponse = {
258+
data: [
259+
{
260+
product: {
261+
active: true,
262+
name: 'Monthly Contractor Subscription',
263+
description: 'Engage and pay contractors compliantly',
264+
features: [
265+
'Localized contract templates',
266+
'Only pay for active contractors',
267+
'Work with contractors in 200+ countries and jurisdictions',
268+
'AI-powered features to reduce misclassification risks',
269+
],
270+
identifier:
271+
'urn:remotecom:resource:product:contractor:standard:monthly',
272+
slug: '8af901a0-25d7-4989-8105-dbd939cc4c82',
273+
inserted_at: '2025-06-10',
274+
short_name: 'CM',
275+
frequency: 'monthly',
276+
tier: 'standard',
277+
employment_type: 'contractor',
278+
},
279+
currency: {
280+
code: 'USD',
281+
name: 'United States Dollar',
282+
symbol: '$',
283+
slug: '1b2c181d-24c9-44ff-a8e1-2a7025ca491c',
284+
},
285+
price: {
286+
amount: 2900,
287+
final_amount: 2900,
288+
},
289+
total_amount: 0,
290+
company_product: {
291+
slug: '20278d56-b4cf-43f0-80a4-725b53f9e4ff',
292+
},
293+
company_product_discount: {
294+
percent: '0.000000',
295+
expiration_date: null,
296+
},
297+
free_trial: {
298+
status: 'ineligible',
299+
start_date: null,
300+
end_date: null,
301+
},
302+
active_contractors_count: 0,
303+
billable_contractors: [],
304+
billable_contractors_count: 0,
305+
next_invoice_date: '2026-04-01',
306+
summary_period: '2026-03',
307+
},
308+
],
309+
};

src/flows/ContractorOnboarding/api.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -391,9 +391,7 @@ export const useContractorSubscriptionSchemaField = (
391391

392392
const isEmptyContractorSubscriptions = contractorSubscriptions?.length === 0;
393393

394-
const isOnlyCORSubscription =
395-
contractorSubscriptions?.length === 1 &&
396-
contractorSubscriptions[0].product.short_name === 'COR';
394+
const isSingleSubscription = contractorSubscriptions?.length === 1;
397395

398396
const corSubscription = contractorSubscriptions?.find(
399397
(subscription) => subscription.product.short_name === 'COR',
@@ -403,7 +401,7 @@ export const useContractorSubscriptionSchemaField = (
403401
corSubscription?.eligibility_questionnaire?.is_blocking;
404402

405403
const showEorSubscription =
406-
(isOnlyCORSubscription ||
404+
(isSingleSubscription ||
407405
isEligibilityQuestionnaireBlocked === true ||
408406
isEmptyContractorSubscriptions) &&
409407
selectedCountry?.eor_onboarding;

src/flows/ContractorOnboarding/tests/ContractorOnboarding.test.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
mockContractorSubscriptionWithBlockedEligibilityResponse,
4545
mockContractorSubscriptionWithEligibilityResponse,
4646
mockCOROnlyResponse,
47+
mockCMOnlyResponse,
4748
} from '@/src/common/api/fixtures/contractors-subscriptions';
4849
import { mockBlockedEligibilityQuestionnaireResponse } from '@/src/common/api/fixtures/eligibility-questionnaire';
4950

@@ -2327,6 +2328,45 @@ describe('ContractorOnboardingFlow', () => {
23272328
});
23282329
});
23292330

2331+
it('should show Employer of Record option when only CM subscription is available', async () => {
2332+
server.use(
2333+
http.get(
2334+
'*/v1/contractors/employments/*/contractor-subscriptions',
2335+
() => {
2336+
return HttpResponse.json(mockCMOnlyResponse);
2337+
},
2338+
),
2339+
);
2340+
2341+
mockRender.mockImplementation(
2342+
createMockRenderImplementation(MultiStepFormWithoutCountry),
2343+
);
2344+
2345+
render(
2346+
<ContractorOnboardingFlow
2347+
{...defaultProps}
2348+
countryCode='PRT'
2349+
skipSteps={['select_country']}
2350+
/>,
2351+
{ wrapper: TestProviders },
2352+
);
2353+
2354+
await screen.findByText(/Step: Basic Information/i);
2355+
await fillBasicInformation();
2356+
2357+
const nextButton = screen.getByText(/Next Step/i);
2358+
nextButton.click();
2359+
2360+
await screen.findByText(/Step: Pricing Plan/i);
2361+
2362+
await waitFor(() => {
2363+
const eorOption = screen.getByRole('radio', {
2364+
name: /Employer of Record/i,
2365+
});
2366+
expect(eorOption).toBeInTheDocument();
2367+
});
2368+
});
2369+
23302370
it('should NOT show Employer of Record option when eor_onboarding is false', async () => {
23312371
server.use(
23322372
http.get('*/v1/countries', () => {

0 commit comments

Comments
 (0)