blob: dceeaa8b0fe680520dad1750f8e0a63f9e1beb9c [file] [log] [blame]
// Copyright 2019 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:typed_data';
import 'package:cocoon_service/cocoon_service.dart';
import 'package:cocoon_service/protos.dart';
import 'package:cocoon_service/src/request_handling/exceptions.dart';
import 'package:crypto/crypto.dart';
import 'package:test/test.dart';
import '../src/datastore/fake_config.dart';
import '../src/request_handling/fake_http.dart';
import '../src/request_handling/fake_pubsub.dart';
import '../src/request_handling/request_handler_tester.dart';
void main() {
late GithubWebhook webhook;
late FakeConfig config;
late FakeHttpRequest request;
late FakePubSub pubsub;
late RequestHandlerTester tester;
const String keyString = 'not_a_real_key';
String getHmac(Uint8List list, Uint8List key) {
final Hmac hmac = Hmac(sha1, key);
return hmac.convert(list).toString();
}
setUp(() {
request = FakeHttpRequest();
tester = RequestHandlerTester(request: request);
config = FakeConfig(
webhookKeyValue: keyString,
);
pubsub = FakePubSub();
webhook = GithubWebhook(
config: config,
pubsub: pubsub,
secret: config.webhookKey,
topic: 'github-webhooks',
);
});
test('Rejects non-POST methods with methodNotAllowed', () async {
expect(tester.get(webhook), throwsA(isA<MethodNotAllowed>()));
expect(pubsub.messages, isEmpty);
});
test('Rejects missing headers', () async {
expect(tester.post(webhook), throwsA(isA<BadRequestException>()));
expect(pubsub.messages, isEmpty);
});
test('Rejects invalid hmac', () async {
request.headers.set('X-GitHub-Event', 'pull_request');
request.headers.set('X-Hub-Signature', 'bar');
request.body = 'Hello, World!';
expect(tester.post(webhook), throwsA(isA<Forbidden>()));
expect(pubsub.messages, isEmpty);
});
test('Publishes message', () async {
request.headers.set('X-GitHub-Event', 'pull_request');
request.body = '{}';
final Uint8List body = utf8.encode(request.body!);
final Uint8List key = utf8.encode(keyString);
final String hmac = getHmac(body, key);
request.headers.set('X-Hub-Signature', 'sha1=$hmac');
await tester.post(webhook);
expect(pubsub.messages, hasLength(1));
final Map<String, dynamic> messageJson = pubsub.messages.single;
final GithubWebhookMessage message = GithubWebhookMessage.fromJson(jsonEncode(messageJson));
expect(message.event, 'pull_request');
expect(message.payload, '{}');
});
}