[intent_handler] add integration test for intent handler

TEST=
- fx run-test fuchsia_modular_package_integration_tests

Change-Id: If7c123c850cbe9b4cd0eb96583b47c4528f14c58
diff --git a/public/dart/fuchsia_modular/BUILD.gn b/public/dart/fuchsia_modular/BUILD.gn
index b7a4f3a..524da87 100644
--- a/public/dart/fuchsia_modular/BUILD.gn
+++ b/public/dart/fuchsia_modular/BUILD.gn
@@ -116,14 +116,17 @@
     "internal/component_context_integ_test.dart",
     "lifecycle/internal/lifecycle_impl_test.dart",
     "module/internal/module_impl_integ_test.dart",
+    "module/internal/intent_handler_impl_integ_test.dart",
     "proposal/proposal_integ_test.dart",
     "service_connection/agent_service_connection_integ_test.dart",
   ]
 
   deps = [
     ":fuchsia_modular",
+    "//sdk/fidl/fuchsia.modular.testing",
     "//third_party/dart-pkg/pub/mockito",  # Remove after DX-470 is fixed
     "//third_party/dart-pkg/pub/test",
+    "//topaz/public/dart/fuchsia_modular_test",
   ]
   environments = basic_envs
 }
diff --git a/public/dart/fuchsia_modular/meta/fuchsia_modular_package_integration_tests.cmx b/public/dart/fuchsia_modular/meta/fuchsia_modular_package_integration_tests.cmx
index d7a707e..538e643 100644
--- a/public/dart/fuchsia_modular/meta/fuchsia_modular_package_integration_tests.cmx
+++ b/public/dart/fuchsia_modular/meta/fuchsia_modular_package_integration_tests.cmx
@@ -14,6 +14,7 @@
             "fuchsia.modular.ModuleContext",
             "fuchsia.netstack.Netstack",
             "fuchsia.sys.Environment",
+            "fuchsia.sys.Launcher",
             "fuchsia.testing.runner.TestRunner",
             "fuchsia.ui.input.ImeService",
             "fuchsia.ui.policy.Presenter",
diff --git a/public/dart/fuchsia_modular/test/module/internal/intent_handler_impl_integ_test.dart b/public/dart/fuchsia_modular/test/module/internal/intent_handler_impl_integ_test.dart
new file mode 100644
index 0000000..408cadb
--- /dev/null
+++ b/public/dart/fuchsia_modular/test/module/internal/intent_handler_impl_integ_test.dart
@@ -0,0 +1,87 @@
+// 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.
+
+// ignore_for_file: implementation_imports
+
+import 'dart:async';
+
+import 'package:fidl_fuchsia_modular/fidl_async.dart' as fidl_mod;
+import 'package:fuchsia_services/services.dart';
+import 'package:fidl_fuchsia_sys/fidl_async.dart' as fidl_sys;
+import 'package:fuchsia_modular/src/module/internal/_intent_handler_impl.dart';
+import 'package:fuchsia_modular_test/test.dart';
+import 'package:fidl_fuchsia_modular_testing/fidl_async.dart';
+import 'package:test/test.dart';
+
+const _launcherComponentUrl = 'fuchsia.sys.Launcher';
+
+void main() {
+  group('intent handler registration', () {
+    TestHarnessProxy harness;
+
+    setUp(() async {
+      harness = await launchTestHarness();
+    });
+
+    tearDown(() async {
+      harness.ctrl.close();
+    });
+
+    test('register intent handler registers intent', () async {
+      final modUrl = generateComponentUrl();
+      final builder = TestHarnessSpecBuilder()..addComponentToIntercept(modUrl);
+
+      final intent = fidl_mod.Intent(action: 'some_action');
+      final handledIntentCompleter = Completer<fidl_mod.Intent>();
+
+      // Listen for the module to be launched
+      harness.onNewComponent.listen((response) {
+        ////////// IN HERMETIC ENVIROMENT OF LAUNCHED COMPONENT ////////////////
+        if (response.startupInfo.launchInfo.url != modUrl) {
+          return;
+        }
+
+        // create a startup context and expose the intent handler
+        final context = createStartupContext(response.startupInfo);
+        IntentHandlerImpl(startupContext: context).onHandleIntent =
+            handledIntentCompleter.complete;
+        ////////// END HERMETIC ENVIROMENT OF LAUNCHED COMPONENT ///////////////
+      });
+
+      // all setup so run the harness
+      await harness.run(builder.build());
+
+      /////////////////// IN HERMETIC ENVIRONMENT OF TEST HARNESS /////////////////
+      final incoming = Incoming();
+      final launcher = fidl_sys.LauncherProxy();
+      final componentControllerProxy = fidl_sys.ComponentControllerProxy();
+
+      // launch the component in the hermetic environment
+      await harness.connectToEnvironmentService(
+          _launcherComponentUrl, launcher.ctrl.request().passChannel());
+
+      final launchInfo = fidl_sys.LaunchInfo(
+          url: modUrl, directoryRequest: incoming.request().passChannel());
+
+      await launcher.createComponent(
+          launchInfo, componentControllerProxy.ctrl.request());
+
+      launcher.ctrl.close();
+
+      final intentHandlerProxy = fidl_mod.IntentHandlerProxy();
+
+      // connect to the intent handler service in the hermetic environment
+      incoming.connectToService(intentHandlerProxy);
+      await intentHandlerProxy.handleIntent(intent);
+
+      await incoming.close();
+      componentControllerProxy.ctrl.close();
+      /////////////////// END HERMETIC ENVIRONMENT OF TEST HARNESS /////////////////
+
+      // make sure the intent is handled
+      final handledIntent = await handledIntentCompleter.future;
+      expect(handledIntent.action, intent.action);
+    });
+  });
+}
diff --git a/public/dart/fuchsia_modular_test/lib/src/test_harness_fixtures.dart b/public/dart/fuchsia_modular_test/lib/src/test_harness_fixtures.dart
index 7f2c950..1afd7c9 100644
--- a/public/dart/fuchsia_modular_test/lib/src/test_harness_fixtures.dart
+++ b/public/dart/fuchsia_modular_test/lib/src/test_harness_fixtures.dart
@@ -9,6 +9,7 @@
 import 'package:fidl_fuchsia_modular/fidl_async.dart' as fidl_modular;
 import 'package:fidl_fuchsia_sys/fidl_async.dart' as fidl_sys;
 import 'package:fuchsia_services/services.dart';
+import 'package:fuchsia_services/src/internal/_startup_context_impl.dart'; // ignore_for_file: implementation_imports
 
 const _modularTestHarnessURL =
     'fuchsia-pkg://fuchsia.com/modular_test_harness#meta/modular_test_harness.cmx';
@@ -61,3 +62,7 @@
       fidl_testing.ModularService.withComponentContext(proxy.ctrl.request()));
   return proxy;
 }
+
+/// Creates an instance of [StartupContext] from the given [startupInfo]
+StartupContext createStartupContext(fidl_sys.StartupInfo startupInfo) =>
+    StartupContextImpl.from(startupInfo);