chromium/content/browser/speech/tts_controller_unittest.cc

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Unit tests for the TTS Controller.

#include "content/browser/speech/tts_controller_impl.h"

#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "content/browser/speech/tts_utterance_impl.h"
#include "content/public/browser/tts_platform.h"
#include "content/public/browser/visibility.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_renderer_host.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_web_contents.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/speech/speech_synthesis.mojom.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "content/public/browser/tts_controller_delegate.h"
#endif

namespace content {

// Platform Tts implementation that does nothing.
class MockTtsPlatformImpl : public TtsPlatform {};

class MockTtsEngineDelegate : public TtsEngineDelegate {};

#if BUILDFLAG(IS_CHROMEOS_ASH)
class MockTtsControllerDelegate : public TtsControllerDelegate {
 public:
  MockTtsControllerDelegate() = default;
  ~MockTtsControllerDelegate() override = default;

  void SetPreferredVoiceIds(const PreferredVoiceIds& ids) { ids_ = ids; }

  BrowserContext* GetLastBrowserContext() {
    BrowserContext* result = last_browser_context_;
    last_browser_context_ = nullptr;
    return result;
  }

  // TtsControllerDelegate:
  std::unique_ptr<PreferredVoiceIds> GetPreferredVoiceIdsForUtterance(
      TtsUtterance* utterance) override {
    last_browser_context_ = utterance->GetBrowserContext();
    auto ids = std::make_unique<PreferredVoiceIds>(ids_);
    return ids;
  }

  void UpdateUtteranceDefaultsFromPrefs(content::TtsUtterance* utterance,
                                        double* rate,
                                        double* pitch,
                                        double* volume) override {}

 private:
  raw_ptr<BrowserContext> last_browser_context_ = nullptr;
  PreferredVoiceIds ids_;
};
#endif

class MockVoicesChangedDelegate : public VoicesChangedDelegate {};

class TestTtsControllerImpl : public TtsControllerImpl {};

class TtsControllerTest : public testing::Test {};

#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(TtsControllerTest, TestBrowserContextRemoved) {
  std::vector<VoiceData> voices;
  VoiceData voice_data;
  voice_data.engine_id = "x";
  voice_data.events.insert(TTS_EVENT_END);
  voices.push_back(voice_data);
  platform_impl()->set_voices(voices);

  // Speak an utterances associated with this test browser context.
  std::unique_ptr<TtsUtterance> utterance1 =
      TtsUtterance::Create(browser_context());
  utterance1->SetEngineId("x");
  utterance1->SetShouldClearQueue(false);
  utterance1->SetSrcId(1);
  controller()->SpeakOrEnqueue(std::move(utterance1));

  // Assert that the delegate was called and it got our browser context.
  ASSERT_EQ(browser_context(), delegate()->GetLastBrowserContext());

  // Now queue up a second utterance to be spoken, also associated with
  // this browser context.
  std::unique_ptr<TtsUtterance> utterance2 =
      TtsUtterance::Create(browser_context());
  utterance2->SetEngineId("x");
  utterance2->SetShouldClearQueue(false);
  utterance2->SetSrcId(2);
  controller()->SpeakOrEnqueue(std::move(utterance2));

  // Destroy the browser context before the utterance is spoken.
  ReleaseBrowserContext();

  // Now speak the next utterance, and ensure that we don't get the
  // destroyed browser context.
  controller()->FinishCurrentUtterance();
  controller()->SpeakNextUtterance();
  ASSERT_EQ(nullptr, delegate()->GetLastBrowserContext());
}
#else
TEST_F(TtsControllerTest, TestTtsControllerUtteranceDefaults) {}
#endif

TEST_F(TtsControllerTest, TestGetMatchingVoice) {}

// Note: The following tests are disabled since they do not apply for Lacros
// build. TtsPlatformImpl is not supported for Lacros when lacros tts support
// feature is disabled.
// TODO(crbug.com/40189267): Add new tests for lacros with tts support feature
// being enabled.
#if !BUILDFLAG(IS_CHROMEOS_LACROS)
TEST_F(TtsControllerTest, TestTtsControllerShutdown) {}

TEST_F(TtsControllerTest, StopsWhenWebContentsDestroyed) {}

TEST_F(TtsControllerTest, StartsQueuedUtteranceWhenWebContentsDestroyed) {}

TEST_F(TtsControllerTest, StartsQueuedUtteranceWhenWebContentsDestroyed2) {}

TEST_F(TtsControllerTest, StartsUtteranceWhenWebContentsHidden) {}

TEST_F(TtsControllerTest,
       DoesNotStartUtteranceWhenWebContentsHiddenAndStopSpeakingWhenHiddenSet) {}

TEST_F(TtsControllerTest, SkipsQueuedUtteranceFromHiddenWebContents) {}

TEST_F(TtsControllerTest, SpeakPauseResume) {}

TEST_F(TtsControllerTest, SpeakWhenPaused) {}

TEST_F(TtsControllerTest, SpeakWhenPausedAndCannotEnqueueUtterance) {}

TEST_F(TtsControllerTest, StopMustResumeController) {}

TEST_F(TtsControllerTest, PauseAndStopMustResumeController) {}

TEST_F(TtsControllerTest, EngineIdSetNoDelegateSpeakPauseResumeStop) {}
#endif  // !BUILDFLAG(IS_CHROMEOS_LACROS)

TEST_F(TtsControllerTest, PauseResumeNoUtterance) {}

TEST_F(TtsControllerTest, PlatformNotSupported) {}

#if !BUILDFLAG(IS_CHROMEOS_LACROS)
TEST_F(TtsControllerTest, SpeakWhenLoadingPlatformImpl) {}

TEST_F(TtsControllerTest, GetVoicesOnlineOffline) {}
#endif  // !BUILDFLAG(IS_CHROMEOS_LACROS)

#if !BUILDFLAG(IS_ANDROID)
TEST_F(TtsControllerTest, SpeakWhenLoadingBuiltInEngine) {}
#endif  // !BUILDFLAG(IS_ANDROID)

}  // namespace content