diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/pom.xml index 824e17e59c..b6060282d2 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/pom.xml @@ -22,6 +22,7 @@ UTF-8 UTF-8 1.8 + 3.0.1 @@ -51,6 +52,12 @@ spring-boot-starter-test test + + io.rest-assured + rest-assured + ${rest-assured.version} + + diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/persistence/dao/BookRepository.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/persistence/dao/BookRepository.java index 419c735d63..1b0c32218f 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/persistence/dao/BookRepository.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/persistence/dao/BookRepository.java @@ -1,10 +1,13 @@ package org.baeldung.persistence.dao; import org.baeldung.persistence.model.Book; -import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; import org.springframework.data.rest.core.annotation.RepositoryRestResource; @RepositoryRestResource(collectionResourceRel = "books", path = "books") -public interface BookRepository extends JpaRepository { - +public interface BookRepository extends CrudRepository { + Page findByTitle(@Param("title") String title, Pageable pageable); } diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/persistence/model/Book.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/persistence/model/Book.java index 69d217b096..80336d9da9 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/persistence/model/Book.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/persistence/model/Book.java @@ -12,12 +12,9 @@ public class Book { @GeneratedValue(strategy = GenerationType.AUTO) private long id; - @Column(nullable = false) + @Column(nullable = false, unique = true) private String title; - @Column(nullable = false) - private String isbn; - @Column(nullable = false) private String author; @@ -27,10 +24,9 @@ public class Book { super(); } - public Book(String title, String isbn, String author) { + public Book(String title, String author) { super(); this.title = title; - this.isbn = isbn; this.author = author; } @@ -52,14 +48,6 @@ public class Book { this.title = title; } - public String getIsbn() { - return isbn; - } - - public void setIsbn(String isbn) { - this.isbn = isbn; - } - public String getAuthor() { return author; } @@ -76,7 +64,6 @@ public class Book { int result = 1; result = (prime * result) + ((author == null) ? 0 : author.hashCode()); result = (prime * result) + (int) (id ^ (id >>> 32)); - result = (prime * result) + ((isbn == null) ? 0 : isbn.hashCode()); result = (prime * result) + ((title == null) ? 0 : title.hashCode()); return result; } @@ -103,13 +90,7 @@ public class Book { if (id != other.id) { return false; } - if (isbn == null) { - if (other.isbn != null) { - return false; - } - } else if (!isbn.equals(other.isbn)) { - return false; - } + if (title == null) { if (other.title != null) { return false; @@ -127,8 +108,6 @@ public class Book { .append(id) .append(", title=") .append(title) - .append(", isbn=") - .append(isbn) .append(", author=") .append(author) .append("]"); diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/java/org/baeldung/RestApiLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/java/org/baeldung/RestApiLiveTest.java new file mode 100644 index 0000000000..450df4ccf7 --- /dev/null +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/java/org/baeldung/RestApiLiveTest.java @@ -0,0 +1,166 @@ +package org.baeldung; + +import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; +import static org.apache.commons.lang3.RandomStringUtils.randomNumeric; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.restassured.RestAssured; +import io.restassured.response.Response; + +import org.baeldung.persistence.model.Book; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { SpringCloudRestClientApplication.class }, webEnvironment = WebEnvironment.DEFINED_PORT) +public class RestApiLiveTest { + + private static final String API_URI = "http://localhost:8084/books"; + + // GET + + @Test + public void whenGetAllBooks_thenOK() { + final Response response = RestAssured.get(API_URI); + assertEquals(HttpStatus.OK.value(), response.getStatusCode()); + } + + @Test + public void whenGetCreatedBookById_thenOK() { + final Book book = createRandomBook(); + final String location = createBookAsUri(book); + + final Response response = RestAssured.get(location); + assertEquals(HttpStatus.OK.value(), response.getStatusCode()); + assertEquals(book.getTitle(), response.jsonPath() + .get("title")); + } + + @Test + public void whenGetCreatedBookByName_thenOK() { + final Book book = createRandomBook(); + createBookAsUri(book); + + final Response response = RestAssured.get(API_URI + "/search/findByTitle?title=" + book.getTitle()); + assertEquals(HttpStatus.OK.value(), response.getStatusCode()); + assertTrue(response.jsonPath() + .getLong("page.totalElements") > 0); + } + + @Test + public void whenGetNotExistBookById_thenNotFound() { + final Response response = RestAssured.get(API_URI + "/" + randomNumeric(4)); + assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatusCode()); + } + + @Test + public void whenGetNotExistBookByName_thenNotFound() { + final Response response = RestAssured.get(API_URI + "/search/findByTitle?title=" + randomAlphabetic(20)); + assertEquals(HttpStatus.OK.value(), response.getStatusCode()); + assertTrue(response.jsonPath() + .getLong("page.totalElements") == 0); + } + + // POST + @Test + public void whenCreateNewBook_thenCreated() { + final Book book = createRandomBook(); + + final Response response = RestAssured.given() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(book) + .post(API_URI); + assertEquals(HttpStatus.CREATED.value(), response.getStatusCode()); + } + + @Test + public void whenCreateDuplicateBook_thenError() { + final Book book = createRandomBook(); + createBookAsUri(book); + + // duplicate + final Response response = RestAssured.given() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(book) + .post(API_URI); + assertEquals(HttpStatus.CONFLICT.value(), response.getStatusCode()); + } + + @Test + public void whenInvalidBook_thenError() { + final Book book = createRandomBook(); + book.setAuthor(null); + + final Response response = RestAssured.given() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(book) + .post(API_URI); + assertEquals(HttpStatus.CONFLICT.value(), response.getStatusCode()); + } + + @Test + public void whenUpdateCreatedBook_thenUpdated() { + // create + final Book book = createRandomBook(); + final String location = createBookAsUri(book); + + // update + book.setAuthor("newAuthor"); + Response response = RestAssured.given() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(book) + .put(location); + assertEquals(HttpStatus.OK.value(), response.getStatusCode()); + + // check if changes saved + response = RestAssured.get(location); + assertEquals(HttpStatus.OK.value(), response.getStatusCode()); + assertEquals("newAuthor", response.jsonPath() + .get("author")); + + } + + @Test + public void whenDeleteCreatedBook_thenOk() { + // create + final Book book = createRandomBook(); + final String location = createBookAsUri(book); + + // delete + Response response = RestAssured.delete(location); + assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatusCode()); + + // confirm it was deleted + response = RestAssured.get(location); + assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatusCode()); + } + + @Test + public void whenDeleteNotExistBook_thenError() { + final Response response = RestAssured.delete(API_URI + "/" + randomNumeric(4)); + assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatusCode()); + } + + // =============================== Util + + public Book createRandomBook() { + final Book book = new Book(); + book.setTitle(randomAlphabetic(10)); + book.setAuthor(randomAlphabetic(15)); + return book; + } + + public String createBookAsUri(Book book) { + final Response response = RestAssured.given() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(book) + .post(API_URI); + return response.jsonPath() + .get("_links.self.href"); + } +} diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/resources/application.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/resources/application.properties new file mode 100644 index 0000000000..c68aa7dc55 --- /dev/null +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/resources/application.properties @@ -0,0 +1,9 @@ +spring.application.name=spring-cloud-eureka-client +server.port=8084 +eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://localhost:8761/eureka} +eureka.instance.preferIpAddress=true + +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.url=jdbc:h2:mem:cloud_rest;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE +spring.datasource.username=sa +spring.datasource.password= \ No newline at end of file