feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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 { type Mock } from 'vitest';
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
|
||||
import { initEditorByPrologue } from '@/component/onboarding-message/onboarding-editor/method/init-editor';
|
||||
import { useInitEditor } from '@/component/onboarding-message/onboarding-editor/hooks/use-init-editor';
|
||||
import type { OnboardingEditorContext } from '@/component/onboarding-message/onboarding-editor';
|
||||
|
||||
vi.mock(
|
||||
'@/component/onboarding-message/onboarding-editor/method/init-editor',
|
||||
() => ({
|
||||
initEditorByPrologue: vi.fn().mockResolvedValue(undefined),
|
||||
}),
|
||||
);
|
||||
|
||||
describe('useInitEditor', () => {
|
||||
let props;
|
||||
let editorRef;
|
||||
|
||||
beforeEach(() => {
|
||||
props = {
|
||||
initValues: {
|
||||
prologue: 'prologue',
|
||||
},
|
||||
};
|
||||
editorRef = {
|
||||
current: {
|
||||
scrollModule: {
|
||||
scrollTo: vi.fn(),
|
||||
},
|
||||
},
|
||||
};
|
||||
(initEditorByPrologue as Mock).mockClear();
|
||||
});
|
||||
|
||||
it('calls initEditorByPrologue when prologue and editorRef.current are defined', () => {
|
||||
renderHook(() => useInitEditor({ api: undefined, props, editorRef }));
|
||||
|
||||
expect(initEditorByPrologue).toHaveBeenCalledWith({
|
||||
prologue: props.initValues.prologue,
|
||||
editorRef,
|
||||
});
|
||||
});
|
||||
|
||||
it('does not call initEditorByPrologue when prologue is not defined', () => {
|
||||
props.initValues.prologue = undefined;
|
||||
const { result } = renderHook(() =>
|
||||
useInitEditor({ api: undefined, props, editorRef }),
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current;
|
||||
});
|
||||
|
||||
expect(initEditorByPrologue).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not call initEditorByPrologue when editorRef.current is not defined', () => {
|
||||
editorRef.current = undefined;
|
||||
const { result } = renderHook(() =>
|
||||
useInitEditor({ api: undefined, props, editorRef }),
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current;
|
||||
});
|
||||
|
||||
expect(initEditorByPrologue).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not call initEditorByPrologue when it has been initialized', () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
||||
const { rerender } = renderHook<OnboardingEditorContext, void>(hookProps =>
|
||||
useInitEditor({
|
||||
api: hookProps.api ?? undefined,
|
||||
props: hookProps.props ?? props,
|
||||
editorRef,
|
||||
}),
|
||||
);
|
||||
rerender({
|
||||
api: undefined,
|
||||
props: {
|
||||
initValues: {
|
||||
prologue: 'iwdfasdfa',
|
||||
},
|
||||
},
|
||||
editorRef,
|
||||
});
|
||||
rerender({
|
||||
api: undefined,
|
||||
props: {
|
||||
initValues: {
|
||||
prologue: 'acbcfaa',
|
||||
},
|
||||
},
|
||||
editorRef,
|
||||
});
|
||||
|
||||
expect(initEditorByPrologue).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
it('should not call initEditorByPrologue when initValues is not defined', () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
||||
const { rerender } = renderHook<OnboardingEditorContext, void>(hookProps =>
|
||||
useInitEditor({
|
||||
api: hookProps.api ?? undefined,
|
||||
props: hookProps.props ?? props,
|
||||
editorRef,
|
||||
}),
|
||||
);
|
||||
rerender({
|
||||
api: undefined,
|
||||
props: {},
|
||||
editorRef,
|
||||
});
|
||||
|
||||
expect(initEditorByPrologue).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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 { type Mock } from 'vitest';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { Toast } from '@coze-arch/bot-semi';
|
||||
import { PlaygroundApi } from '@coze-arch/bot-api';
|
||||
|
||||
import { getImageUrl } from '@/component/onboarding-message/onboarding-editor/method/get-image-url';
|
||||
|
||||
vi.mock('@coze-arch/bot-api', () => ({
|
||||
PlaygroundApi: {
|
||||
GetImagexShortUrl: vi.fn(),
|
||||
},
|
||||
}));
|
||||
vi.mock('@coze-arch/bot-semi', () => ({
|
||||
Toast: {
|
||||
error: vi.fn(),
|
||||
},
|
||||
}));
|
||||
vi.mock('@coze-arch/i18n');
|
||||
|
||||
describe('getImageUrl', () => {
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
|
||||
it('returns image URL when API call is successful and image is appropriate', async () => {
|
||||
const mockRequest = { Key: 'testUri' };
|
||||
const mockResponse = {
|
||||
code: '200',
|
||||
msg: 'Success',
|
||||
data: {
|
||||
url_info: {
|
||||
testUri: {
|
||||
review_status: true,
|
||||
url: 'http://test.com',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
(PlaygroundApi.GetImagexShortUrl as Mock).mockResolvedValue(mockResponse);
|
||||
|
||||
const result = await getImageUrl(mockRequest);
|
||||
|
||||
expect(result).toEqual({
|
||||
code: 200,
|
||||
message: 'Success',
|
||||
data: {
|
||||
url: 'http://test.com',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('throw error && shows error toast when image is inappropriate', async () => {
|
||||
const mockRequest = { Key: 'testUri' };
|
||||
const mockResponse = {
|
||||
code: '200',
|
||||
msg: 'Success',
|
||||
data: {
|
||||
url_info: {
|
||||
testUri: {
|
||||
review_status: false,
|
||||
url: 'http://test.com',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
(PlaygroundApi.GetImagexShortUrl as Mock).mockResolvedValue(mockResponse);
|
||||
|
||||
await expect(getImageUrl(mockRequest)).rejects.toThrow(
|
||||
'inappropriate_contents',
|
||||
);
|
||||
expect(Toast.error).toHaveBeenCalledWith({
|
||||
content: I18n.t('inappropriate_contents'),
|
||||
showClose: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('throw error when image URL is not present', () => {
|
||||
const mockRequest = { Key: 'testUri' };
|
||||
const mockResponse = {
|
||||
code: '200',
|
||||
msg: 'Success',
|
||||
data: {
|
||||
url_info: {
|
||||
testUri: {
|
||||
review_status: 'appropriate',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
(PlaygroundApi.GetImagexShortUrl as Mock).mockResolvedValue(mockResponse);
|
||||
|
||||
expect(getImageUrl(mockRequest)).rejects.toThrow('inappropriate_contents');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 { type Mock } from 'vitest';
|
||||
import { DeveloperApi } from '@coze-arch/bot-api';
|
||||
|
||||
import { getUploadToken } from '@/component/onboarding-message/onboarding-editor/method/get-upload-token';
|
||||
|
||||
vi.mock('@coze-arch/bot-api', () => ({
|
||||
DeveloperApi: {
|
||||
GetUploadAuthToken: vi.fn(),
|
||||
},
|
||||
}));
|
||||
describe('getUploadToken', () => {
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
|
||||
it('returns the expected response on successful API call', async () => {
|
||||
const mockResponse = {
|
||||
code: 200,
|
||||
msg: 'Success',
|
||||
data: {
|
||||
auth: {
|
||||
token: 'mockToken',
|
||||
},
|
||||
},
|
||||
};
|
||||
(DeveloperApi.GetUploadAuthToken as Mock).mockResolvedValue(mockResponse);
|
||||
|
||||
const result = await getUploadToken();
|
||||
|
||||
expect(result).toEqual({
|
||||
code: 200,
|
||||
message: 'Success',
|
||||
data: {
|
||||
...mockResponse.data,
|
||||
...mockResponse.data.auth,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('throws an error when the API call fails', async () => {
|
||||
const mockError = new Error('API call failed');
|
||||
(DeveloperApi.GetUploadAuthToken as Mock).mockRejectedValue(mockError);
|
||||
|
||||
await expect(getUploadToken()).rejects.toThrow('API call failed');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 { md2html } from '@coze-common/md-editor-adapter';
|
||||
import { type Editor } from '@coze-common/md-editor-adapter';
|
||||
|
||||
import {
|
||||
initEditorByPrologue,
|
||||
type InitEditorByPrologueProps,
|
||||
} from '@/component/onboarding-message/onboarding-editor/method/init-editor';
|
||||
|
||||
vi.mock('@coze-common/md-editor-adapter', () => ({
|
||||
md2html: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('initEditorByPrologue', () => {
|
||||
let editorRef: React.RefObject<Editor>;
|
||||
|
||||
beforeEach(() => {
|
||||
editorRef = { current: { setHTML: vi.fn() } } as any;
|
||||
});
|
||||
|
||||
it('should convert markdown to html and set to editor', () => {
|
||||
const prologue = '**Hello**';
|
||||
const htmlContent = '<strong>Hello</strong>';
|
||||
vi.mocked(md2html).mockReturnValue(htmlContent);
|
||||
|
||||
const props: InitEditorByPrologueProps = { prologue, editorRef };
|
||||
initEditorByPrologue(props);
|
||||
|
||||
expect(md2html).toHaveBeenCalledWith(prologue);
|
||||
expect(editorRef.current?.setHTML).toHaveBeenCalledWith(htmlContent);
|
||||
});
|
||||
|
||||
it('should not set html to editor if editorRef is not defined', () => {
|
||||
const prologue = '**Hello**';
|
||||
const htmlContent = '<strong>Hello</strong>';
|
||||
vi.mocked(md2html).mockReturnValue(htmlContent);
|
||||
|
||||
const props: InitEditorByPrologueProps = { prologue, editorRef: {} as any };
|
||||
initEditorByPrologue(props);
|
||||
|
||||
expect(md2html).toHaveBeenCalledWith(prologue);
|
||||
expect(editorRef.current?.setHTML).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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 { sliceEditor } from '@/component/onboarding-message/onboarding-editor/method/slice-editor';
|
||||
|
||||
// vi.mock需要在顶部,因为它会被提升
|
||||
vi.mock('@coze-common/md-editor-adapter', () => ({
|
||||
ZoneDelta: vi.fn().mockImplementation(() => ({
|
||||
retain: vi.fn().mockReturnThis(),
|
||||
delete: vi.fn().mockReturnThis(),
|
||||
})),
|
||||
}));
|
||||
|
||||
// 导入模拟后的ZoneDelta
|
||||
import { ZoneDelta } from '@coze-common/md-editor-adapter';
|
||||
|
||||
describe('sliceEditor', () => {
|
||||
let editorRef;
|
||||
let maxCount;
|
||||
let mockedEditor;
|
||||
let mockZoneDeltaInstance;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks();
|
||||
|
||||
// 创建一个新的模拟实例
|
||||
mockZoneDeltaInstance = {
|
||||
retain: vi.fn().mockReturnThis(),
|
||||
delete: vi.fn().mockReturnThis(),
|
||||
};
|
||||
|
||||
// 重置ZoneDelta构造函数的实现
|
||||
vi.mocked(ZoneDelta).mockImplementation(() => mockZoneDeltaInstance);
|
||||
|
||||
mockedEditor = {
|
||||
selection: {
|
||||
getSelection: vi.fn(),
|
||||
},
|
||||
getContentState: vi.fn().mockReturnValue({
|
||||
getZoneState: vi.fn(),
|
||||
apply: vi.fn(),
|
||||
}),
|
||||
};
|
||||
editorRef = { current: mockedEditor };
|
||||
maxCount = 5;
|
||||
});
|
||||
|
||||
it('returns early when editorRef is not current', () => {
|
||||
editorRef.current = null;
|
||||
|
||||
const result = sliceEditor(editorRef, maxCount);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('returns early when zoneState is not found', () => {
|
||||
mockedEditor.selection.getSelection.mockReturnValue({
|
||||
start: { zoneId: 'zone1' },
|
||||
});
|
||||
mockedEditor.getContentState.mockReturnValue({
|
||||
getZoneState: vi.fn().mockReturnValue(null),
|
||||
});
|
||||
|
||||
const result = sliceEditor(editorRef, maxCount);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('does not slice when currentCount is less than maxCount', () => {
|
||||
mockedEditor.selection.getSelection.mockReturnValue({
|
||||
start: { zoneId: 'zone1' },
|
||||
});
|
||||
mockedEditor.getContentState.mockReturnValue({
|
||||
getZoneState: vi
|
||||
.fn()
|
||||
.mockReturnValue({ totalWidth: vi.fn().mockReturnValue(4) }),
|
||||
});
|
||||
|
||||
const result = sliceEditor(editorRef, maxCount);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('slices when currentCount is more than maxCount', () => {
|
||||
const mockApply = vi.fn();
|
||||
mockedEditor.selection.getSelection.mockReturnValue({
|
||||
start: { zoneId: 'zone1' },
|
||||
});
|
||||
mockedEditor.getContentState.mockReturnValue({
|
||||
apply: mockApply,
|
||||
getZoneState: vi
|
||||
.fn()
|
||||
.mockReturnValue({ totalWidth: vi.fn().mockReturnValue(7) }),
|
||||
});
|
||||
|
||||
sliceEditor(editorRef, maxCount);
|
||||
|
||||
expect(ZoneDelta).toHaveBeenCalledWith({ zoneId: 'zone1' });
|
||||
expect(mockZoneDeltaInstance.retain).toHaveBeenCalledWith(maxCount);
|
||||
expect(mockZoneDeltaInstance.delete).toHaveBeenCalledWith(1); // 实际计算出的值是1
|
||||
expect(mockApply).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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 { act, renderHook } from '@testing-library/react-hooks';
|
||||
|
||||
import { useCustomPlatformController } from '@/hook/publish-platform-setting/use-custom-platform-controller';
|
||||
|
||||
vi.mock('@coze-foundation/enterprise-store-adapter', () => ({
|
||||
useCurrentEnterpriseInfo: () => ({}),
|
||||
}));
|
||||
|
||||
vi.mock('@coze-arch/bot-api', () => ({
|
||||
connectorApi: {
|
||||
ListConnector: vi
|
||||
.fn()
|
||||
.mockResolvedValueOnce({
|
||||
data: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'test',
|
||||
type: 'mysql',
|
||||
config: {},
|
||||
status: 'ok',
|
||||
},
|
||||
],
|
||||
})
|
||||
.mockRejectedValueOnce([]),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('use-custom-platform-controller', () => {
|
||||
it('use-custom-platform-controller datasource and action should be right', async () => {
|
||||
const { result, waitForValueToChange } = renderHook(() =>
|
||||
useCustomPlatformController(),
|
||||
);
|
||||
|
||||
act(() => result.current.doRefreshDatasource());
|
||||
|
||||
await waitForValueToChange(() => result.current.dataSource);
|
||||
|
||||
expect(result.current.dataSource.length).toBe(1);
|
||||
expect(result.current.loading).toBeFalsy();
|
||||
|
||||
act(() => result.current.doRefreshDatasource());
|
||||
await waitForValueToChange(() => result.current.dataSource);
|
||||
|
||||
expect(result.current.dataSource.length).toBe(0);
|
||||
});
|
||||
|
||||
it('use-custom-platform-controller actionTarget should be right', () => {
|
||||
const { result, waitForValueToChange } = renderHook(() =>
|
||||
useCustomPlatformController(),
|
||||
);
|
||||
|
||||
act(() =>
|
||||
result.current.doSetActionTarget({ target: 'oauth', action: 'create' }),
|
||||
);
|
||||
|
||||
waitForValueToChange(() => result.current.actionTarget);
|
||||
|
||||
expect(result.current.actionTarget).toEqual({
|
||||
target: 'oauth',
|
||||
action: 'create',
|
||||
});
|
||||
});
|
||||
|
||||
it('use-custom-platform-controller copy-action should be right', () => {
|
||||
const { result } = renderHook(() => useCustomPlatformController());
|
||||
|
||||
act(() => result.current.doCopy('test'));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,518 @@
|
||||
/*
|
||||
* 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 { renderHook } from '@testing-library/react-hooks';
|
||||
|
||||
import { useCustomPlatformSettingModalController } from '@/hook/publish-platform-setting/use-custom-platform-setting-modal-controller';
|
||||
|
||||
vi.mock('@coze-foundation/enterprise-store-adapter', () => ({
|
||||
useIsCurrentPersonalEnterprise: () => true,
|
||||
useCurrentEnterpriseRoles: () => [],
|
||||
useCurrentEnterpriseInfo: () => ({ enterprise_id: 'personal' }),
|
||||
}));
|
||||
|
||||
vi.mock('@coze-arch/bot-api', () => ({
|
||||
PlaygroundApi: {
|
||||
GetSpaceListV2: vi.fn().mockResolvedValue({
|
||||
data: {
|
||||
bot_space_list: [
|
||||
{
|
||||
app_ids: [],
|
||||
connectors: [
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '豆包',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '飞书',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '微信客服',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '【即将下线】微信公众号(服务号)',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Web SDK',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '掘金',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot Store',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot as API',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '飞书多维表格',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '豆包',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '飞书',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '微信客服',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '【即将下线】微信公众号(服务号)',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Web SDK',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '掘金',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot Store',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot as API',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '飞书多维表格',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '测试渠道02',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot as API',
|
||||
},
|
||||
],
|
||||
description: 'Personal Space',
|
||||
hide_operation: false,
|
||||
icon_url: '',
|
||||
id: '',
|
||||
name: '个人空间',
|
||||
role_type: 1,
|
||||
space_mode: 0,
|
||||
space_type: 1,
|
||||
},
|
||||
{
|
||||
app_ids: [],
|
||||
connectors: [
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '豆包',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '飞书',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '微信客服',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '【即将下线】微信公众号(服务号)',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Web SDK',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '掘金',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot Store',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot as API',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '飞书多维表格',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '测试渠道03测试渠道03',
|
||||
},
|
||||
],
|
||||
description: 'This is a description for liwei_1019',
|
||||
hide_operation: false,
|
||||
icon_url: '',
|
||||
id: '',
|
||||
name: 'liwei_1019',
|
||||
role_type: 1,
|
||||
space_mode: 0,
|
||||
space_type: 2,
|
||||
},
|
||||
{
|
||||
app_ids: [],
|
||||
connectors: [
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '豆包',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '飞书',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '微信客服',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '【即将下线】微信公众号(服务号)',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Web SDK',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '掘金',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot Store',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot as API',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '飞书多维表格',
|
||||
},
|
||||
],
|
||||
description: '',
|
||||
hide_operation: false,
|
||||
icon_url: '',
|
||||
id: '',
|
||||
name: 'LYH的boe测试团队',
|
||||
role_type: 3,
|
||||
space_mode: 0,
|
||||
space_type: 2,
|
||||
},
|
||||
{
|
||||
app_ids: [],
|
||||
connectors: [
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '豆包',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '飞书',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '微信客服',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '【即将下线】微信公众号(服务号)',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Web SDK',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '掘金',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot Store',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot as API',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '飞书多维表格',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot Store',
|
||||
},
|
||||
],
|
||||
description: '',
|
||||
hide_operation: false,
|
||||
icon_url: '',
|
||||
id: '',
|
||||
name: 'ByteDance Demo',
|
||||
role_type: 3,
|
||||
space_mode: 0,
|
||||
space_type: 2,
|
||||
},
|
||||
{
|
||||
app_ids: [],
|
||||
connectors: [
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '豆包',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '飞书',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '微信客服',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '【即将下线】微信公众号(服务号)',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Web SDK',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '掘金',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot Store',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot as API',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '飞书多维表格',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: '测试渠道03测试渠道03',
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
id: '',
|
||||
name: 'Bot as API',
|
||||
},
|
||||
],
|
||||
description: '',
|
||||
hide_operation: false,
|
||||
icon_url: '',
|
||||
id: '',
|
||||
name: 'liwei_1019_v2',
|
||||
role_type: 1,
|
||||
space_mode: 0,
|
||||
space_type: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
},
|
||||
patPermissionApi: {
|
||||
ListAppMeta: vi.fn().mockResolvedValue({
|
||||
data: {
|
||||
apps: [
|
||||
{
|
||||
appid: '',
|
||||
app_owner_id: '',
|
||||
name: 'showcase渠道',
|
||||
description: 'showcase渠道',
|
||||
created_at: 1722240368,
|
||||
app_type: 'Connector',
|
||||
declared_permission: [],
|
||||
client_id: '',
|
||||
status: 'Active',
|
||||
certificated: 'Noncertificated',
|
||||
connector: {
|
||||
connector_id: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
appid: '',
|
||||
app_owner_id: '',
|
||||
name: 'OauthApp',
|
||||
description: 'OauthApp',
|
||||
created_at: 1721987816,
|
||||
app_type: 'Connector',
|
||||
declared_permission: [
|
||||
{
|
||||
resource_type: 'Connector',
|
||||
actions: ['botChat', 'WorkflowTest', 'botEdit', 'botPublish'],
|
||||
},
|
||||
],
|
||||
client_id: '',
|
||||
status: 'Active',
|
||||
certificated: 'Noncertificated',
|
||||
connector: {
|
||||
connector_id: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
appid: '',
|
||||
app_owner_id: '',
|
||||
name: '1019的测试应用',
|
||||
description: '1019的测试应用',
|
||||
created_at: 1721812683,
|
||||
app_type: 'Normal',
|
||||
declared_permission: [
|
||||
{
|
||||
resource_type: 'Bot',
|
||||
actions: ['chat', 'getMetadata'],
|
||||
},
|
||||
],
|
||||
client_id: '',
|
||||
status: 'Active',
|
||||
certificated: 'Noncertificated',
|
||||
connector: {
|
||||
connector_id: '',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
},
|
||||
connectorApi: {
|
||||
CreateConnector: vi.fn().mockResolvedValue({ code: 0 }),
|
||||
UpdateConnector: vi.fn().mockResolvedValue({ code: 0 }),
|
||||
DeleteConnector: vi.fn().mockResolvedValue({ code: 0 }),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('useCustomPlatformSettingModalController', () => {
|
||||
it('useCustomPlatformSettingModalController fetch data should be right', async () => {
|
||||
const onOk = vi.fn();
|
||||
|
||||
const { result, waitForNextUpdate } = renderHook(() =>
|
||||
useCustomPlatformSettingModalController(onOk),
|
||||
);
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.oauthOptionsList.length).toBe(3);
|
||||
expect(result.current.spaceOptionList.length).toBe(5);
|
||||
expect(result.current.isLoadingOauthDatasource).toBeFalsy();
|
||||
expect(result.current.isLoadingSpace).toBeFalsy();
|
||||
});
|
||||
|
||||
it('useCustomPlatformSettingModalController create & update & delete should be right', async () => {
|
||||
const onOk = vi.fn();
|
||||
|
||||
const { result, waitForNextUpdate } = renderHook(() =>
|
||||
useCustomPlatformSettingModalController(onOk),
|
||||
);
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.isIdle).toBeTruthy();
|
||||
|
||||
await result.current.doCreate({});
|
||||
await result.current.doUpdate({});
|
||||
await result.current.doDel({ id: 'id' });
|
||||
|
||||
expect(onOk).toBeCalledTimes(3);
|
||||
});
|
||||
|
||||
it('useCustomPlatformSettingModalController copy should be right', async () => {
|
||||
const onOk = vi.fn();
|
||||
|
||||
const { result, waitForNextUpdate } = renderHook(() =>
|
||||
useCustomPlatformSettingModalController(onOk),
|
||||
);
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.isIdle).toBeTruthy();
|
||||
|
||||
result.current.doCopy('id');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 { renderHook } from '@testing-library/react-hooks';
|
||||
import { AuthStatus } from '@coze-arch/idl/developer_api';
|
||||
|
||||
import { useNormalPlatformController } from '@/hook/publish-platform-setting/use-normal-platform-controller';
|
||||
|
||||
vi.mock('@coze-studio/user-store', () => ({
|
||||
userStoreService: {
|
||||
useUserAuthInfo: vi.fn().mockReturnValue([
|
||||
{
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
icon: 'icon',
|
||||
auth_status: AuthStatus.Authorized,
|
||||
},
|
||||
{
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
icon: 'icon',
|
||||
auth_status: AuthStatus.Unauthorized,
|
||||
},
|
||||
]),
|
||||
getUserAuthInfos: vi
|
||||
.fn()
|
||||
.mockResolvedValueOnce(0)
|
||||
.mockRejectedValueOnce(-1),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('useNormalPlatformController', () => {
|
||||
it('useNormalPlatformController should return userAuthInfos', () => {
|
||||
const { result } = renderHook(() => useNormalPlatformController());
|
||||
|
||||
expect(result.current.userAuthInfos.length).toEqual(2);
|
||||
});
|
||||
|
||||
it('useNormalPlatformController should return revokeSuccess', async () => {
|
||||
const { result } = renderHook(() => useNormalPlatformController());
|
||||
|
||||
await result.current.revokeSuccess();
|
||||
|
||||
await result.current.revokeSuccess();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* 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 { renderHook } from '@testing-library/react-hooks';
|
||||
|
||||
import { useOauthSettingModalController } from '@/hook/publish-platform-setting/use-oauth-setting-modal-controller';
|
||||
|
||||
vi.mock('@coze-arch/bot-api', () => ({
|
||||
connectorApi: {
|
||||
GetOauthConfigSchema: vi.fn().mockResolvedValue({
|
||||
oauth_schema: {
|
||||
title_text: '填写自定义渠道 oauth 配置信息',
|
||||
start_text:
|
||||
'按照[**自定义渠道配置流程**](https://www.coze.cn/docs/guides/isv_connector)配置并注册自定义渠道,支持 Bot 发布至自定义渠道',
|
||||
schema_area: {
|
||||
schema_list: [
|
||||
{
|
||||
type: 'string',
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '跳转地址 必填',
|
||||
},
|
||||
],
|
||||
placeholder: '请输入跳转地址',
|
||||
name: 'redirect_url',
|
||||
title: '跳转地址',
|
||||
component: 'Input',
|
||||
enums: [],
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
enums: [],
|
||||
type: 'string',
|
||||
rules: [
|
||||
{
|
||||
message: '获取 token 地址 必填',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
placeholder: '请输入获取 token 地址',
|
||||
name: 'access_token_url',
|
||||
title: '获取 token 地址',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
enums: [],
|
||||
type: 'string',
|
||||
rules: [
|
||||
{
|
||||
message: '获取用户信息地址 必填',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
placeholder: '',
|
||||
name: 'user_info_url',
|
||||
title: '获取用户信息地址',
|
||||
},
|
||||
{
|
||||
enums: [],
|
||||
type: 'string',
|
||||
rules: [
|
||||
{
|
||||
message: 'APP ID 必填',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
placeholder: '请输入APP ID',
|
||||
name: 'app_id',
|
||||
title: 'APP ID',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
name: 'app_secret',
|
||||
title: 'APP 密钥',
|
||||
component: 'Input',
|
||||
enums: [],
|
||||
type: 'string',
|
||||
rules: [
|
||||
{
|
||||
message: 'APP 密钥 必填',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
placeholder: '请输入APP 密钥',
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
enums: [],
|
||||
type: 'string',
|
||||
rules: [],
|
||||
placeholder: '',
|
||||
name: 'input_number_test',
|
||||
title: 'input_number_test',
|
||||
},
|
||||
{
|
||||
name: 'select_test',
|
||||
title: 'select_test',
|
||||
component: 'Select',
|
||||
enums: [
|
||||
{
|
||||
label: 'label_1',
|
||||
value: 'value_1',
|
||||
},
|
||||
{
|
||||
label: 'label_2',
|
||||
value: 'value_2',
|
||||
},
|
||||
],
|
||||
type: 'string',
|
||||
rules: [],
|
||||
placeholder: '',
|
||||
},
|
||||
{
|
||||
placeholder: '',
|
||||
name: 'radio_test',
|
||||
title: 'radio_test',
|
||||
component: 'Radio',
|
||||
enums: [
|
||||
{
|
||||
label: 'label_1',
|
||||
value: 'value_1',
|
||||
},
|
||||
{
|
||||
label: 'label_2',
|
||||
value: 'value_2',
|
||||
},
|
||||
],
|
||||
type: 'string',
|
||||
rules: [],
|
||||
},
|
||||
{
|
||||
name: 'Checkbox_test',
|
||||
title: 'Checkbox_test',
|
||||
component: 'Checkbox',
|
||||
enums: [
|
||||
{
|
||||
label: 'label_1',
|
||||
value: 'value_1',
|
||||
},
|
||||
{
|
||||
label: 'label_2',
|
||||
value: 'value_2',
|
||||
},
|
||||
],
|
||||
type: 'string',
|
||||
rules: [],
|
||||
placeholder: '',
|
||||
},
|
||||
{
|
||||
enums: [],
|
||||
type: 'string',
|
||||
rules: [
|
||||
{
|
||||
pattern: '^\\S(.*\\S)?$',
|
||||
message: '请检查输入前后是否有空格',
|
||||
},
|
||||
],
|
||||
placeholder: '',
|
||||
name: 'no_space_input',
|
||||
title: '前后不能有空格',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
name: 'max_ten_words',
|
||||
title: '最大 10 个字符',
|
||||
component: 'Input',
|
||||
enums: [],
|
||||
type: 'string',
|
||||
rules: [
|
||||
{
|
||||
max: 10,
|
||||
message: '最大 10 个字符',
|
||||
},
|
||||
],
|
||||
placeholder: '',
|
||||
},
|
||||
],
|
||||
title_text: '填写 oauth 配置信息',
|
||||
description: '',
|
||||
step_order: 1,
|
||||
},
|
||||
copy_link_area: {},
|
||||
},
|
||||
}),
|
||||
UpdateOauthConfig: vi.fn().mockResolvedValue({ code: 0 }),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('useOauthSettingModalController', () => {
|
||||
it('useOauthSettingModalController fetch form config should be right', async () => {
|
||||
const onOk = vi.fn();
|
||||
|
||||
const { result, waitForNextUpdate } = renderHook(() =>
|
||||
useOauthSettingModalController(
|
||||
{
|
||||
target: 'oauth',
|
||||
action: 'update',
|
||||
},
|
||||
onOk,
|
||||
),
|
||||
);
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.isOauthConfigLoading).toBeFalsy();
|
||||
expect(result.current.oauthFormItemConfigs.length).toBe(11);
|
||||
expect(result.current.oauthModalTitle).toBe('填写 oauth 配置信息');
|
||||
});
|
||||
|
||||
it('useOauthSettingModalController update action should be right', async () => {
|
||||
const onOk = vi.fn();
|
||||
|
||||
const { result, waitForNextUpdate } = renderHook(() =>
|
||||
useOauthSettingModalController(
|
||||
{
|
||||
target: 'oauth',
|
||||
action: 'update',
|
||||
},
|
||||
onOk,
|
||||
),
|
||||
);
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.isOauthConfigLoading).toBeFalsy();
|
||||
expect(result.current.oauthFormItemConfigs.length).toBe(11);
|
||||
expect(result.current.oauthModalTitle).toBe('填写 oauth 配置信息');
|
||||
|
||||
await result.current.doUpdate({});
|
||||
|
||||
expect(onOk).toBeCalled();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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, type Mock } from 'vitest';
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import { userStoreService } from '@coze-studio/user-store';
|
||||
import { useBotInfoStore } from '@coze-studio/bot-detail-store/bot-info';
|
||||
import { useBotDetailIsReadonly } from '@coze-studio/bot-detail-store';
|
||||
|
||||
import { useMonetizeConfigReadonly } from '../../src/hook/use-monetize-config-readonly';
|
||||
|
||||
vi.mock('@coze-studio/user-store', () => ({
|
||||
userStoreService: {
|
||||
useUserInfo: vi.fn(),
|
||||
},
|
||||
}));
|
||||
vi.mock('@coze-studio/bot-detail-store', () => ({
|
||||
useBotDetailIsReadonly: vi.fn(),
|
||||
}));
|
||||
vi.mock('@coze-studio/bot-detail-store/bot-info', () => ({
|
||||
useBotInfoStore: vi.fn(),
|
||||
}));
|
||||
describe('use monetize config readonly', () => {
|
||||
// mock returned user id
|
||||
(userStoreService.useUserInfo as unknown as Mock).mockReturnValue({
|
||||
user_id_str: '114',
|
||||
});
|
||||
|
||||
it('bot detail 只读 & 是作者本人 -> 只读', () => {
|
||||
(useBotInfoStore as unknown as Mock).mockReturnValueOnce('114');
|
||||
(useBotDetailIsReadonly as unknown as Mock).mockReturnValueOnce(true);
|
||||
const {
|
||||
result: { current: isReadonly },
|
||||
} = renderHook(() => useMonetizeConfigReadonly());
|
||||
expect(isReadonly).toBe(true);
|
||||
});
|
||||
|
||||
it('bot detail 可编辑 & 是作者本人 -> 可编辑', () => {
|
||||
(useBotInfoStore as unknown as Mock).mockReturnValueOnce('114');
|
||||
(useBotDetailIsReadonly as unknown as Mock).mockReturnValueOnce(false);
|
||||
const {
|
||||
result: { current: isReadonly },
|
||||
} = renderHook(() => useMonetizeConfigReadonly());
|
||||
expect(isReadonly).toBe(false);
|
||||
});
|
||||
|
||||
it('bot detail 只读 & 不是作者本人 -> 只读', () => {
|
||||
(useBotInfoStore as unknown as Mock).mockReturnValueOnce('514');
|
||||
(useBotDetailIsReadonly as unknown as Mock).mockReturnValueOnce(true);
|
||||
const {
|
||||
result: { current: isReadonly },
|
||||
} = renderHook(() => useMonetizeConfigReadonly());
|
||||
expect(isReadonly).toBe(true);
|
||||
});
|
||||
|
||||
it('bot detail 可编辑 & 不是作者本人 -> 只读', () => {
|
||||
(useBotInfoStore as unknown as Mock).mockReturnValueOnce('514');
|
||||
(useBotDetailIsReadonly as unknown as Mock).mockReturnValueOnce(false);
|
||||
const {
|
||||
result: { current: isReadonly },
|
||||
} = renderHook(() => useMonetizeConfigReadonly());
|
||||
expect(isReadonly).toBe(true);
|
||||
});
|
||||
});
|
||||
114
frontend/packages/agent-ide/space-bot/__tests__/setup.ts
Normal file
114
frontend/packages/agent-ide/space-bot/__tests__/setup.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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 } from 'vitest';
|
||||
|
||||
vi.mock('@coze-arch/logger', () => ({
|
||||
useErrorHandler: vi.fn().mockReturnValue(vi.fn()),
|
||||
logger: {
|
||||
error: vi.fn(),
|
||||
info: vi.fn(),
|
||||
},
|
||||
reporter: {
|
||||
tracer: vi.fn().mockReturnValue(vi.fn()),
|
||||
event: vi.fn(),
|
||||
errorEvent: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@coze-arch/i18n', () => ({
|
||||
I18n: {
|
||||
t: (key, params = {}) => `Translated: ${key} ${JSON.stringify(params)}`,
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@coze-arch/bot-tea', () => ({
|
||||
sendTeaEvent: vi.fn(),
|
||||
EVENT_NAMES: {
|
||||
use_mockset_front: 'use_mockset_front',
|
||||
del_mockset_front: 'del_mockset_front',
|
||||
},
|
||||
ParamsTypeDefine: {},
|
||||
PluginMockDataGenerateMode: {
|
||||
MANUAL: 0, // 手动创建
|
||||
RANDOM: 1, // 随机生成
|
||||
LLM: 2,
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@coze-arch/bot-hooks', () => ({
|
||||
SceneType: {
|
||||
BOT__VIEW__WORKFLOW: 'botViewWorkflow',
|
||||
/** bot 详情页查看 workflow,或新建 workflow 但未发布,点击返回 */
|
||||
WORKFLOW__BACK__BOT: 'workflowBackBot',
|
||||
/** bot 详情页创建 workflow,在 workflow 发布后返回 */
|
||||
WORKFLOW_PUBLISHED__BACK__BOT: 'workflowPublishedBackBot',
|
||||
/** bot 详情页进入 mock data 页面 */
|
||||
BOT__TO__PLUGIN_MOCK_DATA: 'botToPluginMockData',
|
||||
/** workflow 详情页进入 mock data 页面 */
|
||||
WORKFLOW__TO__PLUGIN_MOCK_DATA: 'workflowToPluginMockData',
|
||||
/** mock set 页进入 mock data 页面 */
|
||||
PLUGIN_MOCK_SET__TO__PLUGIN_MOCK_DATA: 'pluginMockSetToPluginMockData',
|
||||
/** bot 详情页进入 knowledge 页面 */
|
||||
BOT__VIEW__KNOWLEDGE: 'botViewKnowledge',
|
||||
/** knowledge 页面点击退出返回 bot 详情页(未点击添加) */
|
||||
KNOWLEDGE__BACK__BOT: 'knowledgeBackBot',
|
||||
/** knowledge 页面点击返回 bot 详情页,并添加到 bot */
|
||||
KNOWLEDGE__ADD_TO__BOT: 'knowledgeAddToBot',
|
||||
},
|
||||
usePageJumpService: vi.fn().mockReturnValue({
|
||||
jump: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@coze-arch/bot-studio-store', () => ({
|
||||
useSpaceStore: {
|
||||
getState: vi.fn().mockReturnValue({
|
||||
getSpaceId: vi.fn().mockReturnValue('spaceId'),
|
||||
}),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@coze-arch/report-events', () => ({
|
||||
createReportEvent: vi.fn().mockReturnValue({
|
||||
success: vi.fn(),
|
||||
error: vi.fn(),
|
||||
}),
|
||||
REPORT_EVENTS: {
|
||||
pluginIdeInitTrace: 'pluginIdeInitTrace',
|
||||
pluginIdeInit: 'pluginIdeInit',
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@coze-arch/bot-error', () => ({
|
||||
CustomError: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('react-router-dom', () => ({
|
||||
useNavigate: vi.fn().mockReturnValue(vi.fn()),
|
||||
useParams: vi.fn().mockReturnValue({
|
||||
space_id: 'space_id',
|
||||
plugin_id: 'plugin_id',
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@coze-arch/coze-design', () => ({
|
||||
Toast: {
|
||||
success: vi.fn(),
|
||||
warning: vi.fn(),
|
||||
},
|
||||
withField: vi.fn(),
|
||||
}));
|
||||
Reference in New Issue
Block a user