Skip to content

Commit 45437aa

Browse files
committed
add tests
1 parent 9e330d2 commit 45437aa

File tree

1 file changed

+123
-2
lines changed

1 file changed

+123
-2
lines changed

packages/clerk-js/src/ui/elements/__tests__/SocialButtons.test.tsx

Lines changed: 123 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
// packages/clerk-js/src/ui/elements/__tests__/SocialButtons.test.tsx
2-
import { render, screen } from '@testing-library/react';
2+
import { render, renderHook, screen } from '@testing-library/react';
33
import { describe, expect, it, vi } from 'vitest';
44

55
import { bindCreateFixtures } from '@/test/utils';
66
import { CardStateProvider } from '@/ui/elements/contexts';
7+
import { useTotalEnabledAuthMethods } from '@/ui/hooks/useTotalEnabledAuthMethods';
78

89
import { SocialButtons } from '../SocialButtons';
910

@@ -117,9 +118,101 @@ describe('SocialButtons', () => {
117118
});
118119

119120
describe('With last authentication strategy', () => {
120-
it('should show "Continue with" prefix for single strategy', async () => {
121+
it('should NOT show "Last used" badge when only one total auth method exists (single social provider, no email/username)', async () => {
122+
const { wrapper, fixtures } = await createFixtures(f => {
123+
f.withSocialProvider({ provider: 'google' });
124+
// Explicitly disable email and username to ensure only one auth method
125+
// Note: By default fixtures have these disabled, but we set them explicitly to be sure
126+
f.withEmailAddress({ enabled: false, used_for_first_factor: false });
127+
f.withUsername({ enabled: false, used_for_first_factor: false });
128+
});
129+
130+
// Verify that email and username are disabled
131+
const enabledIdentifiers = fixtures.environment.userSettings.enabledFirstFactorIdentifiers;
132+
expect(enabledIdentifiers).not.toContain('email_address');
133+
expect(enabledIdentifiers).not.toContain('username');
134+
// Verify only one social provider is enabled
135+
expect(fixtures.environment.userSettings.authenticatableSocialStrategies).toHaveLength(1);
136+
137+
// Verify the total count is actually 1 using the hook
138+
const { result } = renderHook(() => useTotalEnabledAuthMethods(), { wrapper });
139+
expect(result.current.totalCount).toBe(1);
140+
141+
fixtures.clerk.client.lastAuthenticationStrategy = 'oauth_google';
142+
143+
render(
144+
<CardStateProvider>
145+
<SocialButtons
146+
{...defaultProps}
147+
showLastAuthenticationStrategy
148+
/>
149+
</CardStateProvider>,
150+
{ wrapper },
151+
);
152+
153+
const button = screen.getByRole('button', { name: /google/i });
154+
expect(button).toHaveTextContent('Continue with Google');
155+
expect(button).not.toHaveTextContent('Last used');
156+
expect(screen.queryByText('Last used')).not.toBeInTheDocument();
157+
});
158+
159+
it('should show "Last used" badge when email is enabled even with single social provider', async () => {
160+
const { wrapper, fixtures } = await createFixtures(f => {
161+
f.withSocialProvider({ provider: 'google' });
162+
f.withEmailAddress({ enabled: true, used_for_first_factor: true });
163+
f.withUsername({ enabled: false, used_for_first_factor: false });
164+
});
165+
166+
// Verify the total count is 2 (email + google)
167+
const { result } = renderHook(() => useTotalEnabledAuthMethods(), { wrapper });
168+
expect(result.current.totalCount).toBe(2);
169+
170+
fixtures.clerk.client.lastAuthenticationStrategy = 'oauth_google';
171+
172+
render(
173+
<CardStateProvider>
174+
<SocialButtons
175+
{...defaultProps}
176+
showLastAuthenticationStrategy
177+
/>
178+
</CardStateProvider>,
179+
{ wrapper },
180+
);
181+
182+
const button = screen.getByRole('button', { name: /google/i });
183+
expect(button).toHaveTextContent('Continue with Google');
184+
expect(button).toHaveTextContent('Last used');
185+
expect(screen.getByText('Last used')).toBeInTheDocument();
186+
});
187+
188+
it('should show "Last used" badge when only one social provider but email/username is also enabled', async () => {
121189
const { wrapper, fixtures } = await createFixtures(f => {
122190
f.withSocialProvider({ provider: 'google' });
191+
f.withEmailAddress({ enabled: true, used_for_first_factor: true });
192+
});
193+
194+
fixtures.clerk.client.lastAuthenticationStrategy = 'oauth_google';
195+
196+
render(
197+
<CardStateProvider>
198+
<SocialButtons
199+
{...defaultProps}
200+
showLastAuthenticationStrategy
201+
/>
202+
</CardStateProvider>,
203+
{ wrapper },
204+
);
205+
206+
const button = screen.getByRole('button', { name: /google/i });
207+
expect(button).toHaveTextContent('Continue with Google');
208+
expect(button).toHaveTextContent('Last used');
209+
expect(screen.getByText('Last used')).toBeInTheDocument();
210+
});
211+
212+
it('should show "Continue with" prefix for single strategy when multiple auth methods exist', async () => {
213+
const { wrapper, fixtures } = await createFixtures(f => {
214+
f.withSocialProvider({ provider: 'google' });
215+
f.withEmailAddress({ enabled: true, used_for_first_factor: true });
123216
});
124217

125218
fixtures.clerk.client.lastAuthenticationStrategy = 'oauth_google';
@@ -217,6 +310,7 @@ describe('SocialButtons', () => {
217310
it('should handle SAML strategies converted to OAuth', async () => {
218311
const { wrapper, fixtures } = await createFixtures(f => {
219312
f.withSocialProvider({ provider: 'google' });
313+
f.withEmailAddress({ enabled: true, used_for_first_factor: true });
220314
});
221315

222316
// SAML strategy should be converted to OAuth
@@ -235,5 +329,32 @@ describe('SocialButtons', () => {
235329
const googleButton = screen.getByRole('button', { name: /google/i });
236330
expect(googleButton).toHaveTextContent('Continue with Google');
237331
});
332+
333+
it('should NOT show "Last used" badge when only one total auth method exists (single social provider, no email/username, SAML)', async () => {
334+
const { wrapper, fixtures } = await createFixtures(f => {
335+
f.withSocialProvider({ provider: 'google' });
336+
// Disable email and username to ensure only one auth method
337+
f.withEmailAddress({ enabled: false, used_for_first_factor: false });
338+
f.withUsername({ enabled: false, used_for_first_factor: false });
339+
});
340+
341+
// SAML strategy should be converted to OAuth but badge should not show
342+
fixtures.clerk.client.lastAuthenticationStrategy = 'saml_google' as any;
343+
344+
render(
345+
<CardStateProvider>
346+
<SocialButtons
347+
{...defaultProps}
348+
showLastAuthenticationStrategy
349+
/>
350+
</CardStateProvider>,
351+
{ wrapper },
352+
);
353+
354+
const googleButton = screen.getByRole('button', { name: /google/i });
355+
expect(googleButton).toHaveTextContent('Continue with Google');
356+
expect(googleButton).not.toHaveTextContent('Last used');
357+
expect(screen.queryByText('Last used')).not.toBeInTheDocument();
358+
});
238359
});
239360
});

0 commit comments

Comments
 (0)