44using System . Net ;
55using Xunit ;
66
7- namespace Serilog . Enrichers . ClientInfo . Tests
7+ namespace Serilog . Enrichers . ClientInfo . Tests ;
8+
9+ public class ClientIpEnricherTests
810{
9- public class ClientIpEnricherTests
11+ private const string ForwardHeaderKey = "x-forwarded-for" ;
12+ private readonly IHttpContextAccessor _contextAccessor ;
13+
14+ public ClientIpEnricherTests ( )
15+ {
16+ var httpContext = new DefaultHttpContext ( ) ;
17+ _contextAccessor = Substitute . For < IHttpContextAccessor > ( ) ;
18+ _contextAccessor . HttpContext . Returns ( httpContext ) ;
19+ }
20+
21+ [ Fact ]
22+ public void EnrichLogWithClientIp_ShouldCreateClientIpPropertyWithValue ( )
23+ {
24+ // Arrange
25+ _contextAccessor . HttpContext . Connection . RemoteIpAddress = IPAddress . Parse ( "::1" ) ;
26+
27+ var ipEnricher = new ClientIpEnricher ( ForwardHeaderKey , _contextAccessor ) ;
28+
29+ LogEvent evt = null ;
30+ var log = new LoggerConfiguration ( )
31+ . Enrich . With ( ipEnricher )
32+ . WriteTo . Sink ( new DelegatingSink ( e => evt = e ) )
33+ . CreateLogger ( ) ;
34+
35+ // Act
36+ log . Information ( @"Has an IP property" ) ;
37+
38+ // Assert
39+ Assert . NotNull ( evt ) ;
40+ Assert . True ( evt . Properties . ContainsKey ( "ClientIp" ) ) ;
41+ Assert . Equal ( "::1" , evt . Properties [ "ClientIp" ] . LiteralValue ( ) ) ;
42+ }
43+
44+ [ Fact ]
45+ public void EnrichLogWithClientIp_WhenLogMoreThanOnce_ShouldReadClientIpValueFromHttpContextItems ( )
1046 {
11- private readonly IHttpContextAccessor _contextAccessor ;
12-
13- public ClientIpEnricherTests ( )
14- {
15- var httpContext = new DefaultHttpContext ( ) ;
16- _contextAccessor = Substitute . For < IHttpContextAccessor > ( ) ;
17- _contextAccessor . HttpContext . Returns ( httpContext ) ;
18- }
19-
20- [ Fact ]
21- public void When_Enrich_Log_Event_With_IpEnricher_Should_Contain_ClientIp_Property ( )
22- {
23- // Arrange
24- _contextAccessor . HttpContext . Connection . RemoteIpAddress = IPAddress . Parse ( "::1" ) ;
25-
26- var ipEnricher = new ClientIpEnricher ( _contextAccessor ) ;
27-
28- LogEvent evt = null ;
29- var log = new LoggerConfiguration ( )
30- . Enrich . With ( ipEnricher )
31- . WriteTo . Sink ( new DelegatingSink ( e => evt = e ) )
32- . CreateLogger ( ) ;
33-
34- // Act
35- log . Information ( @"Has an IP property" ) ;
36-
37- // Assert
38- Assert . NotNull ( evt ) ;
39- Assert . True ( evt . Properties . ContainsKey ( "ClientIp" ) ) ;
40- Assert . Equal ( "::1" , evt . Properties [ "ClientIp" ] . LiteralValue ( ) ) ;
41- }
42-
43- [ Fact ]
44- public void When_Enrich_Log_Event_With_IpEnricher_And_Log_More_Than_Once_Should_Read_ClientIp_Value_From_HttpContext_Items ( )
45- {
46- //Arrange
47- _contextAccessor . HttpContext . Connection . RemoteIpAddress = IPAddress . Loopback ;
48- var ipEnricher = new ClientIpEnricher ( _contextAccessor ) ;
49-
50- LogEvent evt = null ;
51- var log = new LoggerConfiguration ( )
52- . Enrich . With ( ipEnricher )
53- . WriteTo . Sink ( new DelegatingSink ( e => evt = e ) )
54- . CreateLogger ( ) ;
55-
56- // Act
57- log . Information ( @"Has an IP property" ) ;
58- log . Information ( @"Has an other IP property" ) ;
59-
60- // Assert
61- Assert . NotNull ( evt ) ;
62- Assert . True ( evt . Properties . ContainsKey ( "ClientIp" ) ) ;
63- Assert . Equal ( IPAddress . Loopback . ToString ( ) , evt . Properties [ "ClientIp" ] . LiteralValue ( ) ) ;
64- }
65-
66- [ Fact ]
67- public void When_Enrich_Log_Event_With_IpEnricher_AndRequest_Contain_ForwardHeader_Should_Read_ClientIp_Value_From_Header_Value ( )
68- {
69- //Arrange
70- _contextAccessor . HttpContext . Connection . RemoteIpAddress = IPAddress . Loopback ;
71- _contextAccessor . HttpContext . Request . Headers . Add ( ClinetIpConfiguration . XForwardHeaderName , IPAddress . Broadcast . ToString ( ) ) ;
72-
73- var ipEnricher = new ClientIpEnricher ( _contextAccessor ) ;
74-
75- LogEvent evt = null ;
76- var log = new LoggerConfiguration ( )
77- . Enrich . With ( ipEnricher )
78- . WriteTo . Sink ( new DelegatingSink ( e => evt = e ) )
79- . CreateLogger ( ) ;
80-
81- // Act
82- log . Information ( @"Has an IP property" ) ;
83-
84- // Assert
85- Assert . NotNull ( evt ) ;
86- Assert . True ( evt . Properties . ContainsKey ( "ClientIp" ) ) ;
87- Assert . Equal ( IPAddress . Broadcast . ToString ( ) , evt . Properties [ "ClientIp" ] . LiteralValue ( ) ) ;
88- }
89-
90- [ Fact ]
91- public void When_Enrich_Log_Event_With_IpEnricher_With_Custom_XForwardHeader_AndRequest_Contain_ForwardHeader_Should_Read_ClientIp_Value_From_Header_Value ( )
92- {
93- //Arrange
94- const string customForwardHeader = "CustomForwardHeader" ;
95- _contextAccessor . HttpContext . Connection . RemoteIpAddress = IPAddress . Loopback ;
96- _contextAccessor . HttpContext . Request . Headers . Add ( customForwardHeader , IPAddress . Broadcast . ToString ( ) ) ;
97-
98- var ipEnricher = new ClientIpEnricher ( _contextAccessor ) ;
99- ClinetIpConfiguration . XForwardHeaderName = customForwardHeader ;
100-
101- LogEvent evt = null ;
102- var log = new LoggerConfiguration ( )
103- . Enrich . With ( ipEnricher )
104- . WriteTo . Sink ( new DelegatingSink ( e => evt = e ) )
105- . CreateLogger ( ) ;
106-
107- // Act
108- log . Information ( @"Has an IP property" ) ;
109-
110- // Assert
111- Assert . NotNull ( evt ) ;
112- Assert . True ( evt . Properties . ContainsKey ( "ClientIp" ) ) ;
113- Assert . Equal ( IPAddress . Broadcast . ToString ( ) , evt . Properties [ "ClientIp" ] . LiteralValue ( ) ) ;
114- }
47+ //Arrange
48+ _contextAccessor . HttpContext . Connection . RemoteIpAddress = IPAddress . Loopback ;
49+ var ipEnricher = new ClientIpEnricher ( ForwardHeaderKey , _contextAccessor ) ;
50+
51+ LogEvent evt = null ;
52+ var log = new LoggerConfiguration ( )
53+ . Enrich . With ( ipEnricher )
54+ . WriteTo . Sink ( new DelegatingSink ( e => evt = e ) )
55+ . CreateLogger ( ) ;
56+
57+ // Act
58+ log . Information ( @"Has an IP property" ) ;
59+ log . Information ( @"Has an other IP property" ) ;
60+
61+ // Assert
62+ Assert . NotNull ( evt ) ;
63+ Assert . True ( evt . Properties . ContainsKey ( "ClientIp" ) ) ;
64+ Assert . Equal ( IPAddress . Loopback . ToString ( ) , evt . Properties [ "ClientIp" ] . LiteralValue ( ) ) ;
65+ }
66+
67+ [ Fact ]
68+ public void EnrichLogWithClientIp_WhenRequestContainForwardHeader_ShouldCreateClientIpPropertyWithValue ( )
69+ {
70+ //Arrange
71+ _contextAccessor . HttpContext . Connection . RemoteIpAddress = IPAddress . Loopback ;
72+ _contextAccessor . HttpContext . Request . Headers . Add ( ForwardHeaderKey , IPAddress . Broadcast . ToString ( ) ) ;
73+
74+ var ipEnricher = new ClientIpEnricher ( ForwardHeaderKey , _contextAccessor ) ;
75+
76+ LogEvent evt = null ;
77+ var log = new LoggerConfiguration ( )
78+ . Enrich . With ( ipEnricher )
79+ . WriteTo . Sink ( new DelegatingSink ( e => evt = e ) )
80+ . CreateLogger ( ) ;
81+
82+ // Act
83+ log . Information ( @"Has an IP property" ) ;
84+
85+ // Assert
86+ Assert . NotNull ( evt ) ;
87+ Assert . True ( evt . Properties . ContainsKey ( "ClientIp" ) ) ;
88+ Assert . Equal ( IPAddress . Broadcast . ToString ( ) , evt . Properties [ "ClientIp" ] . LiteralValue ( ) ) ;
89+ }
90+
91+ [ Fact ]
92+ public void EnrichLogWithClientIp_WithCustomForwardHeaderAndRequest_ShouldCreateClientIpPropertyWithValue ( )
93+ {
94+ //Arrange
95+ const string customForwardHeader = "CustomForwardHeader" ;
96+ _contextAccessor . HttpContext . Connection . RemoteIpAddress = IPAddress . Loopback ;
97+ _contextAccessor . HttpContext . Request . Headers . Add ( customForwardHeader , IPAddress . Broadcast . ToString ( ) ) ;
98+
99+ var ipEnricher = new ClientIpEnricher ( customForwardHeader , _contextAccessor ) ;
100+
101+ LogEvent evt = null ;
102+ var log = new LoggerConfiguration ( )
103+ . Enrich . With ( ipEnricher )
104+ . WriteTo . Sink ( new DelegatingSink ( e => evt = e ) )
105+ . CreateLogger ( ) ;
106+
107+ // Act
108+ log . Information ( @"Has an IP property" ) ;
109+
110+ // Assert
111+ Assert . NotNull ( evt ) ;
112+ Assert . True ( evt . Properties . ContainsKey ( "ClientIp" ) ) ;
113+ Assert . Equal ( IPAddress . Broadcast . ToString ( ) , evt . Properties [ "ClientIp" ] . LiteralValue ( ) ) ;
114+ }
115+
116+ [ Fact ]
117+ public void WithClientIp_ThenLoggerIsCalled_ShouldNotThrowException ( )
118+ {
119+ // Arrange
120+ var logger = new LoggerConfiguration ( )
121+ . Enrich . WithClientIp ( )
122+ . WriteTo . Sink ( new DelegatingSink ( e => { } ) )
123+ . CreateLogger ( ) ;
124+
125+ // Act
126+ var exception = Record . Exception ( ( ) => logger . Information ( "LOG" ) ) ;
127+
128+ // Assert
129+ Assert . Null ( exception ) ;
115130 }
116131}
0 commit comments