// Copyright (c) 2012, 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.

library XHRTest;

import 'dart:async';
import 'dart:convert';
import 'dart:html';
import 'dart:typed_data';

import 'package:async_helper/async_minitest.dart';
import 'package:async_helper/async_helper.dart';

// Cache blocker is a workaround for:
// https://code.google.com/p/dart/issues/detail?id=11834
var cacheBlocker = new DateTime.now().millisecondsSinceEpoch;
var url = '/root_dart/tests/lib/html/xhr_cross_origin_data.txt?'
    'cacheBlock=$cacheBlocker';

void validate200Response(xhr) {
  expect(xhr.status, 200);
  var data = json.decode(xhr.responseText);
  expect(data.containsKey('feed'), isTrue);
  expect(data['feed'].containsKey('entry'), isTrue);
  expect(data, isMap);
}

void validate404(xhr) {
  expect(xhr.status, 404);
  // We cannot say much about xhr.responseText, most HTTP servers will
  // include an HTML page explaining the error to a human.
  String responseText = xhr.responseText;
  expect(responseText, isNotNull);
}

Future testXhrNoFile() async {
  HttpRequest xhr = new HttpRequest();
  xhr.open("GET", "NonExistingFile", async: true);
  var completer = new Completer<void>();
  xhr.onReadyStateChange.listen((event) {
    if (!completer.isCompleted && xhr.readyState == HttpRequest.DONE) {
      completer.complete();
      validate404(xhr);
    }
  });
  xhr.send();
  await completer;
}

Future testXhrFile() async {
  var loadEndCalled = false;

  var xhr = new HttpRequest();
  xhr.open('GET', url, async: true);
  var completer = new Completer<void>();
  xhr.onReadyStateChange.listen((e) {
    if (!completer.isCompleted && xhr.readyState == HttpRequest.DONE) {
      completer.complete();
      validate200Response(xhr);

      Timer.run(expectAsync(() {
        expect(loadEndCalled, HttpRequest.supportsLoadEndEvent);
      }));
    }
  });

  xhr.onLoadEnd.listen((ProgressEvent e) {
    loadEndCalled = true;
  });
  xhr.send();
  await completer;
}

Future testRequestNoFile() async {
  try {
    await HttpRequest.request('NonExistingFile');
    fail('Request should not have succeeded.');
  } on ProgressEvent catch (error) {
    HttpRequest xhr = error.target as HttpRequest;
    expect(xhr.readyState, HttpRequest.DONE);
    validate404(xhr);
  }
}

Future testRequestFile() async {
  var xhr = await HttpRequest.request(url);
  expect(xhr.readyState, HttpRequest.DONE);
  validate200Response(xhr);
}

Future testRequestOnProgress() async {
  var progressCalled = false;
  var xhr = await HttpRequest.request(url, onProgress: (_) {
    progressCalled = true;
  });
  expect(xhr.readyState, HttpRequest.DONE);
  expect(progressCalled, HttpRequest.supportsProgressEvent);
  validate200Response(xhr);
}

Future testRequestWithCredentialsNoFile() async {
  try {
    await HttpRequest.request('NonExistingFile', withCredentials: true);
    fail('Request should not have succeeded.');
  } on ProgressEvent catch (error) {
    HttpRequest xhr = error.target as HttpRequest;
    expect(xhr.readyState, HttpRequest.DONE);
    validate404(xhr);
  }
}

Future testRequestWithCredentialsFile() async {
  try {
    HttpRequest xhr = await HttpRequest.request(url, withCredentials: true);
    expect(xhr.readyState, HttpRequest.DONE);
    validate200Response(xhr);
  } catch (_) {
    fail('Request should succeed.');
  }
}

Future testGetStringFile() => HttpRequest.getString(url);

Future testGetStringNoFile() async {
  try {
    await HttpRequest.getString('NonExistingFile');
    fail('Succeeded for non-existing file.');
  } on ProgressEvent catch (error) {
    HttpRequest xhr = error.target as HttpRequest;
    expect(xhr.readyState, HttpRequest.DONE);
    validate404(xhr);
  }
}

