import { HttpStatusCode } from '@angular/common/http';
import { HttpMethod, isConnectionTimeout } from '..';
import { isChangingDataRequest, isForbidden, isServerError, isServiceUnavailable, isUnauthorized, isUnprocessableEntity } from './http.util';

describe('http util', () => {

	const SERVER_ERROR_CODES: HttpStatusCode[] = [500, 501, 505, 506, 507, 508, 510, 511];
	const CONNECTION_TIMEOUT_CODES: HttpStatusCode[] = [502, 503, 504];
	const CLIENT_ERROR: HttpStatusCode[] = [400, 401, 402, 403, 404, 422];

	describe('isForbidden', () => {

		it.each(CLIENT_ERROR.slice(HttpStatusCode.Forbidden).concat(SERVER_ERROR_CODES))
			('should be false on %i', (httpStatusCode: HttpStatusCode) => {
				var result: boolean = isForbidden(httpStatusCode);

				expect(result).toBeFalsy();
			});

		it('should be true on 403', () => {
			var result: boolean = isForbidden(HttpStatusCode.Forbidden);

			expect(result).toBeTruthy();
		})
	})

	describe('isUnauthorized', () => {

		it.each(CLIENT_ERROR.slice(HttpStatusCode.Unauthorized).concat(SERVER_ERROR_CODES))
			('should be false on %i', (httpStatusCode: HttpStatusCode) => {
				var result: boolean = isUnauthorized(httpStatusCode);

				expect(result).toBeFalsy();
			});

		it('should be true on 401', () => {
			var result: boolean = isUnauthorized(HttpStatusCode.Unauthorized);

			expect(result).toBeTruthy();
		});
	})

	describe('isServerError', () => {

		it.each(SERVER_ERROR_CODES)
			('should be true on %i', (httpStatusCode: HttpStatusCode) => {
				var result: boolean = isServerError(httpStatusCode);

				expect(result).toBeTruthy();
			});

		it.each(CLIENT_ERROR.concat(CONNECTION_TIMEOUT_CODES))
			('should be false on %i', () => {
				var result: boolean = isServerError(HttpStatusCode.Forbidden);

				expect(result).toBeFalsy();
			})
	})

	describe('isUnprocessableEntity', () => {

		it.each(CLIENT_ERROR.slice(HttpStatusCode.UnprocessableEntity).concat(SERVER_ERROR_CODES).concat(SERVER_ERROR_CODES))
			('should be false on %i', (httpStatusCode: HttpStatusCode) => {
				var result: boolean = isUnprocessableEntity(httpStatusCode);

				expect(result).toBeFalsy();
			});

		it('should be true on %i', () => {
			var result: boolean = isUnprocessableEntity(HttpStatusCode.UnprocessableEntity);

			expect(result).toBeTruthy();
		})
	})

	describe('isChangingDataRequest', () => {

		const CHANGING_DATA_REQUEST_METHOD: string[] = [HttpMethod.POST, HttpMethod.PUT, HttpMethod.PATCH, HttpMethod.DELETE];

		it.each(CHANGING_DATA_REQUEST_METHOD)
			('should return true on %i', (method: string) => {
				var result: boolean = isChangingDataRequest(<any>{ method });

				expect(result).toBeTruthy();
			})

		it('should return false on %i', () => {
			var result: boolean = isChangingDataRequest(<any>{ method: HttpMethod.GET });

			expect(result).toBeFalsy();
		})
	})

	describe('isConnectionTimeout', () => {

		it.each(CONNECTION_TIMEOUT_CODES)
			('should return true on %i', (statusCode: number) => {
				var result: boolean = isConnectionTimeout(statusCode);

				expect(result).toBeTruthy();
			})

		it.each(SERVER_ERROR_CODES)
			('should return false on %i', (statusCode: number) => {
				var result: boolean = isConnectionTimeout(statusCode);

				expect(result).toBeFalsy();
			})
	})

	describe('isServiceUnavailable', () => {

		it('should return true on %i', () => {
			var result: boolean = isServiceUnavailable(HttpStatusCode.ServiceUnavailable);

			expect(result).toBeTruthy();
		})

		it.each(SERVER_ERROR_CODES.concat(CONNECTION_TIMEOUT_CODES.slice(HttpStatusCode.ServiceUnavailable)))
			('should return false on %i', (statusCode: number) => {
				var result: boolean = isServiceUnavailable(statusCode);

				expect(result).toBeFalsy();
			})
	})
})