def test_switch_account(self): with open('tests/data/switch.json', 'r') as file: response_body = json.loads(file.read()) responses.add(responses.POST, 'https://demo-api.ig.com/gateway/deal/session', headers={ 'CST': 'abc123', 'X-SECURITY-TOKEN': 'xyz987' }, json=response_body, status=200) responses.add(responses.PUT, 'https://demo-api.ig.com/gateway/deal/session', headers={ 'CST': 'abc123', 'X-SECURITY-TOKEN': 'xyz987' }, json=response_body, status=200) ig_service = IGService('username', 'password', 'api_key', 'DEMO') ig_service.create_session() result = ig_service.switch_account(account_id='XYZ987', default_account=True) assert result['trailingStopsEnabled'] is True assert result['dealingEnabled'] is True
def test_session_details(self): with open('tests/data/session.json', 'r') as file: response_body = json.loads(file.read()) responses.add(responses.POST, 'https://demo-api.ig.com/gateway/deal/session', headers={ 'CST': 'abc123', 'X-SECURITY-TOKEN': 'xyz987' }, json=response_body, status=200) responses.add(responses.GET, 'https://demo-api.ig.com/gateway/deal/session', headers={ 'CST': 'abc123', 'X-SECURITY-TOKEN': 'xyz987' }, json=response_body, status=200) ig_service = IGService('username', 'password', 'api_key', 'DEMO') ig_service.create_session() result = ig_service.read_session() assert result['clientId'] == '100112233' assert result['accountId'] == 'ABC123' assert result['currency'] == 'GBP'
def test_logout(self, retrying): ig_service = IGService(config.username, config.password, config.api_key, config.acc_type, retryer=retrying) ig_service.create_session() ig_service.logout() with pytest.raises(Exception) as error: print(error) ig_service.fetch_accounts()
def test_create_session_bad_api_key(self, retrying): ig_service = IGService(config.username, config.password, 'wrong', config.acc_type, retryer=retrying) with pytest.raises(IGException): ig_service.create_session()
def test_create_session_v3_no_acc_num(self, retrying): ig_service = IGService(config.username, config.password, config.api_key, config.acc_type, retryer=retrying) with pytest.raises(IGException): ig_service.create_session(version='3')
def test_create_session_v3(self, retrying): ig_service = IGService(config.username, config.password, config.api_key, config.acc_type, acc_number=config.acc_number, retryer=retrying) ig_service.create_session(version='3') assert 'X-IG-API-KEY' in ig_service.session.headers assert 'Authorization' in ig_service.session.headers assert 'IG-ACCOUNT-ID' in ig_service.session.headers assert len(ig_service.fetch_accounts()) == 2
def test_create_session_encrypted_password(self, retrying): ig_service = IGService(config.username, config.password, config.api_key, config.acc_type, retryer=retrying) ig_service.create_session(encryption=True) assert 'CST' in ig_service.session.headers
def ig_service(): """test fixture logs into IG with the configured credentials""" if config.acc_type == 'LIVE': pytest.fail( 'this integration test should not be executed with a LIVE account') ig_service = IGService(config.username, config.password, config.api_key, config.acc_type) ig_service.create_session() return ig_service
def get_session(): ig_service = IGService( config.username, config.password, config.api_key, config.acc_type, acc_number=config.acc_number, retryer=DEFAULT_RETRY) ig_service.create_session(version='3') return ig_service
def ig_service(request, retrying): """test fixture logs into IG with the configured credentials. Tests both v2 and v3 types""" if config.acc_type == 'LIVE': pytest.fail( 'this integration test should not be executed with a LIVE account') ig_service = IGService(config.username, config.password, config.api_key, config.acc_type, acc_number=config.acc_number, retryer=retrying) ig_service.create_session(version=request.param) yield ig_service ig_service.logout()
def test_login_v1_encrypted_happy(): with open('tests/data/accounts.json', 'r') as file: response_body = json.loads(file.read()) responses.add( responses.GET, 'https://demo-api.ig.com/gateway/deal/session/encryptionKey', json={ 'encryptionKey': 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp9te7zwed8HhdRFsn47EI8exZ1Yi+bJoKtclGTiuaP1T+4AclNqB2mIya/Ik6IV6A2pt4FFVoqvrhJA46dWi4XgA4Ojhl2Xxw4++blAMgT3jU7N5nY13LdJzZuYv/oPZKRcEj6RrlBV68HjrTnjAMWARl0jFbVCiLWovTGJ0stx/zJAKX0GFyuUlsoaJISJJRYeOLUtZ8Z4BE6ZkmKnz4V8YNyyoWCyXQp+IKCZrfoEdlMOPBgsjbRy02Gh9xZqcm2erLsp40F+w3AjHUqQQi7eQuPQaPWq9Lhm8cVDH2CB2BtfM8Ew8T5/A36eqa5eoeQcZaMnLUQP5UYtG2Wd//wIDAQAB', 'timeStamp': '1601218928621' }, status=200) responses.add(responses.POST, 'https://demo-api.ig.com/gateway/deal/session', headers={'CST': 'abc123abc123abc123abc123abc123abc123'}, json=response_body, status=200) ig_service = IGService('username', 'password', 'api_key', 'DEMO') result = ig_service.create_session(encryption=True) assert result['accountType'] == 'SPREADBET' assert result['currentAccountId'] == 'ABC123' assert len(result['accounts']) == 2 assert result['accounts'][1]['accountName'] == 'Demo-cfd' assert result['accounts'][1]['accountType'] == 'CFD' assert result['trailingStopsEnabled'] == True
def test_login_v1_happy(self): with open('tests/data/accounts.json', 'r') as file: response_body = json.loads(file.read()) responses.add(responses.POST, 'https://demo-api.ig.com/gateway/deal/session', headers={ 'CST': 'abc123', 'X-SECURITY-TOKEN': 'xyz987' }, json=response_body, status=200) ig_service = IGService('username', 'password', 'api_key', 'DEMO') result = ig_service.create_session() assert ig_service.crud_session.CLIENT_TOKEN == 'abc123' assert ig_service.crud_session.SECURITY_TOKEN == 'xyz987' assert result['accountType'] == 'SPREADBET' assert result['currentAccountId'] == 'ABC123' assert len(result['accounts']) == 2 assert result['accounts'][1]['accountName'] == 'Demo-cfd' assert result['accounts'][1]['accountType'] == 'CFD' assert result['trailingStopsEnabled'] is True
def test_session_v3_refresh(self, retrying): """ Tests refresh capability of v3 sessions. It makes repeated calls to the 'fetch_accounts' endpoint, with random sleep times in between, to show/test the different scenarios. Will take a long time to run """ ig_service = IGService(config.username, config.password, config.api_key, config.acc_type, acc_number=config.acc_number, retryer=retrying) ig_service.create_session(version='3') delay_choice = [(1, 59), (60, 650)] for count in range(1, 20): data = ig_service.fetch_accounts() logging.info(f"Account count: {len(data)}") option = choice(delay_choice) wait = randint(option[0], option[1]) logging.info(f"Waiting for {wait} seconds...") time.sleep(wait)
def ig_service(request, retrying): """test fixture logs into IG with the configured credentials. Tests both v2 and v3 types""" if config.acc_type == 'LIVE': pytest.fail('this integration test should not be executed with a LIVE account') ig_service = IGService(config.username, config.password, config.api_key, config.acc_type, acc_number=config.acc_number, retryer=retrying) service = ig_service.create_session(version=request.param) if request.param == '2' and service['accountType'] != 'SPREADBET': pytest.fail('Integration test currently only works with a spreadbet account') yield ig_service ig_service.logout()
def test_login_v2_encrypted_bad_key(): responses.add(responses.GET, 'https://demo-api.ig.com/gateway/deal/session/encryptionKey', json={'errorCode': 'error.security.api-key-invalid'}, status=403) ig_service = IGService('username', 'password', 'api_key', 'DEMO') with pytest.raises(IGException): result = ig_service.create_session(encryption=True) assert result['errorCode'] == 'error.security.api-key-invalid'
def test_login_v1_bad_api_key(self): responses.add(responses.POST, 'https://demo-api.ig.com/gateway/deal/session', headers={}, json={'errorCode': 'error.security.api-key-invalid'}, status=403) ig_service = IGService('username', 'password', 'api_key', 'DEMO') with pytest.raises(Exception): result = ig_service.create_session(version='1') assert result['errorCode'] == 'error.security.api-key-invalid'
def test_login_v1_bad_credentials(): responses.add(responses.POST, 'https://demo-api.ig.com/gateway/deal/session', headers={'CST': 'abc123abc123abc123abc123abc123abc123'}, json={'errorCode': 'error.security.invalid-details'}, status=401) ig_service = IGService('username', 'password', 'api_key', 'DEMO') with pytest.raises(Exception): result = ig_service.create_session() assert result['errorCode'] == 'error.security.invalid-details'
def test_login_v2_bad_credentials(self): responses.add(responses.POST, 'https://demo-api.ig.com/gateway/deal/session', headers={}, json={'errorCode': 'error.security.invalid-details'}, status=401) ig_service = IGService('username', 'password', 'api_key', 'DEMO') with pytest.raises(Exception): result = ig_service.create_session(version='2') assert result['errorCode'] == 'error.security.invalid-details' assert ig_service.crud_session.CLIENT_TOKEN is None assert ig_service.crud_session.SECURITY_TOKEN is None
def test_rate_limiter_non_trading_req(self): with open('tests/data/session.json', 'r') as file: session_response_body = json.loads(file.read()) responses.add(responses.POST, 'https://demo-api.ig.com/gateway/deal/session', headers={'CST': 'abc123', 'X-SECURITY-TOKEN': 'xyz987'}, json=session_response_body, status=200) responses.add(responses.GET, 'https://demo-api.ig.com/gateway/deal/session', headers={'CST': 'abc123', 'X-SECURITY-TOKEN': 'xyz987'}, json=session_response_body, status=200) with open('tests/data/application.json', 'r') as file: app_response_body = json.loads(file.read()) responses.add(responses.POST, 'https://demo-api.ig.com/gateway/deal/operations/application', headers={'CST': 'abc123', 'X-SECURITY-TOKEN': 'xyz987'}, json=app_response_body, status=200) responses.add(responses.GET, 'https://demo-api.ig.com/gateway/deal/operations/application', headers={'CST': 'abc123', 'X-SECURITY-TOKEN': 'xyz987'}, json=app_response_body, status=200) with open('tests/data/markets_epic.json', 'r') as file: mkts_epic_response_body = json.loads(file.read()) responses.add(responses.POST, 'https://demo-api.ig.com/gateway/deal/markets/CO.D.CFI.Month2.IP', headers={'CST': 'abc123', 'X-SECURITY-TOKEN': 'xyz987'}, json=mkts_epic_response_body, status=200) responses.add(responses.GET, 'https://demo-api.ig.com/gateway/deal/markets/CO.D.CFI.Month2.IP', headers={'CST': 'abc123', 'X-SECURITY-TOKEN': 'xyz987'}, json=mkts_epic_response_body, status=200) ig_service = IGService('username', 'password', 'api_key', 'DEMO', use_rate_limiter=True) ig_service.create_session() # empty the bucket queue (len=1), before we start timing things ig_service.fetch_market_by_epic('CO.D.CFI.Month2.IP') times = [] for i in range(3): time_last = time.time() ig_service.fetch_market_by_epic('CO.D.CFI.Month2.IP') times.append(time.time() - time_last) ig_service.logout() av_time = sum(times) / len(times) expected_av = 60.0 / app_response_body[0]['allowanceAccountOverall'] time_tolerance = 0.2 assert av_time >= expected_av assert av_time < expected_av + time_tolerance