Teste de integração usando Bot Framework e DirectLine (2)
Nesta parte faremos a autorização DirectLine e obteremos os valores da resposta do bot.
Agora que fizemos a desserialização, é hora de pegar as informações da coleção e os inteiros que usaremos para obter a autorização, fazer as chamadas da API e afirmar o resultado.
A explicação a seguir não cobrirá todas as informações básicas de como funciona o Bot Framework. Se você não entender, consulte a documentação oficial.
Fazendo chamadas de API usando WebClient
Para facilitar a chamada da api, criei uma classe utils, onde salvamos as funções que usaremos algumas vezes, essa classe inclui uploadString para POST e downloadString para GET.
public class Utils
{
/// <summary>
/// Uploads to an URL and gets result
/// </summary>
/// <typeparam name="T">Type of object you are receiving</typeparam>
/// <param name="bearer">Token</param>
/// <param name="url">Url</param>
/// <param name="serializedJson">Serialized JSON to send</param>
/// <returns></returns>
public static T uploadString<T>(string bearer, string url, string serializedJson)
{
string serializedResult = "";
/// Webclient
using (var client = new WebClient())
{
/// Add headers
client.Headers.Add("Content-Type", "application/json");
client.Headers.Add("Authorization", $"Bearer {bearer}");
/// Upload string
serializedResult = client.UploadString(url, serializedJson);
}
/// Get result and return it as an object
return JsonConvert.DeserializeObject<T>(serializedResult);
}
/// <summary>
/// Downloads from URL
/// </summary>
/// <typeparam name="T">Type of object you are receiving</typeparam>
/// <param name="bearer">Token</param>
/// <param name="url">Url</param>
/// <returns></returns>
public static T downloadString<T>(string bearer, string url)
{
string serializedResult = "";
/// Webclient
using (var client = new WebClient())
{
/// Add headers
client.Headers.Add("Content-Type", "application/json");
client.Headers.Add("Authorization", $"Bearer {bearer}");
/// Download string
serializedResult = client.DownloadString(url);
}
/// Get result and return it as an object
return JsonConvert.DeserializeObject<T>(serializedResult);
}
}
Autorização DirectLine
Se você ler a documentação oficial, poderá descobrir como fazer, e é bem fácil, usando nossas funções é ainda mais fácil. Primeiramente lembre-se que estamos dentro da instrução foreach, pois estamos fazendo a autenticação para cada caso, caso o tempo acabe, o que significará que o teste falhará.
/// Arrange with current requested values
string token, newToken, conversationId;
/// Act
/// 1 - Get token using secret from DirectLine in BotFramework panel
token = Utils.uploadString<DirectLineAuth>(data.Secret, data.DirectLineGenerateTokenEndpoint, "").token;
Agora temos o token, que será usado para fazer todas as chamadas seguintes para o endpoint da conversa.
Criando uma conversa.
Para falar com o bot, primeiro precisamos criar uma conversa, esta conversa retornará um novo token que inclui o id da conversa.
/// 2 -Create a new conversation
var createdConversation = Utils.uploadString<DirectLineAuth>(token, data.DirectLineConversationEndpoint, "");
// This returns a new token and a conversationId
newToken = createdConversation.token;
conversationId = createdConversation.conversationId;
Além disso, armazenamos newToken e conversationId, ambos serão necessários para o usuário enviar mensagens ao bot.
Enviar atividade para conversa
Agora, com o conversationId e o conversationEndpoint, podemos criar o endpoint final para enviar um Activity que é o request do arquivo json.
/// 3 - Send an activity to the conversation with new token and conversationId
string directlineConversationActivitiesEndpoint = data.DirectLineConversationEndpoint + conversationId + "/activities";
Utils.uploadString<DirectLineAuth>(newToken, directlineConversationActivitiesEndpoint, JsonConvert.SerializeObject(entry.Request));
Receba a última mensagem
No histórico de mensagens, depois de enviarmos a atividade, o bot já deveria ter respondido, então temos que pegar todas as mensagens com a marca d’água e então usando essa marca d’água, filtrar a última mensagem/atividade.
/// 4 - Get all activities, we get a List<activity> and a watermark
var getLastActivity = Utils.downloadString<ActivityResponse>(newToken, directlineConversationActivitiesEndpoint);
/// 5 - Get the latest activity which is the response we should be expecting
var latestResponse = getLastActivity.activities[Int32.Parse(getLastActivity.watermark)];
E isso é tudo por esta parte, a próxima parte incluirá a parte onde obtemos o texto do assert no json, convertemos para código como usar eval() em Javascript, mas em C#, e então usando o Assert.isTrue() para obter o resultado final do teste.
Lembre-se de que todo o código está armazenado em meu github em este repositório.