Skip to content

Commit 4826d2b

Browse files
authored
Refactor tests for start and stop instance events
1 parent 5699b14 commit 4826d2b

1 file changed

Lines changed: 107 additions & 156 deletions

File tree

functions/scheduleinstance/test/index.test.js

Lines changed: 107 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -19,210 +19,161 @@ const proxyquire = require('proxyquire').noCallThru();
1919
const assert = require('assert');
2020

2121
const getSample = () => {
22-
const requestPromise = sinon
23-
.stub()
24-
.returns(new Promise(resolve => resolve('request sent')));
22+
const getProjectIdStub = sinon.stub().resolves('test-project');
23+
const listStub = sinon.stub().resolves([{ items: [{ name: 'test-instance' }] }]);
24+
const patchStub = sinon.stub().resolves([{ name: 'test-operation' }]);
25+
const registeredFunctions = {};
26+
27+
proxyquire('../index', {
28+
'@google-cloud/functions-framework': {
29+
cloudEvent: (name, handler) => {
30+
registeredFunctions[name] = handler;
31+
},
32+
},
33+
'@google-cloud/sql': {
34+
SqlInstancesServiceClient: function () {
35+
this.getProjectId = getProjectIdStub;
36+
this.list = listStub;
37+
this.patch = patchStub;
38+
},
39+
},
40+
});
2541

2642
return {
27-
program: proxyquire('../', {
28-
'@google-cloud/compute': {
29-
InstancesClient: function client() {
30-
this.list = () => new Promise(resolve => resolve([[]]));
31-
this.start = () => new Promise(resolve => resolve('request sent'));
32-
this.getProjectId = () => 'project';
33-
},
34-
ZoneOperationsClient: function client() {
35-
this.wait = () => new Promise(resolve => resolve('request sent'));
36-
},
37-
},
38-
}),
43+
registeredFunctions,
3944
mocks: {
40-
requestPromise: requestPromise,
45+
getProjectIdStub,
46+
listStub,
47+
patchStub,
4148
},
4249
};
4350
};
4451

45-
const getMocks = () => {
46-
const event = {
47-
data: {},
48-
};
49-
50-
const callback = sinon.spy();
51-
52-
return {
53-
event: event,
54-
context: {},
55-
callback: callback,
56-
};
57-
};
52+
const getCloudEvent = (data) => ({
53+
data: {
54+
message: {
55+
data: Buffer.from(JSON.stringify(data)).toString('base64'),
56+
},
57+
},
58+
});
5859

5960
const stubConsole = function () {
6061
sinon.stub(console, 'error');
6162
sinon.stub(console, 'log');
6263
};
6364

64-
//Restore console
6565
const restoreConsole = function () {
6666
console.log.restore();
6767
console.error.restore();
6868
};
69+
6970
beforeEach(stubConsole);
7071
afterEach(restoreConsole);
7172

