Copy the Chatwoot (v4.14.0) frontend runnable subset into frontend/ for customization: - app/javascript/ (Vue SPA: dashboard, widget, sdk, portal, superadmin) - app/views/ (ERB templates for vite-plugin-ruby entrypoint resolution) - app/helpers/, app/assets/ (Rails view helpers, static assets) - enterprise/ (Enterprise edition frontend overlay) - config/vite.json, vite.config.ts, bin/vite (Vite-Rails toolchain) - package.json, pnpm-lock.yaml, tailwind/postcss/eslint configs - Gemfile, Gemfile.lock (vite_rails gem for bin/vite binstub) Excluded Rails backend: controllers, models, services, jobs, mailers, policies, db, lib, spec, public, node_modules. Update references to the new frontend location: - .gitignore: exclude frontend build artifacts (node_modules, tmp, packs), keep frontend/bin/ and frontend/vendor/ via negation - backend/scripts/parity_frontend_smoke.sh: CHATWOOT_DIR default reference/chatwoot -> ../frontend - backend/scripts/parity_frontend_browser_smoke.mjs: same default update - AGENTS.md: add frontend section with Rails/Vite coupling notes - README: architecture tree includes frontend/
195 lines
5.2 KiB
JavaScript
195 lines
5.2 KiB
JavaScript
import {
|
|
extractChangedAccountUserValues,
|
|
generateTranslationPayload,
|
|
generateLogActionKey,
|
|
} from '../auditlogHelper'; // import the functions
|
|
|
|
describe('Helper functions', () => {
|
|
const agentList = [
|
|
{ id: 1, name: 'Agent 1' },
|
|
{ id: 2, name: 'Agent 2' },
|
|
{ id: 3, name: 'Agent 3' },
|
|
];
|
|
|
|
describe('extractChangedAccountUserValues', () => {
|
|
it('should correctly extract values when role is changed', () => {
|
|
const changes = {
|
|
role: [0, 1],
|
|
};
|
|
const { changes: extractedChanges, values } =
|
|
extractChangedAccountUserValues(changes);
|
|
expect(extractedChanges).toEqual(['role']);
|
|
expect(values).toEqual(['administrator']);
|
|
});
|
|
|
|
it('should correctly extract values when availability is changed', () => {
|
|
const changes = {
|
|
availability: [0, 2],
|
|
};
|
|
const { changes: extractedChanges, values } =
|
|
extractChangedAccountUserValues(changes);
|
|
expect(extractedChanges).toEqual(['availability']);
|
|
expect(values).toEqual(['busy']);
|
|
});
|
|
|
|
it('should correctly extract values when both are changed', () => {
|
|
const changes = {
|
|
role: [1, 0],
|
|
availability: [1, 2],
|
|
};
|
|
const { changes: extractedChanges, values } =
|
|
extractChangedAccountUserValues(changes);
|
|
expect(extractedChanges).toEqual(['role', 'availability']);
|
|
expect(values).toEqual(['agent', 'busy']);
|
|
});
|
|
});
|
|
|
|
describe('generateTranslationPayload', () => {
|
|
it('should handle AccountUser create', () => {
|
|
const auditLogItem = {
|
|
auditable_type: 'AccountUser',
|
|
action: 'create',
|
|
user_id: 1,
|
|
auditable_id: 123,
|
|
audited_changes: {
|
|
user_id: 2,
|
|
role: 1,
|
|
},
|
|
};
|
|
|
|
const payload = generateTranslationPayload(auditLogItem, agentList);
|
|
expect(payload).toEqual({
|
|
agentName: 'Agent 1',
|
|
id: 123,
|
|
invitee: 'Agent 2',
|
|
role: 'administrator',
|
|
});
|
|
});
|
|
|
|
it('should handle AccountUser update', () => {
|
|
const auditLogItem = {
|
|
auditable_type: 'AccountUser',
|
|
action: 'update',
|
|
user_id: 1,
|
|
auditable_id: 123,
|
|
audited_changes: {
|
|
user_id: 2,
|
|
role: [1, 0],
|
|
availability: [0, 2],
|
|
},
|
|
auditable: {
|
|
user_id: 3,
|
|
},
|
|
};
|
|
|
|
const payload = generateTranslationPayload(auditLogItem, agentList);
|
|
expect(payload).toEqual({
|
|
agentName: 'Agent 1',
|
|
id: 123,
|
|
user: 'Agent 3',
|
|
attributes: ['role', 'availability'],
|
|
values: ['agent', 'busy'],
|
|
});
|
|
});
|
|
|
|
it('should handle InboxMember or TeamMember', () => {
|
|
const auditLogItemInboxMember = {
|
|
auditable_type: 'InboxMember',
|
|
action: 'create',
|
|
audited_changes: {
|
|
user_id: 2,
|
|
},
|
|
user_id: 1,
|
|
auditable_id: 789,
|
|
};
|
|
|
|
const payloadInboxMember = generateTranslationPayload(
|
|
auditLogItemInboxMember,
|
|
agentList
|
|
);
|
|
expect(payloadInboxMember).toEqual({
|
|
agentName: 'Agent 1',
|
|
id: 789,
|
|
user: 'Agent 2',
|
|
});
|
|
|
|
const auditLogItemTeamMember = {
|
|
auditable_type: 'TeamMember',
|
|
action: 'create',
|
|
audited_changes: {
|
|
user_id: 3,
|
|
},
|
|
user_id: 1,
|
|
auditable_id: 789,
|
|
};
|
|
|
|
const payloadTeamMember = generateTranslationPayload(
|
|
auditLogItemTeamMember,
|
|
agentList
|
|
);
|
|
expect(payloadTeamMember).toEqual({
|
|
agentName: 'Agent 1',
|
|
id: 789,
|
|
user: 'Agent 3',
|
|
});
|
|
});
|
|
|
|
it('should handle generic case like Team create', () => {
|
|
const auditLogItem = {
|
|
auditable_type: 'Team',
|
|
action: 'create',
|
|
user_id: 1,
|
|
auditable_id: 456,
|
|
};
|
|
|
|
const payload = generateTranslationPayload(auditLogItem, agentList);
|
|
expect(payload).toEqual({
|
|
agentName: 'Agent 1',
|
|
id: 456,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('generateLogActionKey', () => {
|
|
it('should generate correct action key when user updates self', () => {
|
|
const auditLogItem = {
|
|
auditable_type: 'AccountUser',
|
|
action: 'update',
|
|
user_id: 1,
|
|
auditable: {
|
|
user_id: 1,
|
|
},
|
|
};
|
|
|
|
const logActionKey = generateLogActionKey(auditLogItem);
|
|
expect(logActionKey).toEqual('AUDIT_LOGS.ACCOUNT_USER.EDIT.SELF');
|
|
});
|
|
|
|
it('should generate correct action key when user updates other agent', () => {
|
|
const auditLogItem = {
|
|
auditable_type: 'AccountUser',
|
|
action: 'update',
|
|
user_id: 1,
|
|
auditable: {
|
|
user_id: 2,
|
|
},
|
|
};
|
|
|
|
const logActionKey = generateLogActionKey(auditLogItem);
|
|
expect(logActionKey).toEqual('AUDIT_LOGS.ACCOUNT_USER.EDIT.OTHER');
|
|
});
|
|
|
|
it('should generate correct action key when updating a deleted user', () => {
|
|
const auditLogItem = {
|
|
auditable_type: 'AccountUser',
|
|
action: 'update',
|
|
user_id: 1,
|
|
auditable: null,
|
|
};
|
|
|
|
const logActionKey = generateLogActionKey(auditLogItem);
|
|
expect(logActionKey).toEqual('AUDIT_LOGS.ACCOUNT_USER.EDIT.DELETED');
|
|
});
|
|
});
|
|
});
|