// Copyright 2018 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 "peridot/bin/sessionmgr/puppet_master/command_runners/add_mod_command_runner.h"

#include <lib/fidl/cpp/clone.h>
#include <lib/fsl/types/type_converters.h>
#include <lib/fsl/vmo/strings.h>
#include <lib/fxl/type_converter.h>

#include <lib/gtest/test_loop_fixture.h>

#include "gtest/gtest.h"
#include "peridot/lib/ledger_client/page_id.h"
#include "peridot/lib/testing/entity_resolver_fake.h"
#include "peridot/lib/testing/module_resolver_fake.h"
#include "peridot/lib/testing/test_with_session_storage.h"

namespace modular {
namespace {

fuchsia::modular::IntentFilter MakeIntentFilter(
    std::string action,
    std::vector<fuchsia::modular::ParameterConstraint> param_constraints) {
  fuchsia::modular::IntentFilter f;
  f.action = action;
  f.parameter_constraints = param_constraints;
  return f;
}

class AddModCommandRunnerTest : public testing::TestWithSessionStorage {
 public:
  void SetUp() override {
    testing::TestWithSessionStorage::SetUp();
    session_storage_ = MakeSessionStorage("page");
    story_id_ = CreateStory(session_storage_.get());
    story_storage_ = GetStoryStorage(session_storage_.get(), story_id_);
    fake_module_resolver_->Connect(module_resolver_.NewRequest());
    fake_entity_resolver_->Connect(entity_resolver_.NewRequest());
    runner_ = MakeRunner(module_resolver_.get(), entity_resolver_.get());
  }

 protected:
  // This method compares intents field by field, where fuchsia::mem::Buffers
  // are compared via their contents.
  bool AreIntentsEqual(const fuchsia::modular::Intent& old_intent,
                       const fuchsia::modular::Intent& new_intent) {
    if (old_intent.handler != new_intent.handler) {
      return false;
    }

    if (old_intent.action != new_intent.action) {
      return false;
    }

    std::map<fidl::StringPtr, const fuchsia::modular::IntentParameterData*>
        old_params;
    if (old_intent.parameters) {
      for (const auto& entry : *old_intent.parameters) {
        old_params[entry.name] = &entry.data;
      }
    }

    std::map<fidl::StringPtr, const fuchsia::modular::IntentParameterData*>
        new_params;
    if (new_intent.parameters) {
      for (const auto& entry : *new_intent.parameters) {
        new_params[entry.name] = &entry.data;
      }
    }

    if (new_params.size() != old_params.size()) {
      return false;
    }

    for (const auto& entry : new_params) {
      const auto& name = entry.first;
      if (old_params.count(name) == 0) {
        return false;
      }

      const auto& new_param = *entry.second;
      const auto& old_param = *old_params[name];

      // If a parameter type changed, or a link mapping changed, we
      // need to relaunch.
      if (old_param.Which() != new_param.Which()) {
        return false;
      }

      switch (old_param.Which()) {
        case fuchsia::modular::IntentParameterData::Tag::kEntityType:
          if (old_param.entity_type() != new_param.entity_type()) {
            return false;
          }
          break;
        case fuchsia::modular::IntentParameterData::Tag::kEntityReference:
          if (old_param.entity_reference() != new_param.entity_reference()) {
            return false;
          }
          break;
        case fuchsia::modular::IntentParameterData::Tag::kJson: {
          std::string old_string;
          std::string new_string;
          if (old_param.json().size == 0 && new_param.json().size == 0) {
            break;
          }

          FXL_CHECK(fsl::StringFromVmo(old_param.json(), &old_string));
          FXL_CHECK(fsl::StringFromVmo(new_param.json(), &new_string));
          if (old_string != new_string) {
            return false;
          }
          break;
        }
        case fuchsia::modular::IntentParameterData::Tag::Invalid:
          break;
      }
    }
    return true;
  }

  std::unique_ptr<AddModCommandRunner> MakeRunner(
      fuchsia::modular::ModuleResolver* const module_resolver,
      fuchsia::modular::EntityResolver* const entity_resolver) {
    return std::make_unique<AddModCommandRunner>(module_resolver,
                                                 entity_resolver);
  }

