package org.jooby.internal;
import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.Optional;
import org.jooby.Cookie;
import org.jooby.Mutant;
import org.jooby.Request;
import org.jooby.Response;
import org.jooby.Result;
import org.jooby.Route;
import org.jooby.Route.After;
import org.jooby.Session;
import org.jooby.internal.parser.ParserExecutor;
import org.jooby.test.MockUnit;
import org.jooby.test.MockUnit.Block;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.google.common.collect.ImmutableMap;
import com.typesafe.config.Config;
@RunWith(PowerMockRunner.class)
@PrepareForTest({CookieSessionManager.class, SessionImpl.class, Cookie.class })
public class CookieSessionManagerTest {
private Block cookie = unit -> {
Session.Definition sdef = unit.get(Session.Definition.class);
expect(sdef.cookie()).andReturn(unit.get(Cookie.Definition.class));
};
private Block push = unit -> {
Response rsp = unit.get(Response.class);
rsp.after(unit.capture(Route.After.class));
};
@Test
public void newInstance() throws Exception {
String secret = "shhh";
new MockUnit(Session.Definition.class, ParserExecutor.class, Cookie.Definition.class)
.expect(cookie)
.expect(maxAge(-1))
.run(unit -> {
new CookieSessionManager(unit.get(ParserExecutor.class),
unit.get(Session.Definition.class), secret);
});
}
@Test
public void destroy() throws Exception {
String secret = "shhh";
new MockUnit(Session.Definition.class, ParserExecutor.class, Cookie.Definition.class,
Session.class)
.expect(cookie)
.expect(maxAge(-1))
.run(unit -> {
new CookieSessionManager(unit.get(ParserExecutor.class),
unit.get(Session.Definition.class), secret)
.destroy(unit.get(Session.class));
});
}
@Test
public void requestDone() throws Exception {
String secret = "shhh";
new MockUnit(Session.Definition.class, ParserExecutor.class, Cookie.Definition.class,
Session.class)
.expect(cookie)
.expect(maxAge(-1))
.run(unit -> {
new CookieSessionManager(unit.get(ParserExecutor.class),
unit.get(Session.Definition.class), secret)
.requestDone(unit.get(Session.class));
});
}
@Test
public void create() throws Exception {
String secret = "shhh";
new MockUnit(Session.Definition.class, ParserExecutor.class, Cookie.Definition.class,
Request.class, Response.class, SessionImpl.class)
.expect(cookie)
.expect(maxAge(-1))
.expect(sessionBuilder(Session.COOKIE_SESSION, true, -1))
.expect(push)
.run(unit -> {
Session session = new CookieSessionManager(unit.get(ParserExecutor.class),
unit.get(Session.Definition.class), secret)
.create(unit.get(Request.class), unit.get(Response.class));
assertEquals(unit.get(SessionImpl.class), session);
});
}
@Test
public void saveAfter() throws Exception {
String secret = "shhh";
String signed = "$#!";
new MockUnit(Session.Definition.class, ParserExecutor.class, Cookie.Definition.class,
Request.class, Response.class, SessionImpl.class)
.expect(cookie)
.expect(maxAge(-1))
.expect(sessionBuilder(Session.COOKIE_SESSION, true, -1))
.expect(push)
.expect(unit -> {
Cookie.Definition cookie = unit.get(Cookie.Definition.class);
expect(cookie.name()).andReturn(Optional.of("sid"));
Mutant mutant = unit.mock(Mutant.class);
expect(mutant.toOptional()).andReturn(Optional.of(signed));
Request req = unit.get(Request.class);
expect(req.cookie("sid")).andReturn(mutant);
})
.expect(unit -> {
SessionImpl session = unit.get(SessionImpl.class);
expect(session.attributes()).andReturn(ImmutableMap.of("foo", "2"));
Request req = unit.get(Request.class);
expect(req.ifSession()).andReturn(Optional.of(session));
})
.expect(unit -> {
unit.mockStatic(Cookie.Signature.class);
expect(Cookie.Signature.unsign(signed, secret)).andReturn("foo=1");
})
.expect(signCookie(secret, "foo=2", "sss"))
.expect(sendCookie())
.run(unit -> {
Session session = new CookieSessionManager(unit.get(ParserExecutor.class),
unit.get(Session.Definition.class), secret)
.create(unit.get(Request.class), unit.get(Response.class));
assertEquals(unit.get(SessionImpl.class), session);
}, unit -> {
After next = unit.captured(Route.After.class).iterator().next();
Result ok = next.handle(unit.get(Request.class), unit.get(Response.class),
org.jooby.Results.ok());
assertNotNull(ok);
});
}
@Test
public void ignoreSaveAfterIfNoSession() throws Exception {
String secret = "shhh";
new MockUnit(Session.Definition.class, ParserExecutor.class, Cookie.Definition.class,
Request.class, Response.class, SessionImpl.class)
.expect(cookie)
.expect(maxAge(-1))
.expect(sessionBuilder(Session.COOKIE_SESSION, true, -1))
.expect(push)
.expect(unit -> {
Request req = unit.get(Request.class);
expect(req.ifSession()).andReturn(Optional.empty());
})
.run(unit -> {
Session session = new CookieSessionManager(unit.get(ParserExecutor.class),
unit.get(Session.Definition.class), secret)
.create(unit.get(Request.class), unit.get(Response.class));
assertEquals(unit.get(SessionImpl.class), session);
}, unit -> {
After next = unit.captured(Route.After.class).iterator().next();
Result ok = next.handle(unit.get(Request.class), unit.get(Response.class),
org.jooby.Results.ok());
assertNotNull(ok);
});
}
@Test
public void saveAfterTouchSession() throws Exception {
String secret = "shhh";
String signed = "$#!";
new MockUnit(Session.Definition.class, ParserExecutor.class, Cookie.Definition.class,
Request.class, Response.class, SessionImpl.class)
.expect(cookie)
.expect(maxAge(30))
.expect(sessionBuilder(Session.COOKIE_SESSION, true, -1))
.expect(push)
.expect(unit -> {
Cookie.Definition cookie = unit.get(Cookie.Definition.class);
expect(cookie.name()).andReturn(Optional.of("sid"));
Mutant mutant = unit.mock(Mutant.class);
expect(mutant.toOptional()).andReturn(Optional.of(signed));
Request req = unit.get(Request.class);
expect(req.cookie("sid")).andReturn(mutant);
})
.expect(unit -> {
SessionImpl session = unit.get(SessionImpl.class);
expect(session.attributes()).andReturn(ImmutableMap.of("foo", "1"));
Request req = unit.get(Request.class);
expect(req.ifSession()).andReturn(Optional.of(session));
})
.expect(unit -> {
unit.mockStatic(Cookie.Signature.class);
expect(Cookie.Signature.unsign(signed, secret)).andReturn("foo=1");
})
.expect(unit -> {
Cookie.Definition cookie = unit.get(Cookie.Definition.class);
Cookie.Definition newCookie = unit.constructor(Cookie.Definition.class)
.build(cookie);
expect(newCookie.value(signed)).andReturn(newCookie);
unit.registerMock(Cookie.Definition.class, newCookie);
})
.expect(sendCookie())
.run(unit -> {
Session session = new CookieSessionManager(unit.get(ParserExecutor.class),
unit.get(Session.Definition.class), secret)
.create(unit.get(Request.class), unit.get(Response.class));
assertEquals(unit.get(SessionImpl.class), session);
}, unit -> {
After next = unit.captured(Route.After.class).iterator().next();
Result ok = next.handle(unit.get(Request.class), unit.get(Response.class),
org.jooby.Results.ok());
assertNotNull(ok);
});
}
private Block sendCookie() {
return unit -> {
Cookie.Definition cookie = unit.get(Cookie.Definition.class);
Response rsp = unit.get(Response.class);
expect(rsp.cookie(cookie)).andReturn(rsp);
};
}
@Test
public void noSession() throws Exception {
String secret = "shh";
new MockUnit(Config.class, Session.Definition.class, Cookie.Definition.class,
Session.Store.class, ParserExecutor.class, Request.class, Response.class)
.expect(cookie)
.expect(maxAge(-1))
.expect(unit -> {
Cookie.Definition cookie = unit.get(Cookie.Definition.class);
expect(cookie.name()).andReturn(Optional.of("sid"));
Mutant mutant = unit.mock(Mutant.class);
expect(mutant.toOptional()).andReturn(Optional.empty());
Request req = unit.get(Request.class);
expect(req.cookie("sid")).andReturn(mutant);
})
.run(unit -> {
Session session = new CookieSessionManager(unit.get(ParserExecutor.class),
unit.get(Session.Definition.class), secret).get(unit.get(Request.class),
unit.get(Response.class));
assertEquals(null, session);
});
}
@Test
public void getSession() throws Exception {
String secret = "shh";
String signed = "$#!";
new MockUnit(Config.class, Session.Definition.class, Cookie.Definition.class,
Session.Store.class, ParserExecutor.class, Request.class, Response.class, SessionImpl.class)
.expect(cookie)
.expect(maxAge(-1))
.expect(unit -> {
Cookie.Definition cookie = unit.get(Cookie.Definition.class);
expect(cookie.name()).andReturn(Optional.of("sid"));
Mutant mutant = unit.mock(Mutant.class);
expect(mutant.toOptional()).andReturn(Optional.of(signed));
Request req = unit.get(Request.class);
expect(req.cookie("sid")).andReturn(mutant);
})
.expect(unit -> {
unit.mockStatic(Cookie.Signature.class);
expect(Cookie.Signature.unsign(signed, secret)).andReturn("foo=1");
})
.expect(sessionBuilder(Session.COOKIE_SESSION, false, -1))
.expect(unit -> {
Session.Builder builder = unit.get(Session.Builder.class);
expect(builder.set(ImmutableMap.of("foo", "1"))).andReturn(builder);
expect(builder.build()).andReturn(unit.get(SessionImpl.class));
})
.expect(push)
.run(unit -> {
Session session = new CookieSessionManager(unit.get(ParserExecutor.class),
unit.get(Session.Definition.class), secret).get(unit.get(Request.class),
unit.get(Response.class));
assertEquals(unit.get(SessionImpl.class), session);
});
}
private Block signCookie(final String secret, final String value, final String signed) {
return unit -> {
unit.mockStatic(Cookie.Signature.class);
expect(Cookie.Signature.sign(value, secret)).andReturn(signed);
Cookie.Definition cookie = unit.get(Cookie.Definition.class);
Cookie.Definition newCookie = unit.constructor(Cookie.Definition.class)
.build(cookie);
expect(newCookie.value(signed)).andReturn(newCookie);
unit.registerMock(Cookie.Definition.class, newCookie);
};
}
private Block maxAge(final Integer maxAge) {
return unit -> {
Cookie.Definition session = unit.get(Cookie.Definition.class);
expect(session.maxAge()).andReturn(Optional.of(maxAge));
};
}
private Block sessionBuilder(final String id, final boolean isNew, final long timeout) {
return unit -> {
SessionImpl.Builder builder = unit.constructor(SessionImpl.Builder.class)
.build(unit.get(ParserExecutor.class), isNew, id, timeout);
if (isNew) {
expect(builder.build()).andReturn(unit.get(SessionImpl.class));
}
unit.registerMock(Session.Builder.class, builder);
};
}
}