class User(BaseModel):
    email = EmailField(api_name='Email', required=True)
    kyc_level = CharField(api_name='KYCLevel', choices=constants.KYC_LEVEL, default=constants.KYC_LEVEL.light)

    def fixed_kwargs(self):
        return {"user_id": self.id}

    class Meta:
        verbose_name = 'user'
        verbose_name_plural = 'users'
        url = '/users'

    def __init__(self, *args, **kwargs):
        super(User, self).__init__(*args, **kwargs)
        self.disputes = RelatedManager(self, Dispute)

    @classmethod
    def cast(cls, result):
        if 'PersonType' in result:
            if result['PersonType'] == 'NATURAL':
                return NaturalUser
            elif result['PersonType'] == 'LEGAL':
                return LegalUser

        return cls

    def get_emoney(self, *args, **kwargs):
        kwargs['user_id'] = self.id
        select = SelectQuery(EMoney, *args, **kwargs)
        if kwargs.__contains__('month') and kwargs.__contains__('year'):
            select.identifier = 'FOR_MONTH'
        elif kwargs.__contains__('year'):
            select.identifier = 'FOR_YEAR'
        else:
            select.identifier = 'ALL'
        return select.all(*args, **kwargs)

    def get_pre_authorizations(self, *args, **kwargs):
        kwargs['id'] = self.id
        select = SelectQuery(PreAuthorization, *args, **kwargs)
        select.identifier = 'USER_GET_PREAUTHORIZATIONS'
        return select.all(*args, **kwargs)

    def get_block_status(self, *args, **kwargs):
        kwargs['user_id'] = self.id
        select = SelectQuery(UserBlockStatus, *args, **kwargs)
        select.identifier = 'USERS_BLOCK_STATUS'
        return select.get("", *args, **kwargs)

    def get_regulatory(self, *args, **kwargs):
        kwargs['user_id'] = self.id
        select = SelectQuery(UserBlockStatus, *args, **kwargs)
        select.identifier = 'USERS_REGULATORY'
        return select.get("", *args, **kwargs)

    def __str__(self):
        return '%s' % self.email class NaturalUser(User):
    person_type = CharField(api_name='PersonType',
                            choices=constants.USER_TYPE_CHOICES,
                            default=constants.USER_TYPE_CHOICES.natural,
                            required=True)
    first_name = CharField(api_name='FirstName', required=True)
    last_name = CharField(api_name='LastName', required=True)
    address = AddressField(api_name='Address')
    birthday = DateField(api_name='Birthday')
    nationality = CharField(api_name='Nationality', required=True)
    country_of_residence = CharField(api_name='CountryOfResidence', required=True)
    occupation = CharField(api_name='Occupation')
    income_range = CharField(api_name='IncomeRange')
    proof_of_identity = CharField(api_name='ProofOfIdentity')
    proof_of_address = CharField(api_name='ProofOfAddress')
    capacity = CharField(api_name='Capacity', choices=constants.NATURAL_USER_CAPACITY_CHOICES)

    class Meta:
        verbose_name = 'user'
        verbose_name_plural = 'users'
        url = '/users/natural'

    def __str__(self):
        return '%s' % self.email class Wallet(BaseModel):
    owners = ManyToManyField(User, api_name='Owners', related_name='wallets', required=True)
    description = CharField(api_name='Description', required=True)
    currency = CharField(api_name='Currency', required=True)
    balance = MoneyField(api_name='Balance')
    creation_date = DateTimeField(api_name='CreationDate')

    class Meta:
        verbose_name = 'wallet'
        verbose_name_plural = 'wallets'
        url = '/wallets'

    def __init__(self, *args, **kwargs):
        super(Wallet, self).__init__(*args, **kwargs)
        self.disputes = RelatedManager(self, Dispute)

    def __str__(self):
        return 'Wallet n.%s' % self.id

    @classmethod
    def is_client_wallet(cls, obj):
        if isinstance(obj, Wallet) or isinstance(obj, ClientWallet):
            test_id = obj.id
        elif isinstance(obj, str):
            test_id = obj
        else:
            return False
        if test_id.startswith('FEES_') or \
                test_id.startswith('DEFAULT_') or \
                test_id.startswith('CREDIT_'):
            return True
        return False

    @classmethod
    def get(cls, *args, **kwargs):
        if len(args) == 1 and cls.is_client_wallet(args[0]):
            return ClientWallet.get(*tuple(args[0].split('_')), **kwargs)
        return super(Wallet, cls).get(*args, **kwargs) class LegalUser(User):
    person_type = CharField(api_name='PersonType',
                            choices=constants.USER_TYPE_CHOICES,
                            default=constants.USER_TYPE_CHOICES.legal,
                            required=True)
    name = CharField(api_name='Name', required=True)
    legal_person_type = CharField(api_name='LegalPersonType',
                                  choices=constants.LEGAL_USER_TYPE_CHOICES,
                                  default=constants.LEGAL_USER_TYPE_CHOICES.organization,
                                  required=True)
    headquarters_address = AddressField(api_name='HeadquartersAddress')
    legal_representative_first_name = CharField(api_name='LegalRepresentativeFirstName', required=True)
    legal_representative_last_name = CharField(api_name='LegalRepresentativeLastName', required=True)
    legal_representative_address = AddressField(api_name='LegalRepresentativeAddress')
    legal_representative_email = EmailField(api_name='LegalRepresentativeEmail')
    legal_representative_birthday = DateField(api_name='LegalRepresentativeBirthday', required=True)
    legal_representative_nationality = CharField(api_name='LegalRepresentativeNationality', required=True)
    legal_representative_country_of_residence = CharField(api_name='LegalRepresentativeCountryOfResidence',
                                                          required=True)
    legal_representative_proof_of_identity = CharField(api_name='LegalRepresentativeProofOfIdentity')
    statute = CharField(api_name='Statute')
    proof_of_registration = CharField(api_name='ProofOfRegistration')
    shareholder_declaration = CharField(api_name='ShareholderDeclaration')
    company_number = CharField(api_name='CompanyNumber')

    class Meta:
        verbose_name = 'user'
        verbose_name_plural = 'users'
        url = '/users/legal'

    def __str__(self):
        return '%s' % self.email class Transfer(BaseModel):
    author = ForeignKeyField(User, api_name='AuthorId', required=True)
    credited_user = ForeignKeyField(User, api_name='CreditedUserId', required=True, related_name='credited_users')
    debited_funds = MoneyField(api_name='DebitedFunds', required=True)
    fees = MoneyField(api_name='Fees', required=True)
    debited_wallet = ForeignKeyField(Wallet, api_name='DebitedWalletId')
    credited_wallet = ForeignKeyField(Wallet, api_name='CreditedWalletId', required=True)
    creation_date = DateTimeField(api_name='CreationDate')
    credited_funds = MoneyField(api_name='CreditedFunds')
    status = CharField(api_name='Status',
                       choices=constants.STATUS_CHOICES,
                       default=None)
    result_code = CharField(api_name='ResultCode')
    result_message = CharField(api_name='ResultMessage')
    execution_date = DateTimeField(api_name='ExecutionDate')

    def get_refunds(self, *args, **kwargs):
        kwargs['id'] = self.id
        select = SelectQuery(Refund, *args, **kwargs)
        select.identifier = 'TRANSFER_GET_REFUNDS'
        return select.all(*args, **kwargs)

    class Meta:
        verbose_name = 'transfer'
        verbose_name_plural = 'transfers'
        url = '/transfers'

    def __str__(self):
        return 'Transfer from wallet %s to wallet %s' % (self.debited_wallet_id, self.credited_wallet_id) class Transaction(BaseModel):
    author = ForeignKeyField(User, api_name='AuthorId', related_name='transactions')
    credited_user = ForeignKeyField(User, api_name='CreditedUserId')
    debited_funds = MoneyField(api_name='DebitedFunds')
    credited_funds = MoneyField(api_name='CreditedFunds')
    fees = MoneyField(api_name='Fees')
    status = CharField(api_name='Status', choices=constants.STATUS_CHOICES, default=None)
    result_code = CharField(api_name='ResultCode')
    result_message = CharField(api_name='ResultMessage')
    execution_date = DateTimeField(api_name='ExecutionDate')
    type = CharField(api_name='Type', choices=constants.TRANSACTION_TYPE_CHOICES, default=None)
    nature = CharField(api_name='Nature', choices=constants.NATURE_CHOICES, default=None)
    credited_wallet = ForeignKeyField(Wallet, api_name='CreditedWalletId')
    debited_wallet = ForeignKeyField(Wallet, api_name='DebitedWalletId')
    wallet = ForeignKeyField(Wallet, related_name='transactions')
    creation_date = DateTimeField(api_name='CreationDate')

    class Meta:
        verbose_name = 'transaction'
        verbose_name_plural = 'transactions'
        url = {
            SelectQuery.identifier: '/users/%(user_id)s/transactions',
            InsertQuery.identifier: '/users/%(user_id)s/transactions',
            UpdateQuery.identifier: '/users/%(user_id)s/transactions',
            'MANDATE_GET_TRANSACTIONS': '/mandates/%(id)s/transactions',
            'CARD_GET_TRANSACTIONS': '/cards/%(id)s/transactions',
            'BANK_ACCOUNT_GET_TRANSACTIONS': '/bankaccounts/%(id)s/transactions',
            'PRE_AUTHORIZATION_TRANSACTIONS': '/preauthorizations/%(id)s/transactions'
        }

    def __str__(self):
        return 'Transaction n.%s' % self.id class Money(object):
    __hash__ = None

    def __init__(self, amount="0", currency=None):
        try:
            self.amount = decimal.Decimal(amount)
        except decimal.InvalidOperation:
            raise ValueError("amount value could not be converted to "
                             "Decimal(): '{}'".format(amount))
        self.currency = currency

    def __repr__(self):
        return "{} {}".format(self.currency, self.amount)

    def __str__(self):
        return force_text("{} {:,.2f}".format(self.currency, self.amount))

    def __lt__(self, other):
        if isinstance(other, Money):
            if other.currency != self.currency:
                raise CurrencyMismatch(self.currency, other.currency, '<')
            other = other.amount
        return self.amount < other

    def __le__(self, other):
        if isinstance(other, Money):
            if other.currency != self.currency:
                raise CurrencyMismatch(self.currency, other.currency, '<=')
            other = other.amount
        return self.amount <= other

    def __eq__(self, other):
        if isinstance(other, Money):
            return ((self.amount == other.amount) and
                    (self.currency == other.currency))
        return False

    def __ne__(self, other):
        return not self == other

    def __gt__(self, other):
        if isinstance(other, Money):
            if other.currency != self.currency:
                raise CurrencyMismatch(self.currency, other.currency, '>')
            other = other.amount
        return self.amount > other

    def __ge__(self, other):
        if isinstance(other, Money):
            if other.currency != self.currency:
                raise CurrencyMismatch(self.currency, other.currency, '>=')
            other = other.amount
        return self.amount >= other

    def __bool__(self):
        return bool(self.amount)

    def __add__(self, other):
        if isinstance(other, Money):
            if other.currency != self.currency:
                raise CurrencyMismatch(self.currency, other.currency, '+')
            other = other.amount
        amount = self.amount + other
        return self.__class__(amount, self.currency)

    def __radd__(self, other):
        return self.__add__(other)

    def __sub__(self, other):
        if isinstance(other, Money):
            if other.currency != self.currency:
                raise CurrencyMismatch(self.currency, other.currency, '-')
            other = other.amount
        amount = self.amount - other
        return self.__class__(amount, self.currency)

    def __rsub__(self, other):
        return (-self).__add__(other)

    def __mul__(self, other):
        if isinstance(other, Money):
            raise TypeError("multiplication is unsupported between "
                            "two money objects")
        amount = self.amount * other
        return self.__class__(amount, self.currency)

    def __rmul__(self, other):
        return self.__mul__(other)

    def __truediv__(self, other):
        if isinstance(other, Money):
            if other.currency != self.currency:
                raise CurrencyMismatch(self.currency, other.currency, '/')

            if other.amount == 0:
                raise ZeroDivisionError()

            return self.amount / other.amount

        if other == 0:
            raise ZeroDivisionError()

        amount = self.amount / other

        return self.__class__(amount, self.currency)

    def __floordiv__(self, other):
        if isinstance(other, Money):
            if other.currency != self.currency:
                raise CurrencyMismatch(self.currency, other.currency, '//')

            if other.amount == 0:
                raise ZeroDivisionError()
            return self.amount // other.amount

        if other == 0:
            raise ZeroDivisionError()

        amount = self.amount // other
        return self.__class__(amount, self.currency)

    def __mod__(self, other):
        if isinstance(other, Money):
            raise TypeError("modulo is unsupported between two '{}' "
                            "objects".format(self.__class__.__name__))
        if other == 0:
            raise ZeroDivisionError()

        amount = self.amount % other
        return self.__class__(amount, self.currency)

    def __divmod__(self, other):
        if isinstance(other, Money):
            if other.currency != self.currency:
                raise CurrencyMismatch(self.currency, other.currency, 'divmod')

            if other.amount == 0:
                raise ZeroDivisionError()

            return divmod(self.amount, other.amount)

        if other == 0:
            raise ZeroDivisionError()

        whole, remainder = divmod(self.amount, other)

        return (self.__class__(whole, self.currency),
                self.__class__(remainder, self.currency))

    def __pow__(self, other):
        if isinstance(other, Money):
            raise TypeError("power operator is unsupported between two '{}' "
                            "objects".format(self.__class__.__name__))
        amount = self.amount ** other
        return self.__class__(amount, self.currency)

    def __neg__(self):
        return self.__class__(-self.amount, self.currency)

    def __pos__(self):
        return self.__class__(+self.amount, self.currency)

    def __abs__(self):
        return self.__class__(abs(self.amount), self.currency)

    def __int__(self):
        return int(self.amount)

    def __float__(self):
        return float(self.amount)

    def __round__(self, ndigits=0):
        return self.__class__(round(self.amount, ndigits), self.currency) class Address(object):
    def __init__(self, address_line_1=None, address_line_2=None, city=None, region=None,
                 postal_code=None, country=None):
        self.address_line_1 = address_line_1
        self.address_line_2 = address_line_2
        self.city = city
        self.region = region
        self.postal_code = postal_code
        self.country = country

    def __str__(self):
        return 'Address: %s, %s , %s, %s, %s , %s' % \
               (self.address_line_1, self.address_line_2, self.postal_code, self.city, self.region, self.country)

    def __eq__(self, other):
        if isinstance(other, Address):
            stat = ((self.address_line_1 == other.address_line_1) and
                    (self.address_line_2 == other.address_line_2) and
                    (self.postal_code == other.postal_code) and
                    (self.city == other.city) and
                    (self.region == other.region) and
                    (self.country == other.country))
            return stat
        return False

    def to_api_json(self):
        return {
            "AddressLine1": self.address_line_1,
            "AddressLine2": self.address_line_2,
            "PostalCode": self.postal_code,
            "City": self.city,
            "Region": self.region,
            "Country": self.country,
        }     MANGOPAY_CLIENT_ID = 'sdk-unit-tests'
    MANGOPAY_APIKEY = 'cqFfFrWfCcb7UadHNxx2C9Lo6Djw8ZduLi7J9USTmu8bhxxpju'
    MANGOPAY_API_URL = 'https://api.mangopay.com/v2.01/'
    MANGOPAY_API_SANDBOX_URL = 'https://api.sandbox.mangopay.com/v2.01/'
    MANGOPAY_USE_SANDBOX = True
    MANGOPAY_API_VERSION = 2