  fuchsia::modular::StoryCommand MakeAddModCommand(
      const std::string& mod_name, const std::string& parent_mod_name,
      float surface_emphasis, const fuchsia::modular::Intent& intent) {
    fuchsia::modular::AddMod add_mod;
    add_mod.mod_name = {mod_name};
    if (!parent_mod_name.empty()) {
      add_mod.surface_parent_mod_name.reset({parent_mod_name});
    }
    add_mod.surface_relation.emphasis = surface_emphasis;
    intent.Clone(&add_mod.intent);
    fuchsia::modular::StoryCommand command;
    command.set_add_mod(std::move(add_mod));
    return command;
  }

  fuchsia::modular::Intent CreateEmptyIntent(const std::string& action,
                                             const std::string& handler = "") {
    fuchsia::modular::Intent intent;
    intent.action = "intent_action";
    if (!handler.empty()) {
      intent.handler = "mod_url";
    }
    return intent;
  }

  void AddEntityRefParameter(fuchsia::modular::Intent* intent,
                             const std::string& name,
                             const std::string& reference) {
    fuchsia::modular::IntentParameter parameter;
    parameter.name = name;
    parameter.data.set_entity_reference(reference);
    intent->parameters.push_back(std::move(parameter));
  }

  void AddEntityTypeParameter(fuchsia::modular::Intent* intent,
                              const std::string& name,
                              std::vector<std::string> types) {
    fuchsia::modular::IntentParameter parameter;
    parameter.name = name;
    parameter.data.set_entity_type(types);
    intent->parameters.push_back(std::move(parameter));
  }

  void AddParameterWithoutName(fuchsia::modular::Intent* intent) {
    fuchsia::modular::IntentParameter parameter;
    fsl::SizedVmo vmo;
    FXL_CHECK(fsl::VmoFromString("10", &vmo));
    parameter.data.set_json(std::move(vmo).ToTransport());
    intent->parameters.push_back(std::move(parameter));
  }

  void AddJsonParameter(fuchsia::modular::Intent* intent,
                        const std::string& name, const std::string& json) {
    fuchsia::modular::IntentParameter parameter;
    parameter.name = name;
    fsl::SizedVmo vmo;
    FXL_CHECK(fsl::VmoFromString(json, &vmo));
    parameter.data.set_json(std::move(vmo).ToTransport());
    intent->parameters.push_back(std::move(parameter));
  }

  void AddInvalidParameter(fuchsia::modular::Intent* intent,
                           const std::string& name) {
    // This parameter has no data union field set, hence it's invalid.
    fuchsia::modular::IntentParameterData data;
    fuchsia::modular::IntentParameter parameter;
    parameter.name = name;
    parameter.data = std::move(data);
    intent->parameters.push_back(std::move(parameter));
  }

  // Initializes a parent mod for the mod created during the test. The goal of
  // this mod is to test parameters of type link_name and as the
  // surface_relation_parent_mod.
  void InitParentMod(const std::string& mod_name, const std::string& param_name,
                     const std::string& param_value,
                     const std::string& link_path_name) {
    fuchsia::modular::ModuleData module_data;
    module_data.module_path.push_back(mod_name);
    module_data.intent = fuchsia::modular::Intent::New();
    AddJsonParameter(module_data.intent.get(), param_name, param_value);

    fuchsia::modular::ModuleParameterMapEntry parameter_entry;
    auto link_path = MakeLinkPath(link_path_name);
    fidl::Clone(module_data.module_path, &link_path.module_path);
    parameter_entry.name = param_name;
    fidl::Clone(link_path, &parameter_entry.link_path);
    module_data.parameter_map.entries.push_back(std::move(parameter_entry));

    SetLinkValue(story_storage_.get(), link_path, param_value);
    WriteModuleData(story_storage_.get(), std::move(module_data));
  }

  std::unique_ptr<AddModCommandRunner> runner_;
  std::unique_ptr<SessionStorage> session_storage_;
  std::unique_ptr<StoryStorage> story_storage_;
  fuchsia::modular::ModuleResolverPtr module_resolver_;
  fuchsia::modular::EntityResolverPtr entity_resolver_;
  std::string story_id_;
  std::unique_ptr<ModuleResolverFake> fake_module_resolver_ =
      std::make_unique<ModuleResolverFake>();
  std::unique_ptr<EntityResolverFake> fake_entity_resolver_ =
      std::make_unique<EntityResolverFake>();
};

TEST_F(AddModCommandRunnerTest, ExecuteIntentWithIntentHandler) {
  // Set up command
  auto intent = CreateEmptyIntent("intent_action", "mod_url");
  intent.parameters.resize(0);
  auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);

  auto manifest = fuchsia::modular::ModuleManifest::New();
  manifest->intent_filters.push_back(MakeIntentFilter("intent_action", {}));
  manifest->binary = "mod_url";

