blob: 5c228816844b00f709be4ee69fd2eb7da2f8e976 [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.
#include <fuchsia/modular/testing/cpp/fidl.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include "src/lib/fsl/vmo/strings.h"
#include "src/modular/lib/modular_test_harness/cpp/fake_module.h"
#include "src/modular/lib/modular_test_harness/cpp/fake_session_shell.h"
#include "src/modular/lib/modular_test_harness/cpp/fake_story_shell.h"
#include "src/modular/lib/modular_test_harness/cpp/test_harness_fixture.h"
namespace {
constexpr char kParentModuleName[] = "parent_name";
constexpr char kEmbeddedModuleName[] = "embedded_name";
constexpr char kThirdModuleName[] = "third_name";
constexpr char kStoryName[] = "story";
class StoryShellEmbeddedModTest : public modular_testing::TestHarnessFixture {
public:
StoryShellEmbeddedModTest()
: fake_session_shell_(modular_testing::FakeSessionShell::CreateWithDefaultOptions()),
test_story_shell_({.url = modular_testing::TestHarnessBuilder::GenerateFakeUrl(),
.sandbox_services = {"fuchsia.modular.StoryShellContext"}}),
parent_module_(modular_testing::FakeModule::CreateWithDefaultOptions()),
embedded_module_(modular_testing::FakeModule::CreateWithDefaultOptions()),
third_module_(modular_testing::FakeModule::CreateWithDefaultOptions()) {
builder_.InterceptSessionShell(fake_session_shell_->BuildInterceptOptions());
builder_.InterceptStoryShell(test_story_shell_.BuildInterceptOptions());
builder_.InterceptComponent(parent_module_->BuildInterceptOptions());
builder_.InterceptComponent(embedded_module_->BuildInterceptOptions());
builder_.InterceptComponent(third_module_->BuildInterceptOptions());
// Start modular
builder_.BuildAndRun(test_harness());
// Wait for session shell to start
RunLoopUntil([&] { return fake_session_shell_->is_running(); });
}
// Launches an initial parent module.
void LaunchParentModule() {
auto parent_mod_intent = fuchsia::modular::Intent{.handler = parent_module_->url()};
modular_testing::AddModToStory(test_harness(), kStoryName, kParentModuleName,
std::move(parent_mod_intent));
RunLoopUntil([&] { return parent_module_->is_running(); });
}
// The parent module embeds a module.
void ParentModuleEmbedsModule() {
auto embedded_mod_intent = fuchsia::modular::Intent{.handler = embedded_module_->url()};
auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();
fuchsia::modular::ModuleControllerPtr module_controller;
parent_module_->module_context()->EmbedModule(
kEmbeddedModuleName, std::move(embedded_mod_intent), module_controller.NewRequest(),
std::move(view_token), [](const fuchsia::modular::StartModuleStatus status) {});
RunLoopUntil([&] { return embedded_module_->is_running(); });
}
// The embedded module launches a third module in the story shell.
// In this case, the story shell doesn't know about the direct parent of
// the third module because it's embedded and its view is not sent to the
// story shell. Instead, module one must be used as the display parent module
// declared to the story shell for the view of module three.
void EmbeddedModuleLaunchesModule() {
fuchsia::modular::ModuleControllerPtr third_module_ptr;
auto third_module_intent = fuchsia::modular::Intent{.handler = third_module_->url()};
embedded_module_->module_context()->AddModuleToStory(
kThirdModuleName, std::move(third_module_intent), third_module_ptr.NewRequest(),
/* surface_relation */ nullptr, [](const fuchsia::modular::StartModuleStatus) {});
RunLoopUntil([&] { return third_module_->is_running(); });
}
std::unique_ptr<modular_testing::FakeSessionShell> fake_session_shell_;
modular_testing::FakeStoryShell test_story_shell_;
std::unique_ptr<modular_testing::FakeModule> parent_module_;
std::unique_ptr<modular_testing::FakeModule> embedded_module_;
std::unique_ptr<modular_testing::FakeModule> third_module_;
modular_testing::TestHarnessBuilder builder_;
};
} // namespace
// Checks the surface relationships between three modules.
TEST_F(StoryShellEmbeddedModTest, SurfaceRelationships) {
// Set expectations for AddSurface(). Note that we only expect story shell to
// add a surface for non-embedded modules.
test_story_shell_.set_on_add_surface([&](fuchsia::modular::ViewConnection view_connection,
fuchsia::modular::SurfaceInfo surface_info) {
// Continue if this is adding the parent module
if (view_connection.surface_id == kParentModuleName) {
return;
}
// These should pass when the third module is added to the story
EXPECT_EQ(view_connection.surface_id, "parent_name:embedded_name:third_name");
EXPECT_EQ(surface_info.parent_id, kParentModuleName);
});
LaunchParentModule();
// Have the parent module launch an embedded module
ParentModuleEmbedsModule();
// Have the embedded module launch a third module
EmbeddedModuleLaunchesModule();
}