MOCK_TESTS_RESPONSES = True def get_fixture(name):
    def setUp(self):
    def register_mock(self, data):
    def mock_oauth(self):
    def mock_natural_user(self):
    def mock_legal_user(self):
    def mock_declarative_user(self):
    def mock_user_wallet(self):
    def mock_natural_user_wallet(self):
    def mock_legal_user_wallet(self):
    def mock_natural_user_wallet_9(self):
    def mock_legal_user_wallet_89(self):
    def mock_legal_user_wallet_99(self):
    def mock_card(self):
    def mock_tokenization_request(self):
    def mock_user_list_full(self):
    def mock_user_list_2_per_page_page1(self):
    def mock_user_list_3_per_page_page2(self):
    def mock_user_list_page1(self):
    def mock_user_list_2_per_page(self):
    def mock_ubo_declaration(self):
    def mock_list_ubo_declarations(self):
    def mock_get_ubo_declaration(self):
    def mock_ubo_creation(self):
    def mock_get_ubo(self):
    def mock_submit_ubo_declaration(self):
    def mock_update_ubo(self):
class RegisteredMocks(unittest.TestCase): class BaseTest(RegisteredMocks):
    @fixture
    def natural_user(self):
        natural_user_params = {
            "first_name": "Victor",
            "last_name": "Hugo",
            "address": Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
                               city='City', region='Region',
                               postal_code='11222', country='FR'),
            "birthday": time.mktime(date.today().timetuple()),
            "nationality": "FR",
            "country_of_residence": "FR",
            "occupation": "Writer",
            "income_range": 6,
            "proof_of_identity": None,
            "proof_of_address": None,
            "person_type": "NATURAL",
            "email": "victor@hugo.com",
            "tag": "Python SDK Unit Test",
        }
        natural_user = NaturalUser(**natural_user_params)
        natural_user.save()

        return natural_user

    @fixture
    def legal_user(self):
        legal_user_params = {
            "name": "MangoPay",
            "legal_person_type": "BUSINESS",
            "headquarters_address": Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
                                            city='City', region='Region',
                                            postal_code='11222', country='FR'),
            "legal_representative_first_name": "Mango",
            "legal_representative_last_name": "Pay",
            "legal_representative_email": "mango@mangopay.com",
            "legal_representative_birthday": time.mktime(date.today().timetuple()),
            "legal_representative_nationality": "FR",
            "legal_representative_country_of_residence": "FR",
            "proof_of_registration": None,
            "shareholder_declaration": None,
            "legal_representative_address": None,
            "statute": None,
            "person_type": "LEGAL",
            "email": "info@mangopay.com",
            "tag": "Python SDK Unit Test",
            # "creation_date": datetime.now()
        }
        legal_user = LegalUser(**legal_user_params)
        legal_user.save()

        return legal_user

    @fixture
    def legal_user_wallet(self):
        legal_user_wallet_params = {
            'tag': 'My custom tag',
            'owners': [self.legal_user],
            'description': 'Wallet of Victor Hugo',
            'currency': 'EUR'
        }

        legal_user_wallet = Wallet(**legal_user_wallet_params)
        legal_user_wallet.save()

        return legal_user_wallet

    @fixture
    def natural_user_wallet(self):
        natural_user_wallet_params = {
            'tag': 'My custom tag',
            'owners': [self.natural_user],
            'description': 'Wallet of Victor Hugo',
            'currency': 'EUR'
        }

        natural_user_wallet = Wallet(**natural_user_wallet_params)
        natural_user_wallet.save()

        return natural_user_wallet

    @fixture
    def card(self):
        card_params = {
            "user": self.natural_user,
            "currency": 'EUR'
        }
        card_registration = CardRegistration(**card_params)
        card_registration.save()

        self.mock_tokenization_request()

        response = requests.post(card_registration.card_registration_url, data={
            'cardNumber': '4970100000000154',
            'cardCvx': '123',
            'cardExpirationDate': '0124',
            'accessKeyRef': card_registration.access_key,
            'data': card_registration.preregistration_data
        })

        card_registration.registration_data = response.content
        card_registration.save()

        card = Card.get(card_registration.card.get_pk())

        return card

    @fixture
    def natural_user_card(self):
        card_params = {
            "user": self.natural_user,
            "currency": 'EUR'
        }
        card_registration = CardRegistration(**card_params)
        card_registration.save()

        self.mock_tokenization_request()

        response = requests.post(card_registration.card_registration_url, data={
            'cardNumber': '4970101122334422',
            'cardCvx': '123',
            'cardExpirationDate': '0124',
            'accessKeyRef': card_registration.access_key,
            'data': card_registration.preregistration_data
        })

        card_registration.registration_data = response.content
        card_registration.save()

        card = Card.get(card_registration.card.get_pk())

        return card

    @fixture
    def legal_user_card(self):
        card_params = {
            "user": self.legal_user,
            "currency": 'EUR'
        }
        card_registration = CardRegistration(**card_params)
        card_registration.save()

        self.mock_tokenization_request()

        response = requests.post(card_registration.card_registration_url, data={
            'cardNumber': '4970101122334406',
            'cardCvx': '123',
            'cardExpirationDate': '0124',
            'accessKeyRef': card_registration.access_key,
            'data': card_registration.preregistration_data
        })

        card_registration.registration_data = response.content
        card_registration.save()

        card = Card.get(card_registration.card.get_pk())

        return card

    @fixture
    def legal_user_ubo_declaration(self):
        self.mock_declarative_user()
        self.mock_ubo_declaration()

        params = {
            "first_name": "Victor",
            "last_name": "Hugo",
            "address": Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
                               city='City', region='Region',
                               postal_code='11222', country='FR'),
            "birthday": 1231432,
            "nationality": "FR",
            "country_of_residence": "FR",
            "occupation": "Writer",
            "income_range": 6,
            "proof_of_identity": None,
            "proof_of_address": None,
            "person_type": "NATURAL",
            "email": "victor@hugo.com",
            "tag": "Python SDK Unit Test",
            "capacity": "DECLARATIVE"
        }
        user = NaturalUser(**params)
        user.save()

        params = {
            "user": user,
            "creation_date": 1554803756
        }

        ubo_declaration = UboDeclaration(**params)
        ubo_declaration.save()
        return ubo_declaration, user

    @fixture
    def ubo_declaration_ubo(self):
        params = {
            "first_name": "Victor",
            "last_name": "Hugo",
            "address": Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
                               city='City', region='Region',
                               postal_code='11222', country='FR'),
            "birthday": 1231432,
            "nationality": "FR",
            "birthplace": Birthplace(city='Paris', country='FR')
        }
        ubo = Ubo(**params)
        return ubo class BaseTestLive(unittest.TestCase):
    _john = None
    _johns_account = None
    _johns_wallet = None
    _johns_kyc_document = None
    _oauth_manager = AuthorizationTokenManager(get_default_handler(), StaticStorageStrategy())
    _johns_report = None
    _johns_transfer = None
    _johns_payout = None
    _johns_payin = None
    _johns_card = None
    _johns_card_3dsecure = None

    _user_legal = None
    _ubo_declaration = None
    _ubo = None

    _client_account = None

    def setUp(self):
        BaseTestLive.get_john()
        BaseTestLive.get_user_legal()

    @staticmethod
    def get_user_legal(recreate=False):
        if BaseTestLive._user_legal is None or recreate:
            legal = LegalUser()
            legal.name = 'MatrixSampleOrg_PythonSDK'
            legal.email = 'mail@test.com'
            legal.legal_person_type = "BUSINESS"
            legal.legal_representative_first_name = "Mango"
            legal.legal_representative_last_name = 'Pay'
            legal.legal_representative_email = 'mango@mangopay.com'
            legal.person_type = 'LEGAL'
            legal.headquarters_address = Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
                                                 city='City', region='Region',
                                                 postal_code='11222', country='FR')
            legal.legal_representative_birthday = 1300186358
            legal.legal_representative_nationality = 'FR'
            legal.legal_representative_country_of_residence = 'FR'
            legal.company_number = 123456789
            legal.tag = 'Python SDK Unit Test'
            BaseTestLive._user_legal = LegalUser(**legal.save())
        return BaseTestLive._user_legal

    @staticmethod
    def get_ubo_declaration(recreate=False):
        if BaseTestLive._ubo_declaration is None or recreate:
            legal_user = BaseTestLive.get_user_legal()
            params = {
                "user_id": legal_user.id
            }
            BaseTestLive._ubo_declaration = UboDeclaration(**UboDeclaration().create(**params))
        return BaseTestLive._ubo_declaration

    @staticmethod
    def get_ubo(recreate=False):
        if BaseTestLive._ubo is None or recreate:
            address = Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
                              city='City', region='Region',
                              postal_code='11222', country='FR')
            params = {
                "user": BaseTestLive.get_user_legal(True),
                "ubo_declaration": BaseTestLive.get_ubo_declaration(True),
                "first_name": "Victor",
                "last_name": "Hugo",
                "address": address,
                "birthday": date(1970, 1, 15),
                "nationality": "FR",
                "birthplace": Birthplace(city='Paris', country='FR'),
                "isActive": True
            }
            BaseTestLive._ubo = Ubo.create(**params)
        return BaseTestLive._ubo

    @staticmethod
    def get_johns_report(recreate=False):
        if BaseTestLive._johns_report is None or recreate:
            report = ReportTransactions()
            report.report_type = 'transactions'
            report.filters = ReportTransactionsFilters()
            report.filters.author_id = BaseTestLive._john.id
            BaseTestLive._johns_report = ReportTransactions(**report.save())
        return BaseTestLive._johns_report

    @staticmethod
    def get_johns_account(recreate=False):
        if BaseTestLive._johns_account is None or recreate:
            account = BankAccount()
            account.owner_name = BaseTestLive._john.first_name + ' ' + BaseTestLive._john.last_name
            account.user = BaseTestLive._john
            account.type = 'IBAN'
            account.owner_address = BaseTestLive._john.address
            account.iban = 'FR7630004000031234567890143'
            account.bic = 'BNPAFRPP'
            BaseTestLive._johns_account = BankAccount(**account.save())
        return BaseTestLive._johns_account

    @staticmethod
    def get_client_bank_account(recreate=False):
        if BaseTestLive._client_account is None or recreate:
            account = BankAccount()
            account.owner_name = 'Joe Blogs'
            account.type = 'IBAN'

            account.owner_address = Address()
            account.owner_address.address_line_1 = "Main Street"
            account.owner_address.address_line_2 = "no. 5 ap. 6"
            account.owner_address.country = "FR"
            account.owner_address.city = "Lyon"
            account.owner_address.postal_code = "65400"

            account.iban = 'FR7630004000031234567890143'
            account.bic = 'BNPAFRPP'
            account.tag = 'custom meta'

            account.create_client_bank_account()

            BaseTestLive._client_account = BankAccount(**account.create_client_bank_account())

        return BaseTestLive._client_account

    @staticmethod
    def get_john(recreate=False):
        if BaseTestLive._john is None or recreate:
            user = NaturalUser()
            user.first_name = 'John'
            user.last_name = 'Doe'
            user.birthday = 188352000
            user.email = "john.doe@sample.org"
            user.address = Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
                                   city='City', region='Region',
                                   postal_code='11222', country='FR')
            user.nationality = 'FR'
            user.country_of_residence = 'FR'
            user.occupation = 'programmer'
            user.income_range = '1'
            user.person_type = 'NATURAL'
            BaseTestLive._john = NaturalUser(**user.save())
        return BaseTestLive._john

    @staticmethod
    def get_johns_kyc_document(recreate=False):
        if BaseTestLive._johns_kyc_document is None or recreate:
            document = Document()
            document.type = 'IDENTITY_PROOF'
            document.user_id = BaseTestLive.get_john().id
            BaseTestLive._johns_kyc_document = Document(**document.save())
        return BaseTestLive._johns_kyc_document

    @staticmethod
    def get_johns_wallet(recreate=False):
        if BaseTestLive._johns_wallet is None or recreate:
            BaseTestLive._johns_wallet = BaseTestLive.create_new_wallet()
        return BaseTestLive._johns_wallet

    @staticmethod
    def create_new_wallet():
        wallet = Wallet()
        wallet.owners = (BaseTestLive._john,)
        wallet.currency = 'EUR'
        wallet.description = 'WALLET IN EUR'
        return Wallet(**wallet.save())

    @staticmethod
    def get_johns_transfer(recreate=False):
        if BaseTestLive._johns_transfer is None or recreate:
            john = BaseTestLive.get_john()
            wallet1 = BaseTestLive.get_johns_wallet()
            wallet2 = BaseTestLive.create_new_wallet()

            transfer = Transfer()
            transfer.author = john
            transfer.tag = 'DefaultTag'
            transfer.credited_user = john
            transfer.debited_funds = Money(amount=1, currency='EUR')
            transfer.fees = Money(amount=0, currency='EUR')
            transfer.debited_wallet = wallet1
            transfer.credited_wallet = wallet2
            BaseTestLive._johns_transfer = Transfer(**transfer.save())
        return BaseTestLive._johns_transfer

    @staticmethod
    def get_johns_payout(recreate=False):
        if BaseTestLive._johns_payout is None or recreate:
            john = BaseTestLive.get_john()
            wallet = BaseTestLive.get_johns_wallet()
            account = BaseTestLive.get_johns_account()

            payout = BankWirePayOut()
            payout.debited_wallet = wallet
            payout.author = john
            payout.credited_user = john
            payout.tag = 'DefaultTag'
            payout.debited_funds = Money(amount=10, currency='EUR')
            payout.fees = Money(amount=5, currency='EUR')
            payout.bank_account = account
            payout.bank_wire_ref = 'User payment'
            payout.payment_type = 'BANK_WIRE'
            BaseTestLive._johns_payout = BankWirePayOut(**payout.save())
        return BaseTestLive._johns_payout

    @staticmethod
    def get_johns_payin(recreate=False):
        if BaseTestLive._johns_payin is None or recreate:
            wallet = BaseTestLive.get_johns_wallet()
            payin = CardWebPayIn()
            payin.credited_wallet = wallet
            payin.author = BaseTestLive.get_john()
            payin.debited_funds = Money(amount=10000, currency='EUR')
            payin.fees = Money(amount=0, currency='EUR')
            payin.card_type = 'CB_VISA_MASTERCARD'
            payin.return_url = 'https://test.com'
            payin.template_url = 'https://TemplateURL.com'
            payin.secure_mode = 'DEFAULT'
            payin.culture = 'fr'
            BaseTestLive._johns_payin = CardWebPayIn(**payin.save())
        return BaseTestLive._johns_payin

    @staticmethod
    def get_johns_card(recreate=False):
        if BaseTestLive._johns_card is None or recreate:
            card_params = {
                "user": BaseTestLive.get_john(),
                "currency": 'EUR'
            }
            card_registration = CardRegistration(**card_params)
            card_registration.save()

            params = {
                "data_XXX": card_registration.preregistration_data,
                "accessKeyRef": card_registration.access_key,
                "cardNumber": '4970101122334422',
                "cardExpirationDate": '1224',
                "cardCvx": '123'
            }
            response = APIRequest().custom_request('POST', card_registration.card_registration_url, None, None, False,
                                                   False, **params)
            card_registration.registration_data = response
            card_registration.save()
            BaseTestLive._johns_card = card_registration.card
        return BaseTestLive._johns_card

    @staticmethod
    def get_johns_card_3dsecure(recreate=False):
        if BaseTestLive._johns_card_3dsecure is None or recreate:
            card_params = {
                "user": BaseTestLive.get_john(),
                "currency": 'EUR'
            }
            card_registration = CardRegistration(**card_params)
            card_registration.save()

            params = {
                "data_XXX": card_registration.preregistration_data,
                "accessKeyRef": card_registration.access_key,
                "cardNumber": '4970105191923460',
                "cardExpirationDate": '1224',
                "cardCvx": '123'
            }
            response = APIRequest().custom_request('POST', card_registration.card_registration_url, None, None, False,
                                                   False, **params)
            card_registration.registration_data = response
            card_registration.save()
            BaseTestLive._johns_card = card_registration.card
        return BaseTestLive._johns_card

    @staticmethod
    def get_oauth_manager():
        return BaseTestLive._oauth_manager

    def test_handler(self):
        api_url = "test_api_url"
        sandbox_url = "test_sandbox_url"

        sandbox_handler = APIRequest(
            api_sandbox_url=sandbox_url,
            api_url=api_url,
            sandbox=True)

        non_sandbox_handler = APIRequest(
            api_sandbox_url=sandbox_url,
            api_url=api_url,
            sandbox=False)

        self.assertEqual(api_url, non_sandbox_handler.api_url)
        self.assertEqual(sandbox_url, sandbox_handler.api_url)