  // Set up fake module resolver and set validation of GetModuleManifest call.
  fuchsia::modular::ModuleManifestPtr manifest_out;
  fuchsia::modular::ModuleManifestPtr manifest_to_add;
  fidl::Clone(manifest, &manifest_out);
  fidl::Clone(manifest, &manifest_to_add);
  fake_module_resolver_->SetManifest(std::move(manifest_out));
  fake_module_resolver_->SetGetModuleManifestValidation(
      [&](const fidl::StringPtr& module_id) {
        EXPECT_EQ(intent.handler, module_id);
      });

  fuchsia::modular::FindModulesResult res;
  res.module_id = "mod_url";
  res.manifest = std::move(manifest_to_add);
  fake_module_resolver_->AddFindModulesResult(std::move(res));

  // Run the command and assert results.
  bool done = false;
  runner_->Execute(story_id_, story_storage_.get(), std::move(command),
                   [&](fuchsia::modular::ExecuteResult result) {
                     ASSERT_EQ(fuchsia::modular::ExecuteStatus::OK,
                               result.status);
                     done = true;
                   });
  RunLoopUntil([&] { return done; });

  done = false;
  std::vector<std::string> full_path{"parent_mod", "mod"};
  story_storage_->ReadModuleData(std::move(full_path))
      ->Then([&](fuchsia::modular::ModuleDataPtr module_data) {
        EXPECT_EQ("mod_url", module_data->module_url);
        EXPECT_EQ(full_path, module_data->module_path);
        EXPECT_FALSE(module_data->module_deleted);
        EXPECT_EQ(fuchsia::modular::ModuleSource::EXTERNAL,
                  module_data->module_source);
        EXPECT_EQ(0.5, module_data->surface_relation->emphasis);
        EXPECT_TRUE(AreIntentsEqual(intent, *module_data->intent));
        EXPECT_EQ(0u, module_data->parameter_map.entries.size());
        done = true;
      });

  RunLoopUntil([&] { return done; });
}

// Explicitly leave surface_parent_mod_name as null when providing the Intent.
// We should tolerate this, and initialize it to a zero-length vector
// internally.
TEST_F(AddModCommandRunnerTest, ExecuteIntentWithIntentHandler_NoParent) {
  auto intent = CreateEmptyIntent("intent_action", "mod_url");
  intent.parameters.resize(0);
  auto command =
      MakeAddModCommand("mod", "" /* parent mod is null */, 0.5, intent);

  auto manifest = fuchsia::modular::ModuleManifest::New();
  manifest->intent_filters.push_back(MakeIntentFilter("intent_action", {}));
  manifest->binary = "mod_url";

  // Set up fake module resolver and set validation of GetModuleManifest call.
  fuchsia::modular::ModuleManifestPtr manifest_out;
  fuchsia::modular::ModuleManifestPtr manifest_to_add;
  fidl::Clone(manifest, &manifest_out);
  fidl::Clone(manifest, &manifest_to_add);
  fake_module_resolver_->SetManifest(std::move(manifest_out));
  fake_module_resolver_->SetGetModuleManifestValidation(
      [&](const fidl::StringPtr& module_id) {
        EXPECT_EQ(intent.handler, module_id);
      });

  fuchsia::modular::FindModulesResult res;
  res.module_id = "mod_url";
  res.manifest = std::move(manifest_to_add);
  fake_module_resolver_->AddFindModulesResult(std::move(res));

  // Run the command and assert results.
  bool done = false;
  runner_->Execute(story_id_, story_storage_.get(), std::move(command),
                   [&](fuchsia::modular::ExecuteResult result) {
                     ASSERT_EQ(fuchsia::modular::ExecuteStatus::OK,
                               result.status);
                     done = true;
                   });
  RunLoopUntil([&] { return done; });

  done = false;
  std::vector<std::string> full_path{"mod"};
  story_storage_->ReadModuleData(std::move(full_path))
      ->Then([&](fuchsia::modular::ModuleDataPtr module_data) {
        EXPECT_EQ("mod_url", module_data->module_url);
        EXPECT_EQ(full_path, module_data->module_path);
        EXPECT_FALSE(module_data->module_deleted);
        EXPECT_EQ(fuchsia::modular::ModuleSource::EXTERNAL,
                  module_data->module_source);
        EXPECT_EQ(0.5, module_data->surface_relation->emphasis);
        EXPECT_TRUE(AreIntentsEqual(intent, *module_data->intent));
        EXPECT_EQ(0u, module_data->parameter_map.entries.size());
        done = true;
      });

  RunLoopUntil([&] { return done; });
}

TEST_F(AddModCommandRunnerTest, ExecuteIntentThatNeedsResolution) {
  auto reference =
      fake_entity_resolver_->AddEntity({{"entity_type1", "entity_data"}});

  InitParentMod("parent_mod", "param", R"({"@type": "baz"})",
                "parent_link_name");

  // Set up command
  auto intent = CreateEmptyIntent("intent_action");
  AddJsonParameter(&intent, "param_json", R"({"@type": "foo"})");
  AddEntityRefParameter(&intent, "param_ref", reference);
  AddEntityTypeParameter(&intent, "param_type", {"entity_type2"});
  auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);

