Skip to content

Commit

Permalink
Merge pull request #204 from vskurikhin/203-stanza-transactional-job-…
Browse files Browse the repository at this point in the history
…test

Fix #203 unit tests for StanzaTransactionalJob.
  • Loading branch information
vskurikhin authored May 23, 2024
2 parents 1c50836 + 6df5122 commit 6adbf5b
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 83 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* This file was last modified at 2024-05-14 21:36 by Victor N. Skurikhin.
* This file was last modified at 2024-05-22 23:14 by Victor N. Skurikhin.
* This is free and unencumbered software released into the public domain.
* For more information, please refer to <http://unlicense.org>
* IteratorNextMapperEnum.java
Expand All @@ -17,7 +17,7 @@
import java.util.function.Function;

public enum IteratorNextMapperEnum {
Null(it -> Optional.empty()),
Null(null),
LongIdIterator(it -> it.hasNext() ? Optional.of(it.next().getLong(Constants.ID)) : Optional.empty()),
StringIdIterator(it -> it.hasNext() ? Optional.of(it.next().getString(Constants.ID)) : Optional.empty()),
UUIDIdIterator(it -> it.hasNext() ? Optional.of(it.next().getUUID(Constants.ID)) : Optional.empty());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* This file was last modified at 2024-05-14 21:36 by Victor N. Skurikhin.
* This file was last modified at 2024-05-23 18:35 by Victor N. Skurikhin.
* This is free and unencumbered software released into the public domain.
* For more information, please refer to <http://unlicense.org>
* StanzaTransactionalJob.java
Expand Down Expand Up @@ -41,15 +41,14 @@ public StanzaTransactionalJob() {
@TransactionAction(
value = """
INSERT INTO dictionary.stanza
(id, name, description, parent_id, user_name, visible, flags)
VALUES(%s, $2, $3, $4, $5, $7, $8)
ON CONFLICT (name) DO
(id, name, description, parent_id, user_name, enabled, visible, flags)
VALUES($1, $2, $3, $4, $5, $6, $7, $8)
ON CONFLICT (id) DO
UPDATE SET
name = $2,
description = $3,
parent_id = $4,
user_name = $5,
enabled = true,
enabled = $6,
visible = $7,
flags = $8
RETURNING id;
Expand Down Expand Up @@ -80,9 +79,9 @@ public Uni<List<Long>> upsert(Collection<Pair<StanzaTable, Collection<SettingTab
value = """
UPDATE dictionary.setting
SET stanza_id = DEFAULT
WHERE stanza_id = ANY ($1)
WHERE stanza_id = $1
""",
name = Constants.CLEAR_RELATION),
name = Constants.CLEAR_ALL_HAS_RELATION_BY_ID),
@TransactionAction(name = Constants.DELETE_MAIN),
})
public Uni<Optional<Long>> delete(@Nonnull StanzaTable table) {
Expand All @@ -97,7 +96,7 @@ protected Function<RowIterator<Row>, Optional<?>> iteratorNextMapper(String acti
Constants.UPSERT_MAIN_TABLE,
Constants.DELETE_MAIN -> iterator ->
iterator.hasNext()
? Optional.of(iterator.next().getUUID(StanzaTable.ID))
? Optional.of(iterator.next().getLong(StanzaTable.ID))
: Optional.empty();
default -> throw new IllegalStateException("Unexpected value: " + actionName);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* This file was last modified at 2024-05-14 21:36 by Victor N. Skurikhin.
* This file was last modified at 2024-05-22 23:15 by Victor N. Skurikhin.
* This is free and unencumbered software released into the public domain.
* For more information, please refer to <http://unlicense.org>
* AbstractListHelper.java
Expand Down Expand Up @@ -48,7 +48,7 @@ protected void setConnection(@Nonnull final SqlConnection connection) {
}

protected Function<? super RowIterator<Row>, ? extends Optional<?>> iteratorNextMapper(Action action, String aName) {
return (action.iteratorNextMapper() == null)
return action.iteratorNextMapper() == null
? job.iteratorNextMapper(aName)
: action.iteratorNextMapper();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* This file was last modified at 2024-05-14 21:36 by Victor N. Skurikhin.
* This file was last modified at 2024-05-23 18:39 by Victor N. Skurikhin.
* This is free and unencumbered software released into the public domain.
* For more information, please refer to <http://unlicense.org>
* UpsertHelper.java
Expand All @@ -9,6 +9,7 @@
package su.svn.daybook3.api.gateway.domain.transact.one_to_many;

import io.smallrye.mutiny.Uni;
import io.vertx.mutiny.sqlclient.Row;
import io.vertx.mutiny.sqlclient.RowSet;
import io.vertx.mutiny.sqlclient.SqlConnection;
import io.vertx.mutiny.sqlclient.Tuple;
Expand Down Expand Up @@ -55,11 +56,21 @@ public Uni<List<MainId>> apply(@Nonnull final SqlConnection sqlConnection) {

private Uni<List<MainId>> checkCountInJoinTableAndThenInsert() {
LOG.tracef("checkCountInJoinTableAndThenInsert");
return Uni
.join()
.all(this.doEachMainTable())
.andCollectFailures()
.map(this::listOfOptionalToList);
return Uni.combine()
.all()
.unis(this.doEachMainTable())
.with(objects -> {
System.out.println("objects = " + objects);
return objects.stream().map(o -> {
if (o instanceof Optional<?> opt) {
return job.castOptionalMainId().apply(opt);
} else {
return Optional.<MainId>empty();
}
}).filter(Optional::isPresent)
.map(Optional::get)
.toList();
});
}

@Nonnull
Expand All @@ -70,58 +81,8 @@ private List<Uni<Optional<MainId>>> doEachMainTable() {
.toList();
}

@Nonnull
private List<MainId> listOfOptionalToList(List<Optional<MainId>> list) {
return list
.stream()
.map(o -> o.orElse(null))
.filter(Objects::nonNull)
.toList();
}

private Uni<Optional<MainId>> upsertMain(Pair<MainTable, Collection<Subsidiary>> pair) {
var table = pair.getKey();
var subsidiaries = pair.getValue();
var helper = new UpsertMainHelper<>(super.job, super.map, table, subsidiaries);
helper.setConnection(super.connection);
return null;
}

static class UpsertMainHelper<
MainId extends Comparable<? extends Serializable>,
MainTable extends CasesOfId<MainId>,
SubId extends Comparable<? extends Serializable>,
Subsidiary extends CasesOfId<SubId>>
extends AbstractHelper<MainId, MainTable, SubId, Subsidiary> {

private final Action action;
private final MainTable table;
private final Collection<Subsidiary> subsidiaries;

UpsertMainHelper(
AbstractOneToManyJob<MainId, MainTable, SubId, Subsidiary> job,
Map<String, Action> map,
MainTable table,
Collection<Subsidiary> subsidiaries) {
super(job, map);
this.action = super.map.get(Constants.UPSERT_MAIN_TABLE);
this.table = table;
this.subsidiaries = subsidiaries;
}

@Override
public Uni<Optional<MainId>> apply(@Nonnull final SqlConnection sqlConnection) {
return connection
.preparedQuery(this.action.sql())
.execute(Helper.updateTuple(action, table))
.map(RowSet::iterator)
.map(iteratorNextMapper(action, Constants.UPSERT_MAIN_TABLE))
.map(job.castOptionalMainId());
}
}

private Uni<Optional<MainId>> updateRelation(Pair<MainTable, Collection<Subsidiary>> pair) {
var action = super.map.get(Constants.UPDATE_RELATION);
var action = super.map.get(Constants.UPSERT_MAIN_TABLE);
var table = pair.getKey();
var subsidiaries = pair.getValue();
var array = subsidiaries
Expand All @@ -130,27 +91,35 @@ private Uni<Optional<MainId>> updateRelation(Pair<MainTable, Collection<Subsidia
.<SubId>toArray();
return connection
.preparedQuery(action.sql())
.execute(Tuple.of(table.id(), array))
.execute(Helper.updateTuple(action, table))
.map(RowSet::iterator)
.flatMap(r -> rowIteratorUniFunction1(table, array));
.map(iteratorNextMapper(action, Constants.UPSERT_MAIN_TABLE))
.map(job.castOptionalMainId())
.flatMap(
mainId -> rowIteratorUniFunction1(table, array)
.replaceWith(Uni.createFrom().item(mainId))
)
.flatMap(
mainId -> rowIteratorUniFunction2(table, array)
.replaceWith(Uni.createFrom().item(mainId))
);
}

private Uni<Optional<MainId>> rowIteratorUniFunction1(MainTable table, Object[] array) {
private Uni<Optional<Row>> rowIteratorUniFunction1(MainTable table, Object[] array) {
var action = super.map.get(Constants.CLEAR_RELATION);
return connection
.preparedQuery(action.sql())
.execute(Tuple.of(table.id(), array))
.map(RowSet::iterator)
.flatMap(r -> rowIteratorUniFunction2(table));
.map(r -> r.hasNext() ? Optional.of(r.next()) : Optional.empty());
}

private Uni<Optional<MainId>> rowIteratorUniFunction2(MainTable table) {
var action = super.map.get(Constants.UPDATE_MAIN_TABLE);
private Uni<Optional<Row>> rowIteratorUniFunction2(MainTable table, Object[] array) {
var action = super.map.get(Constants.UPDATE_RELATION);
return connection
.preparedQuery(action.sql())
.execute(Helper.updateTuple(action, table))
.execute(Tuple.of(table.id(), array))
.map(RowSet::iterator)
.map(iteratorNextMapper(action, Constants.UPDATE_MAIN_TABLE))
.map(job.castOptionalMainId());
.map(r -> r.hasNext() ? Optional.of(r.next()) : Optional.empty());
}
}
132 changes: 128 additions & 4 deletions api-gateway/src/test/java/su/svn/daybook3/api/gateway/DataBaseIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,54 @@
import io.smallrye.mutiny.Multi;
import io.vertx.core.json.JsonObject;
import jakarta.inject.Inject;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.*;
import su.svn.daybook3.api.gateway.domain.dao.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import su.svn.daybook3.api.gateway.domain.dao.CodifierDao;
import su.svn.daybook3.api.gateway.domain.dao.I18nDao;
import su.svn.daybook3.api.gateway.domain.dao.I18nViewDao;
import su.svn.daybook3.api.gateway.domain.dao.KeyValueDao;
import su.svn.daybook3.api.gateway.domain.dao.LanguageDao;
import su.svn.daybook3.api.gateway.domain.dao.RoleDao;
import su.svn.daybook3.api.gateway.domain.dao.SessionDao;
import su.svn.daybook3.api.gateway.domain.dao.SettingDao;
import su.svn.daybook3.api.gateway.domain.dao.SettingViewDao;
import su.svn.daybook3.api.gateway.domain.dao.StanzaDao;
import su.svn.daybook3.api.gateway.domain.dao.StanzaViewDao;
import su.svn.daybook3.api.gateway.domain.dao.TagLabelDao;
import su.svn.daybook3.api.gateway.domain.dao.UserNameDao;
import su.svn.daybook3.api.gateway.domain.dao.UserViewDao;
import su.svn.daybook3.api.gateway.domain.dao.ValueTypeDao;
import su.svn.daybook3.api.gateway.domain.dao.VocabularyDao;
import su.svn.daybook3.api.gateway.domain.dao.WordDao;
import su.svn.daybook3.api.gateway.domain.messages.Answer;
import su.svn.daybook3.api.gateway.domain.messages.ApiResponse;
import su.svn.daybook3.api.gateway.domain.messages.Request;
import su.svn.daybook3.api.gateway.domain.model.*;
import su.svn.daybook3.api.gateway.domain.model.CodifierTable;
import su.svn.daybook3.api.gateway.domain.model.I18nTable;
import su.svn.daybook3.api.gateway.domain.model.I18nView;
import su.svn.daybook3.api.gateway.domain.model.KeyValueTable;
import su.svn.daybook3.api.gateway.domain.model.LanguageTable;
import su.svn.daybook3.api.gateway.domain.model.RoleTable;
import su.svn.daybook3.api.gateway.domain.model.SessionTable;
import su.svn.daybook3.api.gateway.domain.model.SettingTable;
import su.svn.daybook3.api.gateway.domain.model.SettingView;
import su.svn.daybook3.api.gateway.domain.model.StanzaTable;
import su.svn.daybook3.api.gateway.domain.model.StanzaView;
import su.svn.daybook3.api.gateway.domain.model.TagLabelTable;
import su.svn.daybook3.api.gateway.domain.model.UserNameTable;
import su.svn.daybook3.api.gateway.domain.model.UserView;
import su.svn.daybook3.api.gateway.domain.model.ValueTypeTable;
import su.svn.daybook3.api.gateway.domain.model.VocabularyTable;
import su.svn.daybook3.api.gateway.domain.model.WordTable;
import su.svn.daybook3.api.gateway.domain.transact.I18nTransactionalJob;
import su.svn.daybook3.api.gateway.domain.transact.SettingTransactionalJob;
import su.svn.daybook3.api.gateway.domain.transact.StanzaTransactionalJob;
import su.svn.daybook3.api.gateway.domain.transact.UserTransactionalJob;
import su.svn.daybook3.api.gateway.models.TimeUpdated;
import su.svn.daybook3.api.gateway.models.domain.User;
Expand All @@ -31,14 +70,18 @@
import java.math.BigInteger;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;
import java.util.function.Supplier;

import static su.svn.daybook3.api.gateway.TestUtils.*;
import static su.svn.daybook3.api.gateway.TestUtils.multiAsListHelper;
import static su.svn.daybook3.api.gateway.TestUtils.uniListHelper;
import static su.svn.daybook3.api.gateway.TestUtils.uniOptionalHelper;
import static su.svn.daybook3.api.gateway.TestUtils.uniToAnswerHelper;

@SuppressWarnings({"SameParameterValue"})
@QuarkusTest
Expand Down Expand Up @@ -71,6 +114,8 @@ public class DataBaseIT {
@Inject
StanzaViewDao stanzaViewDao;
@Inject
StanzaTransactionalJob stanzaTransactionalJob;
@Inject
TagLabelDao tagLabelDao;
@Inject
UserNameDao userNameDao;
Expand Down Expand Up @@ -1452,6 +1497,85 @@ void test() {
}
}

@SuppressWarnings("UnusedReturnValue")
@Nested
@DisplayName("StanzaTransactionalJob")
class StanzaTransactionalJobTest {

long valueTypeId;
UUID userNameId;
SettingTable setting;

@BeforeEach
void setUp() {
userNameId = UUID.randomUUID();
var userName = UserNameTable.builder()
.id(userNameId)
.userName("user")
.password("password")
.enabled(true)
.build();
Assertions.assertDoesNotThrow(() -> {
uniOptionalHelper(userNameDao.insert(userName));
});
var valueType = ValueTypeTable.builder()
.valueType(ValueTypeTable.NONE)
.enabled(true)
.build();
Assertions.assertDoesNotThrow(() -> {
valueTypeId = uniOptionalHelper(valueTypeDao.insert(valueType));
});
setting = SettingTable.builder()
.id(13L)
.variable("variable1")
.value(SettingTable.NONE)
.valueTypeId(valueTypeId)
.stanzaId(0L)
.build();
Assertions.assertDoesNotThrow(() -> {
uniOptionalHelper(settingDao.insert(setting));
});
}

@AfterEach
void tearDown() {
Assertions.assertDoesNotThrow(() -> {
uniOptionalHelper(settingDao.delete(13L));
});
Assertions.assertDoesNotThrow(() -> {
uniOptionalHelper(valueTypeDao.delete(valueTypeId));
});
Assertions.assertDoesNotThrow(() -> {
uniOptionalHelper(userNameDao.delete(userNameId));
});
}

@Test
void test() {
var stanza1 = StanzaTable.builder()
.id(13L)
.name("name1")
.description("description1")
.parentId(0L)
.userName("user")
.createTime(LocalDateTime.now())
.updateTime(LocalDateTime.now())
.build();
var setting1 = setting.toBuilder().stanzaId(13L).build();

Collection<SettingTable> settings = Collections.singleton(setting1);
Pair<StanzaTable, Collection<SettingTable>> pair = Pair.of(stanza1, settings);
Collection<Pair<StanzaTable, Collection<SettingTable>>> stanzas = Collections.singleton(pair);

Assertions.assertDoesNotThrow(() -> {
uniListHelper(stanzaTransactionalJob.upsert(stanzas));
});
Assertions.assertDoesNotThrow(() -> {
uniOptionalHelper(stanzaTransactionalJob.delete(stanza1));
});
}
}

@Nested
@DisplayName("TagLabelDao")
class TagLabelDaoTest extends AbstractDaoTest<String, TagLabelTable> {
Expand Down
Loading

0 comments on commit 6adbf5b

Please sign in to comment.