1+ using FluentAssertions ;
2+ using Riber . Domain . Constants . Messages . Entities ;
3+ using Riber . Domain . Exceptions ;
4+
5+ namespace Riber . Domain . Tests . Entities ;
6+
7+ public sealed class Image : BaseTest
8+ {
9+ #region Create
10+
11+ [ Fact ( DisplayName = "Should create image when parameters are valid" ) ]
12+ public void CreateImage_WhenParametersAreValid_ShouldCreateSuccessfully ( )
13+ {
14+ // Arrange
15+ var image = CreateFaker < Domain . Entities . Image > ( )
16+ . CustomInstantiator ( f => Domain . Entities . Image . Create (
17+ length : f . Random . Long ( 1_000L , 10_000_000L ) ,
18+ contentType : f . PickRandom ( "image/png" , "image/jpeg" , "image/webp" ) ,
19+ originalName : f . System . FileName ( "png" ) )
20+ ) ;
21+
22+ // Act
23+ var result = image . Generate ( ) ! ;
24+
25+ // Assert
26+ result . MarkedForDeletionAt . Should ( ) . BeNull ( ) ;
27+ result . ShouldDelete . Should ( ) . BeFalse ( ) ;
28+ result . ContentType . Should ( ) . BeOneOf ( "image/png" , "image/jpeg" , "image/webp" ) ;
29+ result . Length . Should ( ) . BeInRange ( 1_000L , 10_000_000L ) ;
30+ result . OriginalName . Should ( ) . NotBeNullOrWhiteSpace ( ) ;
31+ result . Id . Should ( ) . NotBeEmpty ( ) ;
32+ result . Extension . Should ( ) . BeOneOf ( ".png" , ".jpeg" , ".webp" ) ;
33+ result . Key . Should ( ) . NotBeNullOrWhiteSpace ( ) ;
34+ }
35+
36+ [ Fact ( DisplayName = "Should throw exception when length is less or equal to zero" ) ]
37+ public void CreateImage_WhenLengthIsInvalid_ShouldThrowException ( )
38+ {
39+ // Arrange
40+ var image = CreateFaker < Domain . Entities . Image > ( )
41+ . CustomInstantiator ( f => Domain . Entities . Image . Create (
42+ length : f . Random . Long ( 0L , 0L ) ,
43+ contentType : f . PickRandom ( "image/png" , "image/jpeg" , "image/webp" ) ,
44+ originalName : f . System . FileName ( "png" ) )
45+ ) ;
46+
47+ // Act
48+ var result = ( ) => image . Generate ( ) ;
49+
50+ // Assert
51+ result . Should ( ) . ThrowExactly < InvalidLengthImageException > ( ImageErrors . Length ) ;
52+ }
53+
54+ [ Fact ( DisplayName = "Should throw exception when content type is not allowed" ) ]
55+ public void CreateImage_WhenContentTypeIsInvalid_ShouldThrowException ( )
56+ {
57+ // Arrange
58+ var image = CreateFaker < Domain . Entities . Image > ( )
59+ . CustomInstantiator ( f => Domain . Entities . Image . Create (
60+ length : f . Random . Long ( 1_000L , 10_000_000L ) ,
61+ contentType : "image/gif" ,
62+ originalName : f . System . FileName ( "png" ) )
63+ ) ;
64+
65+ // Act
66+ var result = ( ) => image . Generate ( ) ;
67+
68+ // Assert
69+ result . Should ( ) . ThrowExactly < InvalidTypeImageException > ( ImageErrors . Type ) ;
70+ }
71+
72+ [ Fact ( DisplayName = "Should throw exception when original name is null or empty" ) ]
73+ public void CreateImage_WhenOriginalNameIsEmpty_ShouldThrowException ( )
74+ {
75+ // Arrange
76+ var image = CreateFaker < Domain . Entities . Image > ( )
77+ . CustomInstantiator ( f => Domain . Entities . Image . Create (
78+ length : f . Random . Long ( 1_000L , 10_000_000L ) ,
79+ contentType : f . PickRandom ( "image/png" , "image/jpeg" , "image/webp" ) ,
80+ originalName : string . Empty ) ) ;
81+
82+ // Act
83+ var result = ( ) => image . Generate ( ) ;
84+
85+ // Assert
86+ result . Should ( ) . ThrowExactly < InvalidImageException > ( ImageErrors . NameEmpty ) ;
87+ }
88+
89+ [ Fact ( DisplayName = "Should throw exception when original name has no extension" ) ]
90+ public void CreateImage_WhenOriginalNameHasNoExtension_ShouldThrowException ( )
91+ {
92+ // Arrange
93+ var image = CreateFaker < Domain . Entities . Image > ( )
94+ . CustomInstantiator ( f => Domain . Entities . Image . Create (
95+ length : f . Random . Long ( 1_000L , 10_000_000L ) ,
96+ contentType : f . PickRandom ( "image/png" , "image/jpeg" , "image/webp" ) ,
97+ originalName : f . System . FileName ( "" ) ) ) ;
98+
99+ // Act
100+ var result = ( ) => image . Generate ( ) ;
101+
102+ // Asset
103+ result . Should ( ) . ThrowExactly < InvalidImageException > ( ImageErrors . ExtensionEmpty ) ;
104+ }
105+
106+ #endregion
107+
108+ #region MarkForDeletion
109+
110+ [ Fact ( DisplayName = "Should mark image for deletion and set properties" ) ]
111+ public void MarkForDeletion_WhenCalled_ShouldSetDeletionFlags ( )
112+ {
113+ // Arrange
114+ var image = CreateFaker < Domain . Entities . Image > ( )
115+ . CustomInstantiator ( f => Domain . Entities . Image . Create (
116+ length : f . Random . Long ( 1_000L , 10_000_000L ) ,
117+ contentType : f . PickRandom ( "image/png" , "image/jpeg" , "image/webp" ) ,
118+ originalName : f . System . FileName ( "png" ) )
119+ ) . Generate ( ) ;
120+
121+ // Act
122+ image . MarkForDeletion ( ) ;
123+
124+ // Assert
125+ image . MarkedForDeletionAt . Should ( ) . NotBeNull ( ) ;
126+ image . ShouldDelete . Should ( ) . BeTrue ( ) ;
127+ }
128+
129+
130+ [ Fact ( DisplayName = "Should return true when image is marked for deletion" ) ]
131+ public void IsMarkedForDeletion_WhenMarked_ShouldReturnTrue ( )
132+ {
133+ // Arrange
134+ var image = CreateFaker < Domain . Entities . Image > ( )
135+ . CustomInstantiator ( f => Domain . Entities . Image . Create (
136+ length : f . Random . Long ( 1_000L , 10_000_000L ) ,
137+ contentType : f . PickRandom ( "image/png" , "image/jpeg" , "image/webp" ) ,
138+ originalName : f . System . FileName ( "png" ) )
139+ ) . Generate ( ) ;
140+
141+ // Act
142+ image . MarkForDeletion ( ) ;
143+ var result = image . IsMarkedForDeletion ( ) ;
144+
145+ // Assert
146+ result . Should ( ) . BeTrue ( ) ;
147+ }
148+
149+ #endregion
150+
151+ #region Validation
152+
153+ [ Fact ( DisplayName = "Should return true when content type is allowed" ) ]
154+ public void IsValidImageType_WhenTypeIsAllowed_ShouldReturnTrue ( )
155+ {
156+ // Arrange
157+ string [ ] allowedTypes = [ "image/png" , "image/jpg" , "image/jpeg" , "image/webp" ] ;
158+
159+ // Act
160+ var result = allowedTypes . Any ( Domain . Entities . Image . IsValidImageType ) ;
161+
162+ // Assert
163+ result . Should ( ) . BeTrue ( ) ;
164+ }
165+
166+
167+ [ Fact ( DisplayName = "Should return false when content type is not allowed" ) ]
168+ public void IsValidImageType_WhenTypeIsNotAllowed_ShouldReturnFalse ( )
169+ {
170+ // Arrange
171+ string allowedType = "image/gif" ;
172+
173+ // Act
174+ var result = Domain . Entities . Image . IsValidImageType ( allowedType ) ;
175+
176+ // Assert
177+ result . Should ( ) . BeFalse ( ) ;
178+ }
179+
180+ #endregion
181+
182+ #region ToString & Implicit
183+
184+ [ Fact ( DisplayName = "Should return correct string representation" ) ]
185+ public void ToString_WhenCalled_ShouldReturnKeyWithExtension ( )
186+ {
187+ // Arrange
188+ var image = CreateFaker < Domain . Entities . Image > ( )
189+ . CustomInstantiator ( f => Domain . Entities . Image . Create (
190+ length : f . Random . Long ( 1_000L , 10_000_000L ) ,
191+ contentType : f . PickRandom ( "image/png" , "image/jpeg" , "image/webp" ) ,
192+ originalName : f . System . FileName ( "png" ) )
193+ ) . Generate ( ) ;
194+
195+ // Act
196+ var result = image . ToString ( ) ;
197+
198+ // Assert
199+ result . Should ( ) . Be ( $ "{ image . Key } { image . Extension } ") ;
200+ }
201+
202+ [ Fact ( DisplayName = "Should convert to string implicitly with correct format" ) ]
203+ public void ImplicitOperatorString_WhenCalled_ShouldReturnCorrectString ( )
204+ {
205+ // Arrange
206+ var image = CreateFaker < Domain . Entities . Image > ( )
207+ . CustomInstantiator ( f => Domain . Entities . Image . Create (
208+ length : f . Random . Long ( 1_000L , 10_000_000L ) ,
209+ contentType : f . PickRandom ( "image/png" , "image/jpeg" , "image/webp" ) ,
210+ originalName : f . System . FileName ( "png" ) )
211+ ) . Generate ( ) ;
212+
213+ // Act
214+ string result = image ;
215+
216+ // Assert
217+ result . Should ( ) . Be ( $ "{ image . Key } { image . Extension } ") ;
218+ }
219+
220+ #endregion
221+ }
0 commit comments