Skip to content

Commit

Permalink
Merge branch 'master' of github.com:FirebasePrivate/firebase-functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Lauren Long committed Feb 6, 2020
2 parents d9fc8a6 + 9df27f4 commit ff852c5
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 80 deletions.
106 changes: 72 additions & 34 deletions spec/providers/pubsub.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,45 +311,83 @@ describe('Pubsub Functions', () => {

describe('handler namespace', () => {
describe('#onPublish', () => {
it('should return an empty trigger', () => {
const result = functions.handler.pubsub.topic.onPublish(() => null);
expect(result.__trigger).to.deep.equal({});
});
describe('#topic', () => {
it('should return an empty trigger', () => {
const result = functions.handler.pubsub.topic.onPublish(() => null);
expect(result.__trigger).to.deep.equal({});
});

it('should properly handle a new-style event', () => {
const raw = new Buffer('{"hello":"world"}', 'utf8').toString('base64');
const event = {
data: {
data: raw,
attributes: {
foo: 'bar',
it('should properly handle a new-style event', () => {
const raw = new Buffer('{"hello":"world"}', 'utf8').toString(
'base64'
);
const event = {
data: {
data: raw,
attributes: {
foo: 'bar',
},
},
},
context: {
eventId: '70172329041928',
timestamp: '2018-04-09T07:56:12.975Z',
eventType: 'google.pubsub.topic.publish',
resource: {
service: 'pubsub.googleapis.com',
name: 'projects/project1/topics/toppy',
context: {
eventId: '70172329041928',
timestamp: '2018-04-09T07:56:12.975Z',
eventType: 'google.pubsub.topic.publish',
resource: {
service: 'pubsub.googleapis.com',
name: 'projects/project1/topics/toppy',
},
},
},
};

const result = functions.handler.pubsub.topic.onPublish((data) => {
return {
raw: data.data,
json: data.json,
attributes: data.attributes,
};
});

return expect(
result(event.data, event.context)
).to.eventually.deep.equal({
raw,
json: { hello: 'world' },
attributes: { foo: 'bar' },
const result = functions.handler.pubsub.topic.onPublish((data) => {
return {
raw: data.data,
json: data.json,
attributes: data.attributes,
};
});

return expect(
result(event.data, event.context)
).to.eventually.deep.equal({
raw,
json: { hello: 'world' },
attributes: { foo: 'bar' },
});
});
});
describe('#schedule', () => {
it('should return an empty trigger', () => {
const result = functions.handler.pubsub.schedule.onRun(() => null);
expect(result.__trigger).to.deep.equal({});
});
it('should return a handler with a proper event context', () => {
const raw = new Buffer('{"hello":"world"}', 'utf8').toString(
'base64'
);
const event = {
data: {
data: raw,
attributes: {
foo: 'bar',
},
},
context: {
eventId: '70172329041928',
timestamp: '2018-04-09T07:56:12.975Z',
eventType: 'google.pubsub.topic.publish',
resource: {
service: 'pubsub.googleapis.com',
name: 'projects/project1/topics/toppy',
},
},
};
const result = functions.handler.pubsub.schedule.onRun(
(context) => context.eventId
);
return expect(result(event.data, event.context)).to.eventually.equal(
'70172329041928'
);
});
});
});
Expand Down
6 changes: 6 additions & 0 deletions src/handler-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,12 @@ export class HandlerBuilder {
get topic() {
return new pubsub.TopicBuilder(() => null, {});
},
/**
* Handle periodic events triggered by Cloud Scheduler.
*/
get schedule() {
return new pubsub.ScheduleBuilder(() => null, {});
},
};
}

Expand Down
99 changes: 53 additions & 46 deletions src/providers/pubsub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,52 +63,6 @@ export function _topicWithOptions(
}, options);
}

export function schedule(schedule: string): ScheduleBuilder {
return _scheduleWithOptions(schedule, {});
}

export class ScheduleBuilder {
/** @hidden */
constructor(private options: DeploymentOptions) {}

retryConfig(config: ScheduleRetryConfig): ScheduleBuilder {
this.options.schedule.retryConfig = config;
return this;
}

timeZone(timeZone: string): ScheduleBuilder {
this.options.schedule.timeZone = timeZone;
return this;
}

onRun(handler: (context: EventContext) => PromiseLike<any> | any) {
const triggerResource = () => {
if (!process.env.GCLOUD_PROJECT) {
throw new Error('process.env.GCLOUD_PROJECT is not set.');
}
return `projects/${process.env.GCLOUD_PROJECT}/topics`; // The CLI will append the correct topic name based on region and function name
};
const cloudFunction = makeCloudFunction({
contextOnlyHandler: handler,
provider,
service,
triggerResource,
eventType: 'topic.publish',
options: this.options,
labels: { 'deployment-scheduled': 'true' },
});
return cloudFunction;
}
}

/** @hidden */
export function _scheduleWithOptions(
schedule: string,
options: DeploymentOptions
): ScheduleBuilder {
return new ScheduleBuilder({ ...options, schedule: { schedule } });
}

/**
* The Google Cloud Pub/Sub topic builder.
*
Expand Down Expand Up @@ -144,6 +98,59 @@ export class TopicBuilder {
}
}

export function schedule(schedule: string): ScheduleBuilder {
return _scheduleWithOptions(schedule, {});
}

/** @hidden */
export function _scheduleWithOptions(
schedule: string,
options: DeploymentOptions
): ScheduleBuilder {
const triggerResource = () => {
if (!process.env.GCLOUD_PROJECT) {
throw new Error('process.env.GCLOUD_PROJECT is not set.');
}
// The CLI will append the correct topic name based on region and function name
return `projects/${process.env.GCLOUD_PROJECT}/topics`;
};
return new ScheduleBuilder(triggerResource, {
...options,
schedule: { schedule },
});
}

export class ScheduleBuilder {
/** @hidden */
constructor(
private triggerResource: () => string,
private options: DeploymentOptions
) {}

retryConfig(config: ScheduleRetryConfig): ScheduleBuilder {
this.options.schedule.retryConfig = config;
return this;
}

timeZone(timeZone: string): ScheduleBuilder {
this.options.schedule.timeZone = timeZone;
return this;
}

onRun(handler: (context: EventContext) => PromiseLike<any> | any) {
const cloudFunction = makeCloudFunction({
contextOnlyHandler: handler,
provider,
service,
triggerResource: this.triggerResource,
eventType: 'topic.publish',
options: this.options,
labels: { 'deployment-scheduled': 'true' },
});
return cloudFunction;
}
}

/**
* Interface representing a Google Cloud Pub/Sub message.
*
Expand Down

0 comments on commit ff852c5

Please sign in to comment.