142 lines
3.5 KiB
Go
142 lines
3.5 KiB
Go
package shortserver_test
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"git.maronato.dev/maronato/goshort/internal/config"
|
|
servermiddleware "git.maronato.dev/maronato/goshort/internal/server/middleware"
|
|
shortserver "git.maronato.dev/maronato/goshort/internal/server/short"
|
|
shortservice "git.maronato.dev/maronato/goshort/internal/service/short"
|
|
shortlogservice "git.maronato.dev/maronato/goshort/internal/service/shortlog"
|
|
bunstorage "git.maronato.dev/maronato/goshort/internal/storage/bun"
|
|
"git.maronato.dev/maronato/goshort/internal/storage/models"
|
|
handlerutils "git.maronato.dev/maronato/goshort/internal/util/handler"
|
|
randomutil "git.maronato.dev/maronato/goshort/internal/util/random"
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/go-chi/chi/v5/middleware"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/uptrace/bun"
|
|
"github.com/uptrace/bun/dialect/sqlitedialect"
|
|
_ "modernc.org/sqlite" // Import the SQLite driver.
|
|
)
|
|
|
|
func newStorage(ctx context.Context, cfg *config.Config) *bunstorage.BunStorage {
|
|
filename := randomutil.GenerateSecureToken(16)
|
|
url := "file:memdb_" + filename + "?cache=shared&mode=memory&_foreign_keys=1"
|
|
|
|
sqldb, err := sql.Open("sqlite", url)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
db := bun.NewDB(sqldb, sqlitedialect.New())
|
|
|
|
str := bunstorage.NewBunStorage(cfg, db)
|
|
|
|
err = str.Start(ctx)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return str
|
|
}
|
|
|
|
func setup(ctx context.Context, cfg *config.Config) (
|
|
*shortserver.ShortHandler,
|
|
*shortservice.ShortService,
|
|
*shortlogservice.ShortLogService,
|
|
) {
|
|
str := newStorage(ctx, cfg)
|
|
|
|
shorts := shortservice.NewShortService(str)
|
|
shortLogs := shortlogservice.NewShortLogService(str)
|
|
|
|
handler := shortserver.NewShortHandler(shorts, shortLogs)
|
|
|
|
return handler, shorts, shortLogs
|
|
}
|
|
|
|
func makeRequestServer(handler http.HandlerFunc) http.Handler {
|
|
mux := chi.NewRouter()
|
|
lf := servermiddleware.NewLogFormatter(config.NewConfig())
|
|
lf.DisableStackPrinting()
|
|
|
|
// Add middlewares
|
|
mux.Use(middleware.RequestLogger(lf))
|
|
mux.Use(middleware.Recoverer)
|
|
|
|
// Handle all requests
|
|
|
|
shortRouter := chi.NewRouter()
|
|
shortRouter.Get("/{short}", handler)
|
|
|
|
chained := handlerutils.NewChainedHandler(
|
|
shortRouter,
|
|
http.NotFoundHandler(),
|
|
)
|
|
mux.Mount("/", chained)
|
|
|
|
return mux
|
|
}
|
|
|
|
func makeRequestResponse(ctx context.Context, method, url string, body io.Reader) (*httptest.ResponseRecorder, *http.Request) {
|
|
req, err := http.NewRequestWithContext(ctx, method, url, body)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
rr := httptest.NewRecorder()
|
|
|
|
return rr, req
|
|
}
|
|
|
|
func TestEndpointFindShort(t *testing.T) {
|
|
ctx := context.Background()
|
|
cfg := config.NewConfig()
|
|
|
|
handler, shorts, shortLogs := setup(ctx, cfg)
|
|
|
|
stopWorker, debugCh := shortLogs.StartWorker(ctx)
|
|
defer stopWorker()
|
|
|
|
server := makeRequestServer(handler.FindShort)
|
|
|
|
short, err := shorts.Shorten(ctx, &models.Short{
|
|
URL: "https://example.com",
|
|
Name: "example",
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
t.Run("Redirects", func(t *testing.T) {
|
|
res, req := makeRequestResponse(ctx, "GET", "/"+short.Name, nil)
|
|
server.ServeHTTP(res, req)
|
|
|
|
assert.Equal(t, http.StatusSeeOther, res.Code)
|
|
|
|
assert.Equal(t, short.URL, res.Header().Get("Location"))
|
|
|
|
// Check if the access was logged
|
|
<-debugCh
|
|
|
|
logs, err := shortLogs.ListLogs(ctx, short)
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, 1, len(logs))
|
|
assert.Equal(t, short.ID, logs[0].ShortID)
|
|
})
|
|
|
|
t.Run("NotFound", func(t *testing.T) {
|
|
res, req := makeRequestResponse(ctx, "GET", "/other", nil)
|
|
server.ServeHTTP(res, req)
|
|
|
|
assert.Equal(t, http.StatusNotFound, res.Code)
|
|
})
|
|
}
|