1+ using DocAnalytics . Domain . Common ;
12using DocAnalytics . Domain . Entities ;
3+ using DocAnalytics . Service . Extraction ;
24using DocAnalytics . Service . Files ;
35using DocAnalytics . Service . Tests . Support ;
46using MockQueryable . Moq ;
57using Moq ;
8+ using ErrorCatalogEntry = DocAnalytics . Domain . Entities . ErrorCatalog ;
9+
10+
611
712namespace DocAnalytics . Service . Tests . Files ;
813
914public class FileDetailsServiceTests
1015{
16+ // ── helpers ────────────────────────────────────────────────────────────
17+
1118 private static Mock < DocAnalytics . Data . AppDbContext > Ctx (
12- FileRecord [ ] files , FileStepHistory [ ] steps , ErrorCatalog [ ] catalog )
19+ FileRecord [ ] files , FileStepHistory [ ] steps , ErrorCatalogEntry [ ] catalog )
1320 {
1421 var ctx = MockDb . Create ( ) ;
1522 ctx . Setup ( c => c . Files ) . Returns ( files . ToList ( ) . BuildMockDbSet ( ) . Object ) ;
@@ -18,54 +25,95 @@ public class FileDetailsServiceTests
1825 return ctx ;
1926 }
2027
28+ // Wrap construction so existing tests don't need to know about the new deps
29+ // (IExtractionQueue + ICurrentUser are only used by RetryFileAsync, not these tests)
30+ private static FileDetailsService Svc ( Mock < DocAnalytics . Data . AppDbContext > ctx ) =>
31+ new ( ctx . Object ,
32+ new Mock < IExtractionQueue > ( ) . Object ,
33+ new Mock < ICurrentUser > ( ) . Object ) ;
34+
35+ // ── tests ───────────────────────────────────────────────────────────────
36+
2137 [ Fact ]
2238 public async Task GetFileDetailsAsync_returns_null_when_file_missing ( )
2339 {
24- var sut = new FileDetailsService ( Ctx ( Array . Empty < FileRecord > ( ) , Array . Empty < FileStepHistory > ( ) , Array . Empty < ErrorCatalog > ( ) ) . Object ) ;
40+ var sut = Svc ( Ctx ( Array . Empty < FileRecord > ( ) ,
41+ Array . Empty < FileStepHistory > ( ) ,
42+ Array . Empty < ErrorCatalogEntry > ( ) ) ) ;
2543 Assert . Null ( await sut . GetFileDetailsAsync ( Guid . NewGuid ( ) ) ) ;
2644 }
2745
2846 [ Fact ]
2947 public async Task GetFileDetailsAsync_maps_history_with_remediation ( )
3048 {
3149 var fileId = Guid . NewGuid ( ) ;
32- var files = new [ ] { new FileRecord { Id = fileId , FileName = "a.pdf" , Status = "Failed" , CurrentStep = "Validate" } } ;
50+ var files = new [ ]
51+ {
52+ new FileRecord
53+ {
54+ Id = fileId , FileName = "a.pdf" ,
55+ Status = "Failed" , CurrentStep = "Validate" ,
56+ } ,
57+ } ;
3358 var steps = new [ ]
3459 {
35- new FileStepHistory { Id = Guid . NewGuid ( ) , FileId = fileId , StepName = "Upload" , Status = "Success" , StartedAt = DateTime . UtcNow . AddMinutes ( - 2 ) } ,
36- new FileStepHistory { Id = Guid . NewGuid ( ) , FileId = fileId , StepName = "Validate" , Status = "Failed" , ErrorCode = "E1" , ErrorMessage = "bad" , StartedAt = DateTime . UtcNow . AddMinutes ( - 1 ) } ,
60+ new FileStepHistory
61+ {
62+ Id = Guid . NewGuid ( ) , FileId = fileId , StepName = "Upload" ,
63+ Status = "Success" , StartedAt = DateTime . UtcNow . AddMinutes ( - 2 ) ,
64+ } ,
65+ new FileStepHistory
66+ {
67+ Id = Guid . NewGuid ( ) , FileId = fileId , StepName = "Validate" ,
68+ Status = "Failed" , ErrorCode = "E1" , ErrorMessage = "bad" ,
69+ StartedAt = DateTime . UtcNow . AddMinutes ( - 1 ) ,
70+ } ,
3771 } ;
38- var catalog = new [ ] { new ErrorCatalog { ErrorCode = "E1" , RemediationMsg = "Fix it" } } ;
72+ var catalog = new [ ] { new ErrorCatalogEntry { ErrorCode = "E1" , RemediationMsg = "Fix it" } } ;
3973
40- var dto = await new FileDetailsService ( Ctx ( files , steps , catalog ) . Object ) . GetFileDetailsAsync ( fileId ) ;
74+ var dto = await Svc ( Ctx ( files , steps , catalog ) ) . GetFileDetailsAsync ( fileId ) ;
4175
4276 Assert . NotNull ( dto ) ;
4377 Assert . Equal ( "a.pdf" , dto ! . FileInfo . Name ) ;
4478 Assert . Equal ( 2 , dto . History . Count ) ;
4579 var failed = dto . History . Single ( h => h . Step == "Validate" ) ;
4680 Assert . Equal ( "Fix it" , failed . Error ! . SuggestedFix ) ;
47- Assert . Null ( dto . History . Single ( h => h . Step == "Upload" ) . Error ) ; // success → no error block
81+ Assert . Null ( dto . History . Single ( h => h . Step == "Upload" ) . Error ) ;
4882 }
4983
5084 [ Fact ]
5185 public async Task GetFileLogsAsync_returns_null_when_file_missing ( )
5286 {
53- var sut = new FileDetailsService ( Ctx ( Array . Empty < FileRecord > ( ) , Array . Empty < FileStepHistory > ( ) , Array . Empty < ErrorCatalog > ( ) ) . Object ) ;
87+ var sut = Svc ( Ctx ( Array . Empty < FileRecord > ( ) ,
88+ Array . Empty < FileStepHistory > ( ) ,
89+ Array . Empty < ErrorCatalogEntry > ( ) ) ) ;
5490 Assert . Null ( await sut . GetFileLogsAsync ( Guid . NewGuid ( ) ) ) ;
5591 }
5692
5793 [ Fact ]
5894 public async Task GetFileLogsAsync_builds_downloadable_log ( )
5995 {
6096 var fileId = Guid . NewGuid ( ) ;
61- var files = new [ ] { new FileRecord { Id = fileId , FileName = "a.pdf" , Status = "Failed" , CurrentStep = "Validate" } } ;
97+ var files = new [ ]
98+ {
99+ new FileRecord
100+ {
101+ Id = fileId , FileName = "a.pdf" ,
102+ Status = "Failed" , CurrentStep = "Validate" ,
103+ } ,
104+ } ;
62105 var steps = new [ ]
63106 {
64- new FileStepHistory { Id = Guid . NewGuid ( ) , FileId = fileId , StepName = "Validate" , Status = "Failed" , ErrorCode = "E1" , ErrorMessage = "bad" , StartedAt = DateTime . UtcNow } ,
107+ new FileStepHistory
108+ {
109+ Id = Guid . NewGuid ( ) , FileId = fileId , StepName = "Validate" ,
110+ Status = "Failed" , ErrorCode = "E1" , ErrorMessage = "bad" ,
111+ StartedAt = DateTime . UtcNow ,
112+ } ,
65113 } ;
66- var catalog = new [ ] { new ErrorCatalog { ErrorCode = "E1" , RemediationMsg = "Fix it" } } ;
114+ var catalog = new [ ] { new ErrorCatalogEntry { ErrorCode = "E1" , RemediationMsg = "Fix it" } } ;
67115
68- var log = await new FileDetailsService ( Ctx ( files , steps , catalog ) . Object ) . GetFileLogsAsync ( fileId ) ;
116+ var log = await Svc ( Ctx ( files , steps , catalog ) ) . GetFileLogsAsync ( fileId ) ;
69117
70118 Assert . NotNull ( log ) ;
71119 Assert . Equal ( $ "file_{ fileId } _log.txt", log ! . FileName ) ;
0 commit comments