fix search feature
Build & Push / Pipeline Tests (push) Failing after 1m14s
Build & Push / Build & Push Docker Image (push) Has been skipped
Test / Type Check (all packages) (push) Successful in 53s
Test / API Unit Tests (push) Failing after 50s
Test / Homepage Unit Tests (push) Successful in 45s
Test / Carplace Unit Tests (push) Successful in 44s
Test / Admin Unit Tests (push) Successful in 42s
Test / Dashboard Unit Tests (push) Successful in 43s
Test / API Integration Tests (push) Successful in 1m4s
Build & Push / Pipeline Tests (push) Failing after 1m14s
Build & Push / Build & Push Docker Image (push) Has been skipped
Test / Type Check (all packages) (push) Successful in 53s
Test / API Unit Tests (push) Failing after 50s
Test / Homepage Unit Tests (push) Successful in 45s
Test / Carplace Unit Tests (push) Successful in 44s
Test / Admin Unit Tests (push) Successful in 42s
Test / Dashboard Unit Tests (push) Successful in 43s
Test / API Integration Tests (push) Successful in 1m4s
This commit is contained in:
@@ -6,6 +6,7 @@ function installBrowser(token?: string) {
|
||||
value: {
|
||||
location: {
|
||||
hostname: 'localhost',
|
||||
origin: 'http://localhost',
|
||||
},
|
||||
localStorage: {
|
||||
getItem: vi.fn(() => token ?? null),
|
||||
@@ -28,7 +29,7 @@ afterEach(() => {
|
||||
})
|
||||
|
||||
describe('dashboard apiFetch', () => {
|
||||
it('adds JSON headers and sends cookies for browser requests', async () => {
|
||||
it('sends cookies without forcing JSON headers for bodyless browser requests', async () => {
|
||||
installBrowser()
|
||||
const fetchMock = vi.fn(async () => ({
|
||||
ok: true,
|
||||
@@ -39,6 +40,23 @@ describe('dashboard apiFetch', () => {
|
||||
const { apiFetch } = await import('./api')
|
||||
await expect(apiFetch('/team')).resolves.toEqual({ ok: true })
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledWith(expect.stringMatching(/\/api\/v1\/team$/), expect.objectContaining({
|
||||
credentials: 'include',
|
||||
headers: expect.not.objectContaining({ 'Content-Type': expect.any(String) }),
|
||||
}))
|
||||
})
|
||||
|
||||
it('adds JSON headers for JSON payload requests', async () => {
|
||||
installBrowser()
|
||||
const fetchMock = vi.fn(async () => ({
|
||||
ok: true,
|
||||
json: async () => ({ data: { ok: true } }),
|
||||
}))
|
||||
Object.defineProperty(globalThis, 'fetch', { configurable: true, value: fetchMock })
|
||||
|
||||
const { apiFetch } = await import('./api')
|
||||
await expect(apiFetch('/team', { method: 'POST', body: JSON.stringify({ name: 'Ops' }) })).resolves.toEqual({ ok: true })
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledWith(expect.stringMatching(/\/api\/v1\/team$/), expect.objectContaining({
|
||||
credentials: 'include',
|
||||
headers: expect.objectContaining({
|
||||
@@ -133,6 +151,22 @@ describe('dashboard apiFetch', () => {
|
||||
expect(calledUrl).not.toContain('/api/v1/api/v1')
|
||||
})
|
||||
|
||||
it('resolves the API origin for realtime connections from relative and absolute API bases', async () => {
|
||||
installBrowser()
|
||||
setBrowserHostname('rentaldrivego.ma')
|
||||
process.env.NEXT_PUBLIC_API_URL = '/dashboard/api/v1'
|
||||
|
||||
let api = await import('./api')
|
||||
expect(api.resolveApiOrigin()).toBe('http://localhost')
|
||||
|
||||
vi.resetModules()
|
||||
installBrowser()
|
||||
process.env.NEXT_PUBLIC_API_URL = 'http://localhost:4000/api/v1'
|
||||
|
||||
api = await import('./api')
|
||||
expect(api.resolveApiOrigin()).toBe('http://localhost:4000')
|
||||
})
|
||||
|
||||
it('does not force JSON content type for FormData payloads', async () => {
|
||||
installBrowser()
|
||||
const fetchMock = vi.fn(async () => ({ ok: true, json: async () => ({ data: { uploaded: true } }) }))
|
||||
|
||||
@@ -34,6 +34,16 @@ export function resolveApiBase(): string {
|
||||
return normalizeApiBase(shouldUseDashboardProxy(configuredApiBase) ? DASHBOARD_PROXY_API_BASE : (configuredApiBase || DASHBOARD_PROXY_API_BASE))
|
||||
}
|
||||
|
||||
export function resolveApiOrigin(): string | null {
|
||||
if (typeof window === 'undefined') return null
|
||||
|
||||
try {
|
||||
return new URL(resolveApiBase(), window.location.origin).origin
|
||||
} catch {
|
||||
return window.location.origin
|
||||
}
|
||||
}
|
||||
|
||||
export const API_BASE = resolveApiBase()
|
||||
|
||||
export const EMPLOYEE_PROFILE_KEY = 'employee_profile'
|
||||
@@ -45,7 +55,7 @@ export async function apiFetch<T>(path: string, options?: RequestInit): Promise<
|
||||
...(options?.headers as Record<string, string> ?? {}),
|
||||
}
|
||||
|
||||
if (!isFormData) {
|
||||
if (!isFormData && options?.body !== undefined) {
|
||||
headers['Content-Type'] = 'application/json'
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,12 @@ export const dashboardRoutePolicies: Record<string, DashboardRoutePolicy> = {
|
||||
'/subscription': OWNER_ONLY_BILLING_RECOVERY_POLICY,
|
||||
'/subscription/success': OWNER_ONLY_BILLING_RECOVERY_POLICY,
|
||||
'/subscription/cancel': OWNER_ONLY_BILLING_RECOVERY_POLICY,
|
||||
'/search': {
|
||||
authenticationRequired: true,
|
||||
allowedRoles: null,
|
||||
subscriptionRequired: true,
|
||||
menuRegistrationRequired: false,
|
||||
},
|
||||
}
|
||||
|
||||
export function resolveDashboardRoutePolicy(pathname: string): DashboardRoutePolicy {
|
||||
|
||||
Reference in New Issue
Block a user