package com.vtence.molecule;
import com.vtence.molecule.session.Session;
import org.hamcrest.Matcher;
import org.junit.Test;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.TimeUnit;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.emptyIterable;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
public class SessionTest {
int timeoutInSeconds = (int) TimeUnit.MINUTES.toSeconds(30);
Instant updateTime = Instant.now();
@Test
public void
isFreshWithoutAnId() {
Session newSession = new Session();
assertThat("new is fresh?", newSession.fresh(), equalTo(true));
assertThat("new id", newSession.id(), nullValue());
Session oldSession = new Session("old");
assertThat("old is fresh?", oldSession.fresh(), equalTo(false));
assertThat("old id", oldSession.id(), equalTo("old"));
}
@Test
public void
isInitiallyEmptyAndValid() {
Session session = new Session();
assertThat("initially valid?", !session.invalid(), equalTo(true));
assertThat("initial keys", session.keys(), emptyIterable());
assertThat("initial values", session.values(), emptyIterable());
}
@Test
public void
storesMultipleAttributes() {
Session session = new Session();
session.put("A", "Alice");
session.put("B", "Bob");
session.put("C", "Chris");
assertThat("A(lice)", session.<String>get("A"), equalTo("Alice"));
assertThat("B(ob)", session.<String>get("B"), equalTo("Bob"));
assertThat("C(hris)", session.<String>get("C"), equalTo("Chris"));
}
@Test
public void
allowsOverridingAttributes() {
Session session = new Session();
session.put("key", "original");
session.put("key", "override");
assertThat("overridden value", session.<String>get("key"), equalTo("override"));
}
@Test
public void
allowsRemovingAttributes() {
Session session = new Session();
session.put("A", "Alice");
session.put("B", "Bob");
session.put("C", "Chris");
session.remove("B");
assertThat("values", session.values(), containsItems("Alice", "Chris"));
}
@Test
public void
knowsItsContent() {
Session session = new Session();
session.put("A", "Alice");
session.put("B", "Bob");
session.put("C", "Chris");
assertThat("knows A?", session.contains("A"), equalTo(true));
assertThat("knows Z?", session.contains("Z"), equalTo(false));
assertThat("known size", session.size(), equalTo(3));
assertThat("known keys", session.keys(), containsItems("A", "B", "C"));
assertThat("known values", session.values(), containsItems("Alice", "Bob", "Chris"));
}
@Test
public void
updatesContentFromOtherSession() {
Session session = new Session();
session.put("A", "Albert");
session.put("C", "Chris");
Session other = new Session();
other.put("A", "Alice");
other.put("B", "Bob");
session.merge(other);
assertThat("merged keys", session.keys(), containsItems("A", "B", "C"));
assertThat("merged values", session.values(), containsItems("Alice", "Bob", "Chris"));
}
@Test
public void
dropsContentWhenInvalidated() {
Session session = new Session();
session.put("A", "Alice");
session.put("B", "Bob");
session.put("C", "Chris");
session.invalidate();
assertThat("invalid?", session.invalid(), equalTo(true));
assertThat("keys once invalid", session.keys(), emptyIterable());
assertThat("values once invalid", session.values(), emptyIterable());
}
@Test
public void
isInitiallySetToNeverExpires() {
Session session = new Session();
assertThat("expires", session.expires(), equalTo(false));
assertThat("default max age", session.maxAge(), equalTo(-1));
assertThat("default expiration time", session.expirationTime(), equalTo(Instant.MAX));
assertThat("has expired", !session.expired(Instant.MAX));
}
@Test
public void
expiresAtSpecifiedTime() {
Session session = new Session();
session.updatedAt(updateTime);
session.maxAge(timeoutInSeconds);
assertThat("expires", session.expires(), equalTo(true));
assertThat("expiration time", session.expirationTime(), equalTo(whenTimeoutOccurs(updateTime)));
assertThat("expired too early", !session.expired(justBefore(whenTimeoutOccurs(updateTime))));
assertThat("expired too late", session.expired(whenTimeoutOccurs(updateTime)));
}
@Test(expected = IllegalStateException.class)
public void
canNoLongerBeWrittenOnceInvalidated() {
Session session = new Session();
session.invalidate();
session.put("A", "Alice");
}
private Instant whenTimeoutOccurs(Instant pointInTime) {
return pointInTime.plus(timeoutInSeconds, ChronoUnit.SECONDS);
}
private Instant justBefore(Instant pointInTime) {
return pointInTime.minusNanos(1);
}
private Matcher<Iterable<?>> containsItems(Object... items) {
return containsInAnyOrder(items);
}
}