Improve weather routing and news API fallback

This commit is contained in:
Jacob Dubin
2026-05-11 07:15:11 -05:00
parent 0c597ebbf8
commit af2fdd230c
13 changed files with 57223 additions and 18 deletions

View File

@@ -115,6 +115,40 @@ public sealed class ProviderCachingTests
Assert.Equal(2, handler.GetCallCount("/v2/top-headlines"));
}
[Fact]
public async Task NewsApiBriefingProvider_FallsBackToEverything_WhenTopHeadlinesAreEmpty()
{
var handler = new CountingHttpMessageHandler(message =>
{
var path = message.RequestUri?.AbsolutePath ?? string.Empty;
return path switch
{
"/v2/top-headlines" => JsonResponse("""{"status":"ok","articles":[]}"""),
"/v2/everything" => JsonResponse(
"""{"status":"ok","articles":[{"title":"Robotics breakthrough announced","description":"Lab unveils a new platform.","source":{"name":"Science Daily"},"url":"https://example.com/robotics"}]}"""),
_ => new HttpResponseMessage(HttpStatusCode.NotFound)
};
});
var provider = new NewsApiBriefingProvider(
new HttpClient(handler),
new NewsApiOptions
{
ApiKey = "test-key",
DefaultCategories = ["general"],
CacheTtlSeconds = 300,
FailureCacheTtlSeconds = 30
},
NullLogger<NewsApiBriefingProvider>.Instance);
var result = await provider.GetBriefingAsync(new NewsBriefingRequest([], 3));
Assert.NotNull(result);
Assert.Single(result!.Headlines);
Assert.Equal("Robotics breakthrough announced", result.Headlines[0].Title);
Assert.Equal(2, handler.GetCallCount("/v2/top-headlines"));
Assert.Equal(1, handler.GetCallCount("/v2/everything"));
}
private static HttpResponseMessage JsonResponse(string body)
{
return new HttpResponseMessage(HttpStatusCode.OK)

View File

@@ -1458,7 +1458,7 @@ public sealed class JiboInteractionServiceTests
});
Assert.Equal("weather", decision.IntentName);
Assert.Equal("chitchat-skill", decision.SkillName);
Assert.Equal("report-skill", decision.SkillName);
Assert.NotNull(decision.SkillPayload);
Assert.Contains("cat='weather'", decision.SkillPayload!["esml"]?.ToString(), StringComparison.OrdinalIgnoreCase);
Assert.Contains("meta='rain'", decision.SkillPayload["esml"]?.ToString(), StringComparison.OrdinalIgnoreCase);
@@ -1667,7 +1667,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal(expectedLocationQuery, provider.LastRequest!.LocationQuery);
Assert.Equal(expectedForecastOffset, provider.LastRequest.ForecastDayOffset);
Assert.Equal(expectedIsTomorrow, provider.LastRequest.IsTomorrow);
Assert.Equal("chitchat-skill", decision.SkillName);
Assert.Equal("report-skill", decision.SkillName);
Assert.Equal(true, decision.SkillPayload?["weather_view_enabled"]);
}
@@ -1795,8 +1795,12 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("weather", decision.IntentName);
Assert.Equal("Seattle", provider.LastRequest?.LocationQuery);
Assert.Equal(2, provider.LastRequest?.ForecastDayOffset);
Assert.Equal("Later this week in Seattle, US, expect light rain with a high near 61 degrees Fahrenheit and a low around 52 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal(5, provider.LastRequest?.ForecastDayOffset);
Assert.Equal(5, provider.Requests.Count);
Assert.Contains("rest of this week's forecast", decision.ReplyText, StringComparison.OrdinalIgnoreCase);
Assert.Contains("Tuesday: light rain, high 61, low 52.", decision.ReplyText, StringComparison.OrdinalIgnoreCase);
Assert.Contains("Saturday: light rain, high 61, low 52.", decision.ReplyText, StringComparison.OrdinalIgnoreCase);
Assert.Contains("Temperatures are in Fahrenheit.", decision.ReplyText, StringComparison.OrdinalIgnoreCase);
}
[Fact]
@@ -3024,6 +3028,7 @@ public sealed class JiboInteractionServiceTests
private sealed class CapturingWeatherReportProvider : IWeatherReportProvider
{
public WeatherReportRequest? LastRequest { get; private set; }
public List<WeatherReportRequest> Requests { get; } = [];
public WeatherReportSnapshot? Snapshot { get; init; }
@@ -3032,6 +3037,7 @@ public sealed class JiboInteractionServiceTests
CancellationToken cancellationToken = default)
{
LastRequest = request;
Requests.Add(request);
return Task.FromResult(Snapshot);
}
}

View File

@@ -2198,8 +2198,15 @@ public sealed class JiboWebSocketServiceTests
Assert.True(replies.Count >= 3);
Assert.Equal("LISTEN", ReadReplyType(replies[0]));
Assert.Equal("EOS", ReadReplyType(replies[1]));
Assert.Contains(replies, static reply => string.Equals(ReadReplyType(reply), "SKILL_REDIRECT", StringComparison.Ordinal));
Assert.Contains(replies, static reply => string.Equals(ReadReplyType(reply), "SKILL_ACTION", StringComparison.Ordinal));
using var listenPayload = JsonDocument.Parse(replies[0].Text!);
Assert.Equal(
"report-skill",
listenPayload.RootElement.GetProperty("data").GetProperty("nlu").GetProperty("skill").GetString());
Assert.Equal("weather", listenPayload.RootElement.GetProperty("data").GetProperty("match").GetProperty("cloudSkill").GetString());
var skillReply = replies.Last(static reply => string.Equals(ReadReplyType(reply), "SKILL_ACTION", StringComparison.Ordinal));
using var skillPayload = JsonDocument.Parse(skillReply.Text!);
Assert.Equal(