import test from 'node:test' import assert from 'node:assert/strict' import { readSource } from './helpers.ts' import { isAuthEndpointRequest, isLoginLocation, shouldRedirectUnauthorized, } from '../src/api/envelope.ts' test('test_task_026_unauthorized_redirect_normal_primary_path', () => { // 正常主路径:普通业务页内某受保护接口 401,应跳转登录(携带目标路径)。 assert.equal( shouldRedirectUnauthorized('/admin-vue/account/users', '/api/admin/current-user'), true, '业务页内受保护请求 401 应触发跳登录', ) }) test('test_task_026_unauthorized_redirect_normal_variant_input', () => { // 正常变体:已经在登录页(含 redirect 查询)时任何 401 不再二次踢回,避免循环。 assert.equal(shouldRedirectUnauthorized('/login', '/api/admin/current-user'), false) assert.equal(shouldRedirectUnauthorized('/login?redirect=%2Fadmin-vue%2Faccount%2Fusers', '/api/admin/current-user'), false) }) test('test_task_026_unauthorized_redirect_normal_repeated_operation_is_idempotent', () => { // 正常重复:纯函数重复求值结果稳定,无副作用。 const once = shouldRedirectUnauthorized('/login', '/login') const twice = shouldRedirectUnauthorized('/login', '/login') assert.equal(once, false) assert.equal(twice, once) assert.equal(isLoginLocation('/login?redirect=/x'), isLoginLocation('/login?redirect=/x')) }) test('test_task_026_unauthorized_redirect_boundary_empty_input', () => { // 边界空值:当前路径为空/请求 URL 缺省时不误判为登录场景,按应跳转处理。 assert.equal(shouldRedirectUnauthorized('', undefined), true) assert.equal(shouldRedirectUnauthorized('/admin-vue/', ''), true) assert.equal(isLoginLocation(''), false) assert.equal(isAuthEndpointRequest(undefined), false) }) test('test_task_026_unauthorized_redirect_boundary_single_item', () => { // 边界单元素:401 请求本身是登录提交时不得再跳登录(否则吞掉登录失败反馈)。 assert.equal(shouldRedirectUnauthorized('/admin-vue/account/users', '/login'), false) assert.equal(isAuthEndpointRequest('/login'), true) }) test('test_task_026_unauthorized_redirect_boundary_limit_or_missing_field', () => { // 边界上限/缺字段:登录端点支持绝对 URL 与带查询串的受保护请求两种形态。 assert.equal(isAuthEndpointRequest('http://api.aishufu.top/login'), true) assert.equal(isAuthEndpointRequest('https://aishufu.top/login?device=web'), true) assert.equal(shouldRedirectUnauthorized('/admin-vue/', '/api/admin/current-user?x=1'), true) assert.equal(isAuthEndpointRequest('/api/admin/current-user?x=1'), false) }) test('test_task_026_unauthorized_redirect_invalid_input_rejected', () => { // 异常输入:非法/非字符串输入不抛错,且默认按“应跳转”处理而非误放行。 assert.equal(shouldRedirectUnauthorized(undefined as unknown as string, undefined), true) assert.equal(shouldRedirectUnauthorized(null as unknown as string, null as unknown as string), true) assert.equal(isAuthEndpointRequest(42 as unknown as string), false) assert.equal(isLoginLocation('/admin-vue/login'), false) }) test('test_task_026_unauthorized_redirect_dependency_failure_returns_actionable_message', () => { // 依赖失败:http 层 success/error 两支都要先过守卫再带目标路径跳 /login。 const http = readSource('src/api/http.ts') assert.match(http, /shouldRedirectUnauthorized/, '401 跳转必须经守卫避免登录页循环') assert.match(http, /login\?redirect=/, '跳转仍携带目标路径参数') assert.match(http, /interceptors\.response/) assert.match(http, /response\.config\?\.url/, '成功分支以失败请求 URL 判定登录请求') assert.match(http, /error\?\.config\?\.url|error\.config\.url/, '异常分支同样传入请求 URL') })