Skip to content

Commit 8219547

Browse files
authored
Added WithHeader assertion.
Previously it was only possible to assert WithRequestHeaders and WithContentHeaders, which is in line with how the HttpHeaders are implemented. However, for convenience the WithHeader is added which checks both the RequestHeaders and the ContentHeaders. Closes #5
1 parent 6d94112 commit 8219547

File tree

5 files changed

+202
-7
lines changed

5 files changed

+202
-7
lines changed

src/HttpClientTestHelpers/HttpRequestMessageAsserter.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,39 @@ public HttpRequestMessageAsserter WithContentHeader(string headerName, string he
221221
return With(x => x.HasContentHeader(headerName, headerValue), $"content header '{headerName}' and value '{headerValue}'");
222222
}
223223

224+
/// <summary>
225+
/// Asserts whether requests were made with a specific header name. Values are ignored.
226+
/// </summary>
227+
/// <param name="headerName">The name of the header that is expected.</param>
228+
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
229+
public HttpRequestMessageAsserter WithHeader(string headerName)
230+
{
231+
if (string.IsNullOrEmpty(headerName))
232+
{
233+
throw new ArgumentNullException(nameof(headerName));
234+
}
235+
return With(x => x.HasRequestHeader(headerName) || x.HasContentHeader(headerName), $"header '{headerName}'");
236+
}
237+
238+
/// <summary>
239+
/// Asserts whether requests were made with a specific header name and value.
240+
/// </summary>
241+
/// <param name="headerName">The name of the header that is expected.</param>
242+
/// <param name="headerValue">The value of the expected header, supports wildcards.</param>
243+
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
244+
public HttpRequestMessageAsserter WithHeader(string headerName, string headerValue)
245+
{
246+
if (string.IsNullOrEmpty(headerName))
247+
{
248+
throw new ArgumentNullException(nameof(headerName));
249+
}
250+
if (string.IsNullOrEmpty(headerValue))
251+
{
252+
throw new ArgumentNullException(nameof(headerValue));
253+
}
254+
return With(x => x.HasRequestHeader(headerName, headerValue) || x.HasContentHeader(headerName, headerValue), $"header '{headerName}' and value '{headerValue}'");
255+
}
256+
224257
/// <summary>
225258
/// Asserts that a specific amount of requests were made.
226259
/// </summary>

src/HttpClientTestHelpers/HttpRequestMessageExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ public static bool HasContentHeader(this HttpRequestMessage httpRequestMessage,
206206

207207
private static bool HasHeader(this HttpHeaders headers, string headerName)
208208
{
209-
return headers.Contains(headerName);
209+
return headers.TryGetValues(headerName, out _);
210210
}
211211

212212
private static bool HasHeader(this HttpHeaders headers, string headerName, string headerValue)

test/HttpClientTestHelpers.Tests/HttpRequestMessageAsserterTests.cs

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,147 @@ public void WithContentHeaderNameAndValue_RequestWithMatchinHeader_ReturnsHttpRe
414414
Assert.IsType<HttpRequestMessageAsserter>(result);
415415
}
416416