import re
import requests
import responses
from mangopay.resources import (User, NaturalUser, Wallet,
                                LegalUser, Transfer, Transaction)
from mangopay.utils import Money, Address
from tests import settings
from tests.mocks import today, today_timestamp
from tests.test_base import BaseTest, BaseTestLive
        user.last_name = 'Claver'
        user.save()

        self.assertEqual(previous_pk, user.get_pk())

        self.assertEqual(user.last_name, 'Claver')

    @responses.activate
    def test_create_legal_user(self):
        self.mock_legal_user()

        self.register_mock({
            'method': responses.PUT,
            'url': re.compile(
                r'' + settings.MANGOPAY_API_SANDBOX_URL + settings.MANGOPAY_CLIENT_ID + '/users/legal/\d+'),
            'body': {
                "Name": "MangoPay edited",
                "LegalPersonType": "BUSINESS",
                "HeadquartersAddress": {
                    "AddressLine1": "AddressLine1",
                    "AddressLine2": "AddressLine2",
                    "City": "City",
                    "Region": "Region",
                    "PostalCode": "11222",
                    "Country": "FR"
                },
                "LegalRepresentativeFirstName": "Mango",
                "LegalRepresentativeLastName": "Pay",
                "LegalRepresentativeEmail": "mango@mangopay.com",
                "LegalRepresentativeBirthday": today_timestamp,
                "LegalRepresentativeNationality": "FR",
                "LegalRepresentativeCountryOfResidence": "FR",
                "PersonType": "LEGAL",
                "Email": "info@mangopay.com",
                "Id": "1169420",
                "Tag": "custom tag",
                "CreationDate": 1383322502,
                "KYCLevel": "LIGHT"
            },
            'status': 200
        })

        params = {
            "name": "MangoPay",
            "legal_person_type": "BUSINESS",
            "headquarters_address": Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
                                            city='City', region='Region',
                                            postal_code='11222', country='FR'),
            "legal_representative_first_name": "Mango",
            "legal_representative_last_name": "Pay",
            "legal_representative_email": "mango@mangopay.com",
            "legal_representative_birthday": today,
            "legal_representative_nationality": "FR",
            "legal_representative_country_of_residence": "FR",
            "proof_of_registration": None,
            "shareholder_declaration": None,
            "legal_representative_address": None,
            "statute": None,
            "person_type": "LEGAL",
            "email": "info@mangopay.com",
            "tag": "custom tag",
            # "creation_date": datetime.now()
        }
        user = LegalUser(**params)

        self.assertIsNone(user.get_pk())
        user.save()
        self.assertIsInstance(user, LegalUser)

        for key, value in params.items():
            self.assertEqual(getattr(user, key), value)

        self.assertIsNotNone(user.get_pk())

        previous_pk = user.get_pk()

        user.last_name = 'Claver'
        user.save()

        self.assertEqual(previous_pk, user.get_pk())

        self.assertEqual(user.last_name, 'Claver')

    @responses.activate
    def test_retrieve_natural_user(self):
        self.mock_natural_user()

        self.register_mock([
            {
                'method': responses.GET,
                'url': settings.MANGOPAY_API_SANDBOX_URL + settings.MANGOPAY_CLIENT_ID + '/users/natural/1169419',
                'body': {
                    "FirstName": "Victor",
                    "LastName": "Hugo",
                    "Address": {
                        "AddressLine1": "AddressLine1",
                        "AddressLine2": "AddressLine2",
                        "City": "City",
                        "Region": "Region",
                        "PostalCode": "11222",
                        "Country": "FR"
                    },
                    "Birthday": today_timestamp,
                    "Nationality": "FR",
                    "CountryOfResidence": "FR",
                    "Occupation": "Writer",
                    "IncomeRange": 6,
                    "ProofOfIdentity": None,
                    "ProofOfAddress": None,
                    "PersonType": "NATURAL",
                    "Email": "victor@hugo.com",
                    "Id": "1169419",
                    "Tag": "custom tag",
                    "CreationDate": 1383321421,
                    "KYCLevel": "LIGHT"
                },
                'status': 200
            },
            {
                'method': responses.GET,

                'url': settings.MANGOPAY_API_SANDBOX_URL + settings.MANGOPAY_CLIENT_ID + '/users/natural/1169420',