/** * 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.NameChanged; 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 NameProtocolTest extends RepositoryUsingTest { public NameProtocolTest() { super(NameChanged.class.getPackage(), NameProtocolTest.class.getPackage()); } @Accessors(fluent = true) public static class Rename extends StandardCommand<Void, String> { @Getter private final UUID id; @Getter private final String name; @LayoutConstructor public Rename(UUID id, String name) { this.id = id; this.name = name; } @Builder public Rename(HybridTimestamp timestamp, UUID id, String name) { super(timestamp); this.id = id; this.name = name; } @Override public EventStream<Void> events() throws Exception { return EventStream.of(NameChanged.builder().reference(id).name(name).timestamp(timestamp()).build()); } @Override public String result() { return name; } } public static class TestModel implements Model, NameProtocol { @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 renaming() { HybridTimestamp timestamp = new HybridTimestamp(timeProvider); timestamp.update(); TestModel model = new TestModel(repository, UUID.randomUUID()); Rename rename = new Rename(model.getId(), "Name #1"); repository.publish(rename).get(); assertEquals(model.name(), "Name #1"); Rename renameBefore = Rename.builder().id(model.getId()).name("Name #0").timestamp(timestamp).build(); assertTrue(renameBefore.timestamp().compareTo(rename.timestamp()) < 0); repository.publish(renameBefore).get(); assertEquals(model.name(), "Name #1"); // earlier change shouldn't affect the name rename = new Rename(model.getId(), "Name #2"); repository.publish(rename).get(); assertEquals(model.name(), "Name #2"); } @Test @SneakyThrows public void query() { HybridTimestamp timestamp = new HybridTimestamp(timeProvider); timestamp.update(); TestModel model = new TestModel(repository, UUID.randomUUID()); Rename rename = new Rename(model.getId(), "Name"); repository.publish(rename).get(); Collection<TestModel> models = ModelCollectionQuery .query(repository, NameProtocol.named("Name", TestModel::lookup)); assertEquals(models.size(), 1); assertTrue(models.stream().anyMatch(m -> m.name().contentEquals("Name"))); } }