Merge pull request #13 from KristianJBorgwarth/feat/improve-crud-api
feat: improve create api
This commit is contained in:
commit
f9b9a06b70
5 changed files with 51 additions and 28 deletions
|
|
@ -3,6 +3,7 @@ package handlers
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/KristianJBorgwarth/dendrite.daemon/core/frontmatter"
|
||||
"github.com/KristianJBorgwarth/dendrite.daemon/core/models"
|
||||
|
|
@ -35,7 +36,12 @@ func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (an
|
|||
|
||||
slug := frontmatter.Slugify(cmd.Title)
|
||||
|
||||
templatePath := store.GetVaultStore().GetTemplatePath(cmd.TemplateName)
|
||||
var templatePath string
|
||||
if cmd.TemplateName != "" {
|
||||
templatePath = store.GetVaultStore().GetTemplatePath(cmd.TemplateName)
|
||||
}
|
||||
|
||||
notePath := filepath.Join(store.GetVaultStore().Config.VaultPath(), cmd.Directory, slug+".md")
|
||||
|
||||
data, err := template.RenderTemplate(templatePath, cmd.Title, slug)
|
||||
if err != nil {
|
||||
|
|
@ -82,7 +88,7 @@ func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (an
|
|||
|
||||
tagModels = append(tagModels, dbTags...)
|
||||
|
||||
note := models.CreateNote(cmd.Directory, cmd.Title, slug)
|
||||
note := models.CreateNote(notePath, cmd.Title, slug)
|
||||
|
||||
if err = noteRepo.Upsert(ctx, note); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -92,11 +98,11 @@ func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (an
|
|||
return nil, err
|
||||
}
|
||||
|
||||
h.uow.FileStore.Stage(cmd.Directory, data)
|
||||
h.uow.FileStore.Stage(notePath, data)
|
||||
|
||||
if err = h.uow.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cmd.Directory, nil
|
||||
return notePath, nil
|
||||
}
|
||||
|
|
|
|||
BIN
dendrite
BIN
dendrite
Binary file not shown.
|
|
@ -1,6 +1,8 @@
|
|||
package store
|
||||
|
||||
import "os"
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
type FileStore struct {
|
||||
staged []stagedFile
|
||||
|
|
@ -28,7 +30,6 @@ func (fs *FileStore) Flush() error {
|
|||
if fs.fileExists(file.path) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := os.WriteFile(file.path, file.data, 0o644); err != nil {
|
||||
for _, path := range writtenPaths {
|
||||
_ = os.Remove(path)
|
||||
|
|
@ -58,4 +59,3 @@ func (fs *FileStore) fileExists(path string) bool {
|
|||
_, err := os.Stat(path)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,11 +14,13 @@ import (
|
|||
func TestCreateNoteHandler_NoTemplate_CreatesNoteFileAndReturnsPath(t *testing.T) {
|
||||
// Arrange
|
||||
handler := handlers.NewCreateNoteHandler()
|
||||
|
||||
notePath := filepath.Join(t.TempDir(), "my-note.md")
|
||||
|
||||
vaultPath := Fixture.VaultStore.Config.VaultPath()
|
||||
notePath := filepath.Join(vaultPath, "my-note.md")
|
||||
params, _ := json.Marshal(map[string]any{
|
||||
"title": "My Note",
|
||||
"path": notePath,
|
||||
"title": "My Note",
|
||||
"templateName": "",
|
||||
"directory": "",
|
||||
})
|
||||
|
||||
// Act
|
||||
|
|
@ -39,16 +41,23 @@ func TestCreateNoteHandler_NoTemplate_CreatesNoteFileAndReturnsPath(t *testing.T
|
|||
func TestCreateNoteHandler_WithTemplate_CreatesNoteFileWithTagsAndReturnsPath(t *testing.T) {
|
||||
// Arrange
|
||||
handler := handlers.NewCreateNoteHandler()
|
||||
dir := t.TempDir()
|
||||
|
||||
templatePath := filepath.Join(dir, "template.md")
|
||||
vaultPath := Fixture.VaultStore.Config.VaultPath()
|
||||
templateDir := Fixture.VaultStore.Config.TemplateDirectory()
|
||||
require.NoError(t, os.MkdirAll(templateDir, 0o755))
|
||||
|
||||
templatePath := filepath.Join(templateDir, "template.md")
|
||||
require.NoError(t, os.WriteFile(templatePath, []byte("---\ntitle: Template\ntags: [go, testing]\n---\n"), 0o644))
|
||||
defer os.Remove(templatePath)
|
||||
|
||||
notePath := filepath.Join(dir, "templated-note.md")
|
||||
subDir := "subdir"
|
||||
require.NoError(t, os.MkdirAll(filepath.Join(vaultPath, subDir), 0o755))
|
||||
defer os.RemoveAll(filepath.Join(vaultPath, subDir))
|
||||
notePath := filepath.Join(vaultPath, subDir, "templated-note.md")
|
||||
params, _ := json.Marshal(map[string]any{
|
||||
"title": "Templated Note",
|
||||
"path": notePath,
|
||||
"templatePath": templatePath,
|
||||
"templateName": "template.md",
|
||||
"directory": subDir,
|
||||
})
|
||||
|
||||
// Act
|
||||
|
|
@ -80,17 +89,21 @@ func TestCreateNoteHandler_WithTemplate_CreatesNoteFileWithTagsAndReturnsPath(t
|
|||
|
||||
func TestCreateNoteHandler_DuplicateSlug_Upserts(t *testing.T) {
|
||||
// Arrange
|
||||
dir := t.TempDir()
|
||||
handler := handlers.NewCreateNoteHandler()
|
||||
|
||||
|
||||
path1 := filepath.Join(dir, "dup-note.md")
|
||||
params1, _ := json.Marshal(map[string]any{"title": "Dup Note", "path": path1})
|
||||
vaultPath := Fixture.VaultStore.Config.VaultPath()
|
||||
subDir := "dup-dir"
|
||||
require.NoError(t, os.MkdirAll(filepath.Join(vaultPath, subDir), 0o755))
|
||||
defer os.RemoveAll(filepath.Join(vaultPath, subDir))
|
||||
|
||||
params1, _ := json.Marshal(map[string]any{"title": "Dup Note", "templateName": "", "directory": subDir})
|
||||
_, err := handler.Handle(Fixture.TestContext, params1)
|
||||
require.NoError(t, err)
|
||||
|
||||
path2 := filepath.Join(dir, "dup-note-moved.md")
|
||||
params2, _ := json.Marshal(map[string]any{"title": "Dup Note", "path": path2})
|
||||
subDir2 := "dup-dir-moved"
|
||||
require.NoError(t, os.MkdirAll(filepath.Join(vaultPath, subDir2), 0o755))
|
||||
defer os.RemoveAll(filepath.Join(vaultPath, subDir2))
|
||||
params2, _ := json.Marshal(map[string]any{"title": "Dup Note", "templateName": "", "directory": subDir2})
|
||||
|
||||
// Act
|
||||
_, err = handler.Handle(Fixture.TestContext, params2)
|
||||
|
|
@ -102,15 +115,15 @@ func TestCreateNoteHandler_DuplicateSlug_Upserts(t *testing.T) {
|
|||
require.NoError(t, Fixture.DB.QueryRow(`SELECT COUNT(*) FROM notes WHERE slug = ?`, "dup-note").Scan(&count))
|
||||
assert.Equal(t, 1, count)
|
||||
|
||||
expectedPath := filepath.Join(vaultPath, subDir2, "dup-note.md")
|
||||
var path string
|
||||
require.NoError(t, Fixture.DB.QueryRow(`SELECT path FROM notes WHERE slug = ?`, "dup-note").Scan(&path))
|
||||
assert.Equal(t, path2, path)
|
||||
assert.Equal(t, expectedPath, path)
|
||||
}
|
||||
|
||||
func TestCreateNoteHandler_InvalidJSON_ReturnsError(t *testing.T) {
|
||||
// Arrange
|
||||
handler := handlers.NewCreateNoteHandler()
|
||||
|
||||
|
||||
// Act
|
||||
_, err := handler.Handle(Fixture.TestContext, json.RawMessage(`{invalid json}`))
|
||||
|
|
@ -119,14 +132,14 @@ func TestCreateNoteHandler_InvalidJSON_ReturnsError(t *testing.T) {
|
|||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestCreateNoteHandler_NonExistentTemplatePath_ReturnsError(t *testing.T) {
|
||||
func TestCreateNoteHandler_NonExistentTemplateName_ReturnsError(t *testing.T) {
|
||||
// Arrange
|
||||
handler := handlers.NewCreateNoteHandler()
|
||||
|
||||
|
||||
params, _ := json.Marshal(map[string]any{
|
||||
"title": "Ghost Note",
|
||||
"path": filepath.Join(t.TempDir(), "ghost.md"),
|
||||
"templatePath": "/non/existent/template.md",
|
||||
"templateName": "non-existent-template",
|
||||
"directory": "",
|
||||
})
|
||||
|
||||
// Act
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@ import (
|
|||
"database/sql"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/KristianJBorgwarth/dendrite.daemon/core/rpc"
|
||||
"github.com/KristianJBorgwarth/dendrite.daemon/persistence"
|
||||
"github.com/KristianJBorgwarth/dendrite.daemon/persistence/store"
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
|
|
@ -17,6 +19,7 @@ type DBFixture struct {
|
|||
DB *sql.DB
|
||||
DBPath string
|
||||
TestContext context.Context
|
||||
VaultStore *store.VaultStore
|
||||
}
|
||||
|
||||
func NewDBFixture() *DBFixture {
|
||||
|
|
@ -35,6 +38,7 @@ func NewDBFixture() *DBFixture {
|
|||
DB: dbContext.DB,
|
||||
DBPath: dbPath,
|
||||
TestContext: context.Background(),
|
||||
VaultStore: store.NewVaultStore(vaultPath, path.Join(vaultPath, "templates")),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue