Integrate users and books
- new table userbook linking users and book - moved rating to users book - updated demo data and tests - updated front to hide routes from non connected users
This commit is contained in:
39
book_test.go
39
book_test.go
@@ -35,32 +35,42 @@ func connectDemoUser(router *gin.Engine) string {
|
|||||||
req, _ := http.NewRequest("POST", "/auth/login", strings.NewReader(loginJson))
|
req, _ := http.NewRequest("POST", "/auth/login", strings.NewReader(loginJson))
|
||||||
router.ServeHTTP(w, req)
|
router.ServeHTTP(w, req)
|
||||||
var parsedResponse loginResponse
|
var parsedResponse loginResponse
|
||||||
body := w.Body.String()
|
err := json.Unmarshal(w.Body.Bytes(), &parsedResponse)
|
||||||
err := json.Unmarshal([]byte(body), &parsedResponse)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
return parsedResponse.Token
|
return parsedResponse.Token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type bookUserGet struct {
|
||||||
|
Title string `json:"title" binding:"required,max=300"`
|
||||||
|
Author string `json:"author" binding:"max=100"`
|
||||||
|
Rating int `json:"rating" binding:"min=0,max=10"`
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetBooksHandler(t *testing.T) {
|
func TestGetBooksHandler(t *testing.T) {
|
||||||
router := testSetup()
|
router := testSetup()
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
token := connectDemoUser(router)
|
token := connectDemoUser(router)
|
||||||
req, _ := http.NewRequest("GET", "/books", nil)
|
req, _ := http.NewRequest("GET", "/mybooks", nil)
|
||||||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
|
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
|
||||||
router.ServeHTTP(w, req)
|
router.ServeHTTP(w, req)
|
||||||
|
|
||||||
|
var parsedResponse []bookUserGet
|
||||||
|
err := json.Unmarshal(w.Body.Bytes(), &parsedResponse)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
assert.Equal(t, 200, w.Code)
|
assert.Equal(t, 200, w.Code)
|
||||||
|
assert.Equal(t, 28, len(parsedResponse))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPostBookHandler_Ok(t *testing.T) {
|
func TestPostBookHandler_Ok(t *testing.T) {
|
||||||
bookJson :=
|
bookJson :=
|
||||||
`{
|
`{
|
||||||
"title": "Le château",
|
"title": "Le château",
|
||||||
"author": "Kafka",
|
"author": "Kafka"
|
||||||
"rating": 9
|
|
||||||
}`
|
}`
|
||||||
testPostBookHandler(t, bookJson, 200)
|
testPostBookHandler(t, bookJson, 200)
|
||||||
}
|
}
|
||||||
@@ -76,18 +86,7 @@ func TestPostBookHandler_OkOnlyTitle(t *testing.T) {
|
|||||||
func TestPostBookHandler_noTitle(t *testing.T) {
|
func TestPostBookHandler_noTitle(t *testing.T) {
|
||||||
bookJson :=
|
bookJson :=
|
||||||
`{
|
`{
|
||||||
"author": "Kafka",
|
"author": "Kafka"
|
||||||
"rating": 9
|
|
||||||
}`
|
|
||||||
testPostBookHandler(t, bookJson, 400)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPostBookHandler_WrongRating(t *testing.T) {
|
|
||||||
bookJson :=
|
|
||||||
`{
|
|
||||||
"title": "Le château",
|
|
||||||
"author": "Kafka",
|
|
||||||
"rating": 15
|
|
||||||
}`
|
}`
|
||||||
testPostBookHandler(t, bookJson, 400)
|
testPostBookHandler(t, bookJson, 400)
|
||||||
}
|
}
|
||||||
@@ -96,8 +95,7 @@ func TestPostBookHandler_TitleTooLong(t *testing.T) {
|
|||||||
bookJson :=
|
bookJson :=
|
||||||
`{
|
`{
|
||||||
"title": "Noisy outlaws, unfriendly blobs, and some other things that aren't as scary, maybe, depending on how you feel about lost lands, stray cellphones, creatures from the sky, parents who disappear in Peru, a man named Lars Farf, and one other story we couldn't quite finish, so maybe you could help us out.",
|
"title": "Noisy outlaws, unfriendly blobs, and some other things that aren't as scary, maybe, depending on how you feel about lost lands, stray cellphones, creatures from the sky, parents who disappear in Peru, a man named Lars Farf, and one other story we couldn't quite finish, so maybe you could help us out.",
|
||||||
"author": "Eli Horowitz",
|
"author": "Eli Horowitz"
|
||||||
"rating": 2
|
|
||||||
}`
|
}`
|
||||||
testPostBookHandler(t, bookJson, 400)
|
testPostBookHandler(t, bookJson, 400)
|
||||||
}
|
}
|
||||||
@@ -106,8 +104,7 @@ func TestPostBookHandler_AuthorTooLong(t *testing.T) {
|
|||||||
bookJson :=
|
bookJson :=
|
||||||
`{
|
`{
|
||||||
"title": "something",
|
"title": "something",
|
||||||
"author": "Wolfeschlegelsteinhausenbergerdorffwelchevoralternwarengewissenhaftschaferswessenschafewarenwohlgepflegeundsorgfaltigkeitbeschutzenvonangreifendurchihrraubgierigfeindewelchevoralternzwolftausendjahresvorandieerscheinenvanderersteerdemenschderraumschiffgebrauchlichtalsseinursprungvonkraftgestartseinlangefahrthinzwischensternartigraumaufdersuchenachdiesternwelchegehabtbewohnbarplanetenkreisedrehensichundwohinderneurassevonverstandigmenschlichkeitkonntefortpflanzenundsicherfreuenanlebenslanglichfreudeundruhemitnichteinfurchtvorangreifenvonandererintelligentgeschopfsvonhinzwischensternartigraum",
|
"author": "Wolfeschlegelsteinhausenbergerdorffwelchevoralternwarengewissenhaftschaferswessenschafewarenwohlgepflegeundsorgfaltigkeitbeschutzenvonangreifendurchihrraubgierigfeindewelchevoralternzwolftausendjahresvorandieerscheinenvanderersteerdemenschderraumschiffgebrauchlichtalsseinursprungvonkraftgestartseinlangefahrthinzwischensternartigraumaufdersuchenachdiesternwelchegehabtbewohnbarplanetenkreisedrehensichundwohinderneurassevonverstandigmenschlichkeitkonntefortpflanzenundsicherfreuenanlebenslanglichfreudeundruhemitnichteinfurchtvorangreifenvonandererintelligentgeschopfsvonhinzwischensternartigraum"
|
||||||
"rating": 2
|
|
||||||
}`
|
}`
|
||||||
testPostBookHandler(t, bookJson, 400)
|
testPostBookHandler(t, bookJson, 400)
|
||||||
}
|
}
|
||||||
|
|||||||
84
demodata.sql
84
demodata.sql
@@ -1,29 +1,57 @@
|
|||||||
INSERT INTO users(created_at, name, password) VALUES ('NOW', 'demo','$2a$10$7mfCBxBwIzXDU6r9az26o.zPX/r6IlNZVfU9zxSoLVtc0kRPimzba');
|
INSERT INTO users(created_at, name, password) VALUES ('NOW', 'demo','$2a$10$7mfCBxBwIzXDU6r9az26o.zPX/r6IlNZVfU9zxSoLVtc0kRPimzba');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'O dingos, o chateaux!','Jean-Patrick Manchette', 6);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'O dingos, o chateaux!','Jean-Patrick Manchette');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Le petit bleu de la côte Ouest','Jean-Patrick Manchette', 7);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'O dingos, o chateaux!') ,7);
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'D''un château l''autre','Louis-Ferdinand Céline', 10);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Le petit bleu de la côte Ouest','Jean-Patrick Manchette');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Les dieux ont soif','Anatole France', 7);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Le petit bleu de la côte Ouest') ,7);
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Rigodon','Louis-Ferdinand Céline', 10);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'D''un château l''autre','Louis-Ferdinand Céline');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Un barrage contre le Pacifique','Marguerite Duras', NULL);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'D''un château l''autre') ,10);
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Salammbô','Flaubert Gustave', 8);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Les dieux ont soif','Anatole France');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Langage Machine','Romain Lucazeau', 5);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Les dieux ont soif') ,7);
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'La Ville et les chiens','Mario Vargas Llosa', 7);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Rigodon','Louis-Ferdinand Céline');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'La Fille Du Capitaine','A. Pouchkine', 8);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Rigodon') ,10);
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Aurélien','Louis Aragon', 8);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Un barrage contre le Pacifique','Marguerite Duras');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Duo','Colette', 9);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Un barrage contre le Pacifique') ,7);
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Gargantua','François Rabelais', 7);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Salammbô','Flaubert Gustave');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'The Life of Jesus','Ernest Renan', NULL);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Salammbô') ,8);
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'L''Homme sans qualités, tome 1','Robert Musil', 7);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Langage Machine','Romain Lucazeau');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'The Green House','Mario Vargas Llosa', 6);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Langage Machine') ,5);
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Le coup de pistolet','Alexandre Pouchkine', 8);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'La Ville et les chiens','Mario Vargas Llosa');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'De sang-froid','Truman Capote', 6);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'La Ville et les chiens'),6);
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'La position du tireur couché','Jean-Patrick Manchette', 7);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'La Fille Du Capitaine','A. Pouchkine');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Vers le Phare','Virginia Woolf', 6);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'La Fille Du Capitaine'),8);
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'L''insoutenable légèreté de l''être', 'Milan Kundera', 8);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Aurélien','Louis Aragon');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Le complot contre l''Amérique','Philip Roth', 6);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Aurélien') ,8);
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Nord','Louis-Ferdinand Céline', 10);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Duo','Colette');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Sa majesté des mouches','William Golding', 5);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Duo'),9);
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Le Pavillon d''or','Yukio Mishima', 8);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Gargantua','François Rabelais');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Le meurtre d''O-tsuya','Junichiro Tanizaki', 7);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Gargantua'),7);
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Dojoji et autres nouvelles','Yukio Mishima', 8);
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'The Life of Jesus','Ernest Renan');
|
||||||
INSERT INTO books(created_at, title, author, rating) VALUES ('NOW', 'Noisy outlaws, unfriendly blobs, and some other things that aren''t as scary, maybe, depending on how you feel about lost lands, stray cellphones, creatures from the sky, parents who disappear in Peru, a man named Lars Farf, and one other story we couldn''t quite finish, so maybe you could help us out','Wolfeschlegelsteinhausenbergerdorffwelchevoralternwarengewissenhaftschaferswessenschafewarenwohlgepf', 2);
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'The Life of Jesus'), NULL);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'L''Homme sans qualités, tome 1','Robert Musil');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'L''Homme sans qualités, tome 1') ,7);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'The Green House','Mario Vargas Llosa');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'The Green House') ,6);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Le coup de pistolet','Alexandre Pouchkine');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Le coup de pistolet'),8);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'De sang-froid','Truman Capote');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'De sang-froid'),6);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'La position du tireur couché','Jean-Patrick Manchette');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'La position du tireur couché'),6);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Vers le Phare','Virginia Woolf');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Vers le Phare'),6);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'L''insoutenable légèreté de l''être', 'Milan Kundera');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'L''insoutenable légèreté de l''être') ,8);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Le complot contre l''Amérique','Philip Roth');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Le complot contre l''Amérique'),6);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Nord','Louis-Ferdinand Céline');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Nord'),10);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Sa majesté des mouches','William Golding');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Sa majesté des mouches'),5);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Le Pavillon d''or','Yukio Mishima');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Le Pavillon d''or'),8);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Le meurtre d''O-tsuya','Junichiro Tanizaki');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Le meurtre d''O-tsuya'),7);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Dojoji et autres nouvelles','Yukio Mishima');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Dojoji et autres nouvelles'),8);
|
||||||
|
INSERT INTO books(created_at, title, author) VALUES ('NOW', 'Noisy outlaws, unfriendly blobs, and some other things that aren''t as scary, maybe, depending on how you feel about lost lands, stray cellphones, creatures from the sky, parents who disappear in Peru, a man named Lars Farf, and one other story we couldn''t quite finish, so maybe you could help us out','Wolfeschlegelsteinhausenbergerdorffwelchevoralternwarengewissenhaftschaferswessenschafewarenwohlgepf');
|
||||||
|
INSERT INTO user_books(created_at, user_id, book_id, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Noisy outlaws, unfriendly blobs, and some other things that aren''t as scary, maybe, depending on how you feel about lost lands, stray cellphones, creatures from the sky, parents who disappear in Peru, a man named Lars Farf, and one other story we couldn''t quite finish, so maybe you could help us out'),2);
|
||||||
|
|||||||
@@ -17,15 +17,12 @@
|
|||||||
<RouterLink to="/" class="navbar-item" activeClass="is-active">
|
<RouterLink to="/" class="navbar-item" activeClass="is-active">
|
||||||
Home
|
Home
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<RouterLink to="/add" class="navbar-item" activeClass="is-active">
|
<RouterLink v-if="authStore.user" to="/add" class="navbar-item" activeClass="is-active">
|
||||||
Add Book
|
Add Book
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<a class="navbar-item">
|
<RouterLink v-if="authStore.user" to="/books" class="navbar-item" activeClass="is-active">
|
||||||
Books
|
My Books
|
||||||
</a>
|
</RouterLink>
|
||||||
<a class="navbar-item">
|
|
||||||
Locations
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-end">
|
<div class="navbar-end">
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import BookCard from './BookCard.vue';
|
import BookCard from './BookCard.vue';
|
||||||
import { getBooks } from './api.js'
|
import { getMyBooks } from './api.js'
|
||||||
|
|
||||||
const { data, error } = getBooks();
|
const { data, error } = getMyBooks();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
19
front/src/Home.vue
Normal file
19
front/src/Home.vue
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<script setup>
|
||||||
|
import { useAuthStore } from './auth.store.js'
|
||||||
|
|
||||||
|
const authStore = useAuthStore();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div v-if="authStore.user">
|
||||||
|
Welcome {{ authStore.user.username }} !
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
Welcome to PersonalLibraryManager. Please login ou sign in to continue.
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
@@ -24,8 +24,8 @@ function useFetch(url) {
|
|||||||
return { data, error }
|
return { data, error }
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBooks() {
|
export function getMyBooks() {
|
||||||
return useFetch(baseUrl + '/books');
|
return useFetch(baseUrl + '/mybooks');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function postBook(book) {
|
export function postBook(book) {
|
||||||
|
|||||||
@@ -6,10 +6,12 @@ import BooksBrowser from './BooksBrowser.vue'
|
|||||||
import AddBook from './AddBook.vue'
|
import AddBook from './AddBook.vue'
|
||||||
import SignUp from './SignUp.vue'
|
import SignUp from './SignUp.vue'
|
||||||
import LogIn from './LogIn.vue'
|
import LogIn from './LogIn.vue'
|
||||||
|
import Home from './Home.vue'
|
||||||
|
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{ path: '/', component: BooksBrowser },
|
{ path: '/', component: Home },
|
||||||
|
{ path: '/books', component: BooksBrowser },
|
||||||
{ path: '/add', component: AddBook },
|
{ path: '/add', component: AddBook },
|
||||||
{ path: '/signup', component: SignUp },
|
{ path: '/signup', component: SignUp },
|
||||||
{ path: '/login', component: LogIn },
|
{ path: '/login', component: LogIn },
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package api
|
|||||||
type bookPostCreate struct {
|
type bookPostCreate struct {
|
||||||
Title string `json:"title" binding:"required,max=300"`
|
Title string `json:"title" binding:"required,max=300"`
|
||||||
Author string `json:"author" binding:"max=100"`
|
Author string `json:"author" binding:"max=100"`
|
||||||
Rating int `json:"rating" binding:"min=0,max=10"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type userSignup struct {
|
type userSignup struct {
|
||||||
@@ -15,3 +14,9 @@ type userLogin struct {
|
|||||||
Username string `json:"username" binding:"required,min=2,max=20"`
|
Username string `json:"username" binding:"required,min=2,max=20"`
|
||||||
Password string `json:"password" binding:"required,min=6,max=100"`
|
Password string `json:"password" binding:"required,min=6,max=100"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type bookUserGet struct {
|
||||||
|
Title string `json:"title" binding:"required,max=300"`
|
||||||
|
Author string `json:"author" binding:"max=100"`
|
||||||
|
Rating int `json:"rating" binding:"min=0,max=10"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,13 @@ func (b bookPostCreate) toBook() model.Book {
|
|||||||
return model.Book{
|
return model.Book{
|
||||||
Title: b.Title,
|
Title: b.Title,
|
||||||
Author: b.Author,
|
Author: b.Author,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromUserBookDb(b *model.UserBook) bookUserGet {
|
||||||
|
return bookUserGet{
|
||||||
|
Title: b.Book.Title,
|
||||||
|
Author: b.Book.Author,
|
||||||
Rating: b.Rating,
|
Rating: b.Rating,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,14 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetBooksHanderl(c *gin.Context, db *gorm.DB) {
|
func GetMyBooksHanderl(c *gin.Context, db *gorm.DB) {
|
||||||
var books []model.Book
|
var userbooks []model.UserBook
|
||||||
db.Model(&model.Book{}).Find(&books)
|
db.Preload("Book").Find(&userbooks)
|
||||||
c.JSON(http.StatusOK, books)
|
var booksDto []bookUserGet
|
||||||
|
for _, userbook := range userbooks {
|
||||||
|
booksDto = append(booksDto, fromUserBookDb(&userbook))
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, booksDto)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PostBookHandler(c *gin.Context, db *gorm.DB) {
|
func PostBookHandler(c *gin.Context, db *gorm.DB) {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ func Initdb(databasePath string, demoDataPath string) *gorm.DB {
|
|||||||
// Migrate the schema
|
// Migrate the schema
|
||||||
db.AutoMigrate(&model.Book{})
|
db.AutoMigrate(&model.Book{})
|
||||||
db.AutoMigrate(&model.User{})
|
db.AutoMigrate(&model.User{})
|
||||||
|
db.AutoMigrate(&model.UserBook{})
|
||||||
var book model.Book
|
var book model.Book
|
||||||
queryResult := db.Limit(1).Find(&book)
|
queryResult := db.Limit(1).Find(&book)
|
||||||
if queryResult.RowsAffected == 0 && demoDataPath != "" {
|
if queryResult.RowsAffected == 0 && demoDataPath != "" {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -20,7 +19,6 @@ func Auth() gin.HandlerFunc {
|
|||||||
|
|
||||||
username, err := parseUserFromJwt(c)
|
username, err := parseUserFromJwt(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
|
||||||
c.AbortWithStatusJSON(http.StatusUnauthorized,
|
c.AbortWithStatusJSON(http.StatusUnauthorized,
|
||||||
gin.H{"error": "You must be logged in to access this resource."})
|
gin.H{"error": "You must be logged in to access this resource."})
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -6,5 +6,4 @@ type Book struct {
|
|||||||
gorm.Model
|
gorm.Model
|
||||||
Title string `json:"title" gorm:"not null"`
|
Title string `json:"title" gorm:"not null"`
|
||||||
Author string `json:"author"`
|
Author string `json:"author"`
|
||||||
Rating int `json:"rating"`
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ type User struct {
|
|||||||
gorm.Model
|
gorm.Model
|
||||||
Name string `gorm:"index;uniqueIndex"`
|
Name string `gorm:"index;uniqueIndex"`
|
||||||
Password string
|
Password string
|
||||||
|
UserBooks []UserBook
|
||||||
}
|
}
|
||||||
|
|||||||
12
internal/model/userbook.go
Normal file
12
internal/model/userbook.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "gorm.io/gorm"
|
||||||
|
|
||||||
|
// describes the relationship between a user and a book.
|
||||||
|
type UserBook struct {
|
||||||
|
gorm.Model
|
||||||
|
UserID uint
|
||||||
|
BookID uint
|
||||||
|
Book Book
|
||||||
|
Rating int
|
||||||
|
}
|
||||||
4
main.go
4
main.go
@@ -26,8 +26,8 @@ func setup(config *config.Config) *gin.Engine {
|
|||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
r.Use(cors.New(configureCors())) // All origins allowed by default
|
r.Use(cors.New(configureCors())) // All origins allowed by default
|
||||||
r.Use(middleware.Auth())
|
r.Use(middleware.Auth())
|
||||||
r.GET("/books", func(c *gin.Context) {
|
r.GET("/mybooks", func(c *gin.Context) {
|
||||||
api.GetBooksHanderl(c, db)
|
api.GetMyBooksHanderl(c, db)
|
||||||
})
|
})
|
||||||
r.POST("/book", func(c *gin.Context) {
|
r.POST("/book", func(c *gin.Context) {
|
||||||
api.PostBookHandler(c, db)
|
api.PostBookHandler(c, db)
|
||||||
|
|||||||
Reference in New Issue
Block a user