From 649958023d0ad9b66736eba94591e5325ea3cb3d Mon Sep 17 00:00:00 2001 From: simeng-li Date: Mon, 26 Sep 2022 11:27:25 +0800 Subject: [PATCH] refactor(ui): refactor confirmModalPromisify (#1993) refactor confirmModalPromisify --- .../ui/src/components/ConfirmModal/index.tsx | 1 + .../modalPromisify}/index.test.tsx | 6 ++--- .../ConfirmModal/modalPromisify}/index.tsx | 8 +++--- .../TermsOfUseConfirmModal/index.tsx | 10 +++---- .../TermsOfUseIframeModal/index.tsx | 4 +-- .../containers/UsernameSignIn/index.test.tsx | 6 +++-- packages/ui/src/hooks/use-terms.ts | 27 +++++++------------ packages/ui/src/types/index.ts | 4 +-- packages/ui/src/utils/promisify.test.ts | 18 +++++++++++++ packages/ui/src/utils/promisify.ts | 9 +++++++ 10 files changed, 56 insertions(+), 37 deletions(-) rename packages/ui/src/{containers/TermsOfUse/termsOfUseModalPromisify => components/ConfirmModal/modalPromisify}/index.test.tsx (87%) rename packages/ui/src/{containers/TermsOfUse/termsOfUseModalPromisify => components/ConfirmModal/modalPromisify}/index.tsx (64%) create mode 100644 packages/ui/src/utils/promisify.test.ts create mode 100644 packages/ui/src/utils/promisify.ts diff --git a/packages/ui/src/components/ConfirmModal/index.tsx b/packages/ui/src/components/ConfirmModal/index.tsx index 75f58e97c..476172386 100644 --- a/packages/ui/src/components/ConfirmModal/index.tsx +++ b/packages/ui/src/components/ConfirmModal/index.tsx @@ -1,3 +1,4 @@ export { default as WebModal } from './AcModal'; export { default as MobileModal } from './MobileModal'; export { default as IframeModal } from './IframeConfirmModal'; +export { modalPromisify } from './modalPromisify'; diff --git a/packages/ui/src/containers/TermsOfUse/termsOfUseModalPromisify/index.test.tsx b/packages/ui/src/components/ConfirmModal/modalPromisify/index.test.tsx similarity index 87% rename from packages/ui/src/containers/TermsOfUse/termsOfUseModalPromisify/index.test.tsx rename to packages/ui/src/components/ConfirmModal/modalPromisify/index.test.tsx index 5adf6b5b0..f2bfcd54e 100644 --- a/packages/ui/src/containers/TermsOfUse/termsOfUseModalPromisify/index.test.tsx +++ b/packages/ui/src/components/ConfirmModal/modalPromisify/index.test.tsx @@ -1,15 +1,15 @@ import { fireEvent } from '@testing-library/react'; import renderWithPageContext from '@/__mocks__/RenderWithPageContext'; +import TermsOfUseConfirmModal from '@/containers/TermsOfUse/TermsOfUseConfirmModal'; import { modalPromisify } from '.'; -import TermsOfUseConfirmModal from '../TermsOfUseConfirmModal'; describe('modalPromisify', () => { const onResolve = jest.fn(); const onReject = jest.fn(); - it('render properly', () => { + it('resolve properly', () => { const PromisifyModal = modalPromisify(TermsOfUseConfirmModal); const { getByText } = renderWithPageContext( @@ -22,7 +22,7 @@ describe('modalPromisify', () => { expect(onResolve).toBeCalled(); }); - it('reject with message', () => { + it('reject', () => { const PromisifyModal = modalPromisify(TermsOfUseConfirmModal); const { getByText } = renderWithPageContext( diff --git a/packages/ui/src/containers/TermsOfUse/termsOfUseModalPromisify/index.tsx b/packages/ui/src/components/ConfirmModal/modalPromisify/index.tsx similarity index 64% rename from packages/ui/src/containers/TermsOfUse/termsOfUseModalPromisify/index.tsx rename to packages/ui/src/components/ConfirmModal/modalPromisify/index.tsx index 5db7207a5..8866433de 100644 --- a/packages/ui/src/containers/TermsOfUse/termsOfUseModalPromisify/index.tsx +++ b/packages/ui/src/components/ConfirmModal/modalPromisify/index.tsx @@ -1,11 +1,11 @@ import { InstanceProps } from 'react-modal-promise'; -import { TermsOfUseModalMessage } from '@/types'; +import { ConfirmModalMessage } from '@/types'; type Props = { isOpen?: boolean; onConfirm: () => void; - onClose: (message?: TermsOfUseModalMessage) => void; + onClose: (message?: ConfirmModalMessage) => void; }; export const modalPromisify = @@ -14,14 +14,14 @@ export const modalPromisify = isOpen, onResolve, onReject, - }: Omit, 'open' | 'close'>) => { + }: Omit, 'open' | 'close'>) => { return ( { onResolve(true); }} - onClose={(message?: TermsOfUseModalMessage) => { + onClose={(message?: ConfirmModalMessage) => { onReject(message ?? false); }} /> diff --git a/packages/ui/src/containers/TermsOfUse/TermsOfUseConfirmModal/index.tsx b/packages/ui/src/containers/TermsOfUse/TermsOfUseConfirmModal/index.tsx index 6a561cd23..a3293f277 100644 --- a/packages/ui/src/containers/TermsOfUse/TermsOfUseConfirmModal/index.tsx +++ b/packages/ui/src/containers/TermsOfUse/TermsOfUseConfirmModal/index.tsx @@ -2,13 +2,11 @@ import { useContext } from 'react'; import { useTranslation, Trans } from 'react-i18next'; import { create } from 'react-modal-promise'; -import { WebModal, MobileModal } from '@/components/ConfirmModal'; +import { WebModal, MobileModal, modalPromisify } from '@/components/ConfirmModal'; import TextLink from '@/components/TextLink'; import { PageContext } from '@/hooks/use-page-context'; import usePlatform from '@/hooks/use-platform'; -import { TermsOfUseModalMessage } from '@/types'; - -import { modalPromisify } from '../termsOfUseModalPromisify'; +import { ConfirmModalMessage } from '@/types'; /** * For web use only confirm modal, does not contain Terms iframe @@ -17,7 +15,7 @@ import { modalPromisify } from '../termsOfUseModalPromisify'; type Props = { isOpen?: boolean; onConfirm: () => void; - onClose: (message?: TermsOfUseModalMessage) => void; + onClose: (message?: ConfirmModalMessage) => void; }; const TermsOfUseConfirmModal = ({ isOpen = false, onConfirm, onClose }: Props) => { @@ -33,7 +31,7 @@ const TermsOfUseConfirmModal = ({ isOpen = false, onConfirm, onClose }: Props) = const linkProps = isMobile ? { onClick: () => { - onClose(TermsOfUseModalMessage.SHOW_DETAIL_MODAL); + onClose(ConfirmModalMessage.SHOW_TERMS_DETAIL_MODAL); }, } : { diff --git a/packages/ui/src/containers/TermsOfUse/TermsOfUseIframeModal/index.tsx b/packages/ui/src/containers/TermsOfUse/TermsOfUseIframeModal/index.tsx index 39891f713..f66068131 100644 --- a/packages/ui/src/containers/TermsOfUse/TermsOfUseIframeModal/index.tsx +++ b/packages/ui/src/containers/TermsOfUse/TermsOfUseIframeModal/index.tsx @@ -1,11 +1,9 @@ import { useContext } from 'react'; import { create } from 'react-modal-promise'; -import { IframeModal } from '@/components/ConfirmModal'; +import { IframeModal, modalPromisify } from '@/components/ConfirmModal'; import { PageContext } from '@/hooks/use-page-context'; -import { modalPromisify } from '../termsOfUseModalPromisify'; - /** * For mobile use only, includes embedded Terms iframe */ diff --git a/packages/ui/src/containers/UsernameSignIn/index.test.tsx b/packages/ui/src/containers/UsernameSignIn/index.test.tsx index f027d6d06..eb5d152db 100644 --- a/packages/ui/src/containers/UsernameSignIn/index.test.tsx +++ b/packages/ui/src/containers/UsernameSignIn/index.test.tsx @@ -6,7 +6,7 @@ import SettingsProvider from '@/__mocks__/RenderWithPageContext/SettingsProvider import { signInBasic } from '@/apis/sign-in'; import { termsOfUseConfirmModalPromise } from '@/containers/TermsOfUse/TermsOfUseConfirmModal'; import { termsOfUseIframeModalPromise } from '@/containers/TermsOfUse/TermsOfUseIframeModal'; -import { TermsOfUseModalMessage } from '@/types'; +import { ConfirmModalMessage } from '@/types'; import UsernameSignIn from '.'; @@ -98,7 +98,9 @@ describe('', () => { }); test('should show terms detail modal', async () => { - termsOfUseConfirmModalPromiseMock.mockRejectedValue(TermsOfUseModalMessage.SHOW_DETAIL_MODAL); + termsOfUseConfirmModalPromiseMock.mockRejectedValue( + ConfirmModalMessage.SHOW_TERMS_DETAIL_MODAL + ); const { getByText, container } = renderWithPageContext( diff --git a/packages/ui/src/hooks/use-terms.ts b/packages/ui/src/hooks/use-terms.ts index fbfbbfb34..357a9efef 100644 --- a/packages/ui/src/hooks/use-terms.ts +++ b/packages/ui/src/hooks/use-terms.ts @@ -2,7 +2,8 @@ import { useContext, useCallback } from 'react'; import { termsOfUseConfirmModalPromise } from '@/containers/TermsOfUse/TermsOfUseConfirmModal'; import { termsOfUseIframeModalPromise } from '@/containers/TermsOfUse/TermsOfUseIframeModal'; -import { TermsOfUseModalMessage } from '@/types'; +import { ConfirmModalMessage } from '@/types'; +import { flattenPromiseResult } from '@/utils/promisify'; import { PageContext } from './use-page-context'; @@ -12,29 +13,21 @@ const useTerms = () => { const { termsOfUse } = experienceSettings ?? {}; const termsOfUseIframeModalHandler = useCallback(async () => { - try { - await termsOfUseIframeModalPromise(); + const [result] = await flattenPromiseResult(termsOfUseIframeModalPromise()); - return true; - } catch { - return false; - } + return Boolean(result); }, []); const termsOfUseConfirmModalHandler = useCallback(async () => { - try { - await termsOfUseConfirmModalPromise(); + const [result, error] = await flattenPromiseResult(termsOfUseConfirmModalPromise()); - return true; - } catch (error: unknown) { - if (error === TermsOfUseModalMessage.SHOW_DETAIL_MODAL) { - const result = await termsOfUseIframeModalHandler(); + if (error === ConfirmModalMessage.SHOW_TERMS_DETAIL_MODAL) { + const result = await termsOfUseIframeModalHandler(); - return result; - } - - return false; + return result; } + + return Boolean(result); }, [termsOfUseIframeModalHandler]); const termsValidation = useCallback(async () => { diff --git a/packages/ui/src/types/index.ts b/packages/ui/src/types/index.ts index 1984f8f88..d2c5592aa 100644 --- a/packages/ui/src/types/index.ts +++ b/packages/ui/src/types/index.ts @@ -28,8 +28,8 @@ export type SignInExperienceSettings = Omit< secondarySignInMethods: SignInMethod[]; }; -export enum TermsOfUseModalMessage { - SHOW_DETAIL_MODAL = 'SHOW_DETAIL_MODAL', +export enum ConfirmModalMessage { + SHOW_TERMS_DETAIL_MODAL = 'SHOW_TERMS_DETAIL_MODAL', } export type PreviewConfig = { diff --git a/packages/ui/src/utils/promisify.test.ts b/packages/ui/src/utils/promisify.test.ts new file mode 100644 index 000000000..331ef074d --- /dev/null +++ b/packages/ui/src/utils/promisify.test.ts @@ -0,0 +1,18 @@ +import { flattenPromiseResult } from './promisify'; + +describe('promisify', () => { + test('flattenPromiseResult', async () => { + const promiseResolve = Promise.resolve('resolved'); + const [result, rejection] = await flattenPromiseResult(promiseResolve); + + expect(result).toBe('resolved'); + expect(rejection).toBeUndefined(); + + // eslint-disable-next-line prefer-promise-reject-errors + const promiseRejection = Promise.reject('rejected'); + const [_result, _rejection] = await flattenPromiseResult(promiseRejection); + + expect(_result).toBeUndefined(); + expect(_rejection).toBe('rejected'); + }); +}); diff --git a/packages/ui/src/utils/promisify.ts b/packages/ui/src/utils/promisify.ts new file mode 100644 index 000000000..174249ae4 --- /dev/null +++ b/packages/ui/src/utils/promisify.ts @@ -0,0 +1,9 @@ +export const flattenPromiseResult = async (promise: Promise): Promise<[T?, unknown?]> => { + try { + const result = await promise; + + return [result]; + } catch (error: unknown) { + return [undefined, error]; + } +};