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