/* * Copyright 2013 Hewlett-Packard Development Company, L.P * * Licensed 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 com.hp.alm.ali.idea.rest; import com.hp.alm.ali.ServerVersion; import com.hp.alm.ali.idea.FixtureFactory; import com.hp.alm.ali.idea.IntellijTest; import com.hp.alm.ali.idea.cfg.AliProjectConfiguration; import com.hp.alm.ali.idea.model.HorizonStrategy; import com.hp.alm.ali.idea.model.ServerStrategy; import com.hp.alm.ali.rest.client.AliRestClientFactory; import com.hp.alm.ali.rest.client.InputData; import com.hp.alm.ali.rest.client.RestClient; import com.hp.alm.ali.rest.client.RestClientFactory; import com.hp.alm.ali.rest.client.ResultInfo; import com.hp.alm.ali.rest.client.exception.AuthenticationFailureException; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.util.net.HttpConfigurable; import org.apache.commons.httpclient.methods.RequestEntity; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.io.ByteArrayOutputStream; import java.io.IOException; public class RestServiceTest extends IntellijTest { private RestService restService; private RestClient restClient; private AliProjectConfiguration projectConfiguration; @Before public void preClean() { restService = getComponent(RestService.class); restClient = restService.getRestClient(); projectConfiguration = getComponent(AliProjectConfiguration.class); } @After public void postClean() throws Throwable { handler.checkpoint(); RestService._setFactory(AliRestClientFactory.getInstance()); restService._setRestServiceLogger(ApplicationManager.getApplication().getComponent(TroubleShootService.class)); if(restService.getRestClient() instanceof MockRestClient) { restService._setRestClient(restClient); } HttpConfigurable.getInstance().USE_HTTP_PROXY = false; } public RestServiceTest() { super(ServerVersion.AGM); } @Test public void testCreateRestClient_noProxy() { HttpConfigurable httpConfigurable = HttpConfigurable.getInstance(); httpConfigurable.USE_HTTP_PROXY = false; handler.async(3); RestService._setFactory(new RestClientFactory() { @Override public RestClient create(final String location, final String domain, final String project, final String userName, final String password, final RestClient.SessionStrategy sessionStrategy) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals("location", location); Assert.assertEquals("domain", domain); Assert.assertEquals("project", project); Assert.assertEquals("user", userName); Assert.assertEquals("password", password); Assert.assertEquals(RestClient.SessionStrategy.AUTO_LOGIN, sessionStrategy); } }); return new MockRestClient() { @Override public void setEncoding(final String encoding) { handler.done(new Runnable() { @Override public void run() { Assert.assertNull(encoding); } }); } @Override public void setTimeout(final int timeout) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals(10000, timeout); } }); } }; } }); RestService.createRestClient("location", "domain", "project", "user", "password", RestClient.SessionStrategy.AUTO_LOGIN); } @Test public void testCreateRestClient_unauthenticatedProxy() { HttpConfigurable httpConfigurable = HttpConfigurable.getInstance(); httpConfigurable.USE_HTTP_PROXY = true; httpConfigurable.PROXY_HOST = "localhost"; httpConfigurable.PROXY_PORT = 1234; httpConfigurable.PROXY_AUTHENTICATION = false; handler.async(4); RestService._setFactory(new RestClientFactory() { @Override public RestClient create(final String location, final String domain, final String project, final String userName, final String password, final RestClient.SessionStrategy sessionStrategy) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals("http://location", location); Assert.assertEquals("domain", domain); Assert.assertEquals("project", project); Assert.assertEquals("user", userName); Assert.assertEquals("password", password); Assert.assertEquals(RestClient.SessionStrategy.AUTO_LOGIN, sessionStrategy); } }); return new MockRestClient() { @Override public void setHttpProxy(final String proxyHost, final int proxyPort) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals("localhost", proxyHost); Assert.assertEquals(1234, proxyPort); } }); } @Override public void setEncoding(final String encoding) { handler.done(new Runnable() { @Override public void run() { Assert.assertNull(encoding); } }); } @Override public void setTimeout(final int timeout) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals(10000, timeout); } }); } }; } }); RestService.createRestClient("http://location", "domain", "project", "user", "password", RestClient.SessionStrategy.AUTO_LOGIN); } @Test public void testCreateRestClient_authenticatedProxy() { HttpConfigurable httpConfigurable = HttpConfigurable.getInstance(); httpConfigurable.USE_HTTP_PROXY = true; httpConfigurable.PROXY_HOST = "localhost"; httpConfigurable.PROXY_PORT = 1234; httpConfigurable.PROXY_AUTHENTICATION = true; httpConfigurable.PROXY_LOGIN = "admin"; httpConfigurable.PROXY_PASSWORD_CRYPT = "Y2hhbmdlaXQ="; handler.async(5); RestService._setFactory(new RestClientFactory() { @Override public RestClient create(final String location, final String domain, final String project, final String userName, final String password, final RestClient.SessionStrategy sessionStrategy) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals("http://location", location); Assert.assertEquals("domain", domain); Assert.assertEquals("project", project); Assert.assertEquals("user", userName); Assert.assertEquals("password", password); Assert.assertEquals(RestClient.SessionStrategy.AUTO_LOGIN, sessionStrategy); } }); return new MockRestClient() { @Override public void setHttpProxy(final String proxyHost, final int proxyPort) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals("localhost", proxyHost); Assert.assertEquals(1234, proxyPort); } }); } @Override public void setHttpProxyCredentials(final String username, final String password) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals("admin", username); Assert.assertEquals("changeit", password); } }); } @Override public void setEncoding(final String encoding) { handler.done(new Runnable() { @Override public void run() { Assert.assertNull(encoding); } }); } @Override public void setTimeout(final int timeout) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals(10000, timeout); } }); } }; } }); RestService.createRestClient("http://location", "domain", "project", "user", "password", RestClient.SessionStrategy.AUTO_LOGIN); } @Test public void testGetRestClient() { RestClient restClient = restService.getRestClient(); Assert.assertNotNull(restClient); Assert.assertEquals(RestClient.SessionStrategy.AUTO_LOGIN, restClient.getSessionStrategy()); Assert.assertEquals(restClient, restService.getRestClient()); } @Test public void testGet() { handler.async(); restService._setRestClient(new MockRestClient() { @Override public int get(ResultInfo result, final String template, final Object... params) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals("defects/{0}", template); Assert.assertEquals("1", params[0]); } }); try { result.getBodyStream().write("foo".getBytes()); } catch (IOException e) { throw new RuntimeException(e); } return 200; } }); MyResultInfo result = new MyResultInfo(); int status = restService.get(result, "defects/{0}", "1"); Assert.assertEquals(200, status); Assert.assertEquals("foo", result.getBodyAsString()); } @Test public void testPut() { handler.async(); restService._setRestClient(new MockRestClient() { @Override public int put(final InputData inputData, ResultInfo result, final String template, final Object... params) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals("defects/{0}", template); Assert.assertEquals("1", params[0]); Assert.assertEquals("bar", asString(inputData.getRequestEntity(null))); } }); try { result.getBodyStream().write("foo".getBytes()); } catch (IOException e) { throw new RuntimeException(e); } return 200; } }); MyResultInfo result = new MyResultInfo(); int status = restService.put("bar", result, "defects/{0}", "1"); Assert.assertEquals(200, status); Assert.assertEquals("foo", result.getBodyAsString()); } @Test public void testPost() { handler.async(); restService._setRestClient(new MockRestClient() { @Override public int post(final InputData inputData, ResultInfo result, final String template, final Object... params) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals("defects/{0}", template); Assert.assertEquals("1", params[0]); Assert.assertEquals("bar", asString(inputData.getRequestEntity(null))); } }); try { result.getBodyStream().write("foo".getBytes()); } catch (IOException e) { throw new RuntimeException(e); } return 200; } }); MyResultInfo result = new MyResultInfo(); int status = restService.post("bar", result, "defects/{0}", "1"); Assert.assertEquals(200, status); Assert.assertEquals("foo", result.getBodyAsString()); } @Test public void testDelete() { handler.async(); restService._setRestClient(new MockRestClient() { @Override public int delete(ResultInfo result, final String template, final Object... params) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals("defects/{0}", template); Assert.assertEquals("1", params[0]); } }); try { result.getBodyStream().write("foo".getBytes()); } catch (IOException e) { throw new RuntimeException(e); } return 200; } }); MyResultInfo result = new MyResultInfo(); int status = restService.delete(result, "defects/{0}", "1"); Assert.assertEquals(200, status); Assert.assertEquals("foo", result.getBodyAsString()); } @Test public void testRestServiceLogger() { handler.async(2); restService._setRestServiceLogger(new MockRestServiceLogger() { @Override public long request(Project project, final String name, final MyInputData myInput, final String template, Object... params) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals("POST", name); Assert.assertEquals("defects", template); Assert.assertEquals("bar", myInput.getRequestData()); } }); return 1; } @Override public void response(final long id, final int code, final MyResultInfo myResult) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals(1, id); Assert.assertEquals(200, code); Assert.assertEquals("foo", myResult.getBodyAsString()); } }); } }); restService._setRestClient(new MockRestClient() { @Override public int post(InputData input, ResultInfo result, final String template, final Object... params) { try { result.getBodyStream().write("foo".getBytes()); } catch (IOException e) { throw new RuntimeException(e); } return 200; } }); restService.post("bar", new MyResultInfo(), "defects"); } @Test public void testRestServiceLogger_loginFailure() { handler.async(); restService._setRestServiceLogger(new MockRestServiceLogger() { @Override public long request(Project project, String name, MyInputData myInput, String template, Object... params) { return 1; } @Override public void loginFailure(final long id, final AuthenticationFailureException e) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals(1, id); Assert.assertEquals(401, e.getHttpStatus()); Assert.assertEquals("Forbidden", e.getReasonPhrase()); Assert.assertEquals("defects", e.getLocation()); } }); } }); restService._setRestClient(new MockRestClient() { @Override public int get(ResultInfo result, final String template, final Object... params) { result.setHttpStatus(401); result.setReasonPhrase("Forbidden"); result.setLocation(template); throw new AuthenticationFailureException(result); } }); try { restService.get(new MyResultInfo(), "defects"); Assert.fail("should have failed"); } catch (AuthenticationFailureException e) { // expected } } @Test public void testOnChangedEvent() throws InterruptedException { // when configuration is changed, following should happen: // // 1. logout request is performed // 2. listeners receive REST configuration changed event // 3. listeners receive server type CONNECTING event // 4. server version is negotiated // 5. listeners receive server type AGM event handler.addRequest(false, "GET", "/qcbin/authentication-point/logout", 200); FixtureFactory.handshake(handler, true); handler.async(3); restService.addListener(new OneTimeRestListener(handler, restService) { @Override protected void restConfigurationChangedEvent() { // async done (don't remove) } }); restService.addServerTypeListener(new OneTimeServerTypeListener(handler, restService) { @Override protected void connectedToEvent(ServerType serverType) { Assert.assertEquals(ServerType.CONNECTING, serverType); restService.addServerTypeListener(new OneTimeServerTypeListener(handler, restService) { @Override protected void connectedToEvent(ServerType serverType) { Assert.assertEquals(ServerType.AGM, serverType); } }); } }); projectConfiguration.fireChanged(); // wait for handshake finish handler.consume(); } @Test public void testLogout() { handler.async(); RestService.logout(new MockRestClient() { @Override public void logout() { handler.done(); } }); } @Test public void testCheckConnectivity_whenDisconnected() { // in the disconnected state perform checkConnectivity: // // 1. listeners receive server type CONNECTING event // 2. server version is negotiated // 3. listeners receive server type AGM event FixtureFactory.handshake(handler, false); handler.async(2); restService.addServerTypeListener(new OneTimeServerTypeListener(handler, restService) { @Override protected void connectedToEvent(ServerType serverType) { Assert.assertEquals(ServerType.CONNECTING, serverType); restService.addServerTypeListener(new OneTimeServerTypeListener(handler, restService) { @Override protected void connectedToEvent(ServerType serverType) { Assert.assertEquals(ServerType.AGM, serverType); } }); } }); restService._setServerType(ServerType.NONE); restService.checkConnectivity(); handler.consume(); } @Test public void testCheckConnectivity_whenConnected() { // nothing should happen when connected restService.checkConnectivity(); } @Test public void testGetServerType() throws InterruptedException { try { Assert.assertEquals(ServerType.AGM, restService.getServerType()); } catch (InterruptedException e) { throw new RuntimeException(e); } restService._setServerType(ServerType.NONE); try { Assert.assertEquals(ServerType.NONE, restService.getServerType()); } catch (InterruptedException e) { throw new RuntimeException(e); } restService._setServerType(ServerType.CONNECTING); ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { @Override public void run() { restService._setServerType(ServerType.AGM); } }); Assert.assertEquals(ServerType.AGM, restService.getServerType()); } @Test public void testGetServerType_whenConnected() throws InterruptedException { Assert.assertEquals(ServerType.AGM, restService.getServerType()); } @Test public void testGetServerStrategy() throws InterruptedException { restService._setServerType(ServerType.NONE); try { restService.getServerStrategy(); Assert.fail("Should have failed"); } catch (NotConnectedException e) { // ok } restService._setServerType(ServerType.CONNECTING); try { restService.getServerStrategy(); Assert.fail("Should have failed"); } catch (NotConnectedException e) { // ok } restService._setServerType(ServerType.AGM); ServerStrategy serverStrategy = restService.getServerStrategy(); Assert.assertEquals(HorizonStrategy.class, serverStrategy.getClass()); } private String asString(RequestEntity requestEntity) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { requestEntity.writeRequest(baos); } catch (IOException e) { throw new RuntimeException(e); } return baos.toString(); } }