Skip to content

Commit

Permalink
feat(clerk-js): Introduce with userSettings in UserProfile
Browse files Browse the repository at this point in the history
chore(clerk-js): Change code formatting when destructuring userSettings

fix(clerk-js): Fix showRemovePassword condition in ChangePassword component

fix(clerk-js): Use user_Settings web_wallet attribute to get info about the user's web3 wallet
  • Loading branch information
npetridis authored and nikosdouvlis committed Feb 14, 2022
1 parent d9c8357 commit 62dff26
Show file tree
Hide file tree
Showing 14 changed files with 497 additions and 81 deletions.
59 changes: 49 additions & 10 deletions packages/clerk-js/src/ui/userProfile/UserProfile.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,26 @@ import {
} from '@clerk/types';
import { AuthConfig } from 'core/resources/AuthConfig';
import { ExternalAccount } from 'core/resources/ExternalAccount';
import { UserSettings } from 'core/resources/UserSettings';
import React from 'react';
import ReactDOM from 'react-dom';

import { UserProfile } from './UserProfile';

const mockNavigate = jest.fn();
const mockUseCoreSignIn = jest.fn(
() =>
({
() => (
{
status: null,
} as SignInResource),
} as SignInResource
),
);
const mockUseCoreSignUp = jest.fn(
() =>
({
() => (
{
status: null,
} as SignUpResource),
} as SignUpResource
),
);

const mockUseCoreSessionList = jest.fn(() => [] as SessionResource[]);
Expand Down Expand Up @@ -66,11 +69,47 @@ jest.mock('ui/contexts', () => ({
},
},
},
userSettings: {
attributes: {
phone_number: {
// this should be true since it is a first factor but keeping it false for the needs of the test case
enabled: false,
used_for_second_factor: true,
second_factors: ['phone_code']
},
email_address: {
// this should be true since it is a first factor but keeping it false for the needs of the test case
enabled: false,
used_for_first_factor: true,
first_factors: ['email_code']
},
first_name: {
enabled: true,
},
last_name: {
enabled: false,
},
username: {
enabled: false,
},
password: {
enabled: false,
},
web3_wallet: {
enabled: false
}
},
social: {
oauth_google: {
enabled: true,
},
oauth_facebook: {
enabled: true,
}
}
} as Partial<UserSettings>,
authConfig: {
secondFactors: ['phone_code'],
singleSessionMode: true,
firstFactors: ['email_address', 'oauth_google', 'oauth_facebook'],
emailAddressVerificationStrategies: ['email_code'],
singleSessionMode: true
} as Partial<AuthConfig>,
})),
withCoreUserGuard: (a: any) => a,
Expand Down
61 changes: 50 additions & 11 deletions packages/clerk-js/src/ui/userProfile/account/Account.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { render, screen } from '@clerk/shared/testUtils';
import type { AuthConfigResource, UserResource } from '@clerk/types';
import type { UserResource, UserSettingsResource } from '@clerk/types';
import React from 'react';

import { Account } from './Account';
Expand All @@ -26,6 +26,21 @@ jest.mock('ui/hooks', () => {
};
});

const OTHER_ATTRIBUTES = {
username: {
enabled: false,
},
email_address: {
enabled: false
},
phone_number: {
enabled: false
},
web3_wallet: {
enabled: false
}
};

