// Copyright 2020 Fastly, Inc.

import { URL } from "../url";

describe("Absolute URLs", () => {
  test("Can parse protocol", () => {
    let http = new URL("http://fastly.com");
    expect(http.protocol).toBe("http:");
    let https = new URL("https://fastly.com");
    expect(https.protocol).toBe("https:");
    let file = new URL("file:///home/torch2424/README.md");
    expect(file.protocol).toBe("file:");
  });

  test("Can parse origin", () => {
    let simple = new URL("https://fastly.com");
    expect(simple.origin).toBe("https://fastly.com");
    let port = new URL("https://fastly.com:8080");
    expect(port.origin).toBe("https://fastly.com:8080");
    let ignoreAuth = new URL("http://user:pass@fastly.com:8080");
    expect(ignoreAuth.origin).toBe("http://fastly.com:8080");
  });

  test("Can parse username", () => {
    let simple = new URL("https://user@fastly.com");
    expect(simple.username).toBe("user");
    let withPassword = new URL("https://user:pass@fastly.com");
    expect(withPassword.username).toBe("user");
  });

  test("Can parse password", () => {
    let simple = new URL("https://user:pass@fastly.com");
    expect(simple.password).toBe("pass");
  });

  test("Can parse hostname", () => {
    let simple = new URL("https://fastly.com");
    expect(simple.hostname).toBe("fastly.com");
    let subdomain = new URL("https://subsub.sub.fastly.com");
    expect(subdomain.hostname).toBe("subsub.sub.fastly.com");
  });

  test("Can parse port", () => {
    let simple = new URL("https://fastly.com:8080");
    expect(simple.port).toBe("8080");
    let subdomain = new URL("https://subsub.sub.fastly.com:9090");
    expect(subdomain.port).toBe("9090");

    // Will parse, but ignore, default ports
    // https://url.spec.whatwg.org/#ref-for-default-port
    let defaultPortUrl = new URL("http://fastly.com:80");
    expect(defaultPortUrl.port).toBe("");
  });

  test("Can parse host", () => {
    let simple = new URL("https://fastly.com");
    expect(simple.host).toBe("fastly.com");
    let port = new URL("https://fastly.com:8080");
    expect(port.host).toBe("fastly.com:8080");
    let ignoreAuth = new URL("http://user:pass@fastly.com:9090");
    expect(ignoreAuth.host).toBe("fastly.com:9090");

    // Will parse ipv4
    let localhost = new URL("http://127.0.0.1");
    expect(localhost.host).toBe("127.0.0.1");

    // Will parse ipv6
    let ipvSix = new URL("http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]");
    expect(ipvSix.host).toBe("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]");
  });

  test("Can parse pathname", () => {
    let simple = new URL("https://fastly.com/p/a/t/h");
    expect(simple.pathname).toBe("/p/a/t/h");
    let noPath = new URL("https://fastly.com");
    expect(noPath.pathname).toBe("/");
    let trailingPath = new URL("https://fastly.com/p/a/t/h/");
    expect(trailingPath.pathname).toBe("/p/a/t/h/");
  });

  test("Can parse search", () => {
    let simple = new URL("https://fastly.com?mySearch=true");
    expect(simple.search).toBe("?mySearch=true");
    let withPath = new URL("https://fastly.com/p/a/t/h/?mySearch=true");
    expect(withPath.search).toBe("?mySearch=true");
    let withHash = new URL(
      "https://fastly.com/p/a/t/h/?mySearch=true#properties"
    );
    expect(withHash.search).toBe("?mySearch=true");
    let withMultipleSearch = new URL(
      "https://fastly.com/p/a/t/h/?mySearch=true&otherSearch=2#properties"
    );
    expect(withMultipleSearch.search).toBe("?mySearch=true&otherSearch=2");
  });

  test("Can parse hash", () => {
    let simple = new URL("https://fastly.com#simpleHash");
    expect(simple.hash).toBe("#simpleHash");
    let withPath = new URL("https://fastly.com/p/a/t/h/#pathHash");
    expect(withPath.hash).toBe("#pathHash");
    let withSearch = new URL(
      "https://fastly.com/p/a/t/h/?mySearch=true#searchHash"
    );
    expect(withSearch.hash).toBe("#searchHash");
    let withMultipleHash = new URL(
      "https://fastly.com/p/a/t/h/?mySearch=true&otherSearch=2#myHash&myHash2"
    );
    expect(withMultipleHash.hash).toBe("#myHash&myHash2");
  });

  test("Can parse a complex URL ( https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash )", () => {
    let url = new URL(
      "https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash"
    );
    expect(url.protocol).toBe("https:");
    expect(url.username).toBe("user");
    expect(url.password).toBe("pass");
    expect(url.hostname).toBe("sub.example.com");
    expect(url.port).toBe("8080");
    expect(url.host).toBe("sub.example.com:8080");
    expect(url.origin).toBe("https://sub.example.com:8080");
    expect(url.pathname).toBe("/p/a/t/h");
    expect(url.search).toBe("?query=string");
    expect(url.hash).toBe("#hash");
    expect(url.href).toBe(
      "https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash"
    );
  });

  test("Can parse a development URL ( http://localhost:8080/p/a/t/h?query=string#hash )", () => {
    let url = new URL("http://localhost:8080/p/a/t/h?query=string#hash");
    expect(url.protocol).toBe("http:");
    expect(url.hostname).toBe("localhost");
    expect(url.port).toBe("8080");
    expect(url.host).toBe("localhost:8080");
    expect(url.origin).toBe("http://localhost:8080");
    expect(url.pathname).toBe("/p/a/t/h");
    expect(url.search).toBe("?query=string");
    expect(url.hash).toBe("#hash");
    expect(url.href).toBe("http://localhost:8080/p/a/t/h?query=string#hash");
  });
});