  auto manifest = fuchsia::modular::ModuleManifest::New();
  manifest->binary = "mod_url";
  manifest->intent_filters.push_back(MakeIntentFilter("intent_action", {}));
  fuchsia::modular::FindModulesResult result;
  result.module_id = "mod_url";
  fidl::Clone(manifest, &result.manifest);

  fake_module_resolver_->AddFindModulesResult(std::move(result));
  // Since we are mocking module resolver and returning the expected |result|,
  // ensure that at least it's being called with the right parameters.
  fake_module_resolver_->SetFindModulesValidation(
      [&](const fuchsia::modular::FindModulesQuery& query) {
        EXPECT_EQ("intent_action", query.action);
        auto& constraints = query.parameter_constraints;
        EXPECT_EQ(3u, constraints.size());
        for (auto& constraint : constraints) {
          EXPECT_EQ(1u, constraint.param_types.size());
        }
        EXPECT_EQ("param_json", constraints.at(0).param_name);
        EXPECT_EQ("foo", constraints.at(0).param_types.at(0));
        EXPECT_EQ("param_ref", constraints.at(1).param_name);
        EXPECT_EQ("entity_type1", constraints.at(1).param_types.at(0));
        EXPECT_EQ("param_ref", constraints.at(1).param_name);
        EXPECT_EQ("entity_type1", constraints.at(1).param_types.at(0));
        EXPECT_EQ("param_type", constraints.at(2).param_name);
        EXPECT_EQ("entity_type2", constraints.at(2).param_types.at(0));
      });

  bool done{};
  runner_->Execute(story_id_, story_storage_.get(), std::move(command),
                   [&](fuchsia::modular::ExecuteResult result) {
                     EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK,
                               result.status);
                     done = true;
                   });
  RunLoopUntil([&] { return done; });

  done = false;
  std::vector<std::string> full_path{"parent_mod", "mod"};
  fuchsia::modular::ModuleDataPtr module_data;
  story_storage_->ReadModuleData(std::move(full_path))
      ->Then([&](fuchsia::modular::ModuleDataPtr result) {
        module_data = std::move(result);
        done = true;
      });
  RunLoopUntil([&] { return done; });

  EXPECT_EQ("mod_url", module_data->module_url);
  EXPECT_EQ(full_path, module_data->module_path);
  EXPECT_FALSE(module_data->module_deleted);
  EXPECT_EQ(fuchsia::modular::ModuleSource::EXTERNAL,
            module_data->module_source);
  EXPECT_EQ(0.5, module_data->surface_relation->emphasis);
  EXPECT_TRUE(AreIntentsEqual(intent, *module_data->intent));
  EXPECT_EQ(3u, module_data->parameter_map.entries.size());

  // Verify parameters
  auto& link_path1 = module_data->parameter_map.entries.at(0).link_path;
  EXPECT_EQ("param_json", module_data->parameter_map.entries.at(0).name);
  EXPECT_EQ(full_path, link_path1.module_path);
  EXPECT_EQ("param_json", link_path1.link_name);
  EXPECT_EQ(R"({"@type": "foo"})",
            GetLinkValue(story_storage_.get(), link_path1));

  auto& link_path2 = module_data->parameter_map.entries.at(1).link_path;
  EXPECT_EQ("param_ref", module_data->parameter_map.entries.at(1).name);
  EXPECT_EQ(full_path, link_path2.module_path);
  EXPECT_EQ("param_ref", link_path2.link_name);
  EXPECT_EQ(R"({"@entityRef":")" + *reference + R"("})",
            GetLinkValue(story_storage_.get(), link_path2));

  auto& link_path3 = module_data->parameter_map.entries.at(2).link_path;
  EXPECT_EQ("param_type", module_data->parameter_map.entries.at(2).name);
  EXPECT_EQ(full_path, link_path3.module_path);
  EXPECT_EQ("param_type", link_path3.link_name);
  EXPECT_EQ("null", GetLinkValue(story_storage_.get(), link_path3));
}

