Storybook Helpers (#35158)
This commit is contained in:
		@@ -11,7 +11,21 @@ const config: StorybookConfig = {
 | 
				
			|||||||
    name: '@storybook/react-vite',
 | 
					    name: '@storybook/react-vite',
 | 
				
			||||||
    options: {},
 | 
					    options: {},
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  staticDirs: ['./static'],
 | 
					  staticDirs: [
 | 
				
			||||||
 | 
					    './static',
 | 
				
			||||||
 | 
					    // We need to manually specify the assets because of the symlink in public/sw.js
 | 
				
			||||||
 | 
					    ...[
 | 
				
			||||||
 | 
					      'avatars',
 | 
				
			||||||
 | 
					      'emoji',
 | 
				
			||||||
 | 
					      'headers',
 | 
				
			||||||
 | 
					      'sounds',
 | 
				
			||||||
 | 
					      'badge.png',
 | 
				
			||||||
 | 
					      'loading.gif',
 | 
				
			||||||
 | 
					      'loading.png',
 | 
				
			||||||
 | 
					      'oops.gif',
 | 
				
			||||||
 | 
					      'oops.png',
 | 
				
			||||||
 | 
					    ].map((path) => ({ from: `../public/${path}`, to: `/${path}` })),
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default config;
 | 
					export default config;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,16 +2,19 @@ import { useEffect, useState } from 'react';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { IntlProvider } from 'react-intl';
 | 
					import { IntlProvider } from 'react-intl';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { MemoryRouter, Route } from 'react-router';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { configureStore } from '@reduxjs/toolkit';
 | 
					import { configureStore } from '@reduxjs/toolkit';
 | 
				
			||||||
import { Provider } from 'react-redux';
 | 
					import { Provider } from 'react-redux';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import type { Preview } from '@storybook/react-vite';
 | 
					import type { Preview } from '@storybook/react-vite';
 | 
				
			||||||
import { http, passthrough } from 'msw';
 | 
					 | 
				
			||||||
import { initialize, mswLoader } from 'msw-storybook-addon';
 | 
					import { initialize, mswLoader } from 'msw-storybook-addon';
 | 
				
			||||||
 | 
					import { action } from 'storybook/actions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import type { LocaleData } from '@/mastodon/locales';
 | 
					import type { LocaleData } from '@/mastodon/locales';
 | 
				
			||||||
import { reducerWithInitialState, rootReducer } from '@/mastodon/reducers';
 | 
					import { reducerWithInitialState, rootReducer } from '@/mastodon/reducers';
 | 
				
			||||||
import { defaultMiddleware } from '@/mastodon/store/store';
 | 
					import { defaultMiddleware } from '@/mastodon/store/store';
 | 
				
			||||||
 | 
					import { mockHandlers, unhandledRequestHandler } from '@/testing/api';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// If you want to run the dark theme during development,
 | 
					// If you want to run the dark theme during development,
 | 
				
			||||||
// you can change the below to `/application.scss`
 | 
					// you can change the below to `/application.scss`
 | 
				
			||||||
@@ -22,7 +25,9 @@ const localeFiles = import.meta.glob('@/mastodon/locales/*.json', {
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Initialize MSW
 | 
					// Initialize MSW
 | 
				
			||||||
initialize();
 | 
					initialize({
 | 
				
			||||||
 | 
					  onUnhandledRequest: unhandledRequestHandler,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const preview: Preview = {
 | 
					const preview: Preview = {
 | 
				
			||||||
  // Auto-generate docs: https://storybook.js.org/docs/writing-docs/autodocs
 | 
					  // Auto-generate docs: https://storybook.js.org/docs/writing-docs/autodocs
 | 
				
			||||||
@@ -94,6 +99,21 @@ const preview: Preview = {
 | 
				
			|||||||
        </IntlProvider>
 | 
					        </IntlProvider>
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    (Story) => (
 | 
				
			||||||
 | 
					      <MemoryRouter>
 | 
				
			||||||
 | 
					        <Story />
 | 
				
			||||||
 | 
					        <Route
 | 
				
			||||||
 | 
					          path='*'
 | 
				
			||||||
 | 
					          // eslint-disable-next-line react/jsx-no-bind
 | 
				
			||||||
 | 
					          render={({ location }) => {
 | 
				
			||||||
 | 
					            if (location.pathname !== '/') {
 | 
				
			||||||
 | 
					              action(`route change to ${location.pathname}`)(location);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      </MemoryRouter>
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  loaders: [mswLoader],
 | 
					  loaders: [mswLoader],
 | 
				
			||||||
  parameters: {
 | 
					  parameters: {
 | 
				
			||||||
@@ -115,20 +135,10 @@ const preview: Preview = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    state: {},
 | 
					    state: {},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Force docs to use an iframe as it breaks MSW handlers.
 | 
					    docs: {},
 | 
				
			||||||
    // See: https://github.com/mswjs/msw-storybook-addon/issues/83
 | 
					 | 
				
			||||||
    docs: {
 | 
					 | 
				
			||||||
      story: {
 | 
					 | 
				
			||||||
        inline: false,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    msw: {
 | 
					    msw: {
 | 
				
			||||||
      handlers: [
 | 
					      handlers: mockHandlers,
 | 
				
			||||||
        http.get('/index.json', passthrough),
 | 
					 | 
				
			||||||
        http.get('/packs-dev/*', passthrough),
 | 
					 | 
				
			||||||
        http.get('/sounds/*', passthrough),
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
import renderer from 'react-test-renderer';
 | 
					import renderer from 'react-test-renderer';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { render, fireEvent, screen } from 'mastodon/test_helpers';
 | 
					import { render, fireEvent, screen } from '@/testing/rendering';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { Button } from '../button';
 | 
					import { Button } from '../button';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										120
									
								
								app/javascript/mastodon/components/account/account.stories.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								app/javascript/mastodon/components/account/account.stories.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
				
			|||||||
 | 
					import type { Meta, StoryObj } from '@storybook/react-vite';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { accountFactoryState, relationshipsFactory } from '@/testing/factories';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Account } from './index';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const meta = {
 | 
				
			||||||
 | 
					  title: 'Components/Account',
 | 
				
			||||||
 | 
					  component: Account,
 | 
				
			||||||
 | 
					  argTypes: {
 | 
				
			||||||
 | 
					    id: {
 | 
				
			||||||
 | 
					      type: 'string',
 | 
				
			||||||
 | 
					      description: 'ID of the account to display',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    size: {
 | 
				
			||||||
 | 
					      type: 'number',
 | 
				
			||||||
 | 
					      description: 'Size of the avatar in pixels',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    hidden: {
 | 
				
			||||||
 | 
					      type: 'boolean',
 | 
				
			||||||
 | 
					      description: 'Whether the account is hidden or not',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    minimal: {
 | 
				
			||||||
 | 
					      type: 'boolean',
 | 
				
			||||||
 | 
					      description: 'Whether to display a minimal version of the account',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    defaultAction: {
 | 
				
			||||||
 | 
					      type: 'string',
 | 
				
			||||||
 | 
					      control: 'select',
 | 
				
			||||||
 | 
					      options: ['block', 'mute'],
 | 
				
			||||||
 | 
					      description: 'Default action to take on the account',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    withBio: {
 | 
				
			||||||
 | 
					      type: 'boolean',
 | 
				
			||||||
 | 
					      description: 'Whether to display the account bio or not',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    withMenu: {
 | 
				
			||||||
 | 
					      type: 'boolean',
 | 
				
			||||||
 | 
					      description: 'Whether to display the account menu or not',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  args: {
 | 
				
			||||||
 | 
					    id: '1',
 | 
				
			||||||
 | 
					    size: 46,
 | 
				
			||||||
 | 
					    hidden: false,
 | 
				
			||||||
 | 
					    minimal: false,
 | 
				
			||||||
 | 
					    defaultAction: 'mute',
 | 
				
			||||||
 | 
					    withBio: false,
 | 
				
			||||||
 | 
					    withMenu: true,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  parameters: {
 | 
				
			||||||
 | 
					    state: {
 | 
				
			||||||
 | 
					      accounts: {
 | 
				
			||||||
 | 
					        '1': accountFactoryState(),
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					} satisfies Meta<typeof Account>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default meta;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Story = StoryObj<typeof meta>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const Primary: Story = {
 | 
				
			||||||
 | 
					  args: {
 | 
				
			||||||
 | 
					    id: '1',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const Hidden: Story = {
 | 
				
			||||||
 | 
					  args: {
 | 
				
			||||||
 | 
					    hidden: true,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const Minimal: Story = {
 | 
				
			||||||
 | 
					  args: {
 | 
				
			||||||
 | 
					    minimal: true,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const WithBio: Story = {
 | 
				
			||||||
 | 
					  args: {
 | 
				
			||||||
 | 
					    withBio: true,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const NoMenu: Story = {
 | 
				
			||||||
 | 
					  args: {
 | 
				
			||||||
 | 
					    withMenu: false,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const Blocked: Story = {
 | 
				
			||||||
 | 
					  args: {
 | 
				
			||||||
 | 
					    defaultAction: 'block',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  parameters: {
 | 
				
			||||||
 | 
					    state: {
 | 
				
			||||||
 | 
					      relationships: {
 | 
				
			||||||
 | 
					        '1': relationshipsFactory({
 | 
				
			||||||
 | 
					          blocking: true,
 | 
				
			||||||
 | 
					        }),
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const Muted: Story = {
 | 
				
			||||||
 | 
					  args: {},
 | 
				
			||||||
 | 
					  parameters: {
 | 
				
			||||||
 | 
					    state: {
 | 
				
			||||||
 | 
					      relationships: {
 | 
				
			||||||
 | 
					        '1': relationshipsFactory({
 | 
				
			||||||
 | 
					          muting: true,
 | 
				
			||||||
 | 
					        }),
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import { render, fireEvent, screen } from 'mastodon/test_helpers';
 | 
					import { render, fireEvent, screen } from '@/testing/rendering';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Column from '../column';
 | 
					import Column from '../column';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										53
									
								
								app/javascript/testing/api.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								app/javascript/testing/api.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					import { http, HttpResponse } from 'msw';
 | 
				
			||||||
 | 
					import { action } from 'storybook/actions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { relationshipsFactory } from './factories';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const mockHandlers = {
 | 
				
			||||||
 | 
					  mute: http.post<{ id: string }>('/api/v1/accounts/:id/mute', ({ params }) => {
 | 
				
			||||||
 | 
					    action('muting account')(params);
 | 
				
			||||||
 | 
					    return HttpResponse.json(
 | 
				
			||||||
 | 
					      relationshipsFactory({ id: params.id, muting: true }),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }),
 | 
				
			||||||
 | 
					  unmute: http.post<{ id: string }>(
 | 
				
			||||||
 | 
					    '/api/v1/accounts/:id/unmute',
 | 
				
			||||||
 | 
					    ({ params }) => {
 | 
				
			||||||
 | 
					      action('unmuting account')(params);
 | 
				
			||||||
 | 
					      return HttpResponse.json(
 | 
				
			||||||
 | 
					        relationshipsFactory({ id: params.id, muting: false }),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  block: http.post<{ id: string }>(
 | 
				
			||||||
 | 
					    '/api/v1/accounts/:id/block',
 | 
				
			||||||
 | 
					    ({ params }) => {
 | 
				
			||||||
 | 
					      action('blocking account')(params);
 | 
				
			||||||
 | 
					      return HttpResponse.json(
 | 
				
			||||||
 | 
					        relationshipsFactory({ id: params.id, blocking: true }),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  unblock: http.post<{ id: string }>(
 | 
				
			||||||
 | 
					    '/api/v1/accounts/:id/unblock',
 | 
				
			||||||
 | 
					    ({ params }) => {
 | 
				
			||||||
 | 
					      action('unblocking account')(params);
 | 
				
			||||||
 | 
					      return HttpResponse.json(
 | 
				
			||||||
 | 
					        relationshipsFactory({
 | 
				
			||||||
 | 
					          id: params.id,
 | 
				
			||||||
 | 
					          blocking: false,
 | 
				
			||||||
 | 
					        }),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const unhandledRequestHandler = ({ url }: Request) => {
 | 
				
			||||||
 | 
					  const { pathname } = new URL(url);
 | 
				
			||||||
 | 
					  if (pathname.startsWith('/api/v1/')) {
 | 
				
			||||||
 | 
					    action(`unhandled request to ${pathname}`)(url);
 | 
				
			||||||
 | 
					    console.warn(
 | 
				
			||||||
 | 
					      `Unhandled request to ${pathname}. Please add a handler for this request in your storybook configuration.`,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										70
									
								
								app/javascript/testing/factories.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								app/javascript/testing/factories.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
				
			|||||||
 | 
					import type { ApiRelationshipJSON } from '@/mastodon/api_types/relationships';
 | 
				
			||||||
 | 
					import { createAccountFromServerJSON } from '@/mastodon/models/account';
 | 
				
			||||||
 | 
					import type { ApiAccountJSON } from 'mastodon/api_types/accounts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type FactoryOptions<T> = {
 | 
				
			||||||
 | 
					  id?: string;
 | 
				
			||||||
 | 
					} & Partial<T>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type FactoryFunction<T> = (options?: FactoryOptions<T>) => T;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const accountFactory: FactoryFunction<ApiAccountJSON> = ({
 | 
				
			||||||
 | 
					  id,
 | 
				
			||||||
 | 
					  ...data
 | 
				
			||||||
 | 
					} = {}) => ({
 | 
				
			||||||
 | 
					  id: id ?? '1',
 | 
				
			||||||
 | 
					  acct: 'testuser',
 | 
				
			||||||
 | 
					  avatar: '/avatars/original/missing.png',
 | 
				
			||||||
 | 
					  avatar_static: '/avatars/original/missing.png',
 | 
				
			||||||
 | 
					  username: 'testuser',
 | 
				
			||||||
 | 
					  display_name: 'Test User',
 | 
				
			||||||
 | 
					  bot: false,
 | 
				
			||||||
 | 
					  created_at: '2023-01-01T00:00:00.000Z',
 | 
				
			||||||
 | 
					  discoverable: true,
 | 
				
			||||||
 | 
					  emojis: [],
 | 
				
			||||||
 | 
					  fields: [],
 | 
				
			||||||
 | 
					  followers_count: 0,
 | 
				
			||||||
 | 
					  following_count: 0,
 | 
				
			||||||
 | 
					  group: false,
 | 
				
			||||||
 | 
					  header: '/header.png',
 | 
				
			||||||
 | 
					  header_static: '/header_static.png',
 | 
				
			||||||
 | 
					  indexable: true,
 | 
				
			||||||
 | 
					  last_status_at: '2023-01-01',
 | 
				
			||||||
 | 
					  locked: false,
 | 
				
			||||||
 | 
					  mute_expires_at: null,
 | 
				
			||||||
 | 
					  note: 'This is a test user account.',
 | 
				
			||||||
 | 
					  statuses_count: 0,
 | 
				
			||||||
 | 
					  suspended: false,
 | 
				
			||||||
 | 
					  url: '/@testuser',
 | 
				
			||||||
 | 
					  uri: '/users/testuser',
 | 
				
			||||||
 | 
					  noindex: false,
 | 
				
			||||||
 | 
					  roles: [],
 | 
				
			||||||
 | 
					  hide_collections: false,
 | 
				
			||||||
 | 
					  ...data,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const accountFactoryState = (
 | 
				
			||||||
 | 
					  options: FactoryOptions<ApiAccountJSON> = {},
 | 
				
			||||||
 | 
					) => createAccountFromServerJSON(accountFactory(options));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const relationshipsFactory: FactoryFunction<ApiRelationshipJSON> = ({
 | 
				
			||||||
 | 
					  id,
 | 
				
			||||||
 | 
					  ...data
 | 
				
			||||||
 | 
					} = {}) => ({
 | 
				
			||||||
 | 
					  id: id ?? '1',
 | 
				
			||||||
 | 
					  following: false,
 | 
				
			||||||
 | 
					  followed_by: false,
 | 
				
			||||||
 | 
					  blocking: false,
 | 
				
			||||||
 | 
					  blocked_by: false,
 | 
				
			||||||
 | 
					  languages: null,
 | 
				
			||||||
 | 
					  muting_notifications: false,
 | 
				
			||||||
 | 
					  note: '',
 | 
				
			||||||
 | 
					  requested_by: false,
 | 
				
			||||||
 | 
					  muting: false,
 | 
				
			||||||
 | 
					  requested: false,
 | 
				
			||||||
 | 
					  domain_blocking: false,
 | 
				
			||||||
 | 
					  endorsed: false,
 | 
				
			||||||
 | 
					  notifying: false,
 | 
				
			||||||
 | 
					  showing_reblogs: true,
 | 
				
			||||||
 | 
					  ...data,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -5,7 +5,7 @@ import { MemoryRouter } from 'react-router';
 | 
				
			|||||||
import type { RenderOptions } from '@testing-library/react';
 | 
					import type { RenderOptions } from '@testing-library/react';
 | 
				
			||||||
import { render as rtlRender } from '@testing-library/react';
 | 
					import { render as rtlRender } from '@testing-library/react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { IdentityContext } from './identity_context';
 | 
					import { IdentityContext } from '@/mastodon/identity_context';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
beforeAll(() => {
 | 
					beforeAll(() => {
 | 
				
			||||||
  global.requestIdleCallback = vi.fn((cb: IdleRequestCallback) => {
 | 
					  global.requestIdleCallback = vi.fn((cb: IdleRequestCallback) => {
 | 
				
			||||||
@@ -251,8 +251,7 @@ export default tseslint.config([
 | 
				
			|||||||
          devDependencies: [
 | 
					          devDependencies: [
 | 
				
			||||||
            'eslint.config.mjs',
 | 
					            'eslint.config.mjs',
 | 
				
			||||||
            'app/javascript/mastodon/performance.js',
 | 
					            'app/javascript/mastodon/performance.js',
 | 
				
			||||||
            'app/javascript/mastodon/test_setup.js',
 | 
					            'app/javascript/testing/**/*',
 | 
				
			||||||
            'app/javascript/mastodon/test_helpers.tsx',
 | 
					 | 
				
			||||||
            'app/javascript/**/__tests__/**',
 | 
					            'app/javascript/**/__tests__/**',
 | 
				
			||||||
            'app/javascript/**/*.stories.ts',
 | 
					            'app/javascript/**/*.stories.ts',
 | 
				
			||||||
            'app/javascript/**/*.stories.tsx',
 | 
					            'app/javascript/**/*.stories.tsx',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,10 +29,7 @@
 | 
				
			|||||||
    "vite.config.mts",
 | 
					    "vite.config.mts",
 | 
				
			||||||
    "vitest.config.mts",
 | 
					    "vitest.config.mts",
 | 
				
			||||||
    "config/vite",
 | 
					    "config/vite",
 | 
				
			||||||
    "app/javascript/mastodon",
 | 
					    "app/javascript",
 | 
				
			||||||
    "app/javascript/entrypoints",
 | 
					    ".storybook/*"
 | 
				
			||||||
    "app/javascript/types",
 | 
					 | 
				
			||||||
    ".storybook/*.ts",
 | 
					 | 
				
			||||||
    ".storybook/*.tsx"
 | 
					 | 
				
			||||||
  ]
 | 
					  ]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user