Apache2-API

 view release on metacpan or  search on metacpan

t/07.accept.t  view on Meta::CPAN

# type/* wins over */* and specificity considered
is_match(
    'text/*;q=0.7, */*;q=0.2, application/json;q=0.9',
    [ 'image/png', 'application/json', 'text/html' ],
    'application/json',
    'Specific type beats ranges via q'
);

# Test wildcard
# */* returns first supported
is_match(
    '*/*;q=0.3',
    [ 'application/json', 'text/html' ],
    'application/json',
    'Wildcard */* returns first supported'
);

is_match(
    '*/*;q=0.5',
    ['text/plain', 'image/jpeg'],
    'text/plain',
    'Wildcard */* returns first supported (bis)',
);

# Test no header
# Empty/undefined header => first supported
is_match(
    '',
    [ 'application/json', 'text/html' ],
    'application/json',
    'Empty header means all acceptable'
);

# Test specificity
is_match(
    'text/html;q=0.9,text/*;q=0.9',
    ['text/plain', 'text/html'],
    'text/html',
    'More specific wins at same q',
);

# No supported items => '' (not undef)
{
    no warnings 'Apache2::API';
    my $ac = Apache2::API::Headers::Accept->new( 'text/html' );
    is( scalar( $ac->match( [] ) ), '', 'Empty supported => empty string' );
}

# Wrong type => undef + error
{
    my $ac = Apache2::API::Headers::Accept->new( 'text/html' );
    my $got = $ac->match( { 'not' => 'an array' } );
    ok( !defined $got, 'Wrong type returns undef' );
    ok( defined $ac->error, 'Error is set' );
}

subtest 'edge cases' => sub
{
    # Parameters other than q are ignored for matching
    my $ac;
    $ac = Apache2::API::Headers::Accept->new( 'text/html; charset=UTF-8; q=0.8, application/json;version=2', debug => $DEBUG );
    is( $ac->match( [ 'application/json', 'text/html' ] ), 'application/json', 'Non-q params ignored; json (no q -> 1.0) wins' );

    # Duplicate media types use best q
    $ac = Apache2::API::Headers::Accept->new( 'text/html;q=0.3, text/html;q=0.8, application/json;q=0.7', debug => $DEBUG );
    is( $ac->match( [ 'text/html', 'application/json' ] ), 'text/html', 'Duplicate token keeps highest q' );

    # q=0 excludes a token
    $ac = Apache2::API::Headers::Accept->new( 'application/json;q=0, text/html;q=0.5', debug => $DEBUG );
    is( $ac->match( [ 'application/json', 'text/html' ] ), 'text/html', 'q=0 excludes token' );

    # type/* vs exact specificity
    $ac = Apache2::API::Headers::Accept->new( 'text/*;q=0.9, text/html;q=0.9', debug => $DEBUG );
    is( $ac->match( [ 'text/plain', 'text/html' ] ), 'text/html', 'Exact more specific than type/* at same q' );

    # */* with higher q than specific type
    $ac = Apache2::API::Headers::Accept->new( '*/*;q=1.0, text/html;q=0.9', debug => $DEBUG );
    is( $ac->match( [ 'text/html', 'application/json' ] ), 'text/html', 'Wildcard still chooses first supported (text/html first)' );

    # Test invalid header
    $ac = Apache2::API::Headers::Accept->new( 'invalid', debug => $DEBUG );
    ok( !$ac->preferences->[0], 'Invalid header: empty preferences' );

    # Test empty supported
    {
        no warnings 'Apache2::API';
        is( $ac->match([]), '', 'Empty supported: empty string' );
    }

    # Test error handling
    $ac = Apache2::API::Headers::Accept->new( 'text/html', debug => $DEBUG );
    my $rv = $ac->match( 'not array' );
    ok( !defined( $rv ), 'Non-array supported: error');
    like( $ac->error->message, qr/not an array reference/, 'Error message correct' );

    # Test with parameters (ignored in matching)
    $ac = Apache2::API::Headers::Accept->new( 'text/html;level=1;q=0.9', debug => $DEBUG );
    is( $ac->match( ['text/html'] ), 'text/html', 'Parameters ignored in match' );

    # Test multiple same type different q
    $ac = Apache2::API::Headers::Accept->new( 'text/html;q=0.5,text/html;q=0.9', debug => $DEBUG );
    is_deeply( $ac->preferences, ['text/html'], 'Keeps highest q for duplicate' );

    {
        # Test 0.01 style priority
        local $Apache2::API::Headers::Accept::MATCH_PRIORITY_0_01_STYLE = 1;
        $ac = Apache2::API::Headers::Accept->new( 'text/html;q=0.5,application/json;q=0.5', debug => $DEBUG );
        is( $ac->match( ['application/json', 'text/html'] ), 'application/json', '0.01 style: supported order' );
    }

    # Wildcard and specific at the same q -> prefer the specific (modern mode)
    {
        local $Apache2::API::Headers::AcceptCommon::MATCH_PRIORITY_0_01_STYLE = 0;
        my $ac = Apache2::API::Headers::Accept->new( '*/*;q=0.9, application/json;q=0.9', debug => $DEBUG );
        is(
            $ac->match( [ 'image/png', 'text/html', 'application/json' ] ),
            'application/json',
            'Equal q: specific beats wildcard in modern mode'
        );
    }



( run in 1.003 second using v1.01-cache-2.11-cpan-13bb782fe5a )