FraudCount implements StatefulFunction { @Override public void invoke(Context context, Object input) { if (input instanceof ConfirmFraud) { int current = count.getOrDefault(0); count.set(current + 1); context.sendAfter(Duration.ofDays(30), context.self(), ExpireFraud.getDefaultInstance()); } if (input instanceof ExpireFraud) { int current = count.getOrDefault(0); if (current == 0 || current == 1) { count.clear(); } count.set(current - 1); } if (input instanceof QueryFraud) { int current = count.getOrDefault(0); ReportedFraud response = ReportedFraud.newBuilder().setCount(current).build(); context.reply(response); } }  @Override void invoke(Context context, Object input);  }
@Test public void testCounting() { FunctionTestHarness harness = FunctionTestHarness.test(ignore -> new FraudCount(), FRAUD_FN, "user1"); Assert.assertThat( "When reporting fraud, the function should not respond", harness.invoke(SENDER, ConfirmFraud.getDefaultInstance()), sentNothing()); Assert.assertThat( "When querying fraud, the function should return the current count", harness.invoke(SENDER, QueryFraud.getDefaultInstance()), sent(messagesTo(SENDER, equalTo(ReportedFraud.newBuilder().setCount(1).build())))); }
@Test public void testRollingCount() { FunctionTestHarness harness = FunctionTestHarness.test(ignore -> new FraudCount(), FRAUD_FN, "user1"); Assert.assertThat( "When reporting fraud, the function should not respond", harness.invoke(SENDER, ConfirmFraud.getDefaultInstance()), sentNothing()); Assert.assertThat( "When querying fraud, the function should return the current count", harness.invoke(SENDER, QueryFraud.getDefaultInstance()), sent(messagesTo(SENDER, equalTo(ReportedFraud.newBuilder().setCount(1).build())))); Assert.assertThat( "In 15 days the count should not change the function should not respond", harness.tick(Duration.ofDays(15)), sentNothing()); Assert.assertThat( "In 15 days the count should not change the function should not respond", harness.invoke(SENDER, QueryFraud.getDefaultInstance()), sent(messagesTo(SENDER, equalTo(ReportedFraud.newBuilder().setCount(1).build())))); Assert.assertThat( "When reporting fraud, the function should not respond", harness.invoke(SENDER, ConfirmFraud.getDefaultInstance()), sentNothing()); Assert.assertThat( "When querying fraud, the function should return the current count", harness.invoke(SENDER, QueryFraud.getDefaultInstance()), sent(messagesTo(SENDER, equalTo(ReportedFraud.newBuilder().setCount(2).build())))); Assert.assertThat( "After 30 days the count should decrement, but this won't return anything", harness.tick(Duration.ofDays(15)), sentNothing()); Assert.assertThat( "When querying fraud, the function should return the current count", harness.invoke(SENDER, QueryFraud.getDefaultInstance()), sent(messagesTo(SENDER, equalTo(ReportedFraud.newBuilder().setCount(1).build())))); }