
"use strict";

// deps

	const path = require("path");
	const spawn = require("child_process").spawn;
	const http = require("http");
	const fs = require("fs");
	const assert = require("assert");

// consts

	const MAIN_FILE = path.join(__dirname, "..", "lib", "main.js");
	const MAX_TIMEOUT_REQUEST = 3000;

	const PORT = "3000";
	const MAIN_URL = "http://127.0.0.1:" + PORT + "/";
	const API_URL = MAIN_URL + "api/v1/";

// module

describe("server (127.0.0.1 on port " + PORT + ")", () => {

	let child = null;

	after(() => {

		return Promise.resolve().then(() => {

			if (child) {
				child.stdin.pause();
				child.kill();
			}

			return Promise.resolve();

		});

	});

	it("should run the server", () => {

		return new Promise((resolve, reject) => {

			let timeout = null;

			child = spawn(
				"node",
				[ path.join(__dirname, "..", "lib", "main.js"), "--port", PORT ],
				{ cwd: path.join(__dirname, "..") }
			).on("error", (err) => {

				if (timeout) {
					clearTimeout(timeout);
					timeout = null;
				}

				reject(err);

			});

			timeout = setTimeout(resolve, 1000);

		});

	}).timeout(MAX_TIMEOUT_REQUEST);

	it("should get the main page", () => {

		return new Promise((resolve, reject) => {

			http.get(MAIN_URL, (res) => {

				assert.strictEqual(200, res.statusCode, "The statusCode is not 200");
				assert.strictEqual("OK", res.statusMessage, "The statusMessage is not valid");
				assert.strictEqual("object", typeof res.headers, "The headers are not an object");
				assert.strictEqual("text/html; charset=utf-8", res.headers["content-type"].toLowerCase(), "The content-type header are not html/utf8");

				res.setEncoding("utf8");

				let rawData = "";
				res.on("data", (chunk) => { rawData += chunk; });
				res.on("end", () => {

					assert.strictEqual("string", typeof rawData, "The returned content is not a text");

					fs.readFile(path.join(__dirname, "..", "lib", "web", "index.html"), "utf8", (err, content) => {

						if (err) {
							reject(err);
						}
						else {
							assert.strictEqual(rawData.length, content.length, "The returned content's length is not the same that the file content");
							resolve();
						}

					});

				});

			}).on("error", (err) => {
				reject(err);
			}).end();

		});

	}).timeout(MAX_TIMEOUT_REQUEST);

	describe("API V1", () => {

		it("should get the IPs recovery (" + API_URL + "ips)", () => {

			return new Promise((resolve, reject) => {

				http.get(API_URL + "ips", (res) => {

					assert.strictEqual(200, res.statusCode, "The statusCode is not 200");
					assert.strictEqual("OK", res.statusMessage, "The statusMessage is not valid");
					assert.strictEqual("object", typeof res.headers, "The headers are not an object");
					assert.strictEqual("application/json; charset=utf-8", res.headers["content-type"].toLowerCase(), "The content-type header are not html/utf8");

					res.setEncoding("utf8");

					let rawData = "";
					res.on("data", (chunk) => { rawData += chunk; });
					res.on("end", () => {

						assert.strictEqual("string", typeof rawData, "The the returned content is not a string");

						assert.doesNotThrow(() => {
							JSON.parse(rawData);
						}, "The the returned content is not a JSON");

						resolve();

					});

				}).on("error", (err) => {
					reject(err);
				}).end();

			});

		}).timeout(MAX_TIMEOUT_REQUEST);

	});

});

@@ -445,16 +445,24 @@
 server (
+address 
 127.0.0.
@@ -752,46 +752,14 @@
 olve
-, reject) =%3E %7B%0A%0A%09%09%09let timeout = null;
+) =%3E %7B
 %0A%0A%09%09
@@ -904,171 +904,22 @@
 %09%09%09)
-.on(%22error%22, (err) =%3E %7B%0A%0A%09%09%09%09if (timeout) %7B%0A%09%09%09%09%09clearTimeout(timeout);%0A%09%09%09%09%09timeout = null;%0A%09%09%09%09%7D%0A%0A%09%09%09%09reject(err);%0A%0A%09%09%09%7D);%0A%0A%09%09%09timeout = setTimeout(
+;%0A%0A%09%09%09
 resolve
-, 1000
+(
 );%0A%0A
@@ -989,16 +989,35 @@
 ain page
+ (%22 + MAIN_URL + %22)
 %22, () =%3E
@@ -1045,32 +1045,24 @@
 ise((resolve
-, reject
 ) =%3E %7B%0A%0A%09%09%09h
@@ -1811,61 +1811,83 @@
 %09%09%09%09
-if (err) %7B%0A%09%09%09%09%09%09%09reject(err);%0A%09%09%09%09%09%09%7D%0A%09%09%09%09%09%09else %7B%0A%09
+assert.strictEqual(null, err, %22The returned content's generate an error%22);%0A
 %09%09%09%09
@@ -2007,25 +2007,25 @@
  content%22);%0A
-%09
+%0A
 %09%09%09%09%09%09resolv
@@ -2028,24 +2028,16 @@
 solve();
-%0A%09%09%09%09%09%09%7D
 %0A%0A%09%09%09%09%09%7D
@@ -2058,60 +2058,8 @@
 %09%09%7D)
-.on(%22error%22, (err) =%3E %7B%0A%09%09%09%09reject(err);%0A%09%09%09%7D).end()
 ;%0A%0A%09
@@ -2228,16 +2228,8 @@
 olve
-, reject
 ) =%3E
@@ -3057,62 +3057,8 @@
 %09%09%7D)
-.on(%22error%22, (err) =%3E %7B%0A%09%09%09%09%09reject(err);%0A%09%09%09%09%7D).end()
 ;%0A%0A%09

improve coverage