/*-
 * ============LICENSE_START=======================================================
 * OSAM
 * ================================================================================
 * Copyright (C) 2018 AT&T
 * ================================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ============LICENSE_END=========================================================
 */



package org.onap.osam.controllers;

import org.apache.log4j.BasicConfigurator;
import org.junit.Before;
import org.junit.Test;
import org.onap.osam.controllers.PodDemoController.HealthStatus;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;


public class HealthCheckControllerTest {

	private PodDemoController testSubject;
	private MockMvc mockMvc;

	@Before
	public void setUp() {
		testSubject = new PodDemoController();
		BasicConfigurator.configure();
		mockMvc = MockMvcBuilders.standaloneSetup(testSubject).build();
	}

	@Test
	public void testGetProfileCount() throws Exception {
		String driver = "";
		String URL = "";
		String username = "";
		String password = "";
		int result;

		// default test
		result = testSubject.getProfileCount(driver, URL, username, password);
	}

	@Test
	public void testGethealthCheckStatusforIDNS() throws Exception {
		HealthStatus result;

		// default test
		result = testSubject.gethealthCheckStatusforIDNS();
	}

	@Test
	public void testCommitInfoEndpoint() throws Exception {
		mockMvc.perform(get("/commitInfo")
				.accept(MediaType.APPLICATION_JSON))
				.andExpect(status().isOk())
				.andExpect(jsonPath("$.commitId").value("123987"))
				.andExpect(jsonPath("$.commitMessageShort").value("Test short commit message"))
				.andExpect(jsonPath("$.commitTime").value("1999-09-12T13:48:55+0200"));
	}
}
