@@ -29,6 +29,62 @@ public ScopeExtensionsTests()
2929 _ = _httpContext . Request . Returns ( _httpRequest ) ;
3030 }
3131
32+ private class Fixture
33+ {
34+ public const string ControllerName = "Ctrl" ;
35+ public const string ActionName = "Actn" ;
36+
37+ public readonly Scope Scope = new ( new SentryOptions ( ) ) ;
38+ public HttpContext HttpContext { get ; } = Substitute . For < HttpContext > ( ) ;
39+
40+ public Fixture GetSut ( bool addTransaction = true )
41+ {
42+ if ( addTransaction )
43+ {
44+ Scope . Transaction = Substitute . For < ITransaction > ( ) ;
45+ }
46+
47+ var routeFeature = new RoutingFeature
48+ {
49+ RouteData = new RouteData
50+ {
51+ Values =
52+ {
53+ { "controller" , ControllerName } ,
54+ { "action" , ActionName }
55+ }
56+ }
57+ } ;
58+ var features = new FeatureCollection ( ) ;
59+ features . Set < IRoutingFeature > ( routeFeature ) ;
60+ HttpContext . Features . Returns ( features ) ;
61+ HttpContext . Request . Method . Returns ( "GET" ) ;
62+ return this ;
63+ }
64+
65+ public Fixture GetSutWithEmptyRoute ( bool addTransaction = true )
66+ {
67+ if ( addTransaction )
68+ {
69+ Scope . Transaction = Substitute . For < ITransaction > ( ) ;
70+ }
71+ var routeFeature = new RoutingFeature
72+ {
73+ RouteData = new RouteData
74+ {
75+ Values = { { "" , null } }
76+ }
77+ } ;
78+ var features = new FeatureCollection ( ) ;
79+ features . Set < IRoutingFeature > ( routeFeature ) ;
80+ HttpContext . Features . Returns ( features ) ;
81+ HttpContext . Request . Method . Returns ( "GET" ) ;
82+ return this ;
83+ }
84+ }
85+
86+ private readonly Fixture _fixture = new ( ) ;
87+
3288 [ Fact ]
3389 public void Populate_Request_Method_SetToScope ( )
3490 {
@@ -268,6 +324,7 @@ public void Populate_PayloadExtractors_DoesNotConsiderInvalidResponse(object exp
268324 [ Fact ]
269325 public void Populate_RouteData_SetToScope ( )
270326 {
327+ // Arrange
271328 const string controller = "Ctrl" ;
272329 const string action = "Actn" ;
273330 var routeFeature = new RoutingFeature ( )
@@ -279,8 +336,10 @@ public void Populate_RouteData_SetToScope()
279336 _ = _httpContext . Features . Returns ( features ) ;
280337 _ = _httpContext . Request . Method . Returns ( "GET" ) ;
281338
339+ // Act
282340 _sut . Populate ( _httpContext , SentryAspNetCoreOptions ) ;
283341
342+ // Assert
284343 Assert . Equal ( $ "GET { controller } .{ action } ", _sut . TransactionName ) ;
285344 }
286345
@@ -364,5 +423,50 @@ public void Populate_TraceIdentifier_WhenRequestIdDoesNotMatch_SetAsTag()
364423
365424 Assert . Equal ( expected , _sut . Tags [ nameof ( HttpContext . TraceIdentifier ) ] ) ;
366425 }
426+
427+ [ Fact ]
428+ public void Populate_TransactionAndTransactionNameIsNull_TransactionNameReplaced ( )
429+ {
430+ // Arrange
431+ var sut = _fixture . GetSut ( addTransaction : false ) ;
432+ var scope = sut . Scope ;
433+ var expectedTransactionName = $ "GET { Fixture . ControllerName } .{ Fixture . ActionName } ";
434+
435+ // Act
436+ scope . Populate ( _fixture . HttpContext , SentryAspNetCoreOptions ) ;
437+
438+ // Assert
439+ Assert . Equal ( expectedTransactionName , scope . TransactionName ) ;
440+ }
441+
442+ [ Fact ]
443+ public void Populate_TransactionIsNullAndRouteNotFound_TransactionNameAsNull ( )
444+ {
445+ // Arrange
446+ var sut = _fixture . GetSutWithEmptyRoute ( addTransaction : false ) ;
447+ var scope = sut . Scope ;
448+
449+ // Act
450+ scope . Populate ( _fixture . HttpContext , SentryAspNetCoreOptions ) ;
451+
452+ // Assert
453+ Assert . Null ( scope . TransactionName ) ;
454+ }
455+
456+ [ Fact ]
457+ public void Populate_TransactionNameSet_TransactionNameSkipped ( )
458+ {
459+ // Arrange
460+ var sut = _fixture . GetSut ( ) ;
461+ var scope = sut . Scope ;
462+ var expectedRoute = "MyRoute" ;
463+ scope . Transaction . Name = expectedRoute ;
464+
465+ // Act
466+ scope . Populate ( _fixture . HttpContext , SentryAspNetCoreOptions ) ;
467+
468+ // Assert
469+ Assert . Equal ( expectedRoute , scope . TransactionName ) ;
470+ }
367471 }
368472}
0 commit comments