blob: 8af167ccf2256eea33696f8b85955683307b4d62 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_MODULAR_LIB_MODULAR_TEST_HARNESS_CPP_FAKE_SESSION_SHELL_H_
#define SRC_MODULAR_LIB_MODULAR_TEST_HARNESS_CPP_FAKE_SESSION_SHELL_H_
#include <lib/modular/testing/cpp/fake_component.h>
#include <sdk/lib/sys/cpp/component_context.h>
#include "src/modular/lib/testing/session_shell_impl.h"
namespace modular_testing {
// Session shell fake that provides access to the StoryProvider, the
// SessionShellContext, and a test implementation of SessionShellImpl.
//
// EXAMPLE USAGE:
//
// ...
// modular_testing::TestHarnessBuilder builder;
// auto fake_session_shell = FakeSessionShell::CreateWithDefaultOptions();
//
// builder.InterceptSessionShell(fake_session_shell.BuildInterceptOptions());
// builder.BuildAndRun(test_harness());
//
// // Wait for the session shell to be intercepted.
// RunLoopUntil([&] { return fake_session_shell->is_running(); });
// ...
class FakeSessionShell : public modular_testing::FakeComponent {
public:
explicit FakeSessionShell(FakeComponent::Args args);
~FakeSessionShell() override;
// Instantiates a FakeSessionShell with a randomly generated URL and default sandbox services
// (see GetDefaultSandboxServices()).
static std::unique_ptr<FakeSessionShell> CreateWithDefaultOptions();
// Returns the default list of services (capabilities) a session shell expects in its namespace.
// This method is useful when setting up a session shell for interception.
//
// Default services:
// * fuchsia.modular.ComponentContext
// * fuchsia.modular.SessionShellContext
// * fuchsia.modular.PuppetMaster
static std::vector<std::string> GetDefaultSandboxServices();
// Requires: FakeComponent::is_running()
fuchsia::modular::StoryProvider* story_provider() { return story_provider_.get(); }
// Requires: FakeComponent::is_running()
fuchsia::modular::SessionShellContext* session_shell_context() {
return session_shell_context_.get();
}
// See modular_testing::SessionShellImpl implementation.
void set_on_attach_view(fit::function<void(fuchsia::modular::ViewIdentifier view_id)> callback) {
session_shell_impl_.set_on_attach_view(std::move(callback));
}
// See modular_testing::SessionShellImpl implementation.
void set_on_detach_view(fit::function<void(fuchsia::modular::ViewIdentifier view_id)> callback) {
session_shell_impl_.set_on_detach_view(std::move(callback));
}
// See modular_testing::SessionShellImpl implementation.
void set_detach_delay(zx::duration detach_delay) {
session_shell_impl_.set_detach_delay(std::move(detach_delay));
}
protected:
// |modular_testing::FakeComponent|
void OnCreate(fuchsia::sys::StartupInfo startup_info) override;
private:
modular_testing::SessionShellImpl session_shell_impl_;
fuchsia::modular::SessionShellContextPtr session_shell_context_;
fuchsia::modular::StoryProviderPtr story_provider_;
};
// Simple StoryProviderWatcher that will run a user-provided lambda function
// when it sees a change in story state. Meant to be used to help monitor the
// state of the FakeSessionShell provided above.
//
// EXAMPLE USAGE (after above code snippet that initializes FakeSessionShell):
//
// // Add a function that does something when a story state change is observed.
// const char[] kStoryId = "my_story";
// modular_testing::SimpleStoryProviderWatcher watcher;
// watcher.set_on_change_2([kStoryId](StoryInfo2 story_info,
// StoryState story_state,
// StoryVisibilityState _) {
// EXPECT_EQ(story_info.id, kStoryId);
// });
// watcher.Watch(fake_session_shell.story_provider(),
// /*on_get_stories=*/nullptr);
class SimpleStoryProviderWatcher : public fuchsia::modular::StoryProviderWatcher {
public:
SimpleStoryProviderWatcher() : binding_(this) {}
~SimpleStoryProviderWatcher() override = default;
using OnChange2Function =
fit::function<void(fuchsia::modular::StoryInfo2, fuchsia::modular::StoryState,
fuchsia::modular::StoryVisibilityState)>;
using OnDeleteFunction = fit::function<void(std::string)>;
void set_on_change_2(OnChange2Function on_change_2) { on_change_2_ = std::move(on_change_2); }
void set_on_delete(OnDeleteFunction on_delete) { on_delete_ = std::move(on_delete); }
// Start watching for story state changes in the given story_provider. Takes
// a lambda that allows the caller to do something with the StoryInfo data
// returned by the initial call to GetStories() (this will be the state of
// any existing stories when watching starts).
void Watch(
fuchsia::modular::StoryProvider* story_provider,
fit::function<void(std::vector<fuchsia::modular::StoryInfo2> stories)>* on_get_stories) {
story_provider->GetStories2(
binding_.NewBinding(), on_get_stories != nullptr
? std::move(*on_get_stories)
: [](std::vector<fuchsia::modular::StoryInfo2>) {});
}
private:
// |fuchsia::modular::StoryProviderWatcher|
void OnChange2(fuchsia::modular::StoryInfo2 story_info, fuchsia::modular::StoryState story_state,
fuchsia::modular::StoryVisibilityState story_visibility_state) override {
if (!on_change_2_) {
return;
}
on_change_2_(std::move(story_info), story_state, story_visibility_state);
}
// |fuchsia::modular::StoryProviderWatcher|
void OnDelete(std::string story_id) override {
if (!on_delete_) {
return;
}
on_delete_(story_id);
}
// Optional user-provided lambda that will run with each OnChange2().
OnChange2Function on_change_2_;
// Optional user-provided lambda that will run with each OnDelete().
OnDeleteFunction on_delete_;
fidl::Binding<fuchsia::modular::StoryProviderWatcher> binding_;
};
} // namespace modular_testing
#endif // SRC_MODULAR_LIB_MODULAR_TEST_HARNESS_CPP_FAKE_SESSION_SHELL_H_