Skip to content

Commit 7453d81

Browse files
committed
Add test coverage for anyOf defaulting primitive fields
1 parent c948238 commit 7453d81

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed

packages/core/test/anyOf.test.jsx

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,4 +1818,170 @@ describe('anyOf', () => {
18181818
expect(selects).to.have.length.of(0);
18191819
});
18201820
});
1821+
1822+
describe('Boolean field value preservation', () => {
1823+
it('should preserve boolean values when switching between anyOf options with shared properties', () => {
1824+
const schema = {
1825+
type: 'object',
1826+
properties: {
1827+
items: {
1828+
type: 'array',
1829+
items: {
1830+
type: 'object',
1831+
anyOf: [
1832+
{
1833+
title: 'Type A',
1834+
properties: {
1835+
type: { type: 'string', enum: ['typeA'], default: 'typeA' },
1836+
showField: { type: 'boolean' },
1837+
},
1838+
},
1839+
{
1840+
title: 'Type B',
1841+
properties: {
1842+
type: { type: 'string', enum: ['typeB'], default: 'typeB' },
1843+
showField: { type: 'boolean' },
1844+
},
1845+
},
1846+
],
1847+
},
1848+
},
1849+
},
1850+
};
1851+
1852+
const { node, onChange } = createFormComponent({
1853+
schema,
1854+
formData: {
1855+
items: [{ type: 'typeA', showField: true }],
1856+
},
1857+
experimental_defaultFormStateBehavior: {
1858+
mergeDefaultsIntoFormData: 'useDefaultIfFormDataUndefined',
1859+
},
1860+
});
1861+
1862+
// Wait for initial form setup to complete
1863+
if (onChange.lastCall) {
1864+
// Initial state - should have showField = true
1865+
let lastFormData = onChange.lastCall.args[0].formData;
1866+
expect(lastFormData.items[0].showField).to.equal(true);
1867+
}
1868+
1869+
// Switch to typeB
1870+
const dropdown = node.querySelector('select[id="root_items_0__anyof_select"]');
1871+
if (dropdown) {
1872+
act(() => {
1873+
fireEvent.change(dropdown, { target: { value: '1' } });
1874+
});
1875+
1876+
// After switching, the boolean value should be preserved, not converted to {}
1877+
if (onChange.lastCall) {
1878+
const lastFormData = onChange.lastCall.args[0].formData;
1879+
expect(lastFormData.items[0].type).to.equal('typeB');
1880+
expect(lastFormData.items[0].showField).to.equal(true); // Should still be true, not {}
1881+
}
1882+
}
1883+
});
1884+
1885+
it('should handle undefined boolean fields correctly when switching anyOf options', () => {
1886+
const schema = {
1887+
type: 'object',
1888+
properties: {
1889+
items: {
1890+
type: 'array',
1891+
items: {
1892+
type: 'object',
1893+
anyOf: [
1894+
{
1895+
title: 'Type A',
1896+
properties: {
1897+
type: { type: 'string', enum: ['typeA'], default: 'typeA' },
1898+
showField: { type: 'boolean' },
1899+
},
1900+
},
1901+
{
1902+
title: 'Type B',
1903+
properties: {
1904+
type: { type: 'string', enum: ['typeB'], default: 'typeB' },
1905+
showField: { type: 'boolean' },
1906+
},
1907+
},
1908+
],
1909+
},
1910+
},
1911+
},
1912+
};
1913+
1914+
const { node, onChange } = createFormComponent({
1915+
schema,
1916+
formData: {
1917+
items: [{ type: 'typeA' }], // No showField defined
1918+
},
1919+
experimental_defaultFormStateBehavior: {
1920+
mergeDefaultsIntoFormData: 'useDefaultIfFormDataUndefined',
1921+
},
1922+
});
1923+
1924+
// Switch to typeB
1925+
const dropdown = node.querySelector('select[id="root_items_0__anyof_select"]');
1926+
if (dropdown) {
1927+
act(() => {
1928+
fireEvent.change(dropdown, { target: { value: '1' } });
1929+
});
1930+
1931+
// After switching, undefined boolean should remain undefined, not become {}
1932+
const lastFormData = onChange.lastCall.args[0].formData;
1933+
expect(lastFormData.items[0].type).to.equal('typeB');
1934+
1935+
// showField should be undefined, not {} (the bug we fixed)
1936+
if ('showField' in lastFormData.items[0]) {
1937+
expect(lastFormData.items[0].showField).to.not.deep.equal({});
1938+
}
1939+
}
1940+
});
1941+
1942+
it('should handle boolean field values correctly in direct anyOf schemas', () => {
1943+
const schema = {
1944+
type: 'object',
1945+
anyOf: [
1946+
{
1947+
title: 'Option A',
1948+
properties: {
1949+
type: { type: 'string', enum: ['optionA'], default: 'optionA' },
1950+
enabled: { type: 'boolean' },
1951+
},
1952+
},
1953+
{
1954+
title: 'Option B',
1955+
properties: {
1956+
type: { type: 'string', enum: ['optionB'], default: 'optionB' },
1957+
enabled: { type: 'boolean' },
1958+
},
1959+
},
1960+
],
1961+
};
1962+
1963+
const { node, onChange } = createFormComponent({
1964+
schema,
1965+
formData: { type: 'optionA', enabled: false },
1966+
experimental_defaultFormStateBehavior: {
1967+
mergeDefaultsIntoFormData: 'useDefaultIfFormDataUndefined',
1968+
},
1969+
});
1970+
1971+
// Switch to optionB
1972+
const dropdown = node.querySelector('select[id="root__anyof_select"]');
1973+
if (dropdown) {
1974+
act(() => {
1975+
fireEvent.change(dropdown, { target: { value: '1' } });
1976+
});
1977+
1978+
// After switching, the boolean value should be preserved, not converted to {}
1979+
if (onChange.lastCall) {
1980+
const lastFormData = onChange.lastCall.args[0].formData;
1981+
expect(lastFormData.type).to.equal('optionB');
1982+
expect(lastFormData.enabled).to.equal(false); // Should still be false, not {}
1983+
}
1984+
}
1985+
});
1986+
});
18211987
});

0 commit comments

Comments
 (0)