mirror of
https://gitee.com/pnoker/iot-dc3.git
synced 2026-11-01 02:31:46 +08:00
Apply IDE formatting across all Vue, TypeScript, SCSS and test files. No logic changes — whitespace, quotes and brace style only.
107 lines
4.6 KiB
TypeScript
107 lines
4.6 KiB
TypeScript
/*
|
|
* Copyright 2016-present the IoT DC3 original author or authors.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import {mount, type VueWrapper} from '@vue/test-utils';
|
|
import {createPinia, setActivePinia} from 'pinia';
|
|
import type {Component, ComponentOptions} from 'vue';
|
|
import {createMemoryHistory, createRouter, type RouteRecordRaw} from 'vue-router';
|
|
|
|
import i18n from '@/config/i18n';
|
|
|
|
import {createElButtonStub, createElFormStub, createElPaginationStub, layoutStubs} from '../setup/stubs/element-plus'; // Shared scaffolding for `tests/views/*.test.ts`. Most list pages share the
|
|
|
|
// Shared scaffolding for `tests/views/*.test.ts`. Most list pages share the
|
|
// same Element Plus surface (Card / Tool toolbar / Pagination / Tag) and the
|
|
// same lifecycle (mount → list API fires once → row renders). This helper
|
|
// folds that boilerplate into one call so each view test can stay focused
|
|
// on its own assertions.
|
|
|
|
export interface MountListPageOptions {
|
|
/** Component under test. */
|
|
component: Component;
|
|
/** Props passed to the component. */
|
|
props?: Record<string, unknown>;
|
|
/** Slots passed to the component. */
|
|
slots?: Record<string, string>;
|
|
/** Initial route query. The page's setup() typically reads from useRoute(). */
|
|
routeQuery?: Record<string, string>;
|
|
/** Initial route name to push the test router to. Defaults to a noop /test route. */
|
|
routePath?: string;
|
|
/** Extra named routes the page may navigate to (router.push({ name }) calls). */
|
|
extraRoutes?: RouteRecordRaw[];
|
|
/** Additional stubs merged on top of layoutStubs + button/form/pagination. */
|
|
stubs?: Record<string, ComponentOptions | unknown>;
|
|
/** Skip the default ElForm stub when the component renders no form. */
|
|
skipForm?: boolean;
|
|
}
|
|
|
|
export async function mountListPage(opts: MountListPageOptions): Promise<VueWrapper> {
|
|
const noop = {template: '<div />'};
|
|
|
|
// Some pages (Resource, agentic) reach for Pinia stores during setup.
|
|
// Establish a fresh active pinia per mount so each test starts clean.
|
|
setActivePinia(createPinia());
|
|
|
|
const routes: RouteRecordRaw[] = [{name: 'test', path: '/test', component: noop}, ...(opts.extraRoutes ?? [])];
|
|
|
|
const router = createRouter({
|
|
history: createMemoryHistory(),
|
|
routes,
|
|
});
|
|
|
|
const targetPath = opts.routePath ?? '/test';
|
|
await router.push({path: targetPath, query: opts.routeQuery ?? {}});
|
|
await router.isReady();
|
|
|
|
const {ElForm} = createElFormStub();
|
|
|
|
const wrapper = mount(opts.component, {
|
|
props: opts.props,
|
|
slots: opts.slots,
|
|
global: {
|
|
plugins: [i18n, router],
|
|
// v-loading directive is registered by Element Plus at runtime but
|
|
// not present under the unplugin auto-import we use in tests; the
|
|
// strict warning handler in vitest.setup would promote a missing
|
|
// directive to a thrown error. Stub it as a no-op here.
|
|
directives: {loading: () => undefined},
|
|
stubs: {
|
|
...layoutStubs,
|
|
ElButton: createElButtonStub(),
|
|
ElPagination: createElPaginationStub(),
|
|
...(opts.skipForm ? {} : {ElForm}),
|
|
// Most list pages compose with these — provide light passthroughs
|
|
// so dialog refs / popconfirms don't blow up the smoke path.
|
|
BlankCard: {template: '<section class="blank-card-stub"><slot /></section>'},
|
|
SkeletonCard: {template: '<div class="skeleton-card-stub"><slot /></div>'},
|
|
ToolCard: {
|
|
props: ['formModel', 'page', 'hideSort', 'hidePagination'],
|
|
emits: ['search', 'reset', 'refresh', 'sort', 'size-change', 'current-change'],
|
|
// Mirror the real ToolCard filters-slot contract (`:search`, `:form-data`)
|
|
// so engine-driven pages that destructure `{ search }` don't hit an
|
|
// undefined handler on `@keyup.enter`.
|
|
template:
|
|
'<section class="tool-card-stub"><slot name="filters" :form-data="formModel" :search="() => $emit(\'search\', formModel)" /><slot name="actions" /></section>',
|
|
},
|
|
...(opts.stubs ?? {}),
|
|
},
|
|
},
|
|
});
|
|
|
|
return wrapper;
|
|
}
|