/***********************************************************************************************************
 * Name         : TempFormResponseBatchMonitorTest
 * Purpose      : Test class for TempFormResponseBatchMonitor
 **********************************************************************************************************/

@isTest
private class TempFormResponseBatchMonitorTest {
    @TestSetup
    static void makeData() {
        insert new List<Config__c>{
            new Config__c(Name = 'TFR_MONITOR_CRON_EXPS', Value__c = '0 15 * * * ?'),
            new Config__c(Name = 'TFR_MONITOR_EMAIL_SENDER', Value__c = 'TFR Monitor'),
            new Config__c(Name = 'TFR_MONITOR_EMAIL_SUBJECT', Value__c = 'Subject'),
            new Config__c(Name = 'TFR_MONITOR_EMAIL_RECIPIENTS', Value__c = 'test@sonymusic.com'),
            new Config__c(Name = 'TFR_JOB_MAX_RETRY', Value__c = '1'),
            new Config__c (Name = ConfigUtils.FILE_UPLOAD_JOB_MAX_RETRY, Value__c = '1'),
            new Config__c(
                Name = 'TFR_MONITOR_EMAIL_BODIES',
                Value__c = 'List of previous TempFormResponseBatch jobs attached.' +
                    ';No previous TempFormResponseBatch jobs executions found.'
            )
        };
    }

    /************************************************************************************
     * Method: jobRestartNeededNoPreviousJobs
     * APEX method tested : TempFormResponseBatchMonitor.execute
     * Description : Verifies that the job is restarted when there are no previous
     *  instances of the job
     *************************************************************************************/
    @IsTest
    static void jobRestartNeededNoPreviousJobs() {
        insert new Config__c(Name = 'TFR_MONITOR_CREATED_MINUTES', Value__c = '10');

        User adminUser = TestFactory.getRunAsUserByProfile('System Administrator');
        String userName = adminUser.Username;

        Test.startTest();
        System.runAs(adminUser) {
            Database.executeBatch(new TempFormResponseBatch());
            TempFormResponseBatchMonitor tfrBatchMonitor = new TempFormResponseBatchMonitor();
            tfrBatchMonitor.monitor();
        }
        Test.stopTest();

        System.assertEquals(
            1,
            Database.countQuery(
                'SELECT count() FROM AsyncApexJob WHERE ApexClass.Name = \'TempFormResponseBatch\' AND CreatedBy.Username = :userName'
            )
        );
    }

    /************************************************************************************
     * Method: jobRestartNeededElapsedTime
     * APEX method tested : TempFormResponseBatchMonitor.execute
     * Description : Verifies that the job is restarted when there are instances of
     *  the job that have run but not within the threshold
     *************************************************************************************/
    @IsTest
    static void jobRestartNeededElapsedTime() {
        //Making createdDate a date in the future by using minus
        insert new Config__c(Name = 'TFR_MONITOR_CREATED_MINUTES', Value__c = '-10');

        User adminUser = TestFactory.getRunAsUserByProfile('System Administrator');
        String userName = adminUser.Username;

        Test.startTest();
        System.runAs(adminUser) {
            Database.executeBatch(new TempFormResponseBatch());
            TempFormResponseBatchMonitor tfrBatchMonitor = new TempFormResponseBatchMonitor();
            tfrBatchMonitor.monitor();
        }
        Test.stopTest();

        System.assertEquals(
            1,
            Database.countQuery(
                'SELECT count() FROM AsyncApexJob WHERE ApexClass.Name = \'TempFormResponseBatch\' AND CreatedBy.Username = :userName'
            )
        );
    }

    /************************************************************************************
     * Method: jobRestartNotNeeded
     * APEX method tested : TempFormResponseBatchMonitor.execute
     * Description : Verifies that the job is not restarted when there are instances of
     *  the job that have run within the threshold
     *************************************************************************************/
    @IsTest
    static void jobRestartNotNeeded() {
        insert new Config__c(Name = 'TFR_MONITOR_CREATED_MINUTES', Value__c = '10');

        User adminUser = TestFactory.getRunAsUserByProfile('System Administrator');
        String userName = adminUser.Username;

        Test.startTest();
        Database.executeBatch(new TempFormResponseBatch());
        System.runAs(adminUser) {
            TempFormResponseBatchMonitor tfrBatchMonitor = new TempFormResponseBatchMonitor();
            tfrBatchMonitor.monitor();
        }
        Test.stopTest();

        System.assertEquals(
            0,
            Database.countQuery(
                'SELECT count() FROM AsyncApexJob WHERE ApexClass.Name = \'TempFormResponseBatch\' AND CreatedBy.Username = :userName'
            )
        );
    }

    /************************************************************************************
     * Method: jobRestartNotNeededAnotherActiveInstance
     * APEX method tested : TempFormResponseBatchMonitor.execute
     * Description : Verifies that the job is not restarted when there is another
     *  instance of the job with an active status
     *************************************************************************************/
    @IsTest
    static void jobRestartNotNeededAnotherActiveInstance() {
        insert new Config__c(Name = 'TFR_MONITOR_CREATED_MINUTES', Value__c = '10');

        Test.startTest();
        Database.executeBatch(new TempFormResponseBatch());
        TempFormResponseBatchMonitor tfrBatchMonitor = new TempFormResponseBatchMonitor();
        tfrBatchMonitor.monitor();
        Test.stopTest();

        System.assertEquals(
            1,
            Database.countQuery('SELECT count() FROM AsyncApexJob WHERE ApexClass.Name = \'TempFormResponseBatch\'')
        );
    }

    /************************************************************************************
     * Method: schedule
     * APEX method tested : TempFormResponseBatchMonitor.schedule
     * Description : Verifies that the class is being scheduled properly
     *************************************************************************************/
    @isTest
    static void schedule() {
        String jobName = 'TempFormResponseBatchMonitor';

        List<CronJobDetail> jobs = [
            SELECT Id
            FROM CronJobDetail
            WHERE Name = :jobName
        ];

        System.assert(jobs.isEmpty());

        Test.startTest();
        TempFormResponseBatchMonitor.schedule();
        Test.stopTest();

        jobs = [
            SELECT Id
            FROM CronJobDetail
            WHERE Name LIKE :jobName + '%'
        ];

        System.assertEquals(1, jobs.size());
    }
}
