Skip to content

Commit

Permalink
clean up unbearable icks
Browse files Browse the repository at this point in the history
  • Loading branch information
mushipeas committed Oct 24, 2023
1 parent 6377010 commit eb8bcff
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 87 deletions.
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
A Spring Boot application for finding recipes. Links to bbc-goodfood recipes.

The data is loaded from a postgres database, but this could be changed by replacing the Postgres datasource driver with another one.
Data has been pre-scraped with BS4 and requires pre-populating into the database. A backup of the data can be found under db-backup.

A demo can be seen at:
https://sb-recipes.herokuapp.com/

Data has been pre-scraped with BS4 and requires pre-populating into the database. A backup of the data can be found under db-backup.

## Recommended Setup for Development:

Expand All @@ -18,5 +14,6 @@ Tests currently make use of Mockito and MockMVC modules.

## TODO:

- Update to SB3
- Add tests for Thymeleaf templates
- Full front-end testing using Selenium
- Add testContainers and sample data set for testing
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.mushipeas.springbootrecipes.dao;

import com.mushipeas.springbootrecipes.models.Recipe;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
Expand All @@ -12,9 +12,6 @@
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.mushipeas.springbootrecipes.models.Recipe;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
Expand All @@ -35,16 +32,15 @@ public Page<Recipe> fetchRecipesWhichContainInTitle(Set<String> keywords, Pageab
for (String keyword : keywords) {
predicates.add(cb.like(titlePath, "%"+keyword+"%"));
}
cq.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
cq.where(cb.and(predicates.toArray(new Predicate[0])));

TypedQuery<Recipe> query = em.createQuery(cq);

int totalRows = query.getResultList().size();
List<Recipe> result = query.setFirstResult((int) pageable.getOffset())
.setMaxResults(pageable.getPageSize()).getResultList();

Page<Recipe> resultPage = new PageImpl<>(result, pageable, totalRows);
return resultPage;
return new PageImpl<>(result, pageable, totalRows);
}

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package com.mushipeas.springbootrecipes.services;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import com.mushipeas.springbootrecipes.dao.RecipeDao;
import com.mushipeas.springbootrecipes.models.Recipe;

