package org.apache.maven.archiva.web.action.admin.repositories;

/*
 * 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.
 */

import java.util.Arrays;

import com.meterware.servletunit.ServletRunner;
import com.meterware.servletunit.ServletUnitClient;
import com.opensymphony.xwork2.Action;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.stats.DefaultRepositoryStatisticsManager;
import org.apache.archiva.metadata.repository.stats.RepositoryStatistics;
import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager;
import org.codehaus.plexus.spring.PlexusInSpringTestCase;
import org.codehaus.redback.integration.interceptor.SecureActionBundle;
import org.codehaus.redback.integration.interceptor.SecureActionException;
import org.easymock.MockControl;

/**
 * Test the repositories action returns the correct data.
 */
public class RepositoriesActionTest
    extends PlexusInSpringTestCase
{
    private RepositoriesAction action;

    protected void setUp()
        throws Exception
    {
        super.setUp();

        action = (RepositoriesAction) lookup( Action.class.getName(), "repositoriesAction" );
    }

    public void testGetRepositories()
        throws Exception
    {
        MockControl control = MockControl.createControl( MetadataRepository.class );
        MetadataRepository metadataRepository = (MetadataRepository) control.getMock();
        control.expectAndReturn( metadataRepository.getMetadataFacets( "internal", RepositoryStatistics.FACET_ID ),
                                 Arrays.asList( "20091125.123456.678" ) );
        control.expectAndReturn(
            metadataRepository.getMetadataFacet( "internal", RepositoryStatistics.FACET_ID, "20091125.123456.678" ),
            new RepositoryStatistics() );
        control.expectAndReturn( metadataRepository.getMetadataFacets( "snapshots", RepositoryStatistics.FACET_ID ),
                                 Arrays.asList( "20091112.012345.012" ) );
        control.expectAndReturn(
            metadataRepository.getMetadataFacet( "snapshots", RepositoryStatistics.FACET_ID, "20091112.012345.012" ),
            new RepositoryStatistics() );
        control.replay();

        DefaultRepositoryStatisticsManager statsManager =
            (DefaultRepositoryStatisticsManager) lookup( RepositoryStatisticsManager.class );
        statsManager.setMetadataRepository( metadataRepository );

        ServletRunner sr = new ServletRunner();
        ServletUnitClient sc = sr.newClient();

        action.setServletRequest( sc.newInvocation( "http://localhost/admin/repositories.action" ).getRequest() );
        action.prepare();
        String result = action.execute();
        assertEquals( Action.SUCCESS, result );

        // TODO: for some reason servletunit is not populating the port of the servlet request
        assertEquals( "http://localhost:0/repository", action.getBaseUrl() );

        assertNotNull( action.getManagedRepositories() );
        assertNotNull( action.getRemoteRepositories() );
        assertNotNull( action.getRepositoryStatistics() );

        assertEquals( 2, action.getManagedRepositories().size() );
        assertEquals( 2, action.getRemoteRepositories().size() );
        assertEquals( 2, action.getRepositoryStatistics().size() );

        control.verify();
    }

    public void testSecureActionBundle()
        throws SecureActionException
    {
        SecureActionBundle bundle = action.getSecureActionBundle();
        assertTrue( bundle.requiresAuthentication() );
        assertEquals( 1, bundle.getAuthorizationTuples().size() );
    }
}
