@@ -16,7 +16,7 @@ public void MapToAuthUiError_ShouldReturnError1()
1616 string responseContent = "{ \" code\" : \" " + errorCode + "\" }" ;
1717
1818 // Act
19- ProblemDescriptor actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
19+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
2020
2121 // Assert
2222 Assert . Equal ( expectedErrorCode , actualError . ErrorCode . ToString ( ) ) ;
@@ -31,7 +31,7 @@ public void MapToAuthUiError_ShouldReturnError2()
3131 string responseContent = "{ \" code\" : \" " + errorCode + "\" }" ;
3232
3333 // Act
34- ProblemDescriptor actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
34+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
3535 // Assert
3636 Assert . Equal ( expectedErrorCode , actualError . ErrorCode . ToString ( ) ) ;
3737 }
@@ -45,7 +45,7 @@ public void MapToAuthUiError_ShouldReturnError3()
4545 string responseContent = "{ \" code\" : \" " + errorCode + "\" }" ;
4646
4747 // Act
48- ProblemDescriptor actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
48+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
4949
5050 // Assert
5151 Assert . Equal ( expectedErrorCode , actualError . ErrorCode . ToString ( ) ) ;
@@ -60,7 +60,7 @@ public void MapToAuthUiError_ShouldReturnError4()
6060 string responseContent = "{ \" code\" : \" " + errorCode + "\" }" ;
6161
6262 // Act
63- ProblemDescriptor actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
63+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
6464
6565 // Assert
6666 Assert . Equal ( expectedErrorCode , actualError . ErrorCode . ToString ( ) ) ;
@@ -75,7 +75,7 @@ public void MapToAuthUiError_ShouldReturnError11()
7575 string responseContent = "{ \" code\" : \" " + errorCode + "\" }" ;
7676
7777 // Act
78- ProblemDescriptor actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
78+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
7979
8080 // Assert
8181 Assert . Equal ( expectedErrorCode , actualError . ErrorCode . ToString ( ) ) ;
@@ -90,7 +90,7 @@ public void MapToAuthUiError_ShouldReturnError14()
9090 string responseContent = "{ \" code\" : \" " + errorCode + "\" }" ;
9191
9292 // Act
93- ProblemDescriptor actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
93+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
9494
9595 // Assert
9696 Assert . Equal ( expectedErrorCode , actualError . ErrorCode . ToString ( ) ) ;
@@ -105,7 +105,7 @@ public void MapToAuthUiError_ShouldReturnError16()
105105 string responseContent = "{ \" code\" : \" " + errorCode + "\" }" ;
106106
107107 // Act
108- ProblemDescriptor actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
108+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
109109
110110 // Assert
111111 Assert . Equal ( expectedErrorCode , actualError . ErrorCode . ToString ( ) ) ;
@@ -120,7 +120,7 @@ public void MapToAuthUiError_ShouldReturnError18()
120120 string responseContent = "{ \" code\" : \" " + errorCode + "\" }" ;
121121
122122 // Act
123- ProblemDescriptor actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
123+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
124124
125125 // Assert
126126 Assert . Equal ( expectedErrorCode , actualError . ErrorCode . ToString ( ) ) ;
@@ -135,7 +135,7 @@ public void MapToAuthUiError_ShouldReturnError19()
135135 string responseContent = "{ \" code\" : \" " + errorCode + "\" }" ;
136136
137137 // Act
138- ProblemDescriptor actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
138+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
139139
140140 // Assert
141141 Assert . Equal ( expectedErrorCode , actualError . ErrorCode . ToString ( ) ) ;
@@ -150,7 +150,7 @@ public void MapToAuthUiError_ShouldReturnError20()
150150 string responseContent = "{ \" code\" : \" " + errorCode + "\" }" ;
151151
152152 // Act
153- ProblemDescriptor actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
153+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
154154
155155 // Assert
156156 Assert . Equal ( expectedErrorCode , actualError . ErrorCode . ToString ( ) ) ;
@@ -165,7 +165,7 @@ public void MapToAuthUiError_ShouldGenericError()
165165 string responseContent = "{ \" code\" : \" " + errorCode + "\" }" ;
166166
167167 // Act
168- ProblemDescriptor actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
168+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
169169
170170 // Assert
171171 Assert . Equal ( expectedErrorCode , actualError . ErrorCode . ToString ( ) ) ;
@@ -179,11 +179,61 @@ public void MapToAuthUiError_ShouldShowGenericProblemForErrorWithoutCode()
179179 var expectedStatusCode = HttpStatusCode . Forbidden ;
180180
181181 // Act
182- ProblemDescriptor actualError = ProblemMapper . MapToAuthUiError ( "" , HttpStatusCode . Forbidden ) ;
182+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( "" , HttpStatusCode . Forbidden ) ;
183183
184184 // Assert
185185 Assert . Equal ( expectedErrorCode , actualError . ErrorCode . ToString ( ) ) ;
186186 Assert . Equal ( expectedStatusCode , actualError . StatusCode ) ;
187187 }
188+
189+ [ Fact ]
190+ public void MapToAuthUiError_ForwardsDelegationReasonsExtension ( )
191+ {
192+ // Arrange - the upstream (authentication) problem carries the structured delegationReasons
193+ // extension (a JSON string of resource id + codes). JsonSerializer.Serialize encodes it as a
194+ // JSON string value inside the response body.
195+ string reasons = """[{"type":"resource","id":"resource-a","codes":["MissingRoleAccess"]}]""" ;
196+ string responseContent = "{ \" code\" : \" AUTH-00016\" , \" delegationReasons\" : " + System . Text . Json . JsonSerializer . Serialize ( reasons ) + " }" ;
197+
198+ // Act
199+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
200+
201+ // Assert - the code is mapped AND the structured extension is preserved verbatim on the returned problem
202+ Assert . Equal ( "AMUI-00016" , actualError . ErrorCode . ToString ( ) ) ;
203+ Assert . True ( actualError . Extensions . TryGetValue ( "delegationReasons" , out string reason ) ) ;
204+ Assert . Equal ( reasons , reason ) ;
205+ }
206+
207+ [ Fact ]
208+ public void MapToAuthUiError_WithoutExtensions_DoesNotAddDelegationReasons ( )
209+ {
210+ // Arrange - no extension members on the upstream problem
211+ string responseContent = "{ \" code\" : \" AUTH-00016\" }" ;
212+
213+ // Act
214+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
215+
216+ // Assert - mapped as before, and no delegationReasons is invented
217+ Assert . Equal ( "AMUI-00016" , actualError . ErrorCode . ToString ( ) ) ;
218+ Assert . False ( actualError . Extensions . TryGetValue ( "delegationReasons" , out _ ) ) ;
219+ }
220+
221+ [ Fact ]
222+ public void MapToAuthUiError_ForwardsDelegationReasons_MultipleResourcesAndCodes ( )
223+ {
224+ // Arrange - a realistic structured delegationReasons value spanning multiple resources, each
225+ // with one or more reason codes (as produced by authentication's DelegationHelper). The BFF
226+ // must forward the whole value verbatim - it must not truncate to the first resource/code.
227+ string reasons = """[{"type":"resource","id":"resource-a","codes":["MissingRoleAccess","MissingPackageAccess"]},{"type":"resource","id":"resource-b","codes":["ResourceIsMaskinPortenSchema"]}]""" ;
228+ string responseContent = "{ \" code\" : \" AUTH-00016\" , \" delegationReasons\" : " + System . Text . Json . JsonSerializer . Serialize ( reasons ) + " }" ;
229+
230+ // Act
231+ ProblemInstance actualError = ProblemMapper . MapToAuthUiError ( responseContent , HttpStatusCode . BadRequest ) ;
232+
233+ // Assert - the full multi-resource / multi-code structured value is preserved unchanged
234+ Assert . Equal ( "AMUI-00016" , actualError . ErrorCode . ToString ( ) ) ;
235+ Assert . True ( actualError . Extensions . TryGetValue ( "delegationReasons" , out string reason ) ) ;
236+ Assert . Equal ( reasons , reason ) ;
237+ }
188238 }
189239}
0 commit comments