Add base
This commit is contained in:
6
pom.xml
6
pom.xml
@@ -46,6 +46,12 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.junit.vintage</groupId>
|
||||||
|
<artifactId>junit-vintage-engine</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</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