### Question:
HotelSummaryRepository { public Page<HotelSummary> findByCity(City city, Pageable pageable) { StringBuilder queryString = new StringBuilder(FIND_BY_CITY_QUERY); applySorting(queryString, pageable == null ? null : pageable.getSort()); Query query = entityManager.createQuery(queryString.toString()); query.setParameter(1, city); query.setFirstResult(pageable.getOffset()); query.setMaxResults(pageable.getPageSize()); Query countQuery = entityManager.createQuery(FIND_BY_CITY_COUNT_QUERY); countQuery.setParameter(1, city); @SuppressWarnings("unchecked") List<HotelSummary> content = query.getResultList(); Long total = (Long) countQuery.getSingleResult(); return new PageImpl<HotelSummary>(content, pageable, total); }  Page<HotelSummary> findByCity(City city, Pageable pageable); @SuppressWarnings("unchecked") List<RatingCount> findRatingCounts(Hotel hotel); @PersistenceContext void setEntityManager(EntityManager entityManager);  }### Answer:
@Test public void shouldFindAverage() throws Exception { this.pageable = new PageRequest(0, 10, new Sort(Direction.ASC, "name")); Page<HotelSummary> hotels = this.hotelSummaryRepository.findByCity(this.bath, this.pageable); assertThat(hotels.getTotalElements(), is(2L)); assertThat(hotels.getContent().get(0).getName(), is("Bath Travelodge")); double expected = (0 + 0 + 1 + 0 + 1 + 0 + 0 + 0 + 1 + 1 + 0 + 1 + 2 + 3) / 14.0; expected = new BigDecimal(expected, new MathContext(2)).doubleValue(); assertThat(hotels.getContent().get(0).getAverageRating(), is(expected)); assertThat(hotels.getContent().get(0).getAverageRatingRounded(), is((int) Math.round(expected))); }
@Test public void shouldFindHotelsWithoutReview() throws Exception { Page<HotelSummary> hotels = this.hotelSummaryRepository.findByCity(this.tokyo, this.pageable); assertThat(hotels.getTotalElements(), is(1L)); assertThat(hotels.getContent().get(0).getAverageRating(), is(nullValue())); }
@Test public void shouldSortByRatingAsc() throws Exception { this.pageable = new PageRequest(0, 100, new Sort(Direction.ASC, "averageRating")); Page<HotelSummary> page = this.hotelSummaryRepository.findByCity(this.bath, this.pageable); double rating = page.getContent().get(0).getAverageRating(); for (HotelSummary hotelSummary : page) { assertThat(hotelSummary.getAverageRating(), is(greaterThanOrEqualTo(rating))); } }
@Test public void shouldSortByRatingDesc() throws Exception { this.pageable = new PageRequest(0, 100, new Sort(Direction.DESC, "averageRating")); Page<HotelSummary> page = this.hotelSummaryRepository.findByCity(this.bath, this.pageable); double rating = page.getContent().get(0).getAverageRating(); for (HotelSummary hotelSummary : page) { assertThat(hotelSummary.getAverageRating(), is(lessThanOrEqualTo(rating))); } }
@Test public void shouldSortByHotelName() throws Exception { this.pageable = new PageRequest(0, 100, new Sort(Direction.ASC, "name")); Page<HotelSummary> page = this.hotelSummaryRepository.findByCity(this.bath, this.pageable); List<String> names = new ArrayList<String>(); for (HotelSummary summary : page) { names.add(summary.getName()); } String hotels = StringUtils.collectionToCommaDelimitedString(names); assertThat(hotels, is(equalTo("Bath Travelodge,The Bath Priory Hotel"))); }