/*
 * $Id: TestPropertyMessageResources.java 480549 2006-11-29 12:16:15Z niallp $
 *
 * 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.
 */

package org.apache.struts.util;

import java.util.Locale;

import org.apache.struts.config.MessageResourcesConfig;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * Unit tests for PropertyMessageResources.
 *
 * @version $Revision: 480549 $
 */
public class TestPropertyMessageResources {

    /** FOO_RESOURCES */
    private static final String FOO_RESOURCES = "org.apache.struts.util.Foo";

    /** defaultLocale */
    private Locale defaultLocale;

    // ----------------------------------------------------------------- Basics

    // ----------------------------------------------------- Setup and Teardown

    /**
     * setUp
     */
    @Before
    public void setUp() {
        // cache the default locale
        this.defaultLocale = Locale.getDefault();
    }

    /**
     * tearDown
     */
    @After
    public void tearDown() {
        // restore the default locale
        Locale.setDefault(this.defaultLocale);
    }

    /**
     * Test JSTL compatible PropertyMessageResources behaviour
     */
    @Test
    public void testJstlMode() {

        Locale.setDefault(Locale.US);

        // Create message resources - default Struts Behaviour
        MessageResources resources = createMessageResources("JSTL");

        // Test language (& default) only keys
        Assert.assertEquals("key.lang FRANCE", "LANG default",
                resources.getMessage(Locale.FRANCE, "key.lang"));
        Assert.assertEquals("key.lang English", "LANG en",
                resources.getMessage(Locale.ENGLISH, "key.lang"));
        Assert.assertEquals("key.lang US", "LANG en",
                resources.getMessage(Locale.US, "key.lang"));
        Assert.assertEquals("key.lang ITALY", "LANG default",
                resources.getMessage(Locale.ITALY, "key.lang"));
        Assert.assertEquals("key.lang German", "LANG de",
                resources.getMessage(Locale.GERMAN, "key.lang"));
        Assert.assertEquals("key.lang GERMANY", "LANG de",
                resources.getMessage(Locale.GERMANY, "key.lang"));

        // Test country (& default) only keys
        Assert.assertEquals("key.country FRANCE", "COUNTRY default",
                resources.getMessage(Locale.FRANCE, "key.country"));
        Assert.assertEquals("key.country English", "COUNTRY default",
                resources.getMessage(Locale.ENGLISH, "key.country"));
        Assert.assertEquals("key.country US", "COUNTRY en_US",
                resources.getMessage(Locale.US, "key.country"));
        Assert.assertEquals("key.country ITALY", "COUNTRY default",
                resources.getMessage(Locale.ITALY, "key.country"));
        Assert.assertEquals("key.country German", "COUNTRY default",
                resources.getMessage(Locale.GERMAN, "key.country"));
        Assert.assertEquals("key.country GERMANY", "COUNTRY de_DE",
                resources.getMessage(Locale.GERMANY, "key.country"));

        // Test Unique Keys with wrong Locale
        Assert.assertNull("Wrong Locale en only",
                resources.getMessage(Locale.GERMAN, "key.en"));
        Assert.assertNull("Wrong Locale en_US only",
                resources.getMessage(Locale.GERMANY, "key.en_US"));

        // Run tests with common expected results
        commonTests(resources);

    }

