Skip to content

Commit

Permalink
Add Unit Tests for DeleteBook Handler
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel-Giurgiu committed Oct 3, 2024
1 parent 87508f8 commit 53de437
Show file tree
Hide file tree
Showing 2 changed files with 262 additions and 16 deletions.
32 changes: 16 additions & 16 deletions api/coverage.out
Original file line number Diff line number Diff line change
Expand Up @@ -315,22 +315,22 @@ mymodule/main.go:1186.16,1189.3 2 1
mymodule/main.go:1191.2,1191.65 1 1
mymodule/main.go:1191.65,1194.3 2 1
mymodule/main.go:1196.2,1196.48 1 1
mymodule/main.go:1200.68,1201.35 1 0
mymodule/main.go:1201.35,1204.3 2 0
mymodule/main.go:1206.2,1207.16 2 0
mymodule/main.go:1207.16,1210.3 2 0
mymodule/main.go:1212.2,1214.16 3 0
mymodule/main.go:1214.16,1218.3 3 0
mymodule/main.go:1220.2,1222.16 3 0
mymodule/main.go:1222.16,1226.3 3 0
mymodule/main.go:1228.2,1229.16 2 0
mymodule/main.go:1229.16,1233.3 3 0
mymodule/main.go:1235.2,1236.23 2 0
mymodule/main.go:1236.23,1239.3 2 0
mymodule/main.go:1241.2,1241.24 1 0
mymodule/main.go:1241.24,1243.17 2 0
mymodule/main.go:1243.17,1247.4 3 0
mymodule/main.go:1250.2,1250.46 1 0
mymodule/main.go:1200.68,1201.35 1 1
mymodule/main.go:1201.35,1204.3 2 1
mymodule/main.go:1206.2,1207.16 2 1
mymodule/main.go:1207.16,1210.3 2 1
mymodule/main.go:1212.2,1214.16 3 1
mymodule/main.go:1214.16,1218.3 3 1
mymodule/main.go:1220.2,1222.16 3 1
mymodule/main.go:1222.16,1226.3 3 1
mymodule/main.go:1228.2,1229.16 2 1
mymodule/main.go:1229.16,1233.3 3 1
mymodule/main.go:1235.2,1236.23 2 1
mymodule/main.go:1236.23,1239.3 2 1
mymodule/main.go:1241.2,1241.24 1 1
mymodule/main.go:1241.24,1243.17 2 1
mymodule/main.go:1243.17,1247.4 3 1
mymodule/main.go:1250.2,1250.46 1 1
mymodule/main.go:1254.74,1255.35 1 0
mymodule/main.go:1255.35,1258.3 2 0
mymodule/main.go:1260.2,1261.16 2 0
Expand Down
246 changes: 246 additions & 0 deletions api/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3600,6 +3600,252 @@ func TestDeleteAuthor_MethodNotAllowed(t *testing.T) {
assert.Contains(t, rr.Body.String(), "Only DELETE method is supported")
}

// Tests for DeleteBook handler
func TestDeleteBook_Success(t *testing.T) {
app, mock := createTestApp(t)
defer app.DB.Close()

req := httptest.NewRequest("DELETE", "/books/1", nil)
vars := map[string]string{"id": "1"}
req = mux.SetURLVars(req, vars)
rr := httptest.NewRecorder()

mock.ExpectQuery(regexp.QuoteMeta(`SELECT author_id FROM books WHERE id = ?`)).
WithArgs(1).
WillReturnRows(sqlmock.NewRows([]string{"author_id"}).AddRow(1))

mock.ExpectQuery(regexp.QuoteMeta(`SELECT COUNT(*) FROM books WHERE author_id = ? AND id != ?`)).
WithArgs(1, 1).
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1))

mock.ExpectExec(regexp.QuoteMeta(`DELETE FROM books WHERE id = ?`)).
WithArgs(1).
WillReturnResult(sqlmock.NewResult(1, 1))

handler := http.HandlerFunc(app.DeleteBook)
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusOK, rr.Code)
assert.Contains(t, rr.Body.String(), "Book deleted successfully")

