// Copyright 2020 Fastly, Inc.

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

describe("Getters / Setters", () => {
  // Following: https://developer.mozilla.org/en-US/docs/Web/API/URL#Properties

  test("Get/Set hash", () => {
    let url = new URL("https://fastly.com#myHash");
    expect(url.hash).toBe("#myHash");
    url.hash = "#newHash";
    expect(url.hash).toBe("#newHash");
    url.hash = "noHash";
    expect(url.hash).toBe("#noHash");
  });

  test("Get/Set host", () => {
    let url = new URL("https://fastly.com");
    expect(url.host).toBe("fastly.com");
    expect(url.hostname).toBe("fastly.com");
    expect(url.port).toBe("");
    url.host = "sub.fastly.com:8080";
    expect(url.host).toBe("sub.fastly.com:8080");
    expect(url.hostname).toBe("sub.fastly.com");
    expect(url.port).toBe("8080");
  });

  test("Get/Set hostname", () => {
    let url = new URL("https://fastly.com");
    expect(url.hostname).toBe("fastly.com");
    url.hostname = "sub.fastly.com";
    expect(url.hostname).toBe("sub.fastly.com");
  });

  test("Get/Set href", () => {
    let url = new URL(
      "https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash"
    );
    expect(url.href).toBe(
      "https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash"
    );
    url.href =
      "http://user2:pass2@subsub.example2.io:9090/p/a/a/a/t/h/?query2=string2#hash2";
    expect(url.protocol).toBe("http:");
    expect(url.username).toBe("user2");
    expect(url.password).toBe("pass2");
    expect(url.hostname).toBe("subsub.example2.io");
    expect(url.port).toBe("9090");
    expect(url.host).toBe("subsub.example2.io:9090");
    expect(url.origin).toBe("http://subsub.example2.io:9090");
    expect(url.pathname).toBe("/p/a/a/a/t/h");
    expect(url.search).toBe("?query2=string2");
    expect(url.hash).toBe("#hash2");
    expect(url.href).toBe(
      "http://user2:pass2@subsub.example2.io:9090/p/a/a/a/t/h?query2=string2#hash2"
    );
  });

  test("Get origin", () => {
    let url = new URL(
      "https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash"
    );
    expect(url.origin).toBe("https://sub.example.com:8080");
  });

  test("Get/Set password", () => {
    let url = new URL("https://user:pass@fastly.com");
    expect(url.password).toBe("pass");
    url.password = "newPass";
    expect(url.password).toBe("newPass");

    // A URL cannot have a username/password/port
    // if its host is null or the empty string,
    // its cannot-be-a-base-URL flag is set, or its scheme is "file".
    // https://url.spec.whatwg.org/#url-miscellaneous
    let specialUrl = new URL("file:///home/torch2424/README.md");
    specialUrl.password = "pass";
    expect(specialUrl.password).toBe("");
  });

  test("Get/Set pathname", () => {
    let url = new URL("https://fastly.com/p/a/t/h");
    expect(url.pathname).toBe("/p/a/t/h");
    url.pathname = "/p/a/a/a/t/h/";
    expect(url.pathname).toBe("/p/a/a/a/t/h");
  });

  test("Get/Set port", () => {
    let url = new URL("https://fastly.com");
    expect(url.port).toBe("");
    url.port = "8080";
    expect(url.port).toBe("8080");

    // A URL cannot have a username/password/port
    // if its host is null or the empty string,
    // its cannot-be-a-base-URL flag is set, or its scheme is "file".
    // https://url.spec.whatwg.org/#url-miscellaneous
    let specialUrl = new URL("file:///home/torch2424/README.md");
    specialUrl.port = "2424";
    expect(specialUrl.port).toBe("");
  });

  test("Get/Set protocol", () => {
    let url = new URL("https://fastly.com");
    expect(url.protocol).toBe("https:");
    url.protocol = "http:";
    expect(url.protocol).toBe("http:");
  });

  test("Set protocol should not allow from switching from special schemes to non-special schemes and vice versa", () => {
    // https://nodejs.org/api/url.html#url_special_schemes

    let url = new URL("http://example.org");
    url.protocol = "https";
    expect(url.protocol).toBe("https:");

    url = new URL("http://example.org");
    url.protocol = "fish";
    expect(url.protocol).toBe("http:");

    url = new URL("fish://example.org");
    url.protocol = "http";
    expect(url.protocol).toBe("fish:");
  });

  test("Get/Set search", () => {
    let url = new URL("https://fastly.com?mySearch=true");
    expect(url.search).toBe("?mySearch=true");
    url.search = "search3=true";
    expect(url.search).toBe("?search3=true");
  });

  test("Get/Set username", () => {
    let url = new URL("https://user:pass@fastly.com");
    expect(url.username).toBe("user");
    url.username = "newUser";
    expect(url.username).toBe("newUser");

    // A URL cannot have a username/password/port
    // if its host is null or the empty string,
    // its cannot-be-a-base-URL flag is set, or its scheme is "file".
    // https://url.spec.whatwg.org/#url-miscellaneous
    let specialUrl = new URL("file:///home/torch2424/README.md");
    specialUrl.username = "torch2424";
    expect(specialUrl.username).toBe("");
  });
});
