mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-18 00:55:50 +00:00
fix(frontend): validate series_rules as array in settings parse/save
- Add Array.isArray() guard in parseSettings for series_rules, matching the existing EPG ignore list pattern - Include series_rules in arrayFields list in getChangedSettings to prevent stringification during settings round-trip - Add 5 tests covering valid, corrupted, and missing series_rules data
This commit is contained in:
parent
0d6979ce1d
commit
8624436367
2 changed files with 70 additions and 6 deletions
|
|
@ -174,11 +174,12 @@ export const saveChangedSettings = async (settings, changedSettings) => {
|
|||
export const getChangedSettings = (values, settings) => {
|
||||
const changedSettings = {};
|
||||
|
||||
// EPG fields that should be kept as arrays
|
||||
const epgFields = [
|
||||
// Fields that must remain as arrays and not be stringified
|
||||
const arrayFields = [
|
||||
'epg_match_ignore_prefixes',
|
||||
'epg_match_ignore_suffixes',
|
||||
'epg_match_ignore_custom',
|
||||
'series_rules',
|
||||
];
|
||||
|
||||
for (const settingKey in values) {
|
||||
|
|
@ -199,12 +200,11 @@ export const getChangedSettings = (values, settings) => {
|
|||
continue;
|
||||
}
|
||||
|
||||
// Handle EPG fields specially - keep as arrays, don't skip empty arrays
|
||||
if (epgFields.includes(settingKey)) {
|
||||
// Handle array fields - keep as arrays, don't skip empty arrays
|
||||
if (arrayFields.includes(settingKey)) {
|
||||
if (!Array.isArray(actualValue)) {
|
||||
actualValue = [];
|
||||
}
|
||||
// Always include EPG fields in changes (even if empty)
|
||||
changedSettings[settingKey] = actualValue;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -299,7 +299,9 @@ export const parseSettings = (settings) => {
|
|||
typeof dvrSettings.post_offset_minutes === 'number'
|
||||
? dvrSettings.post_offset_minutes
|
||||
: parseInt(dvrSettings.post_offset_minutes, 10) || 0;
|
||||
parsed.series_rules = dvrSettings.series_rules;
|
||||
parsed.series_rules = Array.isArray(dvrSettings.series_rules)
|
||||
? dvrSettings.series_rules
|
||||
: [];
|
||||
}
|
||||
|
||||
// Backup settings - direct mapping with underscore keys
|
||||
|
|
|
|||
|
|
@ -328,6 +328,51 @@ describe('SettingsUtils', () => {
|
|||
const result = SettingsUtils.parseSettings(mockSettings);
|
||||
expect(result.network_access).toEqual(['192.168.1.0/24', '10.0.0.0/8']);
|
||||
});
|
||||
|
||||
it('should parse valid series_rules as array', () => {
|
||||
const mockSettings = {
|
||||
dvr_settings: {
|
||||
id: 2,
|
||||
key: 'dvr_settings',
|
||||
value: {
|
||||
series_rules: [{ tvg_id: 'abc', mode: 'all', title: 'Show' }],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const result = SettingsUtils.parseSettings(mockSettings);
|
||||
expect(result.series_rules).toEqual([
|
||||
{ tvg_id: 'abc', mode: 'all', title: 'Show' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should default series_rules to empty array when not an array', () => {
|
||||
const mockSettings = {
|
||||
dvr_settings: {
|
||||
id: 2,
|
||||
key: 'dvr_settings',
|
||||
value: {
|
||||
series_rules: 'corrupted',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const result = SettingsUtils.parseSettings(mockSettings);
|
||||
expect(result.series_rules).toEqual([]);
|
||||
});
|
||||
|
||||
it('should default series_rules to empty array when missing', () => {
|
||||
const mockSettings = {
|
||||
dvr_settings: {
|
||||
id: 2,
|
||||
key: 'dvr_settings',
|
||||
value: {},
|
||||
},
|
||||
};
|
||||
|
||||
const result = SettingsUtils.parseSettings(mockSettings);
|
||||
expect(result.series_rules).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getChangedSettings', () => {
|
||||
|
|
@ -447,6 +492,23 @@ describe('SettingsUtils', () => {
|
|||
expect(changes.epg_match_ignore_suffixes).toEqual([]);
|
||||
expect(changes.epg_match_ignore_custom).toEqual([]);
|
||||
});
|
||||
|
||||
it('should keep series_rules as array and not stringify', () => {
|
||||
const rules = [{ tvg_id: 'abc', mode: 'all', title: 'Show' }];
|
||||
const values = { series_rules: rules };
|
||||
const settings = {};
|
||||
|
||||
const changes = SettingsUtils.getChangedSettings(values, settings);
|
||||
expect(changes.series_rules).toEqual(rules);
|
||||
});
|
||||
|
||||
it('should default series_rules to empty array if not an array', () => {
|
||||
const values = { series_rules: 'corrupted' };
|
||||
const settings = {};
|
||||
|
||||
const changes = SettingsUtils.getChangedSettings(values, settings);
|
||||
expect(changes.series_rules).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('saveChangedSettings - EPG Mode', () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue