e9da21b57e
- composables/useApi.ts: base API client with runtimeConfig - composables/useEquipment.ts: equipment API wrapper (list, detail, categories) - components/EquipmentCard.vue: card with image/placeholder, badge, name, price, add-to-cart - pages/mietkatalog.vue: SSR list with search, category chips, sort, pagination, skeleton, empty/error states - pages/mietkatalog/[id].vue: SSR detail with specs table, related items, breadcrumb, add-to-cart - nuxt.config.ts: runtimeConfig with apiBase - 101 vitest tests passing (5 files) - Build: 0 errors, 2.09 MB
100 lines
3.1 KiB
TypeScript
100 lines
3.1 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { readFileSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
|
|
describe("Equipment Detail Page", () => {
|
|
const pagePath = resolve(__dirname, "../../pages/mietkatalog/[id].vue");
|
|
const content = readFileSync(pagePath, "utf-8");
|
|
|
|
it("should use useAsyncData for SSR data fetching", () => {
|
|
expect(content).toContain("useAsyncData");
|
|
});
|
|
|
|
it("should use useEquipment composable", () => {
|
|
expect(content).toContain("useEquipment");
|
|
});
|
|
|
|
it("should fetch detail by route param id", () => {
|
|
expect(content).toContain("route.params.id");
|
|
expect(content).toContain("equipmentApi.detail");
|
|
});
|
|
|
|
it("should have breadcrumb navigation Home > Mietkatalog > Item", () => {
|
|
expect(content).toContain("Breadcrumb");
|
|
expect(content).toContain('to="/"');
|
|
expect(content).toContain('to="/mietkatalog"');
|
|
expect(content).toContain("Home");
|
|
expect(content).toContain("Mietkatalog");
|
|
});
|
|
|
|
it("should display equipment name", () => {
|
|
expect(content).toContain('data-testid="equipment-name"');
|
|
expect(content).toContain("data.name");
|
|
});
|
|
|
|
it("should display equipment description", () => {
|
|
expect(content).toContain('data-testid="equipment-description"');
|
|
});
|
|
|
|
it("should display specs table", () => {
|
|
expect(content).toContain('data-testid="equipment-specs"');
|
|
expect(content).toContain("Spezifikationen");
|
|
expect(content).toContain("specifications");
|
|
});
|
|
|
|
it("should display image with placeholder fallback", () => {
|
|
expect(content).toContain("data.images");
|
|
expect(content).toContain("v-if");
|
|
expect(content).toContain("svg");
|
|
});
|
|
|
|
it("should have Mietanfrage add-to-cart button", () => {
|
|
expect(content).toContain('data-testid="add-to-cart-detail"');
|
|
expect(content).toContain("Mietanfrage");
|
|
expect(content).toContain("onAddToCart");
|
|
});
|
|
|
|
it("should show ErrorState for non-existent ID", () => {
|
|
expect(content).toContain("ErrorState");
|
|
expect(content).toContain("error");
|
|
expect(content).toContain("nicht gefunden");
|
|
});
|
|
|
|
it("should have link back to /mietkatalog on error", () => {
|
|
expect(content).toContain("/mietkatalog");
|
|
});
|
|
|
|
it("should fetch related items by same category", () => {
|
|
expect(content).toContain("related");
|
|
expect(content).toContain("category");
|
|
expect(content).toContain("EquipmentCard");
|
|
});
|
|
|
|
it("should display rental price", () => {
|
|
expect(content).toContain('data-testid="equipment-price"');
|
|
expect(content).toContain("rental_price");
|
|
});
|
|
|
|
it("should use useHead for dynamic page title", () => {
|
|
expect(content).toContain("useHead");
|
|
});
|
|
|
|
it("should use TypeScript with lang=ts", () => {
|
|
expect(content).toContain('script setup lang="ts"');
|
|
});
|
|
|
|
it("should use Tailwind classes, no inline styles", () => {
|
|
expect(content).not.toContain('style="');
|
|
});
|
|
|
|
it("should display availability status", () => {
|
|
expect(content).toContain("available");
|
|
expect(content).toContain("Verfügbar");
|
|
});
|
|
|
|
it("should show brand if available", () => {
|
|
expect(content).toContain("data.brand");
|
|
expect(content).toContain("Marke");
|
|
});
|
|
});
|