this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

back(tests): init toolchain

Clément c8b926a1 acd695c5

+157 -40
+4 -3
.github/workflows/backend.yml
··· 16 16 check: 17 17 name: Checks 18 18 runs-on: ubuntu-latest 19 - env: 20 - GOOS: js 21 - GOARCH: wasm 22 19 23 20 steps: 24 21 - name: Checkout sources ··· 41 38 - name: Lint 42 39 working-directory: backend 43 40 run: go vet uiua.online/... 41 + 42 + - name: Run tests 43 + working-directory: backend 44 + run: go test uiua.online/... 44 45 45 46 - name: Check if files have changed 46 47 run: |
+2 -28
backend/cmd/api/main.go
··· 1 1 package main 2 2 3 3 import ( 4 - "github.com/go-chi/chi/v5" 5 - chimiddleware "github.com/go-chi/chi/v5/middleware" 6 4 "github.com/go-sqlx/sqlx" 7 5 "github.com/syumai/workers" 8 - "uiua.online/internal/handlers" 9 - "uiua.online/internal/middlewares" 10 - "uiua.online/internal/services" 6 + "uiua.online/internal/router" 11 7 "uiua.online/store" 12 8 ) 13 9 14 10 func main() { 15 11 db := sqlx.NewDb(store.Database(), "sqlite") 16 12 17 - sessionSvc := services.NewSessionService(db) 18 - userSvc := services.NewUserService(db) 19 - authSvc := services.NewAuthService(userSvc, sessionSvc) 20 - 21 - auth := middlewares.NewAuthMiddleware(sessionSvc) 22 - 23 - authHandler := handlers.NewAuthHandler(authSvc) 24 - 25 - r := chi.NewRouter() 26 - r.Use(chimiddleware.Logger) 27 - r.Use(chimiddleware.Recoverer) 28 - 29 - r.Get("/", handlers.Health) 30 - 31 - r.Route("/auth", func(r chi.Router) { 32 - r.Post("/login", authHandler.Login) 33 - 34 - r.Group(func(r chi.Router) { 35 - r.Use(auth.RequireAuth) 36 - r.Get("/whoami", authHandler.Whoami) 37 - r.Post("/change-password", authHandler.ChangePassword) 38 - }) 39 - }) 13 + r := router.Router(db) 40 14 41 15 workers.Serve(r) 42 16 }
+3 -7
backend/go.mod
··· 3 3 go 1.25.5 4 4 5 5 require ( 6 + github.com/glebarez/go-sqlite v1.22.0 6 7 github.com/go-chi/chi/v5 v5.2.4 7 - github.com/syumai/workers v0.31.0 8 - ) 9 - 10 - require ( 8 + github.com/go-sqlx/sqlx v1.3.8 11 9 github.com/gofrs/uuid v4.4.0+incompatible 10 + github.com/syumai/workers v0.31.0 12 11 golang.org/x/crypto v0.40.0 13 12 ) 14 13 15 - require github.com/go-sqlx/sqlx v1.3.8 16 - 17 14 require ( 18 15 github.com/dustin/go-humanize v1.0.1 // indirect 19 - github.com/glebarez/go-sqlite v1.22.0 // indirect 20 16 github.com/google/uuid v1.5.0 // indirect 21 17 github.com/mattn/go-isatty v0.0.20 // indirect 22 18 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
+2
backend/go.sum
··· 10 10 github.com/go-sqlx/sqlx v1.3.8/go.mod h1:8IQsxeiq14kP8ndB8cebAO8lTo0k9UMzMA+AWXJ6030= 11 11 github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= 12 12 github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= 13 + github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= 14 + github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= 13 15 github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= 14 16 github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 15 17 github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
+37
backend/internal/handlers/auth_test.go
··· 1 + package handlers_test 2 + 3 + import ( 4 + "net/http" 5 + "net/http/httptest" 6 + "strings" 7 + "testing" 8 + 9 + "github.com/go-sqlx/sqlx" 10 + "github.com/gofrs/uuid" 11 + "golang.org/x/crypto/bcrypt" 12 + "uiua.online/internal/router" 13 + "uiua.online/store" 14 + ) 15 + 16 + func createUser(db *sqlx.DB, email string, password string) { 17 + hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) 18 + if err != nil { 19 + panic(err) 20 + } 21 + db.Exec("insert into users (id, email, password_hash) values (?, ?, ?)", uuid.Must(uuid.NewV7()), email, hashedPassword) 22 + } 23 + 24 + func TestLogin(t *testing.T) { 25 + db := sqlx.NewDb(store.SqliteDatabase(), "sqlite") 26 + r := router.Router(db) 27 + 28 + createUser(db, "contact@drawbu.dev", "hello") 29 + 30 + w := httptest.NewRecorder() 31 + body := strings.NewReader(`{"email": "contact@drawbu.dev", "password": "hello"}`) 32 + r.ServeHTTP(w, httptest.NewRequest(http.MethodPost, "/auth/login", body)) 33 + 34 + if w.Code != http.StatusOK { 35 + t.Errorf("expected status code %d, got %d", http.StatusOK, w.Code) 36 + } 37 + }
+23
backend/internal/handlers/health_test.go
··· 1 + package handlers_test 2 + 3 + import ( 4 + "net/http" 5 + "net/http/httptest" 6 + "testing" 7 + 8 + "github.com/go-sqlx/sqlx" 9 + "uiua.online/internal/router" 10 + "uiua.online/store" 11 + ) 12 + 13 + func TestHealth(t *testing.T) { 14 + db := sqlx.NewDb(store.SqliteDatabase(), "sqlite") 15 + r := router.Router(db) 16 + 17 + w := httptest.NewRecorder() 18 + r.ServeHTTP(w, httptest.NewRequest(http.MethodGet, "/", nil)) 19 + 20 + if w.Code != http.StatusOK { 21 + t.Errorf("expected status code %d, got %d", http.StatusOK, w.Code) 22 + } 23 + }
+38
backend/internal/router/router.go
··· 1 + package router 2 + 3 + import ( 4 + "github.com/go-chi/chi/v5" 5 + chimiddleware "github.com/go-chi/chi/v5/middleware" 6 + "github.com/go-sqlx/sqlx" 7 + "uiua.online/internal/handlers" 8 + "uiua.online/internal/middlewares" 9 + "uiua.online/internal/services" 10 + ) 11 + 12 + func Router(db *sqlx.DB) *chi.Mux { 13 + sessionSvc := services.NewSessionService(db) 14 + userSvc := services.NewUserService(db) 15 + authSvc := services.NewAuthService(userSvc, sessionSvc) 16 + 17 + auth := middlewares.NewAuthMiddleware(sessionSvc) 18 + 19 + authHandler := handlers.NewAuthHandler(authSvc) 20 + 21 + r := chi.NewRouter() 22 + r.Use(chimiddleware.Logger) 23 + r.Use(chimiddleware.Recoverer) 24 + 25 + r.Get("/", handlers.Health) 26 + 27 + r.Route("/auth", func(r chi.Router) { 28 + r.Post("/login", authHandler.Login) 29 + 30 + r.Group(func(r chi.Router) { 31 + r.Use(auth.RequireAuth) 32 + r.Get("/whoami", authHandler.Whoami) 33 + r.Post("/change-password", authHandler.ChangePassword) 34 + }) 35 + }) 36 + 37 + return r 38 + }
+6
backend/migrations/migrations.go
··· 1 + package migrations 2 + 3 + import "embed" 4 + 5 + //go:embed *.sql 6 + var Migrations embed.FS
+38 -2
backend/store/store_mem.go
··· 4 4 5 5 import ( 6 6 "database/sql" 7 + "io/fs" 7 8 "log/slog" 9 + "sort" 8 10 9 11 _ "github.com/glebarez/go-sqlite" // register driver 12 + "uiua.online/migrations" 10 13 ) 11 14 12 - func Database() *sql.DB { 13 - slog.Error("Running with an in-memory database") 15 + func SqliteDatabase() *sql.DB { 14 16 db, err := sql.Open("sqlite", ":memory:") 15 17 if err != nil { 16 18 panic(err) 17 19 } 20 + 21 + if err := applyMigrations(db); err != nil { 22 + panic(err) 23 + } 24 + 18 25 return db 19 26 } 27 + 28 + func applyMigrations(db *sql.DB) error { 29 + entries, err := fs.ReadDir(migrations.Migrations, ".") 30 + if err != nil { 31 + return err 32 + } 33 + 34 + sort.Slice(entries, func(i, j int) bool { 35 + return entries[i].Name() < entries[j].Name() 36 + }) 37 + 38 + for _, entry := range entries { 39 + content, err := fs.ReadFile(migrations.Migrations, entry.Name()) 40 + if err != nil { 41 + return err 42 + } 43 + slog.Info("applying migration", "name", entry.Name()) 44 + if _, err := db.Exec(string(content)); err != nil { 45 + return err 46 + } 47 + } 48 + 49 + return nil 50 + } 51 + 52 + func Database() *sql.DB { 53 + slog.Error("Running with an in-memory database") 54 + return SqliteDatabase() 55 + }
+4
backend/store/store_wasm.go
··· 8 8 _ "github.com/syumai/workers/cloudflare/d1" // register driver 9 9 ) 10 10 11 + func SqliteDatabase() *sql.DB { 12 + panic("should not need sqlite in wasm") 13 + } 14 + 11 15 func Database() *sql.DB { 12 16 db, err := sql.Open("d1", "DB") 13 17 if err != nil {