goshort/internal/server/short/handler_test.go
Gustavo Maronato be39b22ace
Some checks failed
Check / checks (push) Failing after 3m48s
lint
2024-03-09 05:53:28 -05:00

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)
})
}