From 5013dfc6431f786dcdbf4c904ff05fa2260fea6d Mon Sep 17 00:00:00 2001 From: Ivan Hernandez Date: Sat, 8 Mar 2025 13:40:58 +0000 Subject: [PATCH 1/4] feat(bigquery): Add samples for control access 3/3 --- .../test/viewDatasetAccessPolicy.test.js | 35 ++++++++ .../test/viewTableOrViewAccessPolicy.test.js | 90 +++++++++++++++++++ .../cloud-client/viewDatasetAccessPolicy.js | 59 ++++++++++++ .../viewTableOrViewAccessPolicy.js | 68 ++++++++++++++ 4 files changed, 252 insertions(+) create mode 100644 bigquery/cloud-client/test/viewDatasetAccessPolicy.test.js create mode 100644 bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js create mode 100644 bigquery/cloud-client/viewDatasetAccessPolicy.js create mode 100644 bigquery/cloud-client/viewTableOrViewAccessPolicy.js diff --git a/bigquery/cloud-client/test/viewDatasetAccessPolicy.test.js b/bigquery/cloud-client/test/viewDatasetAccessPolicy.test.js new file mode 100644 index 0000000000..725e0763fd --- /dev/null +++ b/bigquery/cloud-client/test/viewDatasetAccessPolicy.test.js @@ -0,0 +1,35 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +const assert = require('assert'); +const {getDataset, setupBeforeAll, teardownAfterAll} = require('./config'); +const {viewDatasetAccessPolicy} = require('../viewDatasetAccessPolicy'); + +describe('viewDatasetAccessPolicy', () => { + before(async () => { + await setupBeforeAll(); + }); + + after(async () => { + await teardownAfterAll(); + }); + + it('should view dataset access policies', async () => { + const dataset = await getDataset(); + const accessPolicy = await viewDatasetAccessPolicy(dataset.id); + + assert.ok(accessPolicy, 'Access policy should be defined'); + assert.ok(Array.isArray(accessPolicy), 'Access policy should be an array'); + }); +}); diff --git a/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js b/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js new file mode 100644 index 0000000000..df50ad6c39 --- /dev/null +++ b/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js @@ -0,0 +1,90 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +const assert = require('assert'); +const { + getProjectId, + getDataset, + getTable, + getView, + setupBeforeAll, + teardownAfterAll, +} = require('./config.js'); +const viewTableOrViewAccessPolicy = require('../viewTableOrViewAccessPolicy.js'); + +describe('viewTableOrViewAccessPolicy', () => { + before(async () => { + await setupBeforeAll(); + }); + + after(async () => { + await teardownAfterAll(); + }); + + it('should view table access policies', async () => { + const projectId = await getProjectId(); + const dataset = await getDataset(); + const table = await getTable(); + + const policy = await viewTableOrViewAccessPolicy( + projectId, + dataset.id, + table.id + ); + + // Verify that the policy exists. + assert.ok(policy, 'Policy should be defined'); + + // Verify that bindings exists and is an array. + assert.ok(Array.isArray(policy.bindings), 'Bindings should be an array'); + + // In a new policy, bindings should be empty. + assert.strictEqual( + policy.bindings.length, + 0, + 'Bindings list should be empty' + ); + + // Verify that etag exists, but do not validate its exact value. + assert.ok(policy.etag, 'Etag should be defined'); + }); + + it('should view view access policies', async () => { + const projectId = await getProjectId(); + const dataset = await getDataset(); + const view = await getView(); + + const policy = await viewTableOrViewAccessPolicy( + projectId, + dataset.id, + view.id + ); + + // Verify that the policy exists. + assert.ok(policy, 'Policy should be defined'); + + // Verify that bindings exists and is an array. + assert.ok(Array.isArray(policy.bindings), 'Bindings should be an array'); + + // In a new policy, bindings should be empty. + assert.strictEqual( + policy.bindings.length, + 0, + 'Bindings list should be empty' + ); + + // Verify that etag exists, but do not validate its exact value. + assert.ok(policy.etag, 'Etag should be defined'); + }); +}); diff --git a/bigquery/cloud-client/viewDatasetAccessPolicy.js b/bigquery/cloud-client/viewDatasetAccessPolicy.js new file mode 100644 index 0000000000..6400e78f55 --- /dev/null +++ b/bigquery/cloud-client/viewDatasetAccessPolicy.js @@ -0,0 +1,59 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +/** + * View access policies for a BigQuery dataset. + * @param {string} datasetId Dataset ID to view access policies for. + * @returns {Array} Array of access entries. + */ +function viewDatasetAccessPolicy(datasetId) { + // [START bigquery_view_dataset_access_policy] + const {BigQuery} = require('@google-cloud/bigquery'); + + // Instantiate a client. + const bigquery = new BigQuery(); + + // TODO (developer): Update and un-comment below lines. + + // Dataset from which to get the access policy. + // datasetId = "my_dataset_id"; + + // Get a reference to the dataset. + const dataset = bigquery.dataset(datasetId); + + return dataset.getMetadata().then(([metadata]) => { + const accessEntries = metadata.access || []; + + // Show the array of AccessEntry objects. + // More details about the AccessEntry object in the BigQuery documentation: + // https://cloud.google.com/nodejs/docs/reference/bigquery/latest + console.log( + `${accessEntries.length} Access entries in dataset '${datasetId}':` + ); + for (const accessEntry of accessEntries) { + console.log(`Role: ${accessEntry.role || 'null'}`); + console.log(`Special group: ${accessEntry.specialGroup || 'null'}`); + console.log(`User by Email: ${accessEntry.userByEmail || 'null'}`); + } + + return accessEntries; + }); + // [END bigquery_view_dataset_access_policy] +} + +module.exports = { + viewDatasetAccessPolicy, +}; diff --git a/bigquery/cloud-client/viewTableOrViewAccessPolicy.js b/bigquery/cloud-client/viewTableOrViewAccessPolicy.js new file mode 100644 index 0000000000..e6cc0a75bc --- /dev/null +++ b/bigquery/cloud-client/viewTableOrViewAccessPolicy.js @@ -0,0 +1,68 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +/** + * View access policy for a BigQuery table or view. + * + * @param {string} projectId Google Cloud Platform project. + * @param {string} datasetId Dataset where the table or view is. + * @param {string} resourceName Table or view name to get the access policy. + * @returns {Promise} The IAM policy object. + */ +async function viewTableOrViewAccessPolicy(projectId, datasetId, resourceName) { + // [START bigquery_view_table_or_view_access_policy] + const {BigQuery} = require('@google-cloud/bigquery'); + + // TODO(developer): Update and un-comment below lines. + + // Google Cloud Platform project. + // projectId = "my_project_id"; + + // Dataset where the table or view is. + // datasetId = "my_dataset_id"; + + // Table or view name to get the access policy. + // resourceName = "my_table_name_id"; + + // Instantiate a client. + const client = new BigQuery(); + + // Get a reference to the dataset by datasetId. + const dataset = client.dataset(datasetId); + // Get a reference to the table by tableName. + const table = dataset.table(resourceName); + + // Get the IAM access policy for the table or view. + const [policy] = await table.getIamPolicy(); + + // Initialize bindings array. + if (!policy.bindings) { + policy.bindings = []; + } + + // Show policy details + // Find more details for the Policy object here: + // https://cloud.google.com/bigquery/docs/reference/rest/v2/Policy + console.log(`Access Policy details for table or view '${resourceName}'.`); + console.log(`Bindings: ${JSON.stringify(policy.bindings, null, 2)}`); + console.log(`etag: ${policy.etag}`); + console.log(`Version: ${policy.version}`); + + // [END bigquery_view_table_or_view_access_policy] + return policy; +} + +module.exports = viewTableOrViewAccessPolicy; From 250ed791b03e0a791fd35f239f25525a33ef1d07 Mon Sep 17 00:00:00 2001 From: Ivan Hernandez Date: Fri, 14 Mar 2025 23:08:07 +0000 Subject: [PATCH 2/4] chore(bigquery): testing, stylistic update --- .../test/viewDatasetAccessPolicy.test.js | 53 ++++++-- .../test/viewTableOrViewAccessPolicy.test.js | 117 ++++++++++-------- .../cloud-client/viewDatasetAccessPolicy.js | 35 +++--- .../viewTableOrViewAccessPolicy.js | 70 +++++------ 4 files changed, 151 insertions(+), 124 deletions(-) diff --git a/bigquery/cloud-client/test/viewDatasetAccessPolicy.test.js b/bigquery/cloud-client/test/viewDatasetAccessPolicy.test.js index 725e0763fd..be96227ccf 100644 --- a/bigquery/cloud-client/test/viewDatasetAccessPolicy.test.js +++ b/bigquery/cloud-client/test/viewDatasetAccessPolicy.test.js @@ -12,24 +12,59 @@ // See the License for the specific language governing permissions and // limitations under the License. +'use strict'; + +const {beforeEach, afterEach, it, describe} = require('mocha'); const assert = require('assert'); -const {getDataset, setupBeforeAll, teardownAfterAll} = require('./config'); +const sinon = require('sinon'); + +const {setupBeforeAll, cleanupResources} = require('./config'); const {viewDatasetAccessPolicy} = require('../viewDatasetAccessPolicy'); describe('viewDatasetAccessPolicy', () => { - before(async () => { - await setupBeforeAll(); + let datasetId = null; + + beforeEach(async () => { + const response = await setupBeforeAll(); + datasetId = response.datasetId; + + sinon.stub(console, 'log'); + sinon.stub(console, 'error'); }); - after(async () => { - await teardownAfterAll(); + afterEach(async () => { + await cleanupResources(datasetId); + console.log.restore(); + console.error.restore(); }); it('should view dataset access policies', async () => { - const dataset = await getDataset(); - const accessPolicy = await viewDatasetAccessPolicy(dataset.id); + // Act: View the dataset access policy + await viewDatasetAccessPolicy(datasetId); + + // Assert: Check that the initial message was logged + assert.strictEqual( + console.log.calledWith( + sinon.match(`Access entries in dataset '${datasetId}':`) + ), + true + ); + + // We're not checking the exact number of entries since that might vary, + // but we're making sure the appropriate logging format was followed + assert.ok( + console.log.calledWith(sinon.match(/Role:/)), + 'Should log role information' + ); + + assert.ok( + console.log.calledWith(sinon.match(/Special group:/)), + 'Should log special group information' + ); - assert.ok(accessPolicy, 'Access policy should be defined'); - assert.ok(Array.isArray(accessPolicy), 'Access policy should be an array'); + assert.ok( + console.log.calledWith(sinon.match(/User by Email:/)), + 'Should log user by email information' + ); }); }); diff --git a/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js b/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js index df50ad6c39..99811f2e5b 100644 --- a/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js +++ b/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js @@ -12,79 +12,90 @@ // See the License for the specific language governing permissions and // limitations under the License. +'use strict'; + +const {describe, it, beforeEach, afterEach} = require('mocha'); const assert = require('assert'); -const { - getProjectId, - getDataset, - getTable, - getView, - setupBeforeAll, - teardownAfterAll, -} = require('./config.js'); -const viewTableOrViewAccessPolicy = require('../viewTableOrViewAccessPolicy.js'); +const sinon = require('sinon'); + +const {setupBeforeAll, cleanupResources} = require('./config'); +const {viewTableOrViewAccessPolicy} = require('../viewTableOrViewAccessPolicy'); describe('viewTableOrViewAccessPolicy', () => { - before(async () => { - await setupBeforeAll(); + let datasetId = null; + let tableId = null; + let viewId = null; + const projectId = process.env.GCLOUD_PROJECT; + + beforeEach(async () => { + const response = await setupBeforeAll(); + datasetId = response.datasetId; + tableId = response.tableId; + viewId = response.viewId; + + sinon.stub(console, 'log'); + sinon.stub(console, 'error'); }); - after(async () => { - await teardownAfterAll(); + afterEach(async () => { + await cleanupResources(datasetId); + console.log.restore(); + console.error.restore(); }); it('should view table access policies', async () => { - const projectId = await getProjectId(); - const dataset = await getDataset(); - const table = await getTable(); - - const policy = await viewTableOrViewAccessPolicy( - projectId, - dataset.id, - table.id - ); + // View the table access policy + await viewTableOrViewAccessPolicy(projectId, datasetId, tableId); - // Verify that the policy exists. - assert.ok(policy, 'Policy should be defined'); + // Check that the right messages were logged + assert.strictEqual( + console.log.calledWith( + `Access Policy details for table or view '${tableId}'.` + ), + true + ); - // Verify that bindings exists and is an array. - assert.ok(Array.isArray(policy.bindings), 'Bindings should be an array'); + assert.ok( + console.log.calledWith(sinon.match('Bindings:')), + 'Should log bindings information' + ); - // In a new policy, bindings should be empty. - assert.strictEqual( - policy.bindings.length, - 0, - 'Bindings list should be empty' + assert.ok( + console.log.calledWith(sinon.match('etag:')), + 'Should log etag information' ); - // Verify that etag exists, but do not validate its exact value. - assert.ok(policy.etag, 'Etag should be defined'); + assert.ok( + console.log.calledWith(sinon.match('Version:')), + 'Should log version information' + ); }); it('should view view access policies', async () => { - const projectId = await getProjectId(); - const dataset = await getDataset(); - const view = await getView(); - - const policy = await viewTableOrViewAccessPolicy( - projectId, - dataset.id, - view.id - ); + // View the view access policy + await viewTableOrViewAccessPolicy(projectId, datasetId, viewId); - // Verify that the policy exists. - assert.ok(policy, 'Policy should be defined'); + // Check that the right messages were logged + assert.strictEqual( + console.log.calledWith( + `Access Policy details for table or view '${viewId}'.` + ), + true + ); - // Verify that bindings exists and is an array. - assert.ok(Array.isArray(policy.bindings), 'Bindings should be an array'); + assert.ok( + console.log.calledWith(sinon.match('Bindings:')), + 'Should log bindings information' + ); - // In a new policy, bindings should be empty. - assert.strictEqual( - policy.bindings.length, - 0, - 'Bindings list should be empty' + assert.ok( + console.log.calledWith(sinon.match('etag:')), + 'Should log etag information' ); - // Verify that etag exists, but do not validate its exact value. - assert.ok(policy.etag, 'Etag should be defined'); + assert.ok( + console.log.calledWith(sinon.match('Version:')), + 'Should log version information' + ); }); }); diff --git a/bigquery/cloud-client/viewDatasetAccessPolicy.js b/bigquery/cloud-client/viewDatasetAccessPolicy.js index 6400e78f55..2f8d412f8e 100644 --- a/bigquery/cloud-client/viewDatasetAccessPolicy.js +++ b/bigquery/cloud-client/viewDatasetAccessPolicy.js @@ -14,30 +14,26 @@ 'use strict'; -/** - * View access policies for a BigQuery dataset. - * @param {string} datasetId Dataset ID to view access policies for. - * @returns {Array} Array of access entries. - */ -function viewDatasetAccessPolicy(datasetId) { +async function main(datasetId) { // [START bigquery_view_dataset_access_policy] + + /** + * TODO(developer): Update and un-comment below lines + */ + // const datasetId = "my_project_id.my_dataset"; + const {BigQuery} = require('@google-cloud/bigquery'); // Instantiate a client. const bigquery = new BigQuery(); - // TODO (developer): Update and un-comment below lines. - - // Dataset from which to get the access policy. - // datasetId = "my_dataset_id"; + async function viewDatasetAccessPolicy() { + const dataset = bigquery.dataset(datasetId); - // Get a reference to the dataset. - const dataset = bigquery.dataset(datasetId); - - return dataset.getMetadata().then(([metadata]) => { + const [metadata] = await dataset.getMetadata(); const accessEntries = metadata.access || []; - // Show the array of AccessEntry objects. + // Show the list of AccessEntry objects. // More details about the AccessEntry object in the BigQuery documentation: // https://cloud.google.com/nodejs/docs/reference/bigquery/latest console.log( @@ -48,12 +44,9 @@ function viewDatasetAccessPolicy(datasetId) { console.log(`Special group: ${accessEntry.specialGroup || 'null'}`); console.log(`User by Email: ${accessEntry.userByEmail || 'null'}`); } - - return accessEntries; - }); + } // [END bigquery_view_dataset_access_policy] + await viewDatasetAccessPolicy(); } -module.exports = { - viewDatasetAccessPolicy, -}; +exports.viewDatasetAccessPolicy = main; diff --git a/bigquery/cloud-client/viewTableOrViewAccessPolicy.js b/bigquery/cloud-client/viewTableOrViewAccessPolicy.js index e6cc0a75bc..d876f27af2 100644 --- a/bigquery/cloud-client/viewTableOrViewAccessPolicy.js +++ b/bigquery/cloud-client/viewTableOrViewAccessPolicy.js @@ -14,55 +14,43 @@ 'use strict'; -/** - * View access policy for a BigQuery table or view. - * - * @param {string} projectId Google Cloud Platform project. - * @param {string} datasetId Dataset where the table or view is. - * @param {string} resourceName Table or view name to get the access policy. - * @returns {Promise} The IAM policy object. - */ -async function viewTableOrViewAccessPolicy(projectId, datasetId, resourceName) { +async function main(projectId, datasetId, resourceName) { // [START bigquery_view_table_or_view_access_policy] - const {BigQuery} = require('@google-cloud/bigquery'); - - // TODO(developer): Update and un-comment below lines. - // Google Cloud Platform project. - // projectId = "my_project_id"; + /** + * TODO(developer): Update and un-comment below lines + */ + // const projectId = "YOUR_PROJECT_ID" + // const datasetId = "YOUR_DATASET_ID" + // const resourceName = "YOUR_RESOURCE_NAME"; - // Dataset where the table or view is. - // datasetId = "my_dataset_id"; - - // Table or view name to get the access policy. - // resourceName = "my_table_name_id"; + const {BigQuery} = require('@google-cloud/bigquery'); // Instantiate a client. const client = new BigQuery(); - // Get a reference to the dataset by datasetId. - const dataset = client.dataset(datasetId); - // Get a reference to the table by tableName. - const table = dataset.table(resourceName); - - // Get the IAM access policy for the table or view. - const [policy] = await table.getIamPolicy(); - - // Initialize bindings array. - if (!policy.bindings) { - policy.bindings = []; + async function viewTableOrViewAccessPolicy() { + const dataset = client.dataset(datasetId); + const table = dataset.table(resourceName); + + // Get the IAM access policy for the table or view. + const [policy] = await table.getIamPolicy(); + + // Initialize bindings if they don't exist + if (!policy.bindings) { + policy.bindings = []; + } + + // Show policy details. + // Find more details for the Policy object here: + // https://cloud.google.com/bigquery/docs/reference/rest/v2/Policy + console.log(`Access Policy details for table or view '${resourceName}'.`); + console.log(`Bindings: ${JSON.stringify(policy.bindings, null, 2)}`); + console.log(`etag: ${policy.etag}`); + console.log(`Version: ${policy.version}`); } - - // Show policy details - // Find more details for the Policy object here: - // https://cloud.google.com/bigquery/docs/reference/rest/v2/Policy - console.log(`Access Policy details for table or view '${resourceName}'.`); - console.log(`Bindings: ${JSON.stringify(policy.bindings, null, 2)}`); - console.log(`etag: ${policy.etag}`); - console.log(`Version: ${policy.version}`); - // [END bigquery_view_table_or_view_access_policy] - return policy; + await viewTableOrViewAccessPolicy(); } -module.exports = viewTableOrViewAccessPolicy; +exports.viewTableOrViewAccessPolicy = main; From 6a26991b3c95f5a8d3446ee9741bc1849e299346 Mon Sep 17 00:00:00 2001 From: Ivan Hernandez Date: Fri, 14 Mar 2025 23:13:04 +0000 Subject: [PATCH 3/4] fix(bigquery): update test from viewTableOrViewAccessPolicy --- .../test/viewTableOrViewAccessPolicy.test.js | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js b/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js index 99811f2e5b..9ece26c35c 100644 --- a/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js +++ b/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js @@ -70,32 +70,4 @@ describe('viewTableOrViewAccessPolicy', () => { 'Should log version information' ); }); - - it('should view view access policies', async () => { - // View the view access policy - await viewTableOrViewAccessPolicy(projectId, datasetId, viewId); - - // Check that the right messages were logged - assert.strictEqual( - console.log.calledWith( - `Access Policy details for table or view '${viewId}'.` - ), - true - ); - - assert.ok( - console.log.calledWith(sinon.match('Bindings:')), - 'Should log bindings information' - ); - - assert.ok( - console.log.calledWith(sinon.match('etag:')), - 'Should log etag information' - ); - - assert.ok( - console.log.calledWith(sinon.match('Version:')), - 'Should log version information' - ); - }); }); From 476a840b3014e08167c7fd29e19df646c44b92d4 Mon Sep 17 00:00:00 2001 From: Ivan Hernandez Date: Fri, 14 Mar 2025 23:17:22 +0000 Subject: [PATCH 4/4] fix(bigquery): fix linting issue --- bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js b/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js index 9ece26c35c..4ef009c818 100644 --- a/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js +++ b/bigquery/cloud-client/test/viewTableOrViewAccessPolicy.test.js @@ -24,14 +24,12 @@ const {viewTableOrViewAccessPolicy} = require('../viewTableOrViewAccessPolicy'); describe('viewTableOrViewAccessPolicy', () => { let datasetId = null; let tableId = null; - let viewId = null; const projectId = process.env.GCLOUD_PROJECT; beforeEach(async () => { const response = await setupBeforeAll(); datasetId = response.datasetId; tableId = response.tableId; - viewId = response.viewId; sinon.stub(console, 'log'); sinon.stub(console, 'error');