Compare commits
1 Commits
main
...
gru/projec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74be2169e4 |
@ -23,13 +23,25 @@ type State = {
|
||||
const createCustomStorage = () => {
|
||||
const sessionKeys = ['source', 'chatId', 'appId'];
|
||||
|
||||
// 从 URL 中获取 appId 作为存储键的一部分
|
||||
const getStorageKey = (name: string) => {
|
||||
let appId = '';
|
||||
if (typeof window !== 'undefined') {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
appId = urlParams.get('appId') || '';
|
||||
}
|
||||
return appId ? `${name}_${appId}` : name;
|
||||
};
|
||||
|
||||
return {
|
||||
getItem: (name: string) => {
|
||||
const sessionData = JSON.parse(sessionStorage.getItem(name) || '{}');
|
||||
const localData = JSON.parse(localStorage.getItem(name) || '{}');
|
||||
const storageKey = getStorageKey(name);
|
||||
const sessionData = JSON.parse(sessionStorage.getItem(storageKey) || '{}');
|
||||
const localData = JSON.parse(localStorage.getItem(storageKey) || '{}');
|
||||
return JSON.stringify({ ...localData, ...sessionData });
|
||||
},
|
||||
setItem: (name: string, value: string) => {
|
||||
const storageKey = getStorageKey(name);
|
||||
const data = JSON.parse(value);
|
||||
|
||||
// 分离 session 和 local 数据
|
||||
@ -42,15 +54,16 @@ const createCustomStorage = () => {
|
||||
|
||||
// 分别存储
|
||||
if (Object.keys(sessionData).length > 0) {
|
||||
sessionStorage.setItem(name, JSON.stringify({ state: sessionData, version: 0 }));
|
||||
sessionStorage.setItem(storageKey, JSON.stringify({ state: sessionData, version: 0 }));
|
||||
}
|
||||
if (Object.keys(localData).length > 0) {
|
||||
localStorage.setItem(name, JSON.stringify({ state: localData, version: 0 }));
|
||||
localStorage.setItem(storageKey, JSON.stringify({ state: localData, version: 0 }));
|
||||
}
|
||||
},
|
||||
removeItem: (name: string) => {
|
||||
sessionStorage.removeItem(name);
|
||||
localStorage.removeItem(name);
|
||||
const storageKey = getStorageKey(name);
|
||||
sessionStorage.removeItem(storageKey);
|
||||
localStorage.removeItem(storageKey);
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -125,3 +138,5 @@ export const useChatStore = create<State>()(
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
export { createCustomStorage };
|
||||
|
||||
170
test/cases/web/core/chat/context/useChatStore.test.ts
Normal file
170
test/cases/web/core/chat/context/useChatStore.test.ts
Normal file
@ -0,0 +1,170 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import { useChatStore, createCustomStorage } from '@/web/core/chat/context/useChatStore';
|
||||
import { ChatSourceEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
||||
|
||||
vi.mock('@fastgpt/global/common/string/tools', () => ({
|
||||
getNanoid: vi.fn().mockReturnValue('test-nanoid')
|
||||
}));
|
||||
|
||||
const mockStorage = () => {
|
||||
const store = new Map();
|
||||
return {
|
||||
getItem: (key: string) => store.get(key) || null,
|
||||
setItem: (key: string, value: string) => store.set(key, value),
|
||||
clear: () => store.clear(),
|
||||
removeItem: (key: string) => store.delete(key)
|
||||
};
|
||||
};
|
||||
|
||||
const mockWindow = () => {
|
||||
const windowMock = {
|
||||
location: {
|
||||
search: '?appId=test123'
|
||||
},
|
||||
sessionStorage: mockStorage(),
|
||||
localStorage: mockStorage()
|
||||
};
|
||||
|
||||
vi.stubGlobal('window', windowMock);
|
||||
global.sessionStorage = windowMock.sessionStorage;
|
||||
global.localStorage = windowMock.localStorage;
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
vi.clearAllMocks();
|
||||
mockWindow();
|
||||
const store = useChatStore.getState();
|
||||
store.source = undefined;
|
||||
store.appId = '';
|
||||
store.chatId = '';
|
||||
store.lastChatId = '';
|
||||
store.lastChatAppId = '';
|
||||
store.outLinkAuthData = {};
|
||||
sessionStorage.clear();
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
describe('useChatStore', () => {
|
||||
it('should set source and restore last chat if available', () => {
|
||||
const store = useChatStore.getState();
|
||||
store.lastChatAppId = 'app123';
|
||||
store.lastChatId = `${ChatSourceEnum.share}-chat123`;
|
||||
|
||||
store.setSource(ChatSourceEnum.share);
|
||||
|
||||
const updatedStore = useChatStore.getState();
|
||||
expect(updatedStore.source).toBe(ChatSourceEnum.share);
|
||||
expect(updatedStore.chatId).toBe('chat123');
|
||||
expect(updatedStore.lastChatAppId).toBe('app123');
|
||||
});
|
||||
|
||||
it('should generate new chatId when source changes', () => {
|
||||
const store = useChatStore.getState();
|
||||
store.source = ChatSourceEnum.share;
|
||||
store.chatId = 'old-id';
|
||||
|
||||
store.setSource(ChatSourceEnum.api);
|
||||
const updatedStore = useChatStore.getState();
|
||||
|
||||
expect(updatedStore.chatId).toBe('test-nanoid');
|
||||
expect(updatedStore.chatId).not.toBe('old-id');
|
||||
});
|
||||
|
||||
it('should set appId and lastChatAppId', () => {
|
||||
const store = useChatStore.getState();
|
||||
store.setAppId('test123');
|
||||
const updatedStore = useChatStore.getState();
|
||||
|
||||
expect(updatedStore.appId).toBe('test123');
|
||||
expect(updatedStore.lastChatAppId).toBe('test123');
|
||||
});
|
||||
|
||||
it('should not set empty appId', () => {
|
||||
const store = useChatStore.getState();
|
||||
store.setAppId('test123');
|
||||
store.setAppId('');
|
||||
const updatedStore = useChatStore.getState();
|
||||
|
||||
expect(updatedStore.appId).toBe('test123');
|
||||
expect(updatedStore.lastChatAppId).toBe('test123');
|
||||
});
|
||||
|
||||
it('should set chatId and lastChatId', () => {
|
||||
const store = useChatStore.getState();
|
||||
store.source = ChatSourceEnum.share;
|
||||
store.setChatId('test-id');
|
||||
const updatedStore = useChatStore.getState();
|
||||
|
||||
expect(updatedStore.chatId).toBe('test-id');
|
||||
expect(updatedStore.lastChatId).toBe(`${ChatSourceEnum.share}-test-id`);
|
||||
});
|
||||
|
||||
it('should generate new chatId if none provided', () => {
|
||||
const store = useChatStore.getState();
|
||||
store.source = ChatSourceEnum.share;
|
||||
store.setChatId();
|
||||
const updatedStore = useChatStore.getState();
|
||||
|
||||
expect(updatedStore.chatId).toBe('test-nanoid');
|
||||
});
|
||||
|
||||
it('should set outLinkAuthData', () => {
|
||||
const store = useChatStore.getState();
|
||||
const authData = { apikey: 'test-key' };
|
||||
store.setOutLinkAuthData(authData);
|
||||
const updatedStore = useChatStore.getState();
|
||||
|
||||
expect(updatedStore.outLinkAuthData).toEqual(authData);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createCustomStorage', () => {
|
||||
it('should create storage with appId in key', () => {
|
||||
const storage = createCustomStorage();
|
||||
const testData = {
|
||||
state: {
|
||||
source: ChatSourceEnum.share,
|
||||
chatId: '123',
|
||||
appId: 'app123',
|
||||
lastChatId: 'last123',
|
||||
lastChatAppId: 'lastApp123'
|
||||
},
|
||||
version: 0
|
||||
};
|
||||
|
||||
storage.setItem('test', JSON.stringify(testData));
|
||||
|
||||
const sessionResult = JSON.parse(sessionStorage.getItem('test_test123') || '{}');
|
||||
const localResult = JSON.parse(localStorage.getItem('test_test123') || '{}');
|
||||
|
||||
expect(sessionResult.state).toEqual({
|
||||
source: ChatSourceEnum.share,
|
||||
chatId: '123',
|
||||
appId: 'app123'
|
||||
});
|
||||
|
||||
expect(localResult.state).toEqual({
|
||||
lastChatId: 'last123',
|
||||
lastChatAppId: 'lastApp123'
|
||||
});
|
||||
});
|
||||
|
||||
it('should remove items from both storages', () => {
|
||||
const storage = createCustomStorage();
|
||||
const testData = {
|
||||
state: {
|
||||
source: ChatSourceEnum.share,
|
||||
chatId: '123'
|
||||
},
|
||||
version: 0
|
||||
};
|
||||
|
||||
storage.setItem('test', JSON.stringify(testData));
|
||||
storage.removeItem('test');
|
||||
|
||||
expect(sessionStorage.getItem('test_test123')).toBeNull();
|
||||
expect(localStorage.getItem('test_test123')).toBeNull();
|
||||
});
|
||||
});
|
||||
Binary file not shown.
@ -0,0 +1 @@
|
||||
{"/root/.cache/node/corepack/v1/pnpm/9.15.5/bin/pnpm.cjs":["f5286335ac1397138eff043e0d78e29501577055",0,1472],"/root/.cache/node/corepack/v1/pnpm/9.15.5/dist/pnpm.cjs":["0b2b22796df6e249cd89f4cdf06786d40a52564e",1472,886352]}
|
||||
Loading…
x
Reference in New Issue
Block a user