import * as chai from 'chai';
import * as request from "request-promise-native";
import 'mocha';

const expect = chai.expect;

const TEST_URL = process.env.TEST_URL || 'http://localhost:8080'

interface Test {
  request: request.OptionsWithUri;
  expect: {
    status: number;
    headers?: {};
    type?: string;
  }
  rejection?: any;
  response?: request.FullResponse;
}


let tests: Test[] = [
  {
    request: {method: 'POST', uri: '/'},
    expect: {status: 405}
  },
  {
    request: {method: 'GET', uri: '/'},
    expect: {status: 404}
  },
  {
    request: {method: 'GET', uri: '/assets/vendor-060b523468fd99fdbf9f.js.map'},
    expect: {status: 404}
  },
  {
    request: {method: 'GET', uri: '/assets/vendor-060b523468fd99fdbf9f.js', headers: {'accept-encoding': 'gzip'}},
    expect: { status: 200, headers: {'cache-control': 'public, max-age=31536000, immutable', vary: 'Accept-Encoding'}}
  },
  {
    request: {method: 'GET', uri: '/config/settings.js'},
    expect: { status: 200, headers: {'cache-control': 'public, max-age=60'}}
  },
  {
    request: {method: 'GET', uri: '/config/manifest.json'},
    expect: { status: 200, headers: {'cache-control': 'public, max-age=300'}}
  },
  {
    request: {method: 'GET', uri: '/debug/return_502'},
    expect: { status: 502, headers: {'cache-control': 'public, max-age=1', 'x-vicarius-retries': '3'}}
  }
]


for (const test of tests) {
  test.request.baseUrl = TEST_URL;
  test.request.resolveWithFullResponse = true;
  test.request.followRedirect = false;
  test.request.simple = false;

  describe(`${test.request.method} ${test.request.uri}`, () => {

    before ('should load', async () => {
      return request(test.request).then(r => {
        test.response = r;
      });
    });


    it('should have status ' + test.expect.status, () => {
      expect(test.response.statusCode).to.equal(test.expect.status)
    });


    if (test.expect.type) {
      it('should have content type ' + test.expect.type, () => {
        let s = test.response.headers['content-type']
        let mediaType = s.indexOf(';') === -1 ? s : s.substr(0, s.indexOf(';'))
        expect(mediaType).to.equal(test.expect.type)
      });
    }

    if (test.expect.headers) {
      it('should have headers ' + Object.entries(test.expect.headers).map(a => a.join(':')).join(', '), () => {
        for (const [k,v] of Object.entries(test.expect.headers)) {
        let s = test.response.headers[k]
        expect(s).to.equal(test.expect.headers[k])
        }
      });
    }

  });
}