001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.test.web.servlet.result; 018 019import java.text.SimpleDateFormat; 020import java.util.Arrays; 021import java.util.Date; 022import java.util.List; 023import java.util.Locale; 024import java.util.TimeZone; 025 026import org.hamcrest.Matcher; 027 028import org.springframework.mock.web.MockHttpServletResponse; 029import org.springframework.test.web.servlet.MvcResult; 030import org.springframework.test.web.servlet.ResultMatcher; 031 032import static org.hamcrest.MatcherAssert.*; 033import static org.springframework.test.util.AssertionErrors.*; 034 035/** 036 * Factory for response header assertions. 037 * 038 * <p>An instance of this class is available via 039 * {@link MockMvcResultMatchers#header}. 040 * 041 * @author Rossen Stoyanchev 042 * @author Sam Brannen 043 * @author Brian Clozel 044 * @since 3.2 045 */ 046public class HeaderResultMatchers { 047 048 /** 049 * Protected constructor. 050 * See {@link MockMvcResultMatchers#header()}. 051 */ 052 protected HeaderResultMatchers() { 053 } 054 055 056 /** 057 * Assert the primary value of the response header with the given Hamcrest 058 * String {@code Matcher}. 059 */ 060 public ResultMatcher string(final String name, final Matcher<? super String> matcher) { 061 return new ResultMatcher() { 062 @Override 063 public void match(MvcResult result) { 064 assertThat("Response header '" + name + "'", result.getResponse().getHeader(name), matcher); 065 } 066 }; 067 } 068 069 /** 070 * Assert the values of the response header with the given Hamcrest 071 * Iterable {@link Matcher}. 072 * @since 4.3 073 */ 074 public <T> ResultMatcher stringValues(final String name, final Matcher<Iterable<String>> matcher) { 075 return new ResultMatcher() { 076 @Override 077 public void match(MvcResult result) { 078 List<String> values = result.getResponse().getHeaders(name); 079 assertThat("Response header '" + name + "'", values, matcher); 080 } 081 }; 082 } 083 084 /** 085 * Assert the primary value of the response header as a String value. 086 */ 087 public ResultMatcher string(final String name, final String value) { 088 return new ResultMatcher() { 089 @Override 090 public void match(MvcResult result) { 091 assertEquals("Response header '" + name + "'", value, result.getResponse().getHeader(name)); 092 } 093 }; 094 } 095 096 /** 097 * Assert the values of the response header as String values. 098 * @since 4.3 099 */ 100 public ResultMatcher stringValues(final String name, final String... values) { 101 return new ResultMatcher() { 102 @Override 103 public void match(MvcResult result) { 104 List<Object> actual = result.getResponse().getHeaderValues(name); 105 assertEquals("Response header '" + name + "'", Arrays.asList(values), actual); 106 } 107 }; 108 } 109 110 /** 111 * Assert that the named response header does not exist. 112 * @since 4.0 113 */ 114 public ResultMatcher doesNotExist(final String name) { 115 return new ResultMatcher() { 116 @Override 117 public void match(MvcResult result) { 118 assertTrue("Response should not contain header '" + name + "'", 119 !result.getResponse().containsHeader(name)); 120 } 121 }; 122 } 123 124 /** 125 * Assert the primary value of the named response header as a {@code long}. 126 * <p>The {@link ResultMatcher} returned by this method throws an 127 * {@link AssertionError} if the response does not contain the specified 128 * header, or if the supplied {@code value} does not match the primary value. 129 */ 130 public ResultMatcher longValue(final String name, final long value) { 131 return new ResultMatcher() { 132 @Override 133 public void match(MvcResult result) { 134 MockHttpServletResponse response = result.getResponse(); 135 assertTrue("Response does not contain header '" + name + "'", response.containsHeader(name)); 136 assertEquals("Response header '" + name + "'", value, Long.parseLong(response.getHeader(name))); 137 } 138 }; 139 } 140 141 /** 142 * Assert the primary value of the named response header as a date String, 143 * using the preferred date format described in RFC 7231. 144 * <p>The {@link ResultMatcher} returned by this method throws an 145 * {@link AssertionError} if the response does not contain the specified 146 * header, or if the supplied {@code value} does not match the primary value. 147 * @see <a href="https://tools.ietf.org/html/rfc7231#section-7.1.1.1">Section 7.1.1.1 of RFC 7231</a> 148 * @since 4.2 149 */ 150 public ResultMatcher dateValue(final String name, final long value) { 151 return new ResultMatcher() { 152 @Override 153 public void match(MvcResult result) { 154 SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US); 155 format.setTimeZone(TimeZone.getTimeZone("GMT")); 156 String formatted = format.format(new Date(value)); 157 MockHttpServletResponse response = result.getResponse(); 158 assertTrue("Response does not contain header '" + name + "'", response.containsHeader(name)); 159 assertEquals("Response header '" + name + "'", formatted, response.getHeader(name)); 160 } 161 }; 162 } 163 164}