diff --git a/pkg/olcrtc/olcrtc.go b/pkg/olcrtc/olcrtc.go index 49af5bb..6b2c9d9 100644 --- a/pkg/olcrtc/olcrtc.go +++ b/pkg/olcrtc/olcrtc.go @@ -43,6 +43,8 @@ var ( ErrURLRequired = errors.New("olcrtc: URL required when using direct engine mode") // ErrTokenRequired is returned when direct mode is used without a token. ErrTokenRequired = errors.New("olcrtc: Token required when using direct engine mode") + // ErrRoomCreationUnsupported is returned when the auth provider cannot create rooms. + ErrRoomCreationUnsupported = errors.New("olcrtc: auth provider does not support room creation") ) // Config is the input to [New]. @@ -228,3 +230,23 @@ func (s *Session) SetEndedCallback(cb func(reason string)) { func (s *Session) SetShouldReconnect(fn func() bool) { s.inner.SetShouldReconnect(fn) } + +// CreateRoom creates a new room via the auth provider and returns the room ID. +// Only works when the session was created with Auth set to a provider that +// supports room creation (wbstream, jazz). Returns [ErrRoomCreationUnsupported] +// for providers that don't support it (e.g. telemost). +func CreateRoom(ctx context.Context, authName string) (string, error) { + p, err := auth.Get(authName) + if err != nil { + return "", fmt.Errorf("olcrtc: auth provider %q not registered: %w", authName, err) + } + creator, ok := p.(auth.RoomCreator) + if !ok { + return "", fmt.Errorf("%w: %s", ErrRoomCreationUnsupported, authName) + } + roomID, err := creator.CreateRoom(ctx, auth.Config{}) + if err != nil { + return "", fmt.Errorf("olcrtc: create room: %w", err) + } + return roomID, nil +} diff --git a/pkg/olcrtc/olcrtc_test.go b/pkg/olcrtc/olcrtc_test.go index 4ee6868..47af01e 100644 --- a/pkg/olcrtc/olcrtc_test.go +++ b/pkg/olcrtc/olcrtc_test.go @@ -60,11 +60,22 @@ func (a stubAuth) Issue(_ context.Context, cfg auth.Config) (auth.Credentials, e return auth.Credentials{URL: "wss://stub/", Token: stubToken}, nil } +type stubAuthWithRoomCreator struct{ stubAuth } + +func (stubAuthWithRoomCreator) CreateRoom(_ context.Context, _ auth.Config) (string, error) { + return "created-room-id", nil +} + func registerStubAuth(t *testing.T, name, engineName string) { t.Helper() auth.Register(name, stubAuth{engineName: engineName}) } +func registerStubAuthWithCreator(t *testing.T, name, engineName string) { + t.Helper() + auth.Register(name, stubAuthWithRoomCreator{stubAuth{engineName: engineName}}) +} + // --- tests --- func TestNewDirect_MissingURL(t *testing.T) { @@ -159,6 +170,28 @@ func TestRegisterDefaults_Idempotent(_ *testing.T) { olcrtc.RegisterDefaults() } +func TestCreateRoom_Unsupported(t *testing.T) { + registerStubAuth(t, "stub-nocreate", "stub-direct") + + _, err := olcrtc.CreateRoom(context.Background(), "stub-nocreate") + if !errors.Is(err, olcrtc.ErrRoomCreationUnsupported) { + t.Fatalf("CreateRoom(no creator) = %v, want ErrRoomCreationUnsupported", err) + } +} + +func TestCreateRoom_OK(t *testing.T) { + registerStubEngine(t, "stub-creator-engine") + registerStubAuthWithCreator(t, "stub-creator", "stub-creator-engine") + + roomID, err := olcrtc.CreateRoom(context.Background(), "stub-creator") + if err != nil { + t.Fatalf("CreateRoom() error = %v", err) + } + if roomID == "" { + t.Fatal("CreateRoom() returned empty room ID") + } +} + func TestDial_RoundTrip(t *testing.T) { registerStubEngine(t, "stub-dial")