Skip to content

Commit

Permalink
add calendar test (microsoft#266)
Browse files Browse the repository at this point in the history
* add calendar test

* update mock event time

* fix comments and warnings

* fix comments

* merge master conficts

* remove functions to keep consistent with email ut

* remove duplicate code for ut

* fix comments

* remove feature code only for test

* rename files

* rename file
  • Loading branch information
neolone authored Nov 19, 2018
1 parent c40c6b5 commit 3a9c952
Show file tree
Hide file tree
Showing 34 changed files with 1,514 additions and 138 deletions.
7 changes: 7 additions & 0 deletions solutions/Virtual-Assistant/src/csharp/VirtualAssistant.sln
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{DFCBFFD7
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Solutions.Tests", "tests\Microsoft.Bot.Solutions.Tests\Microsoft.Bot.Solutions.Tests.csproj", "{18366252-CEA5-4FB9-A022-ED957B491237}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalendarSkillTest", "skills\tests\calendarskilltest\CalendarSkillTest.csproj", "{F67AE5B4-DC61-4C96-947B-87D054191734}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ToDoSkillTest", "skills\tests\todoskilltest\ToDoSkillTest.csproj", "{A69DA245-0C5C-4017-9227-3762E5393879}"
EndProject
Global
Expand Down Expand Up @@ -77,6 +79,10 @@ Global
{18366252-CEA5-4FB9-A022-ED957B491237}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18366252-CEA5-4FB9-A022-ED957B491237}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18366252-CEA5-4FB9-A022-ED957B491237}.Release|Any CPU.Build.0 = Release|Any CPU
{F67AE5B4-DC61-4C96-947B-87D054191734}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F67AE5B4-DC61-4C96-947B-87D054191734}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F67AE5B4-DC61-4C96-947B-87D054191734}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F67AE5B4-DC61-4C96-947B-87D054191734}.Release|Any CPU.Build.0 = Release|Any CPU
{A69DA245-0C5C-4017-9227-3762E5393879}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A69DA245-0C5C-4017-9227-3762E5393879}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A69DA245-0C5C-4017-9227-3762E5393879}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -94,6 +100,7 @@ Global
{1B4F6C4B-C813-476D-84C5-D9FD51678065} = {546AC410-598F-49FD-9583-F912DF35BDA5}
{699BA894-1429-4DB8-ABF6-826E3F143F49} = {546AC410-598F-49FD-9583-F912DF35BDA5}
{18366252-CEA5-4FB9-A022-ED957B491237} = {DFCBFFD7-4882-4C3B-9E21-83EE29CE59BF}
{F67AE5B4-DC61-4C96-947B-87D054191734} = {546AC410-598F-49FD-9583-F912DF35BDA5}
{A69DA245-0C5C-4017-9227-3762E5393879} = {546AC410-598F-49FD-9583-F912DF35BDA5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ namespace CalendarSkill
/// </summary>
public class CalendarSkill : IBot
{
private readonly SkillConfiguration _services;
private readonly ISkillConfiguration _services;
private readonly UserState _userState;
private readonly ConversationState _conversationState;
private readonly IServiceManager _serviceManager;
private DialogSet _dialogs;
private bool _skillMode;
private DialogSet _dialogs;

public CalendarSkill(SkillConfiguration services, ConversationState conversationState, UserState userState, IServiceManager serviceManager = null, bool skillMode = false)
public CalendarSkill(ISkillConfiguration services, ConversationState conversationState, UserState userState, IServiceManager serviceManager = null, bool skillMode = false)
{
_skillMode = skillMode;
_services = services ?? throw new ArgumentNullException(nameof(services));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using CalendarSkill.Dialogs.CreateEvent.Resources;
using CalendarSkill.Dialogs.Shared.Resources;
using CalendarSkill.Extensions;
using CalendarSkill.ServiceClients;
using Luis;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Dialogs;
Expand All @@ -25,7 +26,7 @@ namespace CalendarSkill
public class CreateEventDialog : CalendarSkillDialog
{
public CreateEventDialog(
SkillConfiguration services,
ISkillConfiguration services,
IStatePropertyAccessor<CalendarSkillState> accessor,
IServiceManager serviceManager)
: base(nameof(CreateEventDialog), services, accessor, serviceManager)
Expand Down Expand Up @@ -158,7 +159,9 @@ public CreateEventDialog(
return await sc.EndDialogAsync(true, cancellationToken);
}

ServiceManager.InitCalendarService(state.APIToken, state.EventSource);
var calendarAPI = GraphClientHelper.GetCalendarService(state.APIToken, state.EventSource, ServiceManager.GetGoogleClient());
ServiceManager.InitCalendarService(calendarAPI, state.EventSource);

if (state.Attendees.Count == 0)
{
return await sc.BeginDialogAsync(Actions.UpdateAddress, cancellationToken: cancellationToken);
Expand Down Expand Up @@ -338,7 +341,8 @@ public CreateEventDialog(
TimeZone = TimeZoneInfo.Utc,
Location = state.Location,
};
var calendarService = ServiceManager.InitCalendarService(state.APIToken, state.EventSource);
var calendarAPI = GraphClientHelper.GetCalendarService(state.APIToken, state.EventSource, ServiceManager.GetGoogleClient());
var calendarService = ServiceManager.InitCalendarService(calendarAPI, state.EventSource);
if (await calendarService.CreateEvent(newEvent) != null)
{
var replyMessage = sc.Context.Activity.CreateAdaptiveCardReply(CreateEventResponses.EventCreated, newEvent.OnlineMeetingUrl == null ? "Dialogs/Shared/Resources/Cards/CalendarCardNoJoinButton.json" : "Dialogs/Shared/Resources/Cards/CalendarCard.json", newEvent.ToAdaptiveCardData(state.GetUserTimeZone()));
Expand Down Expand Up @@ -871,7 +875,8 @@ public async Task<List<Person>> GetUserAsync(WaterfallStepContext sc, string nam
try
{
var token = state.APIToken;
var service = ServiceManager.InitUserService(token, state.GetUserTimeZone());
IGraphServiceClient serviceClient = GraphClientHelper.GetAuthenticatedClient(token, state.GetUserTimeZone());
var service = ServiceManager.InitUserService(serviceClient, state.GetUserTimeZone());

// Get users.
var userList = await service.GetUserAsync(name);
Expand All @@ -888,50 +893,71 @@ public async Task<List<Person>> GetUserAsync(WaterfallStepContext sc, string nam
return result;
}

protected async Task<List<Person>> GetPeopleWorkWithAsync(WaterfallStepContext sc, string name)
protected static (List<Person> formattedPersonList, List<Person> formattedUserList) FormatRecipientList(List<Person> personList, List<Person> userList)
{
var result = new List<Person>();
try
{
var state = await Accessor.GetAsync(sc.Context);
var token = state.APIToken;
var service = ServiceManager.InitUserService(token, state.GetUserTimeZone());
// Remove dup items
List<Person> formattedPersonList = new List<Person>();
List<Person> formattedUserList = new List<Person>();

// Get users.
result = await service.GetPeopleAsync(name);
}
catch (Exception ex)
foreach (var person in personList)
{
await HandleDialogExceptions(sc);
throw ex;
}
var mailAddress = person.ScoredEmailAddresses.FirstOrDefault()?.Address ?? person.UserPrincipalName;

return result;
}
bool isDup = false;
foreach (var formattedPerson in formattedPersonList)
{
var formattedMailAddress = formattedPerson.ScoredEmailAddresses.FirstOrDefault()?.Address ?? formattedPerson.UserPrincipalName;

protected async Task<List<Person>> GetContactsAsync(WaterfallStepContext sc, string name)
{
var result = new List<Person>();
try
{
var state = await Accessor.GetAsync(sc.Context);
var token = state.APIToken;
var service = ServiceManager.InitUserService(token, state.GetUserTimeZone());
if (mailAddress.Equals(formattedMailAddress))
{
isDup = true;
break;
}
}

// Get users.
var contactList = await service.GetContactsAsync(name);
foreach (var contact in contactList)
if (!isDup)
{
result.Add(contact.ToPerson());
formattedPersonList.Add(person);
}
}
catch (Exception ex)

foreach (var user in userList)
{
await HandleDialogExceptions(sc);
throw ex;
var mailAddress = user.ScoredEmailAddresses.FirstOrDefault()?.Address ?? user.UserPrincipalName;

bool isDup = false;
foreach (var formattedPerson in formattedPersonList)
{
var formattedMailAddress = formattedPerson.ScoredEmailAddresses.FirstOrDefault()?.Address ?? formattedPerson.UserPrincipalName;

if (mailAddress.Equals(formattedMailAddress))
{
isDup = true;
break;
}
}

if (!isDup)
{
foreach (var formattedUser in formattedUserList)
{
var formattedMailAddress = formattedUser.ScoredEmailAddresses.FirstOrDefault()?.Address ?? formattedUser.UserPrincipalName;

if (mailAddress.Equals(formattedMailAddress))
{
isDup = true;
break;
}
}
}

if (!isDup)
{
formattedUserList.Add(user);
}
}

return result;
return (formattedPersonList, formattedUserList);
}

protected async Task<PromptOptions> GenerateOptions(List<Person> personList, List<Person> userList, DialogContext dc)
Expand Down Expand Up @@ -1024,75 +1050,55 @@ protected async Task<PromptOptions> GenerateOptions(List<Person> personList, Lis
return options;
}

protected static (List<Person> formattedPersonList, List<Person> formattedUserList) FormatRecipientList(List<Person> personList, List<Person> userList)
protected async Task<List<Person>> GetContactsAsync(WaterfallStepContext sc, string name)
{
// Remove dup items
List<Person> formattedPersonList = new List<Person>();
List<Person> formattedUserList = new List<Person>();

foreach (var person in personList)
var result = new List<Person>();
try
{
var mailAddress = person.ScoredEmailAddresses.FirstOrDefault()?.Address ?? person.UserPrincipalName;

bool isDup = false;
foreach (var formattedPerson in formattedPersonList)
{
var formattedMailAddress = formattedPerson.ScoredEmailAddresses.FirstOrDefault()?.Address ?? formattedPerson.UserPrincipalName;

if (mailAddress.Equals(formattedMailAddress))
{
isDup = true;
break;
}
}
var state = await Accessor.GetAsync(sc.Context);
var token = state.APIToken;
IGraphServiceClient serviceClient = GraphClientHelper.GetAuthenticatedClient(token, state.GetUserTimeZone());
var service = ServiceManager.InitUserService(serviceClient, state.GetUserTimeZone());

if (!isDup)
// Get users.
var contactList = await service.GetContactsAsync(name);
foreach (var contact in contactList)
{
formattedPersonList.Add(person);
result.Add(contact.ToPerson());
}
}

foreach (var user in userList)
catch (Exception ex)
{
var mailAddress = user.ScoredEmailAddresses.FirstOrDefault()?.Address ?? user.UserPrincipalName;

bool isDup = false;
foreach (var formattedPerson in formattedPersonList)
{
var formattedMailAddress = formattedPerson.ScoredEmailAddresses.FirstOrDefault()?.Address ?? formattedPerson.UserPrincipalName;

if (mailAddress.Equals(formattedMailAddress))
{
isDup = true;
break;
}
}
await HandleDialogExceptions(sc);
throw ex;
}

if (!isDup)
{
foreach (var formattedUser in formattedUserList)
{
var formattedMailAddress = formattedUser.ScoredEmailAddresses.FirstOrDefault()?.Address ?? formattedUser.UserPrincipalName;
return result;
}

if (mailAddress.Equals(formattedMailAddress))
{
isDup = true;
break;
}
}
}
protected async Task<List<Person>> GetPeopleWorkWithAsync(WaterfallStepContext sc, string name)
{
var result = new List<Person>();
try
{
var state = await Accessor.GetAsync(sc.Context);
var token = state.APIToken;
IGraphServiceClient serviceClient = GraphClientHelper.GetAuthenticatedClient(token, state.GetUserTimeZone());
var service = ServiceManager.InitUserService(serviceClient, state.GetUserTimeZone());

if (!isDup)
{
formattedUserList.Add(user);
}
// Get users.
result = await service.GetPeopleAsync(name);
}
catch (Exception ex)
{
await HandleDialogExceptions(sc);
throw ex;
}

return (formattedPersonList, formattedUserList);
return result;
}


public string GetSelectPromptString(PromptOptions selectOption, bool containNumbers)
private string GetSelectPromptString(PromptOptions selectOption, bool containNumbers)
{
var result = string.Empty;
result += selectOption.Prompt.Text + "\r\n";
Expand All @@ -1102,7 +1108,7 @@ public string GetSelectPromptString(PromptOptions selectOption, bool containNumb
result += " ";
if (containNumbers)
{
result += i + 1 + "-";
result += (i + 1) + "-";
}

result += choice.Value + "\r\n";
Expand All @@ -1111,7 +1117,7 @@ public string GetSelectPromptString(PromptOptions selectOption, bool containNumb
return result;
}

public bool IsEmail(string emailString)
private bool IsEmail(string emailString)
{
return Regex.IsMatch(emailString, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using CalendarSkill.Dialogs.DeleteEvent.Resources;
using CalendarSkill.Dialogs.Main.Resources;
using CalendarSkill.Dialogs.Shared.Resources;
using CalendarSkill.ServiceClients;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Dialogs.Choices;
Expand All @@ -19,7 +20,7 @@ namespace CalendarSkill
public class DeleteEventDialog : CalendarSkillDialog
{
public DeleteEventDialog(
SkillConfiguration services,
ISkillConfiguration services,
IStatePropertyAccessor<CalendarSkillState> accessor,
IServiceManager serviceManager)
: base(nameof(DeleteEventDialog), services, accessor, serviceManager)
Expand Down Expand Up @@ -81,7 +82,8 @@ public DeleteEventDialog(
try
{
var state = await Accessor.GetAsync(sc.Context);
var calendarService = ServiceManager.InitCalendarService(state.APIToken, state.EventSource);
var calendarAPI = GraphClientHelper.GetCalendarService(state.APIToken, state.EventSource, ServiceManager.GetGoogleClient());
var calendarService = ServiceManager.InitCalendarService(calendarAPI, state.EventSource);
var confirmResult = (bool)sc.Result;
if (confirmResult)
{
Expand Down Expand Up @@ -115,7 +117,8 @@ public DeleteEventDialog(
return await sc.EndDialogAsync(true);
}

var calendarService = ServiceManager.InitCalendarService(state.APIToken, state.EventSource);
var calendarAPI = GraphClientHelper.GetCalendarService(state.APIToken, state.EventSource, ServiceManager.GetGoogleClient());
var calendarService = ServiceManager.InitCalendarService(calendarAPI, state.EventSource);
if (state.StartDateTime == null)
{
return await sc.BeginDialogAsync(Actions.UpdateStartTime, new UpdateDateTimeDialogOptions(UpdateDateTimeDialogOptions.UpdateReason.NotFound));
Expand Down Expand Up @@ -172,7 +175,8 @@ public DeleteEventDialog(
var state = await Accessor.GetAsync(sc.Context);
var events = new List<EventModel>();

var calendarService = ServiceManager.InitCalendarService(state.APIToken, state.EventSource);
var calendarAPI = GraphClientHelper.GetCalendarService(state.APIToken, state.EventSource, ServiceManager.GetGoogleClient());
var calendarService = ServiceManager.InitCalendarService(calendarAPI, state.EventSource);

if (state.StartDate != null || state.StartTime != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ namespace CalendarSkill
public class MainDialog : RouterDialog
{
private bool _skillMode;
private SkillConfiguration _services;
private ISkillConfiguration _services;
private UserState _userState;
private ConversationState _conversationState;
private IServiceManager _serviceManager;
private IStatePropertyAccessor<CalendarSkillState> _stateAccessor;
private CalendarSkillResponseBuilder _responseBuilder = new CalendarSkillResponseBuilder();

public MainDialog(
SkillConfiguration services,
ISkillConfiguration services,
ConversationState conversationState,
UserState userState,
IServiceManager serviceManager,
Expand Down
Loading

0 comments on commit 3a9c952

Please sign in to comment.