TEST_F(AddModCommandRunnerTest, ExecuteNoModulesFound) {
  fuchsia::modular::Intent intent;
  fuchsia::modular::AddMod add_mod;
  intent.Clone(&add_mod.intent);
  add_mod.mod_name.push_back("mymod");
  add_mod.intent.action = "intent_action";
  fuchsia::modular::StoryCommand command;
  command.set_add_mod(std::move(add_mod));

  bool done{};
  runner_->Execute(story_id_, story_storage_.get(), std::move(command),
                   [&](fuchsia::modular::ExecuteResult result) {
                     EXPECT_EQ(
                         fuchsia::modular::ExecuteStatus::NO_MODULES_FOUND,
                         result.status);
                     EXPECT_EQ("Resolution of intent gave zero results.",
                               result.error_message);
                     done = true;
                   });
  RunLoopUntil([&] { return done; });
}

TEST_F(AddModCommandRunnerTest, ExecuteInvalidParameter) {
  // Set up command
  auto intent = CreateEmptyIntent("intent_action", "mod_url");
  AddInvalidParameter(&intent, "invalid_param");
  auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);

  auto manifest = fuchsia::modular::ModuleManifest::New();
  manifest->binary = "mod_url";
  manifest->intent_filters.push_back(MakeIntentFilter("intent_action", {}));

  // Set up fake module resolver.
  fuchsia::modular::ModuleManifestPtr manifest_out;
  fidl::Clone(manifest, &manifest_out);
  fake_module_resolver_->SetManifest(std::move(manifest_out));

  // Run the command and assert results.
  bool done{};
  runner_->Execute(story_id_, story_storage_.get(), std::move(command),
                   [&](fuchsia::modular::ExecuteResult result) {
                     EXPECT_EQ(fuchsia::modular::ExecuteStatus::INVALID_COMMAND,
                               result.status);
                     EXPECT_EQ(
                         "Invalid data for parameter with name: "
                         "invalid_param",
                         result.error_message);
                     done = true;
                   });
  RunLoopUntil([&] { return done; });
}

TEST_F(AddModCommandRunnerTest, ExecuteInvalidParameterWithResulution) {
  // Set up command
  auto intent = CreateEmptyIntent("intent_action");
  AddInvalidParameter(&intent, "invalid_param");
  auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);

  // Set up fake module resolver.
  auto manifest = fuchsia::modular::ModuleManifest::New();
  manifest->binary = "mod_url";
  manifest->intent_filters.push_back(MakeIntentFilter("intent_action", {}));
  fuchsia::modular::FindModulesResult result;
  result.module_id = "mod_url";
  fidl::Clone(manifest, &result.manifest);

  fake_module_resolver_->AddFindModulesResult(std::move(result));

  // Run the command and assert results.
  bool done{};
  runner_->Execute(story_id_, story_storage_.get(), std::move(command),
                   [&](fuchsia::modular::ExecuteResult result) {
                     EXPECT_EQ(fuchsia::modular::ExecuteStatus::INVALID_COMMAND,
                               result.status);
                     EXPECT_EQ(
                         "Invalid data for parameter with name: "
                         "invalid_param",
                         result.error_message);
                     done = true;
                   });
  RunLoopUntil([&] { return done; });
}

TEST_F(AddModCommandRunnerTest, ExecuteNullHandlerAndParameter) {
  // Set up command
  auto intent = CreateEmptyIntent("intent_action");
  AddParameterWithoutName(&intent);
  auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);

  // Run the command and assert results.
  bool done{};
  runner_->Execute(story_id_, story_storage_.get(), std::move(command),
                   [&](fuchsia::modular::ExecuteResult result) {
                     EXPECT_EQ(fuchsia::modular::ExecuteStatus::INVALID_COMMAND,
                               result.status);
                     EXPECT_EQ(
                         "A null-named module parameter is not allowed "
                         "when using fuchsia::modular::Intent.",
                         result.error_message);
                     done = true;
                   });
  RunLoopUntil([&] { return done; });
}