err := mock.ExpectationsWereMet()
assert.NoError(t, err)
}

func TestDeleteBook_InvalidBookID(t *testing.T) {
app, _ := createTestApp(t)
defer app.DB.Close()

req := httptest.NewRequest("DELETE", "/books/invalid", nil)
vars := map[string]string{"id": "invalid"}
req = mux.SetURLVars(req, vars)
rr := httptest.NewRecorder()

handler := http.HandlerFunc(app.DeleteBook)
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusBadRequest, rr.Code)
assert.Contains(t, rr.Body.String(), "Invalid book ID")
}

func TestDeleteBook_DBErrorRetrievingAuthorID(t *testing.T) {
app, mock := createTestApp(t)
defer app.DB.Close()

req := httptest.NewRequest("DELETE", "/books/1", nil)
vars := map[string]string{"id": "1"}
req = mux.SetURLVars(req, vars)
rr := httptest.NewRecorder()

mock.ExpectQuery(regexp.QuoteMeta(`SELECT author_id FROM books WHERE id = ?`)).
WithArgs(1).
WillReturnError(fmt.Errorf("DB error"))

handler := http.HandlerFunc(app.DeleteBook)
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusInternalServerError, rr.Code)
assert.Contains(t, rr.Body.String(), "Failed to retrieve author ID")

err := mock.ExpectationsWereMet()
assert.NoError(t, err)
}

func TestDeleteBook_DBErrorCheckingOtherBooks(t *testing.T) {
app, mock := createTestApp(t)
defer app.DB.Close()

req := httptest.NewRequest("DELETE", "/books/1", nil)
vars := map[string]string{"id": "1"}
req = mux.SetURLVars(req, vars)
rr := httptest.NewRecorder()

mock.ExpectQuery(regexp.QuoteMeta(`SELECT author_id FROM books WHERE id = ?`)).
WithArgs(1).
WillReturnRows(sqlmock.NewRows([]string{"author_id"}).AddRow(1))

mock.ExpectQuery(regexp.QuoteMeta(`SELECT COUNT(*) FROM books WHERE author_id = ? AND id != ?`)).
WithArgs(1, 1).
WillReturnError(fmt.Errorf("DB error"))

handler := http.HandlerFunc(app.DeleteBook)
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusInternalServerError, rr.Code)
assert.Contains(t, rr.Body.String(), "Failed to check for other books")

err := mock.ExpectationsWereMet()
assert.NoError(t, err)
}

func TestDeleteBook_NotFound(t *testing.T) {
app, mock := createTestApp(t)
defer app.DB.Close()

req := httptest.NewRequest("DELETE", "/books/1", nil)
vars := map[string]string{"id": "1"}
req = mux.SetURLVars(req, vars)
rr := httptest.NewRecorder()

mock.ExpectQuery(regexp.QuoteMeta(`SELECT author_id FROM books WHERE id = ?`)).
WithArgs(1).
WillReturnRows(sqlmock.NewRows([]string{"author_id"}).AddRow(1))

mock.ExpectQuery(regexp.QuoteMeta(`SELECT COUNT(*) FROM books WHERE author_id = ? AND id != ?`)).
WithArgs(1, 1).
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(0))

mock.ExpectExec(regexp.QuoteMeta(`DELETE FROM books WHERE id = ?`)).
WithArgs(1).
WillReturnResult(sqlmock.NewResult(1, 0))

handler := http.HandlerFunc(app.DeleteBook)
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusNotFound, rr.Code)
assert.Contains(t, rr.Body.String(), "Book not found")

err := mock.ExpectationsWereMet()
assert.NoError(t, err)
}

func TestDeleteBook_DBErrorDeletingBook(t *testing.T) {
app, mock := createTestApp(t)
defer app.DB.Close()

req := httptest.NewRequest("DELETE", "/books/1", nil)
vars := map[string]string{"id": "1"}
req = mux.SetURLVars(req, vars)
rr := httptest.NewRecorder()

mock.ExpectQuery(regexp.QuoteMeta(`SELECT author_id FROM books WHERE id = ?`)).
WithArgs(1).
WillReturnRows(sqlmock.NewRows([]string{"author_id"}).AddRow(1))

mock.ExpectQuery(regexp.QuoteMeta(`SELECT COUNT(*) FROM books WHERE author_id = ? AND id != ?`)).
WithArgs(1, 1).
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(0))

