Skip to content
This repository has been archived by the owner on Nov 6, 2023. It is now read-only.

Video repository to save all published videos and new use case to find the last one. #18

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/mooc/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
dependencies {
compile project(":src:shared")

compileOnly 'org.projectlombok:lombok:1.18.16'
annotationProcessor 'org.projectlombok:lombok:1.18.16'

testCompileOnly 'org.projectlombok:lombok:1.18.16'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.16'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package tv.codely.mooc.video.application.publish;

import lombok.AllArgsConstructor;
import tv.codely.mooc.video.domain.Video;
import tv.codely.mooc.video.domain.VideoRepository;

import java.util.Optional;

@AllArgsConstructor
public final class VideoLastPublishedFinder {
VideoRepository videoRepository;

public Optional<Video> getLastVideoPublished() {
return videoRepository.getLastVideo();
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
package tv.codely.mooc.video.application.publish;

import lombok.AllArgsConstructor;
import tv.codely.mooc.video.domain.Video;
import tv.codely.mooc.video.domain.VideoDescription;
import tv.codely.mooc.video.domain.VideoRepository;
import tv.codely.mooc.video.domain.VideoTitle;
import tv.codely.shared.domain.EventBus;

@AllArgsConstructor
public final class VideoPublisher {
private final EventBus eventBus;

public VideoPublisher(EventBus eventBus) {
this.eventBus = eventBus;
}
EventBus eventBus;
VideoRepository videoRepository;

public void publish(String rawTitle, String rawDescription) {
final var title = new VideoTitle(rawTitle);
final var description = new VideoDescription(rawDescription);

final var video = Video.publish(title, description);

videoRepository.save(video);
eventBus.publish(video.pullDomainEvents());
}
}
9 changes: 4 additions & 5 deletions src/mooc/main/tv/codely/mooc/video/domain/Video.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package tv.codely.mooc.video.domain;

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import tv.codely.shared.domain.AggregateRoot;

@EqualsAndHashCode
@AllArgsConstructor
public final class Video extends AggregateRoot {
private final VideoTitle title;
private final VideoDescription description;

private Video(VideoTitle title, VideoDescription description) {
this.title = title;
this.description = description;
}

public static Video publish(VideoTitle title, VideoDescription description) {
var video = new Video(title, description);

Expand Down
11 changes: 11 additions & 0 deletions src/mooc/main/tv/codely/mooc/video/domain/VideoRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package tv.codely.mooc.video.domain;

import java.util.Optional;

public interface VideoRepository {

void save (Video video);

Optional<Video> getLastVideo();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package tv.codely.mooc.video.infrastructure;

import tv.codely.mooc.video.application.publish.VideoLastPublishedFinder;
import tv.codely.mooc.video.domain.Video;
import tv.codely.mooc.video.domain.VideoRepository;

import java.util.Optional;

public class VideoLastPublishedFinderCliController {
public static void main(String[] args) {
final VideoRepository videoRepository = new VideoRepositoryInMemory();
final var videoLastPublishedFinder = new VideoLastPublishedFinder(videoRepository);

Optional<Video> lastVideoPublished = videoLastPublishedFinder.getLastVideoPublished();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import tv.codely.mooc.notification.application.create.SendPushToSubscribersOnVideoPublished;
import tv.codely.mooc.video.application.publish.VideoPublisher;
import tv.codely.mooc.video.domain.VideoRepository;
import tv.codely.shared.application.DomainEventSubscriber;
import tv.codely.shared.domain.EventBus;
import tv.codely.shared.infrastructure.bus.ReactorEventBus;
Expand All @@ -14,7 +15,8 @@ public static void main(String[] args) {
new SendPushToSubscribersOnVideoPublished()
);
final EventBus eventBus = new ReactorEventBus(subscribers);
final var videoPublisher = new VideoPublisher(eventBus);
final VideoRepository videoRepository = new VideoRepositoryInMemory();
final var videoPublisher = new VideoPublisher(eventBus, videoRepository);

final var videoTitle = "\uD83C\uDF89 New YouTube.com/CodelyTV video title";
final var videoDescription = "This should be the video description \uD83D\uDE42";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package tv.codely.mooc.video.infrastructure;

import lombok.Getter;
import tv.codely.mooc.video.domain.Video;
import tv.codely.mooc.video.domain.VideoRepository;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class VideoRepositoryInMemory implements VideoRepository {

@Getter
private List<Video> videos = new ArrayList<>();

@Override
public void save(Video video) {
videos.add(video);
}

@Override
public Optional<Video> getLastVideo() {
if (videos.isEmpty()) {
return Optional.empty();
} else {
return Optional.of(videos.get(videos.size() - 1));
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package tv.codely.mooc.video.application.publish;

import org.junit.jupiter.api.Test;
import tv.codely.mooc.video.domain.Video;
import tv.codely.mooc.video.domain.VideoDescription;
import tv.codely.mooc.video.domain.VideoRepository;
import tv.codely.mooc.video.domain.VideoTitle;

import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;

final class VideoLastPublishedFinderShould {
@Test
void get_last_video_published() {
final VideoRepository videoRepository = mock(VideoRepository.class);
final var finder = new VideoLastPublishedFinder(videoRepository);
final var exampleVideo = Video.publish(new VideoTitle("t"), new VideoDescription("t"));
doReturn(Optional.of(exampleVideo)).when(videoRepository).getLastVideo();

Optional<Video> lastVideoPublishedOpt = finder.getLastVideoPublished();

assertEquals(exampleVideo, lastVideoPublishedOpt.get());
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package tv.codely.mooc.video.application.publish;

import org.junit.jupiter.api.Test;
import tv.codely.mooc.video.domain.VideoPublished;
import tv.codely.mooc.video.domain.*;
import tv.codely.shared.domain.EventBus;

import java.util.List;
Expand All @@ -13,16 +13,19 @@ final class VideoPublisherShould {
@Test
void publish_the_video_published_domain_event() {
final EventBus eventBus = mock(EventBus.class);
final var videoPublisher = new VideoPublisher(eventBus);
final VideoRepository videoRepository = mock(VideoRepository.class);
final var videoPublisher = new VideoPublisher(eventBus, videoRepository);

final var videoTitle = "\uD83C\uDF89 New YouTube.com/CodelyTV video title";
final var videoDescription = "This should be the video description \uD83D\uDE42";

videoPublisher.publish(videoTitle, videoDescription);

final var expectedVideoCreated = new VideoPublished(videoTitle, videoDescription);
final var expectedVideoSaved = Video.publish(new VideoTitle(videoTitle), new VideoDescription(videoDescription));

verify(eventBus).publish(List.of(expectedVideoCreated));
verify(videoRepository).save(expectedVideoSaved);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package tv.codely.mooc.video.infrastructure;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import tv.codely.mooc.video.domain.Video;
import tv.codely.mooc.video.domain.VideoDescription;
import tv.codely.mooc.video.domain.VideoTitle;

import java.util.Optional;

import static org.junit.jupiter.api.Assertions.*;

class VideoRepositoryInMemoryShould {

VideoRepositoryInMemory repository;

@BeforeEach
void setUp() {
repository = new VideoRepositoryInMemory();
}

@Test
void save_should_persist_in_memory() {
Video video = givenVideo("t", "d");

repository.save(video);

assertEquals(1, repository.getVideos().size());
assertEquals(video, repository.getVideos().get(0));
}

private Video givenVideo(String title, String description) {
return Video.publish(new VideoTitle(title), new VideoDescription(description));
}

@Test
void get_last_should_not_receive_it_not_saved_any() {
Optional<Video> lastVideoOpt = repository.getLastVideo();

assertFalse(lastVideoOpt.isPresent());
}

@Test
void get_last_should_receive_first_if_one_saved() {
Video video = givenVideo("t", "d");
repository.save(video);

Optional<Video> lastVideoOpt = repository.getLastVideo();

assertTrue(lastVideoOpt.isPresent());
assertEquals(video, lastVideoOpt.get());
}

@Test
void get_last_should_receive_first_if_more_than_one_saved() {
Video video = givenVideo("t", "d");
repository.save(video);
Video video2 = givenVideo("t2", "d2");
repository.save(video2);

Optional<Video> lastVideoOpt = repository.getLastVideo();

assertTrue(lastVideoOpt.isPresent());
assertEquals(video2, lastVideoOpt.get());
}

}