diff --git a/docs/ai.md b/docs/ai.md index c386dd7b..6b3c956a 100644 --- a/docs/ai.md +++ b/docs/ai.md @@ -16,7 +16,7 @@ Sends a request to supported LLMs using Box AI. This is intended for direct use, USAGE $ box ai:ask --prompt --items ... [-t ] [--as-user ] [--no-color] [--json | --csv] [-s | --save-to-file-path ] [--fields ] [--bulk-file-path ] [-h] [-v] [-y] [-q] - [--ai-agent ] + [--ai-agent ] [--raw-json | ] FLAGS -h, --help Show CLI help @@ -36,6 +36,9 @@ FLAGS --json Output formatted JSON --no-color Turn off colors for logging --prompt= (required) The prompt for the AI request + --raw-json Output the raw API JSON response instead of the tsClient-normalized object fields. + Added as a non-breaking compatibility flag for users who need JSON field names to + match the API schema exactly. Implies --json. --save-to-file-path= Override default file path to save report DESCRIPTION @@ -55,7 +58,7 @@ Sends an AI request to supported Large Language Models (LLMs) and extracts metad USAGE $ box ai:extract --prompt --items ... [-t ] [--as-user ] [--no-color] [--json | --csv] [-s | --save-to-file-path ] [--fields ] [--bulk-file-path ] [-h] [-v] [-y] [-q] - [--ai-agent ] + [--raw-json | ] [--ai-agent ] FLAGS -h, --help Show CLI help @@ -76,6 +79,9 @@ FLAGS --json Output formatted JSON --no-color Turn off colors for logging --prompt= (required) The prompt provided to a Large Language Model (LLM) in the request. + --raw-json Output the raw API JSON response instead of the tsClient-normalized object fields. + Added as a non-breaking compatibility flag for users who need JSON field names to + match the API schema exactly. Implies --json. --save-to-file-path= Override default file path to save report DESCRIPTION diff --git a/docs/integration-mappings.md b/docs/integration-mappings.md index 6a0f916c..6a317015 100644 --- a/docs/integration-mappings.md +++ b/docs/integration-mappings.md @@ -233,8 +233,8 @@ List Teams integration mappings ``` USAGE $ box integration-mappings:teams [-t ] [--as-user ] [--no-color] [--json | --csv] [-s | --save-to-file-path - ] [--fields ] [--bulk-file-path ] [-h] [-v] [-y] [-q] [--max-items ] [--partner-item-id - ] [--partner-item-type ] [--box-item-id ] [--box-item-type ] + ] [--fields ] [--bulk-file-path ] [-h] [-v] [-y] [-q] [--max-items ] [--raw-json | ] + [--partner-item-id ] [--partner-item-type ] [--box-item-id ] [--box-item-type ] FLAGS -h, --help Show CLI help @@ -258,6 +258,9 @@ FLAGS --partner-item-id= ID of the mapped item, for which the mapping should be returned --partner-item-type= Mapped item type, for which the mapping should be returned, value is one of: channel, team + --raw-json Output the raw API JSON response instead of the tsClient-normalized object fields. + Added as a non-breaking compatibility flag for users who need JSON field names to + match the API schema exactly. Implies --json. --save-to-file-path= Override default file path to save report DESCRIPTION @@ -358,8 +361,8 @@ List Teams integration mappings ``` USAGE $ box integration-mappings:teams:list [-t ] [--as-user ] [--no-color] [--json | --csv] [-s | --save-to-file-path - ] [--fields ] [--bulk-file-path ] [-h] [-v] [-y] [-q] [--max-items ] [--partner-item-id - ] [--partner-item-type ] [--box-item-id ] [--box-item-type ] + ] [--fields ] [--bulk-file-path ] [-h] [-v] [-y] [-q] [--max-items ] [--raw-json | ] + [--partner-item-id ] [--partner-item-type ] [--box-item-id ] [--box-item-type ] FLAGS -h, --help Show CLI help @@ -383,6 +386,9 @@ FLAGS --partner-item-id= ID of the mapped item, for which the mapping should be returned --partner-item-type= Mapped item type, for which the mapping should be returned, value is one of: channel, team + --raw-json Output the raw API JSON response instead of the tsClient-normalized object fields. + Added as a non-breaking compatibility flag for users who need JSON field names to + match the API schema exactly. Implies --json. --save-to-file-path= Override default file path to save report DESCRIPTION @@ -404,7 +410,7 @@ Update Teams integration mapping ``` USAGE $ box integration-mappings:teams:update ID [-t ] [--as-user ] [--no-color] [--json | --csv] [-s | --save-to-file-path - ] [--fields ] [--bulk-file-path ] [-h] [-v] [-y] [-q] [--box-item-id ] + ] [--fields ] [--bulk-file-path ] [-h] [-v] [-y] [-q] [--raw-json | ] [--box-item-id ] ARGUMENTS ID ID of an integration mapping @@ -423,6 +429,9 @@ FLAGS --fields= Comma separated list of fields to show --json Output formatted JSON --no-color Turn off colors for logging + --raw-json Output the raw API JSON response instead of the tsClient-normalized object fields. + Added as a non-breaking compatibility flag for users who need JSON field names to + match the API schema exactly. Implies --json. --save-to-file-path= Override default file path to save report DESCRIPTION diff --git a/src/box-command.js b/src/box-command.js index b99f0419..08db3858 100644 --- a/src/box-command.js +++ b/src/box-command.js @@ -1187,6 +1187,44 @@ class BoxCommand extends Command { return client; } + /** + * Returns true when raw API JSON output was requested. + * + * @returns {boolean} True if raw JSON output should be used + * @private + */ + _wantsRawJsonOutput() { + return Boolean(this.flags && this.flags['raw-json']); + } + + /** + * Preserves default output behavior while adding raw JSON support. + * + * The generated TypeScript client can expose response objects with normalized + * field names that do not match the original API schema. That behavior was + * introduced as newer commands moved to `tsClient`. To fix the JSON output + * shape without a breaking change, commands that support `--raw-json` use this + * wrapper on the top-level response object before calling `output()`. + * + * @param {*} content The content to potentially replace with rawData + * @returns {*} The content to send to output formatting + */ + getOutputContentWithRawJsonSupport(content) { + if (typeof content === 'object' && content !== null) { + if (this._wantsRawJsonOutput()) { + return content.rawData ?? content; + } + + if (Object.hasOwn(content, 'rawData')) { + const output = { ...content }; + delete output.rawData; + return output; + } + } + + return content; + } + /** * Format data for output to stdout * @param {*} content The content to output @@ -1323,7 +1361,11 @@ class BoxCommand extends Command { } const page = await fetchPage(pageQueryParams); - const pageEntries = page.entries || []; + const rawPage = + typeof page?.rawData === 'object' && page.rawData !== null + ? page.rawData + : page; + const pageEntries = rawPage.entries || page.entries || []; entries.push(...pageEntries); remaining -= pageEntries.length; marker = page.nextMarker || page.next_marker; @@ -1393,6 +1435,12 @@ class BoxCommand extends Command { return 'json'; } + // Raw API payloads are only intended for JSON output, so `--raw-json` + // implicitly promotes the format to JSON without changing default behavior. + if (this._wantsRawJsonOutput()) { + return 'json'; + } + if (this.flags.csv) { return 'csv'; } @@ -2214,6 +2262,14 @@ BoxCommand.flags = { }), }; +BoxCommand.rawJsonFlags = Object.freeze({ + 'raw-json': Flags.boolean({ + description: + 'Output the raw API JSON response instead of the tsClient-normalized object fields. Added as a non-breaking compatibility flag for users who need JSON field names to match the API schema exactly. Implies --json.', + exclusive: ['csv'], + }), +}); + BoxCommand.minFlags = _.pick(BoxCommand.flags, [ 'no-color', 'help', diff --git a/src/commands/ai/ask.js b/src/commands/ai/ask.js index abebf8a1..adcdfc6b 100644 --- a/src/commands/ai/ask.js +++ b/src/commands/ai/ask.js @@ -23,8 +23,7 @@ class AiAskCommand extends BoxCommand { } let answer = await this.tsClient.ai.createAiAsk(options); - delete answer.rawData; - await this.output(answer); + await this.output(this.getOutputContentWithRawJsonSupport(answer)); } } @@ -96,6 +95,7 @@ AiAskCommand.flags = { } }, }), + ...BoxCommand.rawJsonFlags, }; module.exports = AiAskCommand; diff --git a/src/commands/ai/extract.js b/src/commands/ai/extract.js index e85b8446..8afe7b51 100644 --- a/src/commands/ai/extract.js +++ b/src/commands/ai/extract.js @@ -20,9 +20,7 @@ class AiExtractCommand extends BoxCommand { } let answer = await this.tsClient.ai.createAiExtract(options); - - delete answer.rawData; - await this.output(answer); + await this.output(this.getOutputContentWithRawJsonSupport(answer)); } } @@ -37,6 +35,7 @@ AiExtractCommand._endpoint = 'post_ai_extract'; // Flags definition AiExtractCommand.flags = { ...BoxCommand.flags, + ...BoxCommand.rawJsonFlags, prompt: Flags.string({ required: true, description: diff --git a/src/commands/hubs/collaborations/create.js b/src/commands/hubs/collaborations/create.js index 37253dd3..0a952c8c 100644 --- a/src/commands/hubs/collaborations/create.js +++ b/src/commands/hubs/collaborations/create.js @@ -46,8 +46,7 @@ class HubsCreateCollaborationCommand extends BoxCommand { await this.tsClient.hubCollaborations.createHubCollaborationV2025R0( requestBody ); - delete collaboration.rawData; - await this.output(collaboration); + await this.output(collaboration.rawData ?? collaboration); } } HubsCreateCollaborationCommand.aliases = ['hubs:collaborations:add']; diff --git a/src/commands/hubs/collaborations/get.js b/src/commands/hubs/collaborations/get.js index 52f0e744..8f9f16ee 100644 --- a/src/commands/hubs/collaborations/get.js +++ b/src/commands/hubs/collaborations/get.js @@ -10,8 +10,7 @@ class HubsGetCollaborationCommand extends BoxCommand { await this.tsClient.hubCollaborations.getHubCollaborationByIdV2025R0( args.id ); - delete collaboration.rawData; - await this.output(collaboration); + await this.output(collaboration.rawData ?? collaboration); } } diff --git a/src/commands/hubs/collaborations/update.js b/src/commands/hubs/collaborations/update.js index fd0e299e..ffc196a8 100644 --- a/src/commands/hubs/collaborations/update.js +++ b/src/commands/hubs/collaborations/update.js @@ -15,8 +15,7 @@ class HubsUpdateCollaborationCommand extends BoxCommand { role: flags.role, } ); - delete collaboration.rawData; - await this.output(collaboration); + await this.output(collaboration.rawData ?? collaboration); } } diff --git a/src/commands/hubs/copy.js b/src/commands/hubs/copy.js index 598939ee..23e95940 100644 --- a/src/commands/hubs/copy.js +++ b/src/commands/hubs/copy.js @@ -17,8 +17,7 @@ class HubsCopyCommand extends BoxCommand { } const hub = await this.tsClient.hubs.copyHubV2025R0(args.id, requestBody); - delete hub.rawData; - await this.output(hub); + await this.output(hub.rawData ?? hub); } } diff --git a/src/commands/hubs/create.js b/src/commands/hubs/create.js index bc690cd9..9db34e1c 100644 --- a/src/commands/hubs/create.js +++ b/src/commands/hubs/create.js @@ -16,8 +16,7 @@ class HubsCreateCommand extends BoxCommand { } const hub = await this.tsClient.hubs.createHubV2025R0(requestBody); - delete hub.rawData; - await this.output(hub); + await this.output(hub.rawData ?? hub); } } diff --git a/src/commands/hubs/get.js b/src/commands/hubs/get.js index db533326..83685b08 100644 --- a/src/commands/hubs/get.js +++ b/src/commands/hubs/get.js @@ -7,8 +7,7 @@ class HubsGetCommand extends BoxCommand { async run() { const { args } = await this.parse(HubsGetCommand); const hub = await this.tsClient.hubs.getHubByIdV2025R0(args.id); - delete hub.rawData; - await this.output(hub); + await this.output(hub.rawData ?? hub); } } diff --git a/src/commands/hubs/items/manage.js b/src/commands/hubs/items/manage.js index bc3791e5..2e7ab696 100644 --- a/src/commands/hubs/items/manage.js +++ b/src/commands/hubs/items/manage.js @@ -51,8 +51,7 @@ class HubsManageItemsCommand extends BoxCommand { args.id, { operations } ); - delete response.rawData; - await this.output(response); + await this.output(response.rawData ?? response); } } diff --git a/src/commands/hubs/update.js b/src/commands/hubs/update.js index 6135a098..7996b4ef 100644 --- a/src/commands/hubs/update.js +++ b/src/commands/hubs/update.js @@ -42,8 +42,7 @@ class HubsUpdateCommand extends BoxCommand { args.id, requestBody ); - delete hub.rawData; - await this.output(hub); + await this.output(hub.rawData ?? hub); } } diff --git a/src/commands/integration-mappings/teams/index.js b/src/commands/integration-mappings/teams/index.js index 3bb2fa75..0b13405c 100644 --- a/src/commands/integration-mappings/teams/index.js +++ b/src/commands/integration-mappings/teams/index.js @@ -26,8 +26,9 @@ class IntegrationMappingsTeamsListCommand extends BoxCommand { await this.tsClient.integrationMappings.getTeamsIntegrationMapping( options ); - delete teamsIntegrationMappings.rawData; - await this.output(teamsIntegrationMappings); + await this.output( + this.getOutputContentWithRawJsonSupport(teamsIntegrationMappings) + ); } } @@ -47,6 +48,7 @@ IntegrationMappingsTeamsListCommand._endpoint = IntegrationMappingsTeamsListCommand.flags = { ...BoxCommand.flags, ...PaginationUtilities.flags, + ...BoxCommand.rawJsonFlags, 'partner-item-id': Flags.string({ hidden: false, description: diff --git a/src/commands/integration-mappings/teams/update.js b/src/commands/integration-mappings/teams/update.js index ce1f5a1c..4f7cbc03 100644 --- a/src/commands/integration-mappings/teams/update.js +++ b/src/commands/integration-mappings/teams/update.js @@ -24,8 +24,9 @@ class IntegrationMappingsTeamsUpdateCommand extends BoxCommand { requestBody: body, } ); - delete integrationMapping.rawData; - await this.output(integrationMapping); + await this.output( + this.getOutputContentWithRawJsonSupport(integrationMapping) + ); } } @@ -39,6 +40,7 @@ IntegrationMappingsTeamsUpdateCommand._endpoint = IntegrationMappingsTeamsUpdateCommand.flags = { ...BoxCommand.flags, + ...BoxCommand.rawJsonFlags, 'box-item-id': Flags.string({ description: 'ID of the mapped folder', }), diff --git a/test/commands/ai.test.js b/test/commands/ai.test.js index 80c7fc27..20daaf44 100644 --- a/test/commands/ai.test.js +++ b/test/commands/ai.test.js @@ -82,6 +82,24 @@ describe('AI', function () { const fixture = getFixture('ai/post_ai_ask_response'); const yamlFixture = getFixture('ai/post_ai_ask_response_yaml.txt'); + test.nock(TEST_API_ROOT, (api) => + api + .post('/2.0/ai/ask', expectedRequestBody) + .reply(200, expectedResponseBody) + ) + .stdout() + .command([ + 'ai:ask', + '--items=content=one,two,three,id=12345,type=file', + '--prompt', + 'What is the status of this document?', + '--raw-json', + '--token=test', + ]) + .it('should output the raw response when --raw-json is passed', (context) => { + assert.deepEqual(JSON.parse(context.stdout), expectedResponseBody); + }); + test.nock(TEST_API_ROOT, (api) => api .post('/2.0/ai/ask', expectedRequestBody) @@ -301,6 +319,29 @@ describe('AI', function () { const fixture = getFixture('ai/post_ai_extract_response'); const yamlFixture = getFixture('ai/post_ai_extract_response_yaml.txt'); + test.nock(TEST_API_ROOT, (api) => { + api.post('/2.0/ai/extract', expectedRequestBody).reply( + 200, + expectedResponseBody + ); + }) + .stdout() + .command([ + 'ai:extract', + '--items=content=one,two,three,id=12345,type=file', + '--prompt', + 'firstName, lastName, location, yearOfBirth, company', + '--raw-json', + '--token=test', + ]) + + .it( + 'should output the raw response when --raw-json is passed', + (context) => { + assert.deepEqual(JSON.parse(context.stdout), expectedResponseBody); + } + ); + test.nock(TEST_API_ROOT, (api) => { api.post('/2.0/ai/extract', expectedRequestBody).reply( 200, diff --git a/test/commands/hubs.test.js b/test/commands/hubs.test.js index 4a76098a..7b3eadf3 100644 --- a/test/commands/hubs.test.js +++ b/test/commands/hubs.test.js @@ -5,74 +5,11 @@ const { assert } = require('chai'); const os = require('node:os'); const { TEST_API_ROOT, getFixture } = require('../helpers/test-helper'); -// Hub fixtures use API snake_case fields, but the TS SDK currently returns camelCase JSON output. -// It also wraps date-time fields in `{ value: ... }` objects, so tests need a normalized expected shape. -// This is a temporary test helper until a future PR makes command JSON output follow API field naming. -function formatHubJsonOutput(hub) { - return { - id: hub.id, - type: hub.type, - title: hub.title, - description: hub.description, - createdAt: { - value: hub.created_at, - }, - updatedAt: { - value: hub.updated_at, - }, - createdBy: hub.created_by, - updatedBy: hub.updated_by, - viewCount: hub.view_count, - isAiEnabled: hub.is_ai_enabled, - isCollaborationRestrictedToEnterprise: - hub.is_collaboration_restricted_to_enterprise, - canNonOwnersInvite: hub.can_non_owners_invite, - canSharedLinkBeCreated: hub.can_shared_link_be_created, - canPublicSharedLinkBeCreated: hub.can_public_shared_link_be_created, - }; -} - -function formatHubCollaborationGrantee(grantee) { - const output = { - id: grantee.id, - type: grantee.type, - }; - - if (grantee.name) { - output.name = grantee.name; - } - if (grantee.login) { - output.login = grantee.login; - } - if (grantee.group_type) { - output.groupType = grantee.group_type; - } - - return output; -} - -function formatHubCollaborationJsonOutput(collaboration) { - const output = { - id: collaboration.id, - type: collaboration.type, - hub: collaboration.hub, - role: collaboration.role, - status: collaboration.status, - }; - - if (collaboration.accessible_by) { - output.accessibleBy = formatHubCollaborationGrantee( - collaboration.accessible_by - ); - } - - return output; -} - describe('Hubs', function () { describe('hubs', function () { + const hubResponse = JSON.parse(getFixture('hubs/get_hubs_id')); const response = { - entries: [{ id: '12345', type: 'hubs', title: 'Team Hub' }], + entries: [hubResponse], limit: 10, }; @@ -101,9 +38,7 @@ describe('Hubs', function () { '--token=test', ]) .it('lists hubs with provided filters', (context) => { - assert.deepEqual(JSON.parse(context.stdout), [ - { id: '12345', type: 'hubs', title: 'Team Hub' }, - ]); + assert.deepEqual(JSON.parse(context.stdout), response.entries); }); const firstPageEntries = Array.from({ length: 1000 }, (_, index) => ({ @@ -153,8 +88,9 @@ describe('Hubs', function () { }); describe('hubs:enterprise', function () { + const hubResponse = JSON.parse(getFixture('hubs/get_hubs_id')); const response = { - entries: [{ id: '11111', type: 'hubs', title: 'Enterprise Hub' }], + entries: [hubResponse], limit: 50, }; @@ -181,13 +117,7 @@ describe('Hubs', function () { '--token=test', ]) .it('lists enterprise hubs with provided filters', (context) => { - assert.deepEqual(JSON.parse(context.stdout), [ - { - id: '11111', - type: 'hubs', - title: 'Enterprise Hub', - }, - ]); + assert.deepEqual(JSON.parse(context.stdout), response.entries); }); }); @@ -256,27 +186,7 @@ describe('Hubs', function () { '--token=test', ]) .it('adds and removes items in a hub', (context) => { - assert.deepEqual(JSON.parse(context.stdout), { - operations: [ - { - action: 'add', - item: { - id: '11111', - type: 'file', - }, - parentId: '67890', - status: 201, - }, - { - action: 'remove', - item: { - id: '22222', - type: 'folder', - }, - status: 204, - }, - ], - }); + assert.deepEqual(JSON.parse(context.stdout), response); }); }); @@ -302,19 +212,7 @@ describe('Hubs', function () { '--token=test', ]) .it('lists hub document pages', (context) => { - assert.deepEqual(JSON.parse(context.stdout), [ - { - id: 'page_1', - type: 'page', - titleFragment: 'Overview', - }, - { - id: 'page_2', - type: 'page', - parentId: 'page_1', - titleFragment: 'Launch Plan', - }, - ]); + assert.deepEqual(JSON.parse(context.stdout), response.entries); }); }); @@ -342,19 +240,7 @@ describe('Hubs', function () { '--token=test', ]) .it('lists hub document blocks for a page', (context) => { - assert.deepEqual(JSON.parse(context.stdout), [ - { - id: 'block_1', - type: 'section_title', - parentId: 'page_1', - fragment: 'Goals', - }, - { - id: 'block_2', - type: 'item_list', - parentId: 'page_1', - }, - ]); + assert.deepEqual(JSON.parse(context.stdout), response.entries); }); }); @@ -368,10 +254,7 @@ describe('Hubs', function () { .stdout() .command(['hubs:get', '12345', '--json', '--token=test']) .it('gets a hub by ID', (context) => { - assert.deepEqual( - JSON.parse(context.stdout), - formatHubJsonOutput(response) - ); + assert.deepEqual(JSON.parse(context.stdout), response); }); }); @@ -440,10 +323,7 @@ describe('Hubs', function () { '--token=test', ]) .it('updates a hub with provided fields', (context) => { - assert.deepEqual( - JSON.parse(context.stdout), - formatHubJsonOutput(response) - ); + assert.deepEqual(JSON.parse(context.stdout), response); }); }); @@ -517,9 +397,7 @@ describe('Hubs', function () { '--token=test', ]) .it('lists collaborations for a hub', (context) => { - assert.deepEqual(JSON.parse(context.stdout), [ - formatHubCollaborationJsonOutput(response.entries[0]), - ]); + assert.deepEqual(JSON.parse(context.stdout), response.entries); }); }); @@ -552,10 +430,7 @@ describe('Hubs', function () { '--token=test', ]) .it('creates a collaboration for a hub', (context) => { - assert.deepEqual( - JSON.parse(context.stdout), - formatHubCollaborationJsonOutput(response) - ); + assert.deepEqual(JSON.parse(context.stdout), response); }); it('rejects unsupported hub collaboration roles on create', async function () { @@ -591,10 +466,7 @@ describe('Hubs', function () { '--token=test', ]) .it('gets a hub collaboration by ID', (context) => { - assert.deepEqual( - JSON.parse(context.stdout), - formatHubCollaborationJsonOutput(response) - ); + assert.deepEqual(JSON.parse(context.stdout), response); }); }); @@ -620,10 +492,7 @@ describe('Hubs', function () { '--token=test', ]) .it('updates a hub collaboration role', (context) => { - assert.deepEqual( - JSON.parse(context.stdout), - formatHubCollaborationJsonOutput(response) - ); + assert.deepEqual(JSON.parse(context.stdout), response); }); it('rejects unsupported hub collaboration roles on update', async function () { diff --git a/test/commands/integration-mappings.test.js b/test/commands/integration-mappings.test.js index fbbf8b7c..a02319d5 100644 --- a/test/commands/integration-mappings.test.js +++ b/test/commands/integration-mappings.test.js @@ -213,6 +213,38 @@ describe('Integration Mappings', function () { assert.equal(context.stderr, ''); assert.deepEqual(JSON.parse(context.stdout), expectedResult); }); + + test.nock(TEST_API_ROOT, (api) => + api + .get('/2.0/integration_mappings/teams') + .query({ + partner_item_id: partnerItemId, + partner_item_type: partnerItemType, + box_item_id: boxItemId, + box_item_type: boxItemType, + }) + .reply(200, fixture, { + 'Content-Type': 'application/json', + }) + ) + .stderr() + .stdout() + .command([ + 'integration-mappings:teams:list', + `--partner-item-id=${partnerItemId}`, + `--partner-item-type=${partnerItemType}`, + `--box-item-id=${boxItemId}`, + `--box-item-type=${boxItemType}`, + '--raw-json', + '--token=test', + ]) + .it( + 'should list Teams integration mappings using raw JSON output', + (context) => { + assert.equal(context.stderr, ''); + assert.deepEqual(JSON.parse(context.stdout), JSON.parse(fixture)); + } + ); }); describe('integration-mappings:teams:create', function () { @@ -338,6 +370,38 @@ describe('Integration Mappings', function () { assert.equal(context.stderr, ''); assert.deepEqual(JSON.parse(context.stdout), expectedResult); }); + + test.nock(TEST_API_ROOT, (api) => + api + .put( + `/2.0/integration_mappings/teams/${integrationMappingId}`, + { + box_item: { + id: boxItemId, + type: 'folder', + }, + } + ) + .reply(200, fixture, { + 'Content-Type': 'application/json', + }) + ) + .stderr() + .stdout() + .command([ + 'integration-mappings:teams:update', + integrationMappingId, + `--box-item-id=${boxItemId}`, + '--raw-json', + '--token=test', + ]) + .it( + 'should update a Teams integration mapping using raw JSON output', + (context) => { + assert.equal(context.stderr, ''); + assert.deepEqual(JSON.parse(context.stdout), JSON.parse(fixture)); + } + ); }); describe('integration-mappings:teams:delete', function () {