Co-authored-by: Vinay Keerthi <11478411+stonecharioteer@users.noreply.github.com> Co-authored-by: Shivam Mishra <scm.mymail@gmail.com> Co-authored-by: Pranav <pranav@chatwoot.com>
762 lines
23 KiB
JavaScript
762 lines
23 KiB
JavaScript
import { setActivePinia, createPinia } from 'pinia';
|
|
import { throwErrorMessage } from 'dashboard/store/utils/api';
|
|
import * as MutationHelpers from 'shared/helpers/vuex/mutationHelpers';
|
|
import {
|
|
generateMutationTypes,
|
|
createInitialState,
|
|
createGetters,
|
|
createMutations,
|
|
createCrudActions,
|
|
createStore,
|
|
} from './storeFactory';
|
|
|
|
vi.mock('dashboard/store/utils/api', () => ({
|
|
throwErrorMessage: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('shared/helpers/vuex/mutationHelpers', () => ({
|
|
set: vi.fn(),
|
|
create: vi.fn(),
|
|
update: vi.fn(),
|
|
destroy: vi.fn(),
|
|
setSingleRecord: vi.fn(),
|
|
}));
|
|
|
|
describe('storeFactory', () => {
|
|
describe('createStore with type parameter', () => {
|
|
beforeEach(() => {
|
|
setActivePinia(createPinia());
|
|
});
|
|
|
|
it('creates Vuex store by default', () => {
|
|
const API = {};
|
|
const store = createStore({ name: 'test', API });
|
|
|
|
expect(store.namespaced).toBe(true);
|
|
expect(store.state).toBeDefined();
|
|
expect(store.mutations).toBeDefined();
|
|
});
|
|
|
|
it('creates Pinia store when type is "pinia"', () => {
|
|
const API = {
|
|
get: vi.fn(),
|
|
show: vi.fn(),
|
|
create: vi.fn(),
|
|
update: vi.fn(),
|
|
delete: vi.fn(),
|
|
};
|
|
|
|
const useTestStore = createStore({
|
|
name: 'test',
|
|
API,
|
|
type: 'pinia',
|
|
});
|
|
|
|
const store = useTestStore();
|
|
|
|
expect(store.records).toBeDefined();
|
|
expect(store.get).toBeTypeOf('function');
|
|
expect(store.setUIFlag).toBeTypeOf('function');
|
|
});
|
|
|
|
it('creates Vuex store when type is "vuex"', () => {
|
|
const API = {};
|
|
const store = createStore({
|
|
name: 'test',
|
|
API,
|
|
type: 'vuex',
|
|
});
|
|
|
|
expect(store.namespaced).toBe(true);
|
|
expect(store.state).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('generateMutationTypes', () => {
|
|
it('generates correct mutation types with capitalized name', () => {
|
|
const result = generateMutationTypes('test');
|
|
expect(result).toEqual({
|
|
SET_UI_FLAG: 'SET_TEST_UI_FLAG',
|
|
SET: 'SET_TEST',
|
|
ADD: 'ADD_TEST',
|
|
EDIT: 'EDIT_TEST',
|
|
DELETE: 'DELETE_TEST',
|
|
SET_META: 'SET_TEST_META',
|
|
UPSERT: 'UPSERT_TEST',
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('createInitialState', () => {
|
|
it('returns the correct initial state structure', () => {
|
|
const result = createInitialState();
|
|
expect(result).toEqual({
|
|
records: [],
|
|
meta: {},
|
|
uiFlags: {
|
|
fetchingList: false,
|
|
fetchingItem: false,
|
|
creatingItem: false,
|
|
updatingItem: false,
|
|
deletingItem: false,
|
|
},
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('createGetters', () => {
|
|
it('returns getters with correct implementations', () => {
|
|
const getters = createGetters();
|
|
|
|
const state = {
|
|
records: [{ id: 2 }, { id: 1 }, { id: 3 }],
|
|
uiFlags: { fetchingList: true },
|
|
meta: { totalCount: 10, page: 1 },
|
|
};
|
|
expect(getters.getRecords(state)).toEqual([
|
|
{ id: 3 },
|
|
{ id: 2 },
|
|
{ id: 1 },
|
|
]);
|
|
|
|
expect(getters.getRecord(state)(2)).toEqual({ id: 2 });
|
|
expect(getters.getRecord(state)(4)).toEqual({});
|
|
|
|
expect(getters.getUIFlags(state)).toEqual({
|
|
fetchingList: true,
|
|
});
|
|
|
|
expect(getters.getMeta(state)).toEqual({
|
|
totalCount: 10,
|
|
page: 1,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('createMutations', () => {
|
|
it('creates mutations with correct implementations', () => {
|
|
const mutationTypes = generateMutationTypes('test');
|
|
const mutations = createMutations(mutationTypes);
|
|
|
|
const state = { uiFlags: { fetchingList: false } };
|
|
mutations[mutationTypes.SET_UI_FLAG](state, { fetchingList: true });
|
|
expect(state.uiFlags).toEqual({ fetchingList: true });
|
|
|
|
const metaState = { meta: {} };
|
|
mutations[mutationTypes.SET_META](metaState, {
|
|
total_count: '10',
|
|
page: '2',
|
|
});
|
|
expect(metaState.meta).toEqual({ totalCount: 10, page: 2 });
|
|
|
|
expect(mutations[mutationTypes.SET]).toBe(MutationHelpers.set);
|
|
expect(mutations[mutationTypes.ADD]).toBe(MutationHelpers.create);
|
|
expect(mutations[mutationTypes.EDIT]).toBe(MutationHelpers.update);
|
|
expect(mutations[mutationTypes.DELETE]).toBe(MutationHelpers.destroy);
|
|
expect(mutations[mutationTypes.UPSERT]).toBe(
|
|
MutationHelpers.setSingleRecord
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('createCrudActions', () => {
|
|
let API;
|
|
let commit;
|
|
let mutationTypes;
|
|
let actions;
|
|
|
|
beforeEach(() => {
|
|
API = {
|
|
get: vi.fn(),
|
|
show: vi.fn(),
|
|
create: vi.fn(),
|
|
update: vi.fn(),
|
|
delete: vi.fn(),
|
|
};
|
|
commit = vi.fn();
|
|
mutationTypes = generateMutationTypes('test');
|
|
actions = createCrudActions(API, mutationTypes);
|
|
});
|
|
|
|
describe('get action', () => {
|
|
it('handles successful API response', async () => {
|
|
const payload = [{ id: 1 }];
|
|
const meta = { total_count: 10, page: 1 };
|
|
API.get.mockResolvedValue({ data: { payload, meta } });
|
|
|
|
const result = await actions.get({ commit });
|
|
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
fetchingList: true,
|
|
});
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET, payload);
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_META, meta);
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
fetchingList: false,
|
|
});
|
|
expect(result).toEqual(payload);
|
|
});
|
|
|
|
it('handles API error', async () => {
|
|
const error = new Error('API Error');
|
|
API.get.mockRejectedValue(error);
|
|
throwErrorMessage.mockReturnValue('Error thrown');
|
|
|
|
const result = await actions.get({ commit });
|
|
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
fetchingList: true,
|
|
});
|
|
expect(throwErrorMessage).toHaveBeenCalledWith(error);
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
fetchingList: false,
|
|
});
|
|
expect(result).toEqual('Error thrown');
|
|
});
|
|
});
|
|
|
|
describe('show action', () => {
|
|
it('handles successful API response', async () => {
|
|
const data = { id: 1, name: 'Test' };
|
|
API.show.mockResolvedValue({ data });
|
|
|
|
const result = await actions.show({ commit }, 1);
|
|
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
fetchingItem: true,
|
|
});
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.UPSERT, data);
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
fetchingItem: false,
|
|
});
|
|
expect(result).toEqual(data);
|
|
});
|
|
|
|
it('handles API error', async () => {
|
|
const error = new Error('API Error');
|
|
API.show.mockRejectedValue(error);
|
|
throwErrorMessage.mockReturnValue('Error thrown');
|
|
|
|
const result = await actions.show({ commit }, 1);
|
|
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
fetchingItem: true,
|
|
});
|
|
expect(throwErrorMessage).toHaveBeenCalledWith(error);
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
fetchingItem: false,
|
|
});
|
|
expect(result).toEqual('Error thrown');
|
|
});
|
|
});
|
|
|
|
describe('create action', () => {
|
|
it('handles successful API response', async () => {
|
|
const data = { id: 1, name: 'Test' };
|
|
API.create.mockResolvedValue({ data });
|
|
|
|
const result = await actions.create({ commit }, { name: 'Test' });
|
|
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
creatingItem: true,
|
|
});
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.UPSERT, data);
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
creatingItem: false,
|
|
});
|
|
expect(result).toEqual(data);
|
|
});
|
|
|
|
it('handles API error', async () => {
|
|
const error = new Error('API Error');
|
|
API.create.mockRejectedValue(error);
|
|
throwErrorMessage.mockReturnValue('Error thrown');
|
|
|
|
const result = await actions.create({ commit }, { name: 'Test' });
|
|
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
creatingItem: true,
|
|
});
|
|
expect(throwErrorMessage).toHaveBeenCalledWith(error);
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
creatingItem: false,
|
|
});
|
|
expect(result).toEqual('Error thrown');
|
|
});
|
|
});
|
|
|
|
describe('update action', () => {
|
|
it('handles successful API response', async () => {
|
|
const data = { id: 1, name: 'Updated' };
|
|
API.update.mockResolvedValue({ data });
|
|
|
|
const result = await actions.update(
|
|
{ commit },
|
|
{ id: 1, name: 'Updated' }
|
|
);
|
|
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
updatingItem: true,
|
|
});
|
|
expect(API.update).toHaveBeenCalledWith(1, { name: 'Updated' });
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.EDIT, data);
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
updatingItem: false,
|
|
});
|
|
expect(result).toEqual(data);
|
|
});
|
|
|
|
it('handles API error', async () => {
|
|
const error = new Error('API Error');
|
|
API.update.mockRejectedValue(error);
|
|
throwErrorMessage.mockReturnValue('Error thrown');
|
|
|
|
const result = await actions.update(
|
|
{ commit },
|
|
{ id: 1, name: 'Updated' }
|
|
);
|
|
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
updatingItem: true,
|
|
});
|
|
expect(throwErrorMessage).toHaveBeenCalledWith(error);
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
updatingItem: false,
|
|
});
|
|
expect(result).toEqual('Error thrown');
|
|
});
|
|
});
|
|
|
|
describe('delete action', () => {
|
|
it('handles successful API response', async () => {
|
|
API.delete.mockResolvedValue({});
|
|
|
|
const result = await actions.delete({ commit }, 1);
|
|
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
deletingItem: true,
|
|
});
|
|
expect(API.delete).toHaveBeenCalledWith(1);
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.DELETE, 1);
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
deletingItem: false,
|
|
});
|
|
expect(result).toEqual(1);
|
|
});
|
|
|
|
it('handles API error', async () => {
|
|
const error = new Error('API Error');
|
|
API.delete.mockRejectedValue(error);
|
|
throwErrorMessage.mockReturnValue('Error thrown');
|
|
|
|
const result = await actions.delete({ commit }, 1);
|
|
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
deletingItem: true,
|
|
});
|
|
expect(throwErrorMessage).toHaveBeenCalledWith(error);
|
|
expect(commit).toHaveBeenCalledWith(mutationTypes.SET_UI_FLAG, {
|
|
deletingItem: false,
|
|
});
|
|
expect(result).toEqual('Error thrown');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('createStore - Vuex type', () => {
|
|
it('creates a complete Vuex store with default options', () => {
|
|
const API = {};
|
|
const store = createStore({ name: 'test', API, type: 'vuex' });
|
|
|
|
expect(store.namespaced).toBe(true);
|
|
expect(store.state).toEqual(createInitialState());
|
|
expect(Object.keys(store.getters)).toEqual([
|
|
'getRecords',
|
|
'getRecord',
|
|
'getUIFlags',
|
|
'getMeta',
|
|
]);
|
|
expect(Object.keys(store.mutations)).toEqual([
|
|
'SET_TEST_UI_FLAG',
|
|
'SET_TEST_META',
|
|
'SET_TEST',
|
|
'ADD_TEST',
|
|
'EDIT_TEST',
|
|
'DELETE_TEST',
|
|
'UPSERT_TEST',
|
|
]);
|
|
expect(Object.keys(store.actions)).toEqual([
|
|
'get',
|
|
'show',
|
|
'create',
|
|
'update',
|
|
'delete',
|
|
]);
|
|
});
|
|
|
|
it('creates a Vuex store with custom actions and getters', () => {
|
|
const API = {};
|
|
const customGetters = { customGetter: () => 'custom' };
|
|
const customActions = () => ({
|
|
customAction: () => 'custom',
|
|
});
|
|
|
|
const store = createStore({
|
|
name: 'test',
|
|
API,
|
|
type: 'vuex',
|
|
getters: customGetters,
|
|
actions: customActions,
|
|
});
|
|
|
|
expect(store.getters).toHaveProperty('customGetter');
|
|
expect(store.actions).toHaveProperty('customAction');
|
|
expect(Object.keys(store.getters)).toEqual([
|
|
'getRecords',
|
|
'getRecord',
|
|
'getUIFlags',
|
|
'getMeta',
|
|
'customGetter',
|
|
]);
|
|
expect(Object.keys(store.actions)).toEqual([
|
|
'get',
|
|
'show',
|
|
'create',
|
|
'update',
|
|
'delete',
|
|
'customAction',
|
|
]);
|
|
});
|
|
|
|
it('creates a Vuex store with custom mutations', () => {
|
|
const API = {};
|
|
const customMutations = {
|
|
CUSTOM_MUTATION: state => {
|
|
state.custom = true;
|
|
},
|
|
};
|
|
|
|
const store = createStore({
|
|
name: 'test',
|
|
API,
|
|
type: 'vuex',
|
|
mutations: customMutations,
|
|
});
|
|
|
|
expect(store.mutations).toHaveProperty('CUSTOM_MUTATION');
|
|
});
|
|
});
|
|
|
|
describe('createStore - Pinia type', () => {
|
|
let API;
|
|
|
|
beforeEach(() => {
|
|
setActivePinia(createPinia());
|
|
API = {
|
|
get: vi.fn(),
|
|
show: vi.fn(),
|
|
create: vi.fn(),
|
|
update: vi.fn(),
|
|
delete: vi.fn(),
|
|
};
|
|
});
|
|
|
|
it('creates a Pinia store with correct structure', () => {
|
|
const useTestStore = createStore({
|
|
name: 'test',
|
|
API,
|
|
type: 'pinia',
|
|
});
|
|
|
|
const store = useTestStore();
|
|
|
|
expect(store.records).toEqual([]);
|
|
expect(store.meta).toEqual({});
|
|
expect(store.uiFlags).toEqual({
|
|
fetchingList: false,
|
|
fetchingItem: false,
|
|
creatingItem: false,
|
|
updatingItem: false,
|
|
deletingItem: false,
|
|
});
|
|
});
|
|
|
|
it('has standard getters', () => {
|
|
const useTestStore = createStore({
|
|
name: 'test',
|
|
API,
|
|
type: 'pinia',
|
|
});
|
|
|
|
const store = useTestStore();
|
|
store.records = [{ id: 2 }, { id: 1 }, { id: 3 }];
|
|
store.meta = { totalCount: 10, page: 1 };
|
|
store.uiFlags = { fetchingList: true };
|
|
|
|
expect(store.getRecords).toEqual([{ id: 3 }, { id: 2 }, { id: 1 }]);
|
|
expect(store.getRecord(2)).toEqual({ id: 2 });
|
|
expect(store.getRecord(4)).toEqual({});
|
|
expect(store.getUIFlags).toEqual({ fetchingList: true });
|
|
expect(store.getMeta).toEqual({ totalCount: 10, page: 1 });
|
|
});
|
|
|
|
it('has custom getters', () => {
|
|
const useTestStore = createStore({
|
|
name: 'test',
|
|
API,
|
|
type: 'pinia',
|
|
getters: {
|
|
customGetter: state => state.records.length,
|
|
},
|
|
});
|
|
|
|
const store = useTestStore();
|
|
store.records = [{ id: 1 }, { id: 2 }];
|
|
|
|
expect(store.customGetter).toBe(2);
|
|
});
|
|
|
|
describe('setUIFlag action', () => {
|
|
it('updates UI flags correctly', () => {
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
|
|
store.setUIFlag({ fetchingList: true });
|
|
expect(store.uiFlags.fetchingList).toBe(true);
|
|
|
|
store.setUIFlag({ creatingItem: true });
|
|
expect(store.uiFlags.fetchingList).toBe(true);
|
|
expect(store.uiFlags.creatingItem).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('setMeta action', () => {
|
|
it('updates meta with snake_case input', () => {
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
|
|
store.setMeta({ total_count: '10', page: '2' });
|
|
expect(store.meta.totalCount).toBe(10);
|
|
expect(store.meta.page).toBe(2);
|
|
});
|
|
|
|
it('updates meta with camelCase input', () => {
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
|
|
store.setMeta({ totalCount: 15, page: 3 });
|
|
expect(store.meta.totalCount).toBe(15);
|
|
expect(store.meta.page).toBe(3);
|
|
});
|
|
});
|
|
|
|
describe('get action', () => {
|
|
it('fetches records successfully', async () => {
|
|
const payload = [{ id: 1, name: 'Test' }];
|
|
const meta = { total_count: 1, page: 1 };
|
|
API.get.mockResolvedValue({ data: { payload, meta } });
|
|
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
|
|
await store.get({ page: 1 });
|
|
|
|
expect(API.get).toHaveBeenCalledWith({ page: 1 });
|
|
expect(store.records).toEqual(payload);
|
|
expect(store.meta.totalCount).toBe(1);
|
|
expect(store.meta.page).toBe(1);
|
|
expect(store.uiFlags.fetchingList).toBe(false);
|
|
});
|
|
|
|
it('handles API response without meta', async () => {
|
|
const data = [{ id: 1, name: 'Test' }];
|
|
API.get.mockResolvedValue({ data });
|
|
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
|
|
await store.get();
|
|
|
|
expect(store.records).toEqual(data);
|
|
});
|
|
|
|
it('handles errors and resets UI flags', async () => {
|
|
const error = new Error('API Error');
|
|
API.get.mockRejectedValue(error);
|
|
throwErrorMessage.mockReturnValue('Error thrown');
|
|
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
|
|
const result = await store.get();
|
|
|
|
expect(throwErrorMessage).toHaveBeenCalledWith(error);
|
|
expect(store.uiFlags.fetchingList).toBe(false);
|
|
expect(result).toBe('Error thrown');
|
|
});
|
|
});
|
|
|
|
describe('show action', () => {
|
|
it('fetches and upserts a record', async () => {
|
|
const data = { id: 1, name: 'Test' };
|
|
API.show.mockResolvedValue({ data });
|
|
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
|
|
const result = await store.show(1);
|
|
|
|
expect(API.show).toHaveBeenCalledWith(1);
|
|
expect(store.records).toContainEqual(data);
|
|
expect(result).toEqual(data);
|
|
expect(store.uiFlags.fetchingItem).toBe(false);
|
|
});
|
|
|
|
it('updates existing record', async () => {
|
|
const data = { id: 1, name: 'Updated' };
|
|
API.show.mockResolvedValue({ data });
|
|
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
store.records = [{ id: 1, name: 'Original' }];
|
|
|
|
await store.show(1);
|
|
|
|
expect(store.records).toHaveLength(1);
|
|
expect(store.records[0].name).toBe('Updated');
|
|
});
|
|
|
|
it('handles payload wrapper', async () => {
|
|
const record = { id: 1, name: 'Test' };
|
|
API.show.mockResolvedValue({ data: { payload: record } });
|
|
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
|
|
const result = await store.show(1);
|
|
|
|
expect(result).toEqual(record);
|
|
expect(store.records).toContainEqual(record);
|
|
});
|
|
});
|
|
|
|
describe('create action', () => {
|
|
it('creates a new record', async () => {
|
|
const data = { id: 1, name: 'New' };
|
|
API.create.mockResolvedValue({ data });
|
|
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
|
|
const result = await store.create({ name: 'New' });
|
|
|
|
expect(API.create).toHaveBeenCalledWith({ name: 'New' });
|
|
expect(store.records).toContainEqual(data);
|
|
expect(result).toEqual(data);
|
|
expect(store.uiFlags.creatingItem).toBe(false);
|
|
});
|
|
|
|
it('handles payload wrapper', async () => {
|
|
const record = { id: 1, name: 'New' };
|
|
API.create.mockResolvedValue({ data: { payload: record } });
|
|
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
|
|
const result = await store.create({ name: 'New' });
|
|
|
|
expect(result).toEqual(record);
|
|
expect(store.records).toContainEqual(record);
|
|
});
|
|
});
|
|
|
|
describe('update action', () => {
|
|
it('updates an existing record', async () => {
|
|
const data = { id: 1, name: 'Updated' };
|
|
API.update.mockResolvedValue({ data });
|
|
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
store.records = [{ id: 1, name: 'Original' }];
|
|
|
|
const result = await store.update({ id: 1, name: 'Updated' });
|
|
|
|
expect(API.update).toHaveBeenCalledWith(1, { name: 'Updated' });
|
|
expect(store.records[0].name).toBe('Updated');
|
|
expect(result).toEqual(data);
|
|
expect(store.uiFlags.updatingItem).toBe(false);
|
|
});
|
|
|
|
it('handles payload wrapper', async () => {
|
|
const record = { id: 1, name: 'Updated' };
|
|
API.update.mockResolvedValue({ data: { payload: record } });
|
|
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
store.records = [{ id: 1, name: 'Original' }];
|
|
|
|
const result = await store.update({ id: 1, name: 'Updated' });
|
|
|
|
expect(result).toEqual(record);
|
|
expect(store.records[0]).toEqual(record);
|
|
});
|
|
});
|
|
|
|
describe('delete action', () => {
|
|
it('deletes a record', async () => {
|
|
API.delete.mockResolvedValue({});
|
|
|
|
const useTestStore = createStore({ name: 'test', API, type: 'pinia' });
|
|
const store = useTestStore();
|
|
store.records = [{ id: 1 }, { id: 2 }, { id: 3 }];
|
|
|
|
const result = await store.delete(2);
|
|
|
|
expect(API.delete).toHaveBeenCalledWith(2);
|
|
expect(store.records).toHaveLength(2);
|
|
expect(store.records).not.toContainEqual({ id: 2 });
|
|
expect(result).toBe(2);
|
|
expect(store.uiFlags.deletingItem).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('custom actions', () => {
|
|
it('includes custom actions', async () => {
|
|
const useTestStore = createStore({
|
|
name: 'test',
|
|
API,
|
|
type: 'pinia',
|
|
actions: () => ({
|
|
customAction() {
|
|
return 'custom result';
|
|
},
|
|
}),
|
|
});
|
|
|
|
const store = useTestStore();
|
|
const result = store.customAction();
|
|
|
|
expect(result).toBe('custom result');
|
|
});
|
|
|
|
it('custom actions can access store state', () => {
|
|
const useTestStore = createStore({
|
|
name: 'test',
|
|
API,
|
|
type: 'pinia',
|
|
actions: () => ({
|
|
getRecordCount() {
|
|
return this.records.length;
|
|
},
|
|
}),
|
|
});
|
|
|
|
const store = useTestStore();
|
|
store.records = [{ id: 1 }, { id: 2 }];
|
|
|
|
expect(store.getRecordCount()).toBe(2);
|
|
});
|
|
});
|
|
});
|
|
});
|