/*
 * ====================================================================
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */
package org.apache.http.message;

import org.apache.http.HeaderElement;
import org.apache.http.NameValuePair;
import org.junit.Assert;
import org.junit.Test;

/**
 * Tests for header value formatting.
 *
 *
 */
public class TestBasicHeaderValueFormatter {

    @Test
    public void testNVPFormatting() throws Exception {
        final NameValuePair param1 = new BasicNameValuePair("param", "regular_stuff");
        final NameValuePair param2 = new BasicNameValuePair("param", "this\\that");
        final NameValuePair param3 = new BasicNameValuePair("param", "this,that");
        final NameValuePair param4 = new BasicNameValuePair("param", "quote marks (\") must be escaped");
        final NameValuePair param5 = new BasicNameValuePair("param", "back slash (\\) must be escaped too");
        final NameValuePair param6 = new BasicNameValuePair("param", "values with\tblanks must always be quoted");
        final NameValuePair param7 = new BasicNameValuePair("param", null);


        Assert.assertEquals("param=regular_stuff",
                     BasicHeaderValueFormatter.formatNameValuePair
                     (param1, false, null));
        Assert.assertEquals("param=\"this\\\\that\"",
                     BasicHeaderValueFormatter.formatNameValuePair
                     (param2, false, null));
        Assert.assertEquals("param=\"this,that\"",
                     BasicHeaderValueFormatter.formatNameValuePair
                     (param3, false, null));
        Assert.assertEquals("param=\"quote marks (\\\") must be escaped\"",
                     BasicHeaderValueFormatter.formatNameValuePair
                     (param4, false, null));
        Assert.assertEquals("param=\"back slash (\\\\) must be escaped too\"",
                     BasicHeaderValueFormatter.formatNameValuePair
                     (param5, false, null));
        Assert.assertEquals("param=\"values with\tblanks must always be quoted\"",
                     BasicHeaderValueFormatter.formatNameValuePair
                     (param6, false, null));
        Assert.assertEquals("param", BasicHeaderValueFormatter.formatNameValuePair
                     (param7, false, null));

        Assert.assertEquals("param=\"regular_stuff\"",
                     BasicHeaderValueFormatter.formatNameValuePair
                     (param1, true, null));
        Assert.assertEquals("param=\"this\\\\that\"",
                     BasicHeaderValueFormatter.formatNameValuePair
                     (param2, true, null));
        Assert.assertEquals("param=\"this,that\"",
                     BasicHeaderValueFormatter.formatNameValuePair
                     (param3, true, null));
        Assert.assertEquals("param=\"quote marks (\\\") must be escaped\"",
                     BasicHeaderValueFormatter.formatNameValuePair
                     (param4, true, null));
        Assert.assertEquals("param=\"back slash (\\\\) must be escaped too\"",
                     BasicHeaderValueFormatter.formatNameValuePair
                     (param5, true, null));
        Assert.assertEquals("param=\"values with\tblanks must always be quoted\"",
                     BasicHeaderValueFormatter.formatNameValuePair
                     (param6, true, null));
        Assert.assertEquals("param",
                     BasicHeaderValueFormatter.formatNameValuePair
                     (param7, false, null));
    }



    @Test
    public void testParamsFormatting() throws Exception {
        final NameValuePair param1 = new BasicNameValuePair("param", "regular_stuff");
        final NameValuePair param2 = new BasicNameValuePair("param", "this\\that");
        final NameValuePair param3 = new BasicNameValuePair("param", "this,that");
        final NameValuePair[] params = new NameValuePair[] {param1, param2, param3};
        Assert.assertEquals("param=regular_stuff; param=\"this\\\\that\"; param=\"this,that\"",
                     BasicHeaderValueFormatter.formatParameters(params, false, null));
        Assert.assertEquals("param=\"regular_stuff\"; param=\"this\\\\that\"; param=\"this,that\"",
                     BasicHeaderValueFormatter.formatParameters(params, true, null));
    }



    @Test
    public void testHEFormatting() throws Exception {
        final NameValuePair param1 = new BasicNameValuePair("param", "regular_stuff");
        final NameValuePair param2 = new BasicNameValuePair("param", "this\\that");
        final NameValuePair param3 = new BasicNameValuePair("param", "this,that");
        final NameValuePair param4 = new BasicNameValuePair("param", null);
        final NameValuePair[] params = new NameValuePair[] {param1, param2, param3, param4};
        final HeaderElement element = new BasicHeaderElement("name", "value", params);

        Assert.assertEquals("name=value; param=regular_stuff; param=\"this\\\\that\"; param=\"this,that\"; param",
                     BasicHeaderValueFormatter.formatHeaderElement(element, false, null));
    }

    @Test
    public void testElementsFormatting() throws Exception {
        final NameValuePair param1 = new BasicNameValuePair("param", "regular_stuff");
        final NameValuePair param2 = new BasicNameValuePair("param", "this\\that");
        final NameValuePair param3 = new BasicNameValuePair("param", "this,that");
        final NameValuePair param4 = new BasicNameValuePair("param", null);
        final HeaderElement element1 = new BasicHeaderElement("name1", "value1", new NameValuePair[] {param1});
        final HeaderElement element2 = new BasicHeaderElement("name2", "value2", new NameValuePair[] {param2});
        final HeaderElement element3 = new BasicHeaderElement("name3", "value3", new NameValuePair[] {param3});
        final HeaderElement element4 = new BasicHeaderElement("name4", "value4", new NameValuePair[] {param4});
        final HeaderElement element5 = new BasicHeaderElement("name5", null);
        final HeaderElement[] elements = new HeaderElement[] {element1, element2, element3, element4, element5};

        Assert.assertEquals
            ("name1=value1; param=regular_stuff, name2=value2; " +
             "param=\"this\\\\that\", name3=value3; param=\"this,that\", " +
             "name4=value4; param, name5",
             BasicHeaderValueFormatter.formatElements(elements, false, null));
    }


    @Test
    public void testInvalidHEArguments() throws Exception {
        try {
            BasicHeaderValueFormatter.formatHeaderElement
                ((HeaderElement) null, false,
                 BasicHeaderValueFormatter.INSTANCE);
            Assert.fail("IllegalArgumentException should habe been thrown");
        } catch (final IllegalArgumentException ex) {
            // expected
        }

        try {
            BasicHeaderValueFormatter.formatElements
                ((HeaderElement[]) null, false,
                 BasicHeaderValueFormatter.INSTANCE);
            Assert.fail("IllegalArgumentException should habe been thrown");
        } catch (final IllegalArgumentException ex) {
            // expected
        }
    }


    @Test
    public void testInvalidNVArguments() throws Exception {

        try {
            BasicHeaderValueFormatter.formatNameValuePair
                ((NameValuePair) null, true, null);
            Assert.fail("IllegalArgumentException should habe been thrown");
        } catch (final IllegalArgumentException ex) {
            // expected
        }

        try {
            BasicHeaderValueFormatter.formatParameters
                ((NameValuePair[]) null, true,
                 BasicHeaderValueFormatter.INSTANCE);
            Assert.fail("IllegalArgumentException should habe been thrown");
        } catch (final IllegalArgumentException ex) {
            // expected
        }
    }


}