describe('<Account/>', () => {
afterEach(() => {
jest.clearAllMocks();
Expand All @@ -34,9 +49,18 @@ describe('<Account/>', () => {
it('renders personal information for auth config that requires name', () => {
mockEnvironment.mockImplementation(() => {
return {
authConfig: {
firstName: 'required',
} as AuthConfigResource,
userSettings: {
attributes: {
first_name: {
enabled: true,
required: true
},
last_name: {
enabled: false
},
...OTHER_ATTRIBUTES
}
} as UserSettingsResource,
};
});
render(<Account />);
Expand All @@ -46,9 +70,17 @@ describe('<Account/>', () => {
it('renders personal information for auth config that has name turned on', () => {
mockEnvironment.mockImplementation(() => {
return {
authConfig: {
lastName: 'on',
} as AuthConfigResource,
userSettings: {
attributes: {
last_name: {
enabled: true,
},
first_name: {
enabled: false,
},
...OTHER_ATTRIBUTES
}
} as UserSettingsResource
};
});
render(<Account />);
Expand All @@ -58,10 +90,17 @@ describe('<Account/>', () => {
it('does not render personal information for auth config that has named turned off', () => {
mockEnvironment.mockImplementation(() => {
return {
authConfig: {
firstName: 'off',
lastName: 'off',
} as AuthConfigResource,
userSettings: {
attributes: {
first_name: {
enabled: false,
},
last_name: {
enabled: false,
},
...OTHER_ATTRIBUTES
}
} as UserSettingsResource
};
});
render(<Account />);
Expand Down
11 changes: 6 additions & 5 deletions packages/clerk-js/src/ui/userProfile/account/Account.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { AuthConfigResource } from '@clerk/types';
import type { UserSettingsResource } from '@clerk/types';
import React from 'react';
import { useEnvironment } from 'ui/contexts';
import { PersonalInformationCard } from 'ui/userProfile/account/personalInformation';
import { ProfileCard } from 'ui/userProfile/account/profileCard';
import { PageHeading } from 'ui/userProfile/pageHeading';

export const Account = (): JSX.Element => {
const { authConfig } = useEnvironment();
const { userSettings } = useEnvironment();

return (
<>
Expand All @@ -15,13 +15,14 @@ export const Account = (): JSX.Element => {
subtitle='Manage settings related to your account'
/>
<ProfileCard />
{shouldShowPersonalInformation(authConfig) && <PersonalInformationCard />}
{shouldShowPersonalInformation(userSettings) && <PersonalInformationCard />}
</>
);
};

function shouldShowPersonalInformation(
authConfig: AuthConfigResource,
userSettings: UserSettingsResource,
): boolean {
return authConfig.firstName !== 'off' || authConfig.lastName !== 'off';
const { attributes: { first_name, last_name } } = userSettings;
return first_name.enabled || last_name.enabled;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { renderJSON } from '@clerk/shared/testUtils';
import { EmailAddressResource, UserResource } from '@clerk/types';
import * as React from 'react';
import { PartialDeep } from 'type-fest';
import {
useEnvironment
} from 'ui/contexts';

import { ProfileCard } from './ProfileCard';

Expand All @@ -12,15 +16,8 @@ jest.mock('ui/hooks', () => {

jest.mock('ui/contexts', () => {
return {
useEnvironment: () => ({
authConfig: {
emailAddress: 'required',
phoneNumber: 'on',
username: 'off',
},
displayConfig: {},
}),
useCoreUser: (): Partial<UserResource> => {
useEnvironment: jest.fn(),
useCoreUser: (): PartialDeep<UserResource> => {
return {
isPrimaryIdentification: jest.fn(() => true),
emailAddresses: [
Expand All @@ -37,15 +34,65 @@ jest.mock('ui/contexts', () => {
],
phoneNumbers: [],
externalAccounts: [],
web3Wallets: [{ web3Wallet: '0x123456789' }]
};
},
useCoreClerk: jest.fn(),
};
});

(useEnvironment as jest.Mock).mockImplementation(() => ({
displayConfig: {},
userSettings: {
attributes: {
email_address: {
enabled: true
},
phone_number: {
enabled: true
},
username: {
enabled: false
},
web3_wallet: {
enabled: false
}
}
}
}));

describe('<ProfileCard/>', () => {
afterEach(() => {
jest.clearAllMocks();
});

it('renders the ProfileCard', () => {
const tree = renderJSON(<ProfileCard />);
expect(tree).toMatchSnapshot();
});

it('renders the ProfileCard ', () => {
(useEnvironment as jest.Mock).mockImplementation(() => ({
displayConfig: {},
userSettings: {
attributes: {
email_address: {
enabled: true
},
phone_number: {
enabled: true
},
username: {
enabled: false
},
web3_wallet: {
enabled: true
}
}
}
}));

const tree = renderJSON(<ProfileCard />);
expect(tree).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,9 @@ function getWeb3WalletAddress(user: UserResource): string {
return '';
}

function checkIfSectionIsOn(section: string) {
return section === 'on' || section === 'required';
}

export function ProfileCard(): JSX.Element {
const { authConfig } = useEnvironment();
const { userSettings } = useEnvironment();
const { attributes } = userSettings;
const user = useCoreUser();
const { navigate } = useNavigate();
const web3Wallet = getWeb3WalletAddress(user);
Expand Down Expand Up @@ -100,10 +97,10 @@ export function ProfileCard(): JSX.Element {
</List.Item>
);

const showWebWallet = !!web3Wallet;
const showUsername = checkIfSectionIsOn(authConfig.username);
const showEmail = checkIfSectionIsOn(authConfig.emailAddress);
const showPhone = checkIfSectionIsOn(authConfig.phoneNumber);
const showWebWallet = attributes.web3_wallet.enabled;
const showUsername = attributes.username.enabled;
const showEmail = attributes.email_address.enabled;
const showPhone = attributes.phone_number.enabled;

return (
<TitledCard
Expand Down
Loading

0 comments on commit 62dff26

Please sign in to comment.