fix(editor): Fix workflows filter resetting (#8411)

This commit is contained in:
Csaba Tuncsik 2024-01-26 06:55:08 +01:00 committed by GitHub
parent caab97e667
commit ad4b298be3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 251 additions and 0 deletions

View file

@ -6,6 +6,8 @@ import { routesForVariables } from './variable';
import { routesForSettings } from './settings';
import { routesForSSO } from './sso';
import { routesForSourceControl } from './sourceControl';
import { routesForWorkflows } from './workflow';
import { routesForTags } from './tag';
const endpoints: Array<(server: Server) => void> = [
routesForCredentials,
@ -15,6 +17,8 @@ const endpoints: Array<(server: Server) => void> = [
routesForSettings,
routesForSSO,
routesForSourceControl,
routesForWorkflows,
routesForTags,
];
export { endpoints };

View file

@ -0,0 +1,11 @@
import type { Server } from 'miragejs';
import { Response } from 'miragejs';
import type { AppSchema } from '../types';
export function routesForTags(server: Server) {
server.get('/rest/tags', (schema: AppSchema) => {
const { models: data } = schema.all('tag');
return new Response(200, {}, { data });
});
}

View file

@ -0,0 +1,16 @@
import type { Server } from 'miragejs';
import { Response } from 'miragejs';
import type { AppSchema } from '../types';
export function routesForWorkflows(server: Server) {
server.get('/rest/workflows', (schema: AppSchema) => {
const { models: data } = schema.all('workflow');
return new Response(200, {}, { data });
});
server.get('/rest/active-workflows', (schema: AppSchema) => {
const { models: data } = schema.all('workflow');
return new Response(200, {}, { data });
});
}

View file

@ -2,6 +2,8 @@ import { userFactory } from './user';
import { credentialFactory } from './credential';
import { credentialTypeFactory } from './credentialType';
import { variableFactory } from './variable';
import { workflowFactory } from './workflow';
import { tagFactory } from './tag';
export * from './user';
export * from './credential';
@ -13,4 +15,6 @@ export const factories = {
credentialType: credentialTypeFactory,
user: userFactory,
variable: variableFactory,
workflow: workflowFactory,
tag: tagFactory,
};

View file

@ -0,0 +1,12 @@
import { Factory } from 'miragejs';
import type { ITag } from '@/Interface';
import { faker } from '@faker-js/faker';
export const tagFactory = Factory.extend<ITag>({
id(i: string) {
return i;
},
name() {
return faker.lorem.word();
},
});

View file

@ -0,0 +1,18 @@
import { Factory } from 'miragejs';
import type { IWorkflowDb } from '@/Interface';
import { faker } from '@faker-js/faker';
export const workflowFactory = Factory.extend<IWorkflowDb>({
id(i: string) {
return i;
},
name() {
return faker.lorem.word();
},
createdAt() {
return faker.date.recent().toISOString();
},
tags() {
return faker.lorem.words(2.5).split(' ');
},
});

View file

@ -0,0 +1,7 @@
import { tags } from './tags';
import { workflows } from './workflows';
export const fixtures = {
tags,
workflows,
};

View file

@ -0,0 +1,15 @@
import type { ITag } from '@/Interface';
export const tags: ITag[] = [
{
id: '1',
name: 'tag1',
},
{
id: '2',
name: 'tag2',
},
{
id: '3',
name: 'tag3',
},
];

View file

@ -0,0 +1,47 @@
import type { IWorkflowDb } from '@/Interface';
import { faker } from '@faker-js/faker';
export const workflows = [
{
id: '1',
name: 'workflow1',
tags: [],
},
{
id: '2',
name: 'workflow2',
tags: [
{ id: '1', name: 'tag1' },
{ id: '2', name: 'tag2' },
],
},
{
id: '3',
name: 'workflow3',
tags: [
{ id: '1', name: 'tag1' },
{ id: '3', name: 'tag3' },
],
},
{
id: '4',
name: 'workflow4',
tags: [
{ id: '2', name: 'tag2' },
{ id: '3', name: 'tag3' },
],
},
{
id: '5',
name: 'workflow5',
tags: [
{ id: '1', name: 'tag1' },
{ id: '2', name: 'tag2' },
{ id: '3', name: 'tag3' },
],
},
].map((wf, idx) => ({
...wf,
createdAt: faker.date.recent().toISOString(),
updatedAt: new Date(`2024-1-${idx + 1}`).toISOString(),
})) as IWorkflowDb[];

View file

@ -2,12 +2,15 @@ import { createServer } from 'miragejs';
import { endpoints } from './endpoints';
import { models } from './models';
import { factories } from './factories';
import { fixtures } from './fixtures';
export function setupServer() {
const server = createServer({
models,
factories,
fixtures,
seeds(server) {
server.loadFixtures('tags', 'workflows');
server.createList('credentialType', 8);
server.create('user', {
firstName: 'Nathan',

View file

@ -2,10 +2,14 @@ import { UserModel } from './user';
import { CredentialModel } from './credential';
import { CredentialTypeModel } from './credentialType';
import { VariableModel } from './variable';
import { WorkflowModel } from './workflow';
import { TagModel } from './tag';
export const models = {
credential: CredentialModel,
credentialType: CredentialTypeModel,
user: UserModel,
variable: VariableModel,
workflow: WorkflowModel,
tag: TagModel,
};

View file

@ -0,0 +1,5 @@
import type { ITag } from '@/Interface';
import { Model } from 'miragejs';
import type { ModelDefinition } from 'miragejs/-types';
export const TagModel: ModelDefinition<ITag> = Model.extend({});

View file

@ -0,0 +1,5 @@
import type { IWorkflowDb } from '@/Interface';
import { Model } from 'miragejs';
import type { ModelDefinition } from 'miragejs/-types';
export const WorkflowModel: ModelDefinition<IWorkflowDb> = Model.extend({});

View file

@ -454,6 +454,7 @@ export default defineComponent({
this.resettingFilters = true;
this.sendFiltersTelemetry('reset');
this.$emit('update:filters', this.filtersModel);
},
focusSearchInput() {
if (this.$refs.search) {

View file

@ -0,0 +1,99 @@
import { afterAll, beforeAll } from 'vitest';
import { setActivePinia, createPinia } from 'pinia';
import { waitFor } from '@testing-library/vue';
import userEvent from '@testing-library/user-event';
import { setupServer } from '@/__tests__/server';
import WorkflowsView from '@/views/WorkflowsView.vue';
import { useSettingsStore } from '@/stores/settings.store';
import { useUsersStore } from '@/stores/users.store';
import { createComponentRenderer } from '@/__tests__/render';
const originalOffsetHeight = Object.getOwnPropertyDescriptor(
HTMLElement.prototype,
'offsetHeight',
) as PropertyDescriptor;
describe('WorkflowsView', () => {
let server: ReturnType<typeof setupServer>;
let pinia: ReturnType<typeof createPinia>;
let settingsStore: ReturnType<typeof useSettingsStore>;
let usersStore: ReturnType<typeof useUsersStore>;
const renderComponent = createComponentRenderer(WorkflowsView, {
global: {
mocks: {
$route: {
query: {},
},
$router: {
replace: vi.fn(),
},
},
},
});
beforeAll(() => {
Object.defineProperties(HTMLElement.prototype, {
offsetHeight: {
get() {
return this.getAttribute('data-test-id') === 'resources-list' ? 1000 : 100;
},
},
});
server = setupServer();
});
afterAll(() => {
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', originalOffsetHeight);
});
beforeEach(async () => {
pinia = createPinia();
setActivePinia(pinia);
settingsStore = useSettingsStore();
usersStore = useUsersStore();
await settingsStore.getSettings();
await usersStore.fetchUsers();
await usersStore.loginWithCookie();
});
afterAll(() => {
server.shutdown();
});
it('should filter workflows by tags', async () => {
const { container, getByTestId, getAllByTestId, queryByTestId } = renderComponent({
pinia,
});
expect(container.querySelectorAll('.n8n-loading')).toHaveLength(3);
expect(queryByTestId('resources-list')).not.toBeInTheDocument();
await waitFor(() => {
expect(container.querySelectorAll('.n8n-loading')).toHaveLength(0);
// There are 5 workflows defined in server fixtures
expect(getAllByTestId('resources-list-item')).toHaveLength(5);
});
await userEvent.click(
getAllByTestId('resources-list-item')[0].querySelector('.n8n-tag') as HTMLElement,
);
await waitFor(() => {
expect(getAllByTestId('resources-list-item').length).toBeLessThan(5);
});
await userEvent.click(getByTestId('workflows-filter-reset'));
await waitFor(() => {
expect(getAllByTestId('resources-list-item')).toHaveLength(5);
});
await userEvent.click(
getAllByTestId('resources-list-item')[3].querySelector('.n8n-tag') as HTMLElement,
);
await waitFor(() => {
expect(getAllByTestId('resources-list-item').length).toBeLessThan(5);
});
});
});