    /**
     * Test "PropertyResourceBundle" compatible PropertyMessageResources behaviour
     */
    @Test
    public void testResourceBundleMode() {

        Locale.setDefault(Locale.US);

        // Create message resources - default Struts Behaviour
        MessageResources resources = createMessageResources("RESOURCE");

        // Test language (& default) only keys
        Assert.assertEquals("key.lang FRANCE", "LANG en",
                resources.getMessage(Locale.FRANCE, "key.lang"));
        Assert.assertEquals("key.lang English", "LANG en",
                resources.getMessage(Locale.ENGLISH, "key.lang"));
        Assert.assertEquals("key.lang US", "LANG en",
                resources.getMessage(Locale.US, "key.lang"));
        Assert.assertEquals("key.lang ITALY", "LANG en",
                resources.getMessage(Locale.ITALY, "key.lang"));
        Assert.assertEquals("key.lang German", "LANG de",
                resources.getMessage(Locale.GERMAN, "key.lang"));
        Assert.assertEquals("key.lang GERMANY", "LANG de",
                resources.getMessage(Locale.GERMANY, "key.lang"));

        // Test country (& default) only keys
        Assert.assertEquals("key.country FRANCE", "COUNTRY en_US",
                resources.getMessage(Locale.FRANCE, "key.country"));
        Assert.assertEquals("key.country English", "COUNTRY en_US",
                resources.getMessage(Locale.ENGLISH, "key.country"));
        Assert.assertEquals("key.country US", "COUNTRY en_US",
                resources.getMessage(Locale.US, "key.country"));
        Assert.assertEquals("key.country ITALY", "COUNTRY en_US",
                resources.getMessage(Locale.ITALY, "key.country"));
        Assert.assertEquals("key.country German", "COUNTRY en_US",
                resources.getMessage(Locale.GERMAN, "key.country"));
        Assert.assertEquals("key.country GERMANY", "COUNTRY de_DE",
                resources.getMessage(Locale.GERMANY, "key.country"));

        // Test Unique Keys with wrong Locale
        Assert.assertEquals("Wrong Locale en only", "en only",
                resources.getMessage(Locale.GERMAN, "key.en"));
        Assert.assertEquals("Wrong Locale en_US only", "en_US only",
                resources.getMessage(Locale.GERMANY, "key.en_US"));

        // Run tests with common expected results
        commonTests(resources);
    }

    /**
     * Tests with common expected results
     * @param resources MessageResources
     */
    protected void commonTests(final MessageResources resources) {
        // Test "null" Locale
        Assert.assertEquals("null Locale", "ALL default",
                resources.getMessage(null, "key.all"));

        // Test Default only key with all Locales
        Assert.assertEquals("Check default en", "default only",
                resources.getMessage(Locale.ENGLISH, "key.default"));
        Assert.assertEquals("Check default en_US", "default only",
                resources.getMessage(Locale.US, "key.default"));
        Assert.assertEquals("Check default de", "default only",
                resources.getMessage(Locale.GERMAN, "key.default"));
        Assert.assertEquals("Check default de_DE", "default only",
                resources.getMessage(Locale.GERMANY, "key.default"));

        // Test key in all locales
        Assert.assertEquals("Check ALL en", "ALL en",
                resources.getMessage(Locale.ENGLISH, "key.all"));
        Assert.assertEquals("Check ALL en_US", "ALL en_US",
                resources.getMessage(Locale.US, "key.all"));
        Assert.assertEquals("Check ALL de", "ALL de",
                resources.getMessage(Locale.GERMAN, "key.all"));
        Assert.assertEquals("Check ALL de_DE", "ALL de_DE",
                resources.getMessage(Locale.GERMANY, "key.all"));

        // Test key unique to each locale
        Assert.assertEquals("Check en only", "en only",
                resources.getMessage(Locale.ENGLISH, "key.en"));
        Assert.assertEquals("Check en_US only", "en_US only",
                resources.getMessage(Locale.US, "key.en_US"));
        Assert.assertEquals("Check de only", "de only",
                resources.getMessage(Locale.GERMAN, "key.de"));
        Assert.assertEquals("Check de_DE only", "de_DE only",
                resources.getMessage(Locale.GERMANY, "key.de_DE"));

        // Test unique keys with incorrect Locale
        Assert.assertNull("Missing default",
                resources.getMessage(Locale.ENGLISH, "missing"));
        Assert.assertNull("Missing de only",
                resources.getMessage(Locale.US, "key.de"));
        Assert.assertNull("Missing de_DE only",
                resources.getMessage(Locale.US, "key.de_DE"));
    }

    /**
     * Create the PropertyMessageResources.
     *
     * @param mode String
     * @return MessageResources
     */
    private MessageResources createMessageResources(final String mode) {
        MessageResourcesConfig config = new MessageResourcesConfig();
        config.setParameter(FOO_RESOURCES);
        config.setNull(true);
        if (mode != null) {
            config.setProperty("mode", mode);
        }
        PropertyMessageResourcesFactory factory = new PropertyMessageResourcesFactory();
        return factory.createResources(config);
    }
}