417+
#nullable disable
418+
[Theory]
419+
[InlineData(null)]
420+
[InlineData("")]
421+
public void WithHeader_NullOrEmptyHeaderName_ThrowsArgumentNullException(string headerName)
422+
{
423+
var sut = new HttpRequestMessageAsserter(Enumerable.Empty<HttpRequestMessage>());
424+
425+
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithHeader(headerName));
426+
427+
Assert.Equal("headerName", exception.ParamName);
428+
}
429+
#nullable restore
430+
431+
[Fact]
432+
public void WithHeader_NoRequests_ThrowsHttpRequestMessageAssertionExceptionWithSpecificMessage()
433+
{
434+
var sut = new HttpRequestMessageAsserter(Enumerable.Empty<HttpRequestMessage>());
435+
436+
var exception = Assert.Throws<HttpRequestMessageAssertionException>(() => sut.WithHeader("Content-Type"));
437+
438+
Assert.Equal("Expected at least one request to be made with header 'Content-Type', but no requests were made.", exception.Message);
439+
}
440+
441+
[Fact]
442+
public void WithHeader_NoMatchingRequests_ThrowsHttpRequestMessageAssertionExceptionWithSpecificMessage()
443+
{
444+
var sut = new HttpRequestMessageAsserter(new[] { new HttpRequestMessage() });
445+
446+
var exception = Assert.Throws<HttpRequestMessageAssertionException>(() => sut.WithHeader("Content-Type"));
447+
448+
Assert.Equal("Expected at least one request to be made with header 'Content-Type', but no requests were made.", exception.Message);
449+
}
450+
451+
[Theory]
452+
[InlineData("Host")]
453+
[InlineData("Content-Type")]
454+
public void WithHeader_MatchingRequest_ReturnsHttpRequestMessageAsserter(string headerName)
455+
{
456+
var request = new HttpRequestMessage();
457+
request.Headers.Host = "host";
458+
request.Content = new StringContent("");
459+
var sut = new HttpRequestMessageAsserter(new[] { request });
460+
461+
var result = sut.WithHeader(headerName);
462+
463+
Assert.NotNull(result);
464+
Assert.IsType<HttpRequestMessageAsserter>(result);
465+
}
466+
467+
#nullable disable
468+
[Theory]
469+
[InlineData(null)]
470+
[InlineData("")]
471+
public void WithHeaderNameAndValue_NullOrEmptyHeaderName_ThrowsArgumentNullException(string headerName)
472+
{
473+
var sut = new HttpRequestMessageAsserter(Enumerable.Empty<HttpRequestMessage>());
474+
475+
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithHeader(headerName, "someValue"));
476+
477+
Assert.Equal("headerName", exception.ParamName);
478+
}
479+
480+
[Theory]
481+
[InlineData(null)]
482+
[InlineData("")]
483+
public void WithHeaderNameAndValue_NullOrEmptyValue_ThrowsArgumentNullException(string headerValue)
484+
{
485+
var sut = new HttpRequestMessageAsserter(Enumerable.Empty<HttpRequestMessage>());
486+
487+
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithHeader("someHeader", headerValue));
488+
489+
Assert.Equal("headerValue", exception.ParamName);
490+
}
491+
#nullable restore
492+
493+
[Fact]
494+
public void WithHeaderNameAndValue_NoRequests_ThrowsHttpRequestMessageAssertionExceptionWithSpecificMessage()
495+
{
496+
var sut = new HttpRequestMessageAsserter(Enumerable.Empty<HttpRequestMessage>());
497+
498+
var exception = Assert.Throws<HttpRequestMessageAssertionException>(() => sut.WithHeader("someHeader", "someValue"));
499+
500+
Assert.Equal("Expected at least one request to be made with header 'someHeader' and value 'someValue', but no requests were made.", exception.Message);
501+
}
502+
503+
[Fact]
504+
public void WithHeaderNameAndValue_RequestWithoutHeaders_ThrowsHttpRequestMessageAssertionExceptionWithSpecificMessage()
505+
{
506+
var request = new HttpRequestMessage();
507+
var sut = new HttpRequestMessageAsserter(new[] { request });
508+
509+
var exception = Assert.Throws<HttpRequestMessageAssertionException>(() => sut.WithHeader("Content-Type", "application/json"));
510+
511+
Assert.Equal("Expected at least one request to be made with header 'Content-Type' and value 'application/json', but no requests were made.", exception.Message);
512+
}
513+
514+
[Fact]
515+
public void WithHeaderNameAndValue_RequestWithNotMatchingHeaderName_ThrowsHttpRequestMessageAssertionExceptionWithSpecificMessage()
516+
{
517+
var request = new HttpRequestMessage();
518+
request.Headers.Host = "test";
519+
request.Content = new StringContent("");
520+
var sut = new HttpRequestMessageAsserter(new[] { request });
521+
522+
var exception = Assert.Throws<HttpRequestMessageAssertionException>(() => sut.WithHeader("Content-Disposition", "inline"));
523+
524+
Assert.Equal("Expected at least one request to be made with header 'Content-Disposition' and value 'inline', but no requests were made.", exception.Message);
525+
}
526+
527+
[Theory]
528+
[InlineData("Content-Type", "application/json")]
529+
[InlineData("Host", "Test")]
530+
public void WithHeaderNameAndValue_RequestWithNotMatchingHeaderValue_ThrowsHttpRequestMessageAssertionExceptionWithSpecificMessage(string name, string value)
531+
{
532+
var request = new HttpRequestMessage();
533+
request.Headers.Host = "example";
534+
request.Content = new StringContent("");
535+
var sut = new HttpRequestMessageAsserter(new[] { request });
536+
537+
var exception = Assert.Throws<HttpRequestMessageAssertionException>(() => sut.WithHeader(name, value));
538+
539+
Assert.Equal($"Expected at least one request to be made with header '{name}' and value '{value}', but no requests were made.", exception.Message);
540+
}
541+
542+
[Theory]
543+
[InlineData("Content-Type", "application/json")]
544+
[InlineData("Host", "Test")]
545+
public void WithHeaderNameAndValue_RequestWithMatchinHeader_ReturnsHttpRequestMessageAssert(string name, string value)
546+
{
547+
var request = new HttpRequestMessage();
548+
request.Headers.Host = "Test";
549+
request.Content = new StringContent("", Encoding.UTF8, "application/json");
550+
var sut = new HttpRequestMessageAsserter(new[] { request });
551+
552+
var result = sut.WithHeader(name, value);
553+
554+
Assert.NotNull(result);
555+
Assert.IsType<HttpRequestMessageAsserter>(result);
556+
}
557+
417558
[Fact]
418559
public void Times_ValueLessThan0_ThrowsArgumentException()
419560
{

test/HttpClientTestHelpers.Tests/HttpRequestMessageExtensionsTests.HasContentHeader.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,15 @@ public void HasContentHeader_ExistingHeaderName_ReturnsTrue()
6868
Assert.True(sut.HasContentHeader("Content-Disposition"));
6969
}
7070

