/**
* 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.EventStream;
import com.eventsourcing.Model;
import com.eventsourcing.Repository;
import com.eventsourcing.StandardCommand;
import com.eventsourcing.cep.events.DescriptionChanged;
import com.eventsourcing.hlc.HybridTimestamp;
import com.eventsourcing.layout.LayoutConstructor;
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.assertEquals;
import static org.testng.Assert.assertTrue;
public class DescriptionProtocolTest extends RepositoryUsingTest {
public DescriptionProtocolTest() {
super(DescriptionChanged.class.getPackage(), DescriptionProtocolTest.class.getPackage());
}
@Accessors(fluent = true)
public static class ChangeDescription extends StandardCommand<Void, String> {
@Getter
private final UUID id;
@Getter
private final String description;
@LayoutConstructor
public ChangeDescription(UUID id, String description) {
this.id = id;
this.description = description;
}
@Builder
public ChangeDescription(HybridTimestamp timestamp, UUID id, String description) {
super(timestamp);
this.id = id;
this.description = description;
}
@Override
public EventStream<Void> events() throws Exception {
return EventStream.of(DescriptionChanged.builder()
.reference(id)
.description(description)
.timestamp(timestamp()).build());
}
@Override
public String result() {
return description;
}
}
public static class TestModel implements Model, DescriptionProtocol {
@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 uuid) {
return Optional.of(new TestModel(repository, uuid));
}
}
@Test
@SneakyThrows
public void changingDescription() {
HybridTimestamp timestamp = new HybridTimestamp(timeProvider);
timestamp.update();
TestModel model = new TestModel(repository, UUID.randomUUID());
ChangeDescription changeDescription = new ChangeDescription(model.getId(), "Description #1");
repository.publish(changeDescription).get();
assertEquals(model.description(), "Description #1");
ChangeDescription changeBefore = ChangeDescription.builder()
.id(model.getId()).description("Description #0")
.timestamp(timestamp).build();
assertTrue(changeBefore.timestamp().compareTo(changeDescription.timestamp()) < 0);
repository.publish(changeBefore).get();
assertEquals(model.description(), "Description #1"); // earlier change shouldn't affect the description
changeDescription = new ChangeDescription(model.getId(), "Description #2");
repository.publish(changeDescription).get();
assertEquals(model.description(), "Description #2");
}
@Test
@SneakyThrows
public void query() {
HybridTimestamp timestamp = new HybridTimestamp(timeProvider);
timestamp.update();
NameProtocolTest.TestModel model = new NameProtocolTest.TestModel(repository, UUID.randomUUID());
ChangeDescription changeDescription = new ChangeDescription(model.getId(), "Description");
repository.publish(changeDescription).get();
Collection<TestModel> models = ModelCollectionQuery.query(repository, DescriptionProtocol.described("Description", TestModel::lookup));
assertEquals(models.size(), 1);
assertTrue(models.stream().anyMatch(m -> m.description().contentEquals("Description")));
}
}