feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
193
frontend/packages/arch/bot-api/__tests__/axios.test.ts
Normal file
193
frontend/packages/arch/bot-api/__tests__/axios.test.ts
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { vi, describe, it, expect, beforeAll, beforeEach } from 'vitest';
|
||||
import { Toast } from '@coze-arch/bot-semi';
|
||||
import { axiosInstance, isApiError, ApiError } from '@coze-arch/bot-http';
|
||||
|
||||
// 导入 axios 配置以触发 Toast 配置
|
||||
import '../src/axios';
|
||||
|
||||
vi.mock('@coze-arch/bot-semi', () => ({
|
||||
Toast: {
|
||||
config: vi.fn(),
|
||||
error: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
// 模拟 isApiError 函数
|
||||
vi.mock('@coze-arch/bot-http', () => {
|
||||
// 保存原始的 axiosInstance.interceptors.response.use 方法
|
||||
const originalUse = vi.fn();
|
||||
|
||||
return {
|
||||
axiosInstance: {
|
||||
interceptors: {
|
||||
response: {
|
||||
use: originalUse,
|
||||
},
|
||||
},
|
||||
},
|
||||
isApiError: vi.fn(),
|
||||
ApiError: vi.fn().mockImplementation(function (
|
||||
this: any,
|
||||
code: string,
|
||||
msg: string,
|
||||
) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.config = {};
|
||||
this.name = 'ApiError';
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('axios configuration', () => {
|
||||
let onFulfilled: Function;
|
||||
let onRejected: Function;
|
||||
|
||||
beforeAll(async () => {
|
||||
// 导入 axios 配置以触发 Toast 配置和拦截器注册
|
||||
await import('../src/axios');
|
||||
|
||||
// 验证 Toast.config 被调用
|
||||
expect(Toast.config).toHaveBeenCalledWith({ top: 80 });
|
||||
|
||||
// 获取注册的拦截器函数
|
||||
const useArgs = (axiosInstance.interceptors.response.use as any).mock
|
||||
.calls[0];
|
||||
onFulfilled = useArgs[0];
|
||||
onRejected = useArgs[1];
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('response interceptor', () => {
|
||||
it('should return response data directly on success', () => {
|
||||
const mockData = { foo: 'bar' };
|
||||
const mockResponse = { data: mockData };
|
||||
|
||||
const result = onFulfilled(mockResponse);
|
||||
|
||||
expect(result).toEqual(mockData);
|
||||
});
|
||||
|
||||
it('should show error toast when API error occurs', () => {
|
||||
// 创建一个 API 错误
|
||||
const apiError = new (ApiError as any)('500', 'API Error');
|
||||
|
||||
// 模拟 isApiError 返回 true
|
||||
(isApiError as any).mockReturnValue(true);
|
||||
|
||||
try {
|
||||
onRejected(apiError);
|
||||
// 如果没有抛出错误,测试应该失败
|
||||
expect(true).toBe(false);
|
||||
} catch (error) {
|
||||
expect(isApiError).toHaveBeenCalledWith(apiError);
|
||||
expect(Toast.error).toHaveBeenCalledWith({
|
||||
content: apiError.msg,
|
||||
showClose: false,
|
||||
});
|
||||
expect(error).toBe(apiError);
|
||||
}
|
||||
});
|
||||
|
||||
it('should not show error toast when __disableErrorToast is true', () => {
|
||||
// 创建一个 API 错误,并设置 __disableErrorToast 为 true
|
||||
const apiError = new (ApiError as any)('401', 'Unauthorized');
|
||||
apiError.config.__disableErrorToast = true;
|
||||
|
||||
// 模拟 isApiError 返回 true
|
||||
(isApiError as any).mockReturnValue(true);
|
||||
|
||||
try {
|
||||
onRejected(apiError);
|
||||
// 如果没有抛出错误,测试应该失败
|
||||
expect(true).toBe(false);
|
||||
} catch (error) {
|
||||
expect(isApiError).toHaveBeenCalledWith(apiError);
|
||||
expect(Toast.error).not.toHaveBeenCalled();
|
||||
expect(error).toBe(apiError);
|
||||
}
|
||||
});
|
||||
|
||||
it('should not show error toast when error has no message', () => {
|
||||
// 创建一个没有消息的 API 错误
|
||||
const apiError = new (ApiError as any)('403', undefined);
|
||||
|
||||
// 模拟 isApiError 返回 true
|
||||
(isApiError as any).mockReturnValue(true);
|
||||
|
||||
try {
|
||||
onRejected(apiError);
|
||||
// 如果没有抛出错误,测试应该失败
|
||||
expect(true).toBe(false);
|
||||
} catch (error) {
|
||||
expect(isApiError).toHaveBeenCalledWith(apiError);
|
||||
expect(Toast.error).not.toHaveBeenCalled();
|
||||
expect(error).toBe(apiError);
|
||||
}
|
||||
});
|
||||
|
||||
it('should not show error toast when isApiError returns false', () => {
|
||||
// 创建一个普通错误
|
||||
const regularError = new Error('Regular Error');
|
||||
(regularError as any).msg = 'Error message';
|
||||
|
||||
// 模拟 isApiError 返回 false
|
||||
(isApiError as any).mockReturnValue(false);
|
||||
|
||||
try {
|
||||
onRejected(regularError);
|
||||
// 如果没有抛出错误,测试应该失败
|
||||
expect(true).toBe(false);
|
||||
} catch (error) {
|
||||
expect(isApiError).toHaveBeenCalledWith(regularError);
|
||||
expect(Toast.error).not.toHaveBeenCalled();
|
||||
expect(error).toBe(regularError);
|
||||
}
|
||||
});
|
||||
|
||||
it('should handle null or undefined error', () => {
|
||||
// 测试 null 错误
|
||||
try {
|
||||
onRejected(null);
|
||||
// 如果没有抛出错误,测试应该失败
|
||||
expect(true).toBe(false);
|
||||
} catch (error) {
|
||||
expect(isApiError).toHaveBeenCalledWith(null);
|
||||
expect(Toast.error).not.toHaveBeenCalled();
|
||||
expect(error).toBe(null);
|
||||
}
|
||||
|
||||
vi.clearAllMocks();
|
||||
|
||||
// 测试 undefined 错误
|
||||
try {
|
||||
onRejected(undefined);
|
||||
// 如果没有抛出错误,测试应该失败
|
||||
expect(true).toBe(false);
|
||||
} catch (error) {
|
||||
expect(isApiError).toHaveBeenCalledWith(undefined);
|
||||
expect(Toast.error).not.toHaveBeenCalled();
|
||||
expect(error).toBe(undefined);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user