/**
* Copyright (c) 2016, All Contributors (see CONTRIBUTORS file)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.eventsourcing.cep.protocols;
import com.eventsourcing.*;
import com.eventsourcing.cep.events.Deleted;
import com.eventsourcing.cep.events.Undeleted;
import com.eventsourcing.hlc.HybridTimestamp;
import com.eventsourcing.index.SimpleIndex;
import com.eventsourcing.queries.ModelCollectionQuery;
import lombok.Builder;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.experimental.Accessors;
import org.testng.annotations.Test;
import java.util.Collection;
import java.util.Optional;
import java.util.UUID;
import static org.testng.Assert.*;
public class DeletedProtocolTest extends RepositoryUsingTest {
public DeletedProtocolTest() {
super(com.eventsourcing.cep.events.Deleted.class.getPackage(), DeletedProtocolTest.class.getPackage());
}
public static class Create extends StandardCommand<Created, Created> {
@Override public EventStream<Created> events() throws Exception {
Created created = new Created();
return EventStream.ofWithState(created, created);
}
@Override public Created result(Created state) {
return state;
}
}
public static class Created extends StandardEvent {
public final static SimpleIndex<Created, UUID> ID = SimpleIndex.as(StandardEntity::uuid);
}
@Accessors(fluent = true)
public static class Delete extends StandardCommand<Void, Void> {
@Getter
final private UUID id;
private UUID eventId;
@Builder
public Delete(UUID id, HybridTimestamp timestamp) {
super(timestamp);
this.id = id;
}
public Delete(UUID id) {
this.id = id;
}
@Override
public EventStream<Void> events() throws Exception {
Deleted reference = Deleted.builder().reference(id).build();
eventId = reference.uuid();
return EventStream.of(reference);
}
@Override
public Void result() {
return null;
}
}
@Accessors(fluent = true)
public static class Undelete extends StandardCommand<Void, Void> {
@Getter
private final UUID id;
@Builder
public Undelete(UUID id, HybridTimestamp timestamp) {
super(timestamp);
this.id = id;
}
public Undelete(UUID id) {
this.id = id;
}
@Override
public EventStream<Void> events() throws Exception {
return EventStream.of(Undeleted.builder().deleted(id).build());
}
@Override
public Void result() {
return null;
}
}
public static class TestModel implements Model, DeletedProtocol {
@Getter
private final Repository repository;
@Getter
private final UUID id;
public TestModel(Repository repository, UUID id) {
this.repository = repository;
this.id = id;
}
public static Optional<TestModel> lookup(Repository repository, UUID id) {
return Optional.of(new TestModel(repository, id));
}
}
@Test @SneakyThrows
public void deletion() {
TestModel model = new TestModel(repository, UUID.randomUUID());
assertFalse(model.deleted().isPresent());
Delete delete = new Delete(model.getId());
repository.publish(delete).get();
assertTrue(model.deleted().isPresent());
}
@Test @SneakyThrows
public void undeletion() {
TestModel model = new TestModel(repository, UUID.randomUUID());
Delete delete = new Delete(model.getId());
repository.publish(delete).get();
Undelete undelete = new Undelete(delete.eventId);
repository.publish(undelete).get();
assertFalse(model.deleted().isPresent());
}
@Test @SneakyThrows
public void queryNonDeleted() {
TestModel model = new TestModel(repository, UUID.randomUUID());
Collection<TestModel> models = ModelCollectionQuery
.query(repository, DeletedProtocol.deleted(TestModel::lookup));
assertEquals(models.size(), 0);
}
@Test @SneakyThrows
public void queryUndeleted() {
TestModel model = new TestModel(repository, UUID.randomUUID());
assertFalse(model.deleted().isPresent());
Delete delete = new Delete(model.getId());
repository.publish(delete).get();
Undelete undelete = new Undelete(delete.eventId);
repository.publish(undelete).get();
Collection<TestModel> models = ModelCollectionQuery
.query(repository, DeletedProtocol.deleted(TestModel::lookup));
assertEquals(models.size(), 0);
}
@Test @SneakyThrows
public void queryDeleted() {
TestModel model = new TestModel(repository, UUID.randomUUID());
assertFalse(model.deleted().isPresent());
Delete delete = new Delete(model.getId());
repository.publish(delete).get();
Collection<TestModel> models = ModelCollectionQuery
.query(repository, DeletedProtocol.deleted(TestModel::lookup));
assertEquals(models.size(), 1);
}
@Test @SneakyThrows
public void queryNonDeletedForNonDeleted() {
Created created = repository.publish(new Create()).get();
Collection<TestModel> models = ModelCollectionQuery
.query(repository, DeletedProtocol.notDeleted(Created.class, Created.ID, TestModel::lookup));
assertEquals(models.size(), 1);
}
@Test @SneakyThrows
public void queryNonDeletedForUndeleted() {
Created created = repository.publish(new Create()).get();
Delete delete = new Delete(created.uuid());
repository.publish(delete).get();
Undelete undelete = new Undelete(delete.eventId);
repository.publish(undelete).get();
Collection<TestModel> models = ModelCollectionQuery
.query(repository, DeletedProtocol.notDeleted(Created.class, Created.ID, TestModel::lookup));
assertEquals(models.size(), 1);
}
@Test @SneakyThrows
public void queryNonDeletedForDeleted() {
Created created = repository.publish(new Create()).get();
Delete delete = new Delete(created.uuid());
repository.publish(delete).get();
Collection<TestModel> models = ModelCollectionQuery
.query(repository, DeletedProtocol.notDeleted(Created.class, Created.ID, TestModel::lookup));
assertEquals(models.size(), 0);
}
}