Skip to content

Commit 8f333d2

Browse files
committed
Address PR4 reviewer feedback
1. Added LINQ Filter Verification Tests - Added 7 test methods verifying LINQ expressions produce correct Google API URLs - Tests cover equality, contains, inequality, compound filters with URL validation - Expanded test suite from 29 to 36 tests (all passing) - Addresses reviewer comment: 'Some tests to verify the filter url that is created from the different linq expressions would be good' 2. Fixed Documentation Standards - Updated all property summaries in GoogleWebPage.cs to use 'Gets or sets the' convention - Applied to all 11 properties following .NET documentation standards - Addresses reviewer comment: 'These property summaries should start with Gets or sets the to conform to the documentation standard' 3. Performance Optimization - Added static readonly s_supportedPatterns array to avoid allocations in error paths - Moved error messages from inline array allocation to static field - Addresses reviewer comment: 'Consider making this a static field on the class. No need to allocate a new array of strings for each failed invocation' 4. Code Consolidation - Extracted shared LINQ processing logic into helper methods - Eliminated duplication between ConvertLinqExpressionToGoogleFilter and CollectAndCombineFilters - Applied DRY principles throughout LINQ expression processing - Addresses reviewer comment: 'This code seems very similar to that in CollectAndCombineFilters. Can this be consolidated?' Validation: - Build: Release configuration successful - Tests: 36/36 passing - Format: dotnet format compliance verified - Regression: All existing functionality preserved Note: API design question about return type consistency deferred for architectural discussion
1 parent 7576d94 commit 8f333d2

3 files changed

Lines changed: 338 additions & 156 deletions

File tree

dotnet/src/Plugins/Plugins.UnitTests/Web/Google/GoogleTextSearchTests.cs

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,201 @@ public async Task GenericSearchWithComplexCompoundFilterReturnsSuccessfullyAsync
507507
Assert.Equal(4, resultList.Count);
508508
}
509509