mock.ExpectExec(regexp.QuoteMeta(`DELETE FROM books WHERE id = ?`)).
WithArgs(1).
WillReturnError(fmt.Errorf("DB error"))

handler := http.HandlerFunc(app.DeleteBook)
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusInternalServerError, rr.Code)
assert.Contains(t, rr.Body.String(), "Failed to delete book")

err := mock.ExpectationsWereMet()
assert.NoError(t, err)
}

func TestDeleteBook_DeleteAuthorWhenNoOtherBooks(t *testing.T) {
app, mock := createTestApp(t)
defer app.DB.Close()

req := httptest.NewRequest("DELETE", "/books/1", nil)
vars := map[string]string{"id": "1"}
req = mux.SetURLVars(req, vars)
rr := httptest.NewRecorder()

mock.ExpectQuery(regexp.QuoteMeta(`SELECT author_id FROM books WHERE id = ?`)).
WithArgs(1).
WillReturnRows(sqlmock.NewRows([]string{"author_id"}).AddRow(1))

mock.ExpectQuery(regexp.QuoteMeta(`SELECT COUNT(*) FROM books WHERE author_id = ? AND id != ?`)).
WithArgs(1, 1).
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(0))

mock.ExpectExec(regexp.QuoteMeta(`DELETE FROM books WHERE id = ?`)).
WithArgs(1).
WillReturnResult(sqlmock.NewResult(1, 1))

mock.ExpectExec(regexp.QuoteMeta(`DELETE FROM authors WHERE id = ?`)).
WithArgs(1).
WillReturnResult(sqlmock.NewResult(1, 1))

handler := http.HandlerFunc(app.DeleteBook)
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusOK, rr.Code)
assert.Contains(t, rr.Body.String(), "Book deleted successfully")

err := mock.ExpectationsWereMet()
assert.NoError(t, err)
}

func TestDeleteBook_MethodNotAllowed(t *testing.T) {
app, _ := createTestApp(t)
defer app.DB.Close()

req := httptest.NewRequest("GET", "/books/1", nil)
vars := map[string]string{"id": "1"}
req = mux.SetURLVars(req, vars)
rr := httptest.NewRecorder()

handler := http.HandlerFunc(app.DeleteBook)
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusMethodNotAllowed, rr.Code)
assert.Contains(t, rr.Body.String(), "Only DELETE method is supported")
}

func TestDeleteBook_FailedToDeleteAuthor(t *testing.T) {
app, mock := createTestApp(t)
defer app.DB.Close()

req := httptest.NewRequest("DELETE", "/books/1", nil)
vars := map[string]string{"id": "1"}
req = mux.SetURLVars(req, vars)
rr := httptest.NewRecorder()

mock.ExpectQuery(regexp.QuoteMeta(`SELECT author_id FROM books WHERE id = ?`)).
WithArgs(1).
WillReturnRows(sqlmock.NewRows([]string{"author_id"}).AddRow(1))

mock.ExpectQuery(regexp.QuoteMeta(`SELECT COUNT(*) FROM books WHERE author_id = ? AND id != ?`)).
WithArgs(1, 1).
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(0))

mock.ExpectExec(regexp.QuoteMeta(`DELETE FROM books WHERE id = ?`)).
WithArgs(1).
WillReturnResult(sqlmock.NewResult(1, 1))

mock.ExpectExec(regexp.QuoteMeta(`DELETE FROM authors WHERE id = ?`)).
WithArgs(1).
WillReturnError(fmt.Errorf("DB error"))

handler := http.HandlerFunc(app.DeleteBook)
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusInternalServerError, rr.Code)
assert.Contains(t, rr.Body.String(), "Failed to delete author")

err := mock.ExpectationsWereMet()
assert.NoError(t, err)
}




0 comments on commit 53de437

Please sign in to comment.