add userbook from searched book

This commit is contained in:
2025-10-20 17:56:12 +02:00
parent 6d15374c87
commit e5347e3583
5 changed files with 43 additions and 6 deletions

View File

@@ -1,4 +1,9 @@
<script setup> <script setup>
import { ref } from 'vue'
import { postUserBook } from './api.js'
import { useRouter } from 'vue-router'
const router = useRouter();
const props = defineProps({ const props = defineProps({
title: String, title: String,
@@ -6,15 +11,27 @@
id: BigInt, id: BigInt,
imagePath: String, imagePath: String,
}); });
const imagePathOrDefault = (props.imagePath == "" || typeof props.imagePath === 'undefined') ? "../defaultbook.png" : props.imagePath; const imagePathOrDefault = (props.imagePath == "" || typeof props.imagePath === 'undefined') ? "../defaultbook.png" : props.imagePath;
const error = ref(null)
async function onUserBookAdd() {
const res = await postUserBook({bookId: props.id});
if (res.ok) {
router.push('/books')
} else {
res.json().then((json) => (error.value = json));
}
}
</script> </script>
<template> <template>
<div v-if="error" class="notification is-danger">
<p>{{error}}</p>
</div>
<div class="columns box container has-background-dark"> <div class="columns box container has-background-dark">
<div class="column is-narrow"> <div class="column is-narrow">
<button class="button"> <button @click="onUserBookAdd" class="button">
<span class="icon" title="Add"> <span class="icon" title="Add">
<b-icon-plus /> <b-icon-plus />
</span> </span>

View File

@@ -36,6 +36,10 @@ export function postBook(book) {
return genericPostCall('/book', book.value) return genericPostCall('/book', book.value)
} }
export async function postUserBook(userbook) {
return genericPostCall('/userbook', userbook)
}
export function postLogin(user) { export function postLogin(user) {
return genericPostCallNoAuth('/auth/login', user.value) return genericPostCallNoAuth('/auth/login', user.value)
} }

View File

@@ -15,13 +15,28 @@ import (
type bookSearchGet struct { type bookSearchGet 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"`
Id uint `json:"id"`
} }
func TestSearchBook(t *testing.T) { func TestSearchBook_MultipleBooks(t *testing.T) {
books := testSearchBook(t, "san")
assert.Equal(t, 2, len(books))
}
func TestSearchBook_AllFields(t *testing.T) {
books := testSearchBook(t, "de san")
assert.Equal(t, 1, len(books))
assert.Equal(t,
[]bookSearchGet{{Title: "De sang-froid", Author: "Truman Capote", Id: 18}},
books)
}
func testSearchBook(t *testing.T, searchterm string) []bookSearchGet {
router := testutils.TestSetup() router := testutils.TestSetup()
token := testutils.ConnectDemoUser(router) token := testutils.ConnectDemoUser(router)
req, _ := http.NewRequest("GET", "/search/san", nil) req, _ := http.NewRequest("GET", "/search/"+searchterm, nil)
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)
@@ -32,6 +47,5 @@ func TestSearchBook(t *testing.T) {
log.Fatal(err) log.Fatal(err)
} }
assert.Equal(t, 200, w.Code) assert.Equal(t, 200, w.Code)
return books
assert.Equal(t, 2, len(books))
} }

View File

@@ -3,4 +3,5 @@ package dto
type BookSearchGet struct { type BookSearchGet 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"`
ID uint `json:"id"`
} }

View File

@@ -9,5 +9,6 @@ func BookDbToWs(b *model.Book) dto.BookSearchGet {
return dto.BookSearchGet{ return dto.BookSearchGet{
Title: b.Title, Title: b.Title,
Author: b.Author, Author: b.Author,
ID: b.ID,
} }
} }