n8n/packages/editor-ui/src/components/BannersStack.test.ts

154 lines
4.6 KiB
TypeScript

import { merge } from 'lodash-es';
import userEvent from '@testing-library/user-event';
import { SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils';
import { ROLE, STORES } from '@/constants';
import { createTestingPinia } from '@pinia/testing';
import BannerStack from '@/components/banners/BannerStack.vue';
import type { RenderOptions } from '@/__tests__/render';
import { createComponentRenderer } from '@/__tests__/render';
import { waitFor } from '@testing-library/vue';
import { useUIStore } from '@/stores/ui.store';
import { useUsersStore } from '@/stores/users.store';
let uiStore: ReturnType<typeof useUIStore>;
const initialState = {
[STORES.SETTINGS]: {
settings: merge({}, SETTINGS_STORE_DEFAULT_STATE.settings),
},
[STORES.UI]: {
bannerStack: ['TRIAL_OVER', 'V1', 'NON_PRODUCTION_LICENSE', 'EMAIL_CONFIRMATION'],
},
[STORES.USERS]: {
currentUserId: 'aaa-bbb',
usersById: {
'aaa-bbb': {
id: 'aaa-bbb',
role: ROLE.Owner,
},
'bbb-bbb': {
id: 'bbb-bbb',
role: ROLE.Member,
},
},
},
};
const defaultRenderOptions: RenderOptions = {
pinia: createTestingPinia({ initialState }),
};
const renderComponent = createComponentRenderer(BannerStack, defaultRenderOptions);
describe('BannerStack', () => {
beforeEach(() => {
uiStore = useUIStore();
});
afterEach(() => {
vi.clearAllMocks();
});
it('should render banner with the highest priority', async () => {
const { getByTestId, queryByTestId } = renderComponent();
const bannerStack = getByTestId('banner-stack');
expect(bannerStack).toBeInTheDocument();
// Only V1 banner should be visible
expect(getByTestId('banners-V1')).toBeInTheDocument();
expect(queryByTestId('banners-TRIAL_OVER')).not.toBeInTheDocument();
});
it('should dismiss banner on click', async () => {
const { getByTestId } = renderComponent();
const dismissBannerSpy = vi.spyOn(uiStore, 'dismissBanner').mockImplementation(async () => {});
expect(getByTestId('banners-V1')).toBeInTheDocument();
const closeTrialBannerButton = getByTestId('banner-V1-close');
expect(closeTrialBannerButton).toBeInTheDocument();
await userEvent.click(closeTrialBannerButton);
expect(dismissBannerSpy).toHaveBeenCalledWith('V1');
});
it('should permanently dismiss banner on click', async () => {
const { getByTestId } = renderComponent();
const dismissBannerSpy = vi.spyOn(uiStore, 'dismissBanner').mockImplementation(async () => {});
const permanentlyDismissBannerLink = getByTestId('banner-confirm-v1');
expect(permanentlyDismissBannerLink).toBeInTheDocument();
await userEvent.click(permanentlyDismissBannerLink);
expect(dismissBannerSpy).toHaveBeenCalledWith('V1', 'permanent');
});
it('should not render permanent dismiss link if user is not owner', async () => {
const { queryByTestId } = renderComponent({
pinia: createTestingPinia({
initialState: merge(initialState, {
[STORES.USERS]: {
currentUserId: 'bbb-bbb',
},
}),
}),
});
expect(queryByTestId('banner-confirm-v1')).not.toBeInTheDocument();
});
it('should send email confirmation request from the banner', async () => {
const { getByTestId, getByText } = renderComponent({
pinia: createTestingPinia({
initialState: {
...initialState,
[STORES.UI]: {
bannerStack: ['EMAIL_CONFIRMATION'],
},
},
}),
});
const confirmEmailSpy = vi.spyOn(useUsersStore(), 'sendConfirmationEmail');
getByTestId('confirm-email-button').click();
await waitFor(() => expect(confirmEmailSpy).toHaveBeenCalled());
await waitFor(() => {
expect(getByText('Confirmation email sent')).toBeInTheDocument();
});
});
it('should show error message if email confirmation fails', async () => {
const ERROR_MESSAGE = 'Something went wrong';
const { getByTestId, getByText } = renderComponent({
pinia: createTestingPinia({
initialState: {
...initialState,
[STORES.UI]: {
bannerStack: ['EMAIL_CONFIRMATION'],
},
},
}),
});
const confirmEmailSpy = vi
.spyOn(useUsersStore(), 'sendConfirmationEmail')
.mockImplementation(() => {
throw new Error(ERROR_MESSAGE);
});
getByTestId('confirm-email-button').click();
await waitFor(() => expect(confirmEmailSpy).toHaveBeenCalled());
await waitFor(() => {
expect(getByText(ERROR_MESSAGE)).toBeInTheDocument();
});
});
it('should render empty banner stack when there are no banners to display', async () => {
const { queryByTestId } = renderComponent({
pinia: createTestingPinia({
initialState: {
...initialState,
[STORES.UI]: {
bannerStack: [],
},
},
}),
});
expect(queryByTestId('banner-stack')).toBeEmptyDOMElement();
});
});