| // Copyright 2020 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. |
| |
| import 'dart:convert'; |
| import 'dart:io'; |
| |
| import 'package:cocoon_service/src/model/appengine/branch.dart'; |
| import 'package:cocoon_service/src/request_handlers/update_branches.dart'; |
| import 'package:cocoon_service/src/request_handling/body.dart'; |
| import 'package:cocoon_service/src/service/datastore.dart'; |
| import 'package:gcloud/db.dart'; |
| import 'package:github/github.dart' show GitCommit, GitCommitUser, RepositoryCommit; |
| import 'package:mockito/mockito.dart'; |
| import 'package:test/test.dart'; |
| |
| import '../src/datastore/fake_config.dart'; |
| import '../src/datastore/fake_datastore.dart'; |
| import '../src/request_handling/fake_authentication.dart'; |
| import '../src/request_handling/fake_http.dart'; |
| import '../src/request_handling/request_handler_tester.dart'; |
| import '../src/utilities/mocks.dart'; |
| |
| void main() { |
| group('update branches', () { |
| late FakeConfig config; |
| late RequestHandlerTester tester; |
| late UpdateBranches handler; |
| late FakeHttpRequest request; |
| late FakeDatastoreDB db; |
| FakeClientContext clientContext; |
| FakeKeyHelper keyHelper; |
| late MockRepositoriesService mockRepositoriesService; |
| final MockProcessManager processManager = MockProcessManager(); |
| |
| String stdoutResult = '72fe8a9ec3af4d76097f09a9c01bf31c62a942aa refs/heads/main'; |
| const String testBranchSha = '72fe8a9ec3af4d76097f09a9c01bf31c62a942aa'; |
| |
| Future<T?> decodeHandlerBody<T>() async { |
| final Body body = await tester.get(handler); |
| return await utf8.decoder.bind(body.serialize() as Stream<List<int>>).transform(json.decoder).single as T?; |
| } |
| |
| setUp(() { |
| db = FakeDatastoreDB(); |
| clientContext = FakeClientContext(); |
| request = FakeHttpRequest(); |
| keyHelper = FakeKeyHelper(applicationContext: clientContext.applicationContext); |
| tester = RequestHandlerTester(request: request); |
| |
| final MockGitHub mockGitHubClient = MockGitHub(); |
| mockRepositoriesService = MockRepositoriesService(); |
| when(mockGitHubClient.repositories).thenReturn(mockRepositoriesService); |
| when(processManager.runSync(any)).thenAnswer((Invocation invocation) => ProcessResult(1, 0, stdoutResult, '')); |
| |
| config = FakeConfig(dbValue: db, keyHelperValue: keyHelper, githubClient: mockGitHubClient); |
| handler = UpdateBranches( |
| config: config, |
| datastoreProvider: (DatastoreDB db) => DatastoreService(config.db, 5), |
| processManager: processManager, |
| ); |
| |
| const String id = 'flutter/flutter/main'; |
| int lastActivity = DateTime.tryParse("2019-05-15T15:20:56Z")!.millisecondsSinceEpoch; |
| final Key<String> branchKey = db.emptyKey.append<String>(Branch, id: id); |
| final Branch currentBranch = Branch( |
| key: branchKey, |
| lastActivity: lastActivity, |
| ); |
| db.values[currentBranch.key] = currentBranch; |
| }); |
| |
| test('should not retrieve branches older than 2 months', () async { |
| expect(db.values.values.whereType<Branch>().length, 1); |
| when(mockRepositoriesService.getCommit(any, any)).thenAnswer((Invocation invocation) { |
| return Future<RepositoryCommit>.value(RepositoryCommit( |
| sha: testBranchSha, |
| commit: GitCommit( |
| committer: GitCommitUser( |
| 'dash', |
| 'dash@google.com', |
| DateTime.now().subtract(const Duration(days: 90)), |
| )))); |
| }); |
| |
| final List<dynamic> result = (await decodeHandlerBody())!; |
| expect(result, isEmpty); |
| }); |
| |
| test('should retrieve branches with commit acitivities in the past week', () async { |
| expect(db.values.values.whereType<Branch>().length, 1); |
| |
| // a recent commit is added for each of the 6 repos |
| when(mockRepositoriesService.getCommit(any, any)).thenAnswer((Invocation invocation) { |
| return Future<RepositoryCommit>.value(RepositoryCommit( |
| sha: testBranchSha, |
| commit: GitCommit( |
| committer: GitCommitUser( |
| 'dash', |
| 'dash@google.com', |
| DateTime.now(), |
| )))); |
| }); |
| |
| final List<dynamic> result = (await decodeHandlerBody())!; |
| List<String> repos = []; |
| for (dynamic k in result) { |
| repos.add('${k['branch']['repository']}/${k['branch']['branch']}'); |
| } |
| expect(repos, contains('flutter/flutter/main')); //flutter/flutter/main is updated |
| expect(result.length, 1); |
| expect(db.values.values.whereType<Branch>().length, 1); |
| }); |
| |
| test('should not retrieve branch if updated commit acitivities happened long ago', () async { |
| expect(db.values.values.whereType<Branch>().length, 1); |
| |
| when(mockRepositoriesService.getCommit(any, any)).thenAnswer((Invocation invocation) { |
| return Future<RepositoryCommit>.value(RepositoryCommit( |
| sha: testBranchSha, |
| commit: GitCommit( |
| committer: GitCommitUser( |
| 'dash', |
| 'dash@google.com', |
| DateTime.tryParse('2020-05-15T15:20:56Z'), |
| )))); |
| }); |
| |
| final List<dynamic> result = (await decodeHandlerBody())!; |
| expect(result, isEmpty); |
| }); |
| |
| test('should throw exception when git ls-remote fails', () async { |
| expect(db.values.values.whereType<Branch>().length, 1); |
| when(processManager.runSync(any)).thenAnswer((Invocation invocation) => ProcessResult(1, -1, stdoutResult, '')); |
| |
| when(mockRepositoriesService.getCommit(any, any)).thenAnswer((Invocation invocation) { |
| return Future<RepositoryCommit>.value(RepositoryCommit( |
| sha: testBranchSha, |
| commit: GitCommit( |
| committer: GitCommitUser( |
| 'dash', |
| 'dash@google.com', |
| DateTime.tryParse('2020-05-15T15:20:56Z'), |
| )))); |
| }); |
| |
| expect(() => decodeHandlerBody<List<dynamic>>(), throwsA(const TypeMatcher<FormatException>())); |
| }); |
| }); |
| } |