Added more tests and a way to send responses to the user without going through hubot
This commit is contained in:
Родитель
a3871df3c9
Коммит
9007425105
|
@ -43,6 +43,15 @@ class TextMiddleware extends BaseMiddleware
|
||||||
|
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
# Constructs a text message response to indicate an error to the user in the
|
||||||
|
# message channel they are using
|
||||||
|
constructErrorResponse: (activity, text) ->
|
||||||
|
payload =
|
||||||
|
type: 'message'
|
||||||
|
text: "#{text}"
|
||||||
|
address: activity?.address
|
||||||
|
return payload
|
||||||
|
|
||||||
# Indicates that the authorization isn't supported for this middleware
|
# Indicates that the authorization isn't supported for this middleware
|
||||||
supportsAuth: () ->
|
supportsAuth: () ->
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -23,7 +23,7 @@ class BotFrameworkAdapter extends Adapter
|
||||||
constructor: (robot) ->
|
constructor: (robot) ->
|
||||||
super robot
|
super robot
|
||||||
@appId = process.env.BOTBUILDER_APP_ID
|
@appId = process.env.BOTBUILDER_APP_ID
|
||||||
@appPassword = process.env.BOTBUILDER_APP_PASSWORD
|
@appPassword = process.env.BOTBUILDER_APP_PASSWORD
|
||||||
@endpoint = process.env.BOTBUILDER_ENDPOINT || "/api/messages"
|
@endpoint = process.env.BOTBUILDER_ENDPOINT || "/api/messages"
|
||||||
@enableAuth = process.env.HUBOT_TEAMS_ENABLE_AUTH || 'false'
|
@enableAuth = process.env.HUBOT_TEAMS_ENABLE_AUTH || 'false'
|
||||||
robot.logger.info "#{LogPrefix} Adapter loaded. Using appId #{@appId}"
|
robot.logger.info "#{LogPrefix} Adapter loaded. Using appId #{@appId}"
|
||||||
|
@ -49,12 +49,21 @@ class BotFrameworkAdapter extends Adapter
|
||||||
|
|
||||||
@connector.onEvent (events, cb) => @onBotEvents events, cb
|
@connector.onEvent (events, cb) => @onBotEvents events, cb
|
||||||
|
|
||||||
@connector.onInvoke (events, cb) => @sendTextToHubot events, cb
|
@connector.onInvoke (events, cb) => @menuCardInvoke events, cb
|
||||||
|
|
||||||
sendTextToHubot: (invokeEvent, cb) ->
|
|
||||||
invokeEvent.text = invokeEvent.value.hubotMessage
|
# If the command for the invoke doesn't need user input, handle the command
|
||||||
delete invokeEvent.value
|
# normally. If it does need user input, return a prompt for user input.
|
||||||
@handleActivity(invokeEvent)
|
menuCardInvoke: (invokeEvent, cb) ->
|
||||||
|
middleware = @using(invokeEvent.source)
|
||||||
|
payload = middleware.maybeConstructUserInputPrompt(invokeEvent)
|
||||||
|
if payload == null
|
||||||
|
invokeEvent.text = invokeEvent.value.hubotMessage
|
||||||
|
delete invokeEvent.value
|
||||||
|
@handleActivity(invokeEvent)
|
||||||
|
else
|
||||||
|
@sendPayload(@robot, payload)
|
||||||
|
return
|
||||||
|
|
||||||
using: (name) ->
|
using: (name) ->
|
||||||
MiddlewareClass = Middleware.middlewareFor(name)
|
MiddlewareClass = Middleware.middlewareFor(name)
|
||||||
|
@ -68,7 +77,8 @@ class BotFrameworkAdapter extends Adapter
|
||||||
handleActivity: (activity) ->
|
handleActivity: (activity) ->
|
||||||
console.log("handle activity")
|
console.log("handle activity")
|
||||||
console.log(activity)
|
console.log(activity)
|
||||||
@robot.logger.info "#{LogPrefix} Handling activity Channel: #{activity.source}; type: #{activity.type}"
|
@robot.logger.info "#{LogPrefix} Handling activity Channel:
|
||||||
|
#{activity.source}; type: #{activity.type}"
|
||||||
|
|
||||||
# Construct the middleware
|
# Construct the middleware
|
||||||
middleware = @using(activity.source)
|
middleware = @using(activity.source)
|
||||||
|
@ -79,17 +89,32 @@ class BotFrameworkAdapter extends Adapter
|
||||||
# the text middleware, otherwise use the Teams middleware
|
# the text middleware, otherwise use the Teams middleware
|
||||||
if not middleware.supportsAuth()
|
if not middleware.supportsAuth()
|
||||||
if @enableAuth == 'true'
|
if @enableAuth == 'true'
|
||||||
@robot.logger.info "#{LogPrefix} Message source doesn't support authorization"
|
# @robot.logger.info "#{LogPrefix} Message source doesn't support authorization"
|
||||||
activity.text = "hubot return source authorization not supported error"
|
# activity.text = "hubot return source authorization not supported error"
|
||||||
# This redundant section is included if we do the short circuit sendPayload thing
|
# # This redundant section is included if we do the short circuit sendPayload thing
|
||||||
event = middleware.toReceivable activity
|
# event = middleware.toReceivable activity
|
||||||
if event?
|
# if event?
|
||||||
@robot.receive event
|
# @robot.receive event
|
||||||
|
# A payload has at least type and address
|
||||||
|
@robot.logger.info "#{LogPrefix} Authorization isn\'t supported for the channel"
|
||||||
|
text = "Authorization isn't supported for the channel"
|
||||||
|
payload = middleware.constructErrorResponse(activity, text)
|
||||||
|
@sendPayload(@robot, payload)
|
||||||
|
return
|
||||||
else
|
else
|
||||||
event = middleware.toReceivable activity
|
event = middleware.toReceivable activity
|
||||||
if event?
|
if event?
|
||||||
@robot.receive event
|
@robot.receive event
|
||||||
else
|
else
|
||||||
|
# Check for clicks from the dropdown menu
|
||||||
|
if activity?.value?.needsUserInput == 'true'
|
||||||
|
payload = middleware.maybeConstructUserInputPrompt(activity)
|
||||||
|
if payload != null
|
||||||
|
@sendPayload(@robot, payload)
|
||||||
|
return
|
||||||
|
activity.text = activity.value.hubotMessage
|
||||||
|
delete activity.value
|
||||||
|
|
||||||
# Construct a TeamsChatConnector to pass to toReceivable
|
# Construct a TeamsChatConnector to pass to toReceivable
|
||||||
teamsConnector = new BotBuilderTeams.TeamsChatConnector {
|
teamsConnector = new BotBuilderTeams.TeamsChatConnector {
|
||||||
appId: @robot.adapter.appId
|
appId: @robot.adapter.appId
|
||||||
|
@ -99,43 +124,18 @@ class BotFrameworkAdapter extends Adapter
|
||||||
if event?
|
if event?
|
||||||
console.log("********************************")
|
console.log("********************************")
|
||||||
console.log(event)
|
console.log(event)
|
||||||
# If unauthorized error occurred, overwrite the text
|
|
||||||
if unauthorizedError
|
if unauthorizedError
|
||||||
event.text = "hubot return unauthorized user error"
|
@robot.logger.info "#{LogPrefix} Unauthorized user, sending error"
|
||||||
|
|
||||||
|
text = "You are not authorized to send commands to hubot.
|
||||||
|
To gain access, talk to your admins:"
|
||||||
|
payload = middleware.constructErrorResponse(activity, text, true)
|
||||||
|
@sendPayload(@robot, payload)
|
||||||
|
return
|
||||||
|
|
||||||
@robot.receive event
|
@robot.receive event
|
||||||
|
|
||||||
# # Return an error to the user if authorization is enabled and the message
|
|
||||||
# # is either from a channel that doesn't support auth or if the user who sent the
|
|
||||||
# # message isn't authorized
|
|
||||||
# authorizedUsers = @robot.brain.get("authorizedUsers")
|
|
||||||
# aadObjectId = activity?.address?.user?.aadObjectId
|
|
||||||
# if @enableAuth == 'true'
|
|
||||||
# if middleware.supportsAuth()
|
|
||||||
# if aadObjectId is undefined or authorizedUsers[aadObjectId] is undefined
|
|
||||||
# @robot.logger.info "#{LogPrefix} Unauthorized user; returning error"
|
|
||||||
# activity.text = "hubot return unauthorized user error"
|
|
||||||
# # Change this to make a call to a middleware function that returns
|
|
||||||
# # a payload with the error text to return
|
|
||||||
# else
|
|
||||||
# @robot.logger.info "#{LogPrefix} Message source doesn't support authorization"
|
|
||||||
# activity.text = "hubot return source authorization not supported error"
|
|
||||||
|
|
||||||
# # If authorization isn't supported by the activity source, use
|
|
||||||
# # the text middleware, otherwise use the Teams middleware
|
|
||||||
# if not middleware.supportsAuth()
|
|
||||||
# event = middleware.toReceivable activity
|
|
||||||
# if event?
|
|
||||||
# @robot.receive event
|
|
||||||
# else
|
|
||||||
# # Construct a TeamsChatConnector to pass to toReceivable
|
|
||||||
# teamsConnector = new BotBuilderTeams.TeamsChatConnector {
|
|
||||||
# appId: @robot.adapter.appId
|
|
||||||
# appPassword: @robot.adapter.appPassword
|
|
||||||
# }
|
|
||||||
# middleware.toReceivable activity, teamsConnector, (event) =>
|
|
||||||
# if event?
|
|
||||||
# @robot.receive event
|
|
||||||
|
|
||||||
send: (context, messages...) ->
|
send: (context, messages...) ->
|
||||||
@robot.logger.info "#{LogPrefix} send"
|
@robot.logger.info "#{LogPrefix} send"
|
||||||
@reply context, messages...
|
@reply context, messages...
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
|
|
||||||
HubotQueryParts = require './hubot-query-parts'
|
HubotQueryParts = require './hubot-query-parts'
|
||||||
|
|
||||||
maybeConstructCard = (response, query) ->
|
maybeConstructResponseCard = (response, query) ->
|
||||||
# Check if the response is from a list commands follow up button press.
|
# Check if the response is from a list commands follow up button press.
|
||||||
# If so, construct the needed input card and return it
|
# If so, construct the needed input card and return it
|
||||||
index = query.search("generate input card")
|
# index = query.search("generate input card")
|
||||||
if (index != -1)
|
# if (index != -1)
|
||||||
return constructMenuInputCard(query.replace("generate input card", ""), response.text)
|
# return maybeConstructMenuInputCard(response.text)
|
||||||
|
|
||||||
# Check if response.text matches one of the reg exps in the LUT
|
# Check if response.text matches one of the reg exps in the LUT
|
||||||
for regex of HubotResponseCards
|
for regex of HubotResponseCards
|
||||||
|
@ -20,10 +20,19 @@ maybeConstructCard = (response, query) ->
|
||||||
return card
|
return card
|
||||||
return null
|
return null
|
||||||
|
|
||||||
# Constructs an input card
|
# Constructs an input card if needed or returns null if the
|
||||||
constructMenuInputCard = (query, text) ->
|
# query doesn't need user input
|
||||||
card = initializeAdaptiveCard(query)
|
maybeConstructMenuInputCard = (query) ->
|
||||||
queryParts = HubotQueryParts[text]
|
queryParts = HubotQueryParts[query]
|
||||||
|
|
||||||
|
# Check if the query needs a user input card
|
||||||
|
console.log(queryParts.inputParts is undefined)
|
||||||
|
console.log(queryParts.inputParts == undefined)
|
||||||
|
if queryParts.inputParts is undefined
|
||||||
|
return null
|
||||||
|
|
||||||
|
shortQuery = constructShortQuery(query)
|
||||||
|
card = initializeAdaptiveCard(shortQuery)
|
||||||
|
|
||||||
# Create the input fields of the sub card
|
# Create the input fields of the sub card
|
||||||
for i in [0 ... queryParts.inputParts.length]
|
for i in [0 ... queryParts.inputParts.length]
|
||||||
|
@ -38,7 +47,8 @@ constructMenuInputCard = (query, text) ->
|
||||||
|
|
||||||
# Create selector
|
# Create selector
|
||||||
if index != -1
|
if index != -1
|
||||||
card.content.body.push(addSelector(query, inputPart.substring(index + 1), query + " - input" + "#{i}"))
|
card.content.body.push(addSelector(query, inputPart.substring(index + 1),
|
||||||
|
query + " - input" + "#{i}"))
|
||||||
# Create text input
|
# Create text input
|
||||||
else
|
else
|
||||||
card.content.body.push(addTextInput(query + " - input" + "#{i}", inputPart))
|
card.content.body.push(addTextInput(query + " - input" + "#{i}", inputPart))
|
||||||
|
@ -126,13 +136,7 @@ addTextInput = (id, inputPart) ->
|
||||||
getFollowUpButtons = (query, regex) ->
|
getFollowUpButtons = (query, regex) ->
|
||||||
actions = []
|
actions = []
|
||||||
for followUpQuery in HubotResponseCards[regex]
|
for followUpQuery in HubotResponseCards[regex]
|
||||||
|
shortQuery = constructShortQuery(followUpQuery)
|
||||||
# Create a short version of the command by including only the
|
|
||||||
# start of the command to the first user input marked by ( or <
|
|
||||||
shortQueryEnd = followUpQuery.search(new RegExp("[(<]"))
|
|
||||||
if shortQueryEnd == -1
|
|
||||||
shortQueryEnd = followUpQuery.length
|
|
||||||
shortQuery = followUpQuery.substring(0, shortQueryEnd)
|
|
||||||
action = {
|
action = {
|
||||||
'title': shortQuery
|
'title': shortQuery
|
||||||
}
|
}
|
||||||
|
@ -246,6 +250,15 @@ appendCardActions = (card1, card2) ->
|
||||||
|
|
||||||
return card1
|
return card1
|
||||||
|
|
||||||
|
# Create a short version of the command by including only the
|
||||||
|
# start of the command to the first user input marked by ( or <
|
||||||
|
constructShortQuery = (query) ->
|
||||||
|
shortQueryEnd = query.search(new RegExp("[(<]"))
|
||||||
|
if shortQueryEnd == -1
|
||||||
|
shortQueryEnd = query.length
|
||||||
|
shortQuery = query.substring(0, shortQueryEnd)
|
||||||
|
return shortQuery.trim()
|
||||||
|
|
||||||
# HubotResponseCards maps from regex's of hubot queries to an array of follow up hubot
|
# HubotResponseCards maps from regex's of hubot queries to an array of follow up hubot
|
||||||
# queries stored as strings
|
# queries stored as strings
|
||||||
HubotResponseCards = {
|
HubotResponseCards = {
|
||||||
|
@ -285,7 +298,8 @@ HubotResponseCards = {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
maybeConstructCard,
|
maybeConstructResponseCard,
|
||||||
|
maybeConstructMenuInputCard,
|
||||||
appendCardBody,
|
appendCardBody,
|
||||||
appendCardActions
|
appendCardActions
|
||||||
}
|
}
|
|
@ -25,7 +25,7 @@
|
||||||
BotBuilder = require 'botbuilder'
|
BotBuilder = require 'botbuilder'
|
||||||
BotBuilderTeams = require 'botbuilder-teams'
|
BotBuilderTeams = require 'botbuilder-teams'
|
||||||
HubotResponseCards = require './hubot-response-cards'
|
HubotResponseCards = require './hubot-response-cards'
|
||||||
#MicrosoftGraph = require '@microsoft/microsoft-graph-client'
|
HubotQueryParts = require './hubot-query-parts'
|
||||||
{ Robot, TextMessage, Message, User } = require 'hubot'
|
{ Robot, TextMessage, Message, User } = require 'hubot'
|
||||||
{ BaseMiddleware, registerMiddleware } = require './adapter-middleware'
|
{ BaseMiddleware, registerMiddleware } = require './adapter-middleware'
|
||||||
LogPrefix = "hubot-msteams:"
|
LogPrefix = "hubot-msteams:"
|
||||||
|
@ -41,7 +41,8 @@ class MicrosoftTeamsMiddleware extends BaseMiddleware
|
||||||
@allowedTenants = []
|
@allowedTenants = []
|
||||||
if process.env.HUBOT_OFFICE365_TENANT_FILTER?
|
if process.env.HUBOT_OFFICE365_TENANT_FILTER?
|
||||||
@allowedTenants = process.env.HUBOT_OFFICE365_TENANT_FILTER.split(",")
|
@allowedTenants = process.env.HUBOT_OFFICE365_TENANT_FILTER.split(",")
|
||||||
@robot.logger.info("#{LogPrefix} Restricting tenants to #{JSON.stringify(@allowedTenants)}")
|
@robot.logger.info("#{LogPrefix} Restricting tenants to \
|
||||||
|
#{JSON.stringify(@allowedTenants)}")
|
||||||
|
|
||||||
toReceivable: (activity, teamsConnector, authEnabled, cb) ->
|
toReceivable: (activity, teamsConnector, authEnabled, cb) ->
|
||||||
@robot.logger.info "#{LogPrefix} toReceivable"
|
@robot.logger.info "#{LogPrefix} toReceivable"
|
||||||
|
@ -54,45 +55,43 @@ class MicrosoftTeamsMiddleware extends BaseMiddleware
|
||||||
# Get the user
|
# Get the user
|
||||||
user = getUser(activity)
|
user = getUser(activity)
|
||||||
user = @robot.brain.userForId(user.id, user)
|
user = @robot.brain.userForId(user.id, user)
|
||||||
console.log("++++++++++++++++++++++++++++++++++++++++++++++")
|
|
||||||
console.log(user)
|
|
||||||
|
|
||||||
# We don't want to save the activity or room in the brain since its something that changes per chat.
|
# We don't want to save the activity or room in the brain since its
|
||||||
|
# something that changes per chat.
|
||||||
user.activity = activity
|
user.activity = activity
|
||||||
user.room = getRoomId(activity)
|
user.room = getRoomId(activity)
|
||||||
|
|
||||||
if activity.type != 'message' && activity.type != 'invoke'
|
# Fetch the roster of members to do authorization based on UPN
|
||||||
return new Message(user)
|
teamsConnector.fetchMembers activity?.address?.serviceUrl, \
|
||||||
else
|
activity?.address?.conversation?.id, (err, chatMembers) =>
|
||||||
# Fetch the roster of members to do authorization based on UPN
|
if err
|
||||||
teamsConnector.fetchMembers activity?.address?.serviceUrl, activity?.address?.conversation?.id, (err, chatMembers) =>
|
console.log("YUP AN ERR")
|
||||||
if err
|
return
|
||||||
return
|
|
||||||
console.log("==========================================")
|
|
||||||
console.log(chatMembers)
|
|
||||||
# Set the unauthorizedError to true if auth is enabled and the user who sent
|
|
||||||
# the message is not authorized
|
|
||||||
unauthorizedError = false
|
|
||||||
if authEnabled
|
|
||||||
authorizedUsers = @robot.brain.get("authorizedUsers")
|
|
||||||
console.log("---------------")
|
|
||||||
console.log(chatMembers[0].userPrincipalName)
|
|
||||||
# Get the sender's UPN
|
|
||||||
senderUPN = getSenderUPN(user, chatMembers)
|
|
||||||
console.log(senderUPN)
|
|
||||||
if senderUPN is undefined or authorizedUsers[senderUPN] is undefined
|
|
||||||
@robot.logger.info "#{LogPrefix} Unauthorized user; returning error"
|
|
||||||
unauthorizedError = true
|
|
||||||
# activity.text = "hubot return unauthorized user error"
|
|
||||||
# Change this to make a call to a middleware function that returns
|
|
||||||
# a payload with the error text to return
|
|
||||||
|
|
||||||
# Add the sender's UPN to user
|
|
||||||
user.userPrincipalName = senderUPN
|
|
||||||
|
|
||||||
activity = fixActivityForHubot(activity, @robot, chatMembers)
|
# Set the unauthorizedError to true if auth is enabled and the user who sent
|
||||||
message = new TextMessage(user, activity.text, activity.address.id)
|
# the message is not authorized
|
||||||
cb(message, unauthorizedError)
|
unauthorizedError = false
|
||||||
|
if authEnabled
|
||||||
|
authorizedUsers = @robot.brain.get("authorizedUsers")
|
||||||
|
# Get the sender's UPN
|
||||||
|
senderUPN = getSenderUPN(user, chatMembers)
|
||||||
|
if senderUPN is undefined or authorizedUsers[senderUPN] is undefined
|
||||||
|
@robot.logger.info "#{LogPrefix} Unauthorized user; returning error"
|
||||||
|
unauthorizedError = true
|
||||||
|
# activity.text = "hubot return unauthorized user error"
|
||||||
|
# Change this to make a call to a middleware function that returns
|
||||||
|
# a payload with the error text to return
|
||||||
|
|
||||||
|
# Add the sender's UPN to user
|
||||||
|
user.userPrincipalName = senderUPN
|
||||||
|
|
||||||
|
# Return a generic message if the activity isn't a message or invoke
|
||||||
|
if activity.type != 'message' && activity.type != 'invoke'
|
||||||
|
cb(new Message(user), unauthorizedError)
|
||||||
|
|
||||||
|
activity = fixActivityForHubot(activity, @robot, chatMembers)
|
||||||
|
message = new TextMessage(user, activity.text, activity.address.id)
|
||||||
|
cb(message, unauthorizedError)
|
||||||
|
|
||||||
toSendable: (context, message) ->
|
toSendable: (context, message) ->
|
||||||
@robot.logger.info "#{LogPrefix} toSendable"
|
@robot.logger.info "#{LogPrefix} toSendable"
|
||||||
|
@ -109,7 +108,7 @@ class MicrosoftTeamsMiddleware extends BaseMiddleware
|
||||||
# If the query sent by the user should trigger a card,
|
# If the query sent by the user should trigger a card,
|
||||||
# construct the card to attach to the response
|
# construct the card to attach to the response
|
||||||
# and remove sentQuery from the brain
|
# and remove sentQuery from the brain
|
||||||
card = HubotResponseCards.maybeConstructCard(response, activity.text)
|
card = HubotResponseCards.maybeConstructResponseCard(response, activity.text)
|
||||||
if card != null
|
if card != null
|
||||||
delete response.text
|
delete response.text
|
||||||
response.attachments = [card]
|
response.attachments = [card]
|
||||||
|
@ -156,7 +155,7 @@ class MicrosoftTeamsMiddleware extends BaseMiddleware
|
||||||
return true
|
return true
|
||||||
|
|
||||||
# Combines the text and attachments of multiple hubot messages sent in succession.
|
# Combines the text and attachments of multiple hubot messages sent in succession.
|
||||||
# Most of the first received response is kept, and the text and attachments of
|
# Most of the first received response is kept, and the text and attachments of
|
||||||
# subsequent responses received within 500ms of the first are combined into the
|
# subsequent responses received within 500ms of the first are combined into the
|
||||||
# first response.
|
# first response.
|
||||||
combineResponses: (storedPayload, newPayload) ->
|
combineResponses: (storedPayload, newPayload) ->
|
||||||
|
@ -197,9 +196,53 @@ class MicrosoftTeamsMiddleware extends BaseMiddleware
|
||||||
if attachment.contentType != "application/vnd.microsoft.card.adaptive"
|
if attachment.contentType != "application/vnd.microsoft.card.adaptive"
|
||||||
storedMessage.attachments.push(attachment)
|
storedMessage.attachments.push(attachment)
|
||||||
else
|
else
|
||||||
storedCard = HubotResponseCards.appendCardBody(storedCard, attachment)
|
storedCard = HubotResponseCards.appendCardBody(storedCard, \
|
||||||
storedCard = HubotResponseCards.appendCardActions(storedCard, attachment)
|
attachment)
|
||||||
|
storedCard = HubotResponseCards.appendCardActions(storedCard, \
|
||||||
|
attachment)
|
||||||
|
|
||||||
|
# Constructs a text message response to indicate an error to the user in the
|
||||||
|
# message channel they are using
|
||||||
|
constructErrorResponse: (activity, text, appendAdmins) ->
|
||||||
|
if appendAdmins
|
||||||
|
authorizedUsers = @robot.brain.get("authorizedUsers")
|
||||||
|
for userKey, isAdmin of authorizedUsers
|
||||||
|
if isAdmin
|
||||||
|
text = """#{text}
|
||||||
|
#{userKey}"""
|
||||||
|
typing =
|
||||||
|
type: 'typing'
|
||||||
|
address: activity?.address
|
||||||
|
|
||||||
|
payload =
|
||||||
|
type: 'message'
|
||||||
|
text: "#{text}"
|
||||||
|
address: activity?.address
|
||||||
|
|
||||||
|
return [typing, payload]
|
||||||
|
|
||||||
|
# Constructs a response containing a card for user input if needed or null
|
||||||
|
# if user input is not needed
|
||||||
|
maybeConstructUserInputPrompt: (event) ->
|
||||||
|
query = event.value.hubotMessage
|
||||||
|
|
||||||
|
# Remove the hubot prefix, if there is one
|
||||||
|
query = query.replace("hubot ", "")
|
||||||
|
console.log(query)
|
||||||
|
|
||||||
|
card = HubotResponseCards.maybeConstructMenuInputCard(query)
|
||||||
|
if card is null
|
||||||
|
console.log("CARD IS NULL")
|
||||||
|
return null
|
||||||
|
|
||||||
|
response =
|
||||||
|
type: 'message'
|
||||||
|
address: event?.address
|
||||||
|
attachments: [
|
||||||
|
card
|
||||||
|
]
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# Helper methods for generating richer messages
|
# Helper methods for generating richer messages
|
||||||
|
@ -256,7 +299,8 @@ class MicrosoftTeamsMiddleware extends BaseMiddleware
|
||||||
entities = activity?.entities || []
|
entities = activity?.entities || []
|
||||||
if not Array.isArray(entities)
|
if not Array.isArray(entities)
|
||||||
entities = [entities]
|
entities = [entities]
|
||||||
return entities.filter((entity) -> entity.type == "mention" && (not userId? || userId == entity.mentioned?.id))
|
return entities.filter((entity) -> entity.type == "mention" && \
|
||||||
|
(not userId? || userId == entity.mentioned?.id))
|
||||||
|
|
||||||
# Returns the provided user's userPrincipalName (UPN) or null if one cannot be found
|
# Returns the provided user's userPrincipalName (UPN) or null if one cannot be found
|
||||||
getSenderUPN = (user, chatMembers) ->
|
getSenderUPN = (user, chatMembers) ->
|
||||||
|
@ -270,14 +314,16 @@ class MicrosoftTeamsMiddleware extends BaseMiddleware
|
||||||
|
|
||||||
# Fixes the activity to have the proper information for Hubot
|
# Fixes the activity to have the proper information for Hubot
|
||||||
# 1. Constructs the text command to send to hubot if the event is from a
|
# 1. Constructs the text command to send to hubot if the event is from a
|
||||||
# submit on an adaptive card (containing the value property).
|
# submit on an adaptive card (containing the value property).
|
||||||
# 2. Replaces all occurrences of the channel's bot at mention name with the configured name in hubot.
|
# 2. Replaces all occurrences of the channel's bot at mention name with the configured
|
||||||
|
# name in hubot.
|
||||||
# The hubot's configured name might not be the same name that is sent from the chat service in
|
# The hubot's configured name might not be the same name that is sent from the chat service in
|
||||||
# the activity's text.
|
# the activity's text.
|
||||||
# 3. Replaces all occurrences of @ mentions to users with their aad object id if the user is
|
# 3. Replaces all occurrences of @ mentions to users with their aad object id if the user is
|
||||||
# on the roster of chanenl members from Teams. If a mentioned user is not in the chat roster,
|
# on the roster of chanenl members from Teams. If a mentioned user is not in the chat roster,
|
||||||
# the mention is replaced with their name.
|
# the mention is replaced with their name.
|
||||||
# 4. Prepends hubot's name to the message for personal messages if it's not already
|
# 4. Trims all whitespace and newlines from the beginning and end of the text.
|
||||||
|
# 5. Prepends hubot's name to the message for personal messages if it's not already
|
||||||
# there
|
# there
|
||||||
fixActivityForHubot = (activity, robot, chatMembers) ->
|
fixActivityForHubot = (activity, robot, chatMembers) ->
|
||||||
# If activity.value exists, the command is from a card and the correct
|
# If activity.value exists, the command is from a card and the correct
|
||||||
|
@ -309,10 +355,11 @@ class MicrosoftTeamsMiddleware extends BaseMiddleware
|
||||||
|
|
||||||
# Set the constructed query as the text of the activity
|
# Set the constructed query as the text of the activity
|
||||||
activity.text = text
|
activity.text = text
|
||||||
return activity
|
#return activity
|
||||||
|
|
||||||
if not activity?.text? || typeof activity.text isnt 'string'
|
if not activity?.text? || typeof activity.text isnt 'string'
|
||||||
return activity
|
return activity
|
||||||
|
|
||||||
myChatId = activity?.address?.bot?.id
|
myChatId = activity?.address?.bot?.id
|
||||||
if not myChatId?
|
if not myChatId?
|
||||||
return activity
|
return activity
|
||||||
|
@ -332,6 +379,9 @@ class MicrosoftTeamsMiddleware extends BaseMiddleware
|
||||||
replacement = member.userPrincipalName
|
replacement = member.userPrincipalName
|
||||||
# *** replacement = member.objectId
|
# *** replacement = member.objectId
|
||||||
activity.text = activity.text.replace(mentionTextRegExp, replacement)
|
activity.text = activity.text.replace(mentionTextRegExp, replacement)
|
||||||
|
|
||||||
|
# Remove leading/trailing whitespace and newlines
|
||||||
|
activity.text = activity.text.trim()
|
||||||
|
|
||||||
# prepends the robot's name for direct messages if it's not already there
|
# prepends the robot's name for direct messages if it's not already there
|
||||||
if getConversationType(activity) == 'personal' && activity.text.search(robot.name) != 0
|
if getConversationType(activity) == 'personal' && activity.text.search(robot.name) != 0
|
||||||
|
|
|
@ -4,15 +4,28 @@ expect = chai.expect
|
||||||
BotFrameworkAdapter = require '../src/adapter'
|
BotFrameworkAdapter = require '../src/adapter'
|
||||||
MockRobot = require './mock-robot'
|
MockRobot = require './mock-robot'
|
||||||
|
|
||||||
|
|
||||||
describe 'Main Adapter', ->
|
describe 'Main Adapter', ->
|
||||||
describe 'Test Auth', ->
|
describe 'Test Authorization Setup', ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
process.env.HUBOT_TEAMS_INITIAL_ADMINS = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee,eight888-four-4444-fore-twelve121212'
|
process.env.HUBOT_TEAMS_INITIAL_ADMINS = 'an-1_20@em.ail,authorized_user@email.la'
|
||||||
process.env.BOTBUILDER_APP_ID = 'botbuilder-app-id'
|
# process.env.BOTBUILDER_APP_ID = 'botbuilder-app-id'
|
||||||
process.env.BOTBUILDER_APP_PASSWORD = 'botbuilder-app-password'
|
# process.env.BOTBUILDER_APP_PASSWORD = 'botbuilder-app-password'
|
||||||
process.env.HUBOT_DEBUG_LEVEL = 'error'
|
|
||||||
process.env.HUBOT_TEAMS_ENABLE_AUTH = 'true'
|
process.env.HUBOT_TEAMS_ENABLE_AUTH = 'true'
|
||||||
|
|
||||||
|
it 'should not set initial admins when auth enable is not set', ->
|
||||||
|
# Setup
|
||||||
|
delete process.env.HUBOT_TEAMS_ENABLE_AUTH
|
||||||
|
robot = new MockRobot
|
||||||
|
|
||||||
|
# Action
|
||||||
|
expect(() ->
|
||||||
|
adapter = BotFrameworkAdapter.use(robot)
|
||||||
|
).to.not.throw()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
expect(robot.brain.get("authorizedUsers")).to.be.null
|
||||||
|
|
||||||
it 'should not set initial admins when auth is not enabled', ->
|
it 'should not set initial admins when auth is not enabled', ->
|
||||||
# Setup
|
# Setup
|
||||||
process.env.HUBOT_TEAMS_ENABLE_AUTH = 'false'
|
process.env.HUBOT_TEAMS_ENABLE_AUTH = 'false'
|
||||||
|
@ -25,6 +38,16 @@ describe 'Main Adapter', ->
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
expect(robot.brain.get("authorizedUsers")).to.be.null
|
expect(robot.brain.get("authorizedUsers")).to.be.null
|
||||||
|
|
||||||
|
it 'should throw error when auth is enabled and initial admins', ->
|
||||||
|
# Setup
|
||||||
|
delete process.env.HUBOT_TEAMS_INITIAL_ADMINS
|
||||||
|
robot = new MockRobot
|
||||||
|
|
||||||
|
# Action and Assert
|
||||||
|
expect(() ->
|
||||||
|
adapter = BotFrameworkAdapter.use(robot)
|
||||||
|
).to.throw()
|
||||||
|
|
||||||
it 'should set initial admins when auth is enabled', ->
|
it 'should set initial admins when auth is enabled', ->
|
||||||
# Setup
|
# Setup
|
||||||
|
@ -37,50 +60,22 @@ describe 'Main Adapter', ->
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
expect(robot.brain.get("authorizedUsers")).to.eql {
|
expect(robot.brain.get("authorizedUsers")).to.eql {
|
||||||
'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee': true
|
'an-1_20@em.ail': true
|
||||||
'eight888-four-4444-fore-twelve121212': true
|
'authorized_user@email.la': true
|
||||||
}
|
}
|
||||||
|
|
||||||
it 'should not set initial admins when auth enable is not set', ->
|
|
||||||
# Setup
|
|
||||||
delete process.env.HUBOT_TEAMS_ENABLE_AUTH
|
|
||||||
robot = new MockRobot
|
|
||||||
|
|
||||||
# Action
|
|
||||||
expect(() ->
|
|
||||||
adapter = BotFrameworkAdapter.use(robot)
|
|
||||||
).to.not.throw()
|
|
||||||
|
|
||||||
# Assert
|
|
||||||
expect(robot.brain.get("authorizedUsers")).to.be.null
|
|
||||||
|
|
||||||
it 'should allow messages from authorized users', ->
|
describe 'Test Authorization Support for Teams Channel', ->
|
||||||
# Setup
|
robot = null
|
||||||
|
adapter = null
|
||||||
|
event = null
|
||||||
|
beforeEach ->
|
||||||
|
process.env.HUBOT_TEAMS_INITIAL_ADMINS = 'an-1_20@em.ail,authorized_user@email.la'
|
||||||
|
process.env.BOTBUILDER_APP_ID = 'botbuilder-app-id'
|
||||||
|
process.env.BOTBUILDER_APP_PASSWORD = 'botbuilder-app-password'
|
||||||
|
process.env.HUBOT_TEAMS_ENABLE_AUTH = 'true'
|
||||||
robot = new MockRobot
|
robot = new MockRobot
|
||||||
adapter = BotFrameworkAdapter.use(robot)
|
adapter = BotFrameworkAdapter.use(robot)
|
||||||
robot.adapter = adapter
|
robot.adapter = adapter
|
||||||
adapter.connector.fetchMembers = (serviceUrl, teamId, callback) ->
|
|
||||||
members = [
|
|
||||||
{
|
|
||||||
id: 'id-1'
|
|
||||||
objectId: 'aad-object-id-1'
|
|
||||||
name: 'user1 one'
|
|
||||||
givenName: 'user1'
|
|
||||||
surname: 'one'
|
|
||||||
email: 'one@user.one'
|
|
||||||
userPrincipalName: 'one@user.one'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'user-id'
|
|
||||||
objectId: 'eight888-four-4444-fore-twelve121212'
|
|
||||||
name: 'user-name'
|
|
||||||
givenName: 'user-'
|
|
||||||
surname: 'name'
|
|
||||||
email: 'em@ai.l'
|
|
||||||
userPrincipalName: 'em@ai.l'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
callback false, members
|
|
||||||
event =
|
event =
|
||||||
type: 'message'
|
type: 'message'
|
||||||
text: '<at>Bot</at> do something <at>Bot</at> and tell <at>User</at> about it'
|
text: '<at>Bot</at> do something <at>Bot</at> and tell <at>User</at> about it'
|
||||||
|
@ -112,88 +107,44 @@ describe 'Main Adapter', ->
|
||||||
id: "user-id"
|
id: "user-id"
|
||||||
name: "user-name"
|
name: "user-name"
|
||||||
aadObjectId: "eight888-four-4444-fore-twelve121212"
|
aadObjectId: "eight888-four-4444-fore-twelve121212"
|
||||||
|
userPrincipalName: "user-UPN"
|
||||||
serviceUrl: 'url-serviceUrl/a-url'
|
serviceUrl: 'url-serviceUrl/a-url'
|
||||||
|
|
||||||
|
it 'should return authorization not supported error for non-Teams channels', ->
|
||||||
|
# Setup
|
||||||
|
event.source = 'authorization-not-supported-source'
|
||||||
|
|
||||||
# Action
|
# Action
|
||||||
expect(() ->
|
expect(() ->
|
||||||
result = adapter.handleActivity(event)
|
adapter.handleActivity(event)
|
||||||
).to.not.throw()
|
).to.not.throw()
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
expect(robot.brain.get("authorizedUsers")).to.eql {
|
result = robot.brain.get("event")
|
||||||
'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee': true
|
expect(result.text).to.eql "hubot return source authorization not supported error"
|
||||||
'eight888-four-4444-fore-twelve121212': true
|
|
||||||
}
|
|
||||||
|
|
||||||
# it 'should overwrite the hubot command text to return an error message to unauthorized users', ->
|
it 'should work when authorization is enabled and message is from Teams', ->
|
||||||
# # Setup
|
# Setup
|
||||||
# robot = new Robot('../../hubot-botframework', 'botframework', false, 'hubot')
|
|
||||||
# adapter = BotFrameworkAdapter.use(robot)
|
|
||||||
# adapter.connector.fetchMembers = (serviceUrl, teamId, callback) ->
|
|
||||||
# members = [
|
|
||||||
# {
|
|
||||||
# id: 'id-1'
|
|
||||||
# objectId: 'aad-object-id-1'
|
|
||||||
# name: 'user1 one'
|
|
||||||
# givenName: 'user1'
|
|
||||||
# surname: 'one'
|
|
||||||
# email: 'one@user.one'
|
|
||||||
# userPrincipalName: 'one@user.one'
|
|
||||||
# },
|
|
||||||
# {
|
|
||||||
# id: 'user-id'
|
|
||||||
# objectId: 'eight888-four-4444-fore-twelve121212'
|
|
||||||
# name: 'user-name'
|
|
||||||
# givenName: 'user-'
|
|
||||||
# surname: 'name'
|
|
||||||
# email: 'em@ai.l'
|
|
||||||
# userPrincipalName: 'em@ai.l'
|
|
||||||
# }
|
|
||||||
# ]
|
|
||||||
# callback false, members
|
|
||||||
# event =
|
|
||||||
# type: 'message'
|
|
||||||
# text: '<at>Bot</at> do something <at>Bot</at> and tell <at>User</at> about it'
|
|
||||||
# agent: 'tests'
|
|
||||||
# source: 'msteams'
|
|
||||||
# entities: [
|
|
||||||
# type: "mention"
|
|
||||||
# text: "<at>Bot</at>"
|
|
||||||
# mentioned:
|
|
||||||
# id: "bot-id"
|
|
||||||
# name: "bot-name"
|
|
||||||
# ,
|
|
||||||
# type: "mention"
|
|
||||||
# text: "<at>User</at>"
|
|
||||||
# mentioned:
|
|
||||||
# id: "user-id"
|
|
||||||
# name: "user-name"
|
|
||||||
# ]
|
|
||||||
# attachments: []
|
|
||||||
# sourceEvent:
|
|
||||||
# tenant:
|
|
||||||
# id: "tenant-id"
|
|
||||||
# address:
|
|
||||||
# conversation:
|
|
||||||
# id: "19:conversation-id"
|
|
||||||
# bot:
|
|
||||||
# id: "bot-id"
|
|
||||||
# user:
|
|
||||||
# id: "id-1"
|
|
||||||
# name: "user1 one"
|
|
||||||
# aadObjectId: "aad-object-id-1"
|
|
||||||
# serviceUrl: 'url-serviceUrl/a-url'
|
|
||||||
|
|
||||||
# # Action
|
# Action
|
||||||
# expect(() ->
|
expect(() ->
|
||||||
# result = adapter.handleActivity(event)
|
adapter.handleActivity(event)
|
||||||
# ).to.not.throw()
|
).to.not.throw()
|
||||||
|
|
||||||
# console.log("=======================================")
|
# Assert
|
||||||
# console.log(adapter)
|
result = robot.brain.get("event")
|
||||||
|
|
||||||
# # Assert
|
it 'should work when message is from invoke', ->
|
||||||
# expect(robot.brain.get("authorizedUsers")).to.eql {
|
# Setup
|
||||||
# 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee': true
|
event.type = 'invoke'
|
||||||
# 'eight888-four-4444-fore-twelve121212': true
|
event.value =
|
||||||
# }
|
hubotMessage: 'hubot do something'
|
||||||
|
delete event.text
|
||||||
|
|
||||||
|
# Action
|
||||||
|
expect(() ->
|
||||||
|
adapter.sendTextToHubot(event)
|
||||||
|
).to.not.throw()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
|
|
@ -9,7 +9,19 @@ class MockRobot
|
||||||
"hubot b - does something b"
|
"hubot b - does something b"
|
||||||
]
|
]
|
||||||
@brain =
|
@brain =
|
||||||
userForId: -> {}
|
data: {}
|
||||||
|
userForId: (id, options) ->
|
||||||
|
user = {
|
||||||
|
id: "#{id}"
|
||||||
|
name: "a-hubot-user-name"
|
||||||
|
}
|
||||||
|
if options is null
|
||||||
|
return user
|
||||||
|
else
|
||||||
|
for key of options
|
||||||
|
user[key] = options[key]
|
||||||
|
return user
|
||||||
|
|
||||||
users: -> []
|
users: -> []
|
||||||
get: (key) ->
|
get: (key) ->
|
||||||
if @data is undefined
|
if @data is undefined
|
||||||
|
@ -18,16 +30,9 @@ class MockRobot
|
||||||
if key == storedKey
|
if key == storedKey
|
||||||
return @data[storedKey]
|
return @data[storedKey]
|
||||||
return null
|
return null
|
||||||
|
set: (key, value) ->
|
||||||
|
@data[key] = value
|
||||||
|
|
||||||
if process.env.HUBOT_TEAMS_ENABLE_AUTH == 'true'
|
receive: (event) ->
|
||||||
if process.env.HUBOT_TEAMS_INITIAL_ADMINS
|
@brain.data["event"] = event
|
||||||
@brain.data = {}
|
|
||||||
authorizedUsers = {}
|
|
||||||
for admin in process.env.HUBOT_TEAMS_INITIAL_ADMINS.split(",")
|
|
||||||
authorizedUsers[admin] = true
|
|
||||||
@brain.data["authorizedUsers"] = authorizedUsers
|
|
||||||
|
|
||||||
else
|
|
||||||
throw new Error("HUBOT_TEAMS_INITIAL_ADMINS is required")
|
|
||||||
receive: -> {}
|
|
||||||
module.exports = MockRobot
|
module.exports = MockRobot
|
||||||
|
|
|
@ -11,15 +11,21 @@ describe 'MicrosoftTeamsMiddleware', ->
|
||||||
describe 'toReceivable', ->
|
describe 'toReceivable', ->
|
||||||
robot = null
|
robot = null
|
||||||
event = null
|
event = null
|
||||||
chatMembers = null
|
teamsChatConnector = null
|
||||||
cb = -> {}
|
authEnabled = false
|
||||||
|
cb = ->
|
||||||
|
robot.receive event
|
||||||
|
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
delete process.env.HUBOT_OFFICE365_TENANT_FILTER
|
delete process.env.HUBOT_OFFICE365_TENANT_FILTER
|
||||||
|
|
||||||
robot = new MockRobot
|
robot = new MockRobot
|
||||||
adapter = BotFrameworkAdapter.use(robot)
|
options = {
|
||||||
robot.adapter = adapter
|
appId: 'botframework-app-id'
|
||||||
|
appPassword: 'botframework-app-password'
|
||||||
|
}
|
||||||
|
teamsChatConnector = new MockTeamsChatConnector(options)
|
||||||
|
|
||||||
|
authEnabled = false
|
||||||
event =
|
event =
|
||||||
type: 'message'
|
type: 'message'
|
||||||
text: '<at>Bot</at> do something <at>Bot</at> and tell <at>User</at> about it'
|
text: '<at>Bot</at> do something <at>Bot</at> and tell <at>User</at> about it'
|
||||||
|
@ -52,97 +58,135 @@ describe 'MicrosoftTeamsMiddleware', ->
|
||||||
name: "user-name"
|
name: "user-name"
|
||||||
aadObjectId: 'eight888-four-4444-fore-twelve121212'
|
aadObjectId: 'eight888-four-4444-fore-twelve121212'
|
||||||
|
|
||||||
it 'should allow messages without tenant id when tenant filter is empty', ->
|
|
||||||
|
it 'should allow messages when auth is not enabled', ->
|
||||||
# Setup
|
# Setup
|
||||||
console.log("**************************************")
|
|
||||||
console.log(MicrosoftTeamsMiddleware.toString())
|
|
||||||
delete event.sourceEvent
|
delete event.sourceEvent
|
||||||
teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
||||||
options = {
|
|
||||||
appId: 'botframework-app-id'
|
|
||||||
appPassword: 'botframework-app-password'
|
|
||||||
}
|
|
||||||
teamsChatConnector = new MockTeamsChatConnector(options)
|
|
||||||
|
|
||||||
|
|
||||||
# Action
|
# Action
|
||||||
receivable = null
|
|
||||||
expect(() ->
|
expect(() ->
|
||||||
receivable = teamsMiddleware.toReceivable(event, teamsChatConnector, cb)
|
teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb)
|
||||||
).to.not.throw()
|
).to.not.throw()
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
expect(receivable).to.be.a('Object')
|
result = robot.brain.get("event")
|
||||||
|
expect(result).to.be.a('Object')
|
||||||
|
|
||||||
# it 'should allow messages with tenant id when tenant filter is empty', ->
|
it 'should set unauthorized error for message when user isn\'t authorized', ->
|
||||||
# # Setup
|
# Setup
|
||||||
# teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
robot.brain.data["authorizedUsers"] =
|
||||||
|
'an-1_20@em.ail': true
|
||||||
|
'authorized_user@email.la': false
|
||||||
|
teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
||||||
|
authEnabled = true
|
||||||
|
cb = (event, unauthorizedError) ->
|
||||||
|
robot.brain.data["unauthError"] = unauthorizedError
|
||||||
|
robot.receive event
|
||||||
|
|
||||||
# # Action
|
# Action
|
||||||
# receivable = null
|
expect(() ->
|
||||||
# expect(() ->
|
teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb)
|
||||||
# receivable = teamsMiddleware.toReceivable(event, cb)
|
).to.not.throw()
|
||||||
# ).to.not.throw()
|
|
||||||
|
|
||||||
# # Assert
|
# Assert
|
||||||
# expect(receivable).to.be.a('Object')
|
result = robot.brain.get("event")
|
||||||
|
expect(result).to.be.a('Object')
|
||||||
|
expect(robot.brain.get("unauthError")).to.be.true
|
||||||
|
|
||||||
# it 'should allow messages from allowed tenant ids', ->
|
it 'should allow messages without tenant id when tenant filter is empty', ->
|
||||||
# # Setup
|
# Setup
|
||||||
# process.env.HUBOT_OFFICE365_TENANT_FILTER = event.sourceEvent.tenant.id
|
delete event.sourceEvent
|
||||||
# teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
||||||
|
|
||||||
# # Action
|
# Action
|
||||||
# receivable = null
|
expect(() ->
|
||||||
# expect(() ->
|
teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb)
|
||||||
# receivable = teamsMiddleware.toReceivable(event, cb)
|
).to.not.throw()
|
||||||
# ).to.not.throw()
|
|
||||||
|
|
||||||
# # Assert
|
# Assert
|
||||||
# expect(receivable).to.be.a('Object')
|
result = robot.brain.get("event")
|
||||||
|
expect(result).to.be.a('Object')
|
||||||
|
|
||||||
# it 'should block messages from unallowed tenant ids', ->
|
it 'should allow messages with tenant id when tenant filter is empty', ->
|
||||||
# # Setup
|
# Setup
|
||||||
# process.env.HUBOT_OFFICE365_TENANT_FILTER = event.sourceEvent.tenant.id
|
teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
||||||
# event.sourceEvent.tenant.id = "different-tenant-id"
|
|
||||||
# teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
|
||||||
|
|
||||||
# # Action
|
# Action
|
||||||
# receivable = null
|
expect(() ->
|
||||||
# expect(() ->
|
teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb)
|
||||||
# receivable = teamsMiddleware.toReceivable(event, cb)
|
).to.not.throw()
|
||||||
# ).to.not.throw()
|
|
||||||
|
|
||||||
# # Assert
|
# Assert
|
||||||
# expect(receivable).to.be.null
|
result = robot.brain.get("event")
|
||||||
|
expect(result).to.be.a('Object')
|
||||||
|
|
||||||
# it 'return generic message when appropriate type is not found', ->
|
it 'should allow messages from allowed tenant ids', ->
|
||||||
# # Setup
|
# Setup
|
||||||
# event.type = 'typing'
|
process.env.HUBOT_OFFICE365_TENANT_FILTER = event.sourceEvent.tenant.id
|
||||||
# teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
||||||
|
|
||||||
# # Action
|
# Action
|
||||||
# receivable = null
|
expect(() ->
|
||||||
# expect(() ->
|
teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb)
|
||||||
# receivable = teamsMiddleware.toReceivable(event, cb)
|
).to.not.throw()
|
||||||
# ).to.not.throw()
|
|
||||||
|
|
||||||
# # Assert
|
# Assert
|
||||||
# expect(receivable).to.be.not.null
|
result = robot.brain.get("event")
|
||||||
|
expect(result).to.be.a('Object')
|
||||||
|
|
||||||
# it 'should work when activity text is an object', ->
|
it 'should block messages from unallowed tenant ids', ->
|
||||||
# # Setup
|
# Setup
|
||||||
# event.text = event
|
process.env.HUBOT_OFFICE365_TENANT_FILTER = event.sourceEvent.tenant.id
|
||||||
# teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
event.sourceEvent.tenant.id = "different-tenant-id"
|
||||||
|
teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
||||||
|
|
||||||
# # Action
|
# Action
|
||||||
# receivable = null
|
expect(() ->
|
||||||
# expect(() ->
|
teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb)
|
||||||
# receivable = teamsMiddleware.toReceivable(event, cb)
|
).to.not.throw()
|
||||||
# ).to.not.throw()
|
|
||||||
|
|
||||||
# # Assert
|
# Assert
|
||||||
# expect(receivable.text).to.equal(event)
|
result = robot.brain.get("event")
|
||||||
|
expect(result).to.be.null
|
||||||
|
|
||||||
|
it 'return generic message when appropriate type is not found', ->
|
||||||
|
# Setup
|
||||||
|
event.type = 'typing'
|
||||||
|
teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
||||||
|
|
||||||
|
# Action
|
||||||
|
expect(() ->
|
||||||
|
teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb)
|
||||||
|
).to.not.throw()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
result = robot.brain.get("event")
|
||||||
|
expect(result).to.be.not.null
|
||||||
|
|
||||||
|
# Test when message is from follow up button
|
||||||
|
it 'should work when activity value contains query parts', ->
|
||||||
|
# Setup
|
||||||
|
|
||||||
|
|
||||||
|
# Action
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
|
||||||
|
|
||||||
|
it 'should work when activity text is an object', ->
|
||||||
|
# Setup
|
||||||
|
event.text = event
|
||||||
|
teamsMiddleware = new MicrosoftTeamsMiddleware(robot)
|
||||||
|
|
||||||
|
# Action
|
||||||
|
expect(() ->
|
||||||
|
teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb)
|
||||||
|
).to.not.throw()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
result = robot.brain.get("event")
|
||||||
|
expect(result.text).to.equal(event)
|
||||||
|
|
||||||
# it 'should work when mentions not provided', ->
|
# it 'should work when mentions not provided', ->
|
||||||
# # Setup
|
# # Setup
|
||||||
|
|
Загрузка…
Ссылка в новой задаче