public static void BuildFailureThrowsInvalidOperation() { var mockClient = new MockLexClient(); mockClient.Get <GetBotResponse>().Status = Status.BUILDING; // Wait for the second GetBot action to set status to failed var count = 0; void onRequest(object request) { if (request is GetBotRequest && ++count == 2) { mockClient.Get <GetBotResponse>().Status = Status.FAILED; } } mockClient.OnRequest = onRequest; using (var lex = new LexNLUService(string.Empty, string.Empty, new LexSettings(), mockClient)) { var utterance = new LabeledUtterance(string.Empty, string.Empty, null); var buildFailed = new Func <Task>(() => lex.TrainAsync(new[] { utterance })); buildFailed.Should().Throw <InvalidOperationException>(); mockClient.Get <GetBotResponse>().Status = new Status("UNKNOWN"); buildFailed.Should().Throw <InvalidOperationException>(); mockClient.Get <GetBotResponse>().Status = Status.NOT_BUILT; buildFailed.Should().NotThrow <InvalidOperationException>(); } }
public static async Task DoesNotCreateIfBotExists() { var botName = Guid.NewGuid().ToString(); var mockClient = new MockLexClient(); mockClient.Set(new GetBotsResponse { Bots = new List <BotMetadata> { new BotMetadata { Name = botName, }, }, }); using (var lex = new LexNLUService(botName, string.Empty, new LexSettings(), mockClient)) { await lex.TrainAsync(Array.Empty <LabeledUtterance>()).ConfigureAwait(false); // There are at most two put bot requests, the first to create the bot, the second to build // If the bot exists, only the second put bot to build should occur. mockClient.Requests.OfType <PutBotRequest>().Count().Should().Be(1); mockClient.Requests.OfType <PutBotRequest>().First().ProcessBehavior.Should().Be(ProcessBehavior.BUILD); } }
public static void ImportFailureThrowsInvalidOperation() { var importId = Guid.NewGuid().ToString(); var failureReason = new List <string> { Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), }; var mockClient = new MockLexClient(); mockClient.Get <StartImportResponse>().ImportId = importId; mockClient.Get <StartImportResponse>().ImportStatus = ImportStatus.FAILED; mockClient.Get <GetImportResponse>().ImportId = importId; mockClient.Get <GetImportResponse>().ImportStatus = ImportStatus.FAILED; using (var lex = new LexNLUService(string.Empty, string.Empty, new LexSettings(), mockClient)) { var utterance = new LabeledUtterance(string.Empty, string.Empty, null); // Null failure reason should be okay var importFails = new Func <Task>(() => lex.TrainAsync(new[] { utterance })); importFails.Should().Throw <InvalidOperationException>().And.Message.Should().BeEmpty(); // Failure reason is concatenated in message mockClient.Get <GetImportResponse>().FailureReason = failureReason; var expectedMessage = string.Join(Environment.NewLine, failureReason); importFails.Should().Throw <InvalidOperationException>().And.Message.Should().Be(expectedMessage); } }
public static async Task ReplacesCorrectTokensInSampleUtterances( string text, string entityMatch, string entityTypeName, int matchIndex, string sampleUtterance) { var intent = Guid.NewGuid().ToString(); var mockClient = new MockLexClient(); var slot = CreateSlot(entityTypeName, entityTypeName); var lexSettings = new LexSettings(new JArray { slot }); using (var lex = new LexNLUService(string.Empty, string.Empty, lexSettings, mockClient)) { var entity = new Entity(entityTypeName, string.Empty, entityMatch, matchIndex); var utterance = new LabeledUtterance(text, intent, new[] { entity }); await lex.TrainAsync(new[] { utterance }).ConfigureAwait(false); var startImportRequest = mockClient.Requests.OfType <StartImportRequest>().FirstOrDefault(); var payloadJson = GetPayloadJson(startImportRequest.Payload); var payload = JObject.Parse(payloadJson); // assert template utterance is set payload.SelectToken(".resource.intents[0].sampleUtterances").Count().Should().Be(1); payload.SelectToken(".resource.intents[0].sampleUtterances[0]").Value <string>().Should().Be(sampleUtterance); } }
public static void MissingEntityMatchInTextThrowsInvalidOperation() { var text = "foo"; var match = "bar"; using (var service = new LexNLUService(string.Empty, string.Empty, new LexSettings(), new MockLexClient())) { var entity = new Entity(string.Empty, string.Empty, match, 0); var utterance = new LabeledUtterance(text, string.Empty, new[] { entity }); var invalidEntityMatch = new Func <Task>(() => service.TrainAsync(new[] { utterance })); invalidEntityMatch.Should().Throw <InvalidOperationException>(); } }
public static void ThrowsArgumentNull() { var nullBotName = new Action(() => new LexNLUService(null, string.Empty, null, default(ILexClient))); var nullBotAlias = new Action(() => new LexNLUService(string.Empty, null, null, default(ILexClient))); var nullLexSettings = new Action(() => new LexNLUService(string.Empty, string.Empty, null, default(ILexClient))); var nullLexClient = new Action(() => new LexNLUService(string.Empty, string.Empty, new LexSettings(), default(ILexClient))); nullBotName.Should().Throw <ArgumentNullException>().And.ParamName.Should().Be("botName"); nullBotAlias.Should().Throw <ArgumentNullException>().And.ParamName.Should().Be("botAlias"); nullLexSettings.Should().Throw <ArgumentNullException>().And.ParamName.Should().Be("lexSettings"); nullLexClient.Should().Throw <ArgumentNullException>().And.ParamName.Should().Be("lexClient"); using (var service = new LexNLUService(string.Empty, string.Empty, new LexSettings(), new MockLexClient())) { var nullUtterances = new Func <Task>(() => service.TrainAsync(null)); var nullUtteranceItem = new Func <Task>(() => service.TrainAsync(new LabeledUtterance[] { null })); var nullSpeechFile = new Func <Task>(() => service.TestSpeechAsync(null)); var nullTestUtterance = new Func <Task>(() => service.TestAsync(null)); nullUtterances.Should().Throw <ArgumentNullException>().And.ParamName.Should().Be("utterances"); nullUtteranceItem.Should().Throw <ArgumentException>().And.ParamName.Should().Be("utterances"); nullSpeechFile.Should().Throw <ArgumentNullException>().And.ParamName.Should().Be("speechFile"); nullTestUtterance.Should().Throw <ArgumentNullException>().And.ParamName.Should().Be("utterance"); } }
public static async Task WaitsForImportCompletion() { var importId = Guid.NewGuid().ToString(); var mockClient = new MockLexClient(); mockClient.Get <StartImportResponse>().ImportId = importId; mockClient.Get <StartImportResponse>().ImportStatus = ImportStatus.IN_PROGRESS; mockClient.Get <GetImportResponse>().ImportId = importId; mockClient.Get <GetImportResponse>().ImportStatus = ImportStatus.IN_PROGRESS; // Wait for the second GetImport action to set status to complete var count = 0; void onRequest(object request) { if (request is GetImportRequest && ++count == 2) { mockClient.Get <GetImportResponse>().ImportStatus = ImportStatus.COMPLETE; } } mockClient.OnRequest = onRequest; using (var lex = new LexNLUService(string.Empty, string.Empty, new LexSettings(), mockClient)) { var utterance = new LabeledUtterance(string.Empty, string.Empty, null); await lex.TrainAsync(new[] { utterance }).ConfigureAwait(false); // Assert two GetImport actions occur mockClient.Requests.OfType <GetImportRequest>().Count().Should().Be(2); // Assert that the time difference is at least two seconds var requests = mockClient.TimestampedRequests .Where(tuple => tuple.Item1 is GetImportRequest) .Select(tuple => new { Request = (GetImportRequest)tuple.Item1, Timestamp = tuple.Item2 }) .ToArray(); var difference = requests[1].Timestamp - requests[0].Timestamp; difference.Should().BeGreaterThan(TimeSpan.FromSeconds(2) - Epsilon); } }
public static async Task CreatesBot() { var text = "hello world"; var intent = Guid.NewGuid().ToString(); var entityTypeName = "Planet"; var botName = Guid.NewGuid().ToString(); var mockClient = new MockLexClient(); var slot = CreateSlot(entityTypeName, entityTypeName); var lexSettings = new LexSettings(new JArray { slot }); using (var lex = new LexNLUService(botName, string.Empty, lexSettings, mockClient)) { var entity = new Entity(entityTypeName, "Earth", "world", 0); var utterance = new LabeledUtterance(text, intent, new[] { entity }); await lex.TrainAsync(new[] { utterance }).ConfigureAwait(false); // get StartImport request var startImportRequest = mockClient.Requests.OfType <StartImportRequest>().FirstOrDefault(); startImportRequest.Should().NotBeNull(); // get payload var payloadJson = GetPayloadJson(startImportRequest.Payload); payloadJson.Should().NotBeNull().And.NotBeEmpty(); var payload = JObject.Parse(payloadJson); // assert name is set payload.SelectToken(".resource.name").Value <string>().Should().Be(botName); // assert intent is created payload.SelectToken(".resource.intents").Count().Should().Be(1); payload.SelectToken(".resource.intents[0].name").Value <string>().Should().Be(intent); // assert template utterance is set payload.SelectToken(".resource.intents[0].sampleUtterances").Count().Should().Be(1); payload.SelectToken(".resource.intents[0].sampleUtterances[0]").Value <string>().Should().Be("hello {Planet}"); // assert slot is created in intent payload.SelectToken(".resource.intents[0].slots").Count().Should().Be(1); payload.SelectToken(".resource.intents[0].slots[0].name").Value <string>().Should().Be(entityTypeName); payload.SelectToken(".resource.intents[0].slots[0].slotType").Value <string>().Should().Be(entityTypeName); } }
public static async Task WaitsForBuildCompletion() { var mockClient = new MockLexClient(); mockClient.Get <GetBotResponse>().Status = Status.BUILDING; // Wait for the third GetBot action to set status to complete var count = 0; void onRequest(object request) { if (request is GetBotRequest && ++count == 3) { mockClient.Get <GetBotResponse>().Status = Status.READY; } } mockClient.OnRequest = onRequest; using (var lex = new LexNLUService(string.Empty, string.Empty, new LexSettings(), mockClient)) { var utterance = new LabeledUtterance(string.Empty, string.Empty, null); await lex.TrainAsync(new[] { utterance }).ConfigureAwait(false); // Assert three GetBot actions occur mockClient.Requests.OfType <GetBotRequest>().Count().Should().Be(3); // Assert that the time difference is at least two seconds var requests = mockClient.TimestampedRequests .Where(tuple => tuple.Item1 is GetBotRequest) .Select(tuple => new { Request = (GetBotRequest)tuple.Item1, Timestamp = tuple.Item2 }) .ToArray(); var difference = requests[2].Timestamp - requests[1].Timestamp; difference.Should().BeGreaterThan(TimeSpan.FromSeconds(2) - Epsilon); } }
public static async Task DoesNotPublishIfAliasExists() { var botAlias = Guid.NewGuid().ToString(); var mockClient = new MockLexClient(); mockClient.Set(new GetBotAliasesResponse { BotAliases = new List <BotAliasMetadata> { new BotAliasMetadata { Name = botAlias, }, }, }); using (var lex = new LexNLUService(string.Empty, botAlias, new LexSettings(), mockClient)) { await lex.TrainAsync(Array.Empty <LabeledUtterance>()).ConfigureAwait(false); // If the bot alias exists, the 'PutBotAlias' request should not occur mockClient.Requests.OfType <PutBotAliasRequest>().Count().Should().Be(0); } }
public static async Task DoesNotOverwriteIntent() { var canary = Guid.NewGuid().ToString(); var intentName = Guid.NewGuid().ToString(); var entityTypeName = Guid.NewGuid().ToString(); var existingUtterance = Guid.NewGuid().ToString(); var existingSlot = new JObject { { "name", entityTypeName }, { "slotType", canary }, }; var existingIntent = new JObject { { "name", intentName }, { "canary", canary }, { "sampleUtterances", new JArray { existingUtterance } }, { "slots", new JArray { existingSlot } }, }; var importBotTemplate = new JObject { { "resource", new JObject { { "intents", new JArray { existingIntent } }, } } }; var mockClient = new MockLexClient(); var slot = CreateSlot(entityTypeName, Guid.NewGuid().ToString()); var lexSettings = new LexSettings(new JArray { slot }, importBotTemplate); using (var lex = new LexNLUService(string.Empty, string.Empty, lexSettings, mockClient)) { var text = Guid.NewGuid().ToString(); var entity = new Entity(entityTypeName, null, text, 0); var utterance = new LabeledUtterance(text, intentName, new[] { entity }); await lex.TrainAsync(new[] { utterance }).ConfigureAwait(false); // get StartImport request var startImportRequest = mockClient.Requests.OfType <StartImportRequest>().FirstOrDefault(); startImportRequest.Should().NotBeNull(); // get payload var payloadJson = GetPayloadJson(startImportRequest.Payload); payloadJson.Should().NotBeNull().And.NotBeEmpty(); var payload = JObject.Parse(payloadJson); // get intent var intents = payload.SelectTokens($".resource.intents[?(@.name == '{intentName}')]"); intents.Count().Should().Be(1); intents.First().Value <string>("canary").Should().Be(canary); intents.First().SelectToken(".sampleUtterances").Count().Should().Be(2); intents.First().SelectToken(".sampleUtterances").Should().Contain(u => u.Value <string>() == existingUtterance); intents.First().SelectToken(".sampleUtterances").Should().Contain(u => u.Value <string>() == $"{{{entityTypeName}}}"); intents.First().SelectToken(".slots").Count().Should().Be(1); intents.First().SelectToken(".slots").First().Value <string>("slotType").Should().Be(canary); intents.First().SelectToken(".slots").First().Value <string>("slotConstraint").Should().Be("Optional"); } }