22using HappyNotes . Common . Enums ;
33using HappyNotes . Entities ;
44using HappyNotes . Services . interfaces ;
5+ using HappyNotes . Repositories . interfaces ;
56using Moq ;
67using Moq . Protected ;
78using SqlSugar ;
@@ -12,12 +13,14 @@ namespace HappyNotes.Services.Tests;
1213public class SearchServiceTests
1314{
1415 private readonly Mock < IDatabaseClient > _mockDatabaseClient ;
16+ private readonly Mock < INoteRepository > _mockNoteRepository ;
1517 private readonly SearchService _searchService ;
1618 private readonly Mock < HttpMessageHandler > _mockHandler ;
1719
1820 public SearchServiceTests ( )
1921 {
2022 _mockDatabaseClient = new Mock < IDatabaseClient > ( ) ;
23+ _mockNoteRepository = new Mock < INoteRepository > ( ) ;
2124 _mockHandler = new Mock < HttpMessageHandler > ( ) ;
2225 _mockHandler . Protected ( )
2326 . Setup < Task < HttpResponseMessage > > ( "SendAsync" , ItExpr . IsAny < HttpRequestMessage > ( ) , ItExpr . IsAny < CancellationToken > ( ) )
@@ -28,14 +31,15 @@ public SearchServiceTests()
2831 } ) ;
2932 var httpClient = new HttpClient ( _mockHandler . Object ) ;
3033 var options = new ManticoreConnectionOptions { HttpEndpoint = "http://127.0.0.1:9308" } ;
31- _searchService = new SearchService ( _mockDatabaseClient . Object , httpClient , options ) ;
34+ _searchService = new SearchService ( _mockDatabaseClient . Object , httpClient , options , _mockNoteRepository . Object ) ;
3235 }
3336
3437 [ SetUp ]
3538 public void Setup ( )
3639 {
3740 // Reset mock invocations before each test to avoid cross-test interference.
3841 _mockDatabaseClient . Reset ( ) ;
42+ _mockNoteRepository . Reset ( ) ;
3943 _mockHandler . Reset ( ) ;
4044 _mockHandler . Protected ( )
4145 . Setup < Task < HttpResponseMessage > > ( "SendAsync" , ItExpr . IsAny < HttpRequestMessage > ( ) , ItExpr . IsAny < CancellationToken > ( ) )
@@ -315,11 +319,9 @@ public async Task GetNoteIdsByKeywordAsync_IntegerQuery_FirstPage_UserOwnsNote_P
315319 Content = new StringContent ( "{\" took\" :0,\" timed_out\" :false,\" hits\" :{\" total\" :2,\" hits\" :[{\" _id\" :456,\" _source\" :{\" id\" :456}},{\" _id\" :789,\" _source\" :{\" id\" :789}}]}}" )
316320 } ) ;
317321
318- // Mock database query to return user's note
319- _mockDatabaseClient . Setup ( x => x . SqlQueryAsync < Note > (
320- It . IsAny < string > ( ) ,
321- It . IsAny < object > ( ) ) )
322- . ReturnsAsync ( new List < Note > { new Note { Id = 123 , UserId = 1 } } ) ;
322+ // Mock repository query to return user's note
323+ _mockNoteRepository . Setup ( x => x . GetFirstOrDefaultAsync ( It . IsAny < System . Linq . Expressions . Expression < System . Func < Note , bool > > > ( ) , null ) )
324+ . ReturnsAsync ( new Note { Id = 123 , UserId = 1 } ) ;
323325
324326 // Act
325327 var result = await _searchService . GetNoteIdsByKeywordAsync ( userId , query , pageNumber , pageSize ) ;
@@ -349,11 +351,9 @@ public async Task GetNoteIdsByKeywordAsync_IntegerQuery_FirstPage_UserDoesNotOwn
349351 Content = new StringContent ( "{\" took\" :0,\" timed_out\" :false,\" hits\" :{\" total\" :2,\" hits\" :[{\" _id\" :456,\" _source\" :{\" id\" :456}},{\" _id\" :789,\" _source\" :{\" id\" :789}}]}}" )
350352 } ) ;
351353
352- // Mock database query to return note owned by different user
353- _mockDatabaseClient . Setup ( x => x . SqlQueryAsync < Note > (
354- It . IsAny < string > ( ) ,
355- It . IsAny < object > ( ) ) )
356- . ReturnsAsync ( new List < Note > { new Note { Id = 123 , UserId = 2 } } ) ; // Different user
354+ // Mock repository query to return note owned by different user
355+ _mockNoteRepository . Setup ( x => x . GetFirstOrDefaultAsync ( It . IsAny < System . Linq . Expressions . Expression < System . Func < Note , bool > > > ( ) , null ) )
356+ . ReturnsAsync ( new Note { Id = 123 , UserId = 2 } ) ; // Different user
357357
358358 // Act
359359 var result = await _searchService . GetNoteIdsByKeywordAsync ( userId , query , pageNumber , pageSize ) ;
@@ -390,7 +390,7 @@ public async Task GetNoteIdsByKeywordAsync_IntegerQuery_SecondPage_DoesNotPrepen
390390 Assert . That ( result . Item1 . Count , Is . EqualTo ( 2 ) ) ; // Should remain 2 notes
391391 CollectionAssert . AreEqual ( new List < long > { 456 , 789 } , result . Item1 ) ;
392392 // Verify database was not called since it's not first page
393- _mockDatabaseClient . Verify ( x => x . SqlQueryAsync < Note > ( It . IsAny < string > ( ) , It . IsAny < object > ( ) ) , Times . Never ) ;
393+ _mockNoteRepository . Verify ( x => x . GetFirstOrDefaultAsync ( It . IsAny < System . Linq . Expressions . Expression < System . Func < Note , bool > > > ( ) , null ) , Times . Never ) ;
394394 }
395395
396396 [ Test ]
@@ -411,11 +411,9 @@ public async Task GetNoteIdsByKeywordAsync_IntegerQuery_NoteNotFound_DoesNotPrep
411411 Content = new StringContent ( "{\" took\" :0,\" timed_out\" :false,\" hits\" :{\" total\" :2,\" hits\" :[{\" _id\" :456,\" _source\" :{\" id\" :456}},{\" _id\" :789,\" _source\" :{\" id\" :789}}]}}" )
412412 } ) ;
413413
414- // Mock database query to return empty list (note not found)
415- _mockDatabaseClient . Setup ( x => x . SqlQueryAsync < Note > (
416- It . IsAny < string > ( ) ,
417- It . IsAny < object > ( ) ) )
418- . ReturnsAsync ( new List < Note > ( ) ) ;
414+ // Mock repository query to return null (note not found)
415+ _mockNoteRepository . Setup ( x => x . GetFirstOrDefaultAsync ( It . IsAny < System . Linq . Expressions . Expression < System . Func < Note , bool > > > ( ) , null ) )
416+ . ReturnsAsync ( ( Note ? ) null ) ;
419417
420418 // Act
421419 var result = await _searchService . GetNoteIdsByKeywordAsync ( userId , query , pageNumber , pageSize ) ;
@@ -444,11 +442,9 @@ public async Task GetNoteIdsByKeywordAsync_IntegerQuery_FirstPage_NoteAlreadyInR
444442 Content = new StringContent ( "{\" took\" :0,\" timed_out\" :false,\" hits\" :{\" total\" :3,\" hits\" :[{\" _id\" :456,\" _source\" :{\" id\" :456}},{\" _id\" :123,\" _source\" :{\" id\" :123}},{\" _id\" :789,\" _source\" :{\" id\" :789}}]}}" )
445443 } ) ;
446444
447- // Mock database query to return user's note
448- _mockDatabaseClient . Setup ( x => x . SqlQueryAsync < Note > (
449- It . IsAny < string > ( ) ,
450- It . IsAny < object > ( ) ) )
451- . ReturnsAsync ( new List < Note > { new Note { Id = 123 , UserId = 1 } } ) ;
445+ // Mock repository query to return user's note
446+ _mockNoteRepository . Setup ( x => x . GetFirstOrDefaultAsync ( It . IsAny < System . Linq . Expressions . Expression < System . Func < Note , bool > > > ( ) , null ) )
447+ . ReturnsAsync ( new Note { Id = 123 , UserId = 1 } ) ;
452448
453449 // Act
454450 var result = await _searchService . GetNoteIdsByKeywordAsync ( userId , query , pageNumber , pageSize ) ;
@@ -486,6 +482,6 @@ public async Task GetNoteIdsByKeywordAsync_NonIntegerQuery_DoesNotPrepend()
486482 Assert . That ( result . Item1 . Count , Is . EqualTo ( 2 ) ) ; // Should remain 2 notes
487483 CollectionAssert . AreEqual ( new List < long > { 456 , 789 } , result . Item1 ) ;
488484 // Verify database was not called since query is not an integer
489- _mockDatabaseClient . Verify ( x => x . SqlQueryAsync < Note > ( It . IsAny < string > ( ) , It . IsAny < object > ( ) ) , Times . Never ) ;
485+ _mockNoteRepository . Verify ( x => x . GetFirstOrDefaultAsync ( It . IsAny < System . Linq . Expressions . Expression < System . Func < Note , bool > > > ( ) , null ) , Times . Never ) ;
490486 }
491487}
0 commit comments