// -*- mode: java; c-basic-offset: 2; -*- // Copyright 2009-2011 Google, All Rights reserved // Copyright 2011-2012 MIT, All rights reserved // Released under the Apache License, Version 2.0 // http://www.apache.org/licenses/LICENSE-2.0 package com.google.appinventor.server; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import com.google.appinventor.shared.rpc.user.User; import com.google.appinventor.common.testutils.TestUtils; import static junit.framework.Assert.*; import junitx.framework.Assert; import org.easymock.EasyMock; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.easymock.PowerMock; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.FilterChain; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author markf@google.com (Mark Friedman) */ @RunWith(PowerMockRunner.class) @PrepareForTest({ LocalUser.class, OdeAuthFilter.class, OdeAuthFilter.UserInfo.class }) public class OdeAuthFilterTest { // If OdeAuthFilterTest (which uses PowerMock.mockStatic) extends LocalDatastoreTestCase, then // it will probably fail with Ant version 1.8.2. private final LocalDatastoreTestCase helper = LocalDatastoreTestCase.createHelper(); private FilterChain mockFilterChain; private HttpServletRequest mockServletRequest; private HttpServletResponse mockServletResponse; private LocalUser localUserMock; private OdeAuthFilter.UserInfo localUserInfo; @Before public void setUp() throws Exception { helper.setUp(); localUserMock = PowerMock.createMock(LocalUser.class); PowerMock.mockStatic(LocalUser.class); expect(LocalUser.getInstance()).andReturn(localUserMock).anyTimes(); localUserMock.set(new User("1", "NonSuch", "NoName", null, 0, false, false, 0, null)); expectLastCall().times(1); expect(localUserMock.getUserEmail()).andReturn("NonSuch").times(1); localUserInfo = PowerMock.createMock(OdeAuthFilter.UserInfo.class); expect(localUserInfo.buildCookie(false)).andReturn("NoCookie").anyTimes(); expect(localUserInfo.buildCookie(true)).andReturn("NoCookie").anyTimes(); mockFilterChain = PowerMock.createNiceMock(FilterChain.class); mockServletRequest = PowerMock.createNiceMock(HttpServletRequest.class); mockServletResponse = PowerMock.createNiceMock(HttpServletResponse.class); } @After public void tearDown() throws Exception { helper.tearDown(); PowerMock.resetAll(); } @Test public void testDoFilterShouldContinueFilterChainIfNotWhitelisted() throws Exception { final AtomicInteger isUserWhitelistedCounter = new AtomicInteger(0); expect(localUserMock.getUserTosAccepted()).andReturn(true).times(1); // This is the key expectation, i.e. that we continue by calling the doFilter method of the // internal mocked FilterChain that will be passed into the tested FilterChain mockFilterChain.doFilter(mockServletRequest, mockServletResponse); EasyMock.expectLastCall().once(); PowerMock.replayAll(); // Here's where we say that the whitelist is not active OdeAuthFilter.useWhitelist.setForTest(false); OdeAuthFilter myAuthFilter = new OdeAuthFilter() { @Override void setUserFromUserId(String userId, boolean isAdmin, boolean isReadOnly) { localUserMock.set(new User("1", "NonSuch", "NoName", null, 0, false, false, 0, null)); return;} @Override void removeUser() {} @Override boolean isUserWhitelisted() { isUserWhitelistedCounter.incrementAndGet(); return false; } }; myAuthFilter.doMyFilter(localUserInfo, false, false, mockServletRequest, mockServletResponse, mockFilterChain); // isUserWhitelisted should not have been called. assertEquals(0, isUserWhitelistedCounter.get()); // getUserTosAccepted should have been called once. PowerMock.verifyAll(); } @Test public void testDoFilterShouldNotContinueFilterChainIfNotWhitelisted() throws Exception { final AtomicInteger isUserWhitelistedCounter = new AtomicInteger(0); final AtomicInteger writeWhitelistErrorMessageCounter = new AtomicInteger(0); // Note the lack any expectation of a call to the doFilter method of the // internal mocked FilterChain that will be passed into the tested FilterChain, unlike the // case in testDoFilterShouldContinueFilterChainIfNotWhitelisted(). // In other words, if it IS using a whitelist and the user is NOT whitelisted for testing, // mockFilterChain.doFilter should never be called. PowerMock.replayAll(); // Here's where we say that it IS a staging server OdeAuthFilter.useWhitelist.setForTest(true); OdeAuthFilter myAuthFilter = new OdeAuthFilter() { @Override void setUserFromUserId(String userId, boolean isAdmin, boolean isReadOnly) { localUserMock.set(new User("1", "NonSuch", "NoName", null, 0, false, false, 0, null)); return;} @Override void removeUser() {} @Override boolean isUserWhitelisted() { isUserWhitelistedCounter.incrementAndGet(); return false; } @Override void writeWhitelistErrorMessage(HttpServletResponse response) { writeWhitelistErrorMessageCounter.incrementAndGet(); } }; myAuthFilter.doMyFilter(localUserInfo, false, false, mockServletRequest, mockServletResponse, mockFilterChain); // isUserWhitelisted should have been called once. assertEquals(1, isUserWhitelistedCounter.get()); // writeWhitelistErrorMessage should have been called once assertEquals(1, writeWhitelistErrorMessageCounter.get()); // getUserTosAccepted should not have been called. PowerMock.verifyAll(); } }