1+ // Licensed to the .NET Foundation under one or more agreements.
2+ // The .NET Foundation licenses this file to you under the MIT license.
3+
4+ #nullable enable
5+
6+ using System . Globalization ;
7+ using Microsoft . AspNetCore . Components . Endpoints . FormMapping ;
8+ using Microsoft . AspNetCore . Components . Forms ;
9+ using Microsoft . AspNetCore . Http ;
10+ using Microsoft . Extensions . Primitives ;
11+ using Moq ;
12+
13+ namespace Microsoft . AspNetCore . Components . Endpoints . Tests . FormMapping ;
14+
15+ public class FileConverterTests
16+ {
17+ [ Fact ]
18+ public void TryRead_IBrowserFile_WithMissingLastModifiedHeader_ReturnsMinValue ( )
19+ {
20+ // Arrange
21+ const string prefixName = "file" ;
22+ var culture = CultureInfo . GetCultureInfo ( "en-US" ) ;
23+
24+ var mockFormFile = CreateMockFormFile ( ) ;
25+ var formFileCollection = new Mock < IFormFileCollection > ( ) ;
26+ formFileCollection . Setup ( x => x . GetFile ( prefixName ) ) . Returns ( mockFormFile . Object ) ;
27+
28+ var buffer = prefixName . ToCharArray ( ) . AsMemory ( ) ;
29+ var reader = new FormDataReader ( new Dictionary < FormKey , StringValues > ( ) , culture , buffer , formFileCollection . Object ) ;
30+ reader . PushPrefix ( prefixName ) ;
31+
32+ var converter = new FileConverter < IBrowserFile > ( ) ;
33+
34+ // Act
35+ var result = converter . TryRead ( ref reader , typeof ( IBrowserFile ) , default ! , out var browserFile , out var found ) ;
36+
37+ // Assert
38+ Assert . True ( result ) ;
39+ Assert . True ( found ) ;
40+ Assert . NotNull ( browserFile ) ;
41+ Assert . Equal ( DateTimeOffset . MinValue , browserFile . LastModified ) ;
42+ }
43+
44+ [ Fact ]
45+ public void TryRead_IBrowserFile_WithMalformedLastModifiedHeader_ReturnsMinValue ( )
46+ {
47+ // Arrange
48+ const string prefixName = "file" ;
49+ var culture = CultureInfo . GetCultureInfo ( "en-US" ) ;
50+
51+ var mockFormFile = CreateMockFormFile ( lastModified : "invalid-date" ) ;
52+ var formFileCollection = new Mock < IFormFileCollection > ( ) ;
53+ formFileCollection . Setup ( x => x . GetFile ( prefixName ) ) . Returns ( mockFormFile . Object ) ;
54+
55+ var buffer = prefixName . ToCharArray ( ) . AsMemory ( ) ;
56+ var reader = new FormDataReader ( new Dictionary < FormKey , StringValues > ( ) , culture , buffer , formFileCollection . Object ) ;
57+ reader . PushPrefix ( prefixName ) ;
58+
59+ var converter = new FileConverter < IBrowserFile > ( ) ;
60+
61+ // Act
62+ var result = converter . TryRead ( ref reader , typeof ( IBrowserFile ) , default ! , out var browserFile , out var found ) ;
63+
64+ // Assert
65+ Assert . True ( result ) ;
66+ Assert . True ( found ) ;
67+ Assert . NotNull ( browserFile ) ;
68+ Assert . Equal ( DateTimeOffset . MinValue , browserFile . LastModified ) ;
69+ }
70+
71+ [ Fact ]
72+ public void TryRead_IBrowserFile_WithValidLastModifiedHeader_ReturnsCorrectValue ( )
73+ {
74+ // Arrange
75+ const string prefixName = "file" ;
76+ var culture = CultureInfo . GetCultureInfo ( "en-US" ) ;
77+ var expectedDate = new DateTimeOffset ( 2023 , 11 , 30 , 12 , 0 , 0 , TimeSpan . Zero ) ;
78+
79+ var mockFormFile = CreateMockFormFile ( lastModified : expectedDate . ToString ( "r" ) ) ;
80+ var formFileCollection = new Mock < IFormFileCollection > ( ) ;
81+ formFileCollection . Setup ( x => x . GetFile ( prefixName ) ) . Returns ( mockFormFile . Object ) ;
82+
83+ var buffer = prefixName . ToCharArray ( ) . AsMemory ( ) ;
84+ var reader = new FormDataReader ( new Dictionary < FormKey , StringValues > ( ) , culture , buffer , formFileCollection . Object ) ;
85+ reader . PushPrefix ( prefixName ) ;
86+
87+ var converter = new FileConverter < IBrowserFile > ( ) ;
88+
89+ // Act
90+ var result = converter . TryRead ( ref reader , typeof ( IBrowserFile ) , default ! , out var browserFile , out var found ) ;
91+
92+ // Assert
93+ Assert . True ( result ) ;
94+ Assert . True ( found ) ;
95+ Assert . NotNull ( browserFile ) ;
96+ Assert . Equal ( expectedDate , browserFile . LastModified ) ;
97+ }
98+
99+ [ Fact ]
100+ public void TryRead_IBrowserFile_WithEmptyLastModifiedHeader_ReturnsMinValue ( )
101+ {
102+ // Arrange
103+ const string prefixName = "file" ;
104+ var culture = CultureInfo . GetCultureInfo ( "en-US" ) ;
105+
106+ var mockFormFile = CreateMockFormFile ( lastModified : string . Empty ) ;
107+ var formFileCollection = new Mock < IFormFileCollection > ( ) ;
108+ formFileCollection . Setup ( x => x . GetFile ( prefixName ) ) . Returns ( mockFormFile . Object ) ;
109+
110+ var buffer = prefixName . ToCharArray ( ) . AsMemory ( ) ;
111+ var reader = new FormDataReader ( new Dictionary < FormKey , StringValues > ( ) , culture , buffer , formFileCollection . Object ) ;
112+ reader . PushPrefix ( prefixName ) ;
113+
114+ var converter = new FileConverter < IBrowserFile > ( ) ;
115+
116+ // Act
117+ var result = converter . TryRead ( ref reader , typeof ( IBrowserFile ) , default ! , out var browserFile , out var found ) ;
118+
119+ // Assert
120+ Assert . True ( result ) ;
121+ Assert . True ( found ) ;
122+ Assert . NotNull ( browserFile ) ;
123+ Assert . Equal ( DateTimeOffset . MinValue , browserFile . LastModified ) ;
124+ }
125+
126+ private static Mock < IFormFile > CreateMockFormFile ( string ? lastModified = null ! )
127+ {
128+ var mockFormFile = new Mock < IFormFile > ( ) ;
129+ var mockHeaders = new Mock < IHeaderDictionary > ( ) ;
130+
131+ mockHeaders . Setup ( x => x . LastModified ) . Returns ( new StringValues ( lastModified ) ) ;
132+ mockFormFile . Setup ( x => x . Headers ) . Returns ( mockHeaders . Object ) ;
133+ mockFormFile . Setup ( x => x . Name ) . Returns ( "testfile.txt" ) ;
134+ mockFormFile . Setup ( x => x . ContentType ) . Returns ( "text/plain" ) ;
135+ mockFormFile . Setup ( x => x . Length ) . Returns ( 1024 ) ;
136+ mockFormFile . Setup ( x => x . OpenReadStream ( ) ) . Returns ( new MemoryStream ( ) ) ;
137+
138+ return mockFormFile ;
139+ }
140+ }
0 commit comments