[cloud functions] Test code that links a landed CL with its review

Code being tested is from CL
https://dart-review.googlesource.com/c/dart_ci/+/126880

Change-Id: I946ccea55beee8c7f6215513ec1da2fe60ea2ff7
Reviewed-on: https://dart-review.googlesource.com/c/dart_ci/+/127021
Reviewed-by: Alexander Thomas <athom@google.com>
diff --git a/functions/node/test/firestore_mock.dart b/functions/node/test/firestore_mock.dart
deleted file mode 100644
index 1bbd969..0000000
--- a/functions/node/test/firestore_mock.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:mockito/mockito.dart';
-
-import '../firestore.dart';
-import 'test_data.dart';
-
-class FirestoreServiceMock extends Mock implements FirestoreService {
-  FirestoreServiceMock() {
-    when(this.getCommit(existingCommitHash))
-        .thenAnswer((_) => Future.value(existingCommit));
-    when(this.getCommit(previousCommitHash))
-        .thenAnswer((_) => Future.value(previousCommit));
-  }
-}
diff --git a/functions/node/test/http_mock.dart b/functions/node/test/http_mock.dart
deleted file mode 100644
index 0ce904e..0000000
--- a/functions/node/test/http_mock.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:http/http.dart';
-import 'package:mockito/mockito.dart';
-
-import 'test_data.dart';
-
-class HttpClientMock extends Mock implements BaseClient {}
diff --git a/functions/node/test/test.dart b/functions/node/test/test.dart
index 912007f..0ae6fe1 100644
--- a/functions/node/test/test.dart
+++ b/functions/node/test/test.dart
@@ -4,19 +4,32 @@
 
 import 'package:mockito/mockito.dart';
 import 'package:test/test.dart';
+import 'package:http/http.dart';
 
 import '../builder.dart';
-import 'firestore_mock.dart';
-import 'http_mock.dart';
+import '../firestore.dart';
 import 'test_data.dart';
 
+class FirestoreServiceMock extends Mock implements FirestoreService {}
+
+class HttpClientMock extends Mock implements BaseClient {}
+
+class ResponseFake extends Fake implements Response {
+  String body;
+  ResponseFake(this.body);
+}
+
 void main() async {
   test("Store already existing commit", () async {
     final client = HttpClientMock();
     final firestore = FirestoreServiceMock();
-    final change = alreadyExistingCommitChange;
+    when(firestore.getCommit(existingCommitHash))
+        .thenAnswer((_) => Future.value(existingCommit));
+    when(firestore.getCommit(previousCommitHash))
+        .thenAnswer((_) => Future.value(previousCommit));
 
-    final builder = Build(existingCommitHash, change, firestore, client);
+    final builder =
+        Build(existingCommitHash, existingCommitChange, firestore, client);
     await builder.storeBuildCommitsInfo();
     expect(builder.endIndex, existingCommit['index']);
     expect(builder.startIndex, previousCommit['index'] + 1);
@@ -24,5 +37,52 @@
       firestore.getCommit(existingCommitHash),
       firestore.getCommit(previousCommitHash)
     ]);
+    verifyNoMoreInteractions(firestore);
+    verifyZeroInteractions(client);
+  });
+
+  test("Link landed commit to review", () async {
+    final client = HttpClientMock();
+    final firestore = FirestoreServiceMock();
+    when(firestore.getCommit(existingCommitHash))
+        .thenAnswer((_) => Future.value(existingCommit));
+    final landedResponses = [null, landedCommit];
+    when(firestore.getCommit(landedCommitHash))
+        .thenAnswer((_) => Future(() => landedResponses.removeAt(0)));
+    when(firestore.getLastCommit()).thenAnswer(
+        (_) => Future(() => {...existingCommit, 'id': existingCommitHash}));
+    when(firestore.reviewIsLanded(any)).thenAnswer((_) => Future.value(true));
+
+    when(client.get(any))
+        .thenAnswer((_) => Future(() => ResponseFake(gitilesLog)));
+
+    final builder =
+        Build(landedCommitHash, landedCommitChange, firestore, client);
+    await builder.storeBuildCommitsInfo();
+    expect(builder.endIndex, landedCommit['index']);
+    expect(builder.startIndex, existingCommit['index'] + 1);
+    verifyInOrder([
+      verify(firestore.getCommit(landedCommitHash)).called(2),
+      verify(firestore.getLastCommit()),
+      verify(firestore.addCommit(gitLogCommitHash, {
+        'author': 'user@example.com',
+        'created': DateTime.parse('2019-11-28 12:07:55 +0000'),
+        'index': 53,
+        'title': 'A commit on the git log',
+        'review': 77779
+      })),
+      verify(firestore.reviewIsLanded(77779)),
+      verify(firestore.addCommit(landedCommitHash, {
+        'author': 'gerrit_user@example.com',
+        'created': DateTime.parse('2019-11-29 15:15:00 +0000'),
+        'index': 54,
+        'title': 'A commit used for testing tryjob approvals, with index 54',
+        'review': 44445
+      })),
+      verify(firestore.reviewIsLanded(44445)),
+      // We want to verify firestore.getCommit(landedCommitHash) here,
+      // but it is already matched by the earlier check for the same call.
+      verify(firestore.getCommit(existingCommitHash))
+    ]);
   });
 }
