Refactor: make only one API route to update userbooks
This commit is contained in:
@@ -99,35 +99,35 @@ export async function postImportBook(id, language) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function putReadBook(bookId) {
|
export async function putReadBook(bookId) {
|
||||||
return genericPayloadCall('/ws/book/' + bookId + '/read', { read: true }, 'PUT')
|
return genericPayloadCall('/ws/book/' + bookId, { read: true }, 'PUT')
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function putUnreadBook(bookId) {
|
export async function putUnreadBook(bookId) {
|
||||||
return genericPayloadCall('/ws/book/' + bookId + '/read', { read: false }, 'PUT')
|
return genericPayloadCall('/ws/book/' + bookId, { read: false }, 'PUT')
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function putEndReadDate(bookId, enddate) {
|
export async function putEndReadDate(bookId, enddate) {
|
||||||
return genericPayloadCall('/ws/book/' + bookId + '/read', { read: true, endDate: enddate }, 'PUT')
|
return genericPayloadCall('/ws/book/' + bookId, { read: true, endDate: enddate }, 'PUT')
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function putEndReadDateUnset(bookId) {
|
export async function putEndReadDateUnset(bookId) {
|
||||||
return genericPayloadCall('/ws/book/' + bookId + '/read', { read: true, endDate: 'null' }, 'PUT')
|
return genericPayloadCall('/ws/book/' + bookId, { read: true, endDate: 'null' }, 'PUT')
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function putStartReadDateUnset(bookId) {
|
export async function putStartReadDateUnset(bookId) {
|
||||||
return genericPayloadCall('/ws/book/' + bookId + '/startread', { startDate: 'null' }, 'PUT')
|
return genericPayloadCall('/ws/book/' + bookId, { startDate: 'null' }, 'PUT')
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function putStartReadDate(bookId, startdate) {
|
export async function putStartReadDate(bookId, startdate) {
|
||||||
return genericPayloadCall('/ws/book/' + bookId + '/startread', { startDate: startdate }, 'PUT')
|
return genericPayloadCall('/ws/book/' + bookId, { startDate: startdate }, 'PUT')
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function putWantReadBook(bookId, payload) {
|
export async function putWantReadBook(bookId, payload) {
|
||||||
return genericPayloadCall('/ws/book/' + bookId + '/wantread', payload, 'PUT')
|
return genericPayloadCall('/ws/book/' + bookId, payload, 'PUT')
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function putRateBook(bookId, payload) {
|
export async function putRateBook(bookId, payload) {
|
||||||
return genericPayloadCall('/ws/book/' + bookId + '/rate', payload, 'PUT')
|
return genericPayloadCall('/ws/book/' + bookId, payload, 'PUT')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function postLogin(user) {
|
export function postLogin(user) {
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
package apitest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.artlef.fr/bibliomane/internal/testutils"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPutRatingUserBooksHandler_UpdateRating(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"rating": 5
|
|
||||||
}`
|
|
||||||
bookId := "17"
|
|
||||||
testPutRateUserBooks(t, payload, bookId, http.StatusOK)
|
|
||||||
book := testGetBook(t, bookId, http.StatusOK)
|
|
||||||
assert.Equal(t, 5, book.Rating)
|
|
||||||
assert.Equal(t, true, book.Read)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutRatingUserBooksHandler_RateNewBookMakeItRead(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"rating": 7
|
|
||||||
}`
|
|
||||||
bookId := "18"
|
|
||||||
testPutRateUserBooks(t, payload, bookId, http.StatusOK)
|
|
||||||
book := testGetBook(t, bookId, http.StatusOK)
|
|
||||||
assert.Equal(t, 7, book.Rating)
|
|
||||||
assert.Equal(t, true, book.Read)
|
|
||||||
assert.Equal(t, false, book.WantRead)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutRatingUserBooksHandler_RateWantedBook(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"rating": 6
|
|
||||||
}`
|
|
||||||
bookId := "2"
|
|
||||||
testPutRateUserBooks(t, payload, bookId, http.StatusOK)
|
|
||||||
book := testGetBook(t, bookId, http.StatusOK)
|
|
||||||
assert.Equal(t, 6, book.Rating)
|
|
||||||
assert.Equal(t, true, book.Read)
|
|
||||||
assert.Equal(t, false, book.WantRead)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutRatingUserBooksHandler_RatingTypeWrong(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"rating": "bad"
|
|
||||||
}`
|
|
||||||
bookId := "18"
|
|
||||||
testPutRateUserBooks(t, payload, bookId, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutRatingUserBooksHandler_RatingMin(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"rating": -3
|
|
||||||
}`
|
|
||||||
bookId := "18"
|
|
||||||
testPutRateUserBooks(t, payload, bookId, http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutRatingUserBooksHandler_RatingMax(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"rating": 15
|
|
||||||
}`
|
|
||||||
bookId := "18"
|
|
||||||
testPutRateUserBooks(t, payload, bookId, http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutRatingUserBooksHandler_BadBookId(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"rating": 15
|
|
||||||
}`
|
|
||||||
bookId := "18574"
|
|
||||||
testPutRateUserBooks(t, payload, bookId, http.StatusNotFound)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testPutRateUserBooks(t *testing.T, payload string, bookId string, expectedCode int) {
|
|
||||||
testutils.TestBookPutCallWithDemoPayload(t, payload, bookId, expectedCode, "/ws/book/"+bookId+"/rate")
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package apitest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.artlef.fr/bibliomane/internal/testutils"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPutReadUserBooks_NewReadOk(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"read": true
|
|
||||||
}`
|
|
||||||
bookId := "21"
|
|
||||||
testPutReadUserBooks(t, payload, bookId, http.StatusOK)
|
|
||||||
book := testGetBook(t, bookId, http.StatusOK)
|
|
||||||
assert.Equal(t, true, book.Read)
|
|
||||||
assert.Equal(t, false, book.WantRead)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutReadUserBooks_NewReadDateOk(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"read": true,
|
|
||||||
"endDate": "2025-10-20"
|
|
||||||
}`
|
|
||||||
bookId := "9"
|
|
||||||
testPutReadUserBooks(t, payload, bookId, http.StatusOK)
|
|
||||||
book := testGetBook(t, bookId, http.StatusOK)
|
|
||||||
assert.Equal(t, true, book.Read)
|
|
||||||
assert.Equal(t, "2025-10-20", book.EndReadDate)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutReadUserBooks_UnsetEndDate(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"read": true,
|
|
||||||
"endDate": "null"
|
|
||||||
}`
|
|
||||||
bookId := "9"
|
|
||||||
testPutReadUserBooks(t, payload, bookId, http.StatusOK)
|
|
||||||
book := testGetBook(t, bookId, http.StatusOK)
|
|
||||||
assert.Equal(t, true, book.Read)
|
|
||||||
assert.Equal(t, "", book.EndReadDate)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutReadUserBooks_UnsetReadOk(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"read": false
|
|
||||||
}`
|
|
||||||
bookId := "9"
|
|
||||||
testPutReadUserBooks(t, payload, bookId, http.StatusOK)
|
|
||||||
book := testGetBook(t, bookId, http.StatusOK)
|
|
||||||
assert.Equal(t, false, book.Read)
|
|
||||||
assert.Equal(t, "", book.EndReadDate)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testPutReadUserBooks(t *testing.T, payload string, bookId string, expectedCode int) {
|
|
||||||
testutils.TestBookPutCallWithDemoPayload(t, payload, bookId, expectedCode, "/ws/book/"+bookId+"/read")
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
package apitest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.artlef.fr/bibliomane/internal/testutils"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPutStartReadUserBooks_NoDate(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"date": "2025-11-19"
|
|
||||||
}`
|
|
||||||
bookId := "6"
|
|
||||||
testPutStartReadUserBooks(t, payload, bookId, http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutStartReadUserBooks_WrongDateFormat(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"startDate": "19/11/2025"
|
|
||||||
}`
|
|
||||||
bookId := "6"
|
|
||||||
testPutStartReadUserBooks(t, payload, bookId, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutStartReadUserBooks_NewReadOk(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"startDate": "2025-11-19"
|
|
||||||
}`
|
|
||||||
bookId := "6"
|
|
||||||
testPutStartReadUserBooks(t, payload, bookId, http.StatusOK)
|
|
||||||
book := testGetBook(t, bookId, http.StatusOK)
|
|
||||||
assert.Equal(t, "2025-11-19", book.StartReadDate)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutStartReadUserBooks_Unset(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"startDate": "null"
|
|
||||||
}`
|
|
||||||
bookId := "6"
|
|
||||||
testPutStartReadUserBooks(t, payload, bookId, http.StatusOK)
|
|
||||||
book := testGetBook(t, bookId, http.StatusOK)
|
|
||||||
assert.Equal(t, "", book.StartReadDate)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testPutStartReadUserBooks(t *testing.T, payload string, bookId string, expectedCode int) {
|
|
||||||
testutils.TestBookPutCallWithDemoPayload(t, payload, bookId, expectedCode, "/ws/book/"+bookId+"/startread")
|
|
||||||
}
|
|
||||||
190
internal/apitest/put_userbook_test.go
Normal file
190
internal/apitest/put_userbook_test.go
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
package apitest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.artlef.fr/bibliomane/internal/testutils"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPutRatingUserBooksHandler_UpdateRating(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"rating": 5
|
||||||
|
}`
|
||||||
|
bookId := "17"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusOK)
|
||||||
|
book := testGetBook(t, bookId, http.StatusOK)
|
||||||
|
assert.Equal(t, 5, book.Rating)
|
||||||
|
assert.Equal(t, true, book.Read)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutRatingUserBooksHandler_RateNewBookMakeItRead(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"rating": 7
|
||||||
|
}`
|
||||||
|
bookId := "18"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusOK)
|
||||||
|
book := testGetBook(t, bookId, http.StatusOK)
|
||||||
|
assert.Equal(t, 7, book.Rating)
|
||||||
|
assert.Equal(t, true, book.Read)
|
||||||
|
assert.Equal(t, false, book.WantRead)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutRatingUserBooksHandler_RateWantedBook(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"rating": 6
|
||||||
|
}`
|
||||||
|
bookId := "2"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusOK)
|
||||||
|
book := testGetBook(t, bookId, http.StatusOK)
|
||||||
|
assert.Equal(t, 6, book.Rating)
|
||||||
|
assert.Equal(t, true, book.Read)
|
||||||
|
assert.Equal(t, false, book.WantRead)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutRatingUserBooksHandler_RatingTypeWrong(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"rating": "bad"
|
||||||
|
}`
|
||||||
|
bookId := "18"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutRatingUserBooksHandler_RatingMin(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"rating": -3
|
||||||
|
}`
|
||||||
|
bookId := "18"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutRatingUserBooksHandler_RatingMax(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"rating": 15
|
||||||
|
}`
|
||||||
|
bookId := "18"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutRatingUserBooksHandler_BadBookId(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"rating": 15
|
||||||
|
}`
|
||||||
|
bookId := "18574"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutReadUserBooks_NewReadOk(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"read": true
|
||||||
|
}`
|
||||||
|
bookId := "21"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusOK)
|
||||||
|
book := testGetBook(t, bookId, http.StatusOK)
|
||||||
|
assert.Equal(t, true, book.Read)
|
||||||
|
assert.Equal(t, false, book.WantRead)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutReadUserBooks_NewReadDateOk(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"read": true,
|
||||||
|
"endDate": "2025-10-20"
|
||||||
|
}`
|
||||||
|
bookId := "9"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusOK)
|
||||||
|
book := testGetBook(t, bookId, http.StatusOK)
|
||||||
|
assert.Equal(t, true, book.Read)
|
||||||
|
assert.Equal(t, "2025-10-20", book.EndReadDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutReadUserBooks_UnsetEndDate(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"read": true,
|
||||||
|
"endDate": "null"
|
||||||
|
}`
|
||||||
|
bookId := "9"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusOK)
|
||||||
|
book := testGetBook(t, bookId, http.StatusOK)
|
||||||
|
assert.Equal(t, true, book.Read)
|
||||||
|
assert.Equal(t, "", book.EndReadDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutReadUserBooks_UnsetReadOk(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"read": false
|
||||||
|
}`
|
||||||
|
bookId := "9"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusOK)
|
||||||
|
book := testGetBook(t, bookId, http.StatusOK)
|
||||||
|
assert.Equal(t, false, book.Read)
|
||||||
|
assert.Equal(t, "", book.EndReadDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutStartReadUserBooks_WrongDateFormat(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"startDate": "19/11/2025"
|
||||||
|
}`
|
||||||
|
bookId := "6"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutStartReadUserBooks_NewReadOk(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"startDate": "2025-11-19"
|
||||||
|
}`
|
||||||
|
bookId := "6"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusOK)
|
||||||
|
book := testGetBook(t, bookId, http.StatusOK)
|
||||||
|
assert.Equal(t, "2025-11-19", book.StartReadDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutStartReadUserBooks_Unset(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"startDate": "null"
|
||||||
|
}`
|
||||||
|
bookId := "6"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusOK)
|
||||||
|
book := testGetBook(t, bookId, http.StatusOK)
|
||||||
|
assert.Equal(t, "", book.StartReadDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutWantRead_SetTrue(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"wantread": true
|
||||||
|
}`
|
||||||
|
bookId := "17"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusOK)
|
||||||
|
book := testGetBook(t, bookId, http.StatusOK)
|
||||||
|
assert.Equal(t, true, book.WantRead)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPutWantRead_SetFalse(t *testing.T) {
|
||||||
|
payload :=
|
||||||
|
`{
|
||||||
|
"wantread": false
|
||||||
|
}`
|
||||||
|
bookId := "2"
|
||||||
|
testPutUserBooks(t, payload, bookId, http.StatusOK)
|
||||||
|
book := testGetBook(t, bookId, http.StatusOK)
|
||||||
|
assert.Equal(t, false, book.WantRead)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPutUserBooks(t *testing.T, payload string, bookId string, expectedCode int) {
|
||||||
|
testutils.TestBookPutCallWithDemoPayload(t, payload, bookId, expectedCode, "/ws/book/"+bookId)
|
||||||
|
}
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package apitest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.artlef.fr/bibliomane/internal/testutils"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPutWantRead_SetTrue(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"wantread": true
|
|
||||||
}`
|
|
||||||
bookId := "17"
|
|
||||||
testPutWantReadUserBooks(t, payload, bookId, http.StatusOK)
|
|
||||||
book := testGetBook(t, bookId, http.StatusOK)
|
|
||||||
assert.Equal(t, true, book.WantRead)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutWantRead_SetFalse(t *testing.T) {
|
|
||||||
payload :=
|
|
||||||
`{
|
|
||||||
"wantread": false
|
|
||||||
}`
|
|
||||||
bookId := "2"
|
|
||||||
testPutWantReadUserBooks(t, payload, bookId, http.StatusOK)
|
|
||||||
book := testGetBook(t, bookId, http.StatusOK)
|
|
||||||
assert.Equal(t, false, book.WantRead)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testPutWantReadUserBooks(t *testing.T, payload string, bookId string, expectedCode int) {
|
|
||||||
testutils.TestBookPutCallWithDemoPayload(t, payload, bookId, expectedCode, "/ws/book/"+bookId+"/wantread")
|
|
||||||
}
|
|
||||||
@@ -21,6 +21,14 @@ type BookPostImport struct {
|
|||||||
Lang string `json:"lang" binding:"required,max=5"`
|
Lang string `json:"lang" binding:"required,max=5"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserBookPutUpdate struct {
|
||||||
|
Read *bool `json:"read"`
|
||||||
|
EndDate *string `json:"endDate"`
|
||||||
|
WantRead *bool `json:"wantread"`
|
||||||
|
Rating *int `json:"rating"`
|
||||||
|
StartDate *string `json:"startDate"`
|
||||||
|
}
|
||||||
|
|
||||||
type FileInfoPost struct {
|
type FileInfoPost struct {
|
||||||
FileID uint `json:"fileId"`
|
FileID uint `json:"fileId"`
|
||||||
FilePath string `json:"filepath"`
|
FilePath string `json:"filepath"`
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ func computeValidationMessage(ac *appcontext.AppContext, fe *validator.FieldErro
|
|||||||
return i18nresource.GetTranslatedMessage(ac, "ValidationRequired")
|
return i18nresource.GetTranslatedMessage(ac, "ValidationRequired")
|
||||||
case "min":
|
case "min":
|
||||||
return fmt.Sprintf(i18nresource.GetTranslatedMessage(ac, "ValidationTooShort"), (*fe).Param())
|
return fmt.Sprintf(i18nresource.GetTranslatedMessage(ac, "ValidationTooShort"), (*fe).Param())
|
||||||
|
case "gte":
|
||||||
|
return fmt.Sprintf("Should be greater than %s", (*fe).Param())
|
||||||
case "max":
|
case "max":
|
||||||
return fmt.Sprintf(i18nresource.GetTranslatedMessage(ac, "ValidationTooLong"), (*fe).Param())
|
return fmt.Sprintf(i18nresource.GetTranslatedMessage(ac, "ValidationTooLong"), (*fe).Param())
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -7,21 +7,35 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.artlef.fr/bibliomane/internal/appcontext"
|
"git.artlef.fr/bibliomane/internal/appcontext"
|
||||||
|
"git.artlef.fr/bibliomane/internal/dto"
|
||||||
"git.artlef.fr/bibliomane/internal/model"
|
"git.artlef.fr/bibliomane/internal/model"
|
||||||
"git.artlef.fr/bibliomane/internal/myvalidator"
|
"git.artlef.fr/bibliomane/internal/myvalidator"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PutReadUserBookHandler(ac appcontext.AppContext) {
|
func PutUserBookHandler(ac appcontext.AppContext) {
|
||||||
data, err := retrieveDataFromContext(ac)
|
bookId64, err := strconv.ParseUint(ac.C.Param("id"), 10, 64)
|
||||||
|
bookId := uint(bookId64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
ac.C.JSON(http.StatusBadRequest, gin.H{"error": err})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
bookId := data.BookId
|
err = myvalidator.ValidateId(ac.Db, bookId, &model.Book{})
|
||||||
user := data.User
|
if err != nil {
|
||||||
var read userbookPutRead
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
err = ac.C.ShouldBindJSON(&read)
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := ac.GetAuthenticatedUser()
|
||||||
|
if err != nil {
|
||||||
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var userBookPut dto.UserBookPutUpdate
|
||||||
|
err = ac.C.ShouldBindJSON(&userBookPut)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
return
|
return
|
||||||
@@ -32,14 +46,53 @@ func PutReadUserBookHandler(ac appcontext.AppContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userbook.Read = read.Read
|
if userBookPut.Read != nil {
|
||||||
|
err = updateReadStatus(&userbook, &userBookPut)
|
||||||
if read.EndDate != "" {
|
|
||||||
d, err := parseDate(read.EndDate)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if userBookPut.WantRead != nil {
|
||||||
|
userbook.WantRead = *userBookPut.WantRead
|
||||||
|
}
|
||||||
|
if userBookPut.StartDate != nil {
|
||||||
|
d, err := parseDate(*userBookPut.StartDate)
|
||||||
|
if err != nil {
|
||||||
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
userbook.StartReadDate = d
|
||||||
|
}
|
||||||
|
if userBookPut.Rating != nil {
|
||||||
|
err = validateRating(*userBookPut.Rating)
|
||||||
|
if err != nil {
|
||||||
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
|
}
|
||||||
|
updateRating(&userbook, &userBookPut)
|
||||||
|
}
|
||||||
|
ac.Db.Save(&userbook)
|
||||||
|
ac.C.String(http.StatusOK, "Success")
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateRating(rating int) error {
|
||||||
|
//struct used for validation
|
||||||
|
var ratingStruct struct {
|
||||||
|
Rating int `validate:"gte=0,lte=10"`
|
||||||
|
}
|
||||||
|
ratingStruct.Rating = rating
|
||||||
|
validate := validator.New()
|
||||||
|
return validate.Struct(ratingStruct)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateReadStatus(userbook *model.UserBook, userBookPut *dto.UserBookPutUpdate) error {
|
||||||
|
userbook.Read = *userBookPut.Read
|
||||||
|
|
||||||
|
if userBookPut.EndDate != nil && *userBookPut.EndDate != "" {
|
||||||
|
d, err := parseDate(*userBookPut.EndDate)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
userbook.EndReadDate = d
|
userbook.EndReadDate = d
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,84 +105,11 @@ func PutReadUserBookHandler(ac appcontext.AppContext) {
|
|||||||
if !userbook.Read {
|
if !userbook.Read {
|
||||||
userbook.EndReadDate = nil
|
userbook.EndReadDate = nil
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
ac.Db.Save(&userbook)
|
|
||||||
ac.C.String(http.StatusOK, "Success")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func PutWantReadUserBookHandler(ac appcontext.AppContext) {
|
func updateRating(userbook *model.UserBook, userBookPut *dto.UserBookPutUpdate) {
|
||||||
data, err := retrieveDataFromContext(ac)
|
userbook.Rating = *userBookPut.Rating
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bookId := data.BookId
|
|
||||||
user := data.User
|
|
||||||
var wantread userbookPutWantRead
|
|
||||||
err = ac.C.ShouldBindJSON(&wantread)
|
|
||||||
if err != nil {
|
|
||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
userbook, err := fetchOrCreateUserBook(ac, bookId, &user)
|
|
||||||
if err != nil {
|
|
||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
userbook.WantRead = wantread.WantRead
|
|
||||||
ac.Db.Save(&userbook)
|
|
||||||
ac.C.String(http.StatusOK, "Success")
|
|
||||||
}
|
|
||||||
|
|
||||||
func PutStartReadUserBookHandler(ac appcontext.AppContext) {
|
|
||||||
data, err := retrieveDataFromContext(ac)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bookId := data.BookId
|
|
||||||
user := data.User
|
|
||||||
|
|
||||||
var startDateToParse userbookPutStartRead
|
|
||||||
err = ac.C.ShouldBindJSON(&startDateToParse)
|
|
||||||
if err != nil {
|
|
||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
userbook, err := fetchOrCreateUserBook(ac, bookId, &user)
|
|
||||||
if err != nil {
|
|
||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
d, err := parseDate(startDateToParse.StartDate)
|
|
||||||
if err != nil {
|
|
||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
userbook.StartReadDate = d
|
|
||||||
|
|
||||||
ac.Db.Save(&userbook)
|
|
||||||
ac.C.String(http.StatusOK, "Success")
|
|
||||||
}
|
|
||||||
|
|
||||||
func PutRateUserBookHandler(ac appcontext.AppContext) {
|
|
||||||
data, err := retrieveDataFromContext(ac)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bookId := data.BookId
|
|
||||||
user := data.User
|
|
||||||
var rating userbookPutRating
|
|
||||||
err = ac.C.ShouldBindJSON(&rating)
|
|
||||||
if err != nil {
|
|
||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
userbook, err := fetchOrCreateUserBook(ac, bookId, &user)
|
|
||||||
if err != nil {
|
|
||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
userbook.Rating = rating.Rating
|
|
||||||
|
|
||||||
//if rated, set to "read" (a rating = 0 means unrated)
|
//if rated, set to "read" (a rating = 0 means unrated)
|
||||||
if userbook.Rating > 0 {
|
if userbook.Rating > 0 {
|
||||||
@@ -137,30 +117,6 @@ func PutRateUserBookHandler(ac appcontext.AppContext) {
|
|||||||
//if set to read, remove want read
|
//if set to read, remove want read
|
||||||
userbook.WantRead = false
|
userbook.WantRead = false
|
||||||
}
|
}
|
||||||
ac.Db.Save(&userbook)
|
|
||||||
ac.C.String(http.StatusOK, "Success")
|
|
||||||
}
|
|
||||||
|
|
||||||
type userbookPutRead struct {
|
|
||||||
Read bool `json:"read"`
|
|
||||||
EndDate string `json:"endDate"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type userbookPutWantRead struct {
|
|
||||||
WantRead bool `json:"wantread"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type userbookPutRating struct {
|
|
||||||
Rating int `json:"rating" binding:"min=0,max=10"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type userbookPutStartRead struct {
|
|
||||||
StartDate string `json:"startDate" binding:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type apiCallData struct {
|
|
||||||
BookId uint
|
|
||||||
User model.User
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseDate(dateToParse string) (*time.Time, error) {
|
func parseDate(dateToParse string) (*time.Time, error) {
|
||||||
@@ -173,27 +129,6 @@ func parseDate(dateToParse string) (*time.Time, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func retrieveDataFromContext(ac appcontext.AppContext) (apiCallData, error) {
|
|
||||||
bookId64, err := strconv.ParseUint(ac.C.Param("id"), 10, 64)
|
|
||||||
bookId := uint(bookId64)
|
|
||||||
if err != nil {
|
|
||||||
ac.C.JSON(http.StatusBadRequest, gin.H{"error": err})
|
|
||||||
return apiCallData{}, err
|
|
||||||
}
|
|
||||||
err = myvalidator.ValidateId(ac.Db, bookId, &model.Book{})
|
|
||||||
if err != nil {
|
|
||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
|
||||||
return apiCallData{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
user, fetchUserErr := ac.GetAuthenticatedUser()
|
|
||||||
if fetchUserErr != nil {
|
|
||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
|
||||||
return apiCallData{}, fetchUserErr
|
|
||||||
}
|
|
||||||
return apiCallData{BookId: bookId, User: user}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func fetchOrCreateUserBook(ac appcontext.AppContext, bookId uint, user *model.User) (model.UserBook, error) {
|
func fetchOrCreateUserBook(ac appcontext.AppContext, bookId uint, user *model.User) (model.UserBook, error) {
|
||||||
var userbook model.UserBook
|
var userbook model.UserBook
|
||||||
res := ac.Db.Where("user_id = ? AND book_id = ?", user.ID, bookId).First(&userbook)
|
res := ac.Db.Where("user_id = ? AND book_id = ?", user.ID, bookId).First(&userbook)
|
||||||
|
|||||||
@@ -58,17 +58,8 @@ func Setup(config *config.Config) *gin.Engine {
|
|||||||
ws.GET("/book/:id", func(c *gin.Context) {
|
ws.GET("/book/:id", func(c *gin.Context) {
|
||||||
routes.GetBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
routes.GetBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
||||||
})
|
})
|
||||||
ws.PUT("/book/:id/read", func(c *gin.Context) {
|
ws.PUT("/book/:id", func(c *gin.Context) {
|
||||||
routes.PutReadUserBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
routes.PutUserBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
||||||
})
|
|
||||||
ws.PUT("/book/:id/wantread", func(c *gin.Context) {
|
|
||||||
routes.PutWantReadUserBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
|
||||||
})
|
|
||||||
ws.PUT("/book/:id/startread", func(c *gin.Context) {
|
|
||||||
routes.PutStartReadUserBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
|
||||||
})
|
|
||||||
ws.PUT("/book/:id/rate", func(c *gin.Context) {
|
|
||||||
routes.PutRateUserBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
|
||||||
})
|
})
|
||||||
ws.POST("/book", func(c *gin.Context) {
|
ws.POST("/book", func(c *gin.Context) {
|
||||||
routes.PostBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
routes.PostBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import (
|
|||||||
"git.artlef.fr/bibliomane/internal/config"
|
"git.artlef.fr/bibliomane/internal/config"
|
||||||
"git.artlef.fr/bibliomane/internal/setup"
|
"git.artlef.fr/bibliomane/internal/setup"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSetup() *gin.Engine {
|
func TestSetup() *gin.Engine {
|
||||||
@@ -62,5 +61,7 @@ func TestBookPutCallWithDemoPayload(t *testing.T, payload string, bookId string,
|
|||||||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
|
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
router.ServeHTTP(w, req)
|
router.ServeHTTP(w, req)
|
||||||
assert.Equal(t, expectedCode, w.Code)
|
if w.Code != expectedCode {
|
||||||
|
t.Errorf("%s", w.Body.String())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user