Future testRequestResponseTypeArrayBuffer() async {
  if (Platform.supportsTypedData) {
    var xhr = await HttpRequest.request(url,
        responseType: 'arraybuffer',
        requestHeaders: {'Content-Type': 'text/xml'});
    expect(xhr.status, 200);
    var byteBuffer = xhr.response;
    expect(byteBuffer, isInstanceOf<ByteBuffer>());
    expect(byteBuffer, isNotNull);
  }
}

Future testOverrideMimeType() async {
  bool gotError = false;
  try {
    await HttpRequest.request(url, mimeType: 'application/binary');
  } catch (_) {
    gotError = true;
  }
  expect(gotError, !HttpRequest.supportsOverrideMimeType);
}

Future testXhrUpload() async {
  if (Platform.supportsTypedData) {
    var xhr = new HttpRequest();
    var progressCalled = false;
    xhr.upload.onProgress.listen((e) {
      progressCalled = true;
    });

    xhr.open(
        'POST', '${window.location.protocol}//${window.location.host}/echo');

    // 10MB of payload data w/ a bit of data to make sure it
    // doesn't get compressed to nil.
    var data = new Uint8List(1 * 1024 * 1024);
    for (var i = 0; i < data.length; ++i) {
      data[i] = i & 0xFF;
    }
    xhr.send(new Uint8List.view(data.buffer));

    await xhr.onLoad.first;
    expect(progressCalled, isTrue, reason: 'onProgress should be fired');
  }
}

Future testXhrPostFormData() async {
  var data = {'name': 'John', 'time': '2 pm'};

  var parts = [];
  for (var key in data.keys) {
    parts.add('${Uri.encodeQueryComponent(key)}='
        '${Uri.encodeQueryComponent(data[key]!)}');
  }
  var encodedData = parts.join('&');

  var xhr = await HttpRequest.postFormData(
      '${window.location.protocol}//${window.location.host}/echo', data);
  expect(xhr.responseText, encodedData);
}

Future testRequestResponseTypeBlob() async {
  if (Platform.supportsTypedData) {
    var xhr = await HttpRequest.request(url, responseType: 'blob');
    expect(xhr.status, 200);
    var blob = xhr.response;
    expect(blob is Blob, isTrue);
    expect(blob, isNotNull);
  }
}

Future testResponseTypeJson() async {
  var url = '${window.location.protocol}//${window.location.host}/echo';
  var data = {
    'key': 'value',
    'a': 'b',
    'one': 2,
  };

  var xhr = await HttpRequest.request(url,
      method: 'POST', sendData: json.encode(data), responseType: 'json');
  expect(xhr.status, 200);
  var jsonResponse = xhr.response;
  expect(jsonResponse, data);
}

Future testResponseHeaders() async {
  var xhr = await HttpRequest.request(url);
  var contentTypeHeader = xhr.responseHeaders['content-type'];
  expect(contentTypeHeader, isNotNull);
  // Should be like: 'text/plain; charset=utf-8'
  expect(contentTypeHeader!.contains('text/plain'), isTrue);
  expect(contentTypeHeader.contains('charset=utf-8'), isTrue);
}

main() {
  test('supportsProgressEvent', () {
    expect(HttpRequest.supportsProgressEvent, isTrue);
  });

  test('supportsOnLoadEnd', () {
    expect(HttpRequest.supportsLoadEndEvent, isTrue);
  });

  test('supportsOverrideMimeType', () {
    expect(HttpRequest.supportsOverrideMimeType, isTrue);
  });

  asyncTest(() async {
    await testXhrNoFile();
    await testXhrFile();
    await testRequestNoFile();
    await testRequestFile();
    await testRequestOnProgress();
    await testRequestWithCredentialsNoFile();
    await testRequestWithCredentialsFile();
    await testGetStringFile();
    await testGetStringNoFile();
    await testRequestResponseTypeArrayBuffer();
    await testOverrideMimeType();
    await testXhrUpload();
    await testXhrPostFormData();

    await testRequestResponseTypeBlob();

    await testResponseTypeJson();

    await testResponseHeaders();
  });
}
