testing.go

 1package backend
 2
 3// InsertWorkspaceForTest registers ws with b under its current ID and
 4// path. It is intended for tests in other packages that need to drive
 5// HTTP handlers against a synthetic workspace without booting a real
 6// app.App. Production code should go through CreateWorkspace.
 7func InsertWorkspaceForTest(b *Backend, ws *Workspace) {
 8	if ws.resolvedPath == "" {
 9		ws.resolvedPath = ws.Path
10	}
11	if ws.clients == nil {
12		ws.clients = make(map[string]*clientState)
13	}
14	b.mu.Lock()
15	defer b.mu.Unlock()
16	b.workspaces.Set(ws.ID, ws)
17	if ws.resolvedPath != "" {
18		b.pathIndex[ws.resolvedPath] = ws.ID
19	}
20}
21
22// RegisterClientForTesting installs a creation hold for clientID on
23// ws using the backend's normal registerClient path. Intended for
24// tests in other packages that need to drive a hold-only client
25// (streams == 0) without booting a real CreateWorkspace flow.
26func RegisterClientForTesting(b *Backend, ws *Workspace, clientID string) error {
27	if _, err := validateClientID(clientID); err != nil {
28		return err
29	}
30	b.registerClient(ws, clientID)
31	return nil
32}
33
34// SetWorkspaceShutdownFnForTest overrides the workspace teardown
35// callback. Useful for tests in other packages that drive synthetic
36// workspaces (where the embedded [app.App] is incomplete) through
37// detach paths that would otherwise crash inside App.Shutdown.
38func SetWorkspaceShutdownFnForTest(ws *Workspace, fn func()) {
39	ws.shutdownFn = fn
40}
41
42// WorkspaceLiveStreamCountForTest returns the number of clients on ws
43// that have at least one live SSE stream. Used by integration tests
44// in other packages to wait for SSE attaches before publishing events.
45func WorkspaceLiveStreamCountForTest(ws *Workspace) int {
46	ws.clientsMu.Lock()
47	defer ws.clientsMu.Unlock()
48	n := 0
49	for _, cs := range ws.clients {
50		if cs.streams > 0 {
51			n++
52		}
53	}
54	return n
55}