71-
[Fact]
72-
public void HasContentHeader_NotExistingHeaderName_ReturnsFalse()
71+
[Theory]
72+
[InlineData("Host")]
73+
[InlineData("Content-Disposition")]
74+
public void HasContentHeader_NotExistingHeaderName_ReturnsFalse(string headerName)
7375
{
7476
using var sut = new HttpRequestMessage();
7577
sut.Content = new StringContent("");
7678

77-
Assert.False(sut.HasContentHeader("Content-Disposition"));
79+
Assert.False(sut.HasContentHeader(headerName));
7880
}
7981

8082
[Fact]
@@ -103,6 +105,15 @@ public void HasContentHeader_ExistingHeaderNameMatchingValue_ReturnsTrue(string
103105
Assert.True(sut.HasContentHeader("Content-Disposition", value));
104106
}
105107

108+
[Fact]
109+
public void HasContentHeader_NotExitingHeaderNameAndValue_ReturnsFalse()
110+
{
111+
using var sut = new HttpRequestMessage();
112+
sut.Content = new StringContent("");
113+
114+
Assert.False(sut.HasContentHeader("Host", "inline"));
115+
}
116+
106117
[Theory]
107118
[InlineData("inline; filename=emtpy.file")]
108119
[InlineData("inline; *")]

test/HttpClientTestHelpers.Tests/HttpRequestMessageExtensionsTests.HasRequestHeader.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,14 @@ public void HasRequestHeader_ExistingHeaderName_ReturnsTrue()
6767
Assert.True(sut.HasRequestHeader("Host"));
6868
}
6969

70-
[Fact]
71-
public void HasRequestHeader_NotExistingHeaderName_ReturnsFalse()
70+
[Theory]
71+
[InlineData("Host")]
72+
[InlineData("Content-Type")]
73+
public void HasRequestHeader_NotExistingHeaderName_ReturnsFalse(string headerName)
7274
{
7375
using var sut = new HttpRequestMessage();
7476

75-
Assert.False(sut.HasRequestHeader("Host"));
77+
Assert.False(sut.HasRequestHeader(headerName));
7678
}
7779

7880
[Theory]
@@ -88,6 +90,14 @@ public void HasRequestHeader_ExistingHeaderNameMatchingValue_ReturnsTrue(string
8890
Assert.True(sut.HasRequestHeader("Host", value));
8991
}
9092

93+
[Fact]
94+
public void HasRequestHeader_NotExitingHeaderNameAndValue_ReturnsFalse()
95+
{
96+
using var sut = new HttpRequestMessage();
97+
98+
Assert.False(sut.HasRequestHeader("Content-Type"));
99+
}
100+
91101
[Theory]
92102
[InlineData("example.com")]
93103
[InlineData("example*")]

0 commit comments

Comments
 (0)