@Test
public void fraudScenarioDsl() {

    Trigger trigger = new Trigger(TEST_TENANT, "fraud-scenario", "Fraud Scenario");
    String expression = "event:groupBy(tags.accountId):window(time,10s):having(count > 1, count.tags.location > 1)";
    ExternalCondition condition = new ExternalCondition(trigger.getId(), FIRING, DATA_ID, ALERTER_ID, expression);
    Expression exp = new Expression(Arrays.asList(new FullTrigger(trigger, null, Arrays.asList(condition))));
    String drl = exp.getDrl();
    // System.out.println(drl);
    startSession(drl);
    // Init t0
    clock.setStartupTime(1);
    long now = clock.getCurrentTime();
    // User1 buys 5 times in < 10 seconds from different locations
    Event e1 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "Buy Book");
    e1.addTag("duration", "1000");
    e1.addTag("accountId", "user1");
    e1.addTag("location", "ip1");
    // User2 buys 3 times > 10 seconds from single location
    Event e6 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "Buy Book");
    e6.addTag("duration", "1000");
    e6.addTag("accountId", "user2");
    e6.addTag("location", "ip3");
    // User3 buys 5 times in < 10 seconds from single location
    Event e11 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "Buy Book");
    e11.addTag("duration", "1000");
    e11.addTag("accountId", "user3");
    e11.addTag("location", "ip10");
    insert(e1, e6, e11);
    // t0 + 1000
    now = clock.advanceTime(1000, TimeUnit.MILLISECONDS);
    Event e2 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "Buy Music");
    e2.addTag("duration", "2000");
    e2.addTag("accountId", "user1");
    e2.addTag("location", "ip1");
    Event e12 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "Buy Music");
    e12.addTag("duration", "2000");
    e12.addTag("accountId", "user3");
    e12.addTag("location", "ip10");
    insert(e2, e12);
    // t0 + 2000
    now = clock.advanceTime(1000, TimeUnit.MILLISECONDS);
    Event e3 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "Buy Groceries");
    e3.addTag("duration", "1500");
    e3.addTag("accountId", "user1");
    e3.addTag("location", "ip1");
    Event e13 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "Buy Groceries");
    e13.addTag("duration", "1500");
    e13.addTag("accountId", "user3");
    e13.addTag("location", "ip10");
    insert(e3, e13);
    // t0 + 3000
    now = clock.advanceTime(1000, TimeUnit.MILLISECONDS);
    Event e4 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "Buy VideoGames");
    e4.addTag("duration", "3000");
    e4.addTag("accountId", "user1");
    e4.addTag("location", "ip2");
    Event e14 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "Buy VideoGames");
    e14.addTag("duration", "3000");
    e14.addTag("accountId", "user3");
    e14.addTag("location", "ip10");
    insert(e4, e14);
    // t0 + 4000
    now = clock.advanceTime(1000, TimeUnit.MILLISECONDS);
    Event e5 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "Buy VideoGames");
    e5.addTag("duration", "3000");
    e5.addTag("accountId", "user1");
    e5.addTag("location", "ip1");
    Event e15 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "Buy VideoGames");
    e15.addTag("duration", "3000");
    e15.addTag("accountId", "user3");
    e15.addTag("location", "ip10");
    insert(e5, e15);
    // t0 + 15000
    now = clock.advanceTime(11000, TimeUnit.MILLISECONDS);
    Event e7 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "Buy Music");
    e7.addTag("duration", "2000");
    e7.addTag("accountId", "user2");
    e7.addTag("location", "ip4");
    insert(e7);
    // t0 + 20000
    now = clock.advanceTime(5000, TimeUnit.MILLISECONDS);
    Event e8 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "Buy Groceries");
    e8.addTag("duration", "1500");
    e8.addTag("accountId", "user2");
    e8.addTag("location", "ip5");
    insert(e8);
    stopSession();
    Assert.assertEquals(3, results.size());
    results.stream().forEach(e -> {
        String accountId = e.getContext().get("accountId");
        Assert.assertTrue(accountId.equals("user1") || accountId.equals("user2"));
        /*
            System.out.println("Event: ");
            System.out.println(e);
            System.out.println("Source events:");
            extractEvents(e).stream().forEach(extracted -> {
                System.out.println(extracted);
            });
            System.out.println("\n");
        */
    });
}