1package server
 2
 3import (
 4	"context"
 5	"errors"
 6	"fmt"
 7	"log"
 8	"os"
 9	"testing"
10	"time"
11
12	"github.com/charmbracelet/soft-serve/server/backend/sqlite"
13	"github.com/charmbracelet/soft-serve/server/config"
14	"github.com/charmbracelet/ssh"
15	bm "github.com/charmbracelet/wish/bubbletea"
16	"github.com/charmbracelet/wish/testsession"
17	"github.com/matryer/is"
18	"github.com/muesli/termenv"
19	gossh "golang.org/x/crypto/ssh"
20)
21
22func TestSession(t *testing.T) {
23	is := is.New(t)
24	t.Run("authorized repo access", func(t *testing.T) {
25		t.Log("setting up")
26		s, close := setup(t)
27		s.Stderr = os.Stderr
28		t.Log("requesting pty")
29		err := s.RequestPty("xterm", 80, 40, nil)
30		is.NoErr(err)
31		go func() {
32			time.Sleep(1 * time.Second)
33			s.Signal(gossh.SIGTERM)
34			// FIXME: exit with code 0 instead of forcibly closing the session
35			s.Close()
36		}()
37		t.Log("waiting for session to exit")
38		_, err = s.Output("test")
39		var ee *gossh.ExitMissingError
40		is.True(errors.As(err, &ee))
41		t.Log("session exited")
42		_ = close()
43	})
44}
45
46func setup(tb testing.TB) (*gossh.Session, func() error) {
47	tb.Helper()
48	is := is.New(tb)
49	dp := tb.TempDir()
50	is.NoErr(os.Setenv("SOFT_SERVE_DATA_PATH", dp))
51	is.NoErr(os.Setenv("SOFT_SERVE_GIT_LISTEN_ADDR", ":9418"))
52	is.NoErr(os.Setenv("SOFT_SERVE_SSH_LISTEN_ADDR", fmt.Sprintf(":%d", randomPort())))
53	tb.Cleanup(func() {
54		is.NoErr(os.Unsetenv("SOFT_SERVE_DATA_PATH"))
55		is.NoErr(os.Unsetenv("SOFT_SERVE_GIT_LISTEN_ADDR"))
56		is.NoErr(os.Unsetenv("SOFT_SERVE_SSH_LISTEN_ADDR"))
57		is.NoErr(os.RemoveAll(dp))
58	})
59	ctx := context.TODO()
60	cfg := config.DefaultConfig()
61	fb, err := sqlite.NewSqliteBackend(ctx, cfg)
62	if err != nil {
63		log.Fatal(err)
64	}
65	cfg = cfg.WithBackend(fb)
66	return testsession.New(tb, &ssh.Server{
67		Handler: bm.MiddlewareWithProgramHandler(SessionHandler(cfg), termenv.ANSI256)(func(s ssh.Session) {
68			_, _, active := s.Pty()
69			if !active {
70				os.Exit(1)
71			}
72			s.Exit(0)
73		}),
74	}, nil), fb.Close
75}