/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.channel.cc.commons.slogger;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import java.io.IOException;

import org.apache.log4j.Appender;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.ErrorHandler;
import org.apache.log4j.spi.LoggingEvent;
import org.junit.Before;
import org.junit.Test;

import com.scytl.slogger.SecureLoggerException;

/**
 * Tests of {@link ErrorTrackerImpl}.
 */
public class ErrorTrackerImplTest {
    private static final int ERROR_CODE = 1;

    private static final String MESSAGE = "message";

    private static final Exception EXCEPTION = new IOException("test");

    private ErrorHandler target;

    private ErrorTrackerImpl tracker;

    @Before
    public void setUp() {
        target = mock(ErrorHandler.class);
        tracker = new ErrorTrackerImpl();
    }

    @Test
    public void testActivateOptions() {
        tracker.activateOptions();
    }

    @Test
    public void testActivateOptionsWithTarget() {
        tracker.setTarget(target);
        tracker.activateOptions();
        verify(target).activateOptions();
    }

    @Test
    public void testCheckNoError() throws SecureLoggerException {
        tracker.checkNoError();
    }

    @Test(expected = SecureLoggerException.class)
    public void testErrorString() throws SecureLoggerException {
        tracker.error(MESSAGE);
        try {
            tracker.checkNoError();
        } catch (SecureLoggerException e) {
            assertEquals(MESSAGE, e.getMessage());
            assertNull(e.getCause());
            throw e;
        }
    }

    @Test(expected = SecureLoggerException.class)
    public void testErrorStringExceptionInt()
            throws SecureLoggerException {
        tracker.error(MESSAGE, EXCEPTION, ERROR_CODE);
        try {
            tracker.checkNoError();
        } catch (SecureLoggerException e) {
            assertEquals(MESSAGE, e.getMessage());
            assertEquals(EXCEPTION, e.getCause());
            throw e;
        }
    }

    @Test(expected = SecureLoggerException.class)
    public void testErrorStringExceptionIntLoggingEvent()
            throws SecureLoggerException {
        LoggingEvent event = mock(LoggingEvent.class);
        tracker.error(MESSAGE, EXCEPTION, ERROR_CODE, event);
        try {
            tracker.checkNoError();
        } catch (SecureLoggerException e) {
            assertEquals(MESSAGE, e.getMessage());
            assertEquals(EXCEPTION, e.getCause());
            throw e;
        }
    }

    @Test(expected = SecureLoggerException.class)
    public void testErrorStringExceptionIntLoggingEventWithTarget()
            throws SecureLoggerException {
        tracker.setTarget(target);
        LoggingEvent event = mock(LoggingEvent.class);
        tracker.error(MESSAGE, EXCEPTION, ERROR_CODE, event);
        try {
            tracker.checkNoError();
        } catch (SecureLoggerException e) {
            verify(target).error(MESSAGE, EXCEPTION, ERROR_CODE, event);
            assertEquals(MESSAGE, e.getMessage());
            assertEquals(EXCEPTION, e.getCause());
            throw e;
        }
    }

    @Test(expected = SecureLoggerException.class)
    public void testErrorStringExceptionIntWithTarget()
            throws SecureLoggerException {
        tracker.setTarget(target);
        tracker.error(MESSAGE, EXCEPTION, ERROR_CODE);
        try {
            tracker.checkNoError();
        } catch (SecureLoggerException e) {
            verify(target).error(MESSAGE, EXCEPTION, ERROR_CODE);
            assertEquals(MESSAGE, e.getMessage());
            assertEquals(EXCEPTION, e.getCause());
            throw e;
        }
    }

    @Test(expected = SecureLoggerException.class)
    public void testErrorStringWithTarget() throws SecureLoggerException {
        tracker.setTarget(target);
        tracker.error(MESSAGE);
        try {
            tracker.checkNoError();
        } catch (SecureLoggerException e) {
            verify(target).error(MESSAGE);
            assertEquals(MESSAGE, e.getMessage());
            assertNull(e.getCause());
            throw e;
        }
    }

    @Test
    public void testSetAppender() {
        tracker.setAppender(mock(Appender.class));
    }

    @Test
    public void testSetAppenderWithTarget() {
        tracker.setTarget(target);
        Appender appender = mock(Appender.class);
        tracker.setAppender(appender);
        verify(target).setAppender(appender);
    }

    @Test
    public void testSetBackupAppender() {
        tracker.setBackupAppender(mock(Appender.class));
    }

    @Test
    public void testSetBackupAppenderWithTarget() {
        tracker.setTarget(target);
        Appender appender = mock(Appender.class);
        tracker.setBackupAppender(appender);
        verify(target).setBackupAppender(appender);
    }

    @Test
    public void testSetLogger() {
        tracker.setLogger(mock(Logger.class));
    }

    @Test
    public void testSetLoggerWithTarget() {
        tracker.setTarget(target);
        Logger logger = mock(Logger.class);
        tracker.setLogger(logger);
        verify(target).setLogger(logger);
    }
}
