From b26fd00a4086ac03761fe47decd899a040cd0c47 Mon Sep 17 00:00:00 2001 From: martmull Date: Thu, 13 Jun 2024 11:47:00 +0200 Subject: [PATCH] 5663 i should be able to accept an invite even if i have an inactive workspace (#5839) - make invitation and reset password available on every page - add a sleep after setKeyPair as tokens are sometimes not updated when redirecting to Index - refactor sleep --- ...sePageChangeEffectNavigateLocation.test.ts | 28 +++++++-------- .../usePageChangeEffectNavigateLocation.ts | 8 +++-- .../__stories__/CommandMenu.stories.tsx | 2 +- .../__tests__/useExportTableData.test.ts | 14 -------- .../options/hooks/useExportTableData.ts | 4 +-- .../SingleEntitySelect.stories.tsx | 2 +- .../spreadsheet-import/tests/mockRsiValues.ts | 25 +++++-------- .../__stories__/IconPicker.stories.tsx | 2 +- .../hooks/useWorkspaceSwitching.ts | 2 ++ .../twenty-front/src/pages/auth/Invite.tsx | 1 - .../__stories__/ImpersonateEffect.stories.tsx | 2 +- .../__stories__/ChooseYourPlan.stories.tsx | 2 +- .../__stories__/SettingsBilling.stories.tsx | 2 +- .../SettingsWorkspaceMembers.stories.tsx | 2 +- .../SettingsAccountsCalendars.stories.tsx | 2 +- ...tingsAccountsCalendarsSettings.stories.tsx | 2 +- .../SettingsObjectDetail.stories.tsx | 2 +- .../SettingsObjectEdit.stories.tsx | 2 +- .../__stories__/SettingsObjects.stories.tsx | 2 +- .../SettingsDevelopers.stories.tsx | 2 +- .../SettingsIntegrationDatabase.stories.tsx | 2 +- ...egrationEditDatabaseConnection.stories.tsx | 2 +- ...tegrationNewDatabaseConnection.stories.tsx | 2 +- ...egrationShowDatabaseConnection.stories.tsx | 2 +- .../SettingsIntegrations.stories.tsx | 2 +- .../pages/tasks/__stories__/Tasks.stories.tsx | 2 +- .../components/ProfilingQueueEffect.tsx | 3 +- packages/twenty-front/src/testing/sleep.ts | 4 --- .../src/utils/__tests__/sleep.test.ts | 35 +++++++++++++++++++ packages/twenty-front/src/utils/sleep.ts | 8 +++++ 30 files changed, 95 insertions(+), 75 deletions(-) delete mode 100644 packages/twenty-front/src/testing/sleep.ts create mode 100644 packages/twenty-front/src/utils/__tests__/sleep.test.ts create mode 100644 packages/twenty-front/src/utils/sleep.ts diff --git a/packages/twenty-front/src/hooks/__tests__/usePageChangeEffectNavigateLocation.test.ts b/packages/twenty-front/src/hooks/__tests__/usePageChangeEffectNavigateLocation.test.ts index fff2fa65e..cf9a7730c 100644 --- a/packages/twenty-front/src/hooks/__tests__/usePageChangeEffectNavigateLocation.test.ts +++ b/packages/twenty-front/src/hooks/__tests__/usePageChangeEffectNavigateLocation.test.ts @@ -52,27 +52,27 @@ const testCases = [ { loc: AppPath.SignInUp, status: OnboardingStatus.Completed, res: defaultHomePagePath }, { loc: AppPath.SignInUp, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath }, - { loc: AppPath.Invite, status: OnboardingStatus.Incomplete, res: AppPath.PlanRequired }, - { loc: AppPath.Invite, status: OnboardingStatus.Canceled, res: '/settings/billing' }, - { loc: AppPath.Invite, status: OnboardingStatus.Unpaid, res: '/settings/billing' }, + { loc: AppPath.Invite, status: OnboardingStatus.Incomplete, res: undefined }, + { loc: AppPath.Invite, status: OnboardingStatus.Canceled, res: undefined }, + { loc: AppPath.Invite, status: OnboardingStatus.Unpaid, res: undefined }, { loc: AppPath.Invite, status: OnboardingStatus.PastDue, res: undefined }, { loc: AppPath.Invite, status: OnboardingStatus.OngoingUserCreation, res: undefined }, - { loc: AppPath.Invite, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace }, - { loc: AppPath.Invite, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile }, - { loc: AppPath.Invite, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails }, - { loc: AppPath.Invite, status: OnboardingStatus.OngoingInviteTeam, res: AppPath.InviteTeam }, + { loc: AppPath.Invite, status: OnboardingStatus.OngoingWorkspaceActivation, res: undefined }, + { loc: AppPath.Invite, status: OnboardingStatus.OngoingProfileCreation, res: undefined }, + { loc: AppPath.Invite, status: OnboardingStatus.OngoingSyncEmail, res: undefined }, + { loc: AppPath.Invite, status: OnboardingStatus.OngoingInviteTeam, res: undefined }, { loc: AppPath.Invite, status: OnboardingStatus.Completed, res: undefined }, { loc: AppPath.Invite, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined }, - { loc: AppPath.ResetPassword, status: OnboardingStatus.Incomplete, res: AppPath.PlanRequired }, - { loc: AppPath.ResetPassword, status: OnboardingStatus.Canceled, res: '/settings/billing' }, - { loc: AppPath.ResetPassword, status: OnboardingStatus.Unpaid, res: '/settings/billing' }, + { loc: AppPath.ResetPassword, status: OnboardingStatus.Incomplete, res: undefined }, + { loc: AppPath.ResetPassword, status: OnboardingStatus.Canceled, res: undefined }, + { loc: AppPath.ResetPassword, status: OnboardingStatus.Unpaid, res: undefined }, { loc: AppPath.ResetPassword, status: OnboardingStatus.PastDue, res: undefined }, { loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingUserCreation, res: undefined }, - { loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace }, - { loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile }, - { loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails }, - { loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingInviteTeam, res: AppPath.InviteTeam }, + { loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingWorkspaceActivation, res: undefined }, + { loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingProfileCreation, res: undefined }, + { loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingSyncEmail, res: undefined }, + { loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingInviteTeam, res: undefined }, { loc: AppPath.ResetPassword, status: OnboardingStatus.Completed, res: undefined }, { loc: AppPath.ResetPassword, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined }, diff --git a/packages/twenty-front/src/hooks/usePageChangeEffectNavigateLocation.ts b/packages/twenty-front/src/hooks/usePageChangeEffectNavigateLocation.ts index 6ca594173..5b34f0771 100644 --- a/packages/twenty-front/src/hooks/usePageChangeEffectNavigateLocation.ts +++ b/packages/twenty-front/src/hooks/usePageChangeEffectNavigateLocation.ts @@ -29,6 +29,10 @@ export const usePageChangeEffectNavigateLocation = () => { isMatchingLocation(AppPath.PlanRequired) || isMatchingLocation(AppPath.PlanRequiredSuccess); + if (isMatchingOpenRoute) { + return; + } + if ( onboardingStatus === OnboardingStatus.OngoingUserCreation && !isMatchingOngoingUserCreationRoute @@ -89,8 +93,7 @@ export const usePageChangeEffectNavigateLocation = () => { if ( onboardingStatus === OnboardingStatus.Completed && - isMatchingOnboardingRoute && - !isMatchingOpenRoute + isMatchingOnboardingRoute ) { return defaultHomePagePath; } @@ -98,7 +101,6 @@ export const usePageChangeEffectNavigateLocation = () => { if ( onboardingStatus === OnboardingStatus.CompletedWithoutSubscription && isMatchingOnboardingRoute && - !isMatchingOpenRoute && !isMatchingLocation(AppPath.PlanRequired) ) { return defaultHomePagePath; diff --git a/packages/twenty-front/src/modules/command-menu/components/__stories__/CommandMenu.stories.tsx b/packages/twenty-front/src/modules/command-menu/components/__stories__/CommandMenu.stories.tsx index 82c6c7606..f3f96062b 100644 --- a/packages/twenty-front/src/modules/command-menu/components/__stories__/CommandMenu.stories.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/__stories__/CommandMenu.stories.tsx @@ -19,7 +19,7 @@ import { mockDefaultWorkspace, mockedWorkspaceMemberData, } from '~/testing/mock-data/users'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; import { CommandMenu } from '../CommandMenu'; diff --git a/packages/twenty-front/src/modules/object-record/record-index/options/hooks/__tests__/useExportTableData.test.ts b/packages/twenty-front/src/modules/object-record/record-index/options/hooks/__tests__/useExportTableData.test.ts index 1b7dbce5d..f5d35d92b 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/options/hooks/__tests__/useExportTableData.test.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/options/hooks/__tests__/useExportTableData.test.ts @@ -6,24 +6,10 @@ import { displayedExportProgress, download, generateCsv, - sleep, } from '../useExportTableData'; jest.useFakeTimers(); -describe('sleep', () => { - it('waits the provided number of milliseconds', async () => { - const spy = jest.fn(); - sleep(1000).then(spy); - - jest.advanceTimersByTime(999); - expect(spy).not.toHaveBeenCalled(); - jest.advanceTimersByTime(1); - await Promise.resolve(); // let queued promises execute - expect(spy).toHaveBeenCalledTimes(1); - }); -}); - describe('download', () => { it('creates a download link and clicks it', () => { const link = document.createElement('a'); diff --git a/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useExportTableData.ts b/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useExportTableData.ts index 4316686f6..785bb8f51 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useExportTableData.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useExportTableData.ts @@ -8,12 +8,10 @@ import { useRecordTableStates } from '@/object-record/record-table/hooks/interna import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition'; import { isDefined } from '~/utils/isDefined'; import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; +import { sleep } from '~/utils/sleep'; import { useFindManyParams } from '../../hooks/useLoadRecordIndexTable'; -export const sleep = (ms: number) => - new Promise((resolve) => setTimeout(resolve, ms)); - export const download = (blob: Blob, filename: string) => { const url = URL.createObjectURL(blob); const link = document.createElement('a'); diff --git a/packages/twenty-front/src/modules/object-record/relation-picker/components/__stories__/SingleEntitySelect.stories.tsx b/packages/twenty-front/src/modules/object-record/relation-picker/components/__stories__/SingleEntitySelect.stories.tsx index 882d5f393..683c83459 100644 --- a/packages/twenty-front/src/modules/object-record/relation-picker/components/__stories__/SingleEntitySelect.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/relation-picker/components/__stories__/SingleEntitySelect.stories.tsx @@ -9,7 +9,7 @@ import { RelationPickerDecorator } from '~/testing/decorators/RelationPickerDeco import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; import { getPeopleMock } from '~/testing/mock-data/people'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; import { EntityForSelect } from '../../types/EntityForSelect'; import { SingleEntitySelect } from '../SingleEntitySelect'; diff --git a/packages/twenty-front/src/modules/spreadsheet-import/tests/mockRsiValues.ts b/packages/twenty-front/src/modules/spreadsheet-import/tests/mockRsiValues.ts index 3621a7941..814dae7a2 100644 --- a/packages/twenty-front/src/modules/spreadsheet-import/tests/mockRsiValues.ts +++ b/packages/twenty-front/src/modules/spreadsheet-import/tests/mockRsiValues.ts @@ -1,5 +1,6 @@ import { defaultSpreadsheetImportProps } from '@/spreadsheet-import/provider/components/SpreadsheetImport'; import { Fields, SpreadsheetOptions } from '@/spreadsheet-import/types'; +import { sleep } from '~/utils/sleep'; const fields = [ { @@ -102,22 +103,16 @@ export const mockRsiValues = mockComponentBehaviourForTypes({ return; }, uploadStepHook: async (data) => { - await new Promise((resolve) => { - setTimeout(() => resolve(data), 4000); - }); + await sleep(4000, (resolve) => resolve(data)); return data; }, selectHeaderStepHook: async (hData, data) => { - await new Promise((resolve) => { - setTimeout( - () => - resolve({ - headerValues: hData, - data, - }), - 4000, - ); - }); + await sleep(4000, (resolve) => + resolve({ + headerValues: hData, + data, + }), + ); return { headerValues: hData, data, @@ -125,9 +120,7 @@ export const mockRsiValues = mockComponentBehaviourForTypes({ }, // Runs after column matching and on entry change, more performant matchColumnsStepHook: async (data) => { - await new Promise((resolve) => { - setTimeout(() => resolve(data), 4000); - }); + await sleep(4000, (resolve) => resolve(data)); return data; }, }); diff --git a/packages/twenty-front/src/modules/ui/input/components/__stories__/IconPicker.stories.tsx b/packages/twenty-front/src/modules/ui/input/components/__stories__/IconPicker.stories.tsx index ec1e0df17..16499b234 100644 --- a/packages/twenty-front/src/modules/ui/input/components/__stories__/IconPicker.stories.tsx +++ b/packages/twenty-front/src/modules/ui/input/components/__stories__/IconPicker.stories.tsx @@ -4,7 +4,7 @@ import { expect, userEvent, within } from '@storybook/test'; import { ComponentDecorator } from 'twenty-ui'; import { IconsProviderDecorator } from '~/testing/decorators/IconsProviderDecorator'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; import { IconPicker, IconPickerProps } from '../IconPicker'; diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/hooks/useWorkspaceSwitching.ts b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/hooks/useWorkspaceSwitching.ts index a5c3de011..7a04238d1 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/hooks/useWorkspaceSwitching.ts +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/hooks/useWorkspaceSwitching.ts @@ -5,6 +5,7 @@ import { tokenPairState } from '@/auth/states/tokenPairState'; import { AppPath } from '@/types/AppPath'; import { useGenerateJwtMutation } from '~/generated/graphql'; import { isDefined } from '~/utils/isDefined'; +import { sleep } from '~/utils/sleep'; export const useWorkspaceSwitching = () => { const setTokenPair = useSetRecoilState(tokenPairState); @@ -29,6 +30,7 @@ export const useWorkspaceSwitching = () => { const { tokens } = jwt.data.generateJWT; setTokenPair(tokens); + await sleep(0); // This hacky workaround is necessary to ensure the tokens stored in the cookie are updated correctly. window.location.href = AppPath.Index; }; diff --git a/packages/twenty-front/src/pages/auth/Invite.tsx b/packages/twenty-front/src/pages/auth/Invite.tsx index b0558f971..87d48e1b2 100644 --- a/packages/twenty-front/src/pages/auth/Invite.tsx +++ b/packages/twenty-front/src/pages/auth/Invite.tsx @@ -66,7 +66,6 @@ export const Invite = () => { <> = { title: 'Pages/Onboarding/ChooseYourPlan', diff --git a/packages/twenty-front/src/pages/settings/__stories__/SettingsBilling.stories.tsx b/packages/twenty-front/src/pages/settings/__stories__/SettingsBilling.stories.tsx index 6be6ad9fb..478423bd9 100644 --- a/packages/twenty-front/src/pages/settings/__stories__/SettingsBilling.stories.tsx +++ b/packages/twenty-front/src/pages/settings/__stories__/SettingsBilling.stories.tsx @@ -8,7 +8,7 @@ import { PageDecoratorArgs, } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; import { SettingsBilling } from '../SettingsBilling'; diff --git a/packages/twenty-front/src/pages/settings/__stories__/SettingsWorkspaceMembers.stories.tsx b/packages/twenty-front/src/pages/settings/__stories__/SettingsWorkspaceMembers.stories.tsx index 655bab8ea..c8a0172c4 100644 --- a/packages/twenty-front/src/pages/settings/__stories__/SettingsWorkspaceMembers.stories.tsx +++ b/packages/twenty-front/src/pages/settings/__stories__/SettingsWorkspaceMembers.stories.tsx @@ -6,7 +6,7 @@ import { PageDecoratorArgs, } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; import { SettingsWorkspaceMembers } from '../SettingsWorkspaceMembers'; diff --git a/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendars.stories.tsx b/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendars.stories.tsx index e53cef2cb..d2134d2f4 100644 --- a/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendars.stories.tsx +++ b/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendars.stories.tsx @@ -8,7 +8,7 @@ import { PageDecoratorArgs, } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; import { SettingsAccountsCalendars } from '../SettingsAccountsCalendars'; diff --git a/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendarsSettings.stories.tsx b/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendarsSettings.stories.tsx index c88b24cb3..1e3ee5934 100644 --- a/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendarsSettings.stories.tsx +++ b/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendarsSettings.stories.tsx @@ -10,7 +10,7 @@ import { } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; import { mockedConnectedAccounts } from '~/testing/mock-data/accounts'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; import { SettingsAccountsCalendarsSettings } from '../SettingsAccountsCalendarsSettings'; diff --git a/packages/twenty-front/src/pages/settings/data-model/__stories__/SettingsObjectDetail.stories.tsx b/packages/twenty-front/src/pages/settings/data-model/__stories__/SettingsObjectDetail.stories.tsx index 6fe42cba8..0e4b4eeac 100644 --- a/packages/twenty-front/src/pages/settings/data-model/__stories__/SettingsObjectDetail.stories.tsx +++ b/packages/twenty-front/src/pages/settings/data-model/__stories__/SettingsObjectDetail.stories.tsx @@ -6,7 +6,7 @@ import { PageDecoratorArgs, } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; import { SettingsObjectDetail } from '../SettingsObjectDetail'; diff --git a/packages/twenty-front/src/pages/settings/data-model/__stories__/SettingsObjectEdit.stories.tsx b/packages/twenty-front/src/pages/settings/data-model/__stories__/SettingsObjectEdit.stories.tsx index 0e7d926d3..d64afb769 100644 --- a/packages/twenty-front/src/pages/settings/data-model/__stories__/SettingsObjectEdit.stories.tsx +++ b/packages/twenty-front/src/pages/settings/data-model/__stories__/SettingsObjectEdit.stories.tsx @@ -5,7 +5,7 @@ import { PageDecoratorArgs, } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; import { SettingsObjectEdit } from '../SettingsObjectEdit'; diff --git a/packages/twenty-front/src/pages/settings/data-model/__stories__/SettingsObjects.stories.tsx b/packages/twenty-front/src/pages/settings/data-model/__stories__/SettingsObjects.stories.tsx index 2e00e15b2..4782f9f23 100644 --- a/packages/twenty-front/src/pages/settings/data-model/__stories__/SettingsObjects.stories.tsx +++ b/packages/twenty-front/src/pages/settings/data-model/__stories__/SettingsObjects.stories.tsx @@ -6,7 +6,7 @@ import { PageDecoratorArgs, } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; import { SettingsObjects } from '../SettingsObjects'; diff --git a/packages/twenty-front/src/pages/settings/developers/__stories__/SettingsDevelopers.stories.tsx b/packages/twenty-front/src/pages/settings/developers/__stories__/SettingsDevelopers.stories.tsx index dcc2c2581..ebe8d272f 100644 --- a/packages/twenty-front/src/pages/settings/developers/__stories__/SettingsDevelopers.stories.tsx +++ b/packages/twenty-front/src/pages/settings/developers/__stories__/SettingsDevelopers.stories.tsx @@ -7,7 +7,7 @@ import { PageDecoratorArgs, } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; const meta: Meta = { title: 'Pages/Settings/Developers/SettingsDevelopers', diff --git a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationDatabase.stories.tsx b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationDatabase.stories.tsx index be0983ca2..e828bfa76 100644 --- a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationDatabase.stories.tsx +++ b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationDatabase.stories.tsx @@ -9,7 +9,7 @@ import { PageDecoratorArgs, } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; const meta: Meta = { title: 'Pages/Settings/Integrations/SettingsIntegrationDatabase', diff --git a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationEditDatabaseConnection.stories.tsx b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationEditDatabaseConnection.stories.tsx index 00e09088c..8adb6d719 100644 --- a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationEditDatabaseConnection.stories.tsx +++ b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationEditDatabaseConnection.stories.tsx @@ -7,7 +7,7 @@ import { PageDecoratorArgs, } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; const meta: Meta = { title: diff --git a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationNewDatabaseConnection.stories.tsx b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationNewDatabaseConnection.stories.tsx index 96f5f88f2..5f95eacb2 100644 --- a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationNewDatabaseConnection.stories.tsx +++ b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationNewDatabaseConnection.stories.tsx @@ -7,7 +7,7 @@ import { PageDecoratorArgs, } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; const meta: Meta = { title: 'Pages/Settings/Integrations/SettingsIntegrationNewDatabaseConnection', diff --git a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationShowDatabaseConnection.stories.tsx b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationShowDatabaseConnection.stories.tsx index b81e24610..bb365de80 100644 --- a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationShowDatabaseConnection.stories.tsx +++ b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationShowDatabaseConnection.stories.tsx @@ -9,7 +9,7 @@ import { PageDecoratorArgs, } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; const meta: Meta = { title: diff --git a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrations.stories.tsx b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrations.stories.tsx index bc11b4f61..c01318c7b 100644 --- a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrations.stories.tsx +++ b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrations.stories.tsx @@ -9,7 +9,7 @@ import { PageDecoratorArgs, } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; const meta: Meta = { title: 'Pages/Settings/Integrations/SettingsIntegrations', diff --git a/packages/twenty-front/src/pages/tasks/__stories__/Tasks.stories.tsx b/packages/twenty-front/src/pages/tasks/__stories__/Tasks.stories.tsx index 3cef9ef7e..458e3f301 100644 --- a/packages/twenty-front/src/pages/tasks/__stories__/Tasks.stories.tsx +++ b/packages/twenty-front/src/pages/tasks/__stories__/Tasks.stories.tsx @@ -8,7 +8,7 @@ import { } from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; import { mockedWorkspaceMemberData } from '~/testing/mock-data/users'; -import { sleep } from '~/testing/sleep'; +import { sleep } from '~/utils/sleep'; import { Tasks } from '../Tasks'; diff --git a/packages/twenty-front/src/testing/profiling/components/ProfilingQueueEffect.tsx b/packages/twenty-front/src/testing/profiling/components/ProfilingQueueEffect.tsx index 22307b316..8da642bd7 100644 --- a/packages/twenty-front/src/testing/profiling/components/ProfilingQueueEffect.tsx +++ b/packages/twenty-front/src/testing/profiling/components/ProfilingQueueEffect.tsx @@ -7,6 +7,7 @@ import { profilingQueueState } from '~/testing/profiling/states/profilingQueueSt import { profilingSessionRunsState } from '~/testing/profiling/states/profilingSessionRunsState'; import { profilingSessionStatusState } from '~/testing/profiling/states/profilingSessionStatusState'; import { getTestArray } from '~/testing/profiling/utils/getTestArray'; +import { sleep } from '~/utils/sleep'; export const ProfilingQueueEffect = ({ profilingId, @@ -84,7 +85,7 @@ export const ProfilingQueueEffect = ({ ? TIME_BETWEEN_TEST_RUNS_IN_MS * 2 : TIME_BETWEEN_TEST_RUNS_IN_MS; - await new Promise((resolve) => setTimeout(resolve, timeInMs)); + await sleep(timeInMs); const nextIndex = currentProfilingRunIndex + 1; diff --git a/packages/twenty-front/src/testing/sleep.ts b/packages/twenty-front/src/testing/sleep.ts deleted file mode 100644 index 3604b7d44..000000000 --- a/packages/twenty-front/src/testing/sleep.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const sleep = async (ms: number) => - new Promise((resolve) => { - setTimeout(resolve, ms); - }); diff --git a/packages/twenty-front/src/utils/__tests__/sleep.test.ts b/packages/twenty-front/src/utils/__tests__/sleep.test.ts new file mode 100644 index 000000000..15501c8fc --- /dev/null +++ b/packages/twenty-front/src/utils/__tests__/sleep.test.ts @@ -0,0 +1,35 @@ +import { sleep } from '~/utils/sleep'; + +jest.useFakeTimers(); +describe('sleep', () => { + it('waits the provided number of milliseconds', async () => { + const spy = jest.fn(); + const promise = sleep(1000).then(spy); + + jest.advanceTimersByTime(999); + expect(spy).not.toHaveBeenCalled(); + jest.advanceTimersByTime(1); + await promise; // let queued promises execute + expect(spy).toHaveBeenCalledTimes(1); + }); + + it('call callback after the wait', async () => { + const spy = jest.fn(); + let increment = 1; + const callback = jest.fn((resolve) => { + increment += 1; + resolve(); + }); + const promise = sleep(1000, callback).then(spy); + + jest.advanceTimersByTime(999); + expect(spy).not.toHaveBeenCalled(); + expect(callback).not.toHaveBeenCalled(); + expect(increment).toEqual(1); + jest.advanceTimersByTime(1); + await promise; // let queued promises execute + expect(spy).toHaveBeenCalledTimes(1); + expect(callback).toHaveBeenCalledTimes(1); + expect(increment).toEqual(2); + }); +}); diff --git a/packages/twenty-front/src/utils/sleep.ts b/packages/twenty-front/src/utils/sleep.ts new file mode 100644 index 000000000..18055af1f --- /dev/null +++ b/packages/twenty-front/src/utils/sleep.ts @@ -0,0 +1,8 @@ +export const sleep = async ( + ms: number, + callback?: (resolve: (value: any) => void) => void, +) => + new Promise((resolve) => { + const handler = callback ? () => callback(resolve) : resolve; + setTimeout(handler, ms); + });