diff --git a/functions/background/test/index.test.js b/functions/background/test/index.test.js index 2ac797cfaa..c71f4f4841 100644 --- a/functions/background/test/index.test.js +++ b/functions/background/test/index.test.js @@ -67,23 +67,25 @@ it('should make a promise request', async () => { assert.ok(response.body.includes(`Example Domain`)); }); -it('should return synchronously', () => { - assert.strictEqual( - program.helloSynchronous({ - something: true, - }), - 'Something is true!' - ); -}); - -it('should throw an error', () => { - assert.throws( - () => { +describe('functions_background_synchronous', () => { + it('should return synchronously', () => { + assert.strictEqual( program.helloSynchronous({ - something: false, - }); - }, - Error, - 'Something was not true!' - ); + something: true, + }), + 'Something is true!' + ); + }); + + it('should throw an error', () => { + assert.throws( + () => { + program.helloSynchronous({ + something: false, + }); + }, + Error, + 'Something was not true!' + ); + }); }); diff --git a/functions/billing/test/index.test.js b/functions/billing/test/index.test.js index f78a39dccb..18a428aa22 100644 --- a/functions/billing/test/index.test.js +++ b/functions/billing/test/index.test.js @@ -69,23 +69,28 @@ describe('functions/billing tests', () => { await handleLinuxFailures(ffProc); }); - it('should notify Slack when budget is exceeded', async () => { - const jsonData = {costAmount: 500, budgetAmount: 400}; - const encodedData = Buffer.from(JSON.stringify(jsonData)).toString( - 'base64' - ); - const pubsubMessage = {data: encodedData, attributes: {}}; - - const response = await requestRetry({ - url: `${BASE_URL}/notifySlack`, - method: 'POST', - body: {data: pubsubMessage}, - retryDelay: 200, - json: true, + describe('functions_billing_slack', () => { + it('should notify Slack when budget is exceeded', async () => { + const jsonData = {costAmount: 500, budgetAmount: 400}; + const encodedData = Buffer.from(JSON.stringify(jsonData)).toString( + 'base64' + ); + const pubsubMessage = {data: encodedData, attributes: {}}; + + const response = await requestRetry({ + url: `${BASE_URL}/notifySlack`, + method: 'POST', + body: {data: pubsubMessage}, + retryDelay: 200, + json: true, + }); + + assert.strictEqual(response.statusCode, 200); + assert.strictEqual( + response.body, + 'Slack notification sent successfully' + ); }); - - assert.strictEqual(response.statusCode, 200); - assert.strictEqual(response.body, 'Slack notification sent successfully'); }); }); @@ -105,60 +110,64 @@ describe('functions/billing tests', () => { await handleLinuxFailures(ffProc); }); - it('should disable billing when budget is exceeded', async () => { - // Use functions framework to ensure sample follows GCF specification - // (Invoking it directly works too, but DOES NOT ensure GCF compatibility) + describe('functions_billing_stop', () => { + it('should disable billing when budget is exceeded', async () => { + // Use functions framework to ensure sample follows GCF specification + // (Invoking it directly works too, but DOES NOT ensure GCF compatibility) + const jsonData = {costAmount: 500, budgetAmount: 400}; + const encodedData = Buffer.from(JSON.stringify(jsonData)).toString( + 'base64' + ); + const pubsubMessage = {data: encodedData, attributes: {}}; + + const response = await requestRetry({ + url: `${BASE_URL}/stopBilling`, + method: 'POST', + body: {data: pubsubMessage}, + retryDelay: 200, + json: true, + }); + + assert.strictEqual(response.statusCode, 200); + assert.ok(response.body.includes('Billing disabled')); + }); + }); + }); +}); + +describe('shuts down GCE instances', () => { + describe('functions_billing_limit', () => { + it('should attempt to shut down GCE instances when budget is exceeded', async () => { + // Mock GCE (because real GCE instances take too long to start/stop) + const listInstancesResponseMock = { + data: { + items: [{name: 'test-instance-1', status: 'RUNNING'}], + }, + }; + + const computeMock = { + instances: { + list: sinon.stub().returns(listInstancesResponseMock), + stop: sinon.stub().resolves({data: {}}), + }, + }; + + const googleapisMock = Object.assign({}, googleapis); + googleapisMock.google.compute = sinon.stub().returns(computeMock); + + // Run test const jsonData = {costAmount: 500, budgetAmount: 400}; const encodedData = Buffer.from(JSON.stringify(jsonData)).toString( 'base64' ); const pubsubMessage = {data: encodedData, attributes: {}}; - const response = await requestRetry({ - url: `${BASE_URL}/stopBilling`, - method: 'POST', - body: {data: pubsubMessage}, - retryDelay: 200, - json: true, - }); + const sample = proxyquire('../', {googleapis: googleapisMock}); // kokoro-allow-mock - assert.strictEqual(response.statusCode, 200); - assert.ok(response.body.includes('Billing disabled')); - }); - }); -}); + await sample.limitUse(pubsubMessage); -describe('shuts down GCE instances', () => { - it('should attempt to shut down GCE instances when budget is exceeded', async () => { - // Mock GCE (because real GCE instances take too long to start/stop) - const listInstancesResponseMock = { - data: { - items: [{name: 'test-instance-1', status: 'RUNNING'}], - }, - }; - - const computeMock = { - instances: { - list: sinon.stub().returns(listInstancesResponseMock), - stop: sinon.stub().resolves({data: {}}), - }, - }; - - const googleapisMock = Object.assign({}, googleapis); - googleapisMock.google.compute = sinon.stub().returns(computeMock); - - // Run test - const jsonData = {costAmount: 500, budgetAmount: 400}; - const encodedData = Buffer.from(JSON.stringify(jsonData)).toString( - 'base64' - ); - const pubsubMessage = {data: encodedData, attributes: {}}; - - const sample = proxyquire('../', {googleapis: googleapisMock}); // kokoro-allow-mock - - await sample.limitUse(pubsubMessage); - - assert.strictEqual(computeMock.instances.list.calledOnce, true); - assert.ok(computeMock.instances.stop.calledOnce); + assert.strictEqual(computeMock.instances.list.calledOnce, true); + assert.ok(computeMock.instances.stop.calledOnce); + }); }); }); diff --git a/functions/billing/test/periodic.test.js b/functions/billing/test/periodic.test.js index 2a9f0b2f2b..8b139103d5 100644 --- a/functions/billing/test/periodic.test.js +++ b/functions/billing/test/periodic.test.js @@ -54,30 +54,34 @@ before(async () => { } }); -it('should shut down GCE instances when budget is exceeded', async () => { - const ffProc = execPromise( - `functions-framework --target=limitUse --signature-type=event`, - {timeout: 1000, shell: true, cwd} - ); +describe('functions_billing_limit', () => { + it('should shut down GCE instances when budget is exceeded', async () => { + const ffProc = execPromise( + `functions-framework --target=limitUse --signature-type=event`, + {timeout: 1000, shell: true, cwd} + ); - const jsonData = {costAmount: 500, budgetAmount: 400}; - const encodedData = Buffer.from(JSON.stringify(jsonData)).toString('base64'); - const pubsubMessage = {data: encodedData, attributes: {}}; + const jsonData = {costAmount: 500, budgetAmount: 400}; + const encodedData = Buffer.from(JSON.stringify(jsonData)).toString( + 'base64' + ); + const pubsubMessage = {data: encodedData, attributes: {}}; - const response = await requestRetry({ - url: `${BASE_URL}/`, - method: 'POST', - body: {data: pubsubMessage}, - retryDelay: 200, - json: true, - }); + const response = await requestRetry({ + url: `${BASE_URL}/`, + method: 'POST', + body: {data: pubsubMessage}, + retryDelay: 200, + json: true, + }); - // Wait for the functions framework to stop - // Must be BEFORE assertions, in case they fail - await ffProc; + // Wait for the functions framework to stop + // Must be BEFORE assertions, in case they fail + await ffProc; - console.log(response.body); + console.log(response.body); - assert.strictEqual(response.statusCode, 200); - assert.ok(response.body.includes('instance(s) stopped successfully')); + assert.strictEqual(response.statusCode, 200); + assert.ok(response.body.includes('instance(s) stopped successfully')); + }); }); diff --git a/functions/composer-storage-trigger/test/index.test.js b/functions/composer-storage-trigger/test/index.test.js index caea21f9d8..dc229d97b6 100644 --- a/functions/composer-storage-trigger/test/index.test.js +++ b/functions/composer-storage-trigger/test/index.test.js @@ -30,62 +30,64 @@ const getSample = FetchStub => { }; }; -it('Handles error in JSON body', async () => { - const event = { - data: { - file: 'some-file', - }, - }; - const expectedMsg = 'Something bad happened.'; - const bodyJson = {error: expectedMsg}; - const body = { - json: sinon.stub().returns(bodyJson), - }; - const sample = getSample(sinon.stub().resolves(body)); +describe('composer_trigger', () => { + it('Handles error in JSON body', async () => { + const event = { + data: { + file: 'some-file', + }, + }; + const expectedMsg = 'Something bad happened.'; + const bodyJson = {error: expectedMsg}; + const body = { + json: sinon.stub().returns(bodyJson), + }; + const sample = getSample(sinon.stub().resolves(body)); - try { - await sample.program.triggerDag(event); - assert.fail('No error thrown'); - } catch (err) { - assert.deepStrictEqual(err, new Error('Something bad happened.')); - } -}); + try { + await sample.program.triggerDag(event); + assert.fail('No error thrown'); + } catch (err) { + assert.deepStrictEqual(err, new Error('Something bad happened.')); + } + }); -it('Handles error in IAP response.', async () => { - const event = { - data: { - file: 'some-file', - }, - }; - const expectedMsg = 'Default IAP Error Message.'; + it('Handles error in IAP response.', async () => { + const event = { + data: { + file: 'some-file', + }, + }; + const expectedMsg = 'Default IAP Error Message.'; - const serviceAccountAccessTokenRes = { - json: sinon.stub().resolves({access_token: 'default-access-token'}), - }; - const signJsonClaimRes = { - json: sinon.stub().resolves({signature: 'default-jwt-signature'}), - }; - const getTokenRes = { - json: sinon.stub().resolves({id_token: 'default-id-token'}), - }; - const makeIapPostRequestRes = { - ok: false, - text: sinon.stub().resolves(expectedMsg), - }; - const FetchStub = sinon - .stub() - .onCall(0) - .resolves(serviceAccountAccessTokenRes) - .onCall(1) - .resolves(signJsonClaimRes) - .onCall(2) - .resolves(getTokenRes) - .onCall(3) - .resolves(makeIapPostRequestRes); - const sample = getSample(FetchStub); - try { - await sample.program.triggerDag(event); - } catch (err) { - assert.deepStrictEqual(err, new Error(expectedMsg)); - } + const serviceAccountAccessTokenRes = { + json: sinon.stub().resolves({access_token: 'default-access-token'}), + }; + const signJsonClaimRes = { + json: sinon.stub().resolves({signature: 'default-jwt-signature'}), + }; + const getTokenRes = { + json: sinon.stub().resolves({id_token: 'default-id-token'}), + }; + const makeIapPostRequestRes = { + ok: false, + text: sinon.stub().resolves(expectedMsg), + }; + const FetchStub = sinon + .stub() + .onCall(0) + .resolves(serviceAccountAccessTokenRes) + .onCall(1) + .resolves(signJsonClaimRes) + .onCall(2) + .resolves(getTokenRes) + .onCall(3) + .resolves(makeIapPostRequestRes); + const sample = getSample(FetchStub); + try { + await sample.program.triggerDag(event); + } catch (err) { + assert.deepStrictEqual(err, new Error(expectedMsg)); + } + }); }); diff --git a/functions/concepts/test/index.test.js b/functions/concepts/test/index.test.js index 13b709463a..8e573c2eb1 100644 --- a/functions/concepts/test/index.test.js +++ b/functions/concepts/test/index.test.js @@ -24,12 +24,14 @@ const sample = require('../'); beforeEach(tools.stubConsole); afterEach(tools.restoreConsole); -it('should demonstrate error type behavior', () => { - const objError = new Error('Error object!'); +describe('functions_concepts_error_object', () => { + it('should demonstrate error type behavior', () => { + const objError = new Error('Error object!'); - const req = {body: {throwAsString: true}}; - const res = {end: sinon.stub()}; + const req = {body: {throwAsString: true}}; + const res = {end: sinon.stub()}; - sample.errorTypes(req, res); - assert.deepStrictEqual(console.error.getCall(0).args, [objError]); + sample.errorTypes(req, res); + assert.deepStrictEqual(console.error.getCall(0).args, [objError]); + }); }); diff --git a/functions/env_vars/test/index.test.js b/functions/env_vars/test/index.test.js index 5e95102f52..4ff71e8c21 100644 --- a/functions/env_vars/test/index.test.js +++ b/functions/env_vars/test/index.test.js @@ -31,11 +31,13 @@ const getMocks = () => { }; }; -it('should read env vars', () => { - const mocks = getMocks(); - process.env['FOO'] = 'bar'; +describe('functions_env_vars', () => { + it('should read env vars', () => { + const mocks = getMocks(); + process.env['FOO'] = 'bar'; - functions.envVar(mocks.req, mocks.res); + functions.envVar(mocks.req, mocks.res); - assert.strictEqual(mocks.res.send.calledWith('bar'), true); + assert.strictEqual(mocks.res.send.calledWith('bar'), true); + }); }); diff --git a/functions/firebase/test/index.test.js b/functions/firebase/test/index.test.js index fa3b84b524..9d377eeea1 100644 --- a/functions/firebase/test/index.test.js +++ b/functions/firebase/test/index.test.js @@ -39,148 +39,158 @@ const getSample = () => { beforeEach(tools.stubConsole); afterEach(tools.restoreConsole); -it('should listen to RTDB', () => { - const sample = getSample(); - - const delta = { - foo: 'bar', - }; - const event = { - resource: 'resource', - auth: { - admin: true, - }, - delta: delta, - params: { - baz: 'quux', - }, - }; - - sample.program.helloRTDB(event); - - assert.strictEqual(console.log.calledWith(' baz: quux'), true); - assert.strictEqual( - console.log.calledWith('Function triggered by change to: resource'), - true - ); - assert.strictEqual(console.log.calledWith('Admin?: true'), true); - assert.strictEqual( - console.log.calledWith(JSON.stringify(delta, null, 2)), - true - ); +describe('functions_firebase_rtdb', () => { + it('should listen to RTDB', () => { + const sample = getSample(); + + const delta = { + foo: 'bar', + }; + const event = { + resource: 'resource', + auth: { + admin: true, + }, + delta: delta, + params: { + baz: 'quux', + }, + }; + + sample.program.helloRTDB(event); + + assert.strictEqual(console.log.calledWith(' baz: quux'), true); + assert.strictEqual( + console.log.calledWith('Function triggered by change to: resource'), + true + ); + assert.strictEqual(console.log.calledWith('Admin?: true'), true); + assert.strictEqual( + console.log.calledWith(JSON.stringify(delta, null, 2)), + true + ); + }); }); -it('should listen to Firestore', () => { - const sample = getSample(); - - const oldValue = { - foo: 'bar', - }; - const value = { - bar: 'baz', - }; - const event = { - resource: 'resource', - eventType: 'type', - data: { - oldValue: oldValue, - value: value, - }, - }; - - sample.program.helloFirestore(event); - - assert.strictEqual( - console.log.calledWith('Function triggered by event on: resource'), - true - ); - assert.strictEqual(console.log.calledWith('Event type: type'), true); - assert.strictEqual( - console.log.calledWith(JSON.stringify(oldValue, null, 2)), - true - ); - assert.strictEqual( - console.log.calledWith(JSON.stringify(value, null, 2)), - true - ); +describe('functions_firebase_firestore', () => { + it('should listen to Firestore', () => { + const sample = getSample(); + + const oldValue = { + foo: 'bar', + }; + const value = { + bar: 'baz', + }; + const event = { + resource: 'resource', + eventType: 'type', + data: { + oldValue: oldValue, + value: value, + }, + }; + + sample.program.helloFirestore(event); + + assert.strictEqual( + console.log.calledWith('Function triggered by event on: resource'), + true + ); + assert.strictEqual(console.log.calledWith('Event type: type'), true); + assert.strictEqual( + console.log.calledWith(JSON.stringify(oldValue, null, 2)), + true + ); + assert.strictEqual( + console.log.calledWith(JSON.stringify(value, null, 2)), + true + ); + }); }); -it('should listen to Auth events', () => { - const sample = getSample(); - const date = Date.now(); - const event = { - resource: 'resource', - data: { - uid: 'me', - email: 'me@example.com', - metadata: { - createdAt: date, +describe('functions_firebase_auth', () => { + it('should listen to Auth events', () => { + const sample = getSample(); + const date = Date.now(); + const event = { + resource: 'resource', + data: { + uid: 'me', + email: 'me@example.com', + metadata: { + createdAt: date, + }, }, - }, - }; + }; - sample.program.helloAuth(event); + sample.program.helloAuth(event); - assert.strictEqual( - console.log.calledWith('Function triggered by change to user: me'), - true - ); - assert.strictEqual(console.log.calledWith(`Created at: ${date}`), true); - assert.strictEqual(console.log.calledWith('Email: me@example.com'), true); + assert.strictEqual( + console.log.calledWith('Function triggered by change to user: me'), + true + ); + assert.strictEqual(console.log.calledWith(`Created at: ${date}`), true); + assert.strictEqual(console.log.calledWith('Email: me@example.com'), true); + }); }); -it('should listen to Analytics events', () => { - const date = new Date(); - const event = { - data: { - eventDim: [ - { - name: 'my-event', - timestampMicros: `${date.valueOf()}000`, - }, - ], - userDim: { - deviceInfo: { - deviceModel: 'Pixel', - }, - geoInfo: { - city: 'London', - country: 'UK', +describe('functions_firebase_analytics', () => { + it('should listen to Analytics events', () => { + const date = new Date(); + const event = { + data: { + eventDim: [ + { + name: 'my-event', + timestampMicros: `${date.valueOf()}000`, + }, + ], + userDim: { + deviceInfo: { + deviceModel: 'Pixel', + }, + geoInfo: { + city: 'London', + country: 'UK', + }, }, }, - }, - resource: 'my-resource', - }; - - const sample = getSample(); - sample.program.helloAnalytics(event); - assert.strictEqual( - console.log.args[0][0], - 'Function triggered by the following event: my-resource' - ); - assert.strictEqual(console.log.args[1][0], 'Name: my-event'); - assert.strictEqual(console.log.args[2][0], `Timestamp: ${date}`); - assert.strictEqual(console.log.args[3][0], 'Device Model: Pixel'); - assert.strictEqual(console.log.args[4][0], 'Location: London, UK'); + resource: 'my-resource', + }; + + const sample = getSample(); + sample.program.helloAnalytics(event); + assert.strictEqual( + console.log.args[0][0], + 'Function triggered by the following event: my-resource' + ); + assert.strictEqual(console.log.args[1][0], 'Name: my-event'); + assert.strictEqual(console.log.args[2][0], `Timestamp: ${date}`); + assert.strictEqual(console.log.args[3][0], 'Device Model: Pixel'); + assert.strictEqual(console.log.args[4][0], 'Location: London, UK'); + }); }); -it('should listen to Remote Config events', () => { - const sample = getSample(); +describe('functions_firebase_remote_config', () => { + it('should listen to Remote Config events', () => { + const sample = getSample(); - const event = { - data: { - updateOrigin: 'CONSOLE', - updateType: 'INCREMENTAL_UPDATE', - versionNumber: '1', - }, - }; + const event = { + data: { + updateOrigin: 'CONSOLE', + updateType: 'INCREMENTAL_UPDATE', + versionNumber: '1', + }, + }; - sample.program.helloRemoteConfig(event); + sample.program.helloRemoteConfig(event); - assert.strictEqual( - console.log.calledWith('Update type: INCREMENTAL_UPDATE'), - true - ); - assert.strictEqual(console.log.calledWith('Origin: CONSOLE'), true); - assert.strictEqual(console.log.calledWith('Version: 1'), true); + assert.strictEqual( + console.log.calledWith('Update type: INCREMENTAL_UPDATE'), + true + ); + assert.strictEqual(console.log.calledWith('Origin: CONSOLE'), true); + assert.strictEqual(console.log.calledWith('Version: 1'), true); + }); }); diff --git a/functions/helloworld/test/index.test.js b/functions/helloworld/test/index.test.js index 3388a2119f..8de212c7d8 100644 --- a/functions/helloworld/test/index.test.js +++ b/functions/helloworld/test/index.test.js @@ -69,7 +69,7 @@ const httpInvocation = (fnUrl, port, body) => { describe('index.test.js', () => { before(tools.checkCredentials); - describe('helloGET', () => { + describe('functions_helloworld_get helloGET', () => { const PORT = 8081; let ffProc; @@ -89,7 +89,7 @@ describe('index.test.js', () => { }); }); - describe('helloHttp', () => { + describe('functions_helloworld_http helloHttp', () => { const PORT = 8082; let ffProc; @@ -132,7 +132,7 @@ describe('index.test.js', () => { }); }); - describe('helloBackground', () => { + describe('functions_helloworld_background helloBackground', () => { const PORT = 8083; let ffProc; @@ -161,15 +161,15 @@ describe('index.test.js', () => { }); }); - describe('helloPubSub', () => { + describe('functions_helloworld_pubsub helloPubSub', () => { /* See sample.integration.pubsub.test.js */ }); - describe('helloGCS', () => { + describe('functions_helloworld_storage helloGCS', () => { /* See sample.integration.storage.test.js */ }); - describe('helloGCSGeneric', () => { + describe('functions_helloworld_storage_generic helloGCSGeneric', () => { it('helloGCSGeneric: should print event details', async () => { const PORT = 8084; const ffProc = startFF('helloGCSGeneric', 'event', PORT); @@ -202,30 +202,32 @@ describe('index.test.js', () => { }); }); - describe('Error handling (unit tests)', () => { - // Silence dummy console calls in the samples - before(tools.stubConsole); - after(tools.restoreConsole); + describe('functions_helloworld_error', () => { + describe('Error handling (unit tests)', () => { + // Silence dummy console calls in the samples + before(tools.stubConsole); + after(tools.restoreConsole); - it('helloError: should throw an error', () => { - assert.throws(program.helloError, 'I failed you'); - }); + it('helloError: should throw an error', () => { + assert.throws(program.helloError, 'I failed you'); + }); - it('helloError2: should throw a value', () => { - assert.throws(program.helloError2, '1'); - }); + it('helloError2: should throw a value', () => { + assert.throws(program.helloError2, '1'); + }); - it('helloError3: callback should return an errback value', () => { - const cb = sinon.stub(); + it('helloError3: callback should return an errback value', () => { + const cb = sinon.stub(); - program.helloError3(null, null, cb); + program.helloError3(null, null, cb); - assert.ok(cb.calledOnce); - assert.ok(cb.calledWith('I failed you')); + assert.ok(cb.calledOnce); + assert.ok(cb.calledWith('I failed you')); + }); }); }); - describe('helloTemplate', () => { + describe('functions_helloworld_template helloTemplate', () => { const PORT = 8085; let ffProc; diff --git a/functions/helloworld/test/sample.integration.http.test.js b/functions/helloworld/test/sample.integration.http.test.js index e46e313d82..3354d4a0b7 100644 --- a/functions/helloworld/test/sample.integration.http.test.js +++ b/functions/helloworld/test/sample.integration.http.test.js @@ -26,7 +26,7 @@ const cwd = path.join(__dirname, '..'); // [END functions_http_integration_test] -describe('HTTP integration test', () => { +describe('functions_helloworld_http HTTP integration test', () => { // [START functions_http_integration_test] let ffProc; diff --git a/functions/helloworld/test/sample.integration.pubsub.test.js b/functions/helloworld/test/sample.integration.pubsub.test.js index 06e2ab5f7d..1c056f60b6 100644 --- a/functions/helloworld/test/sample.integration.pubsub.test.js +++ b/functions/helloworld/test/sample.integration.pubsub.test.js @@ -24,7 +24,7 @@ const cwd = path.join(__dirname, '..'); // [END functions_pubsub_integration_test] -describe('Pub/Sub integration test', () => { +describe('functions_helloworld_pubsub integration test', () => { // [START functions_pubsub_integration_test] it('helloPubSub: should print a name', async () => { const name = uuid.v4(); diff --git a/functions/helloworld/test/sample.integration.storage.test.js b/functions/helloworld/test/sample.integration.storage.test.js index ea9c5f671e..b381178cf2 100644 --- a/functions/helloworld/test/sample.integration.storage.test.js +++ b/functions/helloworld/test/sample.integration.storage.test.js @@ -24,7 +24,7 @@ const cwd = path.join(__dirname, '..'); // [END functions_storage_integration_test] -describe('GCS integration test', () => { +describe('functions_helloworld_storage integration test', () => { // [START functions_storage_integration_test] it('helloGCS: should print uploaded message', async () => { const filename = uuid.v4(); // Use a unique filename to avoid conflicts diff --git a/functions/helloworld/test/sample.unit.http.test.js b/functions/helloworld/test/sample.unit.http.test.js index 1c423bfd8c..3abdc75584 100644 --- a/functions/helloworld/test/sample.unit.http.test.js +++ b/functions/helloworld/test/sample.unit.http.test.js @@ -13,45 +13,47 @@ * limitations under the License. */ -// [START functions_http_unit_test] -const assert = require('assert'); -const sinon = require('sinon'); -const uuid = require('uuid'); - -const {helloHttp} = require('..'); - -it('helloHttp: should print a name', () => { - // Mock ExpressJS 'req' and 'res' parameters - const name = uuid.v4(); - const req = { - query: {}, - body: { - name: name, - }, - }; - const res = {send: sinon.stub()}; - - // Call tested function - helloHttp(req, res); - - // Verify behavior of tested function - assert.ok(res.send.calledOnce); - assert.deepStrictEqual(res.send.firstCall.args, [`Hello ${name}!`]); -}); -// [END functions_http_unit_test] - -it('helloHttp: should print hello world', () => { - // Mock ExpressJS 'req' and 'res' parameters - const req = { - query: {}, - body: {}, - }; - const res = {send: sinon.stub()}; - - // Call tested function - helloHttp(req, res); - - // Verify behavior of tested function - assert.ok(res.send.calledOnce); - assert.deepStrictEqual(res.send.firstCall.args, ['Hello World!']); +describe('functions_helloworld_http', () => { + // [START functions_http_unit_test] + const assert = require('assert'); + const sinon = require('sinon'); + const uuid = require('uuid'); + + const {helloHttp} = require('..'); + + it('helloHttp: should print a name', () => { + // Mock ExpressJS 'req' and 'res' parameters + const name = uuid.v4(); + const req = { + query: {}, + body: { + name: name, + }, + }; + const res = {send: sinon.stub()}; + + // Call tested function + helloHttp(req, res); + + // Verify behavior of tested function + assert.ok(res.send.calledOnce); + assert.deepStrictEqual(res.send.firstCall.args, [`Hello ${name}!`]); + }); + // [END functions_http_unit_test] + + it('helloHttp: should print hello world', () => { + // Mock ExpressJS 'req' and 'res' parameters + const req = { + query: {}, + body: {}, + }; + const res = {send: sinon.stub()}; + + // Call tested function + helloHttp(req, res); + + // Verify behavior of tested function + assert.ok(res.send.calledOnce); + assert.deepStrictEqual(res.send.firstCall.args, ['Hello World!']); + }); }); diff --git a/functions/helloworld/test/sample.unit.pubsub.test.js b/functions/helloworld/test/sample.unit.pubsub.test.js index 6b38d6245c..7264ab8f9e 100644 --- a/functions/helloworld/test/sample.unit.pubsub.test.js +++ b/functions/helloworld/test/sample.unit.pubsub.test.js @@ -13,34 +13,36 @@ * limitations under the License. */ -// [START functions_pubsub_unit_test] -const assert = require('assert'); -const uuid = require('uuid'); -const utils = require('@google-cloud/nodejs-repo-tools'); +describe('functions_helloworld_pubsub', () => { + // [START functions_pubsub_unit_test] + const assert = require('assert'); + const uuid = require('uuid'); + const utils = require('@google-cloud/nodejs-repo-tools'); -const {helloPubSub} = require('..'); + const {helloPubSub} = require('..'); -beforeEach(utils.stubConsole); -afterEach(utils.restoreConsole); + beforeEach(utils.stubConsole); + afterEach(utils.restoreConsole); -it('helloPubSub: should print a name', () => { - // Create mock Pub/Sub event - const name = uuid.v4(); - const event = { - data: Buffer.from(name).toString('base64'), - }; + it('helloPubSub: should print a name', () => { + // Create mock Pub/Sub event + const name = uuid.v4(); + const event = { + data: Buffer.from(name).toString('base64'), + }; - // Call tested function and verify its behavior - helloPubSub(event); - assert.ok(console.log.calledWith(`Hello, ${name}!`)); -}); -// [END functions_pubsub_unit_test] + // Call tested function and verify its behavior + helloPubSub(event); + assert.ok(console.log.calledWith(`Hello, ${name}!`)); + }); + // [END functions_pubsub_unit_test] -it('helloPubSub: should print hello world', () => { - // Create mock Pub/Sub event - const event = {}; + it('helloPubSub: should print hello world', () => { + // Create mock Pub/Sub event + const event = {}; - // Call tested function and verify its behavior - helloPubSub(event); - assert.ok(console.log.calledWith('Hello, World!')); + // Call tested function and verify its behavior + helloPubSub(event); + assert.ok(console.log.calledWith('Hello, World!')); + }); }); diff --git a/functions/helloworld/test/sample.unit.storage.test.js b/functions/helloworld/test/sample.unit.storage.test.js index c48871076b..fd7c78ec5e 100644 --- a/functions/helloworld/test/sample.unit.storage.test.js +++ b/functions/helloworld/test/sample.unit.storage.test.js @@ -13,55 +13,57 @@ * limitations under the License. */ -// [START functions_storage_unit_test] -const assert = require('assert'); -const uuid = require('uuid'); -const utils = require('@google-cloud/nodejs-repo-tools'); +describe('functions_helloworld_storage', () => { + // [START functions_storage_unit_test] + const assert = require('assert'); + const uuid = require('uuid'); + const utils = require('@google-cloud/nodejs-repo-tools'); -const {helloGCS} = require('..'); + const {helloGCS} = require('..'); -beforeEach(utils.stubConsole); -afterEach(utils.restoreConsole); + beforeEach(utils.stubConsole); + afterEach(utils.restoreConsole); -it('helloGCS: should print uploaded message', () => { - // Initialize mocks - const filename = uuid.v4(); - const event = { - name: filename, - resourceState: 'exists', - metageneration: '1', - }; + it('helloGCS: should print uploaded message', () => { + // Initialize mocks + const filename = uuid.v4(); + const event = { + name: filename, + resourceState: 'exists', + metageneration: '1', + }; - // Call tested function and verify its behavior - helloGCS(event); - assert.ok(console.log.calledWith(`File ${filename} uploaded.`)); -}); -// [END functions_storage_unit_test] + // Call tested function and verify its behavior + helloGCS(event); + assert.ok(console.log.calledWith(`File ${filename} uploaded.`)); + }); + // [END functions_storage_unit_test] -it('helloGCS: should print metadata updated message', () => { - // Initialize mocks - const filename = uuid.v4(); - const event = { - name: filename, - resourceState: 'exists', - metageneration: '2', - }; + it('helloGCS: should print metadata updated message', () => { + // Initialize mocks + const filename = uuid.v4(); + const event = { + name: filename, + resourceState: 'exists', + metageneration: '2', + }; - // Call tested function and verify its behavior - helloGCS(event); - assert.ok(console.log.calledWith(`File ${filename} metadata updated.`)); -}); + // Call tested function and verify its behavior + helloGCS(event); + assert.ok(console.log.calledWith(`File ${filename} metadata updated.`)); + }); -it('helloGCS: should print deleted message', () => { - // Initialize mocks - const filename = uuid.v4(); - const event = { - name: filename, - resourceState: 'not_exists', - metageneration: '3', - }; + it('helloGCS: should print deleted message', () => { + // Initialize mocks + const filename = uuid.v4(); + const event = { + name: filename, + resourceState: 'not_exists', + metageneration: '3', + }; - // Call tested function and verify its behavior - helloGCS(event); - assert.ok(console.log.calledWith(`File ${filename} deleted.`)); + // Call tested function and verify its behavior + helloGCS(event); + assert.ok(console.log.calledWith(`File ${filename} deleted.`)); + }); }); diff --git a/functions/http/test/index.test.js b/functions/http/test/index.test.js index e1cc240a81..33908e00e2 100644 --- a/functions/http/test/index.test.js +++ b/functions/http/test/index.test.js @@ -70,180 +70,191 @@ const getMocks = () => { beforeEach(tools.stubConsole); afterEach(tools.restoreConsole); -it('http:helloHttp: should handle GET', () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.method = 'GET'; - httpSample.sample.helloHttp(mocks.req, mocks.res); - - assert.strictEqual(mocks.res.status.calledOnce, true); - assert.strictEqual(mocks.res.status.firstCall.args[0], 200); - assert.strictEqual(mocks.res.send.calledOnce, true); - assert.strictEqual(mocks.res.send.firstCall.args[0], 'Hello World!'); -}); +describe('functions_http_method', () => { + it('http:helloHttp: should handle GET', () => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.method = 'GET'; + httpSample.sample.helloHttp(mocks.req, mocks.res); + + assert.strictEqual(mocks.res.status.calledOnce, true); + assert.strictEqual(mocks.res.status.firstCall.args[0], 200); + assert.strictEqual(mocks.res.send.calledOnce, true); + assert.strictEqual(mocks.res.send.firstCall.args[0], 'Hello World!'); + }); -it('http:helloHttp: should handle PUT', () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.method = 'PUT'; - httpSample.sample.helloHttp(mocks.req, mocks.res); + it('http:helloHttp: should handle PUT', () => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.method = 'PUT'; + httpSample.sample.helloHttp(mocks.req, mocks.res); - assert.strictEqual(mocks.res.status.calledOnce, true); - assert.strictEqual(mocks.res.status.firstCall.args[0], 403); - assert.strictEqual(mocks.res.send.calledOnce, true); - assert.strictEqual(mocks.res.send.firstCall.args[0], 'Forbidden!'); -}); + assert.strictEqual(mocks.res.status.calledOnce, true); + assert.strictEqual(mocks.res.status.firstCall.args[0], 403); + assert.strictEqual(mocks.res.send.calledOnce, true); + assert.strictEqual(mocks.res.send.firstCall.args[0], 'Forbidden!'); + }); -it('http:helloHttp: should handle other methods', () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.method = 'POST'; - httpSample.sample.helloHttp(mocks.req, mocks.res); - - assert.strictEqual(mocks.res.status.calledOnce, true); - assert.strictEqual(mocks.res.status.firstCall.args[0], 405); - assert.strictEqual(mocks.res.send.calledOnce, true); - assert.deepStrictEqual(mocks.res.send.firstCall.args[0], { - error: 'Something blew up!', + it('http:helloHttp: should handle other methods', () => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.method = 'POST'; + httpSample.sample.helloHttp(mocks.req, mocks.res); + + assert.strictEqual(mocks.res.status.calledOnce, true); + assert.strictEqual(mocks.res.status.firstCall.args[0], 405); + assert.strictEqual(mocks.res.send.calledOnce, true); + assert.deepStrictEqual(mocks.res.send.firstCall.args[0], { + error: 'Something blew up!', + }); }); }); -it('http:helloContent: should handle application/json', () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.headers['content-type'] = 'application/json'; - mocks.req.body = {name: 'John'}; - httpSample.sample.helloContent(mocks.req, mocks.res); - - assert.strictEqual(mocks.res.status.calledOnce, true); - assert.strictEqual(mocks.res.status.firstCall.args[0], 200); - assert.strictEqual(mocks.res.send.calledOnce, true); - assert.strictEqual(mocks.res.send.firstCall.args[0], 'Hello John!'); -}); +describe('functions_http_content', () => { + it('http:helloContent: should handle application/json', () => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.headers['content-type'] = 'application/json'; + mocks.req.body = {name: 'John'}; + httpSample.sample.helloContent(mocks.req, mocks.res); + + assert.strictEqual(mocks.res.status.calledOnce, true); + assert.strictEqual(mocks.res.status.firstCall.args[0], 200); + assert.strictEqual(mocks.res.send.calledOnce, true); + assert.strictEqual(mocks.res.send.firstCall.args[0], 'Hello John!'); + }); -it('http:helloContent: should handle application/octet-stream', () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.headers['content-type'] = 'application/octet-stream'; - mocks.req.body = Buffer.from('John'); - httpSample.sample.helloContent(mocks.req, mocks.res); - - assert.strictEqual(mocks.res.status.calledOnce, true); - assert.strictEqual(mocks.res.status.firstCall.args[0], 200); - assert.strictEqual(mocks.res.send.calledOnce, true); - assert.strictEqual(mocks.res.send.firstCall.args[0], 'Hello John!'); -}); + it('http:helloContent: should handle application/octet-stream', () => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.headers['content-type'] = 'application/octet-stream'; + mocks.req.body = Buffer.from('John'); + httpSample.sample.helloContent(mocks.req, mocks.res); + + assert.strictEqual(mocks.res.status.calledOnce, true); + assert.strictEqual(mocks.res.status.firstCall.args[0], 200); + assert.strictEqual(mocks.res.send.calledOnce, true); + assert.strictEqual(mocks.res.send.firstCall.args[0], 'Hello John!'); + }); -it('http:helloContent: should handle text/plain', () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.headers['content-type'] = 'text/plain'; - mocks.req.body = 'John'; - httpSample.sample.helloContent(mocks.req, mocks.res); - - assert.strictEqual(mocks.res.status.calledOnce, true); - assert.strictEqual(mocks.res.status.firstCall.args[0], 200); - assert.strictEqual(mocks.res.send.calledOnce, true); - assert.strictEqual(mocks.res.send.firstCall.args[0], 'Hello John!'); -}); + it('http:helloContent: should handle text/plain', () => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.headers['content-type'] = 'text/plain'; + mocks.req.body = 'John'; + httpSample.sample.helloContent(mocks.req, mocks.res); + + assert.strictEqual(mocks.res.status.calledOnce, true); + assert.strictEqual(mocks.res.status.firstCall.args[0], 200); + assert.strictEqual(mocks.res.send.calledOnce, true); + assert.strictEqual(mocks.res.send.firstCall.args[0], 'Hello John!'); + }); -it('http:helloContent: should handle application/x-www-form-urlencoded', () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.headers['content-type'] = 'application/x-www-form-urlencoded'; - mocks.req.body = {name: 'John'}; - httpSample.sample.helloContent(mocks.req, mocks.res); - - assert.strictEqual(mocks.res.status.calledOnce, true); - assert.strictEqual(mocks.res.status.firstCall.args[0], 200); - assert.strictEqual(mocks.res.send.calledOnce, true); - assert.strictEqual(mocks.res.send.firstCall.args[0], 'Hello John!'); -}); + it('http:helloContent: should handle application/x-www-form-urlencoded', () => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.headers['content-type'] = 'application/x-www-form-urlencoded'; + mocks.req.body = {name: 'John'}; + httpSample.sample.helloContent(mocks.req, mocks.res); + + assert.strictEqual(mocks.res.status.calledOnce, true); + assert.strictEqual(mocks.res.status.firstCall.args[0], 200); + assert.strictEqual(mocks.res.send.calledOnce, true); + assert.strictEqual(mocks.res.send.firstCall.args[0], 'Hello John!'); + }); -it('http:helloContent: should handle other', () => { - const mocks = getMocks(); - const httpSample = getSample(); - httpSample.sample.helloContent(mocks.req, mocks.res); + it('http:helloContent: should handle other', () => { + const mocks = getMocks(); + const httpSample = getSample(); + httpSample.sample.helloContent(mocks.req, mocks.res); - assert.strictEqual(mocks.res.status.calledOnce, true); - assert.strictEqual(mocks.res.status.firstCall.args[0], 200); - assert.strictEqual(mocks.res.send.calledOnce, true); - assert.strictEqual(mocks.res.send.firstCall.args[0], 'Hello World!'); -}); + assert.strictEqual(mocks.res.status.calledOnce, true); + assert.strictEqual(mocks.res.status.firstCall.args[0], 200); + assert.strictEqual(mocks.res.send.calledOnce, true); + assert.strictEqual(mocks.res.send.firstCall.args[0], 'Hello World!'); + }); -it('http:helloContent: should escape XSS', () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.headers['content-type'] = 'text/plain'; - mocks.req.body = {name: ''}; - httpSample.sample.helloContent(mocks.req, mocks.res); - - assert.strictEqual(mocks.res.status.calledOnce, true); - assert.strictEqual(mocks.res.status.firstCall.args[0], 200); - assert.strictEqual(mocks.res.send.calledOnce, true); - assert.strictEqual( - mocks.res.send.firstCall.args[0].includes(''}; + httpSample.sample.helloContent(mocks.req, mocks.res); + + assert.strictEqual(mocks.res.status.calledOnce, true); + assert.strictEqual(mocks.res.status.firstCall.args[0], 200); + assert.strictEqual(mocks.res.send.calledOnce, true); + assert.strictEqual( + mocks.res.send.firstCall.args[0].includes('