aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--go.mod2
-rw-r--r--internal/db/redis/image.go16
-rw-r--r--internal/image/handler.go32
-rw-r--r--internal/image/image_test.go61
-rw-r--r--internal/image/model.go2
-rw-r--r--internal/image/service.go14
-rw-r--r--templates/pages/image.tmpl3
7 files changed, 111 insertions, 19 deletions
diff --git a/go.mod b/go.mod
index 0209999..2332a46 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
github.com/gomodule/redigo v2.0.0+incompatible
github.com/matoous/go-nanoid v1.3.0
github.com/muyo/sno v1.1.0
- github.com/pkg/errors v0.9.1 // indirect
+ github.com/pkg/errors v0.9.1
github.com/rafaeljusto/redigomock v2.3.0+incompatible
github.com/speps/go-hashids v2.0.0+incompatible
github.com/stretchr/testify v1.5.1
diff --git a/internal/db/redis/image.go b/internal/db/redis/image.go
index 1f4e8fa..f216531 100644
--- a/internal/db/redis/image.go
+++ b/internal/db/redis/image.go
@@ -1,6 +1,7 @@
package redis
import (
+ "errors"
"fmt"
"log"
@@ -11,6 +12,8 @@ import (
const V1FilePathFmt = "v1imagepost:%s"
+var ErrNotFound error = errors.New("Not Found")
+
// ImageRepo deps. for storage
type ImageRepo struct {
db *redis.Pool
@@ -23,14 +26,14 @@ func NewRedisImageRepo(conn *redis.Pool) *ImageRepo {
}
}
-func fileKey(filename, V1FilePathFmt string) string {
- return fmt.Sprintf(V1FilePathFmt, filename)
+func fileKey(imageID, V1FilePathFmt string) string {
+ return fmt.Sprintf(V1FilePathFmt, imageID)
}
-func (r *ImageRepo) AddNewFile(filename string, meta *image.PostMeta, timeout int) error {
+func (r *ImageRepo) AddNewFile(imageID string, meta *image.PostMeta, timeout int) error {
conn := r.db.Get()
defer conn.Close()
- key := fileKey(filename, V1FilePathFmt)
+ key := fileKey(imageID, V1FilePathFmt)
_, err := conn.Do("HMSET", redis.Args{}.Add(key).AddFlat(meta)...)
if err != nil {
log.Fatal(err)
@@ -45,8 +48,11 @@ func (r *ImageRepo) GetFile(fileUrl string) (*image.PostMeta, error) {
key := fileKey(fileUrl, V1FilePathFmt)
res, err := redis.Values(conn.Do("HGETALL", key))
if err != nil {
- return &image.PostMeta{}, err
+ return &image.PostMeta{}, ErrNotFound
}
err = redis.ScanStruct(res, imageMeta)
+ if imageMeta.FilePath == "" {
+ return &image.PostMeta{}, ErrNotFound
+ }
return imageMeta, err
}
diff --git a/internal/image/handler.go b/internal/image/handler.go
index 2db4c40..f41ed4d 100644
--- a/internal/image/handler.go
+++ b/internal/image/handler.go
@@ -2,6 +2,7 @@ package image
import (
"fmt"
+ "html/template"
"io/ioutil"
"log"
"net/http"
@@ -40,9 +41,13 @@ func (h *imageHandler) GetImage(w http.ResponseWriter, r *http.Request) {
}
fileUrl := fmt.Sprintf("/f/%s", fileMeta.FilePath)
data := struct {
- ImageUrl string
+ ImageUrl string
+ ImageTitle string
+ ImageDesc string
}{
fileUrl,
+ fileMeta.Title,
+ fileMeta.Desc,
}
h.service.Render(w, "image.tmpl", data)
}
@@ -79,7 +84,30 @@ func (h *imageHandler) PostImage(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Incorrect Content Type"))
return
}
- fileName, fileID, err := h.service.AddFile(extension, fileType, fileBytes)
+ formData := r.PostForm
+ rawPostTitle := formData.Get("title")
+ rawPostDesc := formData.Get("desc")
+ postTitle := template.HTMLEscapeString(rawPostTitle)
+ postDesc := template.HTMLEscapeString(rawPostDesc)
+
+ if len(rawPostDesc) != len(postDesc) {
+ log.Printf("description not clean")
+ w.WriteHeader(400)
+ w.Write([]byte("Incorrect Content Type"))
+ return
+ }
+ if len(rawPostTitle) != len(postTitle) {
+ log.Printf("invalid title")
+ w.WriteHeader(400)
+ w.Write([]byte("Invalid image meta data"))
+ return
+ }
+ postMeta := &PostMeta{
+ MimeType: fileType,
+ Title: postTitle,
+ Desc: postDesc,
+ }
+ fileName, fileID, err := h.service.AddFile(extension, postMeta, fileBytes)
if err != nil {
log.Printf("failed to write file")
w.WriteHeader(500)
diff --git a/internal/image/image_test.go b/internal/image/image_test.go
index 3425213..daf4aea 100644
--- a/internal/image/image_test.go
+++ b/internal/image/image_test.go
@@ -16,6 +16,7 @@ import (
"strings"
"testing"
+ "github.com/go-chi/chi"
"github.com/gomodule/redigo/redis"
"github.com/rafaeljusto/redigomock"
_ "github.com/stretchr/testify/mock"
@@ -27,6 +28,7 @@ import (
var (
projectRoot string
+ emptyBody *bytes.Buffer = bytes.NewBuffer([]byte(``))
)
func init() {
@@ -83,6 +85,34 @@ func prepareRequest(t *testing.T, filename, mimeType string) (*multipart.Writer,
return writer, body, err
}
+func prepareImage() (*redigomock.Conn, image.Handler) {
+ // setup redis for tests
+ conn := redigomock.NewConn()
+ pool := &redis.Pool{
+ // Return the same connection mock for each Get() call.
+ Dial: func() (redis.Conn, error) { return conn, nil },
+ MaxIdle: 10,
+ }
+ repo := db.NewRedisImageRepo(pool)
+
+ // setup image package
+ imageBuildDir, err := ioutil.TempDir("", "test-images")
+ if err != nil {
+ log.Fatal(err)
+ }
+ cwd, _ := os.Getwd()
+ base := filepath.Join(cwd, "templates")
+ renderer, err := tmpl.NewHTMLTmpl(base)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer os.RemoveAll(imageBuildDir)
+ imageService := image.NewService(repo, imageBuildDir, renderer)
+ imageHandler := image.NewHandler(imageService)
+ return conn, imageHandler
+
+}
+
func TestPostImage(t *testing.T) {
// setup redis for tests
conn := redigomock.NewConn()
@@ -91,7 +121,14 @@ func TestPostImage(t *testing.T) {
Dial: func() (redis.Conn, error) { return conn, nil },
MaxIdle: 10,
}
- conn.Command("HMSET", redigomock.NewAnyData(), redigomock.NewAnyData(), redigomock.NewAnyData(), redigomock.NewAnyData(), redigomock.NewAnyData(), redigomock.NewAnyData(), redigomock.NewAnyData(), redigomock.NewAnyData(), redigomock.NewAnyData())
+ conn.Command("HMSET",
+ redigomock.NewAnyData(), redigomock.NewAnyData(),
+ redigomock.NewAnyData(), redigomock.NewAnyData(),
+ redigomock.NewAnyData(), redigomock.NewAnyData(),
+ redigomock.NewAnyData(), redigomock.NewAnyData(),
+ redigomock.NewAnyData(), redigomock.NewAnyData(),
+ redigomock.NewAnyData(), redigomock.NewAnyData(),
+ redigomock.NewAnyData())
repo := db.NewRedisImageRepo(pool)
// setup image package
@@ -176,5 +213,25 @@ func TestPostImage(t *testing.T) {
}
func TestGetImage(t *testing.T) {
-
+ conn, imageHandler := prepareImage()
+ getImageResults := []string{"file_path", "imge/name.jpg", "created_at", "'feb 12'", "user_id", "111", "mime_type", "image/jpg", "title", "mine", "desc", "'hoo har'"}
+ conn.Command("HGETALL", "v1imagepost:fooo").ExpectSlice(getImageResults)
+ m := chi.NewRouter()
+ m.Get("/i/{fileName}", imageHandler.GetImage)
+ srv := httptest.NewServer(m)
+ defer srv.Close()
+ // TODO https://github.com/go-chi/chi/blob/39504566046f2c13f4d059bccfe0fe06ed67aab3/mux_test.go#L1662
+ r, err := http.NewRequest("GET", fmt.Sprintf("%s/i/fooo", srv.URL), emptyBody)
+ if err != nil {
+ t.Errorf("%s", err)
+ }
+ resp, err := http.DefaultClient.Do(r)
+ if err != nil {
+ t.Errorf("%s", err)
+ }
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ t.Errorf("%s", err)
+ }
+ fmt.Printf("hello: %s", body)
}
diff --git a/internal/image/model.go b/internal/image/model.go
index 0d1cd60..a27d039 100644
--- a/internal/image/model.go
+++ b/internal/image/model.go
@@ -6,4 +6,6 @@ type PostMeta struct {
CreatedAt string `redis:"created_at"`
UserID string `redis:"user_id"`
MimeType string `redis:"mime_type"`
+ Title string `redis:"title"`
+ Desc string `redis:"desc"`
}
diff --git a/internal/image/service.go b/internal/image/service.go
index f953bfa..4ffd513 100644
--- a/internal/image/service.go
+++ b/internal/image/service.go
@@ -17,7 +17,7 @@ import (
// Servicer image management
type Servicer interface {
NewID() (string, error)
- AddFile(extension, fileType string, fileBytes []byte) (string, string, error)
+ AddFile(extension string, meta *PostMeta, fileBytes []byte) (string, string, error)
GetFile(fileUrl string) (*PostMeta, error)
Render(w http.ResponseWriter, templateName string, data interface{}) error
}
@@ -48,7 +48,7 @@ func (is *Service) NewID() (string, error) {
}
// AddFile writes to disk, writes meta to db
-func (is *Service) AddFile(extension, fileType string, fileBytes []byte) (string, string, error) {
+func (is *Service) AddFile(extension string, postMeta *PostMeta, fileBytes []byte) (string, string, error) {
fileID, err := is.NewID()
if err != nil {
return "", "", errors.Wrap(err, "generated id for fileID failed")
@@ -64,12 +64,8 @@ func (is *Service) AddFile(extension, fileType string, fileBytes []byte) (string
return "", "", errors.Wrap(err, "generating postid for uuid")
}
t := time.Now().UTC()
- postMeta := &PostMeta{
- FilePath: fileName,
- CreatedAt: t.Format(time.RFC3339),
- UserID: "1",
- MimeType: fileType,
- }
+ postMeta.FilePath = fileName
+ postMeta.CreatedAt = t.Format(time.RFC3339)
is.db.AddNewFile(postID, postMeta, 946080000)
if err := is.db.AddNewFile(postID, postMeta, 946080000); err != nil {
log.Fatal(err)
@@ -81,5 +77,7 @@ func (is *Service) AddFile(extension, fileType string, fileBytes []byte) (string
// GetFile fetch file from db interface
func (is *Service) GetFile(fileUrl string) (*PostMeta, error) {
result, err := is.db.GetFile(fileUrl)
+ if err != nil {
+ }
return result, err
}
diff --git a/templates/pages/image.tmpl b/templates/pages/image.tmpl
index 4c9b7b0..fcebdd5 100644
--- a/templates/pages/image.tmpl
+++ b/templates/pages/image.tmpl
@@ -1,11 +1,12 @@
{{ define "content" }}
<body>
<div>
- <h3>Image</h3>
+ <h3>{{.ImageTitle }} </h3>
</div>
<div>
<figure>
<img src="http://localhost:8080{{ .ImageUrl }}">
+ <caption>{{.ImageDesc}}</caption>
</figure>
</div>
</body>