
import pytest
from src.config.objects import ExecuteDateTime, LastFetchDatetime, TargetObject
from src.salesforce.soql_builder import SOQLBuilder


class TestSOQLBuilder:

    def test_create_count_soql(self):
        """
        Cases:
            件数取得のSOQLが生成できること
        Arranges:
            SOQL生成用のパラメータを用意する
        Expects:
            期待値通りのSOQLが生成されること
        """
        test_target_object_json = {
            'object_name': 'Account',
            'columns': [
                'Id',
                'Name',
                'SystemModstamp',
                'LastModifiedDate',
                'CustomItem1__c',
                'CustomItem2__c',
                'CustomItem3__c',
                'CustomItem4__c',
                'CustomItem5__c',
                'CustomItem6__c',
                'CustomItem7__c',
                'CustomItem8__c'
            ]
        }

        test_last_fetch_datetime_json = {
            'last_fetch_datetime_from': '1999-01-01T00:00:00.000Z',
            'last_fetch_datetime_to': '2000-01-01T00:00:00.000Z',
        }

        execute_datetime = ExecuteDateTime()
        target_object = TargetObject(test_target_object_json, execute_datetime)
        test_last_fetch_datetime = LastFetchDatetime(test_last_fetch_datetime_json, execute_datetime)

        sut = SOQLBuilder(target_object, test_last_fetch_datetime)
        actual = sut.create_count_soql()

        expect = """SELECT
            COUNT(Id)
        FROM
            Account
        WHERE
            SystemModstamp > 1999-01-01T00:00:00.000Z AND
            SystemModstamp <= 2000-01-01T00:00:00.000Z
        """

        assert actual.replace('\n', '').replace(' ', '') == expect.replace('\n', '').replace(' ', '')

    def test_create_fetch_soql(self):
        """
        Cases:
            データ取得用のSOQLが生成できること
        Arranges:
            SOQL生成用のパラメータを用意する
        Expects:
            期待値通りのSOQLが生成されること
        """
        test_target_object_json = {
            'object_name': 'Account',
            'columns': [
                'Id',
                'Name',
                'SystemModstamp',
                'LastModifiedDate',
                'CustomItem1__c',
                'CustomItem2__c',
                'CustomItem3__c',
                'CustomItem4__c',
                'CustomItem5__c',
                'CustomItem6__c',
                'CustomItem7__c',
                'CustomItem8__c'
            ]
        }

        test_last_fetch_datetime_json = {
            'last_fetch_datetime_from': '1999-01-01T00:00:00.000Z',
            'last_fetch_datetime_to': '2000-01-01T00:00:00.000Z',
        }

        execute_datetime = ExecuteDateTime()
        target_object = TargetObject(test_target_object_json, execute_datetime)
        test_last_fetch_datetime = LastFetchDatetime(test_last_fetch_datetime_json, execute_datetime)

        sut = SOQLBuilder(target_object, test_last_fetch_datetime)
        actual = sut.create_fetch_soql()

        expect = """SELECT
            Id,
            Name,
            SystemModstamp,
            LastModifiedDate,
            CustomItem1__c,
            CustomItem2__c,
            CustomItem3__c,
            CustomItem4__c,
            CustomItem5__c,
            CustomItem6__c,
            CustomItem7__c,
            CustomItem8__c
        FROM
            Account
        WHERE
            SystemModstamp > 1999-01-01T00:00:00.000Z AND
            SystemModstamp <= 2000-01-01T00:00:00.000Z
        """

        print('actual', actual)
        print('expect', expect)

        assert actual.replace('\n', '').replace(' ', '') == expect.replace('\n', '').replace(' ', '')

    @pytest.mark.skip('データ取得用のSOQLがカラムがない状態は、TargetObjectクラス側で制御されるため、テストを実施しない')
    def test_raise_create_fetch_soql_cause_no_columns(self):
        """
        Cases:
            データ取得用のSOQLがカラムがない状態で生成されること
        Arranges:
            SOQL生成用のパラメータを用意する
        Expects:
            取得対象のカラムがないSOQLが生成されること
        """
        test_target_object_json = {
            'object_name': 'Account',
            'columns': []
        }

        test_last_fetch_datetime_json = {
            'last_fetch_datetime_from': '1999-01-01T00:00:00.000Z',
            'last_fetch_datetime_to': '2000-01-01T00:00:00.000Z',
        }

        execute_datetime = ExecuteDateTime()
        target_object = TargetObject(test_target_object_json, execute_datetime)
        test_last_fetch_datetime = LastFetchDatetime(test_last_fetch_datetime_json, execute_datetime)

        sut = SOQLBuilder(target_object, test_last_fetch_datetime)
        actual = sut.create_fetch_soql()

        # TargetObjectのバリデーションで、columnsが空の場合はエラーになるため、本来は発生しない
        expect = """SELECT
        FROM
            Account
        WHERE
            SystemModstamp > 1999-01-01T00:00:00.000Z AND
            SystemModstamp <= 2000-01-01T00:00:00.000Z
        """

        print('actual', actual)
        print('expect', expect)

        assert actual.replace('\n', '').replace(' ', '') == expect.replace('\n', '').replace(' ', '')