import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
Expand All @@ -17,25 +13,19 @@
@Service
public class RecipeService {

// @Autowired
// private RecipeDao recipeDao;

private final RecipeDao recipeDao;

@Autowired
public RecipeService(RecipeDao recipeDao) {
this.recipeDao = recipeDao;
}

public Page<Recipe> getAllRecipesWhichContainKeywords(String keywords, Integer pageNo, Integer pageSize, String sortBy)
{
public Page<Recipe> getAllRecipesWhichContainKeywords(String keywords, Integer pageNo, Integer pageSize, String sortBy) {
Pageable paging = PageRequest.of(pageNo, pageSize, Sort.by(sortBy));

Set<String> keywordSet = new HashSet<String>(Arrays.asList(keywords.split(" ")));

Page<Recipe> pagedResult = recipeDao.fetchRecipesWhichContainInTitle(keywordSet, paging);

return pagedResult;
Set<String> keywordSet = Set.of(keywords.split(" "));

return recipeDao.fetchRecipesWhichContainInTitle(keywordSet, paging);
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
package com.mushipeas.springbootrecipes;
package com.mushipeas.springbootrecipes.controllers;

import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;

@SpringBootTest
@AutoConfigureMockMvc
public class WebApplicationIndexPageTest {
class WebApplicationIndexPageTest {

@Autowired
private MockMvc mockMvc;

@Test
public void shouldReturnSearchPage() throws Exception {
this.mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("Search for a recipe..")));
void baseUrl_shouldReturnSearchPage() throws Exception {
mockMvc.perform(get("/"))
.andExpectAll(status().isOk(), content().string(containsString("Search for a recipe..")));
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package com.mushipeas.springbootrecipes;
package com.mushipeas.springbootrecipes.dao;

import com.mushipeas.springbootrecipes.models.Recipe;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.mushipeas.springbootrecipes.dao.RecipeDao;
import com.mushipeas.springbootrecipes.models.Recipe;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -22,58 +19,54 @@

@ExtendWith(SpringExtension.class)
@DataJpaTest
public class RecipeDaoTest {
class RecipeDaoTest {

@Autowired private RecipeDao recipeDao;
private final Recipe recipe1 = new Recipe(1, "test", "beef and broccoli stew", 1, "", "", "", "", "");
private final Recipe recipe2 = new Recipe(2, "test", "beef steak with broccoli cheese", 1, "", "", "", "", "");
private final Recipe recipe3 = new Recipe(3, "test", "chicken steak", 1, "", "", "", "", "");
private final List<Recipe> allRecipes = List.of(recipe1, recipe2, recipe3);

private Recipe recipe1 = new Recipe(1, "test", "beef and broccoli stew", 1, "", "", "", "", "");
private Recipe recipe2 = new Recipe(2, "test", "beef steak with broccoli cheese", 1, "", "", "", "", "");
private Recipe recipe3 = new Recipe(3, "test", "chicken steak", 1, "", "", "", "", "");
private List<Recipe> allRecipes = List.of(recipe1, recipe2, recipe3);
@Autowired private RecipeDao recipeDao;

@BeforeEach
void setup(){
recipeDao.saveAll(allRecipes);
}

@Test
void injectedComponentsAreNotNull(){
Assertions.assertThat(recipeDao).isNotNull();
}

@Test
public void givenKeywordsReturnRecipesWithTitlesContainingKeywords() {
void fetchRecipesWhichContainInTitle_givenKeywords_returnsCorrectRecipes() {
List<Recipe> expectedRecipes = List.of(recipe1, recipe2);

Pageable paging = PageRequest.of(0, 20, Sort.by("title"));
// when

Set<String> recipes1and2ButNot3 = Set.of("beef", "broccoli");
Page<Recipe> returnedRecipes = recipeDao.fetchRecipesWhichContainInTitle(recipes1and2ButNot3, paging);
// then

Assertions.assertThat(returnedRecipes.getContent())
.hasSize(expectedRecipes.size())
.extracting(Recipe::getTitle)
.hasSameElementsAs(expectedRecipes.stream()
.map(recipe -> recipe.getTitle())
.collect(Collectors.toList()));

// .containsExactlyInAnyOrder(recipe1.getTitle(), recipe2.getTitle());
.map(Recipe::getTitle)
.collect(Collectors.toList()));
}

@Test
public void givenNoKeywordsReturnAllRecipes() {
void fetchRecipesWhichContainInTitle_givenNoKeywords_returnAllRecipes() {
List<Recipe> expectedRecipes = new ArrayList<>(allRecipes);;

Pageable paging = PageRequest.of(0, 20, Sort.by("title"));
// when

Set<String> recipes1and2ButNot3 = Set.of("");
Page<Recipe> returnedRecipes = recipeDao.fetchRecipesWhichContainInTitle(recipes1and2ButNot3, paging);
// then

Assertions.assertThat(returnedRecipes.getContent())
.hasSize(expectedRecipes.size())
.extracting(Recipe::getTitle)
.hasSameElementsAs(expectedRecipes.stream()
.map(recipe -> recipe.getTitle())
.collect(Collectors.toList()));
.map(Recipe::getTitle)
.collect(Collectors.toList()));
}
}
Original file line number Diff line number Diff line change
@@ -1,47 +1,40 @@
package com.mushipeas.springbootrecipes;
package com.mushipeas.springbootrecipes.services;

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import com.mushipeas.springbootrecipes.dao.RecipeDao;
import com.mushipeas.springbootrecipes.services.RecipeService;

import org.junit.jupiter.api.BeforeEach;
import java.util.Set;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

@ExtendWith(MockitoExtension.class)
public class RecipeServiceTest {
class RecipeServiceTest {

@Mock private RecipeDao recipeDao;
private RecipeService underTest;
@Mock
private RecipeDao recipeDao;

@BeforeEach
void setUp() {
underTest = new RecipeService(recipeDao);
}
@InjectMocks
private RecipeService underTest;

@Test
public void itShouldModifyKeywordsIntoASetAndPassPaginationRequestAsPageable() {
void getAllRecipesWhichContainKeywords_shouldFetchFromRecipeDaoWithCorrectPagination() {
String keywords = "test words";
Integer pageNo = 1;
Integer pageSize = 21;
int pageNo = 1;
int pageSize = 21;
String sortBy = "title";
// when

underTest.getAllRecipesWhichContainKeywords(keywords, pageNo, pageSize, sortBy);

Pageable expectedPageable = PageRequest.of(pageNo, pageSize, Sort.by(sortBy));
Set<String> expectedKeywordSet = new HashSet<String>(Arrays.asList("test words".split(" ")));
// then
Set<String> expectedKeywordSet = Set.of("test words".split(" "));

verify(recipeDao).fetchRecipesWhichContainInTitle(expectedKeywordSet, expectedPageable);
verifyNoMoreInteractions(recipeDao);
}
Expand Down

0 comments on commit eb8bcff

Please sign in to comment.