♻️ Updated target page searching
This commit is contained in:
parent
9bd2f81c46
commit
9d128a7665
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/adrg/frontmatter"
|
||||
"golang.org/x/text/language"
|
||||
|
@ -38,12 +37,12 @@ func NewFileSystemPageRepository(rootDir fs.FS) page.Repository {
|
|||
}
|
||||
|
||||
func (repo *fileSystemPageRepository) Get(ctx context.Context, lang language.Tag, path string) (*domain.Page, error) {
|
||||
target := "index." + lang.String() + ".md"
|
||||
if lang == language.Und {
|
||||
target = "index.md"
|
||||
ext := ".md"
|
||||
if lang != language.Und {
|
||||
ext = "." + lang.String() + ext
|
||||
}
|
||||
|
||||
target = filepath.Join(path, target)
|
||||
target := path + ext
|
||||
|
||||
f, err := repo.dir.Open(target)
|
||||
if err != nil {
|
||||
|
|
|
@ -18,38 +18,38 @@ func TestGet(t *testing.T) {
|
|||
t.Parallel()
|
||||
|
||||
testData := fstest.MapFS{
|
||||
filepath.Join("index.ru.md"): &fstest.MapFile{
|
||||
Data: []byte("---\ntitle: страница\n---\nпривет, мир!\n"),
|
||||
},
|
||||
filepath.Join("dir", "index.en.md"): &fstest.MapFile{
|
||||
Data: []byte("---\ntitle: page\n---\nhello, world!\n"),
|
||||
},
|
||||
filepath.Join("both", "index.md"): &fstest.MapFile{Data: []byte("both/index.md")},
|
||||
filepath.Join("both.md"): &fstest.MapFile{Data: []byte("both.md")},
|
||||
filepath.Join("file.md"): &fstest.MapFile{Data: []byte("file.md")},
|
||||
filepath.Join("folder", "index.md"): &fstest.MapFile{Data: []byte("folder/index.md")},
|
||||
filepath.Join("index.md"): &fstest.MapFile{Data: []byte("index.md")},
|
||||
}
|
||||
|
||||
repo := repository.NewFileSystemPageRepository(testData)
|
||||
|
||||
for name, tc := range map[string]struct {
|
||||
lang language.Tag
|
||||
expect *domain.Page
|
||||
path string
|
||||
input string
|
||||
}{
|
||||
"file": {
|
||||
lang: language.English,
|
||||
path: path.Join("dir"),
|
||||
expect: &domain.Page{
|
||||
Language: language.English,
|
||||
Title: "page",
|
||||
Content: []byte("hello, world!\n"),
|
||||
},
|
||||
"index": {
|
||||
input: path.Join("index"),
|
||||
expect: &domain.Page{Content: []byte("index.md")},
|
||||
},
|
||||
"dir": {
|
||||
lang: language.Russian,
|
||||
path: path.Join(""),
|
||||
expect: &domain.Page{
|
||||
Language: language.Russian,
|
||||
Title: "страница",
|
||||
Content: []byte("привет, мир!\n"),
|
||||
},
|
||||
"file": {
|
||||
input: path.Join("file"),
|
||||
expect: &domain.Page{Content: []byte("file.md")},
|
||||
},
|
||||
"folder": {
|
||||
input: path.Join("folder", "index"),
|
||||
expect: &domain.Page{Content: []byte("folder/index.md")},
|
||||
},
|
||||
"both-file": {
|
||||
input: path.Join("both"),
|
||||
expect: &domain.Page{Content: []byte("both.md")},
|
||||
},
|
||||
"both-folder": {
|
||||
input: path.Join("both", "index"),
|
||||
expect: &domain.Page{Content: []byte("both/index.md")},
|
||||
},
|
||||
} {
|
||||
name, tc := name, tc
|
||||
|
@ -57,7 +57,7 @@ func TestGet(t *testing.T) {
|
|||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
out, err := repo.Get(context.Background(), tc.lang, tc.path)
|
||||
out, err := repo.Get(context.Background(), language.Und, tc.input)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package page
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
|
||||
|
@ -11,3 +12,5 @@ import (
|
|||
type UseCase interface {
|
||||
Do(ctx context.Context, lang language.Tag, path string) (*domain.Page, error)
|
||||
}
|
||||
|
||||
var ErrNotExist error = errors.New("page not exists")
|
||||
|
|
|
@ -3,11 +3,13 @@ package usecase
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"source.toby3d.me/toby3d/home/internal/domain"
|
||||
"source.toby3d.me/toby3d/home/internal/page"
|
||||
"source.toby3d.me/toby3d/home/internal/urlutil"
|
||||
)
|
||||
|
||||
type pageUseCase struct {
|
||||
|
@ -20,11 +22,32 @@ func NewPageUseCase(pages page.Repository) page.UseCase {
|
|||
}
|
||||
}
|
||||
|
||||
func (ucase *pageUseCase) Do(ctx context.Context, lang language.Tag, path string) (*domain.Page, error) {
|
||||
page, err := ucase.pages.Get(ctx, lang, path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot find '%s' page: %w", path, err)
|
||||
func (ucase *pageUseCase) Do(ctx context.Context, lang language.Tag, p string) (*domain.Page, error) {
|
||||
ext := path.Ext(p)
|
||||
if ext == ".html" {
|
||||
p = p[:len(p)-len(ext)]
|
||||
}
|
||||
|
||||
return page, nil
|
||||
hasTrailingSlash := p[len(p)-1] == '/'
|
||||
head, tail := urlutil.ShiftPath(p)
|
||||
targets := []string{path.Join(head, tail)}
|
||||
|
||||
if tail == "/" {
|
||||
if hasTrailingSlash || ext == "" {
|
||||
targets = append([]string{path.Join(head, "index")}, targets...)
|
||||
}
|
||||
|
||||
targets = append(targets, head)
|
||||
}
|
||||
|
||||
for i := range targets {
|
||||
out, err := ucase.pages.Get(ctx, lang, targets[i])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("cannot find page on path '%s': %w", p, page.ErrNotExist)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package usecase_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
pagefsrepo "source.toby3d.me/toby3d/home/internal/page/repository/fs"
|
||||
"source.toby3d.me/toby3d/home/internal/page/usecase"
|
||||
)
|
||||
|
||||
func TestDo(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
pages := pagefsrepo.NewFileSystemPageRepository(fstest.MapFS{
|
||||
filepath.Join("both", "index.md"): &fstest.MapFile{Data: []byte(`both/index.md`)},
|
||||
filepath.Join("folder", "index.md"): &fstest.MapFile{Data: []byte(`folder/index.md`)},
|
||||
filepath.Join("both.md"): &fstest.MapFile{Data: []byte(`both.md`)},
|
||||
filepath.Join("file.md"): &fstest.MapFile{Data: []byte(`file.md`)},
|
||||
filepath.Join("index.md"): &fstest.MapFile{Data: []byte(`index.md`)},
|
||||
})
|
||||
|
||||
ucase := usecase.NewPageUseCase(pages)
|
||||
|
||||
for name, tc := range map[string]struct {
|
||||
input string
|
||||
expect []byte
|
||||
}{
|
||||
"file": {input: "/file", expect: []byte(`file.md`)},
|
||||
"file-slash": {input: "/file/", expect: []byte(`file.md`)},
|
||||
"file-ext": {input: "/file.html", expect: []byte(`file.md`)},
|
||||
"folder": {input: "/folder", expect: []byte(`folder/index.md`)},
|
||||
"folder-slash": {input: "/folder/", expect: []byte(`folder/index.md`)},
|
||||
"folder-index": {input: "/folder/index.html", expect: []byte(`folder/index.md`)},
|
||||
"both": {input: "/both", expect: []byte(`both/index.md`)},
|
||||
"both-slash": {input: "/both/", expect: []byte(`both/index.md`)},
|
||||
"both-ext": {input: "/both.html", expect: []byte(`both.md`)},
|
||||
"both-index": {input: "/both/index.html", expect: []byte(`both/index.md`)},
|
||||
} {
|
||||
name, tc := name, tc
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
actual, err := ucase.Do(context.Background(), language.Und, tc.input)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(string(actual.Content), string(tc.expect)); diff != "" {
|
||||
t.Error(diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -37,11 +37,13 @@ func NewFileSystemSiteRepository(rootDir fs.FS) site.Repository {
|
|||
}
|
||||
|
||||
func (repo *fileSystemSiteRepository) Get(ctx context.Context, lang language.Tag) (*domain.Site, error) {
|
||||
target := "index." + lang.String() + ".md"
|
||||
if lang == language.Und {
|
||||
target = "index.md"
|
||||
ext := ".md"
|
||||
if lang != language.Und {
|
||||
ext = "." + lang.String() + ext
|
||||
}
|
||||
|
||||
target := "index" + ext
|
||||
|
||||
f, err := repo.dir.Open(target)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot open '%s' site file: %w", target, err)
|
||||
|
|
Loading…
Reference in New Issue