Compare commits
1 Commits
master
...
feature/bo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b93369852 |
6
pom.xml
6
pom.xml
@@ -46,6 +46,12 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.takiguchi.demo.intellijshortcuts.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.takiguchi.demo.intellijshortcuts.model.Game;
|
||||
import org.takiguchi.demo.intellijshortcuts.service.GameService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/games")
|
||||
public class GameController {
|
||||
private final GameService gameService;
|
||||
|
||||
public GameController(GameService gameService) {
|
||||
this.gameService = gameService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public List<Game> getAll() {
|
||||
return gameService.findAll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.takiguchi.demo.intellijshortcuts.model;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
import static javax.persistence.FetchType.LAZY;
|
||||
|
||||
@Entity
|
||||
@Table(name = "dlc")
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class Dlc {
|
||||
@Id
|
||||
@GeneratedValue(generator = "system-uuid")
|
||||
private UUID id;
|
||||
private String title;
|
||||
private LocalDate publicationDate;
|
||||
private Double price;
|
||||
@ManyToOne(fetch = LAZY)
|
||||
@JoinColumn(name = "game_id")
|
||||
private Game game;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.takiguchi.demo.intellijshortcuts.model;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "editor")
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class Editor {
|
||||
@Id
|
||||
@GeneratedValue(generator = "system-uuid")
|
||||
private UUID id;
|
||||
private String name;
|
||||
private LocalDate creationDate;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.takiguchi.demo.intellijshortcuts.model;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static javax.persistence.CascadeType.*;
|
||||
import static javax.persistence.FetchType.LAZY;
|
||||
|
||||
@Entity
|
||||
@Table(name = "game")
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class Game {
|
||||
@Id
|
||||
@GeneratedValue(generator = "system-uuid")
|
||||
private UUID id;
|
||||
private String title;
|
||||
private String description;
|
||||
private LocalDate publicationDate;
|
||||
private Double price;
|
||||
@ManyToOne(fetch = LAZY)
|
||||
@JoinColumn(name = "editor_id")
|
||||
private Editor editor;
|
||||
@OneToMany(mappedBy = "game", cascade = ALL)
|
||||
private List<Dlc> dlcList;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.takiguchi.demo.intellijshortcuts.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.takiguchi.demo.intellijshortcuts.model.Dlc;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface DlcRepository extends JpaRepository<Dlc, UUID> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.takiguchi.demo.intellijshortcuts.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.takiguchi.demo.intellijshortcuts.model.Editor;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface EditorRepository extends JpaRepository<Editor, UUID> {
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.takiguchi.demo.intellijshortcuts.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.takiguchi.demo.intellijshortcuts.model.Game;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface GameRepository extends JpaRepository<Game, UUID> {
|
||||
@Query("SELECT DISTINCT g FROM Game g LEFT JOIN FETCH g.dlcList")
|
||||
List<Game> findAllWithDlcs();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.takiguchi.demo.intellijshortcuts.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.takiguchi.demo.intellijshortcuts.model.Game;
|
||||
import org.takiguchi.demo.intellijshortcuts.repository.GameRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class GameService {
|
||||
private final GameRepository gameRepository;
|
||||
|
||||
public GameService(GameRepository gameRepository) {
|
||||
this.gameRepository = gameRepository;
|
||||
}
|
||||
|
||||
public List<Game> findAll() {
|
||||
return gameRepository.findAllWithDlcs();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.takiguchi.demo.intellijshortcuts.configuration;
|
||||
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.takiguchi.demo.intellijshortcuts.repository.EditorRepository;
|
||||
import org.takiguchi.demo.intellijshortcuts.repository.GameRepository;
|
||||
import org.takiguchi.demo.intellijshortcuts.util.DatabaseInitializer;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@TestConfiguration
|
||||
@ComponentScan(basePackages = "org.takiguchi.demo.intellijshortcuts.repository")
|
||||
public class RepositoryConfiguration {
|
||||
@Bean
|
||||
public EmbeddedDatabase dataSource() {
|
||||
return new EmbeddedDatabaseBuilder()
|
||||
.setType(EmbeddedDatabaseType.H2)
|
||||
.addScript("sql/01_init-db.sql")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
|
||||
return new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DatabaseInitializer dataConfiguration(EditorRepository editorRepository,
|
||||
GameRepository gameRepository) {
|
||||
return new DatabaseInitializer(editorRepository, gameRepository);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.takiguchi.demo.intellijshortcuts.configuration;
|
||||
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
|
||||
@TestConfiguration
|
||||
public class TestUtilsConfiguration {
|
||||
@Bean
|
||||
public RestTemplate restTemplate() {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory("http://localhost:8080"));
|
||||
return restTemplate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.takiguchi.demo.intellijshortcuts.controller;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.takiguchi.demo.intellijshortcuts.configuration.RepositoryConfiguration;
|
||||
import org.takiguchi.demo.intellijshortcuts.configuration.TestUtilsConfiguration;
|
||||
import org.takiguchi.demo.intellijshortcuts.extension.DatabaseInitializationExtension;
|
||||
import org.takiguchi.demo.intellijshortcuts.model.Dlc;
|
||||
import org.takiguchi.demo.intellijshortcuts.model.Game;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ExtendWith({
|
||||
SpringExtension.class,
|
||||
DatabaseInitializationExtension.class
|
||||
})
|
||||
@SpringBootTest(classes = {
|
||||
RepositoryConfiguration.class,
|
||||
TestUtilsConfiguration.class
|
||||
})
|
||||
public class GameControllerTest {
|
||||
@Autowired
|
||||
private GameController gameController;
|
||||
|
||||
@Test
|
||||
void getAll_should_fetch_dlc_list() {
|
||||
// when
|
||||
List<Game> games = gameController.getAll();
|
||||
|
||||
// then
|
||||
assertThat(games).hasSize(5);
|
||||
List<String> dlcTitles = games.stream()
|
||||
.filter(game -> "World of Warcraft".equals(game.getTitle()))
|
||||
.findFirst()
|
||||
.map(Game::getDlcList)
|
||||
.stream()
|
||||
.flatMap(Collection::stream)
|
||||
.map(Dlc::getTitle)
|
||||
.collect(toList());
|
||||
assertThat(dlcTitles).containsExactlyInAnyOrder("The Burning Crusade", "Wrath of the Lich King");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.takiguchi.demo.intellijshortcuts.extension;
|
||||
|
||||
import org.junit.jupiter.api.extension.AfterAllCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeAllCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.takiguchi.demo.intellijshortcuts.util.DatabaseInitializer;
|
||||
|
||||
public class DatabaseInitializationExtension implements BeforeAllCallback, AfterAllCallback {
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext extensionContext) {
|
||||
ApplicationContext applicationContext = SpringExtension.getApplicationContext(extensionContext);
|
||||
DatabaseInitializer databaseInitializer = applicationContext.getBean(DatabaseInitializer.class);
|
||||
databaseInitializer.initData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAll(ExtensionContext extensionContext) {
|
||||
ApplicationContext applicationContext = SpringExtension.getApplicationContext(extensionContext);
|
||||
DatabaseInitializer databaseInitializer = applicationContext.getBean(DatabaseInitializer.class);
|
||||
databaseInitializer.clearData();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package org.takiguchi.demo.intellijshortcuts.util;
|
||||
|
||||
import org.takiguchi.demo.intellijshortcuts.model.Dlc;
|
||||
import org.takiguchi.demo.intellijshortcuts.model.Editor;
|
||||
import org.takiguchi.demo.intellijshortcuts.model.Game;
|
||||
import org.takiguchi.demo.intellijshortcuts.repository.EditorRepository;
|
||||
import org.takiguchi.demo.intellijshortcuts.repository.GameRepository;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
public class DatabaseInitializer {
|
||||
private final EditorRepository editorRepository;
|
||||
private final GameRepository gameRepository;
|
||||
|
||||
public DatabaseInitializer(EditorRepository editorRepository,
|
||||
GameRepository gameRepository) {
|
||||
this.editorRepository = editorRepository;
|
||||
this.gameRepository = gameRepository;
|
||||
}
|
||||
|
||||
public void initData() {
|
||||
Editor psyconix = Editor.builder()
|
||||
.name("Psyconix")
|
||||
.creationDate(LocalDate.of(2000, 4, 30))
|
||||
.build();
|
||||
|
||||
Editor codeMasters = Editor.builder()
|
||||
.name("Codemasters")
|
||||
.creationDate(LocalDate.of(1986, 1, 2))
|
||||
.build();
|
||||
|
||||
Editor blizzard = Editor.builder()
|
||||
.name("Blizzard")
|
||||
.creationDate(LocalDate.of(1991, 2, 8))
|
||||
.build();
|
||||
|
||||
editorRepository.saveAll(List.of(
|
||||
psyconix,
|
||||
codeMasters,
|
||||
blizzard
|
||||
));
|
||||
|
||||
Game rocketLeague = Game.builder()
|
||||
.title("Rocket league")
|
||||
.description("Rocket League est un mélange de jeu de voiture et de jeu de football.")
|
||||
.publicationDate(LocalDate.of(2015, 7, 7))
|
||||
.price(0D)
|
||||
.editor(psyconix)
|
||||
.build();
|
||||
|
||||
Game f1_2019 = Game.builder()
|
||||
.title("F1 2019")
|
||||
.description("Jeu de simulation de courses de F1 pour la saison 2019.")
|
||||
.publicationDate(LocalDate.of(2019, 6, 28))
|
||||
.price(6.99)
|
||||
.editor(codeMasters)
|
||||
.build();
|
||||
|
||||
Game f1_2020 = Game.builder()
|
||||
.title("F1 2020")
|
||||
.description("Jeu de simulation de courses de F1 pour la saison 2020.")
|
||||
.publicationDate(LocalDate.of(2019, 7, 10))
|
||||
.price(6.99)
|
||||
.editor(codeMasters)
|
||||
.build();
|
||||
|
||||
List<Dlc> warcraft3DlcList = List.of(Dlc.builder()
|
||||
.title("Warcraft III: The Frozen Throne.")
|
||||
.publicationDate(LocalDate.of(2003, 7, 1))
|
||||
.price(14.99)
|
||||
.build());
|
||||
Game warcraft3 = Game.builder()
|
||||
.title("Warcraft III")
|
||||
.description("Jeu de stratégie en temps réel dans l'univers de Warcraft.")
|
||||
.publicationDate(LocalDate.of(2002, 7, 3))
|
||||
.price(49.99)
|
||||
.editor(blizzard)
|
||||
.dlcList(warcraft3DlcList)
|
||||
.build();
|
||||
warcraft3DlcList.forEach(dlc -> dlc.setGame(warcraft3));
|
||||
|
||||
List<Dlc> wowDlcList = List.of(
|
||||
Dlc.builder()
|
||||
.title("The Burning Crusade")
|
||||
.publicationDate(LocalDate.of(2007, 1, 16))
|
||||
.price(14.99)
|
||||
.build(),
|
||||
Dlc.builder()
|
||||
.title("Wrath of the Lich King")
|
||||
.publicationDate(LocalDate.of(2008, 11, 13))
|
||||
.price(14.99)
|
||||
.build()
|
||||
);
|
||||
Game worldOfWarcraft = Game.builder()
|
||||
.title("World of Warcraft")
|
||||
.description("MMORPG basé sur l'univers de Warcraft")
|
||||
.publicationDate(LocalDate.of(2004, 11, 23))
|
||||
.price(59.99)
|
||||
.editor(blizzard)
|
||||
.dlcList(wowDlcList)
|
||||
.build();
|
||||
wowDlcList.forEach(dlc -> dlc.setGame(worldOfWarcraft));
|
||||
|
||||
gameRepository.saveAll(List.of(
|
||||
rocketLeague,
|
||||
f1_2019,
|
||||
f1_2020,
|
||||
warcraft3,
|
||||
worldOfWarcraft
|
||||
));
|
||||
}
|
||||
|
||||
public void clearData() {
|
||||
// dlcRepository.deleteAll();
|
||||
gameRepository.deleteAll();
|
||||
editorRepository.deleteAll();
|
||||
}
|
||||
}
|
||||
0
src/test/resources/application-test.yml
Normal file
0
src/test/resources/application-test.yml
Normal file
30
src/test/resources/sql/01_init-db.sql
Normal file
30
src/test/resources/sql/01_init-db.sql
Normal file
@@ -0,0 +1,30 @@
|
||||
CREATE TABLE editor (
|
||||
id UUID DEFAULT random_uuid() NOT NULL,
|
||||
name VARCHAR NOT NULL,
|
||||
creation_date DATE NOT NULL,
|
||||
CONSTRAINT pk_editor PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE game (
|
||||
id UUID DEFAULT random_uuid() NOT NULL,
|
||||
title VARCHAR NOT NULL,
|
||||
description VARCHAR NOT NULL,
|
||||
publication_date DATE NOT NULL,
|
||||
price NUMBER NOT NULL DEFAULT 0,
|
||||
editor_id UUID NOT NULL,
|
||||
CONSTRAINT pk_game PRIMARY KEY (id),
|
||||
CONSTRAINT fk_game_editor_id FOREIGN KEY (editor_id) REFERENCES editor (id)
|
||||
);
|
||||
|
||||
CREATE TABLE dlc (
|
||||
id UUID DEFAULT random_uuid() NOT NULL,
|
||||
title VARCHAR NOT NULL,
|
||||
publication_date DATE NOT NULL,
|
||||
price NUMBER NOT NULL DEFAULT 0,
|
||||
game_id UUID NOT NULL,
|
||||
CONSTRAINT pk_dlc PRIMARY KEY (id),
|
||||
CONSTRAINT fk_dlc_game_id FOREIGN KEY (game_id) REFERENCES game (id)
|
||||
);
|
||||
|
||||
INSERT INTO editor (name, creation_date) VALUES
|
||||
('Psyonix', parsedatetime('2000-04-30', 'dd-MM-YYYY'));
|
||||
Reference in New Issue
Block a user