From b02a7887bc9637df81e82cc31ee5cc4f4a404c79 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 30 Jun 2021 08:07:01 -0700 Subject: [PATCH 1/4] fix: enable TeamsInfo methods to work with CloudAdapter --- libraries/botbuilder/src/teamsInfo.ts | 5 ++-- libraries/botbuilder/tests/teamsInfo.test.js | 28 ++++++++++++++------ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/libraries/botbuilder/src/teamsInfo.ts b/libraries/botbuilder/src/teamsInfo.ts index dfd57157ca..948a8ae219 100644 --- a/libraries/botbuilder/src/teamsInfo.ts +++ b/libraries/botbuilder/src/teamsInfo.ts @@ -414,11 +414,12 @@ export class TeamsInfo { * @private */ private static getConnectorClient(context: TurnContext): ConnectorClient { - if (!context.adapter || !('createConnectorClient' in context.adapter)) { + const client = context.turnState?.get(context.adapter.ConnectorClientKey); + if (!client) { throw new Error('This method requires a connector client.'); } - return (context.adapter as BotFrameworkAdapter).createConnectorClient(context.activity.serviceUrl); + return client; } /** diff --git a/libraries/botbuilder/tests/teamsInfo.test.js b/libraries/botbuilder/tests/teamsInfo.test.js index 536ce5d789..3c8f3582c4 100644 --- a/libraries/botbuilder/tests/teamsInfo.test.js +++ b/libraries/botbuilder/tests/teamsInfo.test.js @@ -3,7 +3,7 @@ const nock = require('nock'); const sinon = require('sinon'); const { BotFrameworkAdapter, TeamsInfo, CloudAdapter } = require('../'); const { Conversations } = require('botframework-connector/lib/connectorApi/operations'); -const { MicrosoftAppCredentials, ConnectorClient } = require('botframework-connector'); +const { MicrosoftAppCredentials, ConnectorClient, ServiceClientCredentialsFactory, PasswordServiceClientCredentialFactory } = require('botframework-connector'); const { TurnContext, MessageFactory, ActionTypes, BotAdapter, Channels } = require('botbuilder-core'); class TeamsInfoAdapter extends BotFrameworkAdapter { @@ -182,6 +182,8 @@ const teamActivity = { }; describe('TeamsInfo', function () { + const connectorClient = new ConnectorClient(new MicrosoftAppCredentials('abc', '123'), { baseUri: 'https://smba.trafficmanager.net/amer' }); + beforeEach(function () { nock.cleanAll(); }); @@ -342,6 +344,7 @@ describe('TeamsInfo', function () { .reply(200, { conversations }); const context = new TestContext(teamActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); const channels = await TeamsInfo.getTeamChannels(context); assert(fetchOauthToken.isDone()); @@ -381,6 +384,7 @@ describe('TeamsInfo', function () { .reply(200, { conversations }); const context = new TestContext(teamActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); const channels = await TeamsInfo.getTeamChannels(context, '19:ChannelIdgeneralChannelId@thread.skype'); assert(fetchOauthToken.isDone()); @@ -431,6 +435,7 @@ describe('TeamsInfo', function () { .reply(200, teamDetails); const context = new TestContext(teamActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); const fetchedTeamDetails = await TeamsInfo.getTeamDetails(context); assert(fetchOauthToken.isDone()); @@ -457,6 +462,7 @@ describe('TeamsInfo', function () { .reply(200, teamDetails); const context = new TestContext(teamActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); const fetchedTeamDetails = await TeamsInfo.getTeamDetails( context, '19:ChannelIdgeneralChannelId@thread.skype' @@ -495,6 +501,7 @@ describe('TeamsInfo', function () { .reply(200, members); const context = new TestContext(oneOnOneActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); const fetchedMembers = await TeamsInfo.getMembers(context); assert(fetchOauthToken.isDone()); @@ -548,6 +555,7 @@ describe('TeamsInfo', function () { .reply(200, members); const context = new TestContext(groupChatActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); const fetchedMembers = await TeamsInfo.getMembers(context); assert(fetchOauthToken.isDone()); @@ -591,6 +599,7 @@ describe('TeamsInfo', function () { .reply(200, members); const context = new TestContext(teamActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); const fetchedMembers = await TeamsInfo.getMembers(context); assert(fetchOauthToken.isDone()); @@ -604,6 +613,7 @@ describe('TeamsInfo', function () { it('should not work if conversationId is falsey', async function () { const context = new TestContext(oneOnOneActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); context.activity.conversation.id = undefined; await assert.rejects(TeamsInfo.getMembers(context), (err) => { @@ -635,6 +645,7 @@ describe('TeamsInfo', function () { .reply(200, member); const context = new TestContext(oneOnOneActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); const fetchedMember = await TeamsInfo.getMember(context, oneOnOneActivity.from.id); assert(fetchOauthToken.isDone()); @@ -663,6 +674,7 @@ describe('TeamsInfo', function () { .reply(200, member); const context = new TestContext(teamActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); const fetchedMember = await TeamsInfo.getMember(context, teamActivity.from.id); assert(fetchOauthToken.isDone()); @@ -685,6 +697,7 @@ describe('TeamsInfo', function () { describe('getMeetingParticipant', function () { const context = new TestContext(teamActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); it('should work with correct arguments', async function () { const participant = { @@ -729,6 +742,7 @@ describe('TeamsInfo', function () { describe('getMeetingInfo', function () { const context = new TestContext(teamActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); it('should work with correct arguments-meetingId in context', async function () { const details = { @@ -772,6 +786,9 @@ describe('TeamsInfo', function () { }); it('should work with correct arguments-meetingId passed in', async function () { + const context = new TestContext(teamActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); + const details = { organizer: { id: teamActivity.from.id, @@ -872,6 +889,7 @@ describe('TeamsInfo', function () { .reply(200, members); const context = new TestContext(teamActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); const fetchedMembers = await TeamsInfo.getTeamMembers(context); assert(fetchOauthToken.isDone()); @@ -915,6 +933,7 @@ describe('TeamsInfo', function () { .reply(200, members); const context = new TestContext(teamActivity); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); const fetchedMembers = await TeamsInfo.getTeamMembers(context, '19:ChannelIdgeneralChannelId@thread.skype'); assert(fetchOauthToken.isDone()); @@ -935,13 +954,6 @@ describe('TeamsInfo', function () { new Error('This method requires a connector client.') ); }); - - it(`should error if the adapter doesn't have a createConnectorClient method`, function () { - assert.throws( - () => TeamsInfo.getConnectorClient({ adapter: {} }), - new Error('This method requires a connector client.') - ); - }); }); describe('getMembersInternal()', function () { From 902a1d53bf52604fe317e9cb9b4d5fc5b907fb03 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 30 Jun 2021 09:24:00 -0700 Subject: [PATCH 2/4] test for no connectorClient on turnState --- libraries/botbuilder/tests/teamsInfo.test.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libraries/botbuilder/tests/teamsInfo.test.js b/libraries/botbuilder/tests/teamsInfo.test.js index 3c8f3582c4..c38f72200f 100644 --- a/libraries/botbuilder/tests/teamsInfo.test.js +++ b/libraries/botbuilder/tests/teamsInfo.test.js @@ -954,6 +954,14 @@ describe('TeamsInfo', function () { new Error('This method requires a connector client.') ); }); + + it(`should error if the turnState doesn't have a ConnectorClient`, function () { + const context = new TestContext(teamActivity); + assert.throws( + () => TeamsInfo.getConnectorClient(context), + new Error('This method requires a connector client.') + ); + }); }); describe('getMembersInternal()', function () { From b9b787155049ef725ae25f8eb87751140fe15642 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 30 Jun 2021 12:54:31 -0700 Subject: [PATCH 3/4] prefer context.adapter, fallback to turnstate.get() --- libraries/botbuilder/src/teamsInfo.ts | 5 ++++- libraries/botbuilder/tests/teamsInfo.test.js | 15 ++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/libraries/botbuilder/src/teamsInfo.ts b/libraries/botbuilder/src/teamsInfo.ts index 948a8ae219..835d8adb8b 100644 --- a/libraries/botbuilder/src/teamsInfo.ts +++ b/libraries/botbuilder/src/teamsInfo.ts @@ -414,7 +414,10 @@ export class TeamsInfo { * @private */ private static getConnectorClient(context: TurnContext): ConnectorClient { - const client = context.turnState?.get(context.adapter.ConnectorClientKey); + const client = + context.adapter && 'createConnectorClient' in context.adapter + ? (context.adapter as BotFrameworkAdapter).createConnectorClient(context.activity.serviceUrl) + : context.turnState?.get(context.adapter.ConnectorClientKey); if (!client) { throw new Error('This method requires a connector client.'); } diff --git a/libraries/botbuilder/tests/teamsInfo.test.js b/libraries/botbuilder/tests/teamsInfo.test.js index c38f72200f..927cde5c0a 100644 --- a/libraries/botbuilder/tests/teamsInfo.test.js +++ b/libraries/botbuilder/tests/teamsInfo.test.js @@ -182,7 +182,9 @@ const teamActivity = { }; describe('TeamsInfo', function () { - const connectorClient = new ConnectorClient(new MicrosoftAppCredentials('abc', '123'), { baseUri: 'https://smba.trafficmanager.net/amer' }); + const connectorClient = new ConnectorClient(new MicrosoftAppCredentials('abc', '123'), { + baseUri: 'https://smba.trafficmanager.net/amer/', + }); beforeEach(function () { nock.cleanAll(); @@ -955,12 +957,11 @@ describe('TeamsInfo', function () { ); }); - it(`should error if the turnState doesn't have a ConnectorClient`, function () { - const context = new TestContext(teamActivity); - assert.throws( - () => TeamsInfo.getConnectorClient(context), - new Error('This method requires a connector client.') - ); + it(`should fallback to the connectorClient on turnState if adapter doesn't exist in context.adapter`, function () { + const context = new TurnContext({}); + context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); + const result = TeamsInfo.getConnectorClient(context); + assert.deepStrictEqual(result, connectorClient); }); }); From 61e310dce5b9cb2f8e0d9e3deba04cef34ae44f1 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 30 Jun 2021 12:59:09 -0700 Subject: [PATCH 4/4] strictEqual --- libraries/botbuilder/tests/teamsInfo.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/botbuilder/tests/teamsInfo.test.js b/libraries/botbuilder/tests/teamsInfo.test.js index 927cde5c0a..4a73ffd061 100644 --- a/libraries/botbuilder/tests/teamsInfo.test.js +++ b/libraries/botbuilder/tests/teamsInfo.test.js @@ -961,7 +961,7 @@ describe('TeamsInfo', function () { const context = new TurnContext({}); context.turnState.set(context.adapter.ConnectorClientKey, connectorClient); const result = TeamsInfo.getConnectorClient(context); - assert.deepStrictEqual(result, connectorClient); + assert.strictEqual(result, connectorClient); }); });