/** * Copyright 2013 Twitter, Inc. * 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.twitter.hbc; import com.google.common.io.ByteStreams; import com.google.common.primitives.Longs; import com.twitter.hbc.core.Constants; import com.twitter.hbc.core.Hosts; import com.twitter.hbc.core.HttpHosts; import com.twitter.hbc.httpclient.ControlStreamException; import com.twitter.hbc.httpclient.auth.Authentication; import com.twitter.hbc.test.ArgumentValidator; import org.apache.http.HttpEntity; import org.apache.http.HttpHeaders; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpUriRequest; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import java.io.*; import java.net.URISyntaxException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.Mockito.*; public class SitestreamControllerTest { private HttpClient client; private Hosts hosts; private Authentication auth; private HttpUriRequest request; private HttpResponse mockResponse; private StatusLine mockStatusLine; private HttpEntity mockEntity; @Before public void setup() { client = mock(HttpClient.class); hosts = new HttpHosts("https://host.com"); auth = mock(Authentication.class); request = mock(HttpUriRequest.class); mockResponse = mock(HttpResponse.class); mockStatusLine = mock(StatusLine.class); mockEntity = mock(HttpEntity.class); } @Test public void testFailControlStreamRequestOnNon200s() throws IOException, URISyntaxException { SitestreamController controlstreams = new SitestreamController(client, hosts, auth); when(client.execute(any(HttpUriRequest.class))).thenReturn(mockResponse); when(mockResponse.getStatusLine()).thenReturn(mockStatusLine); when(mockStatusLine.getStatusCode()).thenReturn(400); try { controlstreams.makeControlStreamRequest(request); fail(); } catch (ControlStreamException c) { // expected } } @Test public void testProperlyCloseEntityContent() throws IOException, ControlStreamException { SitestreamController controlstreams = new SitestreamController(client, hosts, auth); InputStream stream = spy(new ByteArrayInputStream("message".getBytes(Constants.DEFAULT_CHARSET))); when(mockResponse.getEntity()).thenReturn(mockEntity); when(mockEntity.getContent()).thenReturn(stream); controlstreams.consumeHttpEntityContent(mockResponse); verify(stream).close(); } @Test public void testCloseEntityContentOnError() throws IOException, ControlStreamException { SitestreamController controlstreams = new SitestreamController(client, hosts, auth); InputStream mockStream = mock(InputStream.class); when(mockResponse.getEntity()).thenReturn(mockEntity); when(mockEntity.getContent()).thenReturn(mockStream); when(mockStream.read(any(byte[].class), anyInt(), anyInt())) .thenReturn(10) .thenThrow(new IOException()); try { controlstreams.consumeHttpEntityContent(mockResponse); fail(); } catch (IOException e) { // expected } verify(mockStream).close(); } private SitestreamController setupSimplControlStreamRequest(int statusCode, String content) throws IOException { SitestreamController controlstreams = new SitestreamController(client, hosts, auth); when(client.execute(any(HttpUriRequest.class))).thenReturn(mockResponse); when(mockResponse.getStatusLine()).thenReturn(mockStatusLine); when(mockStatusLine.getStatusCode()).thenReturn(statusCode); when(mockResponse.getEntity()).thenReturn(mockEntity); when(mockEntity.getContent()).thenReturn(new ByteArrayInputStream(content.getBytes("UTF-8"))); return controlstreams; } @Test public void testGetInfo() throws IOException, ControlStreamException, URISyntaxException { SitestreamController controlstreams = setupSimplControlStreamRequest(200, "{}"); controlstreams.getInfo("mock_stream_id"); Mockito.verify(client).execute(argThat(new ArgumentValidator<HttpGet>() { @Override public void validate(HttpGet get) { assertEquals("https://host.com/1.1/site/c/mock_stream_id/info.json", get.getURI().toString()); } })); } @Test public void testDeprecatedGetInfo() throws IOException, ControlStreamException, URISyntaxException { SitestreamController controlstreams = setupSimplControlStreamRequest(200, "{}"); controlstreams.getInfo("mock_stream_id", 1234567899L); Mockito.verify(client).execute(argThat(new ArgumentValidator<HttpGet>() { public void validate(HttpGet get) throws Exception { assertEquals("https://host.com/1.1/site/c/mock_stream_id/info.json", get.getURI().toString()); } })); } @Test public void testAddUser() throws IOException, ControlStreamException, URISyntaxException { SitestreamController controlstreams = setupSimplControlStreamRequest(200, "{}"); controlstreams.addUser("mock_stream_id", 123456789L); Mockito.verify(client).execute(argThat(new ArgumentValidator<HttpPost>() { public void validate(HttpPost post) throws Exception { assertEquals("application/x-www-form-urlencoded", post.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue()); assertEquals("https://host.com/1.1/site/c/mock_stream_id/add_user.json", post.getURI().toString()); assertEquals("user_id=123456789", consumeUtf8String(post.getEntity().getContent())); } })); } @Test public void testAddUsers() throws IOException, ControlStreamException, URISyntaxException { SitestreamController controlstreams = setupSimplControlStreamRequest(200, "{}"); controlstreams.addUsers("mock_stream_id", Longs.asList(1111, 2222, 3333, 4444)); Mockito.verify(client).execute(argThat(new ArgumentValidator<HttpPost>() { public void validate(HttpPost post) throws Exception { assertEquals("application/x-www-form-urlencoded", post.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue()); assertEquals("https://host.com/1.1/site/c/mock_stream_id/add_user.json", post.getURI().toString()); assertEquals("user_id=1111%2C2222%2C3333%2C4444", consumeUtf8String(post.getEntity().getContent())); } })); } @Test public void testAddUsersPrecondition() throws IOException, ControlStreamException { SitestreamController controlstreams = new SitestreamController(client, hosts, auth); try { controlstreams.addUsers("mock_stream_id", Longs.asList(new long[101])); fail(); } catch (IllegalArgumentException expected) { } } @Test public void testRemoveUser() throws IOException, ControlStreamException, URISyntaxException { SitestreamController controlstreams = setupSimplControlStreamRequest(200, "{}"); controlstreams.removeUser("mock_stream_id", 123456789L); Mockito.verify(client).execute(argThat(new ArgumentValidator<HttpPost>() { public void validate(HttpPost post) throws Exception { assertEquals("application/x-www-form-urlencoded", post.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue()); assertEquals("https://host.com/1.1/site/c/mock_stream_id/remove_user.json", post.getURI().toString()); assertEquals("user_id=123456789", consumeUtf8String(post.getEntity().getContent())); } })); } @Test public void testRemoveUsers() throws IOException, ControlStreamException, URISyntaxException { SitestreamController controlstreams = setupSimplControlStreamRequest(200, "{}"); controlstreams.removeUsers("mock_stream_id", Longs.asList(1111, 2222, 3333, 4444)); Mockito.verify(client).execute(argThat(new ArgumentValidator<HttpPost>() { public void validate(HttpPost post) throws Exception { assertEquals("application/x-www-form-urlencoded", post.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue()); assertEquals("https://host.com/1.1/site/c/mock_stream_id/remove_user.json", post.getURI().toString()); assertEquals("user_id=1111%2C2222%2C3333%2C4444", consumeUtf8String(post.getEntity().getContent())); } })); } @Test public void testRemoveUsersPrecondition() throws IOException, ControlStreamException { SitestreamController controlstreams = new SitestreamController(client, hosts, auth); try { controlstreams.removeUsers("mock_stream_id", Longs.asList(new long[101])); fail(); } catch (IllegalArgumentException expected) { } } private String consumeUtf8String(InputStream ins) throws IOException { return new String(ByteStreams.toByteArray(ins), "UTF-8"); } }