/** * Copyright (c) 2008-2011 Sonatype, Inc. * All rights reserved. Includes the third-party code listed at http://www.sonatype.com/products/nexus/attributions. * * This program is free software: you can redistribute it and/or modify it only under the terms of the GNU Affero General * Public License Version 3 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License Version 3 * for more details. * * You should have received a copy of the GNU Affero General Public License Version 3 along with this program. If not, see * http://www.gnu.org/licenses. * * Sonatype Nexus (TM) Open Source Version is available from Sonatype, Inc. Sonatype and Sonatype Nexus are trademarks of * Sonatype, Inc. Apache Maven is a trademark of the Apache Foundation. M2Eclipse is a trademark of the Eclipse Foundation. * All other trademarks are the property of their respective owners. */ package org.sonatype.nexus.restlight.testharness; import static junit.framework.Assert.fail; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthPolicy; import org.apache.commons.httpclient.auth.AuthScope; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.junit.After; import org.junit.Before; import org.sonatype.nexus.restlight.common.NxBasicScheme; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; /** * Abstract test class that provides convenience methods for reading XML request/response documents from various * locations, managing the test-harness server, and initializing the test fixture used when a RESTLight client connects * and loads its vocabulary information. */ public abstract class AbstractRESTTest { protected static final String TEST_NX_API_VERSION_SYSPROP = "test.nexus.api.version"; private static final String DEFAULT_TEST_NX_API_VERSION = "1.3.2"; protected static final String DEFAULT_EXPECTED_USER = "testuser"; protected static final String DEFAULT_EXPECTED_PASSWORD = "password"; /** * <p> * The test fixture MUST NOT change during the test. * </p> * <p> * Return the {@link RESTTestFixture} instance that sets expectations for HTTP exchanges between the RESTLight * client under test and the mockup Nexus instance, the test-harness server used here. * </p> */ protected abstract RESTTestFixture getTestFixture(); protected void setupAuthentication( final HttpClient client ) { setupAuthentication( client, getExpectedUser(), getExpectedPassword() ); } protected void setupAuthentication( final HttpClient client, final String user, final String password ) { UsernamePasswordCredentials creds = new UsernamePasswordCredentials( user, password ); List<String> policies = new ArrayList<String>(); policies.add( NxBasicScheme.POLICY_NAME ); AuthPolicy.registerAuthScheme( NxBasicScheme.POLICY_NAME, NxBasicScheme.class ); client.getParams().setParameter( AuthPolicy.AUTH_SCHEME_PRIORITY, policies ); client.getState().setCredentials( AuthScope.ANY, creds ); } protected String getExpectedUser() { return DEFAULT_EXPECTED_USER; } protected String getExpectedPassword() { return DEFAULT_EXPECTED_PASSWORD; } /** * Retrieve the base URL used by the test-harness server. This will serve as the base Nexus URL for tests. */ protected final String getBaseUrl() { return "http://127.0.0.1:" + getTestFixture().getPort(); } /** * Load a {@link Document} instance from a classpath resource with the given path. This document normally is used as * either a request or response body in a {@link RESTTestFixture} instance. */ protected final Document readTestDocumentResource( final String resourcePath ) throws JDOMException, IOException { InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream( resourcePath ); if ( stream == null ) { fail( "Cannot find test resource: '" + resourcePath + "'" ); } try { return new SAXBuilder().build( stream ); } finally { if ( stream != null ) { try { stream.close(); } catch ( IOException e ) { System.out.println( "Failed to close stream to classpath resource: " + resourcePath ); } } } } /** * Load a {@link Document} instance from the given {@link File}. This document normally is used as either a request * or response body in a {@link RESTTestFixture} instance. */ protected final Document readTestDocumentFile( final File file ) throws JDOMException, IOException { FileInputStream stream = null; try { stream = new FileInputStream( file ); return new SAXBuilder().build( stream ); } finally { if ( stream != null ) { try { stream.close(); } catch ( IOException e ) { System.out.println( "Failed to close stream to file: " + file ); } } } } /** * Construct a new {@link GETFixture} that represents the expectations the Nexus server should have for retrieving * the Nexus API version (to allow the client to load the proper REST vocabulary variable set). */ protected final GETFixture getVersionCheckFixture() { GETFixture fixture = new GETFixture( getExpectedUser(), getExpectedPassword() ); Document doc = new Document().setRootElement( new Element( "status" ) ); Element data = new Element( "data" ); data.addContent( new Element( "apiVersion" ).setText( getTestNexusAPIVersion() ) ); doc.getRootElement().addContent( data ); fixture.setExactURI( "/service/local/status" ); fixture.setResponseDocument( doc ); return fixture; } /** * Retrieve the Nexus API version we're testing, either using the System property <code>'test.nexus.api.version'</code>, or else using the default * value of <code>'1.3.1'</code> if no System property is supplied. */ protected String getTestNexusAPIVersion() { return System.getProperty( TEST_NX_API_VERSION_SYSPROP, DEFAULT_TEST_NX_API_VERSION ); } /** * Start the test-harness server. This is a Nexus mock instance, driven by expectations set in the * {@link RESTTestFixture} supplied by the {@link AbstractRESTTest#getTestFixture()} method. */ @Before public void startServer() throws Exception { getTestFixture().startServer(); } /** * Stop the test-harness server that acts as the Nexus mock instance. */ @After public void stopServer() throws Exception { getTestFixture().stopServer(); } }