import { parseQueryParams, withQueryParams, trimQueryParams, QUERY_PARAMS_BLACKLIST } from 'web-client/utilities/url-params';
import { module, test } from 'qunit';

module('Unit | Utility | url params');

test('parseQueryParams works with empty string', function(assert) {
  assert.deepEqual(parseQueryParams(''), {});
});

test('parseQueryParams works with basic scenarios', function(assert) {
  let expectations = [
    ['foo=bar', {foo: 'bar'}],
    ['foo=bar&boo=baz', {foo: 'bar', boo: 'baz'}]
  ];

  assert.expect(expectations.length);

  expectations.forEach(([string, parsed]) => {
    assert.deepEqual(parseQueryParams(string), parsed, `parses ${string} correctly`);
  });
});

test('parseQueryParams decodes keys and values', function(assert) {
  let expectations = [
    ['f%26o=bar&boo=b%26z', {'f&o': 'bar', boo: 'b&z'}],
    ['f%25o=bar&boo=b%25z', {'f%o': 'bar', boo: 'b%z'}],
    ['foo=bar%26boo%3Dbaz', {foo: 'bar&boo=baz'}],
    ['foo=b+a+z', {foo: 'b a z'}],
    ['foo=b a z', {foo: 'b a z'}], // not correctly encoded (space should be "+")
    ['foo=b%20a%20z', {foo: 'b a z'}] // not correctly encoded (space should be "+", not "%20")
  ];

  assert.expect(expectations.length);

  expectations.forEach(([string, parsed]) => {
    assert.deepEqual(parseQueryParams(string), parsed, `parses ${string} correctly`);
  });
});

test('withQueryParams adds query params to a url', function(assert) {
  let url = withQueryParams(
    'http://example.com',
    ['haveit', 'needs_encoding', 'missing'],
    {
      haveit: 'haveit-value',
      needs_encoding: 'needs encoding',
      notWhitelisted: 'not-whitelisted'
    }
  );

  assert.equal(url, 'http://example.com?haveit=haveit-value&needs_encoding=needs%20encoding');
});

test('trimQueryParams with no query parameters', function(assert) {
  const url = 'http://twitch.tv';
  assert.equal(trimQueryParams(url), url, `parses ${url} correctly`);
});

test('trimQueryParams with basic scenarios', function(assert) {
  let expectations = [
    ['http://twitch.tv?foo=bar', 'http://twitch.tv?foo=bar'],
    ['http://twitch.tv?foo=bar&baz=bam', 'http://twitch.tv?foo=bar&baz=bam']
  ];

  assert.expect(expectations.length);
  expectations.forEach(([string, parsed]) => {
    assert.equal(trimQueryParams(string), parsed, `parses ${string} correctly`);
  });
});

test('trimQueryParams with blacklisted parameters', function(assert) {
  let queryUrl = '';
  for (const key in QUERY_PARAMS_BLACKLIST) {
    if (!QUERY_PARAMS_BLACKLIST.hasOwnProperty(key)) {
      continue;
    }
    queryUrl += `${key}=${QUERY_PARAMS_BLACKLIST[key]}`;
  }

  const query = `http://twitch.tv?${queryUrl}`;
  assert.equal(trimQueryParams(query), 'http://twitch.tv', `parses ${query} correctly`);
});

test('trimQueryParams with strangely formed parameters', function(assert) {
  let expectations = [
    ['http://twitch.tv?foo=', 'http://twitch.tv'],
    ['http://twitch.tv?foo=&bar=', 'http://twitch.tv'],
    ['http://twitch.tv?foo[]=1', 'http://twitch.tv?foo%5B%5D=1']
  ];

  assert.expect(expectations.length);
  expectations.forEach(([string, parsed]) => {
    assert.equal(trimQueryParams(string), parsed, `parses ${string} correctly`);
  });
});
