Skip to content

Commit

Permalink
add logic to allow ISO 8601 duration strings
Browse files Browse the repository at this point in the history
  • Loading branch information
hmalik88 committed Dec 24, 2024
1 parent 3e615f5 commit 1e54f3c
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,54 @@ describe('snap_scheduleBackgroundEvent', () => {
});
});

it('schedules a background event using duration', async () => {
const { implementation } = scheduleBackgroundEventHandler;

const scheduleBackgroundEvent = jest.fn();
const hasPermission = jest.fn().mockImplementation(() => true);

const hooks = {
scheduleBackgroundEvent,
hasPermission,
};

const engine = new JsonRpcEngine();

engine.push(createOriginMiddleware(MOCK_SNAP_ID));
engine.push((request, response, next, end) => {
const result = implementation(
request as JsonRpcRequest<ScheduleBackgroundEventParams>,
response as PendingJsonRpcResponse<ScheduleBackgroundEventResult>,
next,
end,
hooks,
);

result?.catch(end);
});

await engine.handle({
jsonrpc: '2.0',
id: 1,
method: 'snap_scheduleBackgroundEvent',
params: {
date: 'PT30S',
request: {
method: 'handleExport',
params: ['p1'],
},
},
});

expect(scheduleBackgroundEvent).toHaveBeenCalledWith({
date: expect.any(String),
request: {
method: 'handleExport',
params: ['p1'],
},
});
});

it('throws if a snap does not have the "endowment:cronjob" permission', async () => {
const { implementation } = scheduleBackgroundEventHandler;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
string,
} from '@metamask/superstruct';
import { assert, type PendingJsonRpcResponse } from '@metamask/utils';
import { DateTime } from 'luxon';
import { DateTime, Duration } from 'luxon';

import { SnapEndowments } from '../endowments';
import type { MethodHooksObject } from '../utils';
Expand Down Expand Up @@ -58,12 +58,15 @@ const offsetRegex = /Z|([+-]\d{2}:?\d{2})$/u;
const ScheduleBackgroundEventsParametersStruct = object({
date: refine(string(), 'date', (val) => {
const date = DateTime.fromISO(val);
const duration = Duration.fromISO(val);
if (date.isValid) {
// Luxon doesn't have a reliable way to check if timezone info was not provided
if (!offsetRegex.test(val)) {
return 'ISO 8601 string must have timezone information';
}
return true;
} else if (duration.isValid) {
return true;
}
return 'Not a valid ISO 8601 string';
}),
Expand Down Expand Up @@ -109,12 +112,22 @@ async function getScheduleBackgroundEventImplementation(

const { date, request } = validatedParams;

let truncatedDate;

const duration = Duration.fromISO(date);

// We have to check if the string is a duration or not
if (duration.isValid) {
truncatedDate = DateTime.fromJSDate(new Date()).toUTC().plus(duration);
} else {
truncatedDate = DateTime.fromISO(date, { setZone: true });
}

// Make sure any millisecond precision is removed.
const truncatedDate = DateTime.fromISO(date, { setZone: true })
.startOf('second')
.toISO({
suppressMilliseconds: true,
});

truncatedDate = truncatedDate.startOf('second').toISO({
suppressMilliseconds: true,
});

assert(truncatedDate);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import type { Cronjob } from '../permissions';
/**
* The request parameters for the `snap_scheduleBackgroundEvent` method.
*
* @property date - The ISO8601 date of when to fire the background event.
* Note: The date generated from a duration will be represented in UTC.
*
* @property date - The ISO 8601 date/duration of when to fire the background event.
* @property request - The request to be called when the event fires.
*/
export type ScheduleBackgroundEventParams = {
Expand Down

0 comments on commit 1e54f3c

Please sign in to comment.