From a9fd7e52364aa30e22d22a42ac6cc82f9f61fec1 Mon Sep 17 00:00:00 2001 From: Jacob Woodward Date: Thu, 25 May 2023 00:21:02 -0700 Subject: [PATCH 01/11] jw-Update backend to be able to handle buying and selling multiple cows --- .../controllers/UserCommonsController.java | 98 +- .../UserCommonsControllerTests.java | 1433 ++++++++--------- 2 files changed, 759 insertions(+), 772 deletions(-) diff --git a/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java b/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java index 7c5fb5660..ff9d9d8cb 100644 --- a/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java +++ b/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java @@ -49,47 +49,47 @@ public class UserCommonsController extends ApiController { @PreAuthorize("hasRole('ROLE_ADMIN')") @GetMapping("") public UserCommons getUserCommonsById( - @ApiParam("userId") @RequestParam Long userId, - @ApiParam("commonsId") @RequestParam Long commonsId) throws JsonProcessingException { - - UserCommons userCommons = userCommonsRepository.findByCommonsIdAndUserId(commonsId, userId) - .orElseThrow( - () -> new EntityNotFoundException(UserCommons.class, "commonsId", commonsId, "userId", userId)); - return userCommons; - } + @ApiParam("userId") @RequestParam Long userId, + @ApiParam("commonsId") @RequestParam Long commonsId) + throws JsonProcessingException { + UserCommons userCommons = userCommonsRepository.findByCommonsIdAndUserId(commonsId, userId) + .orElseThrow(() -> new EntityNotFoundException(UserCommons.class, "commonsId", commonsId, "userId", userId)); + return userCommons; + } @ApiOperation(value = "Get a user commons for current user") @PreAuthorize("hasRole('ROLE_USER')") @GetMapping("/forcurrentuser") public UserCommons getUserCommonsById( - @ApiParam("commonsId") @RequestParam Long commonsId) throws JsonProcessingException { + @ApiParam("commonsId") @RequestParam Long commonsId) + throws JsonProcessingException { + User u = getCurrentUser().getUser(); + Long userId = u.getId(); - User u = getCurrentUser().getUser(); - Long userId = u.getId(); - UserCommons userCommons = userCommonsRepository.findByCommonsIdAndUserId(commonsId, userId) - .orElseThrow( - () -> new EntityNotFoundException(UserCommons.class, "commonsId", commonsId, "userId", userId)); - return userCommons; - } + UserCommons userCommons = userCommonsRepository.findByCommonsIdAndUserId(commonsId, userId) + .orElseThrow(() -> new EntityNotFoundException(UserCommons.class, "commonsId", commonsId, "userId", userId)); + return userCommons; + } - @ApiOperation(value = "Buy a cow, totalWealth updated") + //BUG: Sometimes there is a glitch where clicking the Buy Max button buys more than the max, idk cause + @ApiOperation(value = "Buy cows, totalWealth updated") @PreAuthorize("hasRole('ROLE_USER')") @PutMapping("/buy") public ResponseEntity putUserCommonsByIdBuy( - @ApiParam("commonsId") @RequestParam Long commonsId) throws NotEnoughMoneyException, JsonProcessingException{ - + @ApiParam("commonsId") @RequestParam Long commonsId, + @ApiParam("numCows") @RequestParam int numCows) // Want to set 1 as the default when nothing is passed in + throws NotEnoughMoneyException, JsonProcessingException{ User u = getCurrentUser().getUser(); Long userId = u.getId(); - Commons commons = commonsRepository.findById(commonsId).orElseThrow( - ()->new EntityNotFoundException(Commons.class, commonsId)); + Commons commons = commonsRepository.findById(commonsId) + .orElseThrow(()->new EntityNotFoundException(Commons.class, commonsId)); UserCommons userCommons = userCommonsRepository.findByCommonsIdAndUserId(commonsId, userId) - .orElseThrow( - () -> new EntityNotFoundException(UserCommons.class, "commonsId", commonsId, "userId", userId)); + .orElseThrow(() -> new EntityNotFoundException(UserCommons.class, "commonsId", commonsId, "userId", userId)); - if(userCommons.getTotalWealth() >= commons.getCowPrice() ){ - userCommons.setTotalWealth(userCommons.getTotalWealth() - commons.getCowPrice()); - userCommons.setNumOfCows(userCommons.getNumOfCows() + 1); + if((numCows > 0) && (userCommons.getTotalWealth() >= (numCows * commons.getCowPrice()))){ + userCommons.setTotalWealth(userCommons.getTotalWealth() - (numCows * commons.getCowPrice())); + userCommons.setNumOfCows(userCommons.getNumOfCows() + numCows); } else{ throw new NotEnoughMoneyException("You need more money!"); @@ -98,26 +98,27 @@ public ResponseEntity putUserCommonsByIdBuy( String body = mapper.writeValueAsString(userCommons); return ResponseEntity.ok().body(body); - } + } - @ApiOperation(value = "Sell a cow, totalWealth updated") + @ApiOperation(value = "Sell cows, totalWealth updated") @PreAuthorize("hasRole('ROLE_USER')") @PutMapping("/sell") public ResponseEntity putUserCommonsByIdSell( - @ApiParam("commonsId") @RequestParam Long commonsId) throws NoCowsException, JsonProcessingException { + @ApiParam("commonsId") @RequestParam Long commonsId, + @ApiParam("numCows") @RequestParam int numCows) // Want to set 1 as the default when nothing is passed in + throws NoCowsException, JsonProcessingException { User u = getCurrentUser().getUser(); Long userId = u.getId(); - Commons commons = commonsRepository.findById(commonsId).orElseThrow( - ()->new EntityNotFoundException(Commons.class, commonsId)); + Commons commons = commonsRepository.findById(commonsId) + .orElseThrow(()->new EntityNotFoundException(Commons.class, commonsId)); UserCommons userCommons = userCommonsRepository.findByCommonsIdAndUserId(commonsId, userId) - .orElseThrow( - () -> new EntityNotFoundException(UserCommons.class, "commonsId", commonsId, "userId", userId)); - + .orElseThrow(() -> new EntityNotFoundException(UserCommons.class, "commonsId", commonsId, "userId", userId)); - if(userCommons.getNumOfCows() >= 1 ){ - userCommons.setTotalWealth(userCommons.getTotalWealth() + commons.getCowPrice()); - userCommons.setNumOfCows(userCommons.getNumOfCows() - 1); + if(userCommons.getNumOfCows() >= 1){ + if (numCows > userCommons.getNumOfCows()) numCows = userCommons.getNumOfCows(); + userCommons.setTotalWealth(userCommons.getTotalWealth() + (numCows * commons.getCowPrice())); + userCommons.setNumOfCows(userCommons.getNumOfCows() - numCows); } else{ throw new NoCowsException("You have no cows to sell!"); @@ -126,17 +127,16 @@ public ResponseEntity putUserCommonsByIdSell( String body = mapper.writeValueAsString(userCommons); return ResponseEntity.ok().body(body); - } - - @ApiOperation(value = "Get all user commons for a specific commons") - @GetMapping("/commons/all") - public ResponseEntity getUsersCommonsByCommonsId( - @ApiParam("commonsId") @RequestParam Long commonsId) throws JsonProcessingException { - Iterable uc = userCommonsRepository.findByCommonsId(commonsId); - - - String body = mapper.writeValueAsString(uc); - return ResponseEntity.ok().body(body); - } + } + @ApiOperation(value = "Get all user commons for a specific commons") + @GetMapping("/commons/all") + public ResponseEntity getUsersCommonsByCommonsId( + @ApiParam("commonsId") @RequestParam Long commonsId) + throws JsonProcessingException { + Iterable uc = userCommonsRepository.findByCommonsId(commonsId); + + String body = mapper.writeValueAsString(uc); + return ResponseEntity.ok().body(body); + } } \ No newline at end of file diff --git a/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java b/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java index fd6cb2df8..df32c441d 100644 --- a/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java +++ b/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java @@ -45,703 +45,690 @@ @AutoConfigureDataJpa public class UserCommonsControllerTests extends ControllerTestCase { - @MockBean - UserCommonsRepository userCommonsRepository; - - @MockBean - UserRepository userRepository; - - @MockBean - CommonsRepository commonsRepository; - - @Autowired - private ObjectMapper objectMapper; - - public static UserCommons dummyUserCommons(long id) { - UserCommons userCommons = new UserCommons(id,1,1,"test",1,1, 100); - return userCommons; - } - @WithMockUser(roles = { "ADMIN" }) - @Test - public void test_getUserCommonsById_exists_admin() throws Exception { - - UserCommons expectedUserCommons = dummyUserCommons(1); - when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L),eq(1L))).thenReturn(Optional.of(expectedUserCommons)); - - MvcResult response = mockMvc.perform(get("/api/usercommons/?userId=1&commonsId=1")) - .andExpect(status().isOk()).andReturn(); - - verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L),eq(1L)); - - String expectedJson = mapper.writeValueAsString(expectedUserCommons); - String responseString = response.getResponse().getContentAsString(); - - assertEquals(expectedJson, responseString); - } - - @WithMockUser(roles = { "ADMIN" }) - @Test - public void test_getUserCommonsById_nonexists_admin() throws Exception { - - when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L),eq(1L))).thenReturn(Optional.empty()); - - MvcResult response = mockMvc.perform(get("/api/usercommons/?userId=1&commonsId=1")) - .andExpect(status().is(404)).andReturn(); - - verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L),eq(1L)); - - String responseString = response.getResponse().getContentAsString(); - String expectedString = "{\"message\":\"UserCommons with commonsId 1 and userId 1 not found\",\"type\":\"EntityNotFoundException\"}"; - - Map expectedJson = mapper.readValue(expectedString, Map.class); - Map jsonResponse = responseToJson(response); - assertEquals(expectedJson, jsonResponse); - } - - @WithMockUser(roles = { "USER" }) - @Test - public void test_getUserCommonsById_exists() throws Exception { - - UserCommons expectedUserCommons = dummyUserCommons(1); - when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L),eq(1L))).thenReturn(Optional.of(expectedUserCommons)); - - MvcResult response = mockMvc.perform(get("/api/usercommons/forcurrentuser?commonsId=1")) - .andExpect(status().isOk()).andReturn(); - - verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L),eq(1L)); - - String expectedJson = mapper.writeValueAsString(expectedUserCommons); - String responseString = response.getResponse().getContentAsString(); - - assertEquals(expectedJson, responseString); - } - - @WithMockUser(roles = { "USER" }) - @Test - public void test_getUserCommonsById_nonexists() throws Exception { - - when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L),eq(1L))).thenReturn(Optional.empty()); - - MvcResult response = mockMvc.perform(get("/api/usercommons/forcurrentuser?commonsId=1")) - .andExpect(status().is(404)).andReturn(); - - verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L),eq(1L)); - - String responseString = response.getResponse().getContentAsString(); - String expectedString = "{\"message\":\"UserCommons with commonsId 1 and userId 1 not found\",\"type\":\"EntityNotFoundException\"}"; - Map expectedJson = mapper.readValue(expectedString, Map.class); - Map jsonResponse = responseToJson(response); - assertEquals(expectedJson, jsonResponse); - } - - @WithMockUser(roles = { "USER" }) - @Test - public void test_BuyCow_commons_exists() throws Exception { - - // arrange - - UserCommons origUserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - Commons testCommons = Commons - .builder() - .name("test commons") - .cowPrice(10) - .milkPrice(2) - .startingBalance(300) - .startingDate(LocalDateTime.now()) - .build(); - - UserCommons userCommonsToSend = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - UserCommons correctuserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300-testCommons.getCowPrice()) - .numOfCows(2) - .cowHealth(100) - .build(); - - String requestBody = mapper.writeValueAsString(userCommonsToSend); - String expectedReturn = mapper.writeValueAsString(correctuserCommons); - - when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); - when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); - - // act - MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=1") - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8") - .content(requestBody) - .with(csrf())) - .andExpect(status().isOk()).andReturn(); - - // assert - verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L), eq(1L)); - verify(userCommonsRepository, times(1)).save(correctuserCommons); - String responseString = response.getResponse().getContentAsString(); - assertEquals(expectedReturn, responseString); - } - - @WithMockUser(roles = { "USER" }) - @Test - public void test_BuyCow_commons_exists_user_has_exact_amount_needed() throws Exception { - - // arrange - - UserCommons origUserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - Commons testCommons = Commons - .builder() - .name("test commons") - .cowPrice(300) - .milkPrice(2) - .startingBalance(300) - .startingDate(LocalDateTime.now()) - .build(); - - UserCommons userCommonsToSend = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - UserCommons correctuserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(0) - .numOfCows(2) - .cowHealth(100) - .build(); - - String requestBody = mapper.writeValueAsString(userCommonsToSend); - String expectedReturn = mapper.writeValueAsString(correctuserCommons); - - when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); - when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); - - // act - MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=1") - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8") - .content(requestBody) - .with(csrf())) - .andExpect(status().isOk()).andReturn(); - - // assert - verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L), eq(1L)); - verify(userCommonsRepository, times(1)).save(correctuserCommons); - String responseString = response.getResponse().getContentAsString(); - assertEquals(expectedReturn, responseString); - } - - @WithMockUser(roles = { "USER" }) - @Test - public void test_SellCow_commons_exists() throws Exception { - - // arrange - - UserCommons origUserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - Commons testCommons = Commons - .builder() - .name("test commons") - .cowPrice(10) - .milkPrice(2) - .startingBalance(300) - .startingDate(LocalDateTime.now()) - .build(); - - UserCommons userCommonsToSend = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - UserCommons correctuserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300+testCommons.getCowPrice()) - .numOfCows(0) - .cowHealth(100) - .build(); - - String requestBody = mapper.writeValueAsString(userCommonsToSend); - String expectedReturn = mapper.writeValueAsString(correctuserCommons); - - when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); - when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); - - // act - MvcResult response = mockMvc.perform(put("/api/usercommons/sell?commonsId=1") - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8") - .content(requestBody) - .with(csrf())) - .andExpect(status().isOk()).andReturn(); - - // assert - verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L), eq(1L)); - verify(userCommonsRepository, times(1)).save(correctuserCommons); - String responseString = response.getResponse().getContentAsString(); - assertEquals(expectedReturn, responseString); - } - - @WithMockUser(roles = { "USER" }) - @Test - public void test_BuyCow_commons_for_user_DOES_NOT_exist() throws Exception { - - // arrange - - UserCommons origUserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - Commons testCommons = Commons - .builder() - .name("test commons") - .cowPrice(10) - .milkPrice(2) - .startingBalance(300) - .startingDate(LocalDateTime.now()) - .build(); - - UserCommons userCommonsToSend = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - UserCommons correctuserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300-testCommons.getCowPrice()) - .numOfCows(2) - .cowHealth(100) - .build(); - - String requestBody = mapper.writeValueAsString(userCommonsToSend); - String expectedReturn = mapper.writeValueAsString(correctuserCommons); - - when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); - when(commonsRepository.findById(eq(234L))).thenReturn(Optional.of(testCommons)); - - // act - MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=234") - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8") - .content(requestBody) - .with(csrf())) - .andExpect(status().is(404)).andReturn(); - - // assert - - String responseString = response.getResponse().getContentAsString(); - String expectedString = "{\"message\":\"UserCommons with commonsId 234 and userId 1 not found\",\"type\":\"EntityNotFoundException\"}"; - Map expectedJson = mapper.readValue(expectedString, Map.class); - Map jsonResponse = responseToJson(response); - assertEquals(expectedJson, jsonResponse); - } - - @WithMockUser(roles = { "USER" }) - @Test - public void test_SellCow_commons_for_usercommons_DOES_NOT_exist() throws Exception { - - // arrange - - UserCommons origUserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - Commons testCommons = Commons - .builder() - .id(234L) - .name("test commons") - .cowPrice(10) - .milkPrice(2) - .startingBalance(300) - .startingDate(LocalDateTime.now()) - .build(); - - UserCommons userCommonsToSend = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - UserCommons correctuserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300+testCommons.getCowPrice()) - .numOfCows(2) - .cowHealth(100) - .build(); - - String requestBody = mapper.writeValueAsString(userCommonsToSend); - String expectedReturn = mapper.writeValueAsString(correctuserCommons); - - when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); - when(commonsRepository.findById(eq(234L))).thenReturn(Optional.of(testCommons)); - - // act - MvcResult response = mockMvc.perform(put("/api/usercommons/sell?commonsId=234") - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8") - .content(requestBody) - .with(csrf())) - .andExpect(status().is(404)).andReturn(); - - // assert - String responseString = response.getResponse().getContentAsString(); - String expectedString = "{\"message\":\"UserCommons with commonsId 234 and userId 1 not found\",\"type\":\"EntityNotFoundException\"}"; - Map expectedJson = mapper.readValue(expectedString, Map.class); - Map jsonResponse = responseToJson(response); - assertEquals(expectedJson, jsonResponse); - } - - //tests for when the common itself doesn't exist - - @WithMockUser(roles = { "USER" }) - @Test - public void test_SellCow_commons_DOES_NOT_exist() throws Exception { - - // arrange - - UserCommons origUserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - Commons testCommons = Commons - .builder() - .name("test commons") - .cowPrice(10) - .milkPrice(2) - .startingBalance(300) - .startingDate(LocalDateTime.now()) - .build(); - - UserCommons userCommonsToSend = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - UserCommons correctuserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300+testCommons.getCowPrice()) - .numOfCows(2) - .cowHealth(100) - .build(); - - String requestBody = mapper.writeValueAsString(userCommonsToSend); - String expectedReturn = mapper.writeValueAsString(correctuserCommons); - - when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); - when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); - - // act - MvcResult response = mockMvc.perform(put("/api/usercommons/sell?commonsId=222") - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8") - .content(requestBody) - .with(csrf())) - .andExpect(status().is(404)).andReturn(); - - // assert - String responseString = response.getResponse().getContentAsString(); - String expectedString = "{\"message\":\"Commons with id 222 not found\",\"type\":\"EntityNotFoundException\"}"; - Map expectedJson = mapper.readValue(expectedString, Map.class); - Map jsonResponse = responseToJson(response); - assertEquals(expectedJson, jsonResponse); - } - - @WithMockUser(roles = { "USER" }) - @Test - public void test_BuyCow_commons_DOES_NOT_exist() throws Exception { - - // arrange - - UserCommons origUserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - Commons testCommons = Commons - .builder() - .name("test commons") - .cowPrice(10) - .milkPrice(2) - .startingBalance(300) - .startingDate(LocalDateTime.now()) - .build(); - - UserCommons userCommonsToSend = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(1) - .cowHealth(100) - .build(); - - UserCommons correctuserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300+testCommons.getCowPrice()) - .numOfCows(2) - .cowHealth(100) - .build(); - - String requestBody = mapper.writeValueAsString(userCommonsToSend); - String expectedReturn = mapper.writeValueAsString(correctuserCommons); - - when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); - when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); - - // act - MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=222") - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8") - .content(requestBody) - .with(csrf())) - .andExpect(status().is(404)).andReturn(); - - // assert - String responseString = response.getResponse().getContentAsString(); - String expectedString = "{\"message\":\"Commons with id 222 not found\",\"type\":\"EntityNotFoundException\"}"; - Map expectedJson = mapper.readValue(expectedString, Map.class); - Map jsonResponse = responseToJson(response); - assertEquals(expectedJson, jsonResponse); - } - - - - // Put tests for edge cases (not enough money to buy, or no cow to sell) - - - @WithMockUser(roles = { "USER" }) - @Test - public void test_BuyCow_commons_exists_not_enough_money() throws Exception { - - // arrange - - UserCommons origUserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(0) - .numOfCows(1) - .cowHealth(100) - .build(); - - Commons testCommons = Commons - .builder() - .name("test commons") - .cowPrice(10) - .milkPrice(2) - .startingBalance(0) - .startingDate(LocalDateTime.now()) - .build(); - - UserCommons userCommonsToSend = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(0) - .numOfCows(1) - .cowHealth(100) - .build(); - - UserCommons correctuserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(0) - .numOfCows(1) - .cowHealth(100) - .build(); - - String requestBody = mapper.writeValueAsString(userCommonsToSend); - String expectedReturn = mapper.writeValueAsString(correctuserCommons); - - when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); - when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); - - // act - MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=1") - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8") - .content(requestBody) - .with(csrf())) - .andExpect(status().is(400)).andReturn(); - - // assert - String responseString = response.getResponse().getContentAsString(); - String expectedString = "{\"message\":\"You need more money!\",\"type\":\"NotEnoughMoneyException\"}"; - Map expectedJson = mapper.readValue(expectedString, Map.class); - Map jsonResponse = responseToJson(response); - assertEquals(expectedJson, jsonResponse); - } - - @WithMockUser(roles = { "USER" }) - @Test - public void test_SellCow_commons_exists_no_cow_to_sell() throws Exception { - - // arrange - - UserCommons origUserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(0) - .cowHealth(100) - .build(); - - Commons testCommons = Commons - .builder() - .name("test commons") - .cowPrice(10) - .milkPrice(2) - .startingBalance(300) - .startingDate(LocalDateTime.now()) - .build(); - - UserCommons userCommonsToSend = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(0) - .cowHealth(100) - .build(); - - UserCommons correctuserCommons = UserCommons - .builder() - .id(1L) - .userId(1L) - .commonsId(1L) - .totalWealth(300) - .numOfCows(0) - .cowHealth(100) - .build(); - - String requestBody = mapper.writeValueAsString(userCommonsToSend); - String expectedReturn = mapper.writeValueAsString(correctuserCommons); - - when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); - when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); - - // act - MvcResult response = mockMvc.perform(put("/api/usercommons/sell?commonsId=1") - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8") - .content(requestBody) - .with(csrf())).andExpect(status().is(400)).andReturn(); - - - // assert - String responseString = response.getResponse().getContentAsString(); - String expectedString = "{\"message\":\"You have no cows to sell!\",\"type\":\"NoCowsException\"}"; - Map expectedJson = mapper.readValue(expectedString, Map.class); - Map jsonResponse = responseToJson(response); - assertEquals(expectedJson, jsonResponse); + @MockBean + UserCommonsRepository userCommonsRepository; + + @MockBean + UserRepository userRepository; + + @MockBean + CommonsRepository commonsRepository; + + @Autowired + private ObjectMapper objectMapper; + + public static UserCommons dummyUserCommons(long id) { + UserCommons userCommons = new UserCommons(id,1,1,"test",1,1, 100); + return userCommons; + } + + @WithMockUser(roles = { "ADMIN" }) + @Test + public void test_getUserCommonsById_exists_admin() throws Exception { + + UserCommons expectedUserCommons = dummyUserCommons(1); + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L),eq(1L))).thenReturn(Optional.of(expectedUserCommons)); + + MvcResult response = mockMvc.perform(get("/api/usercommons/?userId=1&commonsId=1")) + .andExpect(status().isOk()).andReturn(); + + verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L),eq(1L)); + + String expectedJson = mapper.writeValueAsString(expectedUserCommons); + String responseString = response.getResponse().getContentAsString(); + + assertEquals(expectedJson, responseString); + } + + @WithMockUser(roles = { "ADMIN" }) + @Test + public void test_getUserCommonsById_nonexists_admin() throws Exception { + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L),eq(1L))).thenReturn(Optional.empty()); + + MvcResult response = mockMvc.perform(get("/api/usercommons/?userId=1&commonsId=1")) + .andExpect(status().is(404)).andReturn(); + + verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L),eq(1L)); + + String responseString = response.getResponse().getContentAsString(); + String expectedString = "{\"message\":\"UserCommons with commonsId 1 and userId 1 not found\",\"type\":\"EntityNotFoundException\"}"; + + Map expectedJson = mapper.readValue(expectedString, Map.class); + Map jsonResponse = responseToJson(response); + assertEquals(expectedJson, jsonResponse); + } + + @WithMockUser(roles = { "USER" }) + @Test + public void test_getUserCommonsById_exists() throws Exception { + + UserCommons expectedUserCommons = dummyUserCommons(1); + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L),eq(1L))).thenReturn(Optional.of(expectedUserCommons)); + + MvcResult response = mockMvc.perform(get("/api/usercommons/forcurrentuser?commonsId=1")) + .andExpect(status().isOk()).andReturn(); + + verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L),eq(1L)); + + String expectedJson = mapper.writeValueAsString(expectedUserCommons); + String responseString = response.getResponse().getContentAsString(); + + assertEquals(expectedJson, responseString); + } + + @WithMockUser(roles = { "USER" }) + @Test + public void test_getUserCommonsById_nonexists() throws Exception { + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L),eq(1L))).thenReturn(Optional.empty()); + + MvcResult response = mockMvc.perform(get("/api/usercommons/forcurrentuser?commonsId=1")) + .andExpect(status().is(404)).andReturn(); + + verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L),eq(1L)); + + String responseString = response.getResponse().getContentAsString(); + String expectedString = "{\"message\":\"UserCommons with commonsId 1 and userId 1 not found\",\"type\":\"EntityNotFoundException\"}"; + Map expectedJson = mapper.readValue(expectedString, Map.class); + Map jsonResponse = responseToJson(response); + assertEquals(expectedJson, jsonResponse); + } + + @WithMockUser(roles = { "USER" }) + @Test + public void test_BuyCow_commons_exists() throws Exception { + + // arrange + UserCommons origUserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + Commons testCommons = Commons + .builder() + .name("test commons") + .cowPrice(10) + .milkPrice(2) + .startingBalance(300) + .startingDate(LocalDateTime.now()) + .build(); + + UserCommons userCommonsToSend = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + UserCommons correctuserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300-testCommons.getCowPrice()) + .numOfCows(2) + .cowHealth(100) + .build(); + + String requestBody = mapper.writeValueAsString(userCommonsToSend); + String expectedReturn = mapper.writeValueAsString(correctuserCommons); + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); + when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); + + // act + MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=1&numCows=1") + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding("utf-8") + .content(requestBody) + .with(csrf())) + .andExpect(status().isOk()).andReturn(); + + // assert + verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L), eq(1L)); + verify(userCommonsRepository, times(1)).save(correctuserCommons); + String responseString = response.getResponse().getContentAsString(); + assertEquals(expectedReturn, responseString); + } + + @WithMockUser(roles = { "USER" }) + @Test + public void test_BuyCow_commons_exists_user_has_exact_amount_needed() throws Exception { + + // arrange + UserCommons origUserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + Commons testCommons = Commons + .builder() + .name("test commons") + .cowPrice(300) + .milkPrice(2) + .startingBalance(300) + .startingDate(LocalDateTime.now()) + .build(); + + UserCommons userCommonsToSend = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + UserCommons correctuserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(0) + .numOfCows(2) + .cowHealth(100) + .build(); + + String requestBody = mapper.writeValueAsString(userCommonsToSend); + String expectedReturn = mapper.writeValueAsString(correctuserCommons); + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); + when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); + + // act + MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=1&numCows=1") + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding("utf-8") + .content(requestBody) + .with(csrf())) + .andExpect(status().isOk()).andReturn(); + + // assert + verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L), eq(1L)); + verify(userCommonsRepository, times(1)).save(correctuserCommons); + String responseString = response.getResponse().getContentAsString(); + assertEquals(expectedReturn, responseString); + } + + @WithMockUser(roles = { "USER" }) + @Test + public void test_SellCow_commons_exists() throws Exception { + + // arrange + UserCommons origUserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + Commons testCommons = Commons + .builder() + .name("test commons") + .cowPrice(10) + .milkPrice(2) + .startingBalance(300) + .startingDate(LocalDateTime.now()) + .build(); + + UserCommons userCommonsToSend = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + UserCommons correctuserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300+testCommons.getCowPrice()) + .numOfCows(0) + .cowHealth(100) + .build(); + + String requestBody = mapper.writeValueAsString(userCommonsToSend); + String expectedReturn = mapper.writeValueAsString(correctuserCommons); + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); + when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); + + // act + MvcResult response = mockMvc.perform(put("/api/usercommons/sell?commonsId=1&numCows=1") + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding("utf-8") + .content(requestBody) + .with(csrf())) + .andExpect(status().isOk()).andReturn(); + + // assert + verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L), eq(1L)); + verify(userCommonsRepository, times(1)).save(correctuserCommons); + String responseString = response.getResponse().getContentAsString(); + assertEquals(expectedReturn, responseString); + } + @WithMockUser(roles = { "USER" }) + @Test + public void test_BuyCow_commons_for_user_DOES_NOT_exist() throws Exception { + + // arrange + UserCommons origUserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + Commons testCommons = Commons + .builder() + .name("test commons") + .cowPrice(10) + .milkPrice(2) + .startingBalance(300) + .startingDate(LocalDateTime.now()) + .build(); + + UserCommons userCommonsToSend = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + UserCommons correctuserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300-testCommons.getCowPrice()) + .numOfCows(2) + .cowHealth(100) + .build(); + + String requestBody = mapper.writeValueAsString(userCommonsToSend); + String expectedReturn = mapper.writeValueAsString(correctuserCommons); + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); + when(commonsRepository.findById(eq(234L))).thenReturn(Optional.of(testCommons)); + + // act + MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=234&numCows=1") + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding("utf-8") + .content(requestBody) + .with(csrf())) + .andExpect(status().is(404)).andReturn(); + + // assert + String responseString = response.getResponse().getContentAsString(); + String expectedString = "{\"message\":\"UserCommons with commonsId 234 and userId 1 not found\",\"type\":\"EntityNotFoundException\"}"; + Map expectedJson = mapper.readValue(expectedString, Map.class); + Map jsonResponse = responseToJson(response); + assertEquals(expectedJson, jsonResponse); + } + + @WithMockUser(roles = { "USER" }) + @Test + public void test_SellCow_commons_for_usercommons_DOES_NOT_exist() throws Exception { + + // arrange + UserCommons origUserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + Commons testCommons = Commons + .builder() + .id(234L) + .name("test commons") + .cowPrice(10) + .milkPrice(2) + .startingBalance(300) + .startingDate(LocalDateTime.now()) + .build(); + + UserCommons userCommonsToSend = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + UserCommons correctuserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300+testCommons.getCowPrice()) + .numOfCows(2) + .cowHealth(100) + .build(); + + String requestBody = mapper.writeValueAsString(userCommonsToSend); + String expectedReturn = mapper.writeValueAsString(correctuserCommons); + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); + when(commonsRepository.findById(eq(234L))).thenReturn(Optional.of(testCommons)); + + // act + MvcResult response = mockMvc.perform(put("/api/usercommons/sell?commonsId=234&numCows=1") + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding("utf-8") + .content(requestBody) + .with(csrf())) + .andExpect(status().is(404)).andReturn(); + + // assert + String responseString = response.getResponse().getContentAsString(); + String expectedString = "{\"message\":\"UserCommons with commonsId 234 and userId 1 not found\",\"type\":\"EntityNotFoundException\"}"; + Map expectedJson = mapper.readValue(expectedString, Map.class); + Map jsonResponse = responseToJson(response); + assertEquals(expectedJson, jsonResponse); + } + + //tests for when the common itself doesn't exist + + @WithMockUser(roles = { "USER" }) + @Test + public void test_SellCow_commons_DOES_NOT_exist() throws Exception { + + // arrange + UserCommons origUserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + Commons testCommons = Commons + .builder() + .name("test commons") + .cowPrice(10) + .milkPrice(2) + .startingBalance(300) + .startingDate(LocalDateTime.now()) + .build(); + + UserCommons userCommonsToSend = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + UserCommons correctuserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300+testCommons.getCowPrice()) + .numOfCows(2) + .cowHealth(100) + .build(); + + String requestBody = mapper.writeValueAsString(userCommonsToSend); + String expectedReturn = mapper.writeValueAsString(correctuserCommons); + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); + when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); + + // act + MvcResult response = mockMvc.perform(put("/api/usercommons/sell?commonsId=222&numCows=1") + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding("utf-8") + .content(requestBody) + .with(csrf())) + .andExpect(status().is(404)).andReturn(); + + // assert + String responseString = response.getResponse().getContentAsString(); + String expectedString = "{\"message\":\"Commons with id 222 not found\",\"type\":\"EntityNotFoundException\"}"; + Map expectedJson = mapper.readValue(expectedString, Map.class); + Map jsonResponse = responseToJson(response); + assertEquals(expectedJson, jsonResponse); + } + + @WithMockUser(roles = { "USER" }) + @Test + public void test_BuyCow_commons_DOES_NOT_exist() throws Exception { + + // arrange + UserCommons origUserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + Commons testCommons = Commons + .builder() + .name("test commons") + .cowPrice(10) + .milkPrice(2) + .startingBalance(300) + .startingDate(LocalDateTime.now()) + .build(); + + UserCommons userCommonsToSend = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(100) + .build(); + + UserCommons correctuserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300+testCommons.getCowPrice()) + .numOfCows(2) + .cowHealth(100) + .build(); + + String requestBody = mapper.writeValueAsString(userCommonsToSend); + String expectedReturn = mapper.writeValueAsString(correctuserCommons); + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); + when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); + + // act + MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=222&numCows=1") + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding("utf-8") + .content(requestBody) + .with(csrf())) + .andExpect(status().is(404)).andReturn(); + + // assert + String responseString = response.getResponse().getContentAsString(); + String expectedString = "{\"message\":\"Commons with id 222 not found\",\"type\":\"EntityNotFoundException\"}"; + Map expectedJson = mapper.readValue(expectedString, Map.class); + Map jsonResponse = responseToJson(response); + assertEquals(expectedJson, jsonResponse); + } + + + // Put tests for edge cases (not enough money to buy, or no cow to sell) + @WithMockUser(roles = { "USER" }) + @Test + public void test_BuyCow_commons_exists_not_enough_money() throws Exception { + + // arrange + UserCommons origUserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(0) + .numOfCows(1) + .cowHealth(100) + .build(); + + Commons testCommons = Commons + .builder() + .name("test commons") + .cowPrice(10) + .milkPrice(2) + .startingBalance(0) + .startingDate(LocalDateTime.now()) + .build(); + + UserCommons userCommonsToSend = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(0) + .numOfCows(1) + .cowHealth(100) + .build(); + + UserCommons correctuserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(0) + .numOfCows(1) + .cowHealth(100) + .build(); + + String requestBody = mapper.writeValueAsString(userCommonsToSend); + String expectedReturn = mapper.writeValueAsString(correctuserCommons); + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); + when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); + + // act + MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=1&numCows=1") + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding("utf-8") + .content(requestBody) + .with(csrf())) + .andExpect(status().is(400)).andReturn(); + + // assert + String responseString = response.getResponse().getContentAsString(); + String expectedString = "{\"message\":\"You need more money!\",\"type\":\"NotEnoughMoneyException\"}"; + Map expectedJson = mapper.readValue(expectedString, Map.class); + Map jsonResponse = responseToJson(response); + assertEquals(expectedJson, jsonResponse); + } + + @WithMockUser(roles = { "USER" }) + @Test + public void test_SellCow_commons_exists_no_cow_to_sell() throws Exception { + + // arrange + UserCommons origUserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(0) + .cowHealth(100) + .build(); + + Commons testCommons = Commons + .builder() + .name("test commons") + .cowPrice(10) + .milkPrice(2) + .startingBalance(300) + .startingDate(LocalDateTime.now()) + .build(); + + UserCommons userCommonsToSend = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(0) + .cowHealth(100) + .build(); + + UserCommons correctuserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(0) + .cowHealth(100) + .build(); + + String requestBody = mapper.writeValueAsString(userCommonsToSend); + String expectedReturn = mapper.writeValueAsString(correctuserCommons); + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); + when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); + + // act + MvcResult response = mockMvc.perform(put("/api/usercommons/sell?commonsId=1&numCows=1") + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding("utf-8") + .content(requestBody) + .with(csrf())).andExpect(status().is(400)).andReturn(); + + + // assert + String responseString = response.getResponse().getContentAsString(); + String expectedString = "{\"message\":\"You have no cows to sell!\",\"type\":\"NoCowsException\"}"; + Map expectedJson = mapper.readValue(expectedString, Map.class); + Map jsonResponse = responseToJson(response); + assertEquals(expectedJson, jsonResponse); } @@ -749,38 +736,38 @@ public void test_SellCow_commons_exists_no_cow_to_sell() throws Exception { @WithMockUser(roles = { "USER" }) @Test public void test_getAllUserCommonsById_exists() throws Exception { - List expectedUserCommons = new ArrayList(); - UserCommons testexpectedUserCommons = dummyUserCommons(1); - expectedUserCommons.add(testexpectedUserCommons); - when(userCommonsRepository.findByCommonsId(eq(1L))).thenReturn(expectedUserCommons); - - MvcResult response = mockMvc.perform(get("/api/usercommons/commons/all?commonsId=1")) - .andExpect(status().isOk()).andReturn(); - - verify(userCommonsRepository, times(1)).findByCommonsId(eq(1L)); - - String expectedJson = mapper.writeValueAsString(expectedUserCommons); - String responseString = response.getResponse().getContentAsString(); - - assertEquals(expectedJson, responseString); + List expectedUserCommons = new ArrayList(); + UserCommons testexpectedUserCommons = dummyUserCommons(1); + expectedUserCommons.add(testexpectedUserCommons); + when(userCommonsRepository.findByCommonsId(eq(1L))).thenReturn(expectedUserCommons); + + MvcResult response = mockMvc.perform(get("/api/usercommons/commons/all?commonsId=1")) + .andExpect(status().isOk()).andReturn(); + + verify(userCommonsRepository, times(1)).findByCommonsId(eq(1L)); + + String expectedJson = mapper.writeValueAsString(expectedUserCommons); + String responseString = response.getResponse().getContentAsString(); + + assertEquals(expectedJson, responseString); } @WithMockUser(roles = { "ADMIN" }) @Test public void test_Admin_getAllUserCommonsById_exists() throws Exception { List expectedUserCommons = new ArrayList(); - UserCommons testexpectedUserCommons = dummyUserCommons(1); - expectedUserCommons.add(testexpectedUserCommons); - when(userCommonsRepository.findByCommonsId(eq(1L))).thenReturn(expectedUserCommons); - - MvcResult response = mockMvc.perform(get("/api/usercommons/commons/all?commonsId=1")) - .andExpect(status().isOk()).andReturn(); - - verify(userCommonsRepository, times(1)).findByCommonsId(eq(1L)); - - String expectedJson = mapper.writeValueAsString(expectedUserCommons); - String responseString = response.getResponse().getContentAsString(); - - assertEquals(expectedJson, responseString); + UserCommons testexpectedUserCommons = dummyUserCommons(1); + expectedUserCommons.add(testexpectedUserCommons); + when(userCommonsRepository.findByCommonsId(eq(1L))).thenReturn(expectedUserCommons); + + MvcResult response = mockMvc.perform(get("/api/usercommons/commons/all?commonsId=1")) + .andExpect(status().isOk()).andReturn(); + + verify(userCommonsRepository, times(1)).findByCommonsId(eq(1L)); + + String expectedJson = mapper.writeValueAsString(expectedUserCommons); + String responseString = response.getResponse().getContentAsString(); + + assertEquals(expectedJson, responseString); } } From 65a94f82c5be28b92e0c66789189b96583d72f80 Mon Sep 17 00:00:00 2001 From: Jacob Woodward Date: Fri, 26 May 2023 16:13:14 -0700 Subject: [PATCH 02/11] jw-add buttons to buy and sell multiple cows --- frontend/src/fixtures/userCommonsFixtures.js | 10 +++ .../src/main/components/Commons/ManageCows.js | 24 ++++-- frontend/src/main/pages/PlayPage.js | 53 +++++------- .../components/Commons/ManageCows.test.js | 31 +++++-- frontend/src/tests/pages/PlayPage.test.js | 83 +++++++++++++------ 5 files changed, 129 insertions(+), 72 deletions(-) diff --git a/frontend/src/fixtures/userCommonsFixtures.js b/frontend/src/fixtures/userCommonsFixtures.js index f644f8f4b..ee1b7961f 100644 --- a/frontend/src/fixtures/userCommonsFixtures.js +++ b/frontend/src/fixtures/userCommonsFixtures.js @@ -1,4 +1,14 @@ const userCommonsFixtures = { + // Backend does not include "commons" or "user", so they probably shouldn't be in these fixtures + oneRealUserCommons: { + "id": 1, + "userId": 1, + "commonsId": 1, + "username": "idk if this field is even used", + "totalWealth": 1000, + "numOfCows": 5, + "cowHealth": 98.0 + }, oneUserCommons: [ { diff --git a/frontend/src/main/components/Commons/ManageCows.js b/frontend/src/main/components/Commons/ManageCows.js index a44207711..c58633a23 100644 --- a/frontend/src/main/components/Commons/ManageCows.js +++ b/frontend/src/main/components/Commons/ManageCows.js @@ -2,14 +2,16 @@ import React from "react"; import { Card, Button, Row, Col } from "react-bootstrap"; import cowHead from "./../../../assets/CowHead.png"; -// add parameters -const ManageCows = ({userCommons,commons, onBuy, onSell}) => { + +// add parameters +const ManageCows = ({userCommons, commons, onBuy, onSell}) => { // update cowPrice from fixture + // Stryker disable ArithmeticOperator : line 24: not very important and unsure of how to test this return ( Manage Cows - {/* change $10 to info from fixture */} + {/* why does removing the optional chaining question mark turn the entire page white? */} Market Cow Price: ${commons?.cowPrice} Number of Cows: {userCommons.numOfCows} @@ -19,10 +21,22 @@ const ManageCows = ({userCommons,commons, onBuy, onSell}) => { - + +
+
+ +
+
+ +
+
+ +
+
+