diff --git a/functions/node/test/test_data.dart b/functions/node/test/test_data.dart
index 140ce6f..55a02bf 100644
--- a/functions/node/test/test_data.dart
+++ b/functions/node/test/test_data.dart
@@ -4,7 +4,7 @@
 
 import 'dart:core';
 
-const Map<String, dynamic> alreadyExistingCommitChange = {
+const Map<String, dynamic> existingCommitChange = {
   "name": "dart2js_extra/local_function_signatures_strong_test/none",
   "configuration": "dart2js-new-rti-linux-x64-d8",
   "suite": "dart2js_extra",
@@ -43,3 +43,68 @@
   'index': 49,
   'title': 'A commit used for testing, with index 49'
 };
+
+const String landedCommitHash = 'a commit landing a CL hash';
+Map<String, dynamic> landedCommit = {
+  'author': 'gerrit_user@example.com',
+  'created': DateTime.parse('2019-11-29 15:15:00Z'),
+  'index': 54,
+  'title': 'A commit used for testing tryjob approvals, with index 54'
+};
+
+const Map<String, dynamic> landedCommitChange = {
+  "name": "dart2js_extra/local_function_signatures_strong_test/none",
+  "configuration": "dart2js-new-rti-linux-x64-d8",
+  "suite": "dart2js_extra",
+  "test_name": "local_function_signatures_strong_test/none",
+  "time_ms": 2384,
+  "result": "RuntimeError",
+  "expected": "Pass",
+  "matches": true,
+  "bot_name": "luci-dart-try-xenial-70-8fkh",
+  "commit_hash": landedCommitHash,
+  "commit_time": 1563576771,
+  "build_number": "308",
+  "builder_name": "dart2js-rti-linux-x64-d8",
+  "flaky": false,
+  "previous_flaky": false,
+  "previous_result": "Pass",
+  "previous_commit_hash": existingCommitHash,
+  "previous_commit_time": 1563576211,
+  "previous_build_number": "306",
+  "changed": true
+};
+
+const Map<String, dynamic> tryjobResult = {};
+
+String gitLogCommitHash = "a commit fetched from the git log";
+
+String gitilesLog = '''
+)]}'
+{
+  "log": [
+    {
+      "commit": "$landedCommitHash",
+      "parents": ["$gitLogCommitHash"],
+      "author": {
+        "email": "gerrit_user@example.com"
+      },
+      "committer": {
+        "time": "Fri Nov 29 15:15:00 2019 +0000"
+      },
+      "message": "A commit used for testing tryjob approvals, with index 54\\n\\nDescription of the landed commit\\nin multiple lines.\\n\\u003e Change-Id: I8dcc08b7571137e869a16ceea8cc73539eb02a5a\\n\\u003e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/33337\\n\\nChange-Id: I89b88c3d9f7c743fc340ee73a45c3f57059bcf30\\nReviewed-on: https://dart-review.googlesource.com/c/sdk/+/44445\\n\\n"
+    },
+    {
+      "commit": "$gitLogCommitHash",
+      "parents": ["$existingCommitHash"],
+      "author": {
+        "email": "user@example.com"
+      },
+      "committer": {
+        "time": "Thu Nov 28 12:07:55 2019 +0000"
+      },
+      "message": "A commit on the git log\\n\\nThis commit does not have results from the CQ\\n\\nChange-Id: I481b2cb8b666885b5c2b9c53fff1177accd01830\\nReviewed-on: https://dart-review.googlesource.com/c/sdk/+/77779\\nCommit-Queue: A user \\u003cuser9@example.com\\u003e\\nReviewed-by: Another user \\u003cuser10@example.com\\u003e\\n"
+    }
+  ]
+}
+''';