/*
 * Copyright (c) 2017, 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.
 */
/**
 * @assertionString userAgent
 *  read / write
 * Set and get the default value of the User-Agent header for all requests
 * generated by this HttpClient. The default value is Dart/<version> (dart:io).
 *
 * If the userAgent is set to null, no default User-Agent header will be added
 * to each request.
 * @description Checks that setting this value changes User-Agent header
 * @author sgrekhov@unipro.ru
 */
import "dart:io";
import "dart:convert";
import "../../../Utils/expect.dart";

var localhost = InternetAddress.loopbackIPv4.address;

test() async {
  String helloWorld = 'Hello, test world!';
  HttpServer server = await HttpServer.bind(localhost, 0);
  asyncStart();
  server.listen((HttpRequest request) {
    Expect.listEquals(
        ["test/1.0"], request.headers[HttpHeaders.userAgentHeader]);
    request.response.write(helloWorld);
    request.response.close();
    server.close();
    asyncEnd();
  });

  HttpClient client = new HttpClient();
  client.userAgent = "test/1.0";

  asyncStart();
  client
      .getUrl(Uri.parse("http://$localhost:${server.port}"))
      .then((HttpClientRequest request) {
    return request.close();
  }).then((HttpClientResponse response) {
    Expect.equals(HttpStatus.ok, response.statusCode);
    response.cast<List<int>>().transform(utf8.decoder).listen((content) {
      Expect.equals(helloWorld, content);
      asyncEnd();
    });
  });
  asyncEnd();
}

main() {
  asyncStart();
  test();
}
