@@ -127,24 +127,14 @@ public void GetExceptionStackTraceLimitsDepth()
127127 }
128128
129129 [ Fact ]
130- public void GetEnvironmentDetailsReturnsValidValues ( )
130+ public void GetApplicationVersionReturnsValidValue ( )
131131 {
132- var method = typeof ( BugReportService ) . GetMethod ( "GetEnvironmentDetails " , BindingFlags . NonPublic | BindingFlags . Static ) ;
132+ var method = typeof ( BugReportService ) . GetMethod ( "GetApplicationVersion " , BindingFlags . NonPublic | BindingFlags . Static ) ;
133133 Assert . NotNull ( method ) ;
134134
135- var result = method . Invoke ( null , null ) ;
135+ var result = method . Invoke ( null , null ) as string ;
136136 Assert . NotNull ( result ) ;
137-
138- var type = result . GetType ( ) ;
139- var osVersion = type . GetField ( "Item1" ) ? . GetValue ( result ) as string ;
140- var architecture = type . GetField ( "Item2" ) ? . GetValue ( result ) as string ;
141- var processorCount = type . GetField ( "Item5" ) ? . GetValue ( result ) ;
142-
143- Assert . NotNull ( osVersion ) ;
144- Assert . NotEmpty ( osVersion ) ;
145- Assert . NotNull ( architecture ) ;
146- Assert . NotEmpty ( architecture ) ;
147- Assert . IsType < int > ( processorCount ) ;
137+ Assert . NotEmpty ( result ) ;
148138 }
149139
150140 [ Fact ]
@@ -167,4 +157,66 @@ public async Task SendBugReportAsyncReturnsFalseOnNetworkError()
167157 var result = await service . SendBugReportAsync ( "Test message" ) ;
168158 Assert . False ( result ) ;
169159 }
160+
161+ [ Fact ]
162+ public void BuildFormattedReportExceptionWithNullFieldsDoesNotCrash ( )
163+ {
164+ var service = new BugReportService ( TestApiUrl , TestApiKey , TestAppName ) ;
165+ var method = typeof ( BugReportService ) . GetMethod ( "BuildFormattedReport" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
166+ Assert . NotNull ( method ) ;
167+
168+ var ex = Record . Exception ( ( ) =>
169+ {
170+ // Exception with no message and no stack trace
171+ var customEx = new Exception ( ( string ? ) null ) ;
172+ var result = method . Invoke ( service , [ "Error summary" , customEx ] ) as string ;
173+ Assert . NotNull ( result ) ;
174+ Assert . Contains ( "Error summary" , result , StringComparison . Ordinal ) ;
175+ } ) ;
176+
177+ Assert . Null ( ex ) ;
178+ }
179+
180+ [ Fact ]
181+ public void BuildFormattedReportEmptyMessageDoesNotCrash ( )
182+ {
183+ var service = new BugReportService ( TestApiUrl , TestApiKey , TestAppName ) ;
184+ var method = typeof ( BugReportService ) . GetMethod ( "BuildFormattedReport" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
185+ Assert . NotNull ( method ) ;
186+
187+ var result = method . Invoke ( service , [ "" , null ] ) as string ;
188+ Assert . NotNull ( result ) ;
189+ Assert . Contains ( "=== Error Details ===" , result , StringComparison . Ordinal ) ;
190+ }
191+
192+ [ Fact ]
193+ public void BuildFormattedReportExceptionWithoutStackTraceDoesNotCrash ( )
194+ {
195+ var service = new BugReportService ( TestApiUrl , TestApiKey , TestAppName ) ;
196+ var method = typeof ( BugReportService ) . GetMethod ( "BuildFormattedReport" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
197+ Assert . NotNull ( method ) ;
198+
199+ // Create exception using parameterless constructor which may not populate StackTrace immediately
200+ var customEx = new InvalidOperationException ( "Error with no explicit stack" ) ;
201+ var result = method . Invoke ( service , [ "Error with null stack" , customEx ] ) as string ;
202+ Assert . NotNull ( result ) ;
203+ Assert . Contains ( "Error with null stack" , result , StringComparison . Ordinal ) ;
204+ Assert . Contains ( "InvalidOperationException" , result , StringComparison . Ordinal ) ;
205+ }
206+
207+ [ Fact ]
208+ public void AppendExceptionDetailsHandlesExceptionWithoutSource ( )
209+ {
210+ var method = typeof ( BugReportService ) . GetMethod ( "AppendExceptionDetails" , BindingFlags . NonPublic | BindingFlags . Static ) ;
211+ Assert . NotNull ( method ) ;
212+
213+ var sb = new StringBuilder ( ) ;
214+ var ex = Record . Exception ( ( ) =>
215+ {
216+ method . Invoke ( null , [ sb , new InvalidOperationException ( ) , 0 ] ) ;
217+ } ) ;
218+
219+ Assert . Null ( ex ) ;
220+ Assert . Contains ( "InvalidOperationException" , sb . ToString ( ) , StringComparison . Ordinal ) ;
221+ }
170222}
0 commit comments