refactor: fold cache revalidation into the event dispatcher

This commit is contained in:
Shivam Mishra
2026-06-10 12:59:26 +05:30
parent 343b25842a
commit 3e65534e68
11 changed files with 136 additions and 184 deletions
@@ -1,37 +1,108 @@
import { dispatchCacheRevalidations } from '../../CacheHelper/dispatchCacheRevalidations';
import InboxesAPI from 'dashboard/api/inboxes';
import LabelsAPI from 'dashboard/api/labels';
import CannedResponseAPI from 'dashboard/api/cannedResponse';
import TeamsAPI from 'dashboard/api/teams';
vi.mock('dashboard/api/inboxes', () => ({
default: {
validateCacheKey: vi.fn(),
refetchAndCommit: vi.fn(),
extractDataFromResponse: vi.fn(),
},
}));
vi.mock('dashboard/api/labels', () => ({
default: {
validateCacheKey: vi.fn(),
refetchAndCommit: vi.fn(),
extractDataFromResponse: vi.fn(),
},
}));
vi.mock('dashboard/api/teams', () => ({
default: {
validateCacheKey: vi.fn(),
refetchAndCommit: vi.fn(),
extractDataFromResponse: vi.fn(),
},
}));
vi.mock('dashboard/api/cannedResponse', () => ({
default: {
validateCacheKey: vi.fn(),
refetchAndCommit: vi.fn(),
extractDataFromResponse: vi.fn(),
},
}));
vi.mock('dashboard/api/agents', () => ({
default: {
validateCacheKey: vi.fn(),
refetchAndCommit: vi.fn(),
extractDataFromResponse: vi.fn(),
},
}));
vi.mock('dashboard/api/attributes', () => ({
default: {
validateCacheKey: vi.fn(),
refetchAndCommit: vi.fn(),
extractDataFromResponse: vi.fn(),
},
}));
describe('dispatchCacheRevalidations', () => {
it('dispatches revalidate actions for cacheable models present in the key payload', async () => {
const store = {
dispatch: vi.fn().mockResolvedValue(),
};
let store;
beforeEach(() => {
vi.clearAllMocks();
store = { commit: vi.fn() };
});
it('refetches stale models and commits via their setMutation', async () => {
InboxesAPI.validateCacheKey.mockResolvedValue(false);
InboxesAPI.refetchAndCommit.mockResolvedValue({ data: { payload: [] } });
InboxesAPI.extractDataFromResponse.mockReturnValue([{ id: 1 }]);
LabelsAPI.validateCacheKey.mockResolvedValue(true);
await dispatchCacheRevalidations(store, {
inbox: 'inbox-key',
label: 'label-key',
canned_response: 'canned-key',
unknown_model: 'ignored-key',
});
expect(store.dispatch).toHaveBeenCalledWith('inboxes/revalidate', {
newKey: 'inbox-key',
});
expect(store.dispatch).toHaveBeenCalledWith('labels/revalidate', {
newKey: 'label-key',
});
expect(store.dispatch).toHaveBeenCalledWith('revalidateCannedResponses', {
newKey: 'canned-key',
});
expect(store.dispatch).toHaveBeenCalledTimes(3);
expect(InboxesAPI.refetchAndCommit).toHaveBeenCalledWith('inbox-key');
expect(store.commit).toHaveBeenCalledWith('inboxes/SET_INBOXES', [
{ id: 1 },
]);
expect(LabelsAPI.refetchAndCommit).not.toHaveBeenCalled();
expect(store.commit).toHaveBeenCalledTimes(1);
});
it('skips models absent from the key payload', async () => {
InboxesAPI.validateCacheKey.mockResolvedValue(true);
await dispatchCacheRevalidations(store, { inbox: 'inbox-key' });
expect(TeamsAPI.validateCacheKey).not.toHaveBeenCalled();
expect(store.commit).not.toHaveBeenCalled();
});
it('treats missing keys as an empty payload', async () => {
const store = {
dispatch: vi.fn(),
};
await dispatchCacheRevalidations(store);
expect(store.dispatch).not.toHaveBeenCalled();
expect(InboxesAPI.validateCacheKey).not.toHaveBeenCalled();
expect(store.commit).not.toHaveBeenCalled();
});
it('swallows per-model errors so one failure does not block the rest', async () => {
InboxesAPI.validateCacheKey.mockResolvedValue(false);
InboxesAPI.refetchAndCommit.mockRejectedValue(new Error('network down'));
CannedResponseAPI.validateCacheKey.mockResolvedValue(false);
CannedResponseAPI.refetchAndCommit.mockResolvedValue({ data: [] });
CannedResponseAPI.extractDataFromResponse.mockReturnValue([{ id: 7 }]);
await dispatchCacheRevalidations(store, {
inbox: 'inbox-key',
canned_response: 'canned-key',
});
expect(store.commit).toHaveBeenCalledWith('SET_CANNED', [{ id: 7 }]);
expect(store.commit).toHaveBeenCalledTimes(1);
});
});