Support branch for tree build status (#679)

* add branch for build status

* formating

* fix test error

* dartfmt

* update test
diff --git a/app_dart/lib/src/request_handlers/get_build_status.dart b/app_dart/lib/src/request_handlers/get_build_status.dart
index 22a9ee8..c3a621a 100644
--- a/app_dart/lib/src/request_handlers/get_build_status.dart
+++ b/app_dart/lib/src/request_handlers/get_build_status.dart
@@ -28,10 +28,13 @@
 
   final BuildStatusProvider buildStatusProvider;
 
+  static const String branchParam = 'branch';
+
   @override
   Future<Body> get() async {
+    final String branch = request.uri.queryParameters[branchParam] ?? 'master';
     final BuildStatus status =
-        await buildStatusProvider.calculateCumulativeStatus();
+        await buildStatusProvider.calculateCumulativeStatus(branch: branch);
 
     return Body.forJson(<String, dynamic>{
       'AnticipatedBuildStatus': _buildStatusLookup[status],
diff --git a/app_dart/lib/src/service/build_status_provider.dart b/app_dart/lib/src/service/build_status_provider.dart
index cc85d81..1e9a0d8 100644
--- a/app_dart/lib/src/service/build_status_provider.dart
+++ b/app_dart/lib/src/service/build_status_provider.dart
@@ -45,9 +45,10 @@
   /// the latest commit status, so it does not impact the build status.
   /// Task B fails because its last known status was to be failing, even though
   /// there is currently a newer version that is in progress.
-  Future<BuildStatus> calculateCumulativeStatus() async {
+  Future<BuildStatus> calculateCumulativeStatus({String branch}) async {
     final List<CommitStatus> statuses = await retrieveCommitStatus(
       limit: numberOfCommitsToReferenceForTreeStatus,
+      branch: branch,
     ).toList();
     if (statuses.isEmpty) {
       return BuildStatus.failed;
diff --git a/app_dart/test/service/build_status_provider_test.dart b/app_dart/test/service/build_status_provider_test.dart
index ea6b3ea..c8ebb26 100644
--- a/app_dart/test/service/build_status_provider_test.dart
+++ b/app_dart/test/service/build_status_provider_test.dart
@@ -177,6 +177,42 @@
             await buildStatusProvider.calculateCumulativeStatus();
         expect(status, BuildStatus.succeeded);
       });
+
+      test('return status when with branch parameter', () async {
+        final Commit commit1 = Commit(
+            key: Key.emptyKey(Partition('ns')).append(Commit, id: 'sha1'),
+            sha: 'sha1',
+            branch: 'flutter-0.0-candidate.0');
+        final Commit commit2 = Commit(
+            key: Key.emptyKey(Partition('ns')).append(Commit, id: 'sha2'),
+            sha: 'sha2',
+            branch: 'master');
+
+        db.values[commit1.key] = commit1;
+        db.values[commit2.key] = commit2;
+
+        final Task task1 = Task(
+            key: commit1.key.append(Task, id: 1),
+            commitKey: commit1.key,
+            name: 'task1',
+            status: Task.statusSucceeded,
+            stageName: 'stage1');
+
+        db.values[task1.key] = task1;
+
+        // Test master branch.
+        final List<CommitStatus> statuses1 =
+            await buildStatusProvider.retrieveCommitStatus(limit: 5).toList();
+        expect(statuses1.length, 1);
+        expect(statuses1.first.commit.branch, 'master');
+
+        // Test dev branch.
+        final List<CommitStatus> statuses2 = await buildStatusProvider
+            .retrieveCommitStatus(limit: 5, branch: 'flutter-0.0-candidate.0')
+            .toList();
+        expect(statuses2.length, 1);
+        expect(statuses2.first.commit.branch, 'flutter-0.0-candidate.0');
+      });
     });
   });
 }
diff --git a/app_dart/test/src/datastore/fake_datastore.dart b/app_dart/test/src/datastore/fake_datastore.dart
index bccd15e..3ad636d 100644
--- a/app_dart/test/src/datastore/fake_datastore.dart
+++ b/app_dart/test/src/datastore/fake_datastore.dart
@@ -168,6 +168,17 @@
   @override
   Stream<T> run() {
     Iterable<T> resultsView = results.skip(start).take(count);
+
+    // This considers only the special case when there exists [branch] filter.
+    for (FakeFilterSpec filter in filters) {
+      final String filterString = filter.filterString;
+      final Object value = filter.comparisonObject;
+      if (filterString.contains('branch =')) {
+        resultsView = resultsView
+            .where((T result) => result.toString().contains(value.toString()));
+      }
+    }
+
     if (db.onQuery.containsKey(T)) {
       resultsView = db.onQuery[T](resultsView).cast<T>();
     }
diff --git a/app_dart/test/src/service/fake_build_status_provider.dart b/app_dart/test/src/service/fake_build_status_provider.dart
index 0aab6db..da386b6 100644
--- a/app_dart/test/src/service/fake_build_status_provider.dart
+++ b/app_dart/test/src/service/fake_build_status_provider.dart
@@ -19,7 +19,7 @@
       throw UnsupportedError('Unsupported');
 
   @override
-  Future<BuildStatus> calculateCumulativeStatus() async {
+  Future<BuildStatus> calculateCumulativeStatus({String branch}) async {
     if (cumulativeStatus == null) {
       throw AssertionError();
     }