def test_04_pg_create_with_portfolio_not_exist(self): """ Test description: ----------------- Here we test attempting to add a portfolio which does not exist to a portfolio group. Expected outcome: ----------------- We expect the entire request to fail with a PortfolioNotFound error. """ test_case_scope = create_scope_id() data_frame = self.csv_to_data_frame_with_scope( "data/port_group_tests/test_4_pg_create_with_portfolio_not_exist.csv", self.portfolio_scope, ) responses = self.cocoon_load_from_dataframe( scope=test_case_scope, data_frame=data_frame ) self.log_error_requests_title("portfolio_groups", responses) # Check that LUSID cannot find the portfolio self.assertEqual( json.loads(responses["portfolio_groups"]["errors"][0].body)["name"], "PortfolioNotFound", ) # Check there are no successful requests self.assertEqual(len(responses["portfolio_groups"]["success"]), 0)
def test_portfolio_missing_attribute(self): unique_id = create_scope_id() data_frame = pd.read_csv( Path(__file__).parent.joinpath(self.file_name)) data_frame["FundCode"] = data_frame["FundCode"] + "-" + unique_id mapping_required = {"code": "FundCode"} mapping_optional = { "description": "description", "created": "created", "base_currency": "base_currency", } with self.assertRaises(ValueError) as error: cocoon.cocoon.load_from_data_frame( api_factory=self.api_factory, scope=self.scope, data_frame=data_frame, mapping_required=mapping_required, mapping_optional=mapping_optional, file_type="reference_portfolio", identifier_mapping={}, property_columns=[], properties_scope=self.scope, sub_holding_keys=[], ) self.assertEqual( error.exception.args[0], """The required attributes {'display_name'} are missing from the mapping. Please add them.""", )
def setUpClass(cls) -> None: secrets_file = Path(__file__).parent.parent.parent.joinpath( "secrets.json") cls.api_factory = lusid.utilities.ApiClientFactory( api_secrets_filename=secrets_file) cls.alias = models.TransactionConfigurationTypeAlias( type=create_scope_id().replace("-", ""), description="TESTBUY1", transaction_class="TESTBUY1", transaction_group="SYSTEM1", transaction_roles="AllRoles", ) cls.movements = [ models.TransactionConfigurationMovementDataRequest( movement_types="StockMovement", side="Side1", direction=1, properties={}, mappings=[], ), models.TransactionConfigurationMovementDataRequest( movement_types="CashCommitment", side="Side2", direction=-1, properties={}, mappings=[], ), ] cls.response = create_transaction_type_configuration( cls.api_factory, cls.alias, cls.movements)
def setUpClass(cls) -> None: cls.scope = create_scope_id().replace("-", "_") cls.api_factory = lusid.utilities.ApiClientFactory( api_secrets_filename=secrets_file ) cls.sample_data = pd.read_csv(seed_sample_data_override_csv)
def setUpClass(cls) -> None: cls.portfolio_scope = create_scope_id() secrets_file = Path(__file__).parent.parent.parent.joinpath("secrets.json") cls.api_factory = lusid.utilities.ApiClientFactory( api_secrets_filename=secrets_file ) cls.unique_portfolios = pd.read_csv( Path(__file__).parent.joinpath( "data/port_group_tests/test_1_pg_create_with_portfolios.csv" ) )["FundCode"].tolist() def create_portfolio_model(code): model = models.CreateTransactionPortfolioRequest( display_name=code, code=code, base_currency="GBP", description="Paper transaction portfolio", created="2020-02-25T00:00:00Z", ) return model try: for code in cls.unique_portfolios: cls.api_factory.build( lusid.api.TransactionPortfoliosApi ).create_portfolio( scope=cls.portfolio_scope, create_transaction_portfolio_request=create_portfolio_model(code), ) except lusid.exceptions.ApiException as e: if e.status == 404: logger.error(f"The portfolio {code} already exists")
def test_11_pg_add_bad_and_good_portfolios(self): """ Test description: ----------------- Here we test updating a portfolio group with good and bad portfolios. Expected result: ----------------- Good portfolios should be added and bad ones not added. """ test_case_scope = create_scope_id() data_frame = self.csv_to_data_frame_with_scope( "data/port_group_tests/test_11_pg_add_bad_and_good_portfolios.csv", self.portfolio_scope, ) # Create the portfolio group as a seperate request port_group_request = lusid.models.CreatePortfolioGroupRequest( code=data_frame["PortGroupCode"][0], display_name=data_frame["PortGroupCode"][0], ) self.api_factory.build(lusid.api.PortfolioGroupsApi).create_portfolio_group( scope=test_case_scope, create_portfolio_group_request=port_group_request ) responses = self.cocoon_load_from_dataframe( scope=test_case_scope, data_frame=data_frame ) self.log_error_requests_title("portfolio_groups", responses) remove_dupe_df = data_frame[~data_frame["FundCode"].str.contains("BAD_PORT")] self.assertEqual( first=sorted( [ code.to_dict() for code in responses["portfolio_groups"]["success"][0].portfolios ], key=lambda item: item.get("code"), ), second=sorted( [ lusid.models.ResourceId( code=remove_dupe_df["FundCode"].tolist()[0], scope=self.portfolio_scope, ).to_dict(), lusid.models.ResourceId( code=remove_dupe_df["FundCode"].tolist()[1], scope=self.portfolio_scope, ).to_dict(), ], key=lambda item: item.get("code"), ), )
def test_05_pg_create_with_duplicate_portfolios(self): """ Test description: ----------------- Here we test attempting to add two of the same portfolios to a portfolio group. Expected result: ---------------- We expect that each unique portfolio gets added and duplicates should be ignored. """ test_case_scope = create_scope_id() data_frame = self.csv_to_data_frame_with_scope( "data/port_group_tests/test_5_pg_create_with_duplicate_portfolios.csv", self.portfolio_scope, ) responses = self.cocoon_load_from_dataframe(scope=test_case_scope, data_frame=data_frame) self.log_error_requests_title("portfolio_groups", responses) data_frame.drop_duplicates(inplace=True) # Check that there is a request for each unique portfolio self.assertEqual( len([ port_group for nested_group in [ port_group.portfolios for port_group in responses["portfolio_groups"]["success"] ] for port_group in nested_group ]), len(data_frame), ) # Check that a request is generated with unqiue portfolio only self.assertEqual( first=sorted( [ code.to_dict() for code in responses["portfolio_groups"] ["success"][0].portfolios ], key=lambda item: item.get("code"), ), second=sorted( [ lusid.models.ResourceId( code=data_frame["FundCode"][0], scope=data_frame["Scope"][0]).to_dict(), lusid.models.ResourceId( code=data_frame["FundCode"][1], scope=data_frame["Scope"][1]).to_dict(), ], key=lambda item: item.get("code"), ), )
def test_load_instrument_lookthrough_portfolio(self): code = create_scope_id() scope = "test-lookthrough" data_frame = pd.DataFrame({ "instrument_name": [ "Portfolio", ], "client_internal": [code], "lookthrough_code": [code], }) mapping = { "identifier_mapping": { "ClientInternal": "client_internal", }, "required": { "name": "instrument_name" }, "optional": { "look_through_portfolio_id.scope": f"${scope}", "look_through_portfolio_id.code": "lookthrough_code", }, } # create portfolio port_response = self.api_factory.build( lusid.api.TransactionPortfoliosApi).create_portfolio( scope=scope, create_transaction_portfolio_request=lusid.models. CreateTransactionPortfolioRequest(display_name=code, description=code, code=code, base_currency="USD"), ) # Upsert lookthrough instrument of portfolio instr_response = cocoon.load_from_data_frame( api_factory=self.api_factory, scope=scope, data_frame=data_frame, mapping_required=mapping["required"], mapping_optional=mapping["optional"], file_type="instruments", identifier_mapping=mapping["identifier_mapping"], property_columns=[], ) self.assertEqual(len(instr_response["instruments"]["success"]), 1) self.assertEqual(len(instr_response["instruments"]["errors"]), 0) self.assertEqual( instr_response["instruments"]["success"] [0].values[f"ClientInternal: {code}"].lookthrough_portfolio.code, code, )
def test_07_pg_create_with_properties(self) -> None: """ Test description: ----------------- Here we test creating a portfolio group with properties. Expected output: ---------------- The response contains the upserted properties. """ test_case_scope = create_scope_id() data_frame = self.csv_to_data_frame_with_scope( "data/port_group_tests/test_7_pg_create_with_properties.csv", self.portfolio_scope, ) responses = self.cocoon_load_from_dataframe( scope=test_case_scope, data_frame=data_frame, property_columns=["location", "MifidFlag"], properties_scope=test_case_scope, ) self.log_error_requests_title("portfolio_groups", responses) response_with_properties = self.api_factory.build( lusid.api.PortfolioGroupsApi).get_group_properties( scope=test_case_scope, code=data_frame["PortGroupCode"].tolist()[0], ) self.assertEqual( { "PortfolioGroup/" + test_case_scope + "/location": lusid.models.ModelProperty( key="PortfolioGroup/" + test_case_scope + "/location", value=lusid.models.PropertyValue(label_value="UK"), effective_from=datetime.datetime.min.replace( tzinfo=tzutc()), effective_until=datetime.datetime.max.replace( tzinfo=tzutc()), ), "PortfolioGroup/" + test_case_scope + "/MifidFlag": lusid.models.ModelProperty( key="PortfolioGroup/" + test_case_scope + "/MifidFlag", value=lusid.models.PropertyValue(label_value="Y"), effective_from=datetime.datetime.min.replace( tzinfo=tzutc()), effective_until=datetime.datetime.max.replace( tzinfo=tzutc()), ), }, response_with_properties.properties, )
def setUpClass(cls) -> None: secrets_file = Path(__file__).parent.parent.parent.joinpath( "secrets.json") cls.api_factory = lusid.utilities.ApiClientFactory( api_secrets_filename=secrets_file) cls.portfolios_api = cls.api_factory.build(lusid.api.PortfoliosApi) cls.unique_id = create_scope_id() cls.logger = logger.LusidLogger("debug") cls.scope = "ModelFundTest" cls.file_name = "data/reference-portfolio/reference-test.csv"
def test_02_pg_create_with_no_portfolio(self) -> None: """ Test description: ----------------- Here we test adding one new portfolio group with no portfolios. Expected outcome: ----------------- We expect one successful new portfolio group with no portfolios. """ test_case_scope = create_scope_id() data_frame = self.csv_to_data_frame_with_scope( "data/port_group_tests/test_2_pg_create_with_no_portfolio.csv", self.portfolio_scope, ) responses = self.cocoon_load_from_dataframe( scope=test_case_scope, data_frame=data_frame, mapping_optional={} ) self.log_error_requests_title("portfolio_groups", responses) # Check that the portfolio group is created self.assertEqual( first=len( [ port_group._id for port_group in responses["portfolio_groups"]["success"] ] ), second=len(data_frame), ) # Check that the correct portfolio group code is used self.assertEqual( first=responses["portfolio_groups"]["success"][0].id, second=lusid.models.ResourceId( scope=test_case_scope, code=data_frame["PortGroupCode"].tolist()[0] ), ) # Check that the portfolio group request has now portfolios self.assertTrue( len(responses["portfolio_groups"]["success"][0].portfolios) == 0 )
def setUpClass(cls) -> None: cls.scope = create_scope_id().replace("-", "_") cls.api_factory = lusid.utilities.ApiClientFactory( api_secrets_filename=secrets_file) cls.test_dataframe = pd.read_csv(sample_data_csv) cls.sample_data = pd.read_csv(sample_data_csv) seed_data( cls.api_factory, ["portfolios", "instruments", "transactions"], cls.scope, cls.test_dataframe, sub_holding_keys=[f"Transaction/{cls.scope}/strategy"], file_type="DataFrame", )
def setUpClass(cls) -> None: cls.scope = create_scope_id().replace("-", "_") cls.api_factory = lusid.utilities.ApiClientFactory( api_secrets_filename=secrets_file) cls.sample_data = pd.read_excel( Path(__file__).parent.joinpath( "data/seed_sample_data/sample_data_excel.xlsx")) seed_data( cls.api_factory, ["portfolios", "instruments", "transactions"], cls.scope, Path(__file__).parent.joinpath( "data/seed_sample_data/sample_data_excel.xlsx"), sub_holding_keys=[f"Transaction/{cls.scope}/strategy"], file_type="xlsx", )
def test_10_pg_add_no_new_portfolio(self) -> None: """ Test description: ------------ Here we test adding an existing portfolio to portfolio group. Expected result: ---------------- The portfolio group response should be returned with one unmodified portfolio. """ test_case_scope = create_scope_id() data_frame = self.csv_to_data_frame_with_scope( "data/port_group_tests/test_10_pg_add_no_new_portfolio.csv", self.portfolio_scope, ) port_group_request = lusid.models.CreatePortfolioGroupRequest( code=data_frame["PortGroupCode"][0], display_name=data_frame["PortGroupCode"][0], values=[ lusid.models.ResourceId( code=data_frame["FundCode"][0], scope=self.portfolio_scope ) ], ) self.api_factory.build(lusid.api.PortfolioGroupsApi).create_portfolio_group( scope=test_case_scope, create_portfolio_group_request=port_group_request, ) responses = self.cocoon_load_from_dataframe( scope=test_case_scope, data_frame=data_frame, ) self.log_error_requests_title("portfolio_groups", responses) self.assertEqual( first=responses["portfolio_groups"]["success"][0].portfolios[0], second=lusid.models.ResourceId( code=data_frame["FundCode"][0], scope=data_frame["Scope"][0] ), )
def test_03_pg_create_multiple_groups_no_portfolio(self) -> None: """ Test description: ----------------- Here we test adding multiple new portfolio group with no portfolios. Expected outcome ----------------- We expect successful requests/responses for multiple new portfolio groups. """ test_case_scope = create_scope_id() data_frame = self.csv_to_data_frame_with_scope( "data/port_group_tests/test_3_pg_create_multiple_groups_no_portfolio.csv", self.portfolio_scope, ) responses = self.cocoon_load_from_dataframe( scope=test_case_scope, data_frame=data_frame, mapping_optional={} ) self.log_error_requests_title("portfolio_groups", responses) # Check that there is a requet per portfolio group self.assertEqual( first=len( [ port_group._id for port_group in responses["portfolio_groups"]["success"] ] ), second=len(data_frame), ) # Check that the portfolio group code matches the code in the dataframe self.assertEqual( first=responses["portfolio_groups"]["success"][1].id, second=lusid.models.ResourceId( scope=test_case_scope, code=data_frame["PortGroupCode"].tolist()[1] ), )
def test_08_pg_add_bad_portfolio(self): """ Description: ------------ Here we test add a portfolio which does not exist to a current portfolio group. Expected results: ----------------- The portfolio group is returned without the portfolios added. """ test_case_scope = create_scope_id() data_frame = self.csv_to_data_frame_with_scope( "data/port_group_tests/test_8_pg_add_bad_portfolio.csv", self.portfolio_scope, ) # Create the portfolio group as a seperate request port_group_request = lusid.models.CreatePortfolioGroupRequest( code=data_frame["PortGroupCode"][0], display_name=data_frame["PortGroupCode"][0], ) self.api_factory.build(lusid.api.PortfolioGroupsApi).create_portfolio_group( scope=test_case_scope, create_portfolio_group_request=port_group_request ) responses = self.cocoon_load_from_dataframe( scope=test_case_scope, data_frame=data_frame ) self.log_error_requests_title("portfolio_groups", responses) self.assertTrue(len(responses["portfolio_groups"]["errors"]) == 0) self.assertEqual( first=responses["portfolio_groups"]["success"][0].id, second=lusid.models.ResourceId( scope=test_case_scope, code=data_frame["PortGroupCode"].tolist()[0] ), )
def test_update_alias_which_does_not_exist(self): alias_which_does_not_exist = deepcopy( self.class_transaction_type_config)[0] alias_which_does_not_exist.aliases[0].type = create_scope_id() upsert_transaction_type_alias(self.api_factory, [alias_which_does_not_exist]) get_transaction_types = (self.system_configuration_api. list_configuration_transaction_types()) uploaded_alias = [] for trans_type in get_transaction_types.transaction_configs: for alias in trans_type.aliases: if alias.type == alias_which_does_not_exist.aliases[0].type: uploaded_alias.append(trans_type) self.assertEqual(uploaded_alias[0], alias_which_does_not_exist)
def test_09_pg_add_duplicate_portfolio(self) -> None: """ Description: ------------ Here we test adding duplicate portfolios to a portfolio group. Expected outcome: ----------------- We expect the one portfolio to be added. """ test_case_scope = create_scope_id() data_frame = self.csv_to_data_frame_with_scope( "data/port_group_tests/test_9_pg_add_duplicate_portfolio.csv", self.portfolio_scope, ) # Create the portfolio group as a seperate request port_group_request = lusid.models.CreatePortfolioGroupRequest( code=data_frame["PortGroupCode"][0], display_name=data_frame["PortGroupCode"][0], ) self.api_factory.build(lusid.api.PortfolioGroupsApi).create_portfolio_group( scope=test_case_scope, create_portfolio_group_request=port_group_request ) responses = self.cocoon_load_from_dataframe( scope=test_case_scope, data_frame=data_frame ) self.log_error_requests_title("portfolio_groups", responses) self.assertEqual( first=responses["portfolio_groups"]["success"][0].portfolios[0], second=lusid.models.ResourceId( code=data_frame["FundCode"][0], scope=data_frame["Scope"][0] ), )
def test_06_pg_create_duplicate_port_group(self): """ Test description: ----------------- Here we test create two of the same portfolio groups Expected results ----------------- We expect one successful requesy for the portfolio group """ test_case_scope = create_scope_id() data_frame = self.csv_to_data_frame_with_scope( "data/port_group_tests/test_6_pg_create_duplicate_port_group.csv", self.portfolio_scope, ) responses = self.cocoon_load_from_dataframe( scope=test_case_scope, data_frame=data_frame, mapping_optional={} ) self.log_error_requests_title("portfolio_groups", responses) # Check for one successful request self.assertEqual(len(responses["portfolio_groups"]["success"]), 1) # Check the successful request has same code as dataframe portfolio group self.assertEqual( first=responses["portfolio_groups"]["success"][0].id, second=lusid.models.ResourceId( scope=test_case_scope, code=data_frame["PortGroupCode"].tolist()[0] ), )
def setUpClass(cls) -> None: cls.scope = create_scope_id().replace("-", "_") cls.api_factory = lusid.utilities.ApiClientFactory( api_secrets_filename=secrets_file) cls.sample_data = pd.read_csv(seed_sample_data_override_csv) seed_data( cls.api_factory, ["portfolios", "instruments", "transactions"], cls.scope, seed_sample_data_override_csv, mappings=dict( load_json_file( Path(__file__).parent.parent.parent.joinpath( "integration", "cocoon", "data", "seed_sample_data", "seed_sample_data_override.json", ))), sub_holding_keys=[f"Transaction/{cls.scope}/strategy"], file_type="csv", )
def test_01_pg_create_with_portfolios(self) -> None: """ Test description: ------------------ Here we test adding multiple new portfolio groups with multiple portfolios. Expected outcome: ----------------- We expect one successful request/response per portfolio group with multiple portfolios. """ test_case_scope = create_scope_id() data_frame = self.csv_to_data_frame_with_scope( "data/port_group_tests/test_1_pg_create_with_portfolios.csv", self.portfolio_scope, ) responses = self.cocoon_load_from_dataframe( scope=test_case_scope, data_frame=data_frame ) self.log_error_requests_title("portfolio_groups", responses) # Test that there is a successful request per line in the dataframe self.assertEqual( len( [ port_group for nested_group in [ port_group.portfolios for port_group in responses["portfolio_groups"]["success"] ] for port_group in nested_group ] ), len(data_frame), ) # Test that all the portfolios in the dataframe are in the request self.assertEqual( first=sorted( [ code.to_dict() for code in responses["portfolio_groups"]["success"][0].portfolios ], key=lambda item: item.get("code"), ), second=sorted( [ lusid.models.ResourceId( code=data_frame["FundCode"][1], scope=data_frame["Scope"][1] ).to_dict(), lusid.models.ResourceId( code=data_frame["FundCode"][0], scope=data_frame["Scope"][0] ).to_dict(), ], key=lambda item: item.get("code"), ), ) self.assertEqual( first=responses["portfolio_groups"]["success"][1].portfolios, second=[ lusid.models.ResourceId( code=data_frame["FundCode"][2], scope=data_frame["Scope"][2] ) ], )
import unittest from pathlib import Path import pandas as pd from lusidtools import cocoon as cocoon from parameterized import parameterized import lusid from lusidtools import logger from datetime import datetime import pytz from lusidtools.cocoon.utilities import create_scope_id unique_properties_scope = create_scope_id() def expected_response(property_scope="TestPropertiesScope1"): return { "instruments": lusid.models.UpsertInstrumentsResponse( values={ "ClientInternal: imd_34534539": lusid.models.Instrument( lusid_instrument_id="LUIDUnknown", version=lusid.models.Version( as_at_date=datetime.now(pytz.UTC), effective_from=datetime.now(pytz.UTC), ), name="USTreasury_6.875_2025", identifiers={ "ClientInternal": "imd_34534539", "Figi": "BBG000DQQNJ8", "Isin": "US912810EV62",
def setUpClass(cls) -> None: cls.scope = create_scope_id().replace("-", "_") cls.api_factory = Mock()
def test_load_instrument_lookthrough(self, _, df, mapping): if "default scope" in _: self.skipTest("Default parameter using '$' is not supported") scope = "test-lookthrough-loading-lusidtools" df = pd.read_csv(df) # replace lookthrough scope df = df.replace({"replace_scope": scope}) # populate portfolio ids with random codes codes = { row["client_internal"]: create_scope_id(use_uuid=True) if "Portfolio" in row["instrument_name"] else row["client_internal"] for index, row in df.iterrows() } df = df.replace(codes) # create portfolios [ self.api_factory.build( lusid.api.TransactionPortfoliosApi).create_portfolio( scope=scope, create_transaction_portfolio_request=lusid.models. CreateTransactionPortfolioRequest( display_name=row["client_internal"], description=row["client_internal"], code=row["client_internal"], base_currency="USD", ), ) if "Portfolio" in row["instrument_name"] else None for index, row in df.drop_duplicates("client_internal").iterrows() ] # Upsert lookthrough instrument of portfolio instr_response = cocoon.load_from_data_frame( api_factory=self.api_factory, scope=scope, data_frame=df, mapping_required=mapping["required"], mapping_optional=mapping["optional"], file_type="instruments", identifier_mapping=mapping["identifier_mapping"], property_columns=[], ) # check successes, errors and instrument lookthrough codes self.assertEqual( len(instr_response["instruments"]["success"][0].values.values()), len(df)) self.assertEqual(len(instr_response["instruments"]["errors"]), 0) # check lookthrough code on response [ self.assertEqual( instr_response["instruments"]["success"] [0].values[f"ClientInternal: {row['client_internal']}"]. lookthrough_portfolio.code, row["lookthrough_code"], ) if "id" not in row["client_internal"] else None for index, row in df.iterrows() ] # tear down this test [ self.api_factory.build(lusid.api.PortfoliosApi).delete_portfolio( scope=scope, code=code) if "id" not in code else None for code in list(codes.values()) ] [ self.api_factory.build(lusid.api.InstrumentsApi).delete_instrument( "ClientInternal", CI) for CI in list(df["client_internal"]) ]
import unittest from lusidtools.extract.group_holdings import get_holdings_for_group from pathlib import Path from lusidtools.cocoon.utilities import create_scope_id from parameterized import parameterized from lusidtools import logger import lusid from lusidtools import cocoon as cocoon import pandas as pd from lusid.models import CurrencyAndAmount # Create the Portfolios, Portfolio Groups and Holdings scope = create_scope_id() class CocoonTestsExtractGroupHoldings(unittest.TestCase): @classmethod def setUpClass(cls) -> None: secrets_file = Path(__file__).parent.parent.parent.joinpath( "secrets.json") cls.api_factory = lusid.utilities.ApiClientFactory( api_secrets_filename=secrets_file) cls.logger = logger.LusidLogger("debug") cls.scope = scope portfolio_holdings = pd.read_csv( Path(__file__).parent.joinpath("./data/holdings-example.csv")) portfolio_groups = pd.read_csv(
def test_12_pg_add_portfolios_different_scopes(self) -> None: """ Test description: ----------------- Here we test adding portfolios with multiple scopes. Expected outcome: ----------------- Request should be successful - returned with portfolios with multiple scopes. """ test_case_scope = create_scope_id() data_frame = self.csv_to_data_frame_with_scope( "data/port_group_tests/test_12_pg_add_portfolios_different_scopes.csv", self.portfolio_scope, ) port_scope_for_test = create_scope_id() self.api_factory.build(lusid.api.TransactionPortfoliosApi).create_portfolio( scope=port_scope_for_test, create_transaction_portfolio_request=models.CreateTransactionPortfolioRequest( display_name=data_frame["FundCode"][0], code=data_frame["FundCode"][0], base_currency="GBP", ), ) port_group_request = lusid.models.CreatePortfolioGroupRequest( code=data_frame["PortGroupCode"][0], display_name=data_frame["PortGroupCode"][0], values=[ lusid.models.ResourceId( code=data_frame["FundCode"][0], scope=port_scope_for_test ) ], ) self.api_factory.build(lusid.api.PortfolioGroupsApi).create_portfolio_group( scope=test_case_scope, create_portfolio_group_request=port_group_request, ) responses = self.cocoon_load_from_dataframe( scope=test_case_scope, data_frame=data_frame, ) self.log_error_requests_title("portfolio_groups", responses) self.assertTrue( expr=all( [ id in responses["portfolio_groups"]["success"][0].portfolios for id in [ lusid.models.ResourceId( code=data_frame["FundCode"][1], scope=data_frame["Scope"][1] ), lusid.models.ResourceId( code=data_frame["FundCode"][0], scope=port_scope_for_test ), lusid.models.ResourceId( code=data_frame["FundCode"][0], scope=data_frame["Scope"][0] ), lusid.models.ResourceId( code=data_frame["FundCode"][2], scope=data_frame["Scope"][2] ), ] ] ) )
import unittest from pathlib import Path import lusid import lusid.models as models from lusidtools.cocoon.utilities import create_scope_id from lusidtools.cocoon.transaction_type_upload import upsert_transaction_type_alias import logging import json from copy import deepcopy logger = logging.getLogger() new_buy_transaction_type = "BUY-LPT-TEST" new_sell_transaction_type = "SELL-LPT-TEST" type_which_does_not_exist = create_scope_id() class CocoonTestTransactionTypeUpload(unittest.TestCase): @classmethod def setUpClass(cls) -> None: secrets_file = Path(__file__).parent.parent.parent.joinpath( "secrets.json") cls.api_factory = lusid.utilities.ApiClientFactory( api_secrets_filename=secrets_file) cls.system_configuration_api = cls.api_factory.build( lusid.api.SystemConfigurationApi) cls.class_transaction_type_config = [ models.TransactionConfigurationData( aliases=[
def test_load_from_data_frame_attributes_and_properties_success( self, _, file_name, mapping_required, mapping_optional, property_columns, ) -> None: """ Test that a reference portfolio can be loaded successfully :param str file_name: The name of the test data file :param dict{str, str} mapping_required: The dictionary mapping the dataframe fields to LUSID's required base transaction/holding schema :param dict{str, str} mapping_optional: The dictionary mapping the dataframe fields to LUSID's optional base transaction/holding schema :param list[str] property_columns: The columns to create properties for :param any expected_outcome: The expected outcome :return: None """ unique_id = create_scope_id() data_frame = pd.read_csv(Path(__file__).parent.joinpath(file_name)) data_frame.drop_duplicates(inplace=True) data_frame["FundCode"] = data_frame["FundCode"] + "-" + unique_id responses = cocoon.cocoon.load_from_data_frame( api_factory=self.api_factory, scope=self.scope, data_frame=data_frame, mapping_required=mapping_required, mapping_optional=mapping_optional, file_type="reference_portfolio", identifier_mapping={}, property_columns=property_columns, properties_scope=self.scope, sub_holding_keys=[], ) # Check that the count of portfolios uploaded equals count of portfolios in DataFrame self.assertEqual( first=len(responses["reference_portfolios"]["success"]), second=len(data_frame), ) # Assert that by no unmatched_identifiers are returned in the response for reference_portfolios self.assertFalse(responses["reference_portfolios"].get( "unmatched_identifiers", False)) # Check that the portfolio IDs of porfolios uploaded matches the IDs of portfolios in DataFrame response_codes = [ response.id.code if isinstance(response, lusid.models.Portfolio) else response.origin_portfolio_id.code for response in responses["reference_portfolios"]["success"] ] self.assertEqual( first=response_codes, second=list(data_frame[mapping_required["code"]].values), ) # Check that properties get added to portfolio for portfolio in responses["reference_portfolios"]["success"]: get_portfolio = self.portfolios_api.get_portfolio( scope=portfolio.id.scope, code=portfolio.id.code, property_keys=[ f"Portfolio/{self.scope}/strategy", f"Portfolio/{self.scope}/custodian", ], ) property_keys_from_params = [ f"Portfolio/{self.scope}/{code}" for code in property_columns if len(property_columns) > 0 ] self.assertCountEqual( [prop for prop in get_portfolio.properties], property_keys_from_params, )