v2 #43
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"mime/multipart"
|
||||
"net/http/httptest"
|
||||
|
@ -44,6 +45,7 @@ func TestEditorFormPost(t *testing.T) {
|
|||
owlApp := App(db)
|
||||
app := owlApp.FiberApp
|
||||
repo := infra.NewEntryRepository(db, owlApp.Registry)
|
||||
binRepo := infra.NewBinaryFileRepo(db)
|
||||
|
||||
fileDir, _ := os.Getwd()
|
||||
fileName := "../../test/fixtures/test.png"
|
||||
|
@ -51,11 +53,13 @@ func TestEditorFormPost(t *testing.T) {
|
|||
|
||||
file, err := os.Open(filePath)
|
||||
require.NoError(t, err)
|
||||
fileBytes, err := ioutil.ReadFile(filePath)
|
||||
require.NoError(t, err)
|
||||
defer file.Close()
|
||||
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
part, _ := writer.CreateFormFile("ImagePath", filepath.Base(file.Name()))
|
||||
part, _ := writer.CreateFormFile("ImageId", filepath.Base(file.Name()))
|
||||
io.Copy(part, file)
|
||||
part, _ = writer.CreateFormField("Content")
|
||||
io.WriteString(part, "test content")
|
||||
|
@ -72,6 +76,11 @@ func TestEditorFormPost(t *testing.T) {
|
|||
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)
|
||||
imageId := entry.MetaData().(*model.ImageEntryMetaData).ImageId
|
||||
require.NotZero(t, imageId)
|
||||
bin, err := binRepo.FindById(imageId)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, bin.Name, "test.png")
|
||||
require.Equal(t, fileBytes, bin.Data)
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package infra
|
||||
|
||||
import (
|
||||
"owl-blogs/app/repository"
|
||||
"owl-blogs/domain/model"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
@ -17,7 +18,7 @@ type DefaultBinaryFileRepo struct {
|
|||
db *sqlx.DB
|
||||
}
|
||||
|
||||
func NewBinaryFileRepo(db Database) *DefaultBinaryFileRepo {
|
||||
func NewBinaryFileRepo(db Database) repository.BinaryRepository {
|
||||
sqlxdb := db.Get()
|
||||
|
||||
// Create table if not exists
|
||||
|
|
|
@ -23,7 +23,7 @@ func NewWebApp(entryService *app.EntryService, typeRegistry *app.EntryTypeRegist
|
|||
rssHandler := NewRSSHandler(entryService)
|
||||
loginHandler := NewLoginHandler(entryService)
|
||||
editorListHandler := NewEditorListHandler(typeRegistry)
|
||||
editorHandler := NewEditorHandler(entryService, typeRegistry)
|
||||
editorHandler := NewEditorHandler(entryService, typeRegistry, binService)
|
||||
|
||||
// app.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
|
||||
app.Get("/", indexHandler.Handle)
|
||||
|
|
|
@ -3,6 +3,7 @@ package editor
|
|||
import (
|
||||
"fmt"
|
||||
"mime/multipart"
|
||||
"owl-blogs/app"
|
||||
"owl-blogs/domain/model"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
@ -21,7 +22,8 @@ type HttpFormData interface {
|
|||
}
|
||||
|
||||
type EditorEntryForm struct {
|
||||
entry model.Entry
|
||||
entry model.Entry
|
||||
binSvc *app.BinaryService
|
||||
}
|
||||
|
||||
type EntryFormFieldParams struct {
|
||||
|
@ -34,9 +36,10 @@ type EntryFormField struct {
|
|||
Params EntryFormFieldParams
|
||||
}
|
||||
|
||||
func NewEntryForm(entry model.Entry) *EditorEntryForm {
|
||||
func NewEntryForm(entry model.Entry, binaryService *app.BinaryService) *EditorEntryForm {
|
||||
return &EditorEntryForm{
|
||||
entry: entry,
|
||||
entry: entry,
|
||||
binSvc: binaryService,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +106,7 @@ func (s *EditorEntryForm) HtmlForm() (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
html := "<form method=\"POST\">\n"
|
||||
html := "<form method=\"POST\" enctype=\"multipart/form-data\">\n"
|
||||
for _, field := range fields {
|
||||
html += field.Html()
|
||||
}
|
||||
|
@ -126,13 +129,42 @@ func (s *EditorEntryForm) Parse(ctx HttpFormData) (model.Entry, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for field := range fields {
|
||||
fieldName := fields[field].Name
|
||||
fieldValue := ctx.FormValue(fieldName)
|
||||
metaField := metaVal.Elem().FieldByName(fieldName)
|
||||
if metaField.IsValid() {
|
||||
metaField.SetString(fieldValue)
|
||||
for _, field := range fields {
|
||||
fieldName := field.Name
|
||||
|
||||
if field.Params.InputType == "file" {
|
||||
file, err := ctx.FormFile(fieldName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fileData, err := file.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer fileData.Close()
|
||||
fileBytes := make([]byte, file.Size)
|
||||
_, err = fileData.Read(fileBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
binaryFile, err := s.binSvc.Create(file.Filename, fileBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
metaField := metaVal.Elem().FieldByName(fieldName)
|
||||
if metaField.IsValid() {
|
||||
metaField.SetString(binaryFile.Id)
|
||||
}
|
||||
} else {
|
||||
formValue := ctx.FormValue(fieldName)
|
||||
metaField := metaVal.Elem().FieldByName(fieldName)
|
||||
if metaField.IsValid() {
|
||||
metaField.SetString(formValue)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return s.entry, nil
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
package editor_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
"owl-blogs/app"
|
||||
"owl-blogs/domain/model"
|
||||
"owl-blogs/infra"
|
||||
"owl-blogs/test"
|
||||
"owl-blogs/web/editor"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -17,10 +25,41 @@ type MockEntryMetaData struct {
|
|||
}
|
||||
|
||||
type MockFormData struct {
|
||||
fileHeader *multipart.FileHeader
|
||||
}
|
||||
|
||||
func NewMockFormData() *MockFormData {
|
||||
fileDir, _ := os.Getwd()
|
||||
fileName := "../../test/fixtures/test.png"
|
||||
filePath := path.Join(fileDir, fileName)
|
||||
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
part, err := writer.CreateFormFile("ImagePath", filepath.Base(file.Name()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
io.Copy(part, file)
|
||||
writer.Close()
|
||||
|
||||
multipartForm := multipart.NewReader(body, writer.Boundary())
|
||||
formData, err := multipartForm.ReadForm(0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fileHeader := formData.File["ImagePath"][0]
|
||||
|
||||
return &MockFormData{fileHeader: fileHeader}
|
||||
}
|
||||
|
||||
func (f *MockFormData) FormFile(key string) (*multipart.FileHeader, error) {
|
||||
return nil, nil
|
||||
return f.fileHeader, nil
|
||||
}
|
||||
|
||||
func (f *MockFormData) FormValue(key string, defaultValue ...string) string {
|
||||
|
@ -75,7 +114,7 @@ func TestStructToFields(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestEditorEntryForm_HtmlForm(t *testing.T) {
|
||||
form := editor.NewEntryForm(&MockEntry{})
|
||||
form := editor.NewEntryForm(&MockEntry{}, nil)
|
||||
html, err := form.HtmlForm()
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, html, "<form")
|
||||
|
@ -87,15 +126,17 @@ func TestEditorEntryForm_HtmlForm(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFormParseNil(t *testing.T) {
|
||||
form := editor.NewEntryForm(&MockEntry{})
|
||||
form := editor.NewEntryForm(&MockEntry{}, nil)
|
||||
_, err := form.Parse(nil)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestFormParse(t *testing.T) {
|
||||
form := editor.NewEntryForm(&MockEntry{})
|
||||
entry, err := form.Parse(&MockFormData{})
|
||||
binRepo := infra.NewBinaryFileRepo(test.NewMockDb())
|
||||
binService := app.NewBinaryFileService(binRepo)
|
||||
form := editor.NewEntryForm(&MockEntry{}, binService)
|
||||
entry, err := form.Parse(NewMockFormData())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "Image", entry.MetaData().(*MockEntryMetaData).Image)
|
||||
require.NotZero(t, entry.MetaData().(*MockEntryMetaData).Image)
|
||||
require.Equal(t, "Content", entry.MetaData().(*MockEntryMetaData).Content)
|
||||
}
|
||||
|
|
|
@ -11,11 +11,12 @@ import (
|
|||
|
||||
type EditorHandler struct {
|
||||
entrySvc *app.EntryService
|
||||
binSvc *app.BinaryService
|
||||
registry *app.EntryTypeRegistry
|
||||
}
|
||||
|
||||
func NewEditorHandler(entryService *app.EntryService, registry *app.EntryTypeRegistry) *EditorHandler {
|
||||
return &EditorHandler{entrySvc: entryService, registry: registry}
|
||||
func NewEditorHandler(entryService *app.EntryService, registry *app.EntryTypeRegistry, binService *app.BinaryService) *EditorHandler {
|
||||
return &EditorHandler{entrySvc: entryService, registry: registry, binSvc: binService}
|
||||
}
|
||||
|
||||
func (h *EditorHandler) paramToEntry(c *fiber.Ctx) (model.Entry, error) {
|
||||
|
@ -35,7 +36,7 @@ func (h *EditorHandler) HandleGet(c *fiber.Ctx) error {
|
|||
return err
|
||||
}
|
||||
|
||||
form := editor.NewEntryForm(entryType)
|
||||
form := editor.NewEntryForm(entryType, h.binSvc)
|
||||
htmlForm, err := form.HtmlForm()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -51,7 +52,7 @@ func (h *EditorHandler) HandlePost(c *fiber.Ctx) error {
|
|||
return err
|
||||
}
|
||||
|
||||
form := editor.NewEntryForm(entryType)
|
||||
form := editor.NewEntryForm(entryType, h.binSvc)
|
||||
// get form data
|
||||
entry, err := form.Parse(c)
|
||||
if err != nil {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{{define "main"}}
|
||||
|
||||
{{.MetaData.ImagePath}}
|
||||
{{.MetaData.ImageId}}
|
||||
|
||||
<p>
|
||||
{{.Content}}
|
||||
|
|
Loading…
Reference in New Issue