first entry created and displayed

This commit is contained in:
Niko Abeler 2023-07-07 21:04:25 +02:00
parent d3784b0337
commit 28fd4f1dc2
9 changed files with 120 additions and 24 deletions

View File

@ -0,0 +1,23 @@
package app_test
import (
"owl-blogs/app"
"owl-blogs/test"
"testing"
"github.com/stretchr/testify/require"
)
func TestRegistryTypeNameNotExisting(t *testing.T) {
register := app.NewEntryTypeRegistry()
_, err := register.TypeName(&test.MockEntry{})
require.Error(t, err)
}
func TestRegistryTypeName(t *testing.T) {
register := app.NewEntryTypeRegistry()
register.Register(&test.MockEntry{})
name, err := register.TypeName(&test.MockEntry{})
require.NoError(t, err)
require.Equal(t, "MockEntry", name)
}

View File

@ -3,18 +3,34 @@ package main
import ( import (
"bytes" "bytes"
"io" "io"
"math/rand"
"mime/multipart" "mime/multipart"
"net/http/httptest" "net/http/httptest"
"os" "os"
"owl-blogs/domain/model"
"owl-blogs/infra"
"path" "path"
"path/filepath" "path/filepath"
"strings"
"testing" "testing"
"time"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func testDbName() string {
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
rand.Seed(time.Now().UnixNano())
b := make([]rune, 6)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return "/tmp/" + string(b) + ".db"
}
func TestEditorFormGet(t *testing.T) { func TestEditorFormGet(t *testing.T) {
app := App().FiberApp db := infra.NewSqliteDB(testDbName())
app := App(db).FiberApp
req := httptest.NewRequest("GET", "/editor/ImageEntry", nil) req := httptest.NewRequest("GET", "/editor/ImageEntry", nil)
resp, err := app.Test(req) resp, err := app.Test(req)
@ -23,7 +39,11 @@ func TestEditorFormGet(t *testing.T) {
} }
func TestEditorFormPost(t *testing.T) { func TestEditorFormPost(t *testing.T) {
app := App().FiberApp dbName := testDbName()
db := infra.NewSqliteDB(dbName)
owlApp := App(db)
app := owlApp.FiberApp
repo := infra.NewEntryRepository(db, owlApp.Registry)
fileDir, _ := os.Getwd() fileDir, _ := os.Getwd()
fileName := "../../test/fixtures/test.png" fileName := "../../test/fixtures/test.png"
@ -41,8 +61,17 @@ func TestEditorFormPost(t *testing.T) {
io.WriteString(part, "test content") io.WriteString(part, "test content")
writer.Close() writer.Close()
req := httptest.NewRequest("POST", "/editor/ImageEntry", nil) req := httptest.NewRequest("POST", "/editor/ImageEntry", body)
req.Header.Set("Content-Type", writer.FormDataContentType())
resp, err := app.Test(req) resp, err := app.Test(req)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode) require.Equal(t, 302, resp.StatusCode)
require.Contains(t, resp.Header.Get("Location"), "/posts/")
id := strings.Split(resp.Header.Get("Location"), "/")[2]
entry, err := repo.FindById(id)
require.NoError(t, err)
require.Equal(t, "test content", entry.MetaData().(*model.ImageEntryMetaData).Content)
// require.Equal(t, "test.png", entry.MetaData().(*model.ImageEntryMetaData).ImagePath)
} }

View File

@ -7,8 +7,9 @@ import (
"owl-blogs/web" "owl-blogs/web"
) )
func App() *web.WebApp { const DbPath = "owlblogs.db"
db := infra.NewSqliteDB("owlblogs.db")
func App(db infra.Database) *web.WebApp {
registry := app.NewEntryTypeRegistry() registry := app.NewEntryTypeRegistry()
registry.Register(&model.ImageEntry{}) registry.Register(&model.ImageEntry{})
@ -20,5 +21,6 @@ func App() *web.WebApp {
} }
func main() { func main() {
App().Run() db := infra.NewSqliteDB(DbPath)
App(db).Run()
} }

View File

@ -9,8 +9,8 @@ type ImageEntry struct {
} }
type ImageEntryMetaData struct { type ImageEntryMetaData struct {
ImagePath string `owl:"inputType=file"` ImagePath string `owl:"inputType=file"`
Content EntryContent `owl:"inputType=text widget=textarea"` Content string `owl:"inputType=text widget=textarea"`
} }
func (e *ImageEntry) ID() string { func (e *ImageEntry) ID() string {
@ -18,7 +18,7 @@ func (e *ImageEntry) ID() string {
} }
func (e *ImageEntry) Content() EntryContent { func (e *ImageEntry) Content() EntryContent {
return e.meta.Content return EntryContent(e.meta.Content)
} }
func (e *ImageEntry) PublishedAt() *time.Time { func (e *ImageEntry) PublishedAt() *time.Time {
@ -26,10 +26,7 @@ func (e *ImageEntry) PublishedAt() *time.Time {
} }
func (e *ImageEntry) MetaData() interface{} { func (e *ImageEntry) MetaData() interface{} {
return &ImageEntryMetaData{ return &e.meta
ImagePath: e.meta.ImagePath,
Content: e.meta.Content,
}
} }
func (e *ImageEntry) Create(id string, publishedAt *time.Time, metaData EntryMetaData) error { func (e *ImageEntry) Create(id string, publishedAt *time.Time, metaData EntryMetaData) error {

View File

@ -8,7 +8,8 @@ import (
type WebApp struct { type WebApp struct {
FiberApp *fiber.App FiberApp *fiber.App
entryService *app.EntryService EntryService *app.EntryService
Registry *app.EntryTypeRegistry
} }
func NewWebApp(entryService *app.EntryService, typeRegistry *app.EntryTypeRegistry) *WebApp { func NewWebApp(entryService *app.EntryService, typeRegistry *app.EntryTypeRegistry) *WebApp {
@ -16,7 +17,7 @@ func NewWebApp(entryService *app.EntryService, typeRegistry *app.EntryTypeRegist
indexHandler := NewIndexHandler(entryService) indexHandler := NewIndexHandler(entryService)
listHandler := NewListHandler(entryService) listHandler := NewListHandler(entryService)
entryHandler := NewEntryHandler(entryService) entryHandler := NewEntryHandler(entryService, typeRegistry)
mediaHandler := NewMediaHandler(entryService) mediaHandler := NewMediaHandler(entryService)
rssHandler := NewRSSHandler(entryService) rssHandler := NewRSSHandler(entryService)
loginHandler := NewLoginHandler(entryService) loginHandler := NewLoginHandler(entryService)
@ -50,7 +51,7 @@ func NewWebApp(entryService *app.EntryService, typeRegistry *app.EntryTypeRegist
// app.Post("/auth/token/", userAuthTokenHandler(repo)) // app.Post("/auth/token/", userAuthTokenHandler(repo))
// app.Get("/.well-known/oauth-authorization-server", userAuthMetadataHandler(repo)) // app.Get("/.well-known/oauth-authorization-server", userAuthMetadataHandler(repo))
// app.NotFound = http.HandlerFunc(notFoundHandler(repo)) // app.NotFound = http.HandlerFunc(notFoundHandler(repo))
return &WebApp{FiberApp: app, entryService: entryService} return &WebApp{FiberApp: app, EntryService: entryService, Registry: typeRegistry}
} }
func (w *WebApp) Run() { func (w *WebApp) Run() {

View File

@ -53,18 +53,17 @@ func (h *EditorHandler) HandlePost(c *fiber.Ctx) error {
form := editor.NewEntryForm(entryType) form := editor.NewEntryForm(entryType)
// get form data // get form data
metaData, err := form.Parse(c) entry, err := form.Parse(c)
if err != nil { if err != nil {
return err return err
} }
// create entry // create entry
now := time.Now() now := time.Now()
entry := entryType err = h.entrySvc.Create(entry, &now, entry.MetaData())
err = h.entrySvc.Create(entry, &now, metaData.MetaData())
if err != nil { if err != nil {
return err return err
} }
return c.Redirect("/posts/" + entry.ID() + "/")
return c.SendString("Hello, Editor!")
} }

View File

@ -2,18 +2,46 @@ package web
import ( import (
"owl-blogs/app" "owl-blogs/app"
"owl-blogs/domain/model"
"text/template"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
type EntryHandler struct { type EntryHandler struct {
entrySvc *app.EntryService entrySvc *app.EntryService
registry *app.EntryTypeRegistry
} }
func NewEntryHandler(entryService *app.EntryService) *EntryHandler { func NewEntryHandler(entryService *app.EntryService, registry *app.EntryTypeRegistry) *EntryHandler {
return &EntryHandler{entrySvc: entryService} return &EntryHandler{entrySvc: entryService, registry: registry}
}
func (h *EntryHandler) getTemplate(entry model.Entry) (*template.Template, error) {
name, err := h.registry.TypeName(entry)
if err != nil {
return nil, err
}
return template.ParseFS(
templates,
"templates/base.tmpl",
"templates/views/entry/"+name+".tmpl",
)
} }
func (h *EntryHandler) Handle(c *fiber.Ctx) error { func (h *EntryHandler) Handle(c *fiber.Ctx) error {
return c.SendString("Hello, RSS!") c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
entryId := c.Params("post")
entry, err := h.entrySvc.FindById(entryId)
if err != nil {
return err
}
template, err := h.getTemplate(entry)
if err != nil {
return err
}
return template.ExecuteTemplate(c, "base", entry)
} }

View File

@ -0,0 +1,17 @@
{{define "title"}}Image Entry{{end}}
{{define "main"}}
{{.MetaData.ImagePath}}
<p>
{{.Content}}
</p>
<p>
Published: {{.PublishedAt}}
</p>
{{end}}