- +

diff --git a/frontend/src/main/pages/PlayPage.js b/frontend/src/main/pages/PlayPage.js index c741ee60b..c81105c46 100644 --- a/frontend/src/main/pages/PlayPage.js +++ b/frontend/src/main/pages/PlayPage.js @@ -32,7 +32,6 @@ export default function PlayPage() { ); // Stryker enable all - // Stryker disable all const { data: commons } = useBackend( @@ -61,64 +60,52 @@ export default function PlayPage() { ); // Stryker enable all - const onSuccessBuy = () => { - toast(`Cow bought!`); + toast(`Cows bought!`); + } + const onSuccessSell = () => { + toast(`Cows sold!`); } - const objectToAxiosParamsBuy = (newUserCommons) => ({ + const onBuy = (userCommons, numToBuy) => { + mutationBuy.mutate({userCommons, numToBuy}) + }; + const onSell = (userCommons, numToSell) => { + mutationSell.mutate({userCommons, numToSell}) + }; + + const objectToAxiosParamsBuy = ({newUserCommons, numToBuy}) => ({ url: "/api/usercommons/buy", method: "PUT", data: newUserCommons, params: { - commonsId: commonsId + commonsId: commonsId, + numCows: numToBuy } }); - - - // Stryker disable all - const mutationbuy = useBackendMutation( + const mutationBuy = useBackendMutation( objectToAxiosParamsBuy, { onSuccess: onSuccessBuy }, // Stryker disable next-line all : hard to set up test for caching [`/api/usercommons/forcurrentuser?commonsId=${commonsId}`] ); - // Stryker enable all - - - const onBuy = (userCommons) => { - mutationbuy.mutate(userCommons) - }; - - const onSuccessSell = () => { - toast(`Cow sold!`); - } - - // Stryker disable all - const objectToAxiosParamsSell = (newUserCommons) => ({ + const objectToAxiosParamsSell = ({newUserCommons, numToSell}) => ({ url: "/api/usercommons/sell", method: "PUT", data: newUserCommons, params: { - commonsId: commonsId + commonsId: commonsId, + numCows: numToSell } }); - // Stryker enable all - - - // Stryker disable all - const mutationsell = useBackendMutation( + const mutationSell = useBackendMutation( objectToAxiosParamsSell, { onSuccess: onSuccessSell }, + // Stryker disable next-line all : hard to set up test for caching [`/api/usercommons/forcurrentuser?commonsId=${commonsId}`] ); - // Stryker enable all - - const onSell = (userCommons) => { - mutationsell.mutate(userCommons) - }; return (
diff --git a/frontend/src/tests/components/Commons/ManageCows.test.js b/frontend/src/tests/components/Commons/ManageCows.test.js index 5a1bc51a2..fd232a7f0 100644 --- a/frontend/src/tests/components/Commons/ManageCows.test.js +++ b/frontend/src/tests/components/Commons/ManageCows.test.js @@ -1,30 +1,43 @@ import { fireEvent, render, screen, waitFor } from "@testing-library/react"; import ManageCows from "main/components/Commons/ManageCows"; import userCommonsFixtures from "fixtures/userCommonsFixtures"; +import commonsFixtures from "fixtures/commonsFixtures"; describe("ManageCows tests", () => { + test("renders without crashing", () => { render( { console.log("onBuy called:",userCommons); }} onSell={ (userCommons) => { console.log("onSell called:",userCommons); }} /> ); }); - test("buying and selling a cow", async () => { + test("buying and selling cows", async () => { const mockBuy = jest.fn(); const mockSell = jest.fn(); render( - + ); - const buyButton = screen.getByTestId("buy-cow-button"); - const sellButton = screen.getByTestId("sell-cow-button"); + const buyMaxButton = screen.getByTestId("buy-max-cows-button"); + const buyTenButton = screen.getByTestId("buy-10-cows-button"); + const buyOneButton = screen.getByTestId("buy-a-cow-button"); + const sellOneButton = screen.getByTestId("sell-a-cow-button"); + const sellTenButton = screen.getByTestId("sell-10-cows-button"); + const sellAllButton = screen.getByTestId("sell-all-cows-button"); - fireEvent.click(buyButton); - await waitFor( ()=>expect(mockBuy).toHaveBeenCalled() ); - - fireEvent.click(sellButton); - await waitFor( ()=>expect(mockSell).toHaveBeenCalled() ); + fireEvent.click(buyMaxButton); + await waitFor( ()=>expect(mockBuy).toHaveBeenCalled()); + fireEvent.click(buyTenButton); + await waitFor( ()=>expect(mockBuy).toHaveBeenCalled()); + fireEvent.click(buyOneButton); + await waitFor( ()=>expect(mockBuy).toHaveBeenCalled()); + fireEvent.click(sellOneButton); + await waitFor( ()=>expect(mockSell).toHaveBeenCalled()); + fireEvent.click(sellTenButton); + await waitFor( ()=>expect(mockSell).toHaveBeenCalled()); + fireEvent.click(sellAllButton); + await waitFor( ()=>expect(mockSell).toHaveBeenCalled()); }); diff --git a/frontend/src/tests/pages/PlayPage.test.js b/frontend/src/tests/pages/PlayPage.test.js index 31fa5508a..977046b6b 100644 --- a/frontend/src/tests/pages/PlayPage.test.js +++ b/frontend/src/tests/pages/PlayPage.test.js @@ -7,6 +7,8 @@ import AxiosMockAdapter from "axios-mock-adapter"; import PlayPage from "main/pages/PlayPage"; import { apiCurrentUserFixtures } from "fixtures/currentUserFixtures"; import { systemInfoFixtures } from "fixtures/systemInfoFixtures"; +import userCommonsFixtures from "fixtures/userCommonsFixtures"; +import commonsFixtures from "fixtures/commonsFixtures"; jest.mock("react-router-dom", () => ({ ...jest.requireActual("react-router-dom"), @@ -20,30 +22,17 @@ describe("PlayPage tests", () => { const queryClient = new QueryClient(); beforeEach(() => { - const userCommons = { - commonsId: 1, - id: 1, - totalWealth: 0, - userId: 1 - }; axiosMock.reset(); axiosMock.resetHistory(); axiosMock.onGet("/api/currentUser").reply(200, apiCurrentUserFixtures.userOnly); + axiosMock.onGet("/api/usercommons").reply(200, userCommonsFixtures.oneUserCommons); axiosMock.onGet("/api/systemInfo").reply(200, systemInfoFixtures.showingNeither); - axiosMock.onGet("/api/usercommons/forcurrentuser", { params: { commonsId: 1 } }).reply(200, userCommons); - axiosMock.onGet("/api/commons", { params: { id: 1 } }).reply(200, { - id: 1, - name: "Sample Commons" - }); - axiosMock.onGet("/api/commons/all").reply(200, [ - { - id: 1, - name: "Sample Commons" - } - ]); + axiosMock.onGet("/api/usercommons/forcurrentuser", { params: { commonsId: 1 } }).reply(200, userCommonsFixtures); + axiosMock.onGet("/api/commons", { params: { id: 1 } }).reply(200, commonsFixtures.oneCommons); + axiosMock.onGet("/api/commons/all").reply(200, commonsFixtures.sevenCommons); axiosMock.onGet("/api/profits/all/commonsid").reply(200, []); - axiosMock.onPut("/api/usercommons/sell").reply(200, userCommons); - axiosMock.onPut("/api/usercommons/buy").reply(200, userCommons); + axiosMock.onPut("/api/usercommons/sell").reply(200, userCommonsFixtures.oneUserCommons); + axiosMock.onPut("/api/usercommons/buy").reply(200, userCommonsFixtures.oneUserCommons); }); test("renders without crashing", () => { @@ -65,18 +54,62 @@ describe("PlayPage tests", () => { ); - expect(await screen.findByTestId("buy-cow-button")).toBeInTheDocument(); - const buyCowButton = screen.getByTestId("buy-cow-button"); - fireEvent.click(buyCowButton); + expect(await screen.getByTestId("buy-a-cow-button")).toBeInTheDocument(); + const buyMaxCowsButton = screen.getByTestId("buy-max-cows-button"); + fireEvent.click(buyMaxCowsButton); await waitFor(() => expect(axiosMock.history.put.length).toBe(1)); + const buyTenCowsButton = screen.getByTestId("buy-10-cows-button"); + fireEvent.click(buyTenCowsButton); + await waitFor(() => expect(axiosMock.history.put.length).toBe(2)); + const buyCowButton = screen.getByTestId("buy-a-cow-button"); + fireEvent.click(buyCowButton); + await waitFor(() => expect(axiosMock.history.put.length).toBe(3)); - const sellCowButton = screen.getByTestId("sell-cow-button"); + const sellCowButton = screen.getByTestId("sell-a-cow-button"); fireEvent.click(sellCowButton); - - await waitFor(() => expect(axiosMock.history.put.length).toBe(2)); + await waitFor(() => expect(axiosMock.history.put.length).toBe(4)); + const sellTenCowsButton = screen.getByTestId("sell-10-cows-button"); + fireEvent.click(sellTenCowsButton); + await waitFor(() => expect(axiosMock.history.put.length).toBe(5)); + const sellAllCowsButton = screen.getByTestId("sell-all-cows-button"); + fireEvent.click(sellAllCowsButton); + await waitFor(() => expect(axiosMock.history.put.length).toBe(6)); }); + // Not sure how to test this since I'm unable to call the onBuy and onSell functions from PlayPage +/* test("test buy and sell buttons work properly", async () => { + render( + + + + + + ); + + const buyMaxButton = screen.getByTestId("buy-max-cows-button"); + const buyTenButton = screen.getByTestId("buy-10-cows-button"); + const buyOneButton = screen.getByTestId("buy-a-cow-button"); + const sellOneButton = screen.getByTestId("sell-a-cow-button"); + const sellTenButton = screen.getByTestId("sell-10-cows-button"); + const sellAllButton = screen.getByTestId("sell-all-cows-button"); + + fireEvent.click(buyMaxButton); + await waitFor( ()=>expect(onBuy).toContain(userCommonsFixtures.oneRealUserCommons, 50)); + fireEvent.click(buyTenButton); + await waitFor( ()=>expect(onBuy).toHaveBeenCalled()); + fireEvent.click(buyOneButton); + await waitFor( ()=>expect(onBuy).toHaveBeenCalled()); + fireEvent.click(sellOneButton); + await waitFor( ()=>expect(onSell).toHaveBeenCalled()); + fireEvent.click(sellTenButton); + await waitFor( ()=>expect(onSell).toHaveBeenCalled()); + fireEvent.click(sellAllButton); + await waitFor( ()=>expect(onSell).toHaveBeenCalled()); + + }); +*/ + test("Make sure that both the Announcements and Welcome Farmer components show up", async () => { render( From 105ac5df25e1964895c08807157a11b7b2af1f88 Mon Sep 17 00:00:00 2001 From: Jacob Woodward Date: Fri, 26 May 2023 17:55:08 -0700 Subject: [PATCH 03/11] jw-add coverage for jacoco and pitest --- .../controllers/UserCommonsController.java | 5 +- .../UserCommonsControllerTests.java | 146 +++++++++++++++++- 2 files changed, 141 insertions(+), 10 deletions(-) diff --git a/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java b/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java index ff9d9d8cb..e459963b8 100644 --- a/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java +++ b/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java @@ -71,7 +71,6 @@ public UserCommons getUserCommonsById( return userCommons; } - //BUG: Sometimes there is a glitch where clicking the Buy Max button buys more than the max, idk cause @ApiOperation(value = "Buy cows, totalWealth updated") @PreAuthorize("hasRole('ROLE_USER')") @PutMapping("/buy") @@ -116,7 +115,9 @@ public ResponseEntity putUserCommonsByIdSell( .orElseThrow(() -> new EntityNotFoundException(UserCommons.class, "commonsId", commonsId, "userId", userId)); if(userCommons.getNumOfCows() >= 1){ - if (numCows > userCommons.getNumOfCows()) numCows = userCommons.getNumOfCows(); + //if (numCows > userCommons.getNumOfCows()) numCows = userCommons.getNumOfCows(); + //numCows = (numCows < userCommons.getNumOfCows()) ? numCows : userCommons.getNumOfCows(); + numCows = Math.min(numCows, userCommons.getNumOfCows()); userCommons.setTotalWealth(userCommons.getTotalWealth() + (numCows * commons.getCowPrice())); userCommons.setNumOfCows(userCommons.getNumOfCows() - numCows); } diff --git a/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java b/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java index df32c441d..bbdd18900 100644 --- a/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java +++ b/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java @@ -210,7 +210,7 @@ public void test_BuyCow_commons_exists_user_has_exact_amount_needed() throws Exc .id(1L) .userId(1L) .commonsId(1L) - .totalWealth(300) + .totalWealth(600) .numOfCows(1) .cowHealth(100) .build(); @@ -229,7 +229,7 @@ public void test_BuyCow_commons_exists_user_has_exact_amount_needed() throws Exc .id(1L) .userId(1L) .commonsId(1L) - .totalWealth(300) + .totalWealth(600) .numOfCows(1) .cowHealth(100) .build(); @@ -240,7 +240,7 @@ public void test_BuyCow_commons_exists_user_has_exact_amount_needed() throws Exc .userId(1L) .commonsId(1L) .totalWealth(0) - .numOfCows(2) + .numOfCows(3) .cowHealth(100) .build(); @@ -251,7 +251,7 @@ public void test_BuyCow_commons_exists_user_has_exact_amount_needed() throws Exc when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); // act - MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=1&numCows=1") + MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=1&numCows=2") .contentType(MediaType.APPLICATION_JSON) .characterEncoding("utf-8") .content(requestBody) @@ -264,7 +264,7 @@ public void test_BuyCow_commons_exists_user_has_exact_amount_needed() throws Exc String responseString = response.getResponse().getContentAsString(); assertEquals(expectedReturn, responseString); } - + @WithMockUser(roles = { "USER" }) @Test public void test_SellCow_commons_exists() throws Exception { @@ -277,7 +277,7 @@ public void test_SellCow_commons_exists() throws Exception { .commonsId(1L) .totalWealth(300) .numOfCows(1) - .cowHealth(100) + .cowHealth(100) .build(); Commons testCommons = Commons @@ -609,7 +609,73 @@ public void test_BuyCow_commons_exists_not_enough_money() throws Exception { .id(1L) .userId(1L) .commonsId(1L) - .totalWealth(0) + .totalWealth(10) + .numOfCows(1) + .cowHealth(100) + .build(); + + Commons testCommons = Commons + .builder() + .name("test commons") + .cowPrice(10) + .milkPrice(2) + .startingBalance(0) + .startingDate(LocalDateTime.now()) + .build(); + + UserCommons userCommonsToSend = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(10) + .numOfCows(1) + .cowHealth(100) + .build(); + + UserCommons correctuserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(10) + .numOfCows(1) + .cowHealth(100) + .build(); + + String requestBody = mapper.writeValueAsString(userCommonsToSend); + String expectedReturn = mapper.writeValueAsString(correctuserCommons); + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); + when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); + + // act + MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=1&numCows=2") + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding("utf-8") + .content(requestBody) + .with(csrf())) + .andExpect(status().is(400)).andReturn(); + + // assert + String responseString = response.getResponse().getContentAsString(); + String expectedString = "{\"message\":\"You need more money!\",\"type\":\"NotEnoughMoneyException\"}"; + Map expectedJson = mapper.readValue(expectedString, Map.class); + Map jsonResponse = responseToJson(response); + assertEquals(expectedJson, jsonResponse); + } + + @WithMockUser(roles = { "USER" }) + @Test + public void test_BuyCow_commons_exists_try_to_buy_zero_cows() throws Exception { + + // arrange + UserCommons origUserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(100) .numOfCows(1) .cowHealth(100) .build(); @@ -650,7 +716,7 @@ public void test_BuyCow_commons_exists_not_enough_money() throws Exception { when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); // act - MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=1&numCows=1") + MvcResult response = mockMvc.perform(put("/api/usercommons/buy?commonsId=1&numCows=0") .contentType(MediaType.APPLICATION_JSON) .characterEncoding("utf-8") .content(requestBody) @@ -731,6 +797,70 @@ public void test_SellCow_commons_exists_no_cow_to_sell() throws Exception { assertEquals(expectedJson, jsonResponse); } + @WithMockUser(roles = { "USER" }) + @Test + public void test_SellCow_commons_exists_user_sells_more_cows_than_owned() throws Exception { + + // arrange + UserCommons origUserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(3) + .cowHealth(100) + .build(); + + Commons testCommons = Commons + .builder() + .name("test commons") + .cowPrice(300) + .milkPrice(2) + .startingBalance(300) + .startingDate(LocalDateTime.now()) + .build(); + + UserCommons userCommonsToSend = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(3) + .cowHealth(100) + .build(); + + UserCommons correctuserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(1200) + .numOfCows(0) + .cowHealth(100) + .build(); + + String requestBody = mapper.writeValueAsString(userCommonsToSend); + String expectedReturn = mapper.writeValueAsString(correctuserCommons); + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); + when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); + + // act + MvcResult response = mockMvc.perform(put("/api/usercommons/sell?commonsId=1&numCows=10") + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding("utf-8") + .content(requestBody) + .with(csrf())) + .andExpect(status().isOk()).andReturn(); + + // assert + verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L), eq(1L)); + verify(userCommonsRepository, times(1)).save(correctuserCommons); + String responseString = response.getResponse().getContentAsString(); + assertEquals(expectedReturn, responseString); + } @WithMockUser(roles = { "USER" }) From c036a0fb722c30ca9f4ef780d7c194f143d21c0b Mon Sep 17 00:00:00 2001 From: Jacob Woodward Date: Fri, 26 May 2023 18:00:00 -0700 Subject: [PATCH 04/11] jw-change getByTestId() to findByTestId() --- frontend/src/tests/pages/PlayPage.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/tests/pages/PlayPage.test.js b/frontend/src/tests/pages/PlayPage.test.js index 977046b6b..771aba731 100644 --- a/frontend/src/tests/pages/PlayPage.test.js +++ b/frontend/src/tests/pages/PlayPage.test.js @@ -54,7 +54,7 @@ describe("PlayPage tests", () => { ); - expect(await screen.getByTestId("buy-a-cow-button")).toBeInTheDocument(); + expect(await screen.findByTestId("buy-a-cow-button")).toBeInTheDocument(); const buyMaxCowsButton = screen.getByTestId("buy-max-cows-button"); fireEvent.click(buyMaxCowsButton); From df0bddc1477939d285d6a93081d811953a9f9aac Mon Sep 17 00:00:00 2001 From: Jacob Woodward Date: Fri, 26 May 2023 23:00:14 -0700 Subject: [PATCH 05/11] jw-add scaleSalePrice param to all relevent fixtures --- frontend/src/fixtures/commonsFixtures.js | 11 +++++++++++ frontend/src/fixtures/commonsPlusFixtures.js | 4 ++++ frontend/src/fixtures/userCommonsFixtures.js | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/frontend/src/fixtures/commonsFixtures.js b/frontend/src/fixtures/commonsFixtures.js index 6c76921f2..e2c425357 100644 --- a/frontend/src/fixtures/commonsFixtures.js +++ b/frontend/src/fixtures/commonsFixtures.js @@ -11,6 +11,7 @@ const commonsFixtures = { "milkPrice": 10, "degradationRate": .5, "showLeaderboard": true, + "scaleSalePrice": true, "carryingCapacity": 100, }, { @@ -24,6 +25,7 @@ const commonsFixtures = { "milkPrice": 10, "degradationRate": .5, "showLeaderboard": true, + "scaleSalePrice": true, "carryingCapacity": 123, }, { @@ -37,6 +39,7 @@ const commonsFixtures = { "milkPrice": 10, "degradationRate": .5, "showLeaderboard": true, + "scaleSalePrice": true, "carryingCapacity": 42, } ], @@ -53,6 +56,7 @@ const commonsFixtures = { "milkPrice": 10, "degradationRate": .5, "showLeaderboard": true, + "scaleSalePrice": true, "carryingCapacity": 314, } ], @@ -66,6 +70,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, + "scaleSalePrice": true, "carryingCapacity": 100, }, { @@ -76,6 +81,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, + "scaleSalePrice": true, "carryingCapacity": 100, }, { @@ -86,6 +92,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, + "scaleSalePrice": true, "carryingCapacity": 100, }, { @@ -96,6 +103,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, + "scaleSalePrice": true, "carryingCapacity": 100, }, { @@ -106,6 +114,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, + "scaleSalePrice": true, "carryingCapacity": 100, }, { @@ -116,6 +125,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, + "scaleSalePrice": true, "carryingCapacity": 100, }, { @@ -126,6 +136,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, + "scaleSalePrice": true, "carryingCapacity": 100, } ], diff --git a/frontend/src/fixtures/commonsPlusFixtures.js b/frontend/src/fixtures/commonsPlusFixtures.js index dbdb734ff..73dacfc71 100644 --- a/frontend/src/fixtures/commonsPlusFixtures.js +++ b/frontend/src/fixtures/commonsPlusFixtures.js @@ -11,6 +11,7 @@ const commonsPlusFixtures = { "endingDate": null, "degradationRate": 0.01, "showLeaderboard": false, + "scaleSalePrice": true, "carryingCapacity": 100, }, "totalCows": 10, @@ -28,6 +29,7 @@ const commonsPlusFixtures = { "endingDate": null, "degradationRate": 0.01, "showLeaderboard": true, + "scaleSalePrice": true, "carryingCapacity": 42, }, "totalCows": 0, @@ -45,6 +47,7 @@ const commonsPlusFixtures = { "endingDate": null, "degradationRate": 5.0, "showLeaderboard": true, + "scaleSalePrice": true, "carryingCapacity": 123, }, "totalCows": 0, @@ -65,6 +68,7 @@ const commonsPlusFixtures = { "endingDate": null, "degradationRate": 3.0, "showLeaderboard": false, + "scaleSalePrice": true, "carryingCapacity": 23, }, "totalCows": 0, diff --git a/frontend/src/fixtures/userCommonsFixtures.js b/frontend/src/fixtures/userCommonsFixtures.js index ee1b7961f..a68c14f5f 100644 --- a/frontend/src/fixtures/userCommonsFixtures.js +++ b/frontend/src/fixtures/userCommonsFixtures.js @@ -26,6 +26,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -50,6 +51,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -71,6 +73,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -92,6 +95,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 100000, @@ -116,6 +120,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -137,6 +142,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -158,6 +164,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 100000, @@ -179,6 +186,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 50, @@ -200,6 +208,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 800, @@ -224,6 +233,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -245,6 +255,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -266,6 +277,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 100000, @@ -287,6 +299,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 50, @@ -308,6 +321,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 800, @@ -329,6 +343,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -350,6 +365,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -371,6 +387,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 100000, @@ -392,6 +409,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 50, @@ -413,6 +431,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, + "scaleSalePrice": true, "degradationRate": .5, }, "totalWealth" : 800, From 702b0ea6dc3fa3b444f78f4417db246c804412ac Mon Sep 17 00:00:00 2001 From: Jacob Woodward Date: Sat, 27 May 2023 00:07:33 -0700 Subject: [PATCH 06/11] jw-update all (hopefully) of frontend to be able to handle scaleCowSalePrice --- frontend/src/fixtures/commonsFixtures.js | 22 +++++------ frontend/src/fixtures/commonsPlusFixtures.js | 8 ++-- frontend/src/fixtures/userCommonsFixtures.js | 38 +++++++++---------- .../main/components/Commons/CommonsForm.js | 10 +++++ .../main/components/Commons/CommonsTable.js | 17 +++++---- .../src/main/components/Commons/ManageCows.js | 4 ++ .../src/main/pages/AdminEditCommonsPage.js | 3 +- .../pages/AdminCreateCommonsPage.test.js | 4 ++ .../tests/pages/AdminEditCommonsPage.test.js | 14 +++++-- 9 files changed, 74 insertions(+), 46 deletions(-) diff --git a/frontend/src/fixtures/commonsFixtures.js b/frontend/src/fixtures/commonsFixtures.js index e2c425357..20746ec40 100644 --- a/frontend/src/fixtures/commonsFixtures.js +++ b/frontend/src/fixtures/commonsFixtures.js @@ -11,7 +11,7 @@ const commonsFixtures = { "milkPrice": 10, "degradationRate": .5, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 100, }, { @@ -25,7 +25,7 @@ const commonsFixtures = { "milkPrice": 10, "degradationRate": .5, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 123, }, { @@ -39,7 +39,7 @@ const commonsFixtures = { "milkPrice": 10, "degradationRate": .5, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 42, } ], @@ -56,7 +56,7 @@ const commonsFixtures = { "milkPrice": 10, "degradationRate": .5, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 314, } ], @@ -70,7 +70,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 100, }, { @@ -81,7 +81,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 100, }, { @@ -92,7 +92,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 100, }, { @@ -103,7 +103,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 100, }, { @@ -114,7 +114,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 100, }, { @@ -125,7 +125,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 100, }, { @@ -136,7 +136,7 @@ const commonsFixtures = { "cowPrice": 15, "degradationRate": .5, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 100, } ], diff --git a/frontend/src/fixtures/commonsPlusFixtures.js b/frontend/src/fixtures/commonsPlusFixtures.js index 73dacfc71..65f0db94e 100644 --- a/frontend/src/fixtures/commonsPlusFixtures.js +++ b/frontend/src/fixtures/commonsPlusFixtures.js @@ -11,7 +11,7 @@ const commonsPlusFixtures = { "endingDate": null, "degradationRate": 0.01, "showLeaderboard": false, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 100, }, "totalCows": 10, @@ -29,7 +29,7 @@ const commonsPlusFixtures = { "endingDate": null, "degradationRate": 0.01, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 42, }, "totalCows": 0, @@ -47,7 +47,7 @@ const commonsPlusFixtures = { "endingDate": null, "degradationRate": 5.0, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 123, }, "totalCows": 0, @@ -68,7 +68,7 @@ const commonsPlusFixtures = { "endingDate": null, "degradationRate": 3.0, "showLeaderboard": false, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "carryingCapacity": 23, }, "totalCows": 0, diff --git a/frontend/src/fixtures/userCommonsFixtures.js b/frontend/src/fixtures/userCommonsFixtures.js index a68c14f5f..f4a00c8f8 100644 --- a/frontend/src/fixtures/userCommonsFixtures.js +++ b/frontend/src/fixtures/userCommonsFixtures.js @@ -26,7 +26,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -51,7 +51,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -73,7 +73,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -95,7 +95,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 100000, @@ -120,7 +120,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -142,7 +142,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -164,7 +164,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 100000, @@ -186,7 +186,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 50, @@ -208,7 +208,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 800, @@ -233,7 +233,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -255,7 +255,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -277,7 +277,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 100000, @@ -299,7 +299,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 50, @@ -321,7 +321,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 800, @@ -343,7 +343,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -365,7 +365,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 1000, @@ -387,7 +387,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 100000, @@ -409,7 +409,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 50, @@ -431,7 +431,7 @@ const userCommonsFixtures = { "totalPlayers": 50, "cowPrice": 15, "showLeaderboard": true, - "scaleSalePrice": true, + "scaleCowSalePrice": true, "degradationRate": .5, }, "totalWealth" : 800, diff --git a/frontend/src/main/components/Commons/CommonsForm.js b/frontend/src/main/components/Commons/CommonsForm.js index fa164feaa..e454ec678 100644 --- a/frontend/src/main/components/Commons/CommonsForm.js +++ b/frontend/src/main/components/Commons/CommonsForm.js @@ -158,6 +158,16 @@ function CommonsForm({ initialCommons, submitAction, buttonLabel = "Create" }) { + + Cow Sale Price Decreases with Health? + + + Show Leaderboard? row.commons.degradationRate, id: 'commons.degradationRate' }, + { + Header:'Cow Sale Price Decreases with Health?', + id: 'commons.scaleCowSalePrice', // needed for tests + accessor: (row, _rowIndex) => String(row.commons.scaleCowSalePrice) // hack needed for boolean values to show up + }, { Header:'Show Leaderboard?', id: 'commons.showLeaderboard', // needed for tests @@ -86,16 +91,12 @@ export default function CommonsTable({ commons, currentUser }) { const columnsIfAdmin = [ ...columns, - ButtonColumn("Edit", -"primary", editCallback, testid), - ButtonColumn("Delete", -"danger", deleteCallback, testid), - ButtonColumn("Leaderboard", -"secondary", leaderboardCallback, testid) + ButtonColumn("Edit", "primary", editCallback, testid), + ButtonColumn("Delete", "danger", deleteCallback, testid), + ButtonColumn("Leaderboard", "secondary", leaderboardCallback, testid) ]; - const columnsToDisplay = hasRole(currentUser, -"ROLE_ADMIN") ? columnsIfAdmin : columns; + const columnsToDisplay = hasRole(currentUser, "ROLE_ADMIN") ? columnsIfAdmin : columns; return {
+ {!!commons?.scaleCowSalePrice && + Note: Buying cows buys at current cow price, but selling cows sells at current cow price times the average health of cows as a percentage! + + } ); diff --git a/frontend/src/main/pages/AdminEditCommonsPage.js b/frontend/src/main/pages/AdminEditCommonsPage.js index a96b0f6be..ee3e58e0e 100644 --- a/frontend/src/main/pages/AdminEditCommonsPage.js +++ b/frontend/src/main/pages/AdminEditCommonsPage.js @@ -36,6 +36,7 @@ export default function CommonsEditPage() { "startingDate": commons.startingDate, "degradationRate": commons.degradationRate, "carryingCapacity": commons.carryingCapacity, + "scaleCowSalePrice": commons.scaleCowSalePrice, "showLeaderboard": commons.showLeaderboard, } }); @@ -64,7 +65,7 @@ export default function CommonsEditPage() { return (
-

Edit Commons

+

Edit Commons

{commons && } diff --git a/frontend/src/tests/pages/AdminCreateCommonsPage.test.js b/frontend/src/tests/pages/AdminCreateCommonsPage.test.js index f491add96..2cf901cdf 100644 --- a/frontend/src/tests/pages/AdminCreateCommonsPage.test.js +++ b/frontend/src/tests/pages/AdminCreateCommonsPage.test.js @@ -61,6 +61,7 @@ describe("AdminCreateCommonsPage tests", () => { "startingDate": "2022-03-05T00:00:00", "degradationRate": 30.4, "carryingCapacity": 25, + "scaleCowSalePrice": false, "showLeaderboard": false }); @@ -81,6 +82,7 @@ describe("AdminCreateCommonsPage tests", () => { const startDateField = screen.getByLabelText("Starting Date"); const degradationRateField = screen.getByLabelText("Degradation Rate"); const carryingCapacityField = screen.getByLabelText("Carrying Capacity"); + const scaleCowSalePriceField = screen.getByLabelText("Cow Sale Price Decreases with Health?"); const showLeaderboardField = screen.getByLabelText("Show Leaderboard?"); const button = screen.getByTestId("CommonsForm-Submit-Button"); @@ -91,6 +93,7 @@ describe("AdminCreateCommonsPage tests", () => { fireEvent.change(startDateField, { target: { value: '2022-03-05' } }) fireEvent.change(degradationRateField, { target: { value: '30.4' } }) fireEvent.change(carryingCapacityField, { target: { value: '25' } }) + fireEvent.change(scaleCowSalePriceField, { target: { value: true } }) fireEvent.change(showLeaderboardField, { target: { value: true } }) fireEvent.click(button); @@ -108,6 +111,7 @@ describe("AdminCreateCommonsPage tests", () => { startingDate: '2022-03-05T00:00:00.000Z', // [1] degradationRate: 30.4, carryingCapacity: 25, + scaleCowSalePrice: false, showLeaderboard: false }; diff --git a/frontend/src/tests/pages/AdminEditCommonsPage.test.js b/frontend/src/tests/pages/AdminEditCommonsPage.test.js index b921f0f88..ee77b8234 100644 --- a/frontend/src/tests/pages/AdminEditCommonsPage.test.js +++ b/frontend/src/tests/pages/AdminEditCommonsPage.test.js @@ -49,7 +49,8 @@ describe("AdminEditCommonsPage tests", () => { "milkPrice": 10, "degradationRate": 20.3, "carryingCapacity": 100, - "showLeaderboard": false, + "scaleCowSalePrice": false, + "showLeaderboard": false }); axiosMock.onPut('/api/commons/update').reply(200, { "id": 5, @@ -60,7 +61,8 @@ describe("AdminEditCommonsPage tests", () => { "milkPrice": 5, "degradationRate": 40.3, "carryingCapacity": 200, - "showLeaderboard": false, + "scaleCowSalePrice": true, + "showLeaderboard": true }); }); @@ -93,6 +95,7 @@ describe("AdminEditCommonsPage tests", () => { const startingDateField = screen.getByLabelText(/Starting Date/); const degradationRateField = screen.getByLabelText(/Degradation Rate/); const carryingCapacityField = screen.getByLabelText(/Carrying Capacity/); + const scaleCowSalePriceField = screen.getByLabelText(/Cow Sale Price Decreases with Health\?/); const showLeaderboardField = screen.getByLabelText(/Show Leaderboard\?/); expect(nameField).toHaveValue("Seths Common"); @@ -102,6 +105,7 @@ describe("AdminEditCommonsPage tests", () => { expect(milkPriceField).toHaveValue(10); expect(degradationRateField).toHaveValue(20.3); expect(carryingCapacityField).toHaveValue(100); + expect(scaleCowSalePriceField).not.toBeChecked(); expect(showLeaderboardField).not.toBeChecked(); }); @@ -123,6 +127,7 @@ describe("AdminEditCommonsPage tests", () => { const startingDateField = screen.getByLabelText(/Starting Date/); const degradationRateField = screen.getByLabelText(/Degradation Rate/); const carryingCapacityField = screen.getByLabelText(/Carrying Capacity/); + const scaleCowSalePriceField = screen.getByLabelText(/Cow Sale Price Decreases with Health\?/); const showLeaderboardField = screen.getByLabelText(/Show Leaderboard\?/); expect(nameField).toHaveValue("Seths Common"); @@ -132,6 +137,7 @@ describe("AdminEditCommonsPage tests", () => { expect(milkPriceField).toHaveValue(10); expect(degradationRateField).toHaveValue(20.3); expect(carryingCapacityField).toHaveValue(100); + expect(scaleCowSalePriceField).not.toBeChecked(); expect(showLeaderboardField).not.toBeChecked(); const submitButton = screen.getByText("Update"); @@ -145,6 +151,7 @@ describe("AdminEditCommonsPage tests", () => { fireEvent.change(milkPriceField, { target: { value: 5 } }) fireEvent.change(degradationRateField, { target: { value: 40.3 } }) fireEvent.change(carryingCapacityField, { target: { value: 200 } }) + fireEvent.click(scaleCowSalePriceField) fireEvent.click(showLeaderboardField) fireEvent.click(submitButton); @@ -163,7 +170,8 @@ describe("AdminEditCommonsPage tests", () => { "startingDate": "2022-03-07T00:00:00.000Z", "degradationRate": 40.3, "carryingCapacity": 200, - "showLeaderboard": true, + "scaleCowSalePrice": true, + "showLeaderboard": true })); // posted object }); }); From b1671e9724d85143af2492f0abac233df2d47af7 Mon Sep 17 00:00:00 2001 From: Jacob Woodward Date: Sat, 27 May 2023 21:09:51 -0700 Subject: [PATCH 07/11] jw-implement cow sale price scaling in the backend --- .../controllers/CommonsController.java | 4 +- .../controllers/UserCommonsController.java | 5 +- .../cs156/happiercows/entities/Commons.java | 1 + .../models/CreateCommonsParams.java | 2 + .../controllers/CommonsControllerTests.java | 12 +++- .../UserCommonsControllerTests.java | 72 ++++++++++++++++++- 6 files changed, 87 insertions(+), 9 deletions(-) diff --git a/src/main/java/edu/ucsb/cs156/happiercows/controllers/CommonsController.java b/src/main/java/edu/ucsb/cs156/happiercows/controllers/CommonsController.java index 399e92d35..6da16f88d 100644 --- a/src/main/java/edu/ucsb/cs156/happiercows/controllers/CommonsController.java +++ b/src/main/java/edu/ucsb/cs156/happiercows/controllers/CommonsController.java @@ -110,6 +110,7 @@ public ResponseEntity updateCommons( updated.setMilkPrice(params.getMilkPrice()); updated.setStartingBalance(params.getStartingBalance()); updated.setStartingDate(params.getStartingDate()); + updated.setScaleCowSalePrice(params.getScaleCowSalePrice()); updated.setShowLeaderboard(params.getShowLeaderboard()); updated.setDegradationRate(params.getDegradationRate()); updated.setCarryingCapacity(params.getCarryingCapacity()); @@ -140,7 +141,7 @@ public Commons getCommonsById( @PostMapping(value = "/new", produces = "application/json") public ResponseEntity createCommons( - @ApiParam("request body") @RequestBody CreateCommonsParams params) throws JsonProcessingException { + @ApiParam("request body") @RequestBody CreateCommonsParams params) throws JsonProcessingException { Commons commons = Commons.builder() .name(params.getName()) .cowPrice(params.getCowPrice()) @@ -148,6 +149,7 @@ public ResponseEntity createCommons( .startingBalance(params.getStartingBalance()) .startingDate(params.getStartingDate()) .degradationRate(params.getDegradationRate()) + .scaleCowSalePrice(params.getScaleCowSalePrice()) .showLeaderboard(params.getShowLeaderboard()) .carryingCapacity(params.getCarryingCapacity()) .build(); diff --git a/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java b/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java index e459963b8..bab5c5f84 100644 --- a/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java +++ b/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java @@ -115,10 +115,11 @@ public ResponseEntity putUserCommonsByIdSell( .orElseThrow(() -> new EntityNotFoundException(UserCommons.class, "commonsId", commonsId, "userId", userId)); if(userCommons.getNumOfCows() >= 1){ + //Causes PITest failure and is untestable, as > and >= are functionally identical //if (numCows > userCommons.getNumOfCows()) numCows = userCommons.getNumOfCows(); - //numCows = (numCows < userCommons.getNumOfCows()) ? numCows : userCommons.getNumOfCows(); numCows = Math.min(numCows, userCommons.getNumOfCows()); - userCommons.setTotalWealth(userCommons.getTotalWealth() + (numCows * commons.getCowPrice())); + userCommons.setTotalWealth(userCommons.getTotalWealth() + (numCows * (commons.isScaleCowSalePrice() ? (commons.getCowPrice() * (userCommons.getCowHealth()/100)) + : commons.getCowPrice()))); userCommons.setNumOfCows(userCommons.getNumOfCows() - numCows); } else{ diff --git a/src/main/java/edu/ucsb/cs156/happiercows/entities/Commons.java b/src/main/java/edu/ucsb/cs156/happiercows/entities/Commons.java index d09ac258f..3fbb6099f 100644 --- a/src/main/java/edu/ucsb/cs156/happiercows/entities/Commons.java +++ b/src/main/java/edu/ucsb/cs156/happiercows/entities/Commons.java @@ -30,6 +30,7 @@ public class Commons private double startingBalance; private LocalDateTime startingDate; private double degradationRate; + private boolean scaleCowSalePrice; private boolean showLeaderboard; private int carryingCapacity; diff --git a/src/main/java/edu/ucsb/cs156/happiercows/models/CreateCommonsParams.java b/src/main/java/edu/ucsb/cs156/happiercows/models/CreateCommonsParams.java index 92c734f8b..e5aef4bb3 100644 --- a/src/main/java/edu/ucsb/cs156/happiercows/models/CreateCommonsParams.java +++ b/src/main/java/edu/ucsb/cs156/happiercows/models/CreateCommonsParams.java @@ -32,6 +32,8 @@ public class CreateCommonsParams { @DateTimeFormat private LocalDateTime startingDate; @Builder.Default + private Boolean scaleCowSalePrice = false; + @Builder.Default private Boolean showLeaderboard = false; @NumberFormat private int carryingCapacity; diff --git a/src/test/java/edu/ucsb/cs156/happiercows/controllers/CommonsControllerTests.java b/src/test/java/edu/ucsb/cs156/happiercows/controllers/CommonsControllerTests.java index d4902adf8..7bc0ac1ea 100644 --- a/src/test/java/edu/ucsb/cs156/happiercows/controllers/CommonsControllerTests.java +++ b/src/test/java/edu/ucsb/cs156/happiercows/controllers/CommonsControllerTests.java @@ -73,7 +73,8 @@ public void createCommonsTest() throws Exception { .startingBalance(1020.10) .startingDate(someTime) .degradationRate(50.0) - .showLeaderboard(false) + .scaleCowSalePrice(true) + .showLeaderboard(true) .carryingCapacity(100) .build(); @@ -84,7 +85,8 @@ public void createCommonsTest() throws Exception { .startingBalance(1020.10) .startingDate(someTime) .degradationRate(50.0) - .showLeaderboard(false) + .scaleCowSalePrice(true) + .showLeaderboard(true) .carryingCapacity(100) .build(); @@ -230,6 +232,7 @@ public void updateCommonsTest() throws Exception { .startingBalance(1020.10) .startingDate(someTime) .degradationRate(50.0) + .scaleCowSalePrice(true) .showLeaderboard(true) .carryingCapacity(100) .build(); @@ -241,6 +244,7 @@ public void updateCommonsTest() throws Exception { .startingBalance(1020.10) .startingDate(someTime) .degradationRate(50.0) + .scaleCowSalePrice(true) .showLeaderboard(true) .carryingCapacity(100) .build(); @@ -263,7 +267,9 @@ public void updateCommonsTest() throws Exception { commons.setMilkPrice(parameters.getMilkPrice()); parameters.setDegradationRate(parameters.getDegradationRate() + 1.00); commons.setDegradationRate(parameters.getDegradationRate()); - parameters.setShowLeaderboard(false); + parameters.setScaleCowSalePrice(true); + commons.setScaleCowSalePrice(parameters.getScaleCowSalePrice()); + parameters.setShowLeaderboard(true); commons.setShowLeaderboard(parameters.getShowLeaderboard()); parameters.setCarryingCapacity(123); commons.setCarryingCapacity(parameters.getCarryingCapacity()); diff --git a/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java b/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java index bbdd18900..0f40248af 100644 --- a/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java +++ b/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java @@ -809,7 +809,7 @@ public void test_SellCow_commons_exists_user_sells_more_cows_than_owned() throws .commonsId(1L) .totalWealth(300) .numOfCows(3) - .cowHealth(100) + .cowHealth(50) .build(); Commons testCommons = Commons @@ -828,7 +828,7 @@ public void test_SellCow_commons_exists_user_sells_more_cows_than_owned() throws .commonsId(1L) .totalWealth(300) .numOfCows(3) - .cowHealth(100) + .cowHealth(50) .build(); UserCommons correctuserCommons = UserCommons @@ -838,7 +838,7 @@ public void test_SellCow_commons_exists_user_sells_more_cows_than_owned() throws .commonsId(1L) .totalWealth(1200) .numOfCows(0) - .cowHealth(100) + .cowHealth(50) .build(); String requestBody = mapper.writeValueAsString(userCommonsToSend); @@ -862,6 +862,72 @@ public void test_SellCow_commons_exists_user_sells_more_cows_than_owned() throws assertEquals(expectedReturn, responseString); } + @WithMockUser(roles = { "USER" }) + @Test + public void test_SellCow_commons_exists_scale_sell_price() throws Exception { + + // arrange + UserCommons origUserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(50) + .build(); + + Commons testCommons = Commons + .builder() + .name("test commons") + .cowPrice(10) + .milkPrice(2) + .startingBalance(300) + .startingDate(LocalDateTime.now()) + .scaleCowSalePrice(true) + .build(); + + UserCommons userCommonsToSend = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(1) + .cowHealth(50) + .build(); + + UserCommons correctuserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(305) + .numOfCows(0) + .cowHealth(50) + .build(); + + String requestBody = mapper.writeValueAsString(userCommonsToSend); + String expectedReturn = mapper.writeValueAsString(correctuserCommons); + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); + when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); + + // act + MvcResult response = mockMvc.perform(put("/api/usercommons/sell?commonsId=1&numCows=1") + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding("utf-8") + .content(requestBody) + .with(csrf())) + .andExpect(status().isOk()).andReturn(); + + // assert + verify(userCommonsRepository, times(1)).findByCommonsIdAndUserId(eq(1L), eq(1L)); + verify(userCommonsRepository, times(1)).save(correctuserCommons); + String responseString = response.getResponse().getContentAsString(); + assertEquals(expectedReturn, responseString); + } + @WithMockUser(roles = { "USER" }) @Test From 1438e6252dcd4c18813499154ba2e7c9ccad4a12 Mon Sep 17 00:00:00 2001 From: Jacob Woodward Date: Sat, 27 May 2023 22:10:55 -0700 Subject: [PATCH 08/11] jw-add tests for frontend --- frontend/src/fixtures/commonsFixtures.js | 4 +-- .../components/Commons/ManageCows.test.js | 26 +++++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/frontend/src/fixtures/commonsFixtures.js b/frontend/src/fixtures/commonsFixtures.js index 20746ec40..d8c95cd66 100644 --- a/frontend/src/fixtures/commonsFixtures.js +++ b/frontend/src/fixtures/commonsFixtures.js @@ -25,7 +25,7 @@ const commonsFixtures = { "milkPrice": 10, "degradationRate": .5, "showLeaderboard": true, - "scaleCowSalePrice": true, + "scaleCowSalePrice": false, "carryingCapacity": 123, }, { @@ -39,7 +39,7 @@ const commonsFixtures = { "milkPrice": 10, "degradationRate": .5, "showLeaderboard": true, - "scaleCowSalePrice": true, + "scaleCowSalePrice": false, "carryingCapacity": 42, } ], diff --git a/frontend/src/tests/components/Commons/ManageCows.test.js b/frontend/src/tests/components/Commons/ManageCows.test.js index fd232a7f0..92fb9e2dc 100644 --- a/frontend/src/tests/components/Commons/ManageCows.test.js +++ b/frontend/src/tests/components/Commons/ManageCows.test.js @@ -1,7 +1,7 @@ import { fireEvent, render, screen, waitFor } from "@testing-library/react"; -import ManageCows from "main/components/Commons/ManageCows"; -import userCommonsFixtures from "fixtures/userCommonsFixtures"; import commonsFixtures from "fixtures/commonsFixtures"; +import userCommonsFixtures from "fixtures/userCommonsFixtures"; +import ManageCows from "main/components/Commons/ManageCows"; describe("ManageCows tests", () => { @@ -41,4 +41,26 @@ describe("ManageCows tests", () => { }); + test("warning appears when cow sell price is scaled", async () => { + const mockBuy = jest.fn(); + const mockSell = jest.fn(); + + render( + + ); + + expect(await screen.findByText(/Note: Buying cows buys at current cow price, but selling cows sells at current cow price times the average health of cows as a percentage!/)).toBeInTheDocument(); + }); + + test("warning is hidden when cow sell price is constant", async () => { + const mockBuy = jest.fn(); + const mockSell = jest.fn(); + + render( + + ); + + expect(screen.queryByText(/Note: Buying cows buys at current cow price, but selling cows sells at current cow price times the average health of cows as a percentage!/)).not.toBeInTheDocument(); + }); + }); \ No newline at end of file From c9a49febfd412c4835c61bb6eff5ad1b3c8f9862 Mon Sep 17 00:00:00 2001 From: Jacob Woodward Date: Wed, 31 May 2023 16:12:28 -0700 Subject: [PATCH 09/11] jw-make changes requested in code review --- frontend/src/tests/pages/PlayPage.test.js | 41 ++----------------- .../controllers/UserCommonsController.java | 8 ++-- 2 files changed, 7 insertions(+), 42 deletions(-) diff --git a/frontend/src/tests/pages/PlayPage.test.js b/frontend/src/tests/pages/PlayPage.test.js index 771aba731..75938b9c4 100644 --- a/frontend/src/tests/pages/PlayPage.test.js +++ b/frontend/src/tests/pages/PlayPage.test.js @@ -1,14 +1,14 @@ import { fireEvent, render, screen, waitFor } from "@testing-library/react"; -import { QueryClient, QueryClientProvider } from "react-query"; -import { MemoryRouter } from "react-router-dom"; import axios from "axios"; import AxiosMockAdapter from "axios-mock-adapter"; +import { QueryClient, QueryClientProvider } from "react-query"; +import { MemoryRouter } from "react-router-dom"; -import PlayPage from "main/pages/PlayPage"; +import commonsFixtures from "fixtures/commonsFixtures"; import { apiCurrentUserFixtures } from "fixtures/currentUserFixtures"; import { systemInfoFixtures } from "fixtures/systemInfoFixtures"; import userCommonsFixtures from "fixtures/userCommonsFixtures"; -import commonsFixtures from "fixtures/commonsFixtures"; +import PlayPage from "main/pages/PlayPage"; jest.mock("react-router-dom", () => ({ ...jest.requireActual("react-router-dom"), @@ -76,39 +76,6 @@ describe("PlayPage tests", () => { fireEvent.click(sellAllCowsButton); await waitFor(() => expect(axiosMock.history.put.length).toBe(6)); }); - - // Not sure how to test this since I'm unable to call the onBuy and onSell functions from PlayPage -/* test("test buy and sell buttons work properly", async () => { - render( - - - - - - ); - - const buyMaxButton = screen.getByTestId("buy-max-cows-button"); - const buyTenButton = screen.getByTestId("buy-10-cows-button"); - const buyOneButton = screen.getByTestId("buy-a-cow-button"); - const sellOneButton = screen.getByTestId("sell-a-cow-button"); - const sellTenButton = screen.getByTestId("sell-10-cows-button"); - const sellAllButton = screen.getByTestId("sell-all-cows-button"); - - fireEvent.click(buyMaxButton); - await waitFor( ()=>expect(onBuy).toContain(userCommonsFixtures.oneRealUserCommons, 50)); - fireEvent.click(buyTenButton); - await waitFor( ()=>expect(onBuy).toHaveBeenCalled()); - fireEvent.click(buyOneButton); - await waitFor( ()=>expect(onBuy).toHaveBeenCalled()); - fireEvent.click(sellOneButton); - await waitFor( ()=>expect(onSell).toHaveBeenCalled()); - fireEvent.click(sellTenButton); - await waitFor( ()=>expect(onSell).toHaveBeenCalled()); - fireEvent.click(sellAllButton); - await waitFor( ()=>expect(onSell).toHaveBeenCalled()); - - }); -*/ test("Make sure that both the Announcements and Welcome Farmer components show up", async () => { render( diff --git a/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java b/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java index bab5c5f84..f30f44cb7 100644 --- a/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java +++ b/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java @@ -76,7 +76,7 @@ public UserCommons getUserCommonsById( @PutMapping("/buy") public ResponseEntity putUserCommonsByIdBuy( @ApiParam("commonsId") @RequestParam Long commonsId, - @ApiParam("numCows") @RequestParam int numCows) // Want to set 1 as the default when nothing is passed in + @ApiParam("numCows") @RequestParam int numCows) throws NotEnoughMoneyException, JsonProcessingException{ User u = getCurrentUser().getUser(); Long userId = u.getId(); @@ -104,7 +104,7 @@ public ResponseEntity putUserCommonsByIdBuy( @PutMapping("/sell") public ResponseEntity putUserCommonsByIdSell( @ApiParam("commonsId") @RequestParam Long commonsId, - @ApiParam("numCows") @RequestParam int numCows) // Want to set 1 as the default when nothing is passed in + @ApiParam("numCows") @RequestParam int numCows) throws NoCowsException, JsonProcessingException { User u = getCurrentUser().getUser(); Long userId = u.getId(); @@ -114,9 +114,7 @@ public ResponseEntity putUserCommonsByIdSell( UserCommons userCommons = userCommonsRepository.findByCommonsIdAndUserId(commonsId, userId) .orElseThrow(() -> new EntityNotFoundException(UserCommons.class, "commonsId", commonsId, "userId", userId)); - if(userCommons.getNumOfCows() >= 1){ - //Causes PITest failure and is untestable, as > and >= are functionally identical - //if (numCows > userCommons.getNumOfCows()) numCows = userCommons.getNumOfCows(); + if((userCommons.getNumOfCows()) >= 1 && (numCows >= 1)){ numCows = Math.min(numCows, userCommons.getNumOfCows()); userCommons.setTotalWealth(userCommons.getTotalWealth() + (numCows * (commons.isScaleCowSalePrice() ? (commons.getCowPrice() * (userCommons.getCowHealth()/100)) : commons.getCowPrice()))); From 50724827fb12ecb7bc2d14df62f362320ac236ed Mon Sep 17 00:00:00 2001 From: Jacob Woodward Date: Wed, 31 May 2023 16:36:28 -0700 Subject: [PATCH 10/11] jw-fix logic and add test for making sure trying to sell less than one cow works properly --- .../controllers/UserCommonsController.java | 2 +- .../UserCommonsControllerTests.java | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java b/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java index f30f44cb7..17466b891 100644 --- a/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java +++ b/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java @@ -114,7 +114,7 @@ public ResponseEntity putUserCommonsByIdSell( UserCommons userCommons = userCommonsRepository.findByCommonsIdAndUserId(commonsId, userId) .orElseThrow(() -> new EntityNotFoundException(UserCommons.class, "commonsId", commonsId, "userId", userId)); - if((userCommons.getNumOfCows()) >= 1 && (numCows >= 1)){ + if((userCommons.getNumOfCows() >= 1) || (numCows >= 1)){ numCows = Math.min(numCows, userCommons.getNumOfCows()); userCommons.setTotalWealth(userCommons.getTotalWealth() + (numCows * (commons.isScaleCowSalePrice() ? (commons.getCowPrice() * (userCommons.getCowHealth()/100)) : commons.getCowPrice()))); diff --git a/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java b/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java index 0f40248af..76667d647 100644 --- a/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java +++ b/src/test/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsControllerTests.java @@ -797,6 +797,72 @@ public void test_SellCow_commons_exists_no_cow_to_sell() throws Exception { assertEquals(expectedJson, jsonResponse); } + @WithMockUser(roles = { "USER" }) + @Test + public void test_SellCow_commons_exists_trys_to_sell_zero_cows() throws Exception { + + // arrange + UserCommons origUserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(10) + .cowHealth(100) + .build(); + + Commons testCommons = Commons + .builder() + .name("test commons") + .cowPrice(10) + .milkPrice(2) + .startingBalance(300) + .startingDate(LocalDateTime.now()) + .build(); + + UserCommons userCommonsToSend = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(10) + .cowHealth(100) + .build(); + + UserCommons correctuserCommons = UserCommons + .builder() + .id(1L) + .userId(1L) + .commonsId(1L) + .totalWealth(300) + .numOfCows(10) + .cowHealth(100) + .build(); + + String requestBody = mapper.writeValueAsString(userCommonsToSend); + String expectedReturn = mapper.writeValueAsString(correctuserCommons); + + when(userCommonsRepository.findByCommonsIdAndUserId(eq(1L), eq(1L))).thenReturn(Optional.of(origUserCommons)); + when(commonsRepository.findById(eq(1L))).thenReturn(Optional.of(testCommons)); + + // act + MvcResult response = mockMvc.perform(put("/api/usercommons/sell?commonsId=1&numCows=0") + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding("utf-8") + .content(requestBody) + .with(csrf())).andExpect(status().is(400)).andReturn(); + + + // assert + String responseString = response.getResponse().getContentAsString(); + String expectedString = "{\"message\":\"You have no cows to sell!\",\"type\":\"NoCowsException\"}"; + Map expectedJson = mapper.readValue(expectedString, Map.class); + Map jsonResponse = responseToJson(response); + assertEquals(expectedJson, jsonResponse); + } + @WithMockUser(roles = { "USER" }) @Test public void test_SellCow_commons_exists_user_sells_more_cows_than_owned() throws Exception { From 886c4fe5d1270b51050a986f1f8c9a8b8170a3cf Mon Sep 17 00:00:00 2001 From: Jacob Woodward Date: Wed, 31 May 2023 16:37:25 -0700 Subject: [PATCH 11/11] jw-fix logic that wasn't broken in the first place --- .../cs156/happiercows/controllers/UserCommonsController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java b/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java index 17466b891..1a9994a89 100644 --- a/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java +++ b/src/main/java/edu/ucsb/cs156/happiercows/controllers/UserCommonsController.java @@ -114,7 +114,7 @@ public ResponseEntity putUserCommonsByIdSell( UserCommons userCommons = userCommonsRepository.findByCommonsIdAndUserId(commonsId, userId) .orElseThrow(() -> new EntityNotFoundException(UserCommons.class, "commonsId", commonsId, "userId", userId)); - if((userCommons.getNumOfCows() >= 1) || (numCows >= 1)){ + if((userCommons.getNumOfCows() >= 1) && (numCows >= 1)){ numCows = Math.min(numCows, userCommons.getNumOfCows()); userCommons.setTotalWealth(userCommons.getTotalWealth() + (numCows * (commons.isScaleCowSalePrice() ? (commons.getCowPrice() * (userCommons.getCowHealth()/100)) : commons.getCowPrice())));