Files
upstream-frappe-crm/frontend/tests/unit/processField.test.js
upstream-mirror db69de1c11
Some checks failed
Frontend / Unit Tests & Coverage (push) Has been skipped
Regenerate POT file (translatable strings) / Regenerate POT file (develop) (push) Failing after 1m13s
Regenerate POT file (translatable strings) / Regenerate POT file (main-hotfix) (push) Failing after 6s
Server / Tests (frappe ${{ matrix.frappe-branch }}) (push) Has been skipped
Server / Resolve frappe matrix (push) Failing after 1s
Frontend / Lint (push) Failing after 1s
Frontend / Production Build (push) Failing after 1s
Server / Coverage Wrap Up (push) Has been skipped
Frontend / Coverage Wrap Up (push) Has been skipped
snapshot of https://github.com/frappe/crm.git (develop, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:36:01 +05:00

275 lines
9.4 KiB
JavaScript

import { processField } from '@/utils/fieldTransforms'
describe('processField', () => {
// ─── Cloning ──────────────────────────────────────────────────
it('returns a new object, not the original', () => {
const raw = { fieldname: 'status', fieldtype: 'Data', label: 'Status' }
const result = processField(raw)
expect(result).not.toBe(raw)
})
it('does not mutate the original field', () => {
const raw = {
fieldname: 'status',
fieldtype: 'Select',
options: 'New\nOpen',
}
processField(raw)
expect(raw.options).toBe('New\nOpen')
expect(raw.fieldtype).toBe('Select')
})
it('does not mutate the original when overrides are applied', () => {
const raw = { fieldname: 'x', fieldtype: 'Data', label: 'Original' }
processField(raw, { propertyOverrides: { x: { label: 'Changed' } } })
expect(raw.label).toBe('Original')
})
it('returns null for null input', () => {
expect(processField(null)).toBeNull()
})
it('returns null for undefined input', () => {
expect(processField(undefined)).toBeNull()
})
// ─── Select option transform ──────────────────────────────────
it('converts Select options string to {label,value} array', () => {
const raw = {
fieldname: 'status',
fieldtype: 'Select',
options: 'New\nOpen\nClosed',
}
const result = processField(raw)
expect(result.options).toEqual([
{ label: '', value: '' },
{ label: 'New', value: 'New' },
{ label: 'Open', value: 'Open' },
{ label: 'Closed', value: 'Closed' },
])
})
it('translates Select option labels but keeps raw values', () => {
const original = globalThis.__
const dictionary = { Billing: 'Rozliczeniowy', Shipping: 'Wysyłkowy' }
globalThis.__ = (msg) => dictionary[msg] || msg
try {
const raw = {
fieldname: 'address_type',
fieldtype: 'Select',
options: 'Billing\nShipping\nOffice',
reqd: 1,
}
const result = processField(raw)
expect(result.options).toEqual([
{ label: 'Rozliczeniowy', value: 'Billing' },
{ label: 'Wysyłkowy', value: 'Shipping' },
{ label: 'Office', value: 'Office' },
])
} finally {
globalThis.__ = original
}
})
it('prepends blank option for non-required Select', () => {
const raw = {
fieldname: 'priority',
fieldtype: 'Select',
options: 'Low\nHigh',
}
const result = processField(raw)
expect(result.options[0]).toEqual({ label: '', value: '' })
expect(result.options).toHaveLength(3)
})
it('skips blank option for required Select', () => {
const raw = {
fieldname: 'status',
fieldtype: 'Select',
options: 'New\nOpen',
reqd: 1,
}
const result = processField(raw)
expect(result.options[0]).toEqual({ label: 'New', value: 'New' })
expect(result.options).toHaveLength(2)
})
it('does not prepend blank when first option is already blank', () => {
const raw = { fieldname: 'x', fieldtype: 'Select', options: '\nA\nB' }
const result = processField(raw)
expect(result.options[0]).toEqual({ label: '', value: '' })
// should NOT have two blanks
expect(result.options.filter((o) => o.value === '')).toHaveLength(1)
})
it('handles single option Select', () => {
const raw = { fieldname: 'x', fieldtype: 'Select', options: 'Only' }
const result = processField(raw)
expect(result.options).toEqual([
{ label: '', value: '' },
{ label: 'Only', value: 'Only' },
])
})
it('handles empty options string', () => {
const raw = { fieldname: 'x', fieldtype: 'Select', options: '' }
const result = processField(raw)
// '' split by \n gives [''] — first value is '' so no blank prepended
expect(result.options).toEqual([{ label: '', value: '' }])
})
it('does not transform if options is already an array', () => {
const opts = [{ label: 'A', value: 'A' }]
const raw = { fieldname: 'x', fieldtype: 'Select', options: opts }
const result = processField(raw)
expect(result.options).toEqual(opts)
})
it('does not transform options for non-Select field types', () => {
const raw = { fieldname: 'x', fieldtype: 'Data', options: 'Email' }
const result = processField(raw)
expect(result.options).toBe('Email')
})
// ─── Link→User transform ─────────────────────────────────────
it('transforms Link with options=User to fieldtype User', () => {
const raw = { fieldname: 'owner', fieldtype: 'Link', options: 'User' }
const result = processField(raw)
expect(result.fieldtype).toBe('User')
// original untouched
expect(raw.fieldtype).toBe('Link')
})
it('does not transform Link with other options', () => {
const raw = { fieldname: 'org', fieldtype: 'Link', options: 'Organization' }
const result = processField(raw)
expect(result.fieldtype).toBe('Link')
expect(result.options).toBe('Organization')
})
it('does not transform non-Link field types', () => {
const raw = { fieldname: 'x', fieldtype: 'Data', options: 'User' }
const result = processField(raw)
expect(result.fieldtype).toBe('Data')
})
// ─── Perm overrides ──────────────────────────────────────────
it('applies perm overrides', () => {
const raw = { fieldname: 'salary', fieldtype: 'Currency', read_only: 0 }
const result = processField(raw, {
permOverrides: { salary: { read_only: 1 } },
})
expect(result.read_only).toBe(1)
})
it('perm overrides do not mutate original', () => {
const raw = { fieldname: 'salary', fieldtype: 'Currency', read_only: 0 }
processField(raw, { permOverrides: { salary: { read_only: 1 } } })
expect(raw.read_only).toBe(0)
})
// ─── Script property overrides ────────────────────────────────
it('applies script property overrides', () => {
const raw = {
fieldname: 'email',
fieldtype: 'Data',
hidden: 0,
label: 'Email',
}
const result = processField(raw, {
propertyOverrides: { email: { hidden: 1, label: 'Work Email' } },
})
expect(result.hidden).toBe(1)
expect(result.label).toBe('Work Email')
})
it('script overrides win over perm overrides', () => {
const raw = { fieldname: 'salary', fieldtype: 'Currency', read_only: 0 }
const result = processField(raw, {
permOverrides: { salary: { read_only: 1 } },
propertyOverrides: { salary: { read_only: 0 } },
})
expect(result.read_only).toBe(0)
})
it('script overrides win over raw field values', () => {
const raw = { fieldname: 'x', fieldtype: 'Data', label: 'Old', hidden: 0 }
const result = processField(raw, {
propertyOverrides: { x: { label: 'New', hidden: true } },
})
expect(result.label).toBe('New')
expect(result.hidden).toBe(true)
})
it('unrelated overrides do not affect the field', () => {
const raw = { fieldname: 'email', fieldtype: 'Data', label: 'Email' }
const result = processField(raw, {
propertyOverrides: { other_field: { hidden: true } },
})
expect(result.label).toBe('Email')
expect(result.hidden).toBeUndefined()
})
// ─── Override changes Select options ──────────────────────────
it('override can replace Select options string', () => {
const raw = { fieldname: 'status', fieldtype: 'Select', options: 'A\nB' }
const result = processField(raw, {
propertyOverrides: { status: { options: 'X\nY\nZ' } },
})
expect(result.options).toEqual([
{ label: '', value: '' },
{ label: 'X', value: 'X' },
{ label: 'Y', value: 'Y' },
{ label: 'Z', value: 'Z' },
])
})
it('override reqd affects blank option prepending', () => {
const raw = {
fieldname: 'status',
fieldtype: 'Select',
options: 'A\nB',
reqd: 0,
}
const result = processField(raw, {
propertyOverrides: { status: { reqd: 1 } },
})
// reqd=1 from override → no blank option
expect(result.options[0]).toEqual({ label: 'A', value: 'A' })
})
// ─── Combined transforms ─────────────────────────────────────
it('applies overrides before Select transform', () => {
// Override changes options string, then transform converts to array
const raw = { fieldname: 's', fieldtype: 'Select', options: 'Old1\nOld2' }
const result = processField(raw, {
propertyOverrides: { s: { options: 'New1\nNew2\nNew3' } },
})
expect(result.options).toHaveLength(4) // blank + 3
expect(result.options[1].value).toBe('New1')
})
it('preserves non-overridden properties', () => {
const raw = {
fieldname: 'x',
fieldtype: 'Data',
label: 'X',
description: 'Help text',
placeholder: 'Enter X',
}
const result = processField(raw, {
propertyOverrides: { x: { label: 'Y' } },
})
expect(result.label).toBe('Y')
expect(result.description).toBe('Help text')
expect(result.placeholder).toBe('Enter X')
})
})