package org.activityinfo.server.login;
/*
* #%L
* ActivityInfo Server
* %%
* Copyright (C) 2009 - 2013 UNICEF
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import com.google.inject.Provider;
import org.activityinfo.model.auth.AuthenticatedUser;
import org.activityinfo.server.database.hibernate.entity.Authentication;
import org.easymock.EasyMock;
import org.junit.Test;
import javax.persistence.EntityManager;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URL;
import static org.easymock.EasyMock.*;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
public class SelectionServletTest {
@Test
public void markManifestAsObsoleteIfAuthTokenIsBadOrExpired()
throws ServletException, IOException {
// this verifies correct behavior in a complicated scenario:
// 1. User authenticates online
// 2. User agent successfully caches the application
// 3. User leaves
// 4. User's auth token is invalidated/expires
// 5. New version is posted to server
// 6. User returns to site
// 7. RPC call fails due to IncompatibleRemoteServiceException
// (so client does not realize that the authToken is no longer valid)
// 8. Cached client app prompts user for refresh
// 9. User refreshes
// 10. User agent receives 500 status code while trying to download new
// manifest (because authToken is invalid)
// so user agent does not know there is a new version
// 11. Goto step 7, repeat infinitely.
// To get the CORRECT behavior, the server needs to respond with status
// code 404
// to the request for the AppCache manifest, which will result in the
// cache being
// marked as obsolete and should force the user agent to delete the
// cache, allowing
// the user to complete a refresh.
EntityManager entityManager = createMock(EntityManager.class);
expect(entityManager.find(eq(Authentication.class), eq("badtoken")))
.andReturn(null);
replay(entityManager);
@SuppressWarnings("unchecked")
Provider<EntityManager> provider = createMock(Provider.class);
expect(provider.get()).andReturn(entityManager);
replay(provider);
Cookie[] cookies = new Cookie[]{
new Cookie(AuthenticatedUser.AUTH_TOKEN_COOKIE, "badtoken")
};
URL permutationMap = getClass().getResource("permutations");
assertThat("permutationMap is present for test", permutationMap,
is(not(nullValue(URL.class))));
ServletContext context = createMock(ServletContext.class);
expect(context.getRealPath(eq("/ActivityInfo/permutations")))
.andReturn(permutationMap.getFile());
replay(context);
ServletConfig config = createMock(ServletConfig.class);
expect(config.getServletContext()).andReturn(context);
replay(config);
HttpServletRequest request = createMock(HttpServletRequest.class);
expect(request.getHeader(eq("User-Agent")))
.andReturn(
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.112 Safari/535.1 Paros/3.2.13");
expect(request.getRequestURI()).andReturn(
"/ActivityInfo/ActivityInfo.appcache");
expect(request.getCookies()).andReturn(cookies).anyTimes();
replay(request);
HttpServletResponse response = createMock(HttpServletResponse.class);
response.sendError(eq(404), EasyMock.<String>anyObject());
expectLastCall();
replay(response);
SelectionServlet servlet = new SelectionServlet(provider);
servlet.testInit(config);
servlet.testGet(request, response);
verify(response);
}
}