TEST_F(AddModCommandRunnerTest, ExecuteInvalidJsonParamResolution) {
  // Set up command
  auto intent = CreateEmptyIntent("intent_action");
  AddJsonParameter(&intent, "invalid_param", "x}");
  auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);

  // Set up fake module resolver.
  auto manifest = fuchsia::modular::ModuleManifest::New();
  manifest->binary = "mod_url";
  manifest->intent_filters.push_back(MakeIntentFilter("intent_action", {}));
  fuchsia::modular::FindModulesResult result;
  result.module_id = "mod_url";
  fidl::Clone(manifest, &result.manifest);
  fake_module_resolver_->AddFindModulesResult(std::move(result));

  // Run the command and assert results.
  bool done{};
  runner_->Execute(story_id_, story_storage_.get(), std::move(command),
                   [&](fuchsia::modular::ExecuteResult result) {
                     EXPECT_EQ(fuchsia::modular::ExecuteStatus::INVALID_COMMAND,
                               result.status);
                     EXPECT_EQ("Mal-formed JSON in parameter: invalid_param",
                               result.error_message);
                     done = true;
                   });
  RunLoopUntil([&] { return done; });
}

TEST_F(AddModCommandRunnerTest, UpdatesModIfItExists) {
  // Set up command
  auto intent = CreateEmptyIntent("intent_action", "mod_url");
  AddJsonParameter(&intent, "param_json", R"({"@type": "foo"})");
  auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);

  auto manifest = fuchsia::modular::ModuleManifest::New();
  manifest->binary = "mod_url";
  manifest->intent_filters.push_back(MakeIntentFilter(
      "intent_action",
      {fuchsia::modular::ParameterConstraint{"param_json", "foo"}}));

  // Set up fake module resolver, set validaiton of GetModuleManifest call, and
  // a dummy result.
  {
    fuchsia::modular::ModuleManifestPtr manifest_out;
    fidl::Clone(manifest, &manifest_out);
    fake_module_resolver_->SetManifest(std::move(manifest_out));

    fuchsia::modular::FindModulesResult res;
    res.module_id = "mod_url";
    res.manifest = std::move(manifest);
    fake_module_resolver_->AddFindModulesResult(std::move(res));
  }

  // Add a mod to begin with.
  bool done{};
  runner_->Execute(story_id_, story_storage_.get(), std::move(command),
                   [&](fuchsia::modular::ExecuteResult result) {
                     ASSERT_EQ(fuchsia::modular::ExecuteStatus::OK,
                               result.status);
                     done = true;
                   });
  RunLoopUntil([&] { return done; });

  // Get the link path for the param of the mod we created.
  fuchsia::modular::LinkPath link_path;
  std::vector<std::string> full_path{"parent_mod", "mod"};
  story_storage_->ReadModuleData(full_path)->Then(
      [&](fuchsia::modular::ModuleDataPtr result) {
        for (auto& entry : result->parameter_map.entries) {
          if (entry.name == "param_json") {
            fidl::Clone(entry.link_path, &link_path);
          }
        }
      });

  // Create AddMod intent for a mod with the same name as the one we created
  // previously.
  auto intent2 = CreateEmptyIntent("intent_action", "mod_url");
  AddJsonParameter(&intent2, "param_json", R"({"@type": "baz"})");
  fuchsia::modular::AddMod add_mod;
  add_mod.mod_name = {"parent_mod", "mod"};
  intent2.Clone(&add_mod.intent);
  fuchsia::modular::StoryCommand command2;
  command2.set_add_mod(std::move(add_mod));

  {
    fuchsia::modular::ModuleManifestPtr manifest_out;
    fidl::Clone(manifest, &manifest_out);
    fake_module_resolver_->SetManifest(std::move(manifest_out));

    fuchsia::modular::FindModulesResult res;
    res.module_id = "mod_url";
    res.manifest = std::move(manifest);
    fake_module_resolver_->AddFindModulesResult(std::move(res));
  }

  done = false;
  runner_->Execute(story_id_, story_storage_.get(), std::move(command2),
                   [&](fuchsia::modular::ExecuteResult result) {
                     ASSERT_EQ(fuchsia::modular::ExecuteStatus::OK,
                               result.status);
                     done = true;
                   });
  RunLoopUntil([&] { return done; });

  done = false;
  // Verify we updated an existing link.
  story_storage_->GetLinkValue(link_path)->Then(
      [&](StoryStorage::Status status, fidl::StringPtr v) {
        EXPECT_EQ(R"({"@type": "baz"})", *v);
        done = true;
      });
  RunLoopUntil([&] { return done; });
}

}  // namespace
}  // namespace modular
