Skip to content

Commit 22f550e

Browse files
authored
allow fully qualified topic and bucket names (#62)
1 parent 9b5e27e commit 22f550e

File tree

4 files changed

+93
-11
lines changed

4 files changed

+93
-11
lines changed

src/builders/pubsub-builder.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,21 @@ export default class PubsubBuilder extends FunctionBuilder {
4545
}
4646

4747
protected _toTrigger(event: string): TriggerDefinition {
48+
const format = new RegExp('^(projects/([^/]+)/topics/)?([^/]+)$');
49+
let match = this.topic.match(format);
50+
if (!match) {
51+
const errorString = 'Topic names must either have the format of'
52+
+ ' "topicId" or "projects/<projectId>/topics/<topicId>".';
53+
throw new Error(errorString);
54+
}
55+
let [,,project, topic] = match;
56+
if (project && project !== process.env.GCLOUD_PROJECT) {
57+
throw new Error('Cannot use a topic that does not belong to this project.');
58+
}
4859
return {
4960
eventTrigger: {
5061
eventType: 'providers/cloud.pubsub/eventTypes/' + event,
51-
resource: 'projects/' + process.env.GCLOUD_PROJECT + '/topics/' + this.topic,
62+
resource: 'projects/' + process.env.GCLOUD_PROJECT + '/topics/' + topic,
5263
},
5364
};
5465
}

src/builders/storage-builder.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,21 @@ export default class CloudStorageBuilder extends FunctionBuilder {
7373
}
7474

7575
protected _toTrigger(event: string): TriggerDefinition {
76+
let bucket;
77+
if (this.bucket) {
78+
const format = new RegExp('^(projects/_/buckets/)?([^/]+)$');
79+
let match = this.bucket.match(format);
80+
if (!match) {
81+
const errorString = 'bucket names must either have the format of'
82+
+ ' "bucketId" or "projects/_/buckets/<bucketId>".';
83+
throw new Error(errorString);
84+
}
85+
bucket = match[2];
86+
}
7687
return {
7788
eventTrigger: {
7889
eventType: 'providers/cloud.storage/eventTypes/' + event,
79-
resource: this.bucket? 'projects/' + process.env.GCLOUD_PROJECT + '/buckets/' + this.bucket: null,
90+
resource: this.bucket? 'projects/_/buckets/' + bucket: null,
8091
},
8192
};
8293
}

test/builders/pubsub-builder.spec.ts

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,28 +41,61 @@ describe('PubsubMessage', () => {
4141
describe('CloudPubsubBuilder', () => {
4242
let subject: CloudPubsubBuilder;
4343
let env: FakeEnv;
44+
let handler: (any) => any;
4445

4546
beforeEach(() => {
4647
env = new FakeEnv();
4748
subject = new CloudPubsubBuilder(env, 'toppy');
49+
handler = (data: Object) => {
50+
return true;
51+
};
52+
process.env.GCLOUD_PROJECT = 'project1';
53+
});
54+
55+
afterEach(() => {
56+
delete process.env.GCLOUD_PROJECT;
4857
});
4958

5059
describe('#onPublish', () => {
51-
it('should return a CloudPubsubTriggerDefinition with appropriate values', () => {
52-
let handler = (data: Object) => {
53-
return true;
54-
};
60+
it('should return a TriggerDefinition with appropriate values', () => {
5561
let result = subject.onPublish(handler);
5662
expect(result.__trigger).to.deep.equal({
5763
eventTrigger: {
5864
eventType: 'providers/cloud.pubsub/eventTypes/topic.publish',
59-
resource: 'projects/undefined/topics/toppy',
65+
resource: 'projects/project1/topics/toppy',
6066
},
6167
});
6268
});
6369

70+
it ('should allow fully qualified topic names', () => {
71+
let subjectQualified = new CloudPubsubBuilder(env, 'projects/project1/topics/toppy');
72+
let result = subjectQualified.onPublish(handler);
73+
expect(result.__trigger).to.deep.equal({
74+
eventTrigger: {
75+
eventType: 'providers/cloud.pubsub/eventTypes/topic.publish',
76+
resource: 'projects/project1/topics/toppy',
77+
},
78+
});
79+
});
80+
81+
it ('should throw with improperly formatted topics', () => {
82+
let func = () => {
83+
let badSubject = new CloudPubsubBuilder(env, 'bad/topic/format');
84+
return badSubject.onPublish(handler);
85+
};
86+
expect(func).to.throw(Error);
87+
});
88+
89+
it ('should throw with when using topic in another project', () => {
90+
let func = () => {
91+
let badSubject = new CloudPubsubBuilder(env, 'projects/anotherProject/topics/toppy');
92+
return badSubject.onPublish(handler);
93+
};
94+
expect(func).to.throw(Error);
95+
});
96+
6497
it('should properly handle a new-style event', () => {
65-
let handler = (ev: Event<PubsubMessage>) => {
98+
let handler2 = (ev: Event<PubsubMessage>) => {
6699
return {
67100
raw: ev.data.data,
68101
json: ev.data.json,
@@ -78,7 +111,7 @@ describe('CloudPubsubBuilder', () => {
78111
},
79112
},
80113
};
81-
let result = subject.onPublish(handler);
114+
let result = subject.onPublish(handler2);
82115
env.makeReady();
83116
return expect(result(event)).to.eventually.deep.equal({
84117
raw,

test/builders/storage-builder.spec.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,41 @@ describe('CloudHttpBuilder', () => {
1818
});
1919

2020
describe('#onChange', () => {
21-
it('should return a CloudStorageTriggerDefinition with appropriate values', () => {
21+
it('should return a TriggerDefinition with appropriate values', () => {
2222
let result = subject.onChange(handler);
2323
expect(result.__trigger).to.deep.equal({
2424
eventTrigger: {
2525
eventType: 'providers/cloud.storage/eventTypes/object.change',
26-
resource: 'projects/undefined/buckets/bucky',
26+
resource: 'projects/_/buckets/bucky',
2727
},
2828
});
2929
});
30+
31+
it ('should allow fully qualified bucket names', () => {
32+
let subjectQualified = new CloudStorageBuilder(env, 'projects/_/buckets/bucky');
33+
let result = subjectQualified.onChange(handler);
34+
expect(result.__trigger).to.deep.equal({
35+
eventTrigger: {
36+
eventType: 'providers/cloud.storage/eventTypes/object.change',
37+
resource: 'projects/_/buckets/bucky',
38+
},
39+
});
40+
});
41+
42+
it ('should throw with improperly formatted buckets', () => {
43+
let func = () => {
44+
let badSubject = new CloudStorageBuilder(env, 'bad/bucket/format');
45+
return badSubject.onChange(handler);
46+
};
47+
expect(func).to.throw(Error);
48+
});
49+
50+
it ('should throw with when using bucket not in _ project', () => {
51+
let func = () => {
52+
let badSubject = new CloudStorageBuilder(env, 'projects/anotherProject/buckets/bucky');
53+
return badSubject.onChange(handler);
54+
};
55+
expect(func).to.throw(Error);
56+
});
3057
});
3158
});

0 commit comments

Comments
 (0)