diff --git a/pom.xml b/pom.xml
index f24b03ad..6bc05cf8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,7 +44,7 @@
9.40
1.9.1
1.4.1
- 1.7.1
+ 1.7.2
5.2.3
1.1.6.RELEASE
diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/api/OpmlService.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/api/OpmlService.java
index 7c37e9ce..51667ac1 100644
--- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/api/OpmlService.java
+++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/api/OpmlService.java
@@ -1,13 +1,12 @@
package fr.ght1pc9kc.baywatch.opml.api;
-import org.springframework.core.io.buffer.DataBuffer;
-import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.io.InputStream;
+import java.util.function.Supplier;
public interface OpmlService {
Mono opmlExport();
- Mono opmlImport(Flux data);
+ Mono opmlImport(Supplier inputSupplier);
}
diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/domain/OpmlServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/domain/OpmlServiceImpl.java
index 3d4a958c..0d190219 100644
--- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/domain/OpmlServiceImpl.java
+++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/domain/OpmlServiceImpl.java
@@ -1,18 +1,16 @@
package fr.ght1pc9kc.baywatch.opml.domain;
import com.machinezoo.noexception.Exceptions;
+import fr.ght1pc9kc.baywatch.common.domain.QueryContext;
import fr.ght1pc9kc.baywatch.opml.api.OpmlService;
import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade;
import fr.ght1pc9kc.baywatch.security.api.model.User;
import fr.ght1pc9kc.baywatch.security.domain.exceptions.UnauthenticatedUser;
import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed;
-import fr.ght1pc9kc.baywatch.common.domain.QueryContext;
import fr.ght1pc9kc.baywatch.techwatch.infra.persistence.FeedRepository;
import fr.ght1pc9kc.entity.api.Entity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.core.io.buffer.DataBuffer;
-import org.springframework.core.io.buffer.DataBufferUtils;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -20,6 +18,7 @@
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
+import java.util.function.Supplier;
@Slf4j
@RequiredArgsConstructor
@@ -47,25 +46,17 @@ public Mono opmlExport() {
}
@Override
- public Mono opmlImport(Flux data) {
- log.debug("Start importing...");
+ public Mono opmlImport(Supplier inputSupplier) {
return authFacade.getConnectedUser()
.switchIfEmpty(Mono.error(new UnauthenticatedUser("Authentication not found !")))
.flatMapMany(Exceptions.wrap().function(owner -> {
- PipedOutputStream pos = new PipedOutputStream();
- PipedInputStream pis = new PipedInputStream(pos);
- Flux> feeds = readOpml(pis);
- Mono> db = DataBufferUtils.write(data, pos)
- .map(DataBufferUtils::release)
- .doOnTerminate(Exceptions.wrap().runnable(() -> {
- pos.flush();
- pos.close();
- }))
- .then(Mono.empty());
- return Flux.merge(db, feeds)
+ InputStream is = inputSupplier.get();
+ return readOpml(is)
.buffer(100)
.flatMap(f -> feedRepository.persist(f).collectList())
- .flatMap(f -> feedRepository.persistUserRelation(owner.id(), f));
+ .flatMap(f -> feedRepository.persistUserRelation(owner.id(), f))
+ .doOnTerminate(Exceptions.wrap().runnable(is::close));
+
})).then();
}
diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/infra/OpmlController.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/infra/OpmlController.java
index d0b0f6f5..ec72b67e 100644
--- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/infra/OpmlController.java
+++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/infra/OpmlController.java
@@ -1,11 +1,13 @@
package fr.ght1pc9kc.baywatch.opml.infra;
+import com.machinezoo.noexception.Exceptions;
import fr.ght1pc9kc.baywatch.opml.api.OpmlService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
@@ -20,9 +22,13 @@
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
+import reactor.core.scheduler.Scheduler;
+import reactor.core.scheduler.Schedulers;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
@@ -34,6 +40,7 @@
public class OpmlController {
private final OpmlService opmlService;
+ private final Scheduler uploadReader = Schedulers.boundedElastic();
@ResponseBody
@GetMapping("/export/baywatch.opml")
@@ -51,8 +58,19 @@ public Mono> exportOpml() {
}
@PostMapping("/import")
+ @SuppressWarnings("CallingSubscribeInNonBlockingScope")
public Mono importOpml(@RequestPart("opml") Mono opmlFilePart) {
Flux data = opmlFilePart.flatMapMany(Part::content);
- return opmlService.opmlImport(data);
+
+ PipedOutputStream pos = new PipedOutputStream();
+ DataBufferUtils.write(data, pos)
+ .doOnTerminate(Exceptions.wrap().runnable(pos::close))
+ .subscribe(
+ DataBufferUtils.releaseConsumer(),
+ t -> log.atError().log("STACKTRACE", t)
+ );
+
+ return opmlService.opmlImport(Exceptions.wrap().supplier(() -> new PipedInputStream(pos)))
+ .subscribeOn(uploadReader);
}
-}
+}
\ No newline at end of file
diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepository.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepository.java
index 99c2844c..4ae26422 100644
--- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepository.java
+++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepository.java
@@ -94,9 +94,9 @@ public Flux>> getFeedProperties(
}
if (nonNull(properties)) {
if (properties.size() == 1) {
- FEEDS_USERS_PROPERTIES.FUPR_PROPERTY_NAME.eq(properties.iterator().next().name());
+ query.addConditions(FEEDS_USERS_PROPERTIES.FUPR_PROPERTY_NAME.eq(properties.iterator().next().name()));
} else if (!properties.isEmpty()) {
- FEEDS_USERS_PROPERTIES.FUPR_PROPERTY_NAME.in(properties.stream().map(FeedProperties::name).toList());
+ query.addConditions(FEEDS_USERS_PROPERTIES.FUPR_PROPERTY_NAME.in(properties.stream().map(FeedProperties::name).toList()));
}
}
query.addOrderBy(FEEDS_USERS_PROPERTIES.FUPR_USER_ID, FEEDS_USERS_PROPERTIES.FUPR_FEED_ID);
diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/opml/domain/OpmlServiceImplTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/opml/domain/OpmlServiceImplTest.java
new file mode 100644
index 00000000..b5b044fb
--- /dev/null
+++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/opml/domain/OpmlServiceImplTest.java
@@ -0,0 +1,75 @@
+package fr.ght1pc9kc.baywatch.opml.domain;
+
+import fr.ght1pc9kc.baywatch.common.domain.QueryContext;
+import fr.ght1pc9kc.baywatch.opml.api.OpmlService;
+import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade;
+import fr.ght1pc9kc.baywatch.security.infra.adapters.SpringAuthenticationContext;
+import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed;
+import fr.ght1pc9kc.baywatch.techwatch.infra.persistence.FeedRepository;
+import fr.ght1pc9kc.baywatch.tests.samples.FeedSamples;
+import fr.ght1pc9kc.baywatch.tests.samples.UserSamples;
+import fr.ght1pc9kc.entity.api.Entity;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+class OpmlServiceImplTest {
+
+ private OpmlService tested;
+
+ private AuthenticationFacade authenticationFacadeMock;
+ private FeedRepository feedRepositoryMock;
+
+ @BeforeEach
+ void setUp() {
+ feedRepositoryMock = mock(FeedRepository.class);
+ doReturn(Flux.just(FeedSamples.JEDI)).when(feedRepositoryMock).list(any(QueryContext.class));
+ doAnswer(answer -> Flux.fromIterable(answer.getArgument(0))).when(feedRepositoryMock).persist(any());
+ doAnswer(answer -> Flux.fromIterable(answer.getArgument(1))).when(feedRepositoryMock).persistUserRelation(anyString(), any());
+
+ authenticationFacadeMock = spy(new SpringAuthenticationContext());
+ tested = new OpmlServiceImpl(feedRepositoryMock, authenticationFacadeMock, OpmlWriter::new, OpmlReader::new);
+ }
+
+ @Test
+ void should_export_opml() {
+ doReturn(Mono.just(UserSamples.OBIWAN)).when(authenticationFacadeMock).getConnectedUser();
+
+ StepVerifier.create(tested.opmlExport())
+ .assertNext(actual -> Assertions.assertThat(actual).asString(StandardCharsets.UTF_8)
+ .contains("Obiwan Kenobi")
+ .contains("Baywatch OPML export")
+ .containsIgnoringNewLines("""
+
+ """))
+ .verifyComplete();
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ void should_import_opml() {
+ doReturn(Mono.just(UserSamples.OBIWAN)).when(authenticationFacadeMock).getConnectedUser();
+
+ StepVerifier.create(tested.opmlImport(() -> OpmlServiceImplTest.class.getResourceAsStream("okenobi.xml")))
+ .verifyComplete();
+
+ ArgumentCaptor>> captor = ArgumentCaptor.forClass(Collection.class);
+ verify(feedRepositoryMock).persist(captor.capture());
+ Assertions.assertThat(captor.getValue()).hasSize(30);
+ }
+}
\ No newline at end of file
diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepositoryTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepositoryTest.java
index eeb25ce8..61966765 100644
--- a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepositoryTest.java
+++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepositoryTest.java
@@ -4,11 +4,14 @@
import fr.ght1pc9kc.baywatch.common.domain.Hasher;
import fr.ght1pc9kc.baywatch.common.domain.QueryContext;
import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsRecord;
+import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsUsersPropertiesRecord;
import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsUsersRecord;
import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed;
import fr.ght1pc9kc.baywatch.techwatch.infra.config.TechwatchMapper;
import fr.ght1pc9kc.baywatch.techwatch.infra.model.FeedDeletedResult;
+import fr.ght1pc9kc.baywatch.techwatch.infra.model.FeedProperties;
import fr.ght1pc9kc.baywatch.tests.samples.infra.FeedRecordSamples;
+import fr.ght1pc9kc.baywatch.tests.samples.infra.FeedsUsersPropertiesRecordSample;
import fr.ght1pc9kc.baywatch.tests.samples.infra.FeedsUsersRecordSample;
import fr.ght1pc9kc.baywatch.tests.samples.infra.NewsRecordSamples;
import fr.ght1pc9kc.baywatch.tests.samples.infra.UsersRecordSamples;
@@ -19,6 +22,8 @@
import fr.ght1pc9kc.testy.jooq.WithDslContext;
import fr.ght1pc9kc.testy.jooq.WithInMemoryDatasource;
import fr.ght1pc9kc.testy.jooq.WithSampleDataLoaded;
+import org.apache.commons.lang3.stream.Streams;
+import org.assertj.core.api.Assertions;
import org.assertj.core.api.SoftAssertions;
import org.jooq.DSLContext;
import org.junit.jupiter.api.BeforeEach;
@@ -32,7 +37,9 @@
import java.net.URI;
import java.time.Instant;
import java.util.Collections;
+import java.util.EnumSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import static fr.ght1pc9kc.baywatch.common.api.model.EntitiesProperties.COUNT;
@@ -40,7 +47,9 @@
import static fr.ght1pc9kc.baywatch.common.api.model.FeedMeta.updated;
import static fr.ght1pc9kc.baywatch.dsl.tables.Feeds.FEEDS;
import static fr.ght1pc9kc.baywatch.dsl.tables.FeedsUsers.FEEDS_USERS;
+import static fr.ght1pc9kc.baywatch.dsl.tables.FeedsUsersProperties.FEEDS_USERS_PROPERTIES;
import static fr.ght1pc9kc.baywatch.tests.samples.UserSamples.OBIWAN;
+import static fr.ght1pc9kc.baywatch.tests.samples.infra.UsersRecordSamples.LSKYWALKER;
import static fr.ght1pc9kc.baywatch.tests.samples.infra.UsersRecordSamples.OKENOBI;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
@@ -57,6 +66,7 @@ class FeedRepositoryTest {
.addDataset(NewsRecordSamples.SAMPLE)
.addDataset(NewsRecordSamples.NewsFeedsRecordSample.SAMPLE)
.addDataset(FeedsUsersRecordSample.SAMPLE)
+ .addDataset(FeedsUsersPropertiesRecordSample.SAMPLE)
.build();
@RegisterExtension
@@ -75,7 +85,8 @@ void setUp(DSLContext dslContext) {
}
@Test
- void should_get_user_feed() {
+ void should_get_user_feed(WithSampleDataLoaded.Tracker tracker) {
+ tracker.skipNextSampleLoad();
FeedsRecord expected = FeedRecordSamples.SAMPLE.records().getFirst();
Entity actual = tested.get(QueryContext.id(expected.getFeedId())).block();
@@ -244,9 +255,137 @@ void should_delete_feeds_for_user(DSLContext dsl) {
}
@Test
- void should_list_orphan_feed() {
+ void should_list_orphan_feed(WithSampleDataLoaded.Tracker tracker) {
+ tracker.skipNextSampleLoad();
List> actuals = tested.list(QueryContext.all(Criteria.property(COUNT).eq(0))).collectList().block();
assertThat(actuals).extracting(Entity::id).containsExactly(
FeedRecordSamples.FEEDS_RECORDS.getLast().getFeedId());
}
+
+ @Test
+ void should_get_feed_user_properties(WithSampleDataLoaded.Tracker tracker) {
+ tracker.skipNextSampleLoad();
+ StepVerifier.create(tested.getFeedProperties(
+ OKENOBI.getUserId(),
+ List.of(FeedRecordSamples.JEDI.getFeedId()),
+ EnumSet.of(FeedProperties.NAME)
+ ))
+ .assertNext(actual -> Assertions.assertThat(actual).isEqualTo(Entity.identify(
+ Map.of(FeedProperties.NAME, "Customized for Obiwan JEDI Name"))
+ .meta(FeedMeta.createdBy, OKENOBI.getUserId())
+ .withId(FeedRecordSamples.JEDI.getFeedId())
+ ))
+ .verifyComplete();
+
+ StepVerifier.create(tested.getFeedProperties(
+ OKENOBI.getUserId(),
+ List.of(FeedRecordSamples.JEDI.getFeedId()),
+ null
+ ))
+ .assertNext(actual -> Assertions.assertThat(actual).isEqualTo(Entity.identify(
+ Map.of(
+ FeedProperties.NAME, "Customized for Obiwan JEDI Name",
+ FeedProperties.TAG, "light,republic"
+ ))
+ .meta(FeedMeta.createdBy, OKENOBI.getUserId())
+ .withId(FeedRecordSamples.JEDI.getFeedId())
+ ))
+ .verifyComplete();
+
+ StepVerifier.create(tested.getFeedProperties(
+ OKENOBI.getUserId(),
+ List.of(FeedRecordSamples.JEDI.getFeedId()),
+ EnumSet.of(FeedProperties.NAME, FeedProperties.TAG)
+ ))
+ .assertNext(actual -> Assertions.assertThat(actual).isEqualTo(Entity.identify(
+ Map.of(
+ FeedProperties.NAME, "Customized for Obiwan JEDI Name",
+ FeedProperties.TAG, "light,republic"
+ ))
+ .meta(FeedMeta.createdBy, OKENOBI.getUserId())
+ .withId(FeedRecordSamples.JEDI.getFeedId())
+ ))
+ .verifyComplete();
+
+ StepVerifier.create(tested.getFeedProperties(
+ OKENOBI.getUserId(),
+ List.of(FeedRecordSamples.JEDI.getFeedId()),
+ EnumSet.noneOf(FeedProperties.class)
+ ))
+ .assertNext(actual -> Assertions.assertThat(actual).isEqualTo(Entity.identify(
+ Map.of(
+ FeedProperties.NAME, "Customized for Obiwan JEDI Name",
+ FeedProperties.TAG, "light,republic"
+ ))
+ .meta(FeedMeta.createdBy, OKENOBI.getUserId())
+ .withId(FeedRecordSamples.JEDI.getFeedId())
+ ))
+ .verifyComplete();
+
+ StepVerifier.create(tested.getFeedProperties(
+ OKENOBI.getUserId(),
+ List.of(FeedRecordSamples.JEDI.getFeedId(), "42"),
+ EnumSet.of(FeedProperties.NAME)
+ ))
+ .assertNext(actual -> Assertions.assertThat(actual).isEqualTo(Entity.identify(
+ Map.of(FeedProperties.NAME, "Customized for Obiwan JEDI Name"))
+ .meta(FeedMeta.createdBy, OKENOBI.getUserId())
+ .withId(FeedRecordSamples.JEDI.getFeedId())
+ ))
+ .verifyComplete();
+
+ StepVerifier.create(tested.getFeedProperties(
+ OKENOBI.getUserId(),
+ List.of(),
+ EnumSet.of(FeedProperties.NAME)
+ )).verifyError(IllegalArgumentException.class);
+ }
+
+ @Test
+ void should_set_feed_user_properties(DSLContext dslContext) {
+ FeedsUsersPropertiesRecord beforeRecord = dslContext.selectFrom(FEEDS_USERS_PROPERTIES).where(
+ FEEDS_USERS_PROPERTIES.FUPR_FEED_ID.eq(FeedRecordSamples.JEDI.getFeedId()),
+ FEEDS_USERS_PROPERTIES.FUPR_USER_ID.eq(LSKYWALKER.getUserId())
+ ).fetchOne();
+
+ Assertions.assertThat(beforeRecord).isNull();
+
+ StepVerifier.create(tested.setFeedProperties(LSKYWALKER.getUserId(), List.of(
+ Entity.identify(WebFeed.builder()
+ .location(URI.create("https://jedi.com"))
+ .name("Customized for Obiwan JEDI Name")
+ .description("Customized for Obiwan JEDI Description")
+ .tags(Set.of("light", "good"))
+ .build())
+ .withId(FeedRecordSamples.JEDI.getFeedId())
+ ))).verifyComplete();
+
+ FeedsUsersPropertiesRecord[] actualRecord = dslContext.selectFrom(FEEDS_USERS_PROPERTIES).where(
+ FEEDS_USERS_PROPERTIES.FUPR_FEED_ID.eq(FeedRecordSamples.JEDI.getFeedId()),
+ FEEDS_USERS_PROPERTIES.FUPR_USER_ID.eq(LSKYWALKER.getUserId())
+ ).fetchArray();
+
+ SoftAssertions.assertSoftly(softly -> {
+ softly.assertThat(actualRecord)
+ .isNotNull()
+ .hasSize(4);
+
+ softly.assertThat(Streams.of(actualRecord).map(FeedsUsersPropertiesRecord::getFuprPropertyName))
+ .containsExactly(
+ FeedProperties.NAME.name(),
+ FeedProperties.DESCRIPTION.name(),
+ FeedProperties.TAG.name(),
+ FeedProperties.TAG.name()
+ );
+
+ softly.assertThat(Streams.of(actualRecord).map(FeedsUsersPropertiesRecord::getFuprPropertyValue))
+ .containsExactlyInAnyOrder(
+ "Customized for Obiwan JEDI Name",
+ "Customized for Obiwan JEDI Description",
+ "light",
+ "good"
+ );
+ });
+
+ }
}
\ No newline at end of file
diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/tests/samples/infra/FeedsUsersPropertiesRecordSample.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/tests/samples/infra/FeedsUsersPropertiesRecordSample.java
new file mode 100644
index 00000000..23a46bf6
--- /dev/null
+++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/tests/samples/infra/FeedsUsersPropertiesRecordSample.java
@@ -0,0 +1,39 @@
+package fr.ght1pc9kc.baywatch.tests.samples.infra;
+
+import fr.ght1pc9kc.baywatch.dsl.tables.FeedsUsersProperties;
+import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsUsersPropertiesRecord;
+import fr.ght1pc9kc.baywatch.techwatch.infra.model.FeedProperties;
+import fr.ght1pc9kc.testy.jooq.model.RelationalDataSet;
+
+import java.util.List;
+
+public class FeedsUsersPropertiesRecordSample implements RelationalDataSet {
+ public static final FeedsUsersPropertiesRecordSample SAMPLE = new FeedsUsersPropertiesRecordSample();
+
+ private static final FeedsUsersPropertiesRecord OBIWAN_JEDI_NAME_PROPERTIES = FeedsUsersProperties.FEEDS_USERS_PROPERTIES.newRecord()
+ .setFuprFeedId(FeedRecordSamples.JEDI.getFeedId())
+ .setFuprUserId(UsersRecordSamples.OKENOBI.getUserId())
+ .setFuprPropertyName(FeedProperties.NAME.name())
+ .setFuprPropertyValue("Customized for Obiwan JEDI Name");
+
+ private static final FeedsUsersPropertiesRecord OBIWAN_JEDI_TAG1_PROPERTIES = FeedsUsersProperties.FEEDS_USERS_PROPERTIES.newRecord()
+ .setFuprFeedId(FeedRecordSamples.JEDI.getFeedId())
+ .setFuprUserId(UsersRecordSamples.OKENOBI.getUserId())
+ .setFuprPropertyName(FeedProperties.TAG.name())
+ .setFuprPropertyValue("light");
+
+ private static final FeedsUsersPropertiesRecord OBIWAN_JEDI_TAG2_PROPERTIES = FeedsUsersProperties.FEEDS_USERS_PROPERTIES.newRecord()
+ .setFuprFeedId(FeedRecordSamples.JEDI.getFeedId())
+ .setFuprUserId(UsersRecordSamples.OKENOBI.getUserId())
+ .setFuprPropertyName(FeedProperties.TAG.name())
+ .setFuprPropertyValue("republic");
+
+ @Override
+ public List records() {
+ return List.of(
+ OBIWAN_JEDI_NAME_PROPERTIES,
+ OBIWAN_JEDI_TAG1_PROPERTIES,
+ OBIWAN_JEDI_TAG2_PROPERTIES
+ );
+ }
+}
diff --git a/sandside/src/test/resources/fr/ght1pc9kc/baywatch/opml/domain/okenobi.xml b/sandside/src/test/resources/fr/ght1pc9kc/baywatch/opml/domain/okenobi.xml
new file mode 100644
index 00000000..531402e9
--- /dev/null
+++ b/sandside/src/test/resources/fr/ght1pc9kc/baywatch/opml/domain/okenobi.xml
@@ -0,0 +1,72 @@
+
+
+
+ Baywatch OPML export
+ Sun, 28 Apr 2024 17:47:47 GMT
+ Fred
+ marthym@gmail.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file