blob: 5fed85a4ede87dad590e4d6a14fa506135a0952e [file] [log] [blame]
// Copyright 2022 The Flutter 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: constant_identifier_names
import 'dart:async';
import 'dart:convert';
import 'package:auto_submit/configuration/repository_configuration.dart';
import 'package:auto_submit/service/config.dart';
import 'package:auto_submit/requests/check_pull_request.dart';
import 'package:auto_submit/requests/graphql_queries.dart';
import 'package:auto_submit/service/log.dart';
import 'package:github/github.dart';
import 'package:googleapis/bigquery/v2.dart';
import 'package:googleapis/pubsub/v1.dart' as pub;
import 'package:graphql/client.dart' hide Request, Response;
import 'package:logging/logging.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
import '../configuration/repository_configuration_data.dart';
import '../service/bigquery_test.dart';
import '../src/service/fake_bigquery_service.dart';
import './github_webhook_test_data.dart';
import '../src/request_handling/fake_pubsub.dart';
import '../src/request_handling/fake_authentication.dart';
import '../src/service/fake_config.dart';
import '../src/service/fake_github_service.dart';
import '../src/service/fake_graphql_client.dart';
import '../utilities/mocks.dart';
import '../utilities/utils.dart' hide createQueryResult;
const String oid = '6dcb09b5b57875f334f61aebed695e2e4193db5e';
const String title = 'some_title';
void main() {
group('Check CheckPullRequest', () {
late CheckPullRequest checkPullRequest;
late FakeConfig config;
late FakeCronAuthProvider auth;
late FakeGraphQLClient githubGraphQLClient;
late FakeGithubService githubService;
late MockJobsResource jobsResource;
late FakeBigqueryService bigqueryService;
late MockPullRequestsService pullRequests;
final MockGitHub gitHub = MockGitHub();
late FakePubSub pubsub;
late PullRequestHelper flutterRequest;
late PullRequestHelper cocoonRequest;
late List<QueryOptions> expectedOptions;
late QueryOptions flutterOption;
late QueryOptions cocoonOption;
const String testSubscription = 'test-sub';
const String testTopic = 'test-topic';
const String rollorAuthor = 'engine-flutter-autoroll';
const String labelName = 'warning: land on red to fix tree breakage';
const String cocoonRepo = 'cocoon';
const String noAutosubmitLabel = 'no_autosubmit';
setUp(() {
githubGraphQLClient = FakeGraphQLClient();
auth = FakeCronAuthProvider();
pubsub = FakePubSub();
expectedOptions = <QueryOptions>[];
githubService = FakeGithubService();
githubGraphQLClient.mutateResultForOptions = (MutationOptions options) => createFakeQueryResult();
githubGraphQLClient.queryResultForOptions = (QueryOptions options) {
expect(options.variables['sOwner'], 'flutter');
final String? repoName = options.variables['sName'] as String?;
if (repoName == 'flutter') {
return createQueryResult(flutterRequest);
} else if (repoName == 'cocoon') {
return createQueryResult(cocoonRequest);
} else {
fail('unexpected repo $repoName');
}
};
final FindPullRequestsWithReviewsQuery findPullRequestsWithReviewsQueryFlutter = FindPullRequestsWithReviewsQuery(
repositoryOwner: 'flutter',
repositoryName: 'flutter',
pullRequestNumber: 0,
);
flutterOption = QueryOptions(
document: findPullRequestsWithReviewsQueryFlutter.documentNode,
fetchPolicy: FetchPolicy.noCache,
variables: findPullRequestsWithReviewsQueryFlutter.variables,
);
final FindPullRequestsWithReviewsQuery findPullRequestsWithReviewsQueryCocoon = FindPullRequestsWithReviewsQuery(
repositoryOwner: 'flutter',
repositoryName: 'cocoon',
pullRequestNumber: 1,
);
cocoonOption = QueryOptions(
document: findPullRequestsWithReviewsQueryCocoon.documentNode,
fetchPolicy: FetchPolicy.noCache,
variables: findPullRequestsWithReviewsQueryCocoon.variables,
);
githubService.checkRunsData = checkRunsMock;
githubService.compareTwoCommitsData = compareTwoCommitsMock;
githubService.successMergeData = successMergeMock;
githubService.createCommentData = createCommentMock;
githubService.commitData = commitMock;
jobsResource = MockJobsResource();
bigqueryService = FakeBigqueryService(jobsResource);
config = FakeConfig(
githubService: githubService,
githubGraphQLClient: githubGraphQLClient,
githubClient: gitHub,
);
config.bigqueryService = bigqueryService;
config.repositoryConfigurationMock = RepositoryConfiguration.fromYaml(sampleConfigNoOverride);
pullRequests = MockPullRequestsService();
when(gitHub.pullRequests).thenReturn(pullRequests);
when(pullRequests.get(any, any)).thenAnswer(
(_) async => PullRequest(
number: 123,
state: 'open',
),
);
when(jobsResource.query(captureAny, any)).thenAnswer((Invocation invocation) {
return Future<QueryResponse>.value(
QueryResponse.fromJson(jsonDecode(insertDeleteUpdateSuccessResponse) as Map<dynamic, dynamic>),
);
});
});
void verifyQueries(List<QueryOptions> expectedOptions) {
githubGraphQLClient.verifyQueries(expectedOptions);
}
test('Multiple identical messages are processed once', () async {
final PullRequest pullRequest1 = generatePullRequest(
prNumber: 0,
repoName: cocoonRepo,
);
// 'member' is in the review nodes and 'author1' is the pr author.
githubService.isTeamMemberMockMap['member'] = true;
githubService.isTeamMemberMockMap['author1'] = true;
githubService.pullRequestData = pullRequest1;
for (int i = 0; i < 2; i++) {
unawaited(pubsub.publish('auto-submit-queue-sub', pullRequest1));
}
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
cocoonRequest = PullRequestHelper(
prNumber: 0,
lastCommitHash: oid,
);
final Map<int, RepositorySlug> expectedMergeRequestMap = {};
expectedMergeRequestMap[0] = RepositorySlug('flutter', cocoonRepo);
await checkPullRequest.get();
githubService.verifyMergePullRequests(expectedMergeRequestMap);
expect(0, pubsub.messagesQueue.length);
});
test('Closed PRs are not processed', () async {
final PullRequest pullRequest1 = generatePullRequest(
prNumber: 0,
repoName: cocoonRepo,
state: 'close',
);
githubService.pullRequestData = pullRequest1;
when(pullRequests.get(any, any)).thenAnswer(
(_) async => PullRequest(
number: 0,
state: 'close',
),
);
for (int i = 0; i < 2; i++) {
unawaited(pubsub.publish('auto-submit-queue-sub', pullRequest1));
}
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
cocoonRequest = PullRequestHelper(
prNumber: 0,
lastCommitHash: oid,
);
await checkPullRequest.get();
githubGraphQLClient.verifyMutations(
<MutationOptions>[],
);
expect(0, pubsub.messagesQueue.length);
});
test('Merge exception is handled correctly', () async {
final PullRequest pullRequest1 = generatePullRequest(prNumber: 0);
final PullRequest pullRequest2 = generatePullRequest(
prNumber: 1,
repoName: cocoonRepo,
);
githubService.pullRequestData = pullRequest1;
// 'member' is in the review nodes and 'author1' is the pr author.
githubService.isTeamMemberMockMap['member'] = true;
githubService.isTeamMemberMockMap['author1'] = true;
final List<PullRequest> pullRequests = <PullRequest>[pullRequest1, pullRequest2];
for (PullRequest pr in pullRequests) {
unawaited(pubsub.publish(testTopic, pr));
}
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
flutterRequest = PullRequestHelper(
prNumber: 0,
lastCommitHash: oid,
);
cocoonRequest = PullRequestHelper(
prNumber: 1,
lastCommitHash: oid,
);
githubService.useMergeRequestMockList = true;
githubService.pullRequestMergeMockList.add(
PullRequestMerge(
merged: false,
message: 'Unable to merge pull request',
),
);
githubService.pullRequestMergeMockList.add(
PullRequestMerge(
merged: true,
sha: 'sha',
message: 'Pull request merged successfully',
),
);
final Map<int, RepositorySlug> expectedMergeRequestMap = {};
expectedMergeRequestMap[0] = RepositorySlug(
'flutter',
'flutter',
);
expectedMergeRequestMap[1] = RepositorySlug(
'flutter',
cocoonRepo,
);
final List<LogRecord> records = <LogRecord>[];
log.onRecord.listen((LogRecord record) => records.add(record));
// this is the test.
await checkPullRequest.get();
// every failure is now acknowledged from the queue.
expect(pubsub.messagesQueue.length, 0);
final List<LogRecord> errorLogs = records.where((LogRecord record) => record.level == Level.SEVERE).toList();
expect(errorLogs.length, 1);
expect(errorLogs[0].message.contains('Failed to merge'), true);
pubsub.messagesQueue.clear();
});
test('Merges PR with successful status and checks', () async {
final PullRequest pullRequest1 = generatePullRequest(prNumber: 0);
final PullRequest pullRequest2 = generatePullRequest(
prNumber: 1,
repoName: cocoonRepo,
);
githubService.pullRequestData = pullRequest1;
// 'octocat' is the pr author from generatePullRequest calls.
// 'member' is in the review nodes and 'author1' is the pr author.
githubService.isTeamMemberMockMap['member'] = true;
githubService.isTeamMemberMockMap['author1'] = true;
final List<PullRequest> pullRequests = <PullRequest>[pullRequest1, pullRequest2];
for (PullRequest pr in pullRequests) {
unawaited(pubsub.publish(testTopic, pr));
}
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
flutterRequest = PullRequestHelper(
prNumber: 0,
lastCommitHash: oid,
);
cocoonRequest = PullRequestHelper(
prNumber: 1,
lastCommitHash: oid,
);
await checkPullRequest.get();
expectedOptions.add(flutterOption);
expectedOptions.add(cocoonOption);
verifyQueries(expectedOptions);
githubService.useMergeRequestMockList = true;
githubService.pullRequestMergeMockList.add(
PullRequestMerge(
merged: true,
sha: 'sha1',
message: 'Pull request merged successfully',
),
);
githubService.pullRequestMergeMockList.add(
PullRequestMerge(
merged: true,
sha: 'sha2',
message: 'Pull request merged successfully',
),
);
final Map<int, RepositorySlug> expectedMergeRequestMap = {};
expectedMergeRequestMap[0] = RepositorySlug('flutter', 'flutter');
expectedMergeRequestMap[1] = RepositorySlug('flutter', cocoonRepo);
githubService.verifyMergePullRequests(expectedMergeRequestMap);
assert(pubsub.messagesQueue.isEmpty);
});
test('Merges unapproved PR from autoroller', () async {
final PullRequest pullRequest = generatePullRequest(
prNumber: 0,
author: rollorAuthor,
);
githubService.pullRequestData = pullRequest;
unawaited(pubsub.publish(testTopic, pullRequest));
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
approverProvider: (Config config) => MockApproverService(),
);
flutterRequest = PullRequestHelper(
prNumber: 0,
author: 'dependabot',
reviews: const <PullRequestReviewHelper>[],
lastCommitHash: oid,
);
await checkPullRequest.get();
expectedOptions.add(flutterOption);
verifyQueries(expectedOptions);
final Map<int, RepositorySlug> expectedMergeRequestMap = {};
expectedMergeRequestMap[0] = RepositorySlug(
'flutter',
'flutter',
);
githubService.mergeRequestMock = PullRequestMerge(
merged: true,
sha: 'sha1',
message: 'Pull request merged successfully',
);
githubService.verifyMergePullRequests(expectedMergeRequestMap);
assert(pubsub.messagesQueue.isEmpty);
});
test('Merges PR with failed tree status if override tree status label is provided', () async {
final PullRequest pullRequest = generatePullRequest(
prNumber: 0,
labelName: labelName,
);
// 'member' is in the review nodes and 'author1' is the pr author.
githubService.isTeamMemberMockMap['member'] = true;
githubService.isTeamMemberMockMap['author1'] = true;
githubService.pullRequestData = pullRequest;
unawaited(
pubsub.publish(
testTopic,
pullRequest,
),
);
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
flutterRequest = PullRequestHelper(
prNumber: 0,
lastCommitHash: oid,
lastCommitStatuses: const <StatusHelper>[
StatusHelper.flutterBuildFailure,
],
);
await checkPullRequest.get();
expectedOptions.add(flutterOption);
verifyQueries(expectedOptions);
final Map<int, RepositorySlug> expectedMergeRequestMap = {};
expectedMergeRequestMap[0] = RepositorySlug(
'flutter',
'flutter',
);
githubService.mergeRequestMock = PullRequestMerge(
merged: true,
sha: 'sha1',
message: 'Pull request merged successfully',
);
githubService.verifyMergePullRequests(expectedMergeRequestMap);
assert(pubsub.messagesQueue.isEmpty);
});
test('Merges a clean revert PR with in progress tests', () async {
final PullRequest pullRequest = generatePullRequest(prNumber: 0);
githubService.pullRequestData = pullRequest;
// 'member' is in the review nodes and 'author1' is the pr author.
githubService.isTeamMemberMockMap['member'] = true;
githubService.isTeamMemberMockMap['author1'] = true;
unawaited(pubsub.publish(testTopic, pullRequest));
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
flutterRequest = PullRequestHelper(
prNumber: 0,
lastCommitHash: oid,
lastCommitStatuses: const <StatusHelper>[
StatusHelper.flutterBuildSuccess,
],
lastCommitMessage: 'Revert "This is a test PR" This reverts commit abc.',
);
await checkPullRequest.get();
expectedOptions.add(flutterOption);
verifyQueries(expectedOptions);
final Map<int, RepositorySlug> expectedMergeRequestMap = {};
expectedMergeRequestMap[0] = RepositorySlug(
'flutter',
'flutter',
);
githubService.mergeRequestMock = PullRequestMerge(
merged: true,
sha: 'sha1',
message: 'Pull request merged successfully',
);
githubService.verifyMergePullRequests(expectedMergeRequestMap);
assert(pubsub.messagesQueue.isEmpty);
});
test('Merges PR with successful checks on repo without tree status', () async {
final PullRequest pullRequest = generatePullRequest(
prNumber: 1,
repoName: cocoonRepo,
);
githubService.pullRequestData = pullRequest;
// 'member' is in the review nodes and 'author1' is the pr author.
githubService.isTeamMemberMockMap['member'] = true;
githubService.isTeamMemberMockMap['author1'] = true;
unawaited(pubsub.publish(testTopic, pullRequest));
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
cocoonRequest = PullRequestHelper(
lastCommitHash: oid,
lastCommitStatuses: const <StatusHelper>[],
);
await checkPullRequest.get();
expectedOptions.add(cocoonOption);
verifyQueries(expectedOptions);
final Map<int, RepositorySlug> expectedMergeRequestMap = {};
expectedMergeRequestMap[1] = RepositorySlug(
'flutter',
cocoonRepo,
);
githubService.mergeRequestMock = PullRequestMerge(
merged: true,
sha: 'sha1',
message: 'Pull request merged successfully',
);
githubService.verifyMergePullRequests(expectedMergeRequestMap);
assert(pubsub.messagesQueue.isEmpty);
});
test('Merges PR with neutral status checkrun', () async {
final PullRequest pullRequest1 = generatePullRequest(prNumber: 0);
final PullRequest pullRequest2 = generatePullRequest(
prNumber: 1,
repoName: cocoonRepo,
);
githubService.pullRequestData = pullRequest1;
// 'member' is in the review nodes and 'author1' is the pr author.
githubService.isTeamMemberMockMap['member'] = true;
githubService.isTeamMemberMockMap['author1'] = true;
final List<PullRequest> pullRequests = <PullRequest>[pullRequest1, pullRequest2];
for (PullRequest pr in pullRequests) {
unawaited(pubsub.publish(testTopic, pr));
}
githubService.checkRunsData = neutralCheckRunsMock;
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
flutterRequest = PullRequestHelper(
prNumber: 0,
lastCommitHash: oid,
);
cocoonRequest = PullRequestHelper(
prNumber: 1,
lastCommitHash: oid,
);
await checkPullRequest.get();
expectedOptions.add(flutterOption);
expectedOptions.add(cocoonOption);
verifyQueries(expectedOptions);
assert(pubsub.messagesQueue.isEmpty);
});
test('Removes the label for the PR with failed tests', () async {
final PullRequest pullRequest1 = generatePullRequest(prNumber: 0);
final PullRequest pullRequest2 = generatePullRequest(
prNumber: 1,
repoName: cocoonRepo,
);
githubService.pullRequestData = pullRequest1;
// 'member' is in the review nodes and 'author1' is the pr author.
githubService.isTeamMemberMockMap['member'] = true;
githubService.isTeamMemberMockMap['author1'] = true;
final List<PullRequest> pullRequests = <PullRequest>[pullRequest1, pullRequest2];
for (PullRequest pr in pullRequests) {
unawaited(pubsub.publish(testTopic, pr));
}
githubService.checkRunsData = failedCheckRunsMock;
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
flutterRequest = PullRequestHelper(
prNumber: 0,
lastCommitHash: oid,
);
cocoonRequest = PullRequestHelper(
prNumber: 1,
lastCommitHash: oid,
);
await checkPullRequest.get();
expectedOptions.add(flutterOption);
expectedOptions.add(cocoonOption);
verifyQueries(expectedOptions);
assert(pubsub.messagesQueue.isEmpty);
});
test('Removes the label for the PR with failed status', () async {
final PullRequest pullRequest = generatePullRequest(prNumber: 0);
githubService.pullRequestData = pullRequest;
// 'member' is in the review nodes and 'author1' is the pr author.
githubService.isTeamMemberMockMap['member'] = true;
githubService.isTeamMemberMockMap['author1'] = true;
unawaited(pubsub.publish(testTopic, pullRequest));
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
flutterRequest = PullRequestHelper(
lastCommitHash: oid,
lastCommitStatuses: const <StatusHelper>[
StatusHelper.flutterBuildSuccess,
StatusHelper.otherStatusFailure,
],
);
await checkPullRequest.get();
expectedOptions.add(flutterOption);
verifyQueries(expectedOptions);
assert(pubsub.messagesQueue.isEmpty);
});
test('Removes the label if non member does not have at least 2 member reviews', () async {
final PullRequest pullRequest = generatePullRequest(
prNumber: 0,
);
githubService.pullRequestData = pullRequest;
// 'octocat' is the pr author from generatePullRequest calls.
githubService.isTeamMemberMockMap['octocat'] = false;
unawaited(pubsub.publish(testTopic, pullRequest));
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
flutterRequest = PullRequestHelper(
authorAssociation: '',
lastCommitHash: oid,
lastCommitStatuses: const <StatusHelper>[
StatusHelper.flutterBuildSuccess,
],
);
await checkPullRequest.get();
expectedOptions.add(flutterOption);
verifyQueries(expectedOptions);
assert(pubsub.messagesQueue.isEmpty);
});
test('Removes the label for the PR with null checks and statuses', () async {
final PullRequest pullRequest = generatePullRequest(prNumber: 0);
githubService.pullRequestData = pullRequest;
// 'octocat' is the pr author from generatePullRequest calls.
githubService.isTeamMemberMockMap['octocat'] = true;
unawaited(pubsub.publish(testTopic, pullRequest));
githubService.checkRunsData = emptyCheckRunsMock;
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
flutterRequest = PullRequestHelper(
lastCommitHash: oid,
lastCommitStatuses: const <StatusHelper>[],
);
await checkPullRequest.get();
expectedOptions.add(flutterOption);
verifyQueries(expectedOptions);
assert(pubsub.messagesQueue.isEmpty);
});
test('Does not merge PR with in progress checks', () async {
final PullRequest pullRequest1 = generatePullRequest(prNumber: 0);
final PullRequest pullRequest2 = generatePullRequest(
prNumber: 1,
repoName: cocoonRepo,
);
githubService.pullRequestData = pullRequest1;
// 'member' is in the review nodes and 'author1' is the pr author.
githubService.isTeamMemberMockMap['member'] = true;
githubService.isTeamMemberMockMap['author1'] = true;
final List<PullRequest> pullRequests = <PullRequest>[pullRequest1, pullRequest2];
for (PullRequest pr in pullRequests) {
unawaited(pubsub.publish(testTopic, pr));
}
githubService.checkRunsData = inProgressCheckRunsMock;
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
flutterRequest = PullRequestHelper(prNumber: 0);
cocoonRequest = PullRequestHelper(prNumber: 1);
await checkPullRequest.get();
expectedOptions.add(flutterOption);
expectedOptions.add(cocoonOption);
verifyQueries(expectedOptions);
expect(pubsub.messagesQueue.length, 2);
pubsub.messagesQueue.clear();
});
test('Does not merge PR if no autosubmit label any more', () async {
final PullRequest pullRequest1 = generatePullRequest(
prNumber: 0,
autosubmitLabel: noAutosubmitLabel,
);
final PullRequest pullRequest2 = generatePullRequest(
prNumber: 1,
autosubmitLabel: noAutosubmitLabel,
repoName: cocoonRepo,
);
githubService.pullRequestData = pullRequest1;
final List<PullRequest> pullRequests = <PullRequest>[pullRequest1, pullRequest2];
for (PullRequest pr in pullRequests) {
unawaited(pubsub.publish(testTopic, pr));
}
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
flutterRequest = PullRequestHelper(prNumber: 0);
cocoonRequest = PullRequestHelper(prNumber: 1);
await checkPullRequest.get();
assert(pubsub.messagesQueue.isEmpty);
});
test('Self review is disallowed', () async {
final PullRequest pullRequest = generatePullRequest(
prNumber: 0,
author: 'some_rando',
);
githubService.pullRequestData = pullRequest;
// 'octocat' is the pr author from generatePullRequest calls.
githubService.isTeamMemberMockMap['some_rando'] = true;
unawaited(pubsub.publish(testTopic, pullRequest));
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
flutterRequest = PullRequestHelper(
author: 'some_rando',
lastCommitHash: oid,
authorAssociation: 'MEMBER',
reviews: <PullRequestReviewHelper>[
const PullRequestReviewHelper(
authorName: 'some_rando',
state: ReviewState.APPROVED,
memberType: MemberType.MEMBER,
),
],
lastCommitStatuses: const <StatusHelper>[
StatusHelper.flutterBuildSuccess,
],
);
await checkPullRequest.get();
expectedOptions.add(flutterOption);
verifyQueries(expectedOptions);
// Re-add to queue to poll for reviews
assert(pubsub.messagesQueue.isNotEmpty);
});
test('All messages are pulled', () async {
for (int i = 0; i < 3; i++) {
final PullRequest pullRequest = generatePullRequest(
prNumber: i,
repoName: cocoonRepo,
);
unawaited(
pubsub.publish(
'auto-submit-queue-sub',
pullRequest,
),
);
}
checkPullRequest = CheckPullRequest(
config: config,
pubsub: pubsub,
cronAuthProvider: auth,
);
cocoonRequest = PullRequestHelper(
prNumber: 0,
lastCommitHash: oid,
);
final List<pub.ReceivedMessage> messages = await checkPullRequest.pullMessages(testSubscription, 5, 5);
expect(messages.length, 3);
});
});
}
QueryResult createQueryResult(PullRequestHelper pullRequest) {
return createFakeQueryResult(
data: <String, dynamic>{
'repository': <String, dynamic>{
'pullRequest': pullRequest.toEntry().cast<String, dynamic>(),
},
},
);
}
Map<String, dynamic> getMergePullRequestVariables(
String id,
String number,
) {
return <String, dynamic>{
'id': id,
'oid': oid,
'title': '$title (#$number)',
};
}