/**
* 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");
}
}