diff --git a/.gitignore b/.gitignore index 9d4f24b..fa18f65 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,3 @@ gobs-cli.1 # Config files config.yaml - -# Test files -*_test.go \ No newline at end of file diff --git a/group_test.go b/group_test.go new file mode 100644 index 0000000..a594e56 --- /dev/null +++ b/group_test.go @@ -0,0 +1,130 @@ +package main + +import ( + "bytes" + "strings" + "testing" +) + +func TestGroupList(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + cmd := &GroupListCmd{ + SceneName: "Scene", + } + err := cmd.Run(context) + if err != nil { + t.Fatalf("Failed to list groups: %v", err) + } + if !strings.Contains(out.String(), "test_group") { + t.Fatalf("Expected output to contain 'test_group', got '%s'", out.String()) + } +} + +func TestGroupShow(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + cmd := &GroupShowCmd{ + SceneName: "Scene", + GroupName: "test_group", + } + err := cmd.Run(context) + if err != nil { + t.Fatalf("Failed to show group: %v", err) + } + if out.String() != "Group test_group is now shown.\n" { + t.Fatalf("Expected output to be 'Group test_group is now shown.', got '%s'", out.String()) + } +} + +func TestGroupToggle(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + cmdStatus := &GroupStatusCmd{ + SceneName: "Scene", + GroupName: "test_group", + } + err := cmdStatus.Run(context) + if err != nil { + t.Fatalf("Failed to get group status: %v", err) + } + var enabled bool + if strings.Contains(out.String(), "Group test_group is shown.") { + enabled = true + } + // Reset output buffer for the next command + out.Reset() + + cmdToggle := &GroupToggleCmd{ + SceneName: "Scene", + GroupName: "test_group", + } + err = cmdToggle.Run(context) + if err != nil { + t.Fatalf("Failed to toggle group: %v", err) + } + if enabled { + if out.String() != "Group test_group is now hidden.\n" { + t.Fatalf("Expected output to be 'Group test_group is now hidden.', got '%s'", out.String()) + } + } else { + if out.String() != "Group test_group is now shown.\n" { + t.Fatalf("Expected output to be 'Group test_group is now shown.', got '%s'", out.String()) + } + } +} + +func TestGroupStatus(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + cmdShow := &GroupShowCmd{ + SceneName: "Scene", + GroupName: "test_group", + } + err := cmdShow.Run(context) + if err != nil { + t.Fatalf("Failed to show group: %v", err) + } + // Reset output buffer for the next command + out.Reset() + + cmdStatus := &GroupStatusCmd{ + SceneName: "Scene", + GroupName: "test_group", + } + err = cmdStatus.Run(context) + if err != nil { + t.Fatalf("Failed to get group status: %v", err) + } + if out.String() != "Group test_group is shown.\n" { + t.Fatalf("Expected output to be 'Group test_group is shown.', got '%s'", out.String()) + } +} diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000..a9b6925 --- /dev/null +++ b/main_test.go @@ -0,0 +1,101 @@ +package main + +import ( + "os" + "testing" + + "github.com/andreykaipov/goobs" + "github.com/andreykaipov/goobs/api/requests/config" + "github.com/andreykaipov/goobs/api/requests/inputs" + "github.com/andreykaipov/goobs/api/requests/scenes" + typedefs "github.com/andreykaipov/goobs/api/typedefs" +) + +func getClient(t *testing.T) (*goobs.Client, func()) { + t.Helper() + client, err := connectObs(ObsConfig{ + Host: os.Getenv("OBS_HOST"), + Port: 4455, + Password: os.Getenv("OBS_PASSWORD"), + Timeout: 5, + }) + if err != nil { + t.Fatalf("Failed to connect to OBS: %v", err) + } + return client, func() { + if err := client.Disconnect(); err != nil { + t.Fatalf("Failed to disconnect from OBS: %v", err) + } + } +} + +func TestMain(m *testing.M) { + client, err := connectObs(ObsConfig{ + Host: os.Getenv("OBS_HOST"), + Port: 4455, + Password: os.Getenv("OBS_PASSWORD"), + Timeout: 5, + }) + if err != nil { + os.Exit(1) + } + defer client.Disconnect() + + setup(client) + + // Run the tests + exitCode := m.Run() + + teardown(client) + + // Exit with the appropriate code + os.Exit(exitCode) +} + +func setup(client *goobs.Client) { + client.Config.SetStreamServiceSettings(config.NewSetStreamServiceSettingsParams(). + WithStreamServiceType("rtmp_common"). + WithStreamServiceSettings(&typedefs.StreamServiceSettings{ + Server: "auto", + Key: os.Getenv("OBS_STREAM_KEY"), + })) + + client.Config.SetCurrentSceneCollection(config.NewSetCurrentSceneCollectionParams(). + WithSceneCollectionName("test-collection")) + + client.Scenes.CreateScene(scenes.NewCreateSceneParams(). + WithSceneName("gobs-test")) + client.Inputs.CreateInput(inputs.NewCreateInputParams(). + WithSceneName("gobs-test"). + WithInputName("gobs-test-input"). + WithInputKind("color_source_v3"). + WithInputSettings(map[string]any{ + "color": 3279460728, + "width": 1920, + "height": 1080, + "visible": true, + }). + WithSceneItemEnabled(true)) + client.Inputs.CreateInput(inputs.NewCreateInputParams(). + WithSceneName("gobs-test"). + WithInputName("gobs-test-input-2"). + WithInputKind("color_source_v3"). + WithInputSettings(map[string]any{ + "color": 1789347616, + "width": 720, + "height": 480, + "visible": true, + }). + WithSceneItemEnabled(true)) +} + +func teardown(client *goobs.Client) { + client.Scenes.RemoveScene(scenes.NewRemoveSceneParams(). + WithSceneName("gobs-test")) + + client.Config.SetCurrentSceneCollection(config.NewSetCurrentSceneCollectionParams(). + WithSceneCollectionName("default")) + + client.Stream.StopStream() + client.Record.StopRecord() +} diff --git a/record_test.go b/record_test.go new file mode 100644 index 0000000..8285b50 --- /dev/null +++ b/record_test.go @@ -0,0 +1,105 @@ +package main + +import ( + "bytes" + "testing" + "time" +) + +func TestRecordStartStatusStop(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + cmdStart := &RecordStartCmd{} + err := cmdStart.Run(context) + if err != nil { + t.Fatalf("Failed to start recording: %v", err) + } + if out.String() != "Recording started successfully.\n" { + t.Fatalf("Expected output to be 'Recording started successfully.', got '%s'", out.String()) + } + // Reset output buffer for the next command + out.Reset() + + time.Sleep(1 * time.Second) // Wait for a second to ensure recording has started + + cmdStatus := &RecordStatusCmd{} + err = cmdStatus.Run(context) + if err != nil { + t.Fatalf("Failed to get recording status: %v", err) + } + if out.String() != "Recording is in progress.\n" { + t.Fatalf("Expected output to be 'Recording is in progress.', got '%s'", out.String()) + } + // Reset output buffer for the next command + out.Reset() + + cmdStop := &RecordStopCmd{} + err = cmdStop.Run(context) + if err != nil { + t.Fatalf("Failed to stop recording: %v", err) + } + if out.String() != "Recording stopped successfully.\n" { + t.Fatalf("Expected output to be 'Recording stopped successfully.', got '%s'", out.String()) + } + // Reset output buffer for the next command + out.Reset() + + time.Sleep(1 * time.Second) // Wait for a second to ensure recording has stopped + + cmdStatus = &RecordStatusCmd{} + err = cmdStatus.Run(context) + if err != nil { + t.Fatalf("Failed to get recording status: %v", err) + } + if out.String() != "Recording is not in progress.\n" { + t.Fatalf("Expected output to be 'Recording is not in progress.', got '%s'", out.String()) + } +} + +func TestRecordToggle(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + cmdStatus := &RecordStatusCmd{} + err := cmdStatus.Run(context) + if err != nil { + t.Fatalf("Failed to get recording status: %v", err) + } + var active bool + if out.String() == "Recording is in progress.\n" { + active = true + } + // Reset output buffer for the next command + out.Reset() + + cmdToggle := &RecordToggleCmd{} + err = cmdToggle.Run(context) + if err != nil { + t.Fatalf("Failed to toggle recording: %v", err) + } + + time.Sleep(1 * time.Second) // Wait for a second to ensure toggle has taken effect + + if active { + if out.String() != "Recording stopped successfully.\n" { + t.Fatalf("Expected output to be 'Recording stopped successfully.', got '%s'", out.String()) + } + } else { + if out.String() != "Recording started successfully.\n" { + t.Fatalf("Expected output to be 'Recording started successfully.', got '%s'", out.String()) + } + } +} diff --git a/scene_test.go b/scene_test.go new file mode 100644 index 0000000..42b3944 --- /dev/null +++ b/scene_test.go @@ -0,0 +1,58 @@ +package main + +import ( + "bytes" + "strings" + "testing" +) + +func TestSceneList(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + cmd := &SceneListCmd{} + err := cmd.Run(context) + if err != nil { + t.Fatalf("Failed to list scenes: %v", err) + } + if !strings.Contains(out.String(), "gobs-test") { + t.Fatalf("Expected output to contain 'gobs-test', got '%s'", out.String()) + } +} + +func TestSceneCurrent(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + // Set the current scene to "gobs-test" + cmdSwitch := &SceneSwitchCmd{ + NewScene: "gobs-test", + } + err := cmdSwitch.Run(context) + if err != nil { + t.Fatalf("Failed to switch to scene: %v", err) + } + // Reset output buffer for the next command + out.Reset() + + cmdCurrent := &SceneCurrentCmd{} + err = cmdCurrent.Run(context) + if err != nil { + t.Fatalf("Failed to get current scene: %v", err) + } + if out.String() != "gobs-test\n" { + t.Fatalf("Expected output to contain 'gobs-test', got '%s'", out.String()) + } +} diff --git a/sceneitem_test.go b/sceneitem_test.go new file mode 100644 index 0000000..a34ef3a --- /dev/null +++ b/sceneitem_test.go @@ -0,0 +1,32 @@ +package main + +import ( + "bytes" + "strings" + "testing" +) + +func TestSceneItemList(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + cmd := &SceneItemListCmd{ + SceneName: "gobs-test", + } + err := cmd.Run(context) + if err != nil { + t.Fatalf("Failed to list scene items: %v", err) + } + if !strings.Contains(out.String(), "gobs-test-input") { + t.Fatalf("Expected output to contain 'gobs-test-input', got '%s'", out.String()) + } + if !strings.Contains(out.String(), "gobs-test-input-2") { + t.Fatalf("Expected output to contain 'gobs-test-input-2', got '%s'", out.String()) + } +} diff --git a/stream_test.go b/stream_test.go new file mode 100644 index 0000000..2418e3b --- /dev/null +++ b/stream_test.go @@ -0,0 +1,131 @@ +package main + +import ( + "bytes" + "strings" + "testing" + "time" +) + +func TestStreamStart(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + cmdStatus := &StreamStatusCmd{} + err := cmdStatus.Run(context) + if err != nil { + t.Fatalf("Failed to get stream status: %v", err) + } + var active bool + if strings.Contains(out.String(), "Output active: true") { + active = true + } + // Reset output buffer for the next command + out.Reset() + + cmdStart := &StreamStartCmd{} + err = cmdStart.Run(context) + if err != nil { + t.Fatalf("Failed to start stream: %v", err) + } + + time.Sleep(1 * time.Second) // Wait for the stream to start + + if active { + if out.String() != "Stream is already active.\n" { + t.Fatalf("Expected 'Stream is already active.', got: %s", out.String()) + } + } else { + if out.String() != "Streaming started successfully.\n" { + t.Fatalf("Expected 'Streaming started successfully.', got: %s", out.String()) + } + } +} + +func TestStreamStop(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + cmdStatus := &StreamStatusCmd{} + err := cmdStatus.Run(context) + if err != nil { + t.Fatalf("Failed to get stream status: %v", err) + } + var active bool + if strings.Contains(out.String(), "Output active: true") { + active = true + } + // Reset output buffer for the next command + out.Reset() + + cmdStop := &StreamStopCmd{} + err = cmdStop.Run(context) + if err != nil { + t.Fatalf("Failed to stop stream: %v", err) + } + + time.Sleep(1 * time.Second) // Wait for the stream to stop + + if active { + if out.String() != "Streaming stopped successfully.\n" { + t.Fatalf("Expected 'Streaming stopped successfully.', got: %s", out.String()) + } + } else { + if out.String() != "Stream is already inactive.\n" { + t.Fatalf("Expected 'Stream is already inactive.', got: %s", out.String()) + } + } +} + +func TestStreamToggle(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + cmdStatus := &StreamStatusCmd{} + err := cmdStatus.Run(context) + if err != nil { + t.Fatalf("Failed to get stream status: %v", err) + } + var active bool + if strings.Contains(out.String(), "Output active: true") { + active = true + } + // Reset output buffer for the next command + out.Reset() + + cmdToggle := &StreamToggleCmd{} + err = cmdToggle.Run(context) + if err != nil { + t.Fatalf("Failed to toggle stream: %v", err) + } + + time.Sleep(1 * time.Second) // Wait for the stream to toggle + + if active { + if out.String() != "Streaming stopped successfully.\n" { + t.Fatalf("Expected 'Streaming stopped successfully.', got: %s", out.String()) + } + } else { + if out.String() != "Streaming started successfully.\n" { + t.Fatalf("Expected 'Streaming started successfully.', got: %s", out.String()) + } + } +} diff --git a/studiomode_test.go b/studiomode_test.go new file mode 100644 index 0000000..88c787f --- /dev/null +++ b/studiomode_test.go @@ -0,0 +1,68 @@ +package main + +import ( + "bytes" + "testing" +) + +func TestStudioModeEnable(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + cmdEnable := &StudioModeEnableCmd{} + err := cmdEnable.Run(context) + if err != nil { + t.Fatalf("failed to enable studio mode: %v", err) + } + if out.String() != "Studio mode is now enabled\n" { + t.Fatalf("expected 'Studio mode is now enabled', got: %s", out.String()) + } + // Reset output buffer for the next command + out.Reset() + + cmdStatus := &StudioModeStatusCmd{} + err = cmdStatus.Run(context) + if err != nil { + t.Fatalf("failed to get studio mode status: %v", err) + } + if out.String() != "Studio mode is enabled\n" { + t.Fatalf("expected 'Studio mode is enabled', got: %s", out.String()) + } +} + +func TestStudioModeDisable(t *testing.T) { + client, disconnect := getClient(t) + defer disconnect() + + var out bytes.Buffer + context := &context{ + Client: client, + Out: &out, + } + + cmdDisable := &StudioModeDisableCmd{} + err := cmdDisable.Run(context) + if err != nil { + t.Fatalf("failed to disable studio mode: %v", err) + } + if out.String() != "Studio mode is now disabled\n" { + t.Fatalf("expected 'Studio mode is now disabled', got: %s", out.String()) + } + // Reset output buffer for the next command + out.Reset() + + cmdStatus := &StudioModeStatusCmd{} + err = cmdStatus.Run(context) + if err != nil { + t.Fatalf("failed to get studio mode status: %v", err) + } + if out.String() != "Studio mode is disabled\n" { + t.Fatalf("expected 'Studio mode is disabled', got: %s", out.String()) + } +}