package org.ovirt.engine.ui.frontend.server.gwt;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ObjectNode;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Captor;
import org.mockito.Mock;
import org.ovirt.engine.core.branding.BrandingManager;
import org.ovirt.engine.core.common.businessentities.aaa.DbUser;
import org.ovirt.engine.core.common.interfaces.BackendLocal;
import org.ovirt.engine.core.common.queries.ConfigurationValues;
import org.ovirt.engine.core.common.queries.GetConfigurationValueParameters;
import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import org.ovirt.engine.core.compat.Guid;
public abstract class AbstractGwtDynamicHostPageServletTest<T extends GwtDynamicHostPageServlet> {
protected static final String SELECTOR_SCRIPT = "myapp.nocache.js"; //$NON-NLS-1$
@Mock
protected HttpServletRequest mockRequest;
@Mock
protected HttpServletResponse mockResponse;
@Mock
private HttpSession mockSession;
@Mock
private BackendLocal mockBackend;
@Mock
private BrandingManager mockBrandingManager;
@Mock
private ServletContext mockServletContext;
@Mock
private DbUser mockUser;
@Mock
private VdcQueryParametersBase mockQueryParams;
@Mock
private GetConfigurationValueParameters mockConfigQueryParams;
@Mock
protected MessageDigest mockDigest;
@Mock
private ObjectNode mockUserInfoObject;
@Captor
protected ArgumentCaptor<byte[]> byteArrayCaptor;
protected T testServlet;
@Before
public void setUp() throws NoSuchAlgorithmException {
when(mockRequest.getAttribute(GwtDynamicHostPageServlet.
MD5Attributes.ATTR_SELECTOR_SCRIPT.getKey())).
thenReturn(SELECTOR_SCRIPT);
when(mockRequest.getSession()).thenReturn(mockSession);
when(mockRequest.getSession().getServletContext()).thenReturn(mockServletContext);
when(mockUser.getId()).thenReturn(Guid.newGuid());
when(mockUser.getLoginName()).thenReturn("admin"); //$NON-NLS-1$
when(mockUser.getDomain()).thenReturn("internal"); //$NON-NLS-1$
stubGetUserBySessionIdQuery();
stubGetConfigurationValuePublicQuery();
setUpTestServlet();
}
protected void setUpTestServlet() throws NoSuchAlgorithmException {
testServlet = getTestServletSpy();
testServlet.setBackend(mockBackend);
testServlet.init(new ObjectMapper(), mockBrandingManager);
doReturn(mockDigest).when(testServlet).createMd5Digest();
}
protected abstract T getTestServletSpy();
@Test
public void testDoGet_WithoutUserInfoObject() throws IOException, ServletException, NoSuchAlgorithmException {
doReturn(null).when(testServlet).getLoggedInUser(nullable(String.class));
doReturn(mockDigest).when(testServlet).getMd5Digest(nullable(HttpServletRequest.class));
testServlet.doGet(mockRequest, mockResponse);
verify(mockRequest).setAttribute(eq(GwtDynamicHostPageServlet.MD5Attributes.ATTR_SELECTOR_SCRIPT.getKey()),
nullable(String.class));
verify(mockRequest, never()).setAttribute(eq(GwtDynamicHostPageServlet.MD5Attributes.ATTR_USER_INFO.getKey()),
nullable(ObjectNode.class));
verify(mockRequest).setAttribute(GwtDynamicHostPageServlet.MD5Attributes.ATTR_MESSAGES.getKey(),
null); //$NON-NLS-1$
}
@Test
public void testDoGet_WithUserInfoObject() throws IOException, ServletException, NoSuchAlgorithmException {
doReturn(mockDigest).when(testServlet).getMd5Digest(nullable(HttpServletRequest.class));
testServlet.doGet(mockRequest, mockResponse);
verify(mockRequest).setAttribute(eq(GwtDynamicHostPageServlet.MD5Attributes.ATTR_SELECTOR_SCRIPT.getKey()),
nullable(String.class));
verify(mockRequest).setAttribute(eq(GwtDynamicHostPageServlet.MD5Attributes.ATTR_USER_INFO.getKey()),
nullable(ObjectNode.class));
verify(mockRequest).setAttribute(GwtDynamicHostPageServlet.MD5Attributes.ATTR_MESSAGES.getKey(),
null); //$NON-NLS-1$
}
@Test
public void testDoGet_CalculateMd5_ResourceNotModifiedResponse() throws IOException, ServletException,
NoSuchAlgorithmException {
String md5sum = "md5sum"; //$NON-NLS-1$
doReturn(md5sum).when(testServlet).getMd5Sum(mockRequest);
when(mockRequest.getHeader(GwtDynamicHostPageServlet.IF_NONE_MATCH_HEADER)).thenReturn(md5sum);
testServlet.doGet(mockRequest, mockResponse);
verify(mockResponse).setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
@Test
public void testDoGet_CalculateMd5_ResourceModifiedEtagResponse() throws IOException, ServletException,
NoSuchAlgorithmException {
String md5sum = "md5sum"; //$NON-NLS-1$
doReturn(md5sum).when(testServlet).getMd5Sum(mockRequest);
testServlet.doGet(mockRequest, mockResponse);
verify(mockResponse).addHeader(GwtDynamicHostPageServlet.ETAG_HEADER, md5sum);
}
@Test
public void testInitQueryParams() {
String sessionId = "sessionId"; //$NON-NLS-1$
testServlet.initQueryParams(mockQueryParams, sessionId);
verify(mockQueryParams).setSessionId(sessionId);
verify(mockQueryParams).setFiltered(testServlet.filterQueries());
}
@Test
public void testRunQuery_GetUserBySessionId() {
String sessionId = "sessionId"; //$NON-NLS-1$
VdcQueryType queryType = VdcQueryType.GetUserBySessionId;
Object result = testServlet.runQuery(queryType, mockQueryParams, sessionId);
assertEquals(result, mockUser);
verify(mockQueryParams).setSessionId(sessionId);
verify(mockQueryParams).setFiltered(testServlet.filterQueries());
verify(mockBackend).runQuery(queryType, mockQueryParams);
}
@Test
public void testRunPublicQuery_GetConfigurationValue() {
String sessionId = "sessionId"; //$NON-NLS-1$
VdcQueryType queryType = VdcQueryType.GetConfigurationValue;
VdcQueryReturnValue returnIntValue = new VdcQueryReturnValue();
returnIntValue.setSucceeded(true);
returnIntValue.setReturnValue(Integer.valueOf(255));
when(mockBackend.runPublicQuery(eq(VdcQueryType.GetConfigurationValue),
eq(mockConfigQueryParams))).thenReturn(returnIntValue);
Object result = testServlet.runPublicQuery(queryType, mockConfigQueryParams, sessionId);
assertThat(result, is(instanceOf(Integer.class)));
verify(mockConfigQueryParams).setSessionId(sessionId);
verify(mockConfigQueryParams).setFiltered(testServlet.filterQueries());
verify(mockBackend).runPublicQuery(queryType, mockConfigQueryParams);
}
@Test
public void testGetUserInfoObject() {
ObjectNode result = testServlet.getUserInfoObject(mockUser, "mockSsoToken"); //$NON-NLS-1$ //$NON-NLS-2$
assertNotNull(result.get("id")); //$NON-NLS-1$
assertEquals("admin", result.get("userName").asText()); //$NON-NLS-1$ //$NON-NLS-2$
assertEquals("internal", result.get("domain").asText()); //$NON-NLS-1$ //$NON-NLS-2$
assertEquals("mockSsoToken", result.get("ssoToken").asText()); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test
public void testGetMd5Digest_WithoutUserInfoObject() throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest result = testServlet.getMd5Digest(mockRequest);
assertEquals(result, mockDigest);
verify(mockDigest, atLeast(1)).update(byteArrayCaptor.capture());
assertArrayEquals(SELECTOR_SCRIPT.getBytes(), byteArrayCaptor.getAllValues().get(0));
}
@Test
public void testGetMd5Digest_WithUserInfoObject() throws NoSuchAlgorithmException, UnsupportedEncodingException {
String userInfo = "{ \"foo\": \"bar\" }"; //$NON-NLS-1$
when(mockUserInfoObject.toString()).thenReturn(userInfo);
when(mockRequest.getAttribute(GwtDynamicHostPageServlet.
MD5Attributes.ATTR_USER_INFO.getKey())).
thenReturn(mockUserInfoObject);
MessageDigest result = testServlet.getMd5Digest(mockRequest);
assertEquals(result, mockDigest);
verify(mockDigest, atLeast(2)).update(byteArrayCaptor.capture());
assertArrayEquals(SELECTOR_SCRIPT.getBytes(), byteArrayCaptor.getAllValues().get(0));
assertArrayEquals(userInfo.getBytes(), byteArrayCaptor.getAllValues().get(1));
}
void stubGetUserBySessionIdQuery() {
VdcQueryReturnValue returnValue = new VdcQueryReturnValue();
returnValue.setSucceeded(true);
returnValue.setReturnValue(mockUser);
when(mockBackend.runQuery(
eq(VdcQueryType.GetUserBySessionId),
isA(VdcQueryParametersBase.class)
)).thenReturn(returnValue);
}
void stubGetConfigurationValuePublicQuery() {
VdcQueryReturnValue returnValue = new VdcQueryReturnValue();
returnValue.setSucceeded(true);
returnValue.setReturnValue("1.2.3"); //$NON-NLS-1$
when(mockBackend.runPublicQuery(
eq(VdcQueryType.GetConfigurationValue),
argThat(configValueParams(ConfigurationValues.ProductRPMVersion))
)).thenReturn(returnValue);
}
ArgumentMatcher<GetConfigurationValueParameters> configValueParams(final ConfigurationValues configValue) {
return argument -> argument.getConfigValue() == configValue;
}
}