72-
/** Tests for startInstancePubSub */
73-
describe('functions_start_instance_pubsub', () => {
74-
it('startInstancePubSub: should accept JSON-formatted event payload with label', async () => {
75-
const mocks = getMocks();
73+
describe('functions_start_instance_event', () => {
74+
it('startInstanceEvent: should accept CloudEvent payload with label', async () => {
7675
const sample = getSample();
77-
const pubsubData = {zone: 'test-zone', label: 'testkey=value'};
78-
mocks.event.data = Buffer.from(JSON.stringify(pubsubData)).toString(
79-
'base64'
80-
);
81-
await sample.program.startInstancePubSub(
82-
mocks.event,
83-
mocks.context,
84-
mocks.callback
85-
);
86-
87-
assert.deepStrictEqual(
88-
mocks.callback.firstCall.args[1],
89-
'Successfully started instance(s)'
90-
);
76+
const cloudEvent = getCloudEvent({ label: 'env=dev' });
77+
78+
await sample.registeredFunctions.startInstanceEvent(cloudEvent);
79+
80+
assert.strictEqual(sample.mocks.getProjectIdStub.calledOnce, true);
81+
assert.strictEqual(sample.mocks.listStub.calledOnce, true);
82+
assert.deepStrictEqual(sample.mocks.listStub.firstCall.args[0], {
83+
project: 'test-project',
84+
filter: 'settings.userLabels.env:dev',
85+
});
86+
assert.strictEqual(sample.mocks.patchStub.calledOnce, true);
87+
assert.deepStrictEqual(sample.mocks.patchStub.firstCall.args[0], {
88+
project: 'test-project',
89+
instance: 'test-instance',
90+
body: {
91+
settings: {
92+
activationPolicy: 'ALWAYS',
93+
},
94+
},
95+
});
9196
});
9297

93-
it("startInstancePubSub: should fail with missing 'zone' attribute", async () => {
94-
const mocks = getMocks();
98+
it("startInstanceEvent: should fail with missing 'label' attribute", async () => {
9599
const sample = getSample();
96-
const pubsubData = {label: 'testkey=value'};
97-
mocks.event.data = Buffer.from(JSON.stringify(pubsubData)).toString(
98-
'base64'
99-
);
100-
await sample.program.startInstancePubSub(
101-
mocks.event,
102-
mocks.context,
103-
mocks.callback
104-
);
100+
const cloudEvent = getCloudEvent({ other: 'value' });
105101

106-
assert.deepStrictEqual(
107-
mocks.callback.firstCall.args[0],
108-
new Error("Attribute 'zone' missing from payload")
102+
await assert.rejects(
103+
sample.registeredFunctions.startInstanceEvent(cloudEvent),
104+
/Attribute 'label' missing from payload/
109105
);
110106
});
111107

112-
it("startInstancePubSub: should fail with missing 'label' attribute", async () => {
113-
const mocks = getMocks();
108+
it('startInstanceEvent: should handle zero instances gracefully', async () => {
114109
const sample = getSample();
115-
const pubsubData = {zone: 'test-zone'};
116-
mocks.event.data = Buffer.from(JSON.stringify(pubsubData)).toString(
117-
'base64'
118-
);
119-
await sample.program.startInstancePubSub(
120-
mocks.event,
121-
mocks.context,
122-
mocks.callback
123-
);
110+
sample.mocks.listStub.resolves([{}]); // Empty object missing 'items' property
111+
const cloudEvent = getCloudEvent({ label: 'env=dev' });
124112

125-
assert.deepStrictEqual(
126-
mocks.callback.firstCall.args[0],
127-
new Error("Attribute 'label' missing from payload")
128-
);
113+
await sample.registeredFunctions.startInstanceEvent(cloudEvent);
114+
115+
assert.strictEqual(sample.mocks.patchStub.called, false);
129116
});
130117

131-
it('startInstancePubSub: should fail with empty event payload', async () => {
132-
const mocks = getMocks();
118+
it('startInstanceEvent: should fail with invalid CloudEvent payload', async () => {
133119
const sample = getSample();
134-
const pubsubData = {};
135-
mocks.event.data = Buffer.from(JSON.stringify(pubsubData)).toString(
136-
'base64'
137-
);
138-
await sample.program.startInstancePubSub(
139-
mocks.event,
140-
mocks.context,
141-
mocks.callback
142-
);
120+
const cloudEvent = {
121+
data: {
122+
message: {
123+
data: 'invalid-base64-payload',
124+
},
125+
},
126+
};
143127

144-
assert.deepStrictEqual(
145-
mocks.callback.firstCall.args[0],
146-
new Error("Attribute 'zone' missing from payload")
128+
await assert.rejects(
129+
sample.registeredFunctions.startInstanceEvent(cloudEvent),
130+
/Invalid CloudEvent \/ Pub\/Sub message/
147131
);
148132
});
149133
});
150134

151-
/** Tests for stopInstancePubSub */
152-
describe('functions_stop_instance_pubsub', () => {
153-
it('stopInstancePubSub: should accept JSON-formatted event payload with label', async () => {
154-
const mocks = getMocks();
135+
describe('functions_stop_instance_event', () => {
136+
it('stopInstanceEvent: should accept CloudEvent payload with label', async () => {
155137
const sample = getSample();
156-
const pubsubData = {zone: 'test-zone', label: 'testkey=value'};
157-
mocks.event.data = Buffer.from(JSON.stringify(pubsubData)).toString(
158-
'base64'
159-
);
160-
await sample.program.stopInstancePubSub(
161-
mocks.event,
162-
mocks.context,
163-
mocks.callback
164-
);
165-
166-
assert.deepStrictEqual(
167-
mocks.callback.firstCall.args[1],
168-
'Successfully stopped instance(s)'
169-
);
138+
const cloudEvent = getCloudEvent({ label: 'env=dev' });
139+
140+
await sample.registeredFunctions.stopInstanceEvent(cloudEvent);
141+
142+
assert.strictEqual(sample.mocks.getProjectIdStub.calledOnce, true);
143+
assert.strictEqual(sample.mocks.listStub.calledOnce, true);
144+
assert.deepStrictEqual(sample.mocks.listStub.firstCall.args[0], {
145+
project: 'test-project',
146+
filter: 'settings.userLabels.env:dev',
147+
});
148+
assert.strictEqual(sample.mocks.patchStub.calledOnce, true);
149+
assert.deepStrictEqual(sample.mocks.patchStub.firstCall.args[0], {
150+
project: 'test-project',
151+
instance: 'test-instance',
152+
body: {
153+
settings: {
154+
activationPolicy: 'NEVER',
155+
},
156+
},
157+
});
170158
});
171159

172-
it("stopInstancePubSub: should fail with missing 'zone' attribute", async () => {
173-
const mocks = getMocks();
160+
it("stopInstanceEvent: should fail with missing 'label' attribute", async () => {
174161
const sample = getSample();
175-
const pubsubData = {label: 'testkey=value'};
176-
mocks.event.data = Buffer.from(JSON.stringify(pubsubData)).toString(
177-
'base64'
178-
);
179-
await sample.program.stopInstancePubSub(
180-
mocks.event,
181-
mocks.context,
182-
mocks.callback
183-
);
162+
const cloudEvent = getCloudEvent({ other: 'value' });
184163

185-
assert.deepStrictEqual(
186-
mocks.callback.firstCall.args[0],
187-
new Error("Attribute 'zone' missing from payload")
164+
await assert.rejects(
165+
sample.registeredFunctions.stopInstanceEvent(cloudEvent),
166+
/Attribute 'label' missing from payload/
188167
);
189168
});
190169

191-
it("stopInstancePubSub: should fail with missing 'label' attribute", async () => {
192-
const mocks = getMocks();
170+
it('stopInstanceEvent: should handle zero instances gracefully', async () => {
193171
const sample = getSample();
194-
const pubsubData = {zone: 'test-zone'};
195-
mocks.event.data = Buffer.from(JSON.stringify(pubsubData)).toString(
196-
'base64'
197-
);
198-
await sample.program.stopInstancePubSub(
199-
mocks.event,
200-
mocks.context,
201-
mocks.callback
202-
);
203-
204-
assert.deepStrictEqual(
205-
mocks.callback.firstCall.args[0],
206-
new Error("Attribute 'label' missing from payload")
207-
);
208-
});
172+
sample.mocks.listStub.resolves([{ items: [] }]); // Empty items array
173+
const cloudEvent = getCloudEvent({ label: 'env=dev' });
209174

210-
it('stopInstancePubSub: should fail with empty event payload', async () => {
211-
const mocks = getMocks();
212-
const sample = getSample();
213-
const pubsubData = {};
214-
mocks.event.data = Buffer.from(JSON.stringify(pubsubData)).toString(
215-
'base64'
216-
);
217-
await sample.program.stopInstancePubSub(
218-
mocks.event,
219-
mocks.context,
220-
mocks.callback
221-
);
175+
await sample.registeredFunctions.stopInstanceEvent(cloudEvent);
222176

223-
assert.deepStrictEqual(
224-
mocks.callback.firstCall.args[0],
225-
new Error("Attribute 'zone' missing from payload")
226-
);
177+
assert.strictEqual(sample.mocks.patchStub.called, false);
227178
});
228179
});

0 commit comments

Comments
 (0)