/*
 * 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.axis2.jaxws.endpoint;

import junit.framework.TestCase;

import javax.jws.WebService;
import javax.xml.ws.Binding;
import javax.xml.ws.Endpoint;
import javax.xml.ws.soap.SOAPBinding;

public class BasicEndpointTests extends TestCase {

    public void testCreateSimpleEndpoint() {
        SampleEndpoint sample = new SampleEndpoint();
        
        Endpoint ep = Endpoint.create(sample);
        assertTrue("The returned Endpoint instance was null", ep != null);
        
        ep.publish("test");
        assertTrue("The endpoint was not published successfully", ep.isPublished());
        ep.stop();
    }
    
    public void testCreateAndPublishEndpoint() {
        SampleEndpoint sample = new SampleEndpoint();

        Endpoint ep = Endpoint.publish("test" , sample);
        assertTrue("The returned Endpoint instance was null", ep != null);
        assertTrue("The endpoint was not published successfully", ep.isPublished());
        ep.stop();
    }
    
    public void testGetBinding() throws Exception {
        SampleEndpoint sample = new SampleEndpoint();

        Endpoint ep = Endpoint.create(sample);
        assertTrue("The returned Endpoint instance was null", ep != null);

        Binding bnd = ep.getBinding();
        assertTrue("The returned Binding instance was null", bnd != null);
        assertTrue("The returned Binding instance was of the wrong type (" + bnd.getClass().getName() + "), expected SOAPBinding", 
                SOAPBinding.class.isAssignableFrom(bnd.getClass()));
        ep.stop();
    }

    public void testCreateAndPublishOnAlternatePort() throws Exception {
        Endpoint ep = Endpoint.create(new SampleEndpoint());
        ep.publish("http://localhost:16060/SampleEndpoint");
        assertTrue("The returned Endpoint instance was null", ep != null);
        assertTrue("The endpoint was not published successfully", ep.isPublished());
        ep.stop();
    }

    @WebService
    class SampleEndpoint {
        
        public int foo(String bar) {
            return bar.length();
        }
    }
}