/// <summary> /// Compares the headers in the current HttpResponse instance with the headers in the actual response /// and returns a set of validation errors for any important differences. /// </summary> /// <param name="actual">The actual response that is compared with the expected (current object) response.</param> /// <param name="errors">An array of errors that were generated by the validation</param> /// <returns>A boolean that is True if the response is valid (no significant errors or warnings detected) or False if errors exist.</returns> public bool ValidateResponseHeaders(HttpResponse actual, out ValidationError[] errors, IEnumerable <int> allowedStatusCodes = null) { if (actual == null) { throw new ArgumentNullException("actual"); } List <ValidationError> errorList = new List <ValidationError>(); // Check the HTTP status code bool usedAllowedStatusCode = false; if (this.StatusCode != actual.StatusCode) { if (null != allowedStatusCodes && allowedStatusCodes.Contains(actual.StatusCode)) { errorList.Add(new ValidationWarning(ValidationErrorCode.HttpStatusCodeDifferent, null, "Response uses an allowed status code that was different than the documentation indcaites: Expected status code: {0}, received: {1}.", this.StatusCode, actual.StatusCode)); usedAllowedStatusCode = true; } else { errorList.Add(new ValidationError(ValidationErrorCode.HttpStatusCodeDifferent, null, "Expected status code: {0}, received: {1}.", this.StatusCode, actual.StatusCode)); } } // Check the HTTP status message if (this.StatusMessage != actual.StatusMessage) { errorList.Add(ValidationError.CreateError(usedAllowedStatusCode, ValidationErrorCode.HttpStatusMessageDifferent, null, "Expected status message {0}, received: {1}.", this.StatusMessage, actual.StatusMessage)); } // Check to see that expected headers were found in the response (headers listed in the // expected response must be present in the actual response and contain the same value). List <string> otherResponseHeaderKeys = new List <string>(); if (actual.Headers != null) { otherResponseHeaderKeys.AddRange(actual.Headers.AllKeys); } var comparer = new HeaderNameComparer(); foreach (var expectedHeader in this.Headers.AllKeys) { if (!otherResponseHeaderKeys.Contains(expectedHeader, comparer)) { errorList.Add(new ValidationError(ValidationErrorCode.HttpRequiredHeaderMissing, null, "Response is missing header expected header: {0}.", expectedHeader)); } else if (this.headersForPartialMatch.Contains(expectedHeader.ToLower())) { var expectedValue = this.Headers[expectedHeader]; var actualValue = actual.Headers[expectedHeader]; if (!actualValue.ToLower().StartsWith(expectedValue)) { errorList.Add(new ValidationError(ValidationErrorCode.HttpHeaderValueDifferent, null, "Header '{0}' has unexpected value '{1}' (expected {2})", expectedHeader, actualValue, expectedValue)); } } } errors = errorList.ToArray(); return(!errors.Any(x => x.IsError || x.IsWarning)); }