Skip to content

Commit

Permalink
미션 목록 조회 구현 (issue #197) (#199)
Browse files Browse the repository at this point in the history
* feat: 미션 설명 주소 생성 구현

* feat: 미션 목록 응답 생성 구현

* feat: 미션 목록 조회 api 구현

* chore: 미션 데이터 추가
  • Loading branch information
Minjoo522 authored Aug 6, 2024
1 parent 9ba330c commit 0118a41
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 0 deletions.
26 changes: 26 additions & 0 deletions backend/src/main/java/develup/api/MissionApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package develup.api;

import java.util.List;
import develup.api.common.ApiResponse;
import develup.application.mission.MissionResponse;
import develup.application.mission.MissionService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MissionApi {

private final MissionService missionService;

public MissionApi(MissionService missionService) {
this.missionService = missionService;
}

@GetMapping("/missions")
public ResponseEntity<ApiResponse<List<MissionResponse>>> getMissions() {
List<MissionResponse> missions = missionService.getMissions();

return ResponseEntity.ok(new ApiResponse<>(missions));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package develup.application.mission;

import develup.domain.mission.Mission;

public record MissionResponse(
Long id,
String title,
String descriptionUrl,
String thumbnail,
String url
) {

public static MissionResponse from(Mission mission) {
return new MissionResponse(
mission.getId(),
mission.getTitle(),
mission.getDescriptionUrl(),
mission.getThumbnail(),
mission.getUrl()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package develup.application.mission;

import java.util.List;
import develup.domain.mission.MissionRepository;
import org.springframework.stereotype.Service;

@Service
public class MissionService {

private final MissionRepository missionRepository;

public MissionService(MissionRepository missionRepository) {
this.missionRepository = missionRepository;
}

public List<MissionResponse> getMissions() {
return missionRepository.findAll().stream()
.map(MissionResponse::from)
.toList();
}
}
9 changes: 9 additions & 0 deletions backend/src/main/java/develup/domain/mission/Mission.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
@Entity
public class Mission {

private static final String DESCRIPTION_BASE_URL_PREFIX = "https://raw.githubusercontent.com/develup-mission/";
private static final String DESCRIPTION_BASE_URL_SUFFIX = "/main/README.md";

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand Down Expand Up @@ -51,4 +54,10 @@ public String getThumbnail() {
public String getUrl() {
return url;
}

public String getDescriptionUrl() {
String[] split = url.split("/");

return DESCRIPTION_BASE_URL_PREFIX + split[split.length - 1] + DESCRIPTION_BASE_URL_SUFFIX;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package develup.domain.mission;

import org.springframework.data.jpa.repository.JpaRepository;

public interface MissionRepository extends JpaRepository<Mission, Long> {
}
4 changes: 4 additions & 0 deletions backend/src/main/resources/data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ VALUES ('[email protected]', 'GITHUB', '1234', '리브', 'www.naver.com');

INSERT INTO member (email, provider, social_id, name, image_url)
VALUES ('[email protected]', 'GITHUB', '1234', '아톰', 'www.naver.com');

INSERT INTO mission (title, thumbnail, url)
VALUES ('java-guessing-number', 'https://raw.githubusercontent.com/develup-mission/docs/main/image/java-smoking.png',
'https://github.com/develup-mission/java-guessing-number')
48 changes: 48 additions & 0 deletions backend/src/test/java/develup/api/MissionApiTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package develup.api;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.util.List;
import develup.application.mission.MissionResponse;
import develup.application.mission.MissionService;
import develup.support.IntegrationTestSupport;
import develup.support.data.MissionTestData;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.BDDMockito;
import org.springframework.boot.test.mock.mockito.MockBean;

class MissionApiTest extends IntegrationTestSupport {

@MockBean
private MissionService missionService;

@Test
@DisplayName("미션 목록을 조회한다.")
void getMissions() throws Exception {
List<MissionResponse> responses = List.of(
MissionResponse.from(MissionTestData.defaultMission().build()),
MissionResponse.from(MissionTestData.defaultMission().build())
);
BDDMockito.given(missionService.getMissions())
.willReturn(responses);

mockMvc.perform(get("/missions"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.data[0].title", equalTo("루터회관 흡연단속")))
.andExpect(jsonPath("$.data[0].thumbnail", equalTo("https://thumbnail.com/1.png")))
.andExpect(jsonPath("$.data[0].url", equalTo("https://github.com/develup/mission")))
.andExpect(jsonPath("$.data[0].descriptionUrl", equalTo("https://raw.githubusercontent.com/develup-mission/mission/main/README.md")))
.andExpect(jsonPath("$.data[1].title", equalTo("루터회관 흡연단속")))
.andExpect(jsonPath("$.data[1].thumbnail", equalTo("https://thumbnail.com/1.png")))
.andExpect(jsonPath("$.data[1].url", equalTo("https://github.com/develup/mission")))
.andExpect(jsonPath("$.data[1].descriptionUrl", equalTo("https://raw.githubusercontent.com/develup-mission/mission/main/README.md")))
.andExpect(jsonPath("$.data.length()", is(2)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package develup.application.mission;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import develup.domain.mission.MissionRepository;
import develup.support.IntegrationTestSupport;
import develup.support.data.MissionTestData;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

class MissionServiceTest extends IntegrationTestSupport {

@Autowired
private MissionService missionService;

@Autowired
private MissionRepository missionRepository;

@Test
@DisplayName("미션 목록을 조회한다.")
void getMissions() {
missionRepository.save(MissionTestData.defaultMission().build());
missionRepository.save(MissionTestData.defaultMission().build());

List<MissionResponse> responses = missionService.getMissions();

assertThat(responses.size()).isEqualTo(2);
}
}
24 changes: 24 additions & 0 deletions backend/src/test/java/develup/domain/mission/MissionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package develup.domain.mission;

import static org.assertj.core.api.Assertions.assertThat;

import develup.support.data.MissionTestData;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

class MissionTest {

@Test
@DisplayName("설명 주소를 가져올 수 있다.")
void getDescriptionUrl() {
String repoName = "java-guessing-number";
Mission mission = MissionTestData.defaultMission()
.withUrl("https://github.com/develup-mission/" + repoName)
.build();
String actual = "https://raw.githubusercontent.com/develup-mission/" + repoName + "/main/README.md";

String expected = mission.getDescriptionUrl();

assertThat(expected).isEqualTo(actual);
}
}

0 comments on commit 0118a41

Please sign in to comment.