/*
* Copyright 2017 LINE Corporation
*
* LINE Corporation licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.linecorp.armeria.common;
import static com.linecorp.armeria.common.MediaType.ANY_AUDIO_TYPE;
import static com.linecorp.armeria.common.MediaType.ANY_TYPE;
import static com.linecorp.armeria.common.MediaType.HTML_UTF_8;
import static com.linecorp.armeria.common.MediaType.PLAIN_TEXT_UTF_8;
import static com.linecorp.armeria.common.MediaType.WEBM_VIDEO;
import static org.assertj.core.api.Assertions.assertThat;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.ImmutableList;
public class MediaTypeSetTest {
@Test
public void getters() {
final MediaTypeSet set = new MediaTypeSet(HTML_UTF_8, PLAIN_TEXT_UTF_8);
assertThat(set).containsOnly(HTML_UTF_8, PLAIN_TEXT_UTF_8).hasSize(2);
}
@Test
public void matchList() {
final MediaTypeSet set = new MediaTypeSet(HTML_UTF_8, PLAIN_TEXT_UTF_8);
// No ranges
assertThat(set.match(ImmutableList.of())).isEmpty();
// More than one range
assertThat(set.match(HTML_UTF_8.withParameter("q", "0.5"), PLAIN_TEXT_UTF_8))
.contains(PLAIN_TEXT_UTF_8);
// Wildcard match
assertThat(set.match(ANY_AUDIO_TYPE, ANY_TYPE)).contains(HTML_UTF_8);
// No matches
assertThat(set.match(WEBM_VIDEO)).isEmpty();
}
@Test
public void matchHeaders() {
final MediaTypeSet set = new MediaTypeSet(HTML_UTF_8, PLAIN_TEXT_UTF_8);
// No ranges
assertThat(set.matchHeaders()).isEmpty();
assertThat(set.matchHeaders("")).isEmpty();
assertThat(set.matchHeaders(ImmutableList.of())).isEmpty();
// More than one range
assertThat(set.matchHeaders("text/html; q=0.5, text/plain")).contains(PLAIN_TEXT_UTF_8);
assertThat(set.matchHeaders(ImmutableList.of("text/html, text/plain; q=0.5")))
.contains(HTML_UTF_8);
// Wildcard match
assertThat(set.matchHeaders("audio/*, */*")).contains(HTML_UTF_8);
// No matches
assertThat(set.matchHeaders("video/webm")).isEmpty();
}
@Test
public void moreSpecificRangeWins() {
final MediaType HTML_UTF_8_LEVEL_1 = HTML_UTF_8.withParameter("level", "1");
final MediaTypeSet set = new MediaTypeSet(WEBM_VIDEO,
PLAIN_TEXT_UTF_8,
HTML_UTF_8,
HTML_UTF_8_LEVEL_1);
assertThat(set.matchHeaders("*/*")).contains(WEBM_VIDEO);
assertThat(set.matchHeaders("*/*, text/*")).contains(PLAIN_TEXT_UTF_8);
assertThat(set.matchHeaders("text/*, text/html")).contains(HTML_UTF_8);
assertThat(set.matchHeaders("text/html, text/html; level=0")).contains(HTML_UTF_8);
assertThat(set.matchHeaders("text/html, text/html; level=1")).contains(HTML_UTF_8_LEVEL_1);
}
@Test
public void invalidRange() {
final MediaTypeSet set = new MediaTypeSet(HTML_UTF_8);
assertThat(set.matchHeaders("foo, */*")).contains(HTML_UTF_8);
}
@Test
public void invalidQValue() {
final MediaTypeSet set = new MediaTypeSet(HTML_UTF_8, PLAIN_TEXT_UTF_8);
// A bad qvalue is interpreted as 0.
assertThat(set.matchHeaders("text/*; q=bad, text/plain; q=0.5")).contains(PLAIN_TEXT_UTF_8);
}
@Test
public void parameterMatching() {
final MediaType HTML_US_ASCII = HTML_UTF_8.withCharset(StandardCharsets.US_ASCII);
final MediaTypeSet set = new MediaTypeSet(HTML_UTF_8, HTML_US_ASCII);
assertThat(set.matchHeaders("*/*")).contains(HTML_UTF_8);
// Parameter requirement must be respected.
assertThat(set.matchHeaders("*/*; charset=UTF-8")).contains(HTML_UTF_8);
assertThat(set.matchHeaders("*/*; charset=US-ASCII")).contains(HTML_US_ASCII);
// Case-insensitive comparison
assertThat(set.matchHeaders("*/*; charset=utf-8")).contains(HTML_UTF_8);
assertThat(set.matchHeaders("*/*; charset=us-ascii")).contains(HTML_US_ASCII);
// Parameter requirements did not meet.
assertThat(set.matchHeaders("*/*; charset=UTF-8; mode=foo")).isEmpty();
}
@Test
public void testAddRanges() {
List<MediaType> ranges = new ArrayList<>();
// Single element without whitespaces
MediaTypeSet.addRanges(ranges, "text/plain");
assertThat(ranges).containsExactly(MediaType.parse("text/plain"));
ranges.clear();
// Multiple elements without whitespaces
MediaTypeSet.addRanges(ranges, "text/plain,text/html");
assertThat(ranges).containsExactly(MediaType.parse("text/plain"),
MediaType.parse("text/html"));
ranges.clear();
// Single element with whitespaces
MediaTypeSet.addRanges(ranges, " text/plain ");
assertThat(ranges).containsExactly(MediaType.parse("text/plain"));
ranges.clear();
// Multiple elements with whitespaces
MediaTypeSet.addRanges(ranges, " text/plain , text/html ");
assertThat(ranges).containsExactly(MediaType.parse("text/plain"),
MediaType.parse("text/html"));
ranges.clear();
// Quoted strings
MediaTypeSet.addRanges(ranges, "text/plain; foo=\"b\\\"a,r\", text/html; bar=\"b\\a\\z\"");
assertThat(ranges).containsExactly(MediaType.parse("text/plain; foo=\"b\\\"a,r\""),
MediaType.parse("text/html; bar=baz"));
ranges.clear();
// Empty elements
MediaTypeSet.addRanges(ranges, ",,,");
assertThat(ranges).isEmpty();
ranges.clear();
// Empty elements with whitespaces
MediaTypeSet.addRanges(ranges, " , , , ");
assertThat(ranges).isEmpty();
ranges.clear();
}
}