diff --git a/resources/js/components/common/KeyValueParameters/KeyValueParameters.vue b/resources/js/components/common/KeyValueParameters/KeyValueParameters.vue
index 8ecfec9..00bec22 100644
--- a/resources/js/components/common/KeyValueParameters/KeyValueParameters.vue
+++ b/resources/js/components/common/KeyValueParameters/KeyValueParameters.vue
@@ -242,7 +242,11 @@ const shouldShowGeneratorIcon = (index: number, parameter: ExtendedParameter) =>
/>
-
+
-
+
{
/>
- {{ duration }}
+ {{ duration }}
/
- {{ size }}
+ {{ size }}
diff --git a/resources/js/components/domain/Client/Response/ResponseStatus/ResponseStatusCode.vue b/resources/js/components/domain/Client/Response/ResponseStatus/ResponseStatusCode.vue
index 9885f68..5262033 100644
--- a/resources/js/components/domain/Client/Response/ResponseStatus/ResponseStatusCode.vue
+++ b/resources/js/components/domain/Client/Response/ResponseStatus/ResponseStatusCode.vue
@@ -14,8 +14,15 @@ const props = defineProps
();
-
{{ props.status }}
-
+
+ {{ props.status }}
+
+
{{ props.response.statusCode }} -
{{ props.response.statusText }}
diff --git a/resources/js/components/domain/Client/Response/ResponseStatus/StatusIndicator.vue b/resources/js/components/domain/Client/Response/ResponseStatus/StatusIndicator.vue
index fa18cf9..617941a 100644
--- a/resources/js/components/domain/Client/Response/ResponseStatus/StatusIndicator.vue
+++ b/resources/js/components/domain/Client/Response/ResponseStatus/StatusIndicator.vue
@@ -30,6 +30,7 @@ const indicatorColor = computed(() => {
diff --git a/resources/js/components/domain/Client/Response/ResponseViewer.vue b/resources/js/components/domain/Client/Response/ResponseViewer.vue
index 894a423..5696d0b 100644
--- a/resources/js/components/domain/Client/Response/ResponseViewer.vue
+++ b/resources/js/components/domain/Client/Response/ResponseViewer.vue
@@ -21,8 +21,12 @@ const lastLog = computed(() => historyStore.lastLog);
-
-
-
+
+
+
diff --git a/resources/js/stores/request/useRequestExecutorStore.ts b/resources/js/stores/request/useRequestExecutorStore.ts
index 0ee2f06..f4d4405 100644
--- a/resources/js/stores/request/useRequestExecutorStore.ts
+++ b/resources/js/stores/request/useRequestExecutorStore.ts
@@ -1,5 +1,6 @@
import { useHttpClient } from '@/composables/request/useHttpClient';
import { ErrorPlainResponse, PendingRequest } from '@/interfaces/http';
+import { useRequestsHistoryStore } from '@/stores';
import {
createRequestTimer,
generateErrorRequestLog,
@@ -7,7 +8,6 @@ import {
} from '@/utils/request';
import { defineStore } from 'pinia';
import { computed, ref } from 'vue';
-import { useRequestsHistoryStore } from './useRequestsHistoryStore';
/**
* Store for managing request execution and timing.
diff --git a/resources/js/tests/_utils/test-utils.ts b/resources/js/tests/_utils/test-utils.ts
index e360f71..0699d7b 100644
--- a/resources/js/tests/_utils/test-utils.ts
+++ b/resources/js/tests/_utils/test-utils.ts
@@ -1,14 +1,14 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-
+import userEvent from '@testing-library/user-event';
+import { render, RenderOptions, screen } from '@testing-library/vue';
+import type { MountingOptions } from '@vue/test-utils';
import { mount, VueWrapper } from '@vue/test-utils';
import { createPinia, setActivePinia } from 'pinia';
import { Component } from 'vue';
import { createRouter, createWebHistory, Router } from 'vue-router';
-/*
- * Custom test utilities for consistent Vue component testing.
- * Provides common setup patterns and helper functions.
- */
+export interface RenderWithProvidersOptions extends RenderOptions {
+ router?: Router;
+}
export function createMockRouter(): Router {
return createRouter({
@@ -33,31 +33,59 @@ export function createMockRouter(): Router {
});
}
-/**
- * Mount a Vue component with common test setup.
- * Includes Pinia store, router, and global stubs.
- */
-export function mountWithPlugins(
+export function renderWithProviders(
component: Component,
- options: any = {},
-): VueWrapper {
+ options: RenderWithProvidersOptions = {},
+) {
const pinia = createPinia();
setActivePinia(pinia);
- const router = createMockRouter();
+ const router = options.router ?? createMockRouter();
+
+ return {
+ user: userEvent.setup(),
+ ...render(component, {
+ ...options,
+ global: {
+ ...(options.global ?? {}),
+ plugins: [...(options.global?.plugins ?? []), pinia, router],
+ stubs: {
+ keepAlive: true,
+ Transition: true,
+ Teleport: true,
+ 'router-link': true,
+ 'router-view': true,
+ ...(options.global?.stubs ?? {}),
+ },
+ },
+ }),
+ };
+}
+
+export function mountWithPlugins(
+ component: Component,
+ options: MountingOptions & { router?: Router } = {},
+): VueWrapper {
+ const pinia = createPinia();
+ setActivePinia(pinia);
+
+ const router = options.router ?? createMockRouter();
return mount(component, {
+ ...options,
global: {
- plugins: [pinia, router],
+ ...(options.global ?? {}),
+ plugins: [...(options.global?.plugins ?? []), pinia, router],
stubs: {
+ keepAlive: true,
+ Transition: true,
+ Teleport: true,
'router-link': true,
'router-view': true,
- 'keep-alive': true,
- transition: true,
- 'transition-group': true,
- teleport: true,
+ ...(options.global?.stubs ?? {}),
},
},
- ...options,
});
}
+
+export { screen };
diff --git a/resources/js/tests/_utils/themes-test-utils.ts b/resources/js/tests/_utils/themes-test-utils.ts
deleted file mode 100644
index bd737d3..0000000
--- a/resources/js/tests/_utils/themes-test-utils.ts
+++ /dev/null
@@ -1,244 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-
-import { mount, VueWrapper } from '@vue/test-utils';
-import { createPinia, setActivePinia } from 'pinia';
-import { describe, expect, it } from 'vitest';
-import { Component } from 'vue';
-import { createRouter, createWebHistory, Router } from 'vue-router';
-
-/**
- * Test utilities for dark theme testing.
- * Provides helpers to test components in both light and dark modes.
- */
-
-// Mock router for testing
-function createMockRouter(): Router {
- return createRouter({
- history: createWebHistory(),
- routes: [
- {
- path: '/',
- name: 'home',
- component: { template: 'Home
' },
- },
- {
- path: '/main',
- name: 'main',
- component: { template: 'Main
' },
- },
- {
- path: '/status',
- name: 'status',
- component: { template: 'Status
' },
- },
- ],
- });
-}
-
-/**
- * Mount a component with dark theme simulation.
- * Adds dark class to the document element to simulate dark mode.
- */
-export function mountWithDarkTheme(
- component: Component,
- options: any = {},
-): VueWrapper {
- const pinia = createPinia();
- setActivePinia(pinia);
-
- const router = createMockRouter();
-
- // Add dark class to document element
- document.documentElement.classList.add('dark');
-
- const wrapper = mount(component, {
- global: {
- plugins: [pinia, router],
- stubs: {
- 'router-link': true,
- 'router-view': true,
- 'keep-alive': true,
- transition: true,
- 'transition-group': true,
- teleport: true,
- },
- },
- ...options,
- });
-
- // Store original unmount function
- const originalUnmount = wrapper.unmount.bind(wrapper);
-
- // Override unmount to clean up dark class
- wrapper.unmount = () => {
- document.documentElement.classList.remove('dark');
-
- return originalUnmount();
- };
-
- return wrapper;
-}
-
-/**
- * Mount a component with light theme simulation.
- * Ensures dark class is not present on the document element.
- */
-export function mountWithLightTheme(
- component: Component,
- options: any = {},
-): VueWrapper {
- const pinia = createPinia();
- setActivePinia(pinia);
-
- const router = createMockRouter();
-
- // Ensure dark class is not present
- document.documentElement.classList.remove('dark');
-
- return mount(component, {
- global: {
- plugins: [pinia, router],
- stubs: {
- 'router-link': true,
- 'router-view': true,
- 'keep-alive': true,
- transition: true,
- 'transition-group': true,
- teleport: true,
- },
- },
- ...options,
- });
-}
-
-/**
- * Test a component in both light and dark themes.
- * Runs the same test function for both themes.
- */
-export function testBothThemes(
- component: Component,
- testFn: (wrapper: VueWrapper, theme: 'light' | 'dark') => void,
- options: any = {},
-) {
- describe('Light Theme', () => {
- it('should render correctly in light theme', () => {
- const wrapper = mountWithLightTheme(component, options);
- testFn(wrapper, 'light');
- wrapper.unmount();
- });
- });
-
- describe('Dark Theme', () => {
- it('should render correctly in dark theme', () => {
- const wrapper = mountWithDarkTheme(component, options);
- testFn(wrapper, 'dark');
- wrapper.unmount();
- });
- });
-}
-
-/**
- * Assert that a component has the correct dark theme classes.
- */
-export function expectDarkThemeClasses(
- wrapper: VueWrapper,
- expectedClasses: string[],
-) {
- const element = wrapper.element;
- const classList = Array.from(element.classList);
-
- expectedClasses.forEach(expectedClass => {
- expect(classList).toContain(expectedClass);
- });
-}
-
-/**
- * Assert that a component has the correct light theme classes.
- */
-export function expectLightThemeClasses(
- wrapper: VueWrapper,
- expectedClasses: string[],
-) {
- const element = wrapper.element;
- const classList = Array.from(element.classList);
-
- expectedClasses.forEach(expectedClass => {
- expect(classList).toContain(expectedClass);
- });
-}
-
-/**
- * Common dark theme class patterns for testing.
- */
-export const darkThemePatterns = {
- // Background colors
- backgrounds: {
- primary: 'dark:bg-zinc-950',
- secondary: 'dark:bg-zinc-900',
- tertiary: 'dark:bg-zinc-800',
- muted: 'dark:bg-gray-800',
- },
-
- // Text colors
- text: {
- primary: 'dark:text-zinc-50',
- secondary: 'dark:text-zinc-100',
- muted: 'dark:text-zinc-400',
- mutedSecondary: 'dark:text-gray-300',
- },
-
- // Border colors
- borders: {
- primary: 'dark:border-zinc-800',
- secondary: 'dark:border-gray-700',
- },
-
- // Focus states
- focus: {
- ring: 'dark:focus-visible:ring-zinc-300',
- ringOffset: 'dark:ring-offset-zinc-950',
- },
-
- // Hover states
- hover: {
- primary: 'dark:hover:bg-zinc-800',
- secondary: 'dark:hover:bg-gray-700',
- },
-};
-
-/**
- * Common light theme class patterns for testing.
- */
-export const lightThemePatterns = {
- // Background colors
- backgrounds: {
- primary: 'bg-white',
- secondary: 'bg-zinc-50',
- tertiary: 'bg-gray-50',
- },
-
- // Text colors
- text: {
- primary: 'text-zinc-950',
- secondary: 'text-zinc-900',
- muted: 'text-zinc-500',
- },
-
- // Border colors
- borders: {
- primary: 'border-zinc-200',
- secondary: 'border-gray-100',
- },
-
- // Focus states
- focus: {
- ring: 'focus-visible:ring-zinc-950',
- ringOffset: 'ring-offset-white',
- },
-
- // Hover states
- hover: {
- primary: 'hover:bg-zinc-100',
- secondary: 'hover:bg-gray-50',
- },
-};
diff --git a/resources/js/tests/components/RequestHeaders.test.ts b/resources/js/tests/components/RequestHeaders.test.ts
index 960e710..d485306 100644
--- a/resources/js/tests/components/RequestHeaders.test.ts
+++ b/resources/js/tests/components/RequestHeaders.test.ts
@@ -1,134 +1,189 @@
import RequestHeaders from '@/components/domain/Client/Request/RequestHeader/RequestHeaders.vue';
-import { mountWithPlugins } from '@/tests/_utils/test-utils';
+import { AuthorizationType } from '@/interfaces/generated';
+import { GeneratorType, PendingRequest, RequestBodyTypeEnum } from '@/interfaces/http';
+import { renderWithProviders } from '@/tests/_utils/test-utils';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { nextTick, reactive, ref } from 'vue';
-// Mocks for stores consumed via '@/stores' barrel
-const mockRequestStore = reactive({
- pendingRequestData: ref(null), // eslint-disable-line @typescript-eslint/no-explicit-any
- updateRequestHeaders: vi.fn(),
-});
-
const mockConfigStore = reactive({
headers: [
- {
- header: 'X-Global',
- type: 'raw',
- value: 'foo',
- },
+ { header: 'X-Global', type: 'raw', value: 'foo' },
+ { header: 'X-Generated', type: 'generator', value: GeneratorType.Email },
],
});
-const mockValueGeneratorStore = reactive({
- generateValue: vi.fn(),
+const generateValue = vi.fn(() => 'generated@example.com');
+
+const mockRequestStore = reactive({
+ pendingRequestData: ref(null),
+ updateRequestHeaders: vi.fn(),
});
-vi.mock('@/stores', () => ({
- useRequestStore: () => mockRequestStore,
- useConfigStore: () => mockConfigStore,
- useValueGeneratorStore: () => mockValueGeneratorStore,
-}));
+vi.mock('@/stores', async importOriginal => {
+ const actual = await importOriginal