Skip to content

Commit 0c1fd78

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 76d8e7e commit 0c1fd78

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
@@ -509,6 +509,201 @@ public async Task GenericSearchWithComplexCompoundFilterReturnsSuccessfullyAsync
509509
Assert.Equal(4, resultList.Count);
510510
}
511511

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

0 commit comments

Comments
 (0)