@isTest
private class TrainingTestResultTriggerTest {

    static testMethod void testExecute() {
        User loginUser = [select Id from User where Id = :UserInfo.getUserId()];
        List<RecordType> rt2 = [select Id from RecordType where SobjectType = 'Training_test_Result__c' and DeveloperName in ('BTC', 'ETC') order by DeveloperName];
        Id rtId = '01210000000Qtky';
        User user = new User();
        user.LastName = 'LastName';
        user.FirstName = 'FirstName';
        user.Alias = 'Alias';
        user.Email = 'olympustest03@sunbridge.com';
        user.Username = 'olympustest03@sunbridge.com';
        user.CommunityNickname = 'CommunityNickname';
        user.IsActive = true;               // trueの場合ライセンス数にカウントされない
        user.EmailEncodingKey = 'ISO-2022-JP';
        user.TimeZoneSidKey = 'Asia/Tokyo';
        user.LocaleSidKey = 'ja_JP';
        user.LanguageLocaleKey = 'ja';
        user.ProfileId = System.Label.ProfileId_SystemAdmin;
        user.Job_Category__c = '销售推广';
        user.Province__c = '上海市';
        user.Post__c = '经理';
        user.MobilePhone = '54321';
        user.Mobile_Phone__c = '12345';
        user.Employee_No__c = '112233';
        user.Work_Location__c = 'Location';
        user.Use_Start_Date__c = Date.today().addMonths(-6);
        insert user;
        system.runAs(loginUser) {
            user.IsActive = false;
            update user;
        }
        Campaign c = new Campaign(Name = 'test', RecordTypeId = '01210000000R91f');       // Internal_training
        insert c;
        Contact e1 = new Contact(LastName = 'loginUser', User__c = UserInfo.getUserId());
        Contact e2 = new Contact(LastName = 'loginUser', User__c = user.Id);
        insert new List<Contact>{e1, e2};
        
        List<Contact> eList = [select Id, Number_of_participant_for_BTC__c, Number_of_participant_for_ETC__c from Contact where Id = :e1.Id];
        System.assertEquals(null, eList[0].Number_of_participant_for_BTC__c);
        System.assertEquals(null, eList[0].Number_of_participant_for_ETC__c);
        
        Training_test_Result__c ttr1 = new Training_test_Result__c(RecordTypeId = rt2[0].Id, employee__c = e1.Id, campaign__c = c.Id);
        insert ttr1;
        eList = [select Id, Number_of_participant_for_BTC__c, Number_of_participant_for_ETC__c from Contact where Id = :e1.Id];
        system.assertEquals(1, eList[0].Number_of_participant_for_BTC__c);
        system.assertEquals(0, eList[0].Number_of_participant_for_ETC__c);

        // ２件同時 insert
        delete ttr1;
        ttr1 = new Training_test_Result__c(RecordTypeId = rt2[0].Id, employee__c = e1.Id, campaign__c = c.Id);
        Training_test_Result__c ttr2 = new Training_test_Result__c(RecordTypeId = rt2[1].Id, employee__c = e1.Id, campaign__c = c.Id);
        insert new List<Training_test_Result__c>{ttr1, ttr2};
        eList = [select Id, Number_of_participant_for_BTC__c, Number_of_participant_for_ETC__c from Contact where Id = :e1.Id];
        System.assertEquals(1, eList[0].Number_of_participant_for_BTC__c);
        System.assertEquals(1, eList[0].Number_of_participant_for_ETC__c);
        
        // User inactive insert
        Training_test_Result__c ttr3 = new Training_test_Result__c(RecordTypeId = rt2[1].Id, employee__c = e2.Id, campaign__c = c.Id);
        insert ttr3;
        Training_test_Result__c ttr = [select Id,OwnerId from Training_test_Result__c where Id = :ttr3.Id];
        System.assertEquals('00510000000fSYI', ttr.OwnerId); // batch用户ID
        eList = [select Id, Number_of_participant_for_BTC__c, Number_of_participant_for_ETC__c from Contact where Id = :e2.Id];
        System.assertEquals(0, eList[0].Number_of_participant_for_BTC__c);
        System.assertEquals(1, eList[0].Number_of_participant_for_ETC__c);
        
        delete ttr3;

        // レコードタイプ変更
        ttr2.RecordTypeId = rt2[0].Id;
        update ttr2;
        eList = [select Id, Number_of_participant_for_BTC__c, Number_of_participant_for_ETC__c from Contact where Id = :e1.Id];
        System.assertEquals(2, eList[0].Number_of_participant_for_BTC__c);
        System.assertEquals(0, eList[0].Number_of_participant_for_ETC__c);

        // e2に変更
        ttr2.employee__c = e2.id;
        update ttr2;
        ttr = [select Id,OwnerId from Training_test_Result__c where Id = :ttr2.Id];
        System.assertEquals('00510000000fSYI', ttr.OwnerId); // batch用户ID
        eList = [select Id, Number_of_participant_for_BTC__c, Number_of_participant_for_ETC__c from Contact where Id = :e1.Id];
        System.assertEquals(1, eList[0].Number_of_participant_for_BTC__c);
        System.assertEquals(0, eList[0].Number_of_participant_for_ETC__c);
        eList = [select Id, Number_of_participant_for_BTC__c, Number_of_participant_for_ETC__c from Contact where Id = :e2.Id];
        System.assertEquals(1, eList[0].Number_of_participant_for_BTC__c);
        System.assertEquals(0, eList[0].Number_of_participant_for_ETC__c);
        
        ttr2.employee__c = e1.id;
        update ttr2;

        // TODO 本身也是loginUser再跑，为什么用runAs跑就不会报错 MIXED_DML_OPERATION
        system.runAs(loginUser) {
            user.IsActive = true;
            update user;
        }
        // User Active insert
        ttr3 = new Training_test_Result__c(RecordTypeId = rt2[1].Id, employee__c = e2.Id, campaign__c = c.Id);
        insert ttr3;
        ttr3 = [select Id, OwnerId from Training_test_Result__c where Id = :ttr3.Id];
        System.assertEquals(user.Id, ttr3.OwnerId);
        eList = [select Id, Number_of_participant_for_BTC__c, Number_of_participant_for_ETC__c from Contact where Id = :e2.Id];
        System.assertEquals(0, eList[0].Number_of_participant_for_BTC__c);
        System.assertEquals(1, eList[0].Number_of_participant_for_ETC__c);

        // update to e2
        ttr2.employee__c = e2.id;
        update ttr2;
        eList = [select Id, Number_of_participant_for_BTC__c, Number_of_participant_for_ETC__c from Contact where Id = :e1.Id];
        System.assertEquals(1, eList[0].Number_of_participant_for_BTC__c);
        System.assertEquals(0, eList[0].Number_of_participant_for_ETC__c);
        eList = [select Id, Number_of_participant_for_BTC__c, Number_of_participant_for_ETC__c from Contact where Id = :e2.Id];
        System.assertEquals(1, eList[0].Number_of_participant_for_BTC__c);
        System.assertEquals(1, eList[0].Number_of_participant_for_ETC__c);
        ttr2 = [select Id, OwnerId from Training_test_Result__c where Id = :ttr2.Id];
        System.assertEquals(user.Id, ttr2.OwnerId);

        // 削除
        delete ttr2;
        eList = [select Id, Number_of_participant_for_BTC__c, Number_of_participant_for_ETC__c from Contact where Id IN: new List<Id>{e1.Id, e2.id}];
        System.assertEquals(1, eList[0].Number_of_participant_for_BTC__c);
        System.assertEquals(0, eList[0].Number_of_participant_for_ETC__c);
    }
}