510+
#region LINQ Filter Verification Tests
511+
// These tests verify that LINQ expressions produce correct Google API URL parameters
512+
// Addressing reviewer feedback: "Some tests to verify the filter url that is created from the different linq expressions would be good"
513+
514+
[Fact]
515+
public async Task LinqEqualityFilterProducesCorrectApiUrlAsync()
516+
{
517+
// Arrange
518+
this._messageHandlerStub.AddJsonResponse(File.ReadAllText(WhatIsTheSKResponseJson));
519+
520+
using var textSearch = new GoogleTextSearch(
521+
initializer: new() { ApiKey = "ApiKey", HttpClientFactory = this._clientFactory },
522+
searchEngineId: "SearchEngineId");
523+
524+
// Act - Use LINQ equality filter for DisplayLink
525+
await textSearch.SearchAsync("test",
526+
new TextSearchOptions<GoogleWebPage>
527+
{
528+
Top = 4,
529+
Skip = 0,
530+
Filter = page => page.DisplayLink == "microsoft.com"
531+
});
532+
533+
// Assert - Verify URL contains correct siteSearch parameter
534+
var requestUris = this._messageHandlerStub.RequestUris;
535+
Assert.Single(requestUris);
536+
var absoluteUri = requestUris[0]!.AbsoluteUri;
537+
Assert.Contains("siteSearch=microsoft.com", absoluteUri);
538+
Assert.Contains("siteSearchFilter=i", absoluteUri);
539+
}
540+
541+
[Fact]
542+
public async Task LinqFileFormatEqualityFilterProducesCorrectApiUrlAsync()
543+
{
544+
// Arrange
545+
this._messageHandlerStub.AddJsonResponse(File.ReadAllText(WhatIsTheSKResponseJson));
546+
547+
using var textSearch = new GoogleTextSearch(
548+
initializer: new() { ApiKey = "ApiKey", HttpClientFactory = this._clientFactory },
549+
searchEngineId: "SearchEngineId");
550+
551+
// Act - Use LINQ equality filter for FileFormat
552+
await textSearch.SearchAsync("test",
553+
new TextSearchOptions<GoogleWebPage>
554+
{
555+
Top = 4,
556+
Skip = 0,
557+
Filter = page => page.FileFormat == "pdf"
558+
});
559+
560+
// Assert - Verify URL contains correct fileType parameter
561+
var requestUris = this._messageHandlerStub.RequestUris;
562+
Assert.Single(requestUris);
563+
var absoluteUri = requestUris[0]!.AbsoluteUri;
564+
Assert.Contains("fileType=pdf", absoluteUri);
565+
}
566+
567+
[Fact]
568+
public async Task LinqContainsFilterProducesCorrectApiUrlAsync()
569+
{
570+
// Arrange
571+
this._messageHandlerStub.AddJsonResponse(File.ReadAllText(WhatIsTheSKResponseJson));
572+
573+
using var textSearch = new GoogleTextSearch(
574+
initializer: new() { ApiKey = "ApiKey", HttpClientFactory = this._clientFactory },
575+
searchEngineId: "SearchEngineId");
576+
577+
// Act - Use LINQ Contains filter for Title
578+
await textSearch.SearchAsync("test",
579+
new TextSearchOptions<GoogleWebPage>
580+
{
581+
Top = 4,
582+
Skip = 0,
583+
Filter = page => page.Title != null && page.Title.Contains("Semantic")
584+
});
585+
586+
// Assert - Verify URL contains correct orTerms parameter (Contains uses orTerms for flexibility)
587+
var requestUris = this._messageHandlerStub.RequestUris;
588+
Assert.Single(requestUris);
589+
var absoluteUri = requestUris[0]!.AbsoluteUri;
590+
Assert.Contains("orTerms=Semantic", absoluteUri);
591+
}
592+
593+
[Fact]
594+
public async Task LinqNotEqualFilterProducesCorrectApiUrlAsync()
595+
{
596+
// Arrange
597+
this._messageHandlerStub.AddJsonResponse(File.ReadAllText(WhatIsTheSKResponseJson));
598+
599+
using var textSearch = new GoogleTextSearch(
600+
initializer: new() { ApiKey = "ApiKey", HttpClientFactory = this._clientFactory },
601+
searchEngineId: "SearchEngineId");
602+
603+
// Act - Use LINQ NOT Equal filter for Title
604+
await textSearch.SearchAsync("test",
605+
new TextSearchOptions<GoogleWebPage>
606+
{
607+
Top = 4,
608+
Skip = 0,
609+
Filter = page => page.Title != "deprecated"
610+
});
611+
612+
// Assert - Verify URL contains correct excludeTerms parameter
613+
var requestUris = this._messageHandlerStub.RequestUris;
614+
Assert.Single(requestUris);
615+
var absoluteUri = requestUris[0]!.AbsoluteUri;
616+
Assert.Contains("excludeTerms=deprecated", absoluteUri);
617+
}
618+
619+
[Fact]
620+
public async Task LinqNotContainsFilterProducesCorrectApiUrlAsync()
621+
{
622+
// Arrange
623+
this._messageHandlerStub.AddJsonResponse(File.ReadAllText(WhatIsTheSKResponseJson));
624+
625+
using var textSearch = new GoogleTextSearch(
626+
initializer: new() { ApiKey = "ApiKey", HttpClientFactory = this._clientFactory },
627+
searchEngineId: "SearchEngineId");
628+
629+
// Act - Use LINQ NOT Contains filter for Snippet
630+
await textSearch.SearchAsync("test",
631+
new TextSearchOptions<GoogleWebPage>
632+
{
633+
Top = 4,
634+
Skip = 0,
635+
Filter = page => page.Snippet != null && !page.Snippet.Contains("outdated")
636+
});
637+
638+
// Assert - Verify URL contains correct excludeTerms parameter
639+
var requestUris = this._messageHandlerStub.RequestUris;
640+
Assert.Single(requestUris);
641+
var absoluteUri = requestUris[0]!.AbsoluteUri;
642+
Assert.Contains("excludeTerms=outdated", absoluteUri);
643+
}
644+
645+
[Fact]
646+
public async Task LinqCompoundAndFilterProducesCorrectApiUrlAsync()
647+
{
648+
// Arrange
649+
this._messageHandlerStub.AddJsonResponse(File.ReadAllText(WhatIsTheSKResponseJson));
650+
651+
using var textSearch = new GoogleTextSearch(
652+
initializer: new() { ApiKey = "ApiKey", HttpClientFactory = this._clientFactory },
653+
searchEngineId: "SearchEngineId");
654+
655+
// Act - Use LINQ compound AND filter
656+
await textSearch.SearchAsync("test",
657+
new TextSearchOptions<GoogleWebPage>
658+
{
659+
Top = 4,
660+
Skip = 0,
661+
Filter = page => page.DisplayLink == "microsoft.com" && page.FileFormat == "pdf"
662+
});
663+
664+
// Assert - Verify URL contains both parameters
665+
var requestUris = this._messageHandlerStub.RequestUris;
666+
Assert.Single(requestUris);
667+
var absoluteUri = requestUris[0]!.AbsoluteUri;
668+
Assert.Contains("siteSearch=microsoft.com", absoluteUri);
669+
Assert.Contains("siteSearchFilter=i", absoluteUri);
670+
Assert.Contains("fileType=pdf", absoluteUri);
671+
}
672+
673+
[Fact]
674+
public async Task LinqComplexCompoundFilterProducesCorrectApiUrlAsync()
675+
{
676+
// Arrange
677+
this._messageHandlerStub.AddJsonResponse(File.ReadAllText(WhatIsTheSKResponseJson));
678+
679+
using var textSearch = new GoogleTextSearch(
680+
initializer: new() { ApiKey = "ApiKey", HttpClientFactory = this._clientFactory },
681+
searchEngineId: "SearchEngineId");
682+
683+
// Act - Use LINQ complex compound filter (equality + contains + exclusion)
684+
await textSearch.SearchAsync("test",
685+
new TextSearchOptions<GoogleWebPage>
686+
{
687+
Top = 4,
688+
Skip = 0,
689+
Filter = page => page.FileFormat == "pdf" &&
690+
page.Title != null && page.Title.Contains("AI") &&
691+
page.Snippet != null && !page.Snippet.Contains("deprecated")
692+
});
693+
694+
// Assert - Verify URL contains all expected parameters
695+
var requestUris = this._messageHandlerStub.RequestUris;
696+
Assert.Single(requestUris);
697+
var absoluteUri = requestUris[0]!.AbsoluteUri;
698+
Assert.Contains("fileType=pdf", absoluteUri);
699+
Assert.Contains("orTerms=AI", absoluteUri); // Contains uses orTerms for flexibility
700+
Assert.Contains("excludeTerms=deprecated", absoluteUri);
701+
}
702+
703+
#endregion
704+
510705
/// <inheritdoc/>
511706
public void Dispose()
512707
{

0 commit comments

Comments
 (0)