<commit_before>// Copyright 2017 The Chromium 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:http/http.dart';
import 'package:mockito/mockito.dart';
import 'package:quiver/time.dart';
import 'package:sentry/sentry.dart';
import 'package:test/test.dart';

const String _testDsn = 'https://public:secret@sentry.example.com/1';

void main() {
  group('$SentryClient', () {
    test('can parse DSN', () async {
      final SentryClient client = new SentryClient(dsn: _testDsn);
      expect(client.dsnUri, Uri.parse(_testDsn));
      expect(client.postUri, 'https://sentry.example.com/api/1/store/');
      expect(client.publicKey, 'public');
      expect(client.secretKey, 'secret');
      expect(client.projectId, '1');
      await client.close();
    });

    testCaptureException(bool compressPayload) async {
      final MockClient httpMock = new MockClient();
      final Clock fakeClock = new Clock.fixed(new DateTime(2017, 1, 2));

      String postUri;
      Map<String, String> headers;
      List<int> body;
      when(httpMock.post(any, headers: any, body: any))
          .thenAnswer((Invocation invocation) {
        postUri = invocation.positionalArguments.single;
        headers = invocation.namedArguments[#headers];
        body = invocation.namedArguments[#body];
        return new Response('{"id": "test-event-id"}', 200);
      });

      final SentryClient client = new SentryClient(
        dsn: _testDsn,
        httpClient: httpMock,
        clock: fakeClock,
        uuidGenerator: () => 'X' * 32,
        compressPayload: compressPayload,
      );

      try {
        throw new ArgumentError('Test error');
      } catch (error, stackTrace) {
        await client.captureException(exception: error, stackTrace: stackTrace);
      }

      expect(postUri, client.postUri);

      Map<String, String> expectedHeaders = <String, String>{
        'User-Agent': '$sdkName/$sdkVersion',
        'Content-Type': 'application/json',
        'X-Sentry-Auth': 'Sentry sentry_version=6, '
            'sentry_client=${SentryClient.sentryClient}, '
            'sentry_timestamp=${fakeClock.now().millisecondsSinceEpoch}, '
            'sentry_key=public, '
            'sentry_secret=secret',
      };

      if (compressPayload) expectedHeaders['Content-Encoding'] = 'gzip';

      expect(headers, expectedHeaders);

      String json;
      if (compressPayload) {
        json = UTF8.decode(GZIP.decode(body));
      } else {
        json = UTF8.decode(body);
      }
      expect(JSON.decode(json), {
        'project': '1',
        'event_id': 'X' * 32,
        'timestamp': '2017-01-02T00:00:00.000',
        'platform': 'dart',
        'exception': [
          {'type': 'ArgumentError', 'value': 'Invalid argument(s): Test error'}
        ],
        'sdk': {'version': '0.0.1', 'name': 'dart'},
        'logger': SentryClient.defaultLoggerName,
      });

      await client.close();
    }

    test('sends an exception report (compressed)', () async {
      await testCaptureException(true);
    });

    test('sends an exception report (uncompressed)', () async {
      await testCaptureException(false);
    });
  });

  group('$Event', () {
    test('serializes to JSON', () {
      final DateTime now = new DateTime(2017);
      expect(
        new Event(
          projectId: '123',
          eventId: 'X' * 32,
          timestamp: now,
          loggerName: 'test-logger',
          message: 'test-message',
          exception: new StateError('test-error'),
          level: SeverityLevel.debug,
          culprit: '<NAME>',
          serverName: 'test.server.com',
          release: '1.2.3',
          tags: <String, String>{
            'a': 'b',
            'c': 'd',
          },
          environment: 'staging',
          extra: <String, dynamic>{
            'e': 'f',
            'g': 2,
          },
          fingerprint: <String>[Event.defaultFingerprint, 'foo'],
        ).toJson(),
        <String, dynamic>{
          'project': '123',
          'event_id': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
          'timestamp': '2017-01-01T00:00:00.000',
          'platform': 'dart',
          'sdk': {'version': '0.0.1', 'name': 'dart'},
          'logger': 'test-logger',
          'message': 'test-message',
          'exception': [
            {'type': 'StateError', 'value': 'Bad state: test-error'}
          ],
          'level': 'debug',
          'culprit': '<NAME>',<commit_msg>unhardcode version number in test<commit_after>// Copyright 2017 The Chromium 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:http/http.dart';
import 'package:mockito/mockito.dart';
import 'package:quiver/time.dart';
import 'package:sentry/sentry.dart';
import 'package:test/test.dart';

const String _testDsn = 'https://public:secret@sentry.example.com/1';

void main() {
  group('$SentryClient', () {
    test('can parse DSN', () async {
      final SentryClient client = new SentryClient(dsn: _testDsn);
      expect(client.dsnUri, Uri.parse(_testDsn));
      expect(client.postUri, 'https://sentry.example.com/api/1/store/');
      expect(client.publicKey, 'public');
      expect(client.secretKey, 'secret');
      expect(client.projectId, '1');
      await client.close();
    });

    testCaptureException(bool compressPayload) async {
      final MockClient httpMock = new MockClient();
      final Clock fakeClock = new Clock.fixed(new DateTime(2017, 1, 2));

      String postUri;
      Map<String, String> headers;
      List<int> body;
      when(httpMock.post(any, headers: any, body: any))
          .thenAnswer((Invocation invocation) {
        postUri = invocation.positionalArguments.single;
        headers = invocation.namedArguments[#headers];
        body = invocation.namedArguments[#body];
        return new Response('{"id": "test-event-id"}', 200);
      });

      final SentryClient client = new SentryClient(
        dsn: _testDsn,
        httpClient: httpMock,
        clock: fakeClock,
        uuidGenerator: () => 'X' * 32,
        compressPayload: compressPayload,
      );

      try {
        throw new ArgumentError('Test error');
      } catch (error, stackTrace) {
        await client.captureException(exception: error, stackTrace: stackTrace);
      }

      expect(postUri, client.postUri);

      Map<String, String> expectedHeaders = <String, String>{
        'User-Agent': '$sdkName/$sdkVersion',
        'Content-Type': 'application/json',
        'X-Sentry-Auth': 'Sentry sentry_version=6, '
            'sentry_client=${SentryClient.sentryClient}, '
            'sentry_timestamp=${fakeClock.now().millisecondsSinceEpoch}, '
            'sentry_key=public, '
            'sentry_secret=secret',
      };

      if (compressPayload) expectedHeaders['Content-Encoding'] = 'gzip';

      expect(headers, expectedHeaders);

      String json;
      if (compressPayload) {
        json = UTF8.decode(GZIP.decode(body));
      } else {
        json = UTF8.decode(body);
      }
      expect(JSON.decode(json), {
        'project': '1',
        'event_id': 'X' * 32,
        'timestamp': '2017-01-02T00:00:00.000',
        'platform': 'dart',
        'exception': [
          {'type': 'ArgumentError', 'value': 'Invalid argument(s): Test error'}
        ],
        'sdk': {'version': sdkVersion, 'name': 'dart'},
        'logger': SentryClient.defaultLoggerName,
      });

      await client.close();
    }

    test('sends an exception report (compressed)', () async {
      await testCaptureException(true);
    });

    test('sends an exception report (uncompressed)', () async {
      await testCaptureException(false);
    });
  });

  group('$Event', () {
    test('serializes to JSON', () {
      final DateTime now = new DateTime(2017);
      expect(
        new Event(
          projectId: '123',
          eventId: 'X' * 32,
          timestamp: now,
          loggerName: 'test-logger',
          message: 'test-message',
          exception: new StateError('test-error'),
          level: SeverityLevel.debug,
          culprit: '<NAME>',
          serverName: 'test.server.com',
          release: '1.2.3',
          tags: <String, String>{
            'a': 'b',
            'c': 'd',
          },
          environment: 'staging',
          extra: <String, dynamic>{
            'e': 'f',
            'g': 2,
          },
          fingerprint: <String>[Event.defaultFingerprint, 'foo'],
        ).toJson(),
        <String, dynamic>{
          'project': '123',
          'event_id': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
          'timestamp': '2017-01-01T00:00:00.000',
          'platform': 'dart',
          'sdk': {'version': sdkVersion, 'name': 'dart'},
          'logger': 'test-logger',
          'message': 'test-message',
          'exception': [
            {'type': 'StateError', 'value': 'Bad state: test-error'}
          ],
          'level': 'debug',
          'culprit': '<NAME>',
{'fraction_non_alphanumeric': 0.15255347010039283, 'fraction_numerical': 0.01680488869489306, 'mean_word_length': 2.4287317620650954, 'pattern_counts': {'":': 2, '<': 23, '<?xml version=': 0, '>': 25, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4634403', 'n_tokens_mistral': 2833, 'n_tokens_neox': 2700, 'n_words': 605}