feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv
2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
/*
* 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 } from '@testing-library/react-hooks';
import { useSpaceStore } from '@coze-foundation/space-store-adapter';
import { useRefreshSpaces } from '../hooks';
vi.mock('@coze-foundation/space-store-adapter', () => ({
useSpaceStore: {
getState: vi.fn(),
},
}));
vi.mock('@coze-foundation/enterprise-store-adapter', () => ({
useCurrentEnterpriseInfo: () => null,
}));
describe('useRefreshSpaces', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('should set loading to true and fetch spaces when refresh is true', async () => {
const mockFetchSpaces = vi.fn().mockResolvedValue([]);
(useSpaceStore.getState as Mock).mockReturnValue({
inited: true,
fetchSpaces: mockFetchSpaces,
});
const { result, waitForNextUpdate } = renderHook(() =>
useRefreshSpaces(true),
);
expect(result.current).toBe(true);
expect(mockFetchSpaces).toHaveBeenCalledTimes(1);
await waitForNextUpdate();
expect(result.current).toBe(false);
});
it('should set loading to false when refresh is false and spaces are already initialized', () => {
(useSpaceStore.getState as Mock).mockReturnValue({
inited: true,
fetchSpaces: vi.fn(),
});
const { result } = renderHook(() => useRefreshSpaces(false));
expect(result.current).toBe(false);
});
it('should set loading to false when refresh is undefined and spaces are already initialized', () => {
(useSpaceStore.getState as Mock).mockReturnValue({
inited: true,
fetchSpaces: vi.fn(),
});
const { result } = renderHook(() => useRefreshSpaces());
expect(result.current).toBe(false);
});
});

View File

@@ -0,0 +1,57 @@
/*
* 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 } from '@testing-library/react-hooks';
import { useSpaceStore } from '@coze-foundation/space-store-adapter';
import { useSpaceList } from '../hooks';
vi.mock('@coze-foundation/space-store-adapter', () => ({
useSpaceStore: vi.fn(),
}));
vi.mock('@coze-foundation/enterprise-store-adapter', () => ({
useCurrentEnterpriseInfo: () => null,
}));
describe('useRefreshSpaces', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('should return correct state from useSpaceList & useRefreshSpaces', async () => {
const mockSpaceList = [
{
id: '1',
name: 'Space 1',
},
];
useSpaceStore.getState = vi.fn();
const mockFetchSpaces = vi.fn().mockResolvedValue([]);
(useSpaceStore.getState as Mock).mockReturnValue({
inited: true,
fetchSpaces: mockFetchSpaces,
});
vi.mocked(useSpaceStore).mockReturnValue([]);
const { result, waitForNextUpdate } = renderHook(() => useSpaceList(true));
expect(result.current.spaces).toEqual([]);
expect(result.current.loading).toEqual(true);
vi.mocked(useSpaceStore).mockReturnValue(mockSpaceList);
await waitForNextUpdate();
expect(result.current.spaces).toEqual(mockSpaceList);
expect(result.current.loading).toBe(false);
});
});

View File

@@ -0,0 +1,58 @@
/*
* 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 { useSpaceStore } from '@coze-foundation/space-store-adapter';
import { useSpace } from '../hooks';
vi.mock('@coze-foundation/space-store-adapter', () => ({
useSpaceStore: vi.fn(),
}));
vi.mock('@coze-foundation/enterprise-store-adapter', () => ({
useCurrentEnterpriseInfo: () => null,
}));
describe('useRefreshSpaces', () => {
beforeEach(() => {
vi.clearAllMocks();
useSpaceStore.getState = vi.fn().mockReturnValue({
fetchSpaces: vi.fn(),
inited: true,
});
});
it('should return current space when id matches', () => {
const mockSpaceList = [
{
id: '1',
name: 'Space 1',
},
{
id: '2',
name: 'Space 2',
},
];
vi.mocked(useSpaceStore).mockImplementation(callback =>
callback({
spaceList: mockSpaceList,
}),
);
const { result } = renderHook(() => useSpace('1'));
expect(result.current.space).toEqual(mockSpaceList[0]);
});
});

View File

@@ -0,0 +1,72 @@
/*
* 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 { useEffect, useState } from 'react';
import { useSpaceStore } from '@coze-foundation/space-store-adapter';
import { useCurrentEnterpriseInfo } from '@coze-foundation/enterprise-store-adapter';
import { type BotSpace } from '@coze-arch/bot-api/developer_api';
export const useRefreshSpaces = (refresh?: boolean) => {
const [loading, setLoading] = useState(true);
const enterpriseInfo = useCurrentEnterpriseInfo();
// 企业发生变化,重新获取空间列表
useEffect(() => {
if (refresh || !useSpaceStore.getState().inited) {
setLoading(true);
useSpaceStore
.getState()
.fetchSpaces(true)
.finally(() => {
setLoading(false);
});
} else {
setLoading(false);
}
}, [enterpriseInfo?.organization_id, refresh]);
return loading;
};
export const useSpaceList: (refresh?: boolean) => {
spaces?: BotSpace[];
loading: boolean;
} = refresh => {
const spaces = useSpaceStore(s => s.spaceList);
const loading = useRefreshSpaces(refresh);
return {
spaces,
loading,
} as const;
};
export const useSpace: (
spaceId: string,
refresh?: boolean,
) => {
space?: BotSpace;
loading: boolean;
} = (spaceId, refresh) => {
const space = useSpaceStore(s =>
s.spaceList.find(spaceItem => spaceItem.id === spaceId),
);
const loading = useRefreshSpaces(refresh);
return {
space,
loading,
} as const;
};