/*
* Copyright (c) 2014 the original author or authors
*
* Licensed 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 io.werval.runtime.http;
import io.werval.api.outcomes.Outcome;
import io.werval.runtime.routes.RoutesParserProvider;
import io.werval.test.WervalHttpRule;
import org.junit.ClassRule;
import org.junit.Test;
import static com.jayway.restassured.RestAssured.expect;
import static com.jayway.restassured.RestAssured.given;
import static io.werval.api.context.CurrentContext.outcomes;
import static io.werval.api.context.CurrentContext.request;
import static io.werval.api.http.Headers.Names.ACCEPT;
import static io.werval.api.http.Headers.Names.VARY;
import static io.werval.api.mime.MimeTypes.APPLICATION_JSON;
import static io.werval.api.mime.MimeTypes.TEXT_HTML;
import static io.werval.api.mime.MimeTypes.WILDCARD_MIMETYPE;
import static org.hamcrest.Matchers.equalTo;
/**
* Content Negotiation Test.
*/
public class ContentNegotiationTest
{
public static class Controller
{
public Outcome accepted()
{
return outcomes()
.ok( request().acceptedMimeTypes().toString() )
.withHeader( VARY, ACCEPT )
.build();
}
public Outcome preferredEmpty()
{
switch( request().preferredMimeType() )
{
case APPLICATION_JSON:
return outcomes().ok( "{}" ).as( APPLICATION_JSON ).withHeader( VARY, ACCEPT ).build();
case WILDCARD_MIMETYPE:
default:
return outcomes().ok( "<p></p>" ).as( TEXT_HTML ).withHeader( VARY, ACCEPT ).build();
}
}
public Outcome preferredAmong()
{
switch( request().preferredMimeType( TEXT_HTML, APPLICATION_JSON ) )
{
case WILDCARD_MIMETYPE:
case TEXT_HTML:
return outcomes().ok( "<p></p>" ).as( TEXT_HTML ).withHeader( VARY, ACCEPT ).build();
case APPLICATION_JSON:
return outcomes().ok( "{}" ).as( APPLICATION_JSON ).withHeader( VARY, ACCEPT ).build();
default:
return outcomes().notAcceptable().build();
}
}
}
@ClassRule
public static final WervalHttpRule WERVAL = new WervalHttpRule( new RoutesParserProvider(
"GET /accepted io.werval.runtime.http.ContentNegotiationTest$Controller.accepted\n"
+ "GET /preferredEmpty io.werval.runtime.http.ContentNegotiationTest$Controller.preferredEmpty\n"
+ "GET /preferredAmong io.werval.runtime.http.ContentNegotiationTest$Controller.preferredAmong\n"
) );
@Test
public void acceptedEmpty()
{
expect()
.header( VARY, equalTo( ACCEPT ) )
.body( equalTo( "[*/*]" ) )
.when()
.get( "/accepted" );
}
@Test
public void acceptedSingle()
{
given()
.header( ACCEPT, APPLICATION_JSON )
.expect()
.statusCode( 200 )
.header( VARY, equalTo( ACCEPT ) )
.body( equalTo( "[application/json]" ) )
.when()
.get( "/accepted" );
}
@Test
public void acceptedListBasic()
{
given()
.header( ACCEPT, APPLICATION_JSON + "," + TEXT_HTML )
.expect()
.statusCode( 200 )
.header( VARY, equalTo( ACCEPT ) )
.body( equalTo( "[application/json, text/html]" ) )
.when()
.get( "/accepted" );
}
@Test
public void acceptedListComplex()
{
given()
.header( ACCEPT, "text/*;q=0.3, text/html;q=0.7, text/html;level=1,text/html;level=2;q=0.4, */*;q=0.5" )
.expect()
.statusCode( 200 )
.header( VARY, equalTo( ACCEPT ) )
.body( equalTo( "[text/html;level=1, text/html;q=0.7, */*;q=0.5, text/html;q=0.4;level=2, text/*;q=0.3]" ) )
.when()
.get( "/accepted" );
}
@Test
public void preferredEmptyNoAccept()
{
expect()
.statusCode( 200 )
.header( VARY, equalTo( ACCEPT ) )
.contentType( TEXT_HTML )
.body( equalTo( "<p></p>" ) )
.when()
.get( "/preferredEmpty" );
}
@Test
public void preferredEmptyAcceptJSON()
{
given()
.header( ACCEPT, APPLICATION_JSON )
.expect()
.statusCode( 200 )
.header( VARY, equalTo( ACCEPT ) )
.contentType( APPLICATION_JSON )
.body( equalTo( "{}" ) )
.when()
.get( "/preferredEmpty" );
}
@Test
public void preferredEmptyComplexAccept()
{
given()
.header( ACCEPT, "text/html;q=0.8,application/json;q=0.9" )
.expect()
.statusCode( 200 )
.header( VARY, equalTo( ACCEPT ) )
.contentType( APPLICATION_JSON )
.body( equalTo( "{}" ) )
.when()
.get( "/preferredEmpty" );
}
@Test
public void preferredAmongNoAccept()
{
expect()
.statusCode( 200 )
.header( VARY, equalTo( ACCEPT ) )
.contentType( TEXT_HTML )
.body( equalTo( "<p></p>" ) )
.when()
.get( "/preferredAmong" );
}
@Test
public void preferredAmongUnacceptable()
{
given()
.header( ACCEPT, "text/plain" )
.expect()
.statusCode( 406 )
.when()
.get( "/preferredAmong" );
}
@Test
public void preferredAmongAcceptJSON()
{
given()
.header( ACCEPT, APPLICATION_JSON )
.expect()
.statusCode( 200 )
.header( VARY, equalTo( ACCEPT ) )
.contentType( APPLICATION_JSON )
.body( equalTo( "{}" ) )
.when()
.get( "/preferredAmong" );
}
@Test
public void preferredAmongComplexAccept()
{
given()
.header( ACCEPT, "text/html;q=0.8,application/json;q=0.9" )
.expect()
.statusCode( 200 )
.header( VARY, equalTo( ACCEPT ) )
.contentType( APPLICATION_JSON )
.body( equalTo( "{}" ) )
.when()
.get( "/preferredAmong" );
}
}