Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Adds MediaItemsController, PatronsController, and PatronsControllerTest #363

Open
wants to merge 7 commits into
base: main
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@
import com.codedifferently.lesson16.library.Librarian;
import com.codedifferently.lesson16.library.Library;
import com.codedifferently.lesson16.library.MediaItem;
import com.codedifferently.lesson16.library.exceptions.MediaItemCheckedOutException;
import com.codedifferently.lesson16.library.search.SearchCriteria;
import jakarta.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
public class MediaItemsController {

private final Library library;
private final Librarian librarian;

Expand All @@ -27,4 +32,39 @@ public GetMediaItemsResponse getItems() {
var response = GetMediaItemsResponse.builder().items(responseItems).build();
return response;
}

@PostMapping("/items")
public CreateMediaItemResponse createItem(@Valid @RequestBody CreateMediaItemRequest request) {
MediaItem item = MediaItemRequest.asMediaItem(request.getItem());
library.addMediaItem(item, librarian);
return CreateMediaItemResponse.builder().item(MediaItemResponse.from(item)).build();
}

@GetMapping("/items/{id}")
public ResponseEntity<MediaItemResponse> getMediaItem(@PathVariable UUID id) {
SearchCriteria criteria = SearchCriteria.builder().id(id.toString()).build();
Set<MediaItem> items = library.search(criteria);
if (!items.isEmpty()) {
MediaItemResponse response = MediaItemResponse.from(items.iterator().next());
return ResponseEntity.ok(response);
} else {
return ResponseEntity.notFound().build();
}
}

@DeleteMapping("/items/{id}")
public ResponseEntity<Void> deleteItem(@PathVariable UUID id) {
SearchCriteria criteria = SearchCriteria.builder().id(id.toString()).build();
Set<MediaItem> items = library.search(criteria);
if (!items.isEmpty()) {
try {
library.removeMediaItem(id, new Librarian("Default", "librarian@example.com"));
cibezim marked this conversation as resolved.
Show resolved Hide resolved
return ResponseEntity.noContent().build();
} catch (MediaItemCheckedOutException e) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
} else {
return ResponseEntity.notFound().build();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.codedifferently.lesson16.web;

import com.codedifferently.lesson16.library.Library;
import com.codedifferently.lesson16.library.LibraryGuest;
import com.codedifferently.lesson16.library.exceptions.MediaItemCheckedOutException;
import jakarta.validation.Valid;
import java.util.Collection;
import java.util.UUID;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/patrons")
public class PatronsController {

private final Library library;

public PatronsController(Library library) {
this.library = library;
}

@GetMapping
public ResponseEntity<Collection<LibraryGuest>> getPatrons() {
Collection<LibraryGuest> patrons = library.getPatrons();
return ResponseEntity.ok(patrons);
}

@PostMapping
public ResponseEntity<?> createPatron(@Valid @RequestBody PatronsRequest request) {
LibraryGuest guest = PatronsRequest.asLibraryGuest(request);
library.addLibraryGuest(guest);
return ResponseEntity.status(HttpStatus.CREATED).build();
}

@GetMapping("/{id}")
public ResponseEntity<Collection<LibraryGuest>> getPatron() {
Collection<LibraryGuest> patron = library.getPatrons();
return ResponseEntity.ok(patron);
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> removePatron(@PathVariable UUID id) {
try {
library.removeLibraryGuest(id);
return ResponseEntity.noContent().build();
} catch (MediaItemCheckedOutException e) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
cibezim marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.codedifferently.lesson16.web;

import com.codedifferently.lesson16.library.LibraryGuest;
import com.codedifferently.lesson16.library.Patron;
import jakarta.validation.constraints.NotBlank;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class PatronsRequest {
private UUID id;

@NotBlank(message = "Name is required")
private String name;

@NotBlank(message = "Email is required")
private String email;

public static LibraryGuest asLibraryGuest(PatronsRequest request) {
UUID id = request.getId();
String name = request.getName();
String email = request.getEmail();

return new Patron(name, email);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.codedifferently.lesson16.web;

import com.codedifferently.lesson16.library.LibraryGuest;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class PatronsResponse {
private UUID id;
private String name;

public static PatronsResponse from(LibraryGuest guest) {
return PatronsResponse.builder().id(guest.getId()).name(guest.getName()).build();
}

public static List<PatronsResponse> from(Collection<LibraryGuest> guests) {
return guests.stream().map(PatronsResponse::from).collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.codedifferently.lesson16.web;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import com.codedifferently.lesson16.library.Library;
import com.codedifferently.lesson16.library.LibraryGuest;
import java.util.Collections;
import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

public class PatronsControllerTest {
cibezim marked this conversation as resolved.
Show resolved Hide resolved

private MockMvc mockMvc;
private Library library;

@BeforeEach
public void setUp() {
library = mock(Library.class);
mockMvc = MockMvcBuilders.standaloneSetup(new PatronsController(library)).build();
}

@Test
public void testGetPatrons() throws Exception {
// Mocking
Set<LibraryGuest> patrons = Collections.emptySet(); // Assuming no patrons for simplicity
when(library.getPatrons()).thenReturn(patrons);

// Execution and Assertion
mockMvc
.perform(get("/patrons"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
}

@Test
public void testCreatePatron() throws Exception {
// Mocking
mockMvc
.perform(
post("/patrons")
.contentType(MediaType.APPLICATION_JSON)
.content(
"{\"id\": \"123e4567-e89b-12d3-a456-426614174000\", \"name\": \"John Doe\", \"email\": \"john@example.com\"}")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isCreated());
}

@Test
public void testRemovePatron() throws Exception {
// Execution and Assertion
mockMvc
.perform(delete("/patrons/{id}", "123e4567-e89b-12d3-a456-426614174000"))
.andExpect(status().isNoContent());
}

@Test
void testGetPatronById() throws Exception {
mockMvc
.perform(
get("/patrons/{id}", "31616162-3831-3832-2d34-3334352d3465")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
}