feat(editor): Implement new banners framework (#6603)
* ⚡ Implemented new grid row - banners * ✨ Fixing node creator and executions sidebar position after layout update * 💄 Added configurable round corners to the Callout component * ⚡ Fixing mouse position detection and main tab bar position * ⚡ Implemented basic banner component structure * ⚡ Implemented banner state and dismiss logic * ⚡ Fixing grid layout. Updating banners height state dynamically * ⚡ Fix zoom to fit position, mouse position in demo mode and callout vertical alignment * ⚡ Implementing proper trial banners logic * 💄 Only showing execution usage data once the sidebar is fully expanded * ✨ Implemented permanent/temporary dismiss logic for v1 flag * ⚡ Minor refactoring of banner logic * ⚡ Updating permanent dismiss logic to work with all banners * 👕 Fixing linting errors * ✔️ Updating Callout component test snapshots * 💄 Tweaking zoom to fit position * ✔️ Updating testing endpoints to use new store data * ✅ Added banners unit tests * ✔️ Fixing failing banner tests * ✅ Added more banner tests * ⚡ Updating banners dimensions on resize, removing leftover code * ✔️ Removing store import from API file * 👕 Fixing lint errors * ⚡ Updating migration files * ⚡ Using query parameters in migrations * 👌 Addressing design review feedback * ⚡ Updating upgrade plan button click * ⚡ Updating the migrations syntax * 👌 Updating permanent banner dismiss endpoint and back-end logic * 👌 Refactoring trial banner component and ui store * 👌 Addressing more points from code review * 👌 Moving DOM logic from the store * ✔️ Updated callout component snapshots * 👌 Updating mysql migration file * ✔️ Updating e2e test canvas coordinates after setting it's position to absolute * 👌 Addressing back-end review feedback * 👌 Improving typing around banners * 👕 Fixing lint errors
This commit is contained in:
committed by
GitHub
parent
ff0759530d
commit
4240e76253
151
packages/editor-ui/src/components/__tests__/BannersStack.test.ts
Normal file
151
packages/editor-ui/src/components/__tests__/BannersStack.test.ts
Normal file
@@ -0,0 +1,151 @@
|
||||
import { PiniaVuePlugin } from 'pinia';
|
||||
import { render, within } from '@testing-library/vue';
|
||||
import { merge } from 'lodash-es';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
import { SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils';
|
||||
import { STORES } from '@/constants';
|
||||
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import BannerStack from '@/components/banners/BannerStack.vue';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useUsersStore } from '@/stores/users.store';
|
||||
|
||||
let uiStore: ReturnType<typeof useUIStore>;
|
||||
let usersStore: ReturnType<typeof useUsersStore>;
|
||||
|
||||
const DEFAULT_SETUP = {
|
||||
pinia: createTestingPinia({
|
||||
initialState: {
|
||||
[STORES.SETTINGS]: {
|
||||
settings: merge({}, SETTINGS_STORE_DEFAULT_STATE.settings),
|
||||
},
|
||||
[STORES.UI]: {
|
||||
banners: {
|
||||
V1: { dismissed: false },
|
||||
TRIAL: { dismissed: false },
|
||||
TRIAL_OVER: { dismissed: false },
|
||||
},
|
||||
},
|
||||
[STORES.USERS]: {
|
||||
currentUserId: 'aaa-bbb',
|
||||
users: {
|
||||
'aaa-bbb': {
|
||||
id: 'aaa-bbb',
|
||||
globalRole: {
|
||||
id: '1',
|
||||
name: 'owner',
|
||||
scope: 'global',
|
||||
},
|
||||
},
|
||||
'bbb-bbb': {
|
||||
id: 'bbb-bbb',
|
||||
globalRoleId: 2,
|
||||
globalRole: {
|
||||
id: '2',
|
||||
name: 'member',
|
||||
scope: 'global',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
const renderComponent = (renderOptions: Parameters<typeof render>[1] = {}) =>
|
||||
render(BannerStack, merge(DEFAULT_SETUP, renderOptions), (vue) => {
|
||||
vue.use(PiniaVuePlugin);
|
||||
});
|
||||
|
||||
describe('BannerStack', () => {
|
||||
beforeEach(() => {
|
||||
uiStore = useUIStore();
|
||||
usersStore = useUsersStore();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should render default configuration', async () => {
|
||||
const { getByTestId } = renderComponent();
|
||||
|
||||
const bannerStack = getByTestId('banner-stack');
|
||||
expect(bannerStack).toBeInTheDocument();
|
||||
|
||||
expect(within(bannerStack).getByTestId('banners-TRIAL')).toBeInTheDocument();
|
||||
expect(within(bannerStack).getByTestId('banners-TRIAL_OVER')).toBeInTheDocument();
|
||||
expect(within(bannerStack).getByTestId('banners-V1')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not render dismissed banners', async () => {
|
||||
const { getByTestId } = renderComponent({
|
||||
pinia: createTestingPinia({
|
||||
initialState: merge(
|
||||
{
|
||||
[STORES.UI]: {
|
||||
banners: {
|
||||
V1: { dismissed: true },
|
||||
TRIAL: { dismissed: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
DEFAULT_SETUP.pinia,
|
||||
),
|
||||
}),
|
||||
});
|
||||
const bannerStack = getByTestId('banner-stack');
|
||||
expect(bannerStack).toBeInTheDocument();
|
||||
|
||||
expect(within(bannerStack).queryByTestId('banners-V1')).not.toBeInTheDocument();
|
||||
expect(within(bannerStack).queryByTestId('banners-TRIAL')).not.toBeInTheDocument();
|
||||
expect(within(bannerStack).getByTestId('banners-TRIAL_OVER')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should dismiss banner on click', async () => {
|
||||
const { getByTestId } = renderComponent();
|
||||
const dismissBannerSpy = vi
|
||||
.spyOn(useUIStore(), 'dismissBanner')
|
||||
.mockImplementation(async (banner, mode) => {});
|
||||
const closeTrialBannerButton = getByTestId('banner-TRIAL_OVER-close');
|
||||
expect(closeTrialBannerButton).toBeInTheDocument();
|
||||
await userEvent.click(closeTrialBannerButton);
|
||||
expect(dismissBannerSpy).toHaveBeenCalledWith('TRIAL_OVER');
|
||||
});
|
||||
|
||||
it('should permanently dismiss banner on click', async () => {
|
||||
const { getByTestId } = renderComponent({
|
||||
pinia: createTestingPinia({
|
||||
initialState: merge(DEFAULT_SETUP.pinia, {
|
||||
[STORES.UI]: {
|
||||
banners: {
|
||||
V1: { dismissed: false },
|
||||
},
|
||||
},
|
||||
}),
|
||||
}),
|
||||
});
|
||||
const dismissBannerSpy = vi
|
||||
.spyOn(useUIStore(), 'dismissBanner')
|
||||
.mockImplementation(async (banner, mode) => {});
|
||||
|
||||
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(DEFAULT_SETUP.pinia, {
|
||||
[STORES.USERS]: {
|
||||
currentUserId: 'bbb-bbb',
|
||||
},
|
||||
}),
|
||||
}),
|
||||
});
|
||||
expect(queryByTestId('banner-confirm-v1')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -8,11 +8,10 @@ import { SOURCE_CONTROL_PULL_MODAL_KEY, STORES } from '@/constants';
|
||||
import { i18nInstance } from '@/plugins/i18n';
|
||||
import { SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils';
|
||||
import MainSidebarSourceControl from '@/components/MainSidebarSourceControl.vue';
|
||||
import { useUsersStore, useSourceControlStore, useUIStore } from '@/stores';
|
||||
import { useSourceControlStore, useUIStore } from '@/stores';
|
||||
|
||||
let pinia: ReturnType<typeof createTestingPinia>;
|
||||
let sourceControlStore: ReturnType<typeof useSourceControlStore>;
|
||||
let usersStore: ReturnType<typeof useUsersStore>;
|
||||
let uiStore: ReturnType<typeof useUIStore>;
|
||||
|
||||
const renderComponent = (renderOptions: Parameters<typeof render>[1] = {}) => {
|
||||
@@ -44,7 +43,6 @@ describe('MainSidebarSourceControl', () => {
|
||||
|
||||
sourceControlStore = useSourceControlStore();
|
||||
uiStore = useUIStore();
|
||||
usersStore = useUsersStore();
|
||||
});
|
||||
|
||||
it('should render nothing', async () => {
|
||||
|
||||
Reference in New Issue
Block a user