Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/public/static/error-codes.json
Original file line number Diff line number Diff line change
Expand Up @@ -288,5 +288,6 @@
"288": "MUI X: useDisposable failed to detect React StrictMode.\nThe instance was disposed on StrictMode's simulated unmount and is about to be reused while torn down.\nThis is an internal invariant violation — please report it at https://github.com/mui/mui-x/issues.",
"289": "MUI X Chat docs-correctness guard: could not load entry point %s (%s). The export surface cannot be enumerated.",
"290": "MUI X Chat docs-correctness guard: %s has no module symbol (%s); it may be missing exports.",
"291": "MUI X Scheduler: All events must have a unique `id`.\nWithout an `id`, an event cannot be tracked and silently overwrites another event in the calendar state.\nAdd an `id` to every event, or set `eventModelStructure.id.getter` to derive one from your event model.\nAn event was provided without an `id`:\n%s"
"291": "MUI X Scheduler: All events must have a unique `id`.\nWithout an `id`, an event cannot be tracked and silently overwrites another event in the calendar state.\nAdd an `id` to every event, or set `eventModelStructure.id.getter` to derive one from your event model.\nAn event was provided without an `id`:\n%s",
"292": "MUI X Scheduler: Invalid FREQ value \"%s\". The frequency must be one of DAILY, WEEKLY, MONTHLY, or YEARLY. Provide a supported frequency value."
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,20 @@ describe('recurring-events/rRuleString', () => {
);
});

it('should throw when FREQ has an unsupported value', () => {
expect(() => parseRRule(adapter, 'FREQ=HOURLY', 'default')).to.throw(
'MUI X Scheduler: Invalid FREQ value "HOURLY". The frequency must be one of DAILY, WEEKLY, MONTHLY, or YEARLY. Provide a supported frequency value.',
);
});

it('should throw when the object input has an unsupported freq value', () => {
expect(() =>
parseRRule(adapter, { freq: 'HOURLY' as SchedulerEventRecurrenceRule['freq'] }, 'default'),
).to.throw(
'MUI X Scheduler: Invalid FREQ value "HOURLY". The frequency must be one of DAILY, WEEKLY, MONTHLY, or YEARLY. Provide a supported frequency value.',
);
});

it('should throw when the RRULE contains unsupported properties', () => {
expect(() => parseRRule(adapter, 'FREQ=DAILY;FOO=bar', 'default')).to.throw(
'MUI X Scheduler: Unsupported RRULE property "FOO". Supported properties are: FREQ, INTERVAL, BYDAY, BYMONTHDAY, BYMONTH, UNTIL, COUNT. Remove or replace the unsupported property.',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,32 @@ const SUPPORTED_RRULE_KEYS = new Set([
'COUNT',
]);

// Fails to compile if `RecurringEventFrequency` changes, keeping the runtime check in sync with the type.
const SUPPORTED_FREQUENCIES: Record<SchedulerProcessedEventRecurrenceRule['freq'], true> = {
DAILY: true,
WEEKLY: true,
MONTHLY: true,
YEARLY: true,
};

function validateFreq(freq: string): SchedulerProcessedEventRecurrenceRule['freq'] {
if (!Object.prototype.hasOwnProperty.call(SUPPORTED_FREQUENCIES, freq)) {
throw new Error(
`MUI X Scheduler: Invalid FREQ value "${freq}". ` +
'The frequency must be one of DAILY, WEEKLY, MONTHLY, or YEARLY. ' +
'Provide a supported frequency value.',
);
}
return freq as SchedulerProcessedEventRecurrenceRule['freq'];
}

export function parseRRule(
adapter: Adapter,
input: string | SchedulerEventRecurrenceRule,
timezone: TemporalTimezone,
): SchedulerProcessedEventRecurrenceRule {
if (typeof input === 'object') {
validateFreq(input.freq);
if (input.until != null) {
return {
...input,
Expand Down Expand Up @@ -72,7 +92,7 @@ export function parseRRule(
}

const rrule: SchedulerProcessedEventRecurrenceRule = {
freq: rruleObject.FREQ as SchedulerProcessedEventRecurrenceRule['freq'],
freq: validateFreq(rruleObject.FREQ),
};

if (rruleObject.INTERVAL) {
Expand Down
Loading