def test_distribute_costs_with_excluded_services(self): self._init_one() usage_orig = PricingServicePlugin._get_usages_per_pricing_object total_orig = PricingServicePlugin._get_total_usage with mock.patch( 'ralph_scrooge.plugins.cost.pricing_service.PricingServiceBasePlugin._get_usages_per_pricing_object' ) as usage_mock: # noqa with mock.patch( 'ralph_scrooge.plugins.cost.pricing_service.PricingServiceBasePlugin._get_total_usage' ) as total_mock: # noqa usage_mock.side_effect = usage_orig total_mock.side_effect = total_orig PricingServicePlugin._distribute_costs( self.today, pricing_service=self.ps1, costs_hierarchy={}, service_usage_types=self.ps1.serviceusagetypes_set.all(), excluded_services=set([ self.se4.service, self.se1.service, self.se2.service, ])) total_mock.assert_any_call( usage_type=self.service_usage_types[0], date=self.today, excluded_services=set([ self.se4.service, self.se1.service, self.se2.service, self.se3.service, ])) total_mock.assert_any_call( usage_type=self.service_usage_types[1], date=self.today, excluded_services=set([ self.se4.service, self.se1.service, self.se2.service, ])) usage_mock.assert_any_call( usage_type=self.service_usage_types[0], date=self.today, excluded_services=set([ self.se4.service, self.se1.service, self.se2.service, self.se3.service, ]), ) usage_mock.assert_any_call( usage_type=self.service_usage_types[1], date=self.today, excluded_services=set([ self.se4.service, self.se1.service, self.se2.service, ]), )
def test_distribute_costs_with_excluded_services(self): self._init_one() usage_orig = PricingServicePlugin._get_usages_per_pricing_object total_orig = PricingServicePlugin._get_total_usage with mock.patch('ralph_scrooge.plugins.cost.pricing_service.PricingServiceBasePlugin._get_usages_per_pricing_object') as usage_mock: # noqa with mock.patch('ralph_scrooge.plugins.cost.pricing_service.PricingServiceBasePlugin._get_total_usage') as total_mock: # noqa usage_mock.side_effect = usage_orig total_mock.side_effect = total_orig PricingServicePlugin._distribute_costs( self.today, pricing_service=self.ps1, costs_hierarchy={}, service_usage_types=self.ps1.serviceusagetypes_set.all(), excluded_services=set([ self.se4.service, self.se1.service, self.se2.service, ]) ) total_mock.assert_any_call( usage_type=self.service_usage_types[0], date=self.today, excluded_services=set([ self.se4.service, self.se1.service, self.se2.service, self.se3.service, ]) ) total_mock.assert_any_call( usage_type=self.service_usage_types[1], date=self.today, excluded_services=set([ self.se4.service, self.se1.service, self.se2.service, ]) ) usage_mock.assert_any_call( usage_type=self.service_usage_types[0], date=self.today, excluded_services=set([ self.se4.service, self.se1.service, self.se2.service, self.se3.service, ]), ) usage_mock.assert_any_call( usage_type=self.service_usage_types[1], date=self.today, excluded_services=set([ self.se4.service, self.se1.service, self.se2.service, ]), )
def test_get_service_extra_cost(self): result = PricingServicePlugin._get_service_extra_cost( self.today, forecast=False, service_environments=self.pricing_service1.service_environments, ) self.assertEquals(result, {self.extra_cost_type.id: (D('200'), {})})
def test_get_pricing_service_real_costs_diff( self, pricing_service_costs_mock, ): ps2 = PricingServiceFactory() self.pricing_service1.charge_diff_to_real_costs = ps2 self.pricing_service1.save() pricing_service_costs_mock.return_value = { self.pricing_service1.id: (D(100), { self.service_usage_types[0].id: (D(50), {}), self.service_usage_types[1].id: (D(50), {}), }) } result = PricingServicePlugin._get_service_charging_by_diffs( ps2, date=self.today, forecast=False, ) self.assertEqual( result, { self.pricing_service1.id: (D(-1100), {}) # 100 - 1200 })
def test_get_pricing_service_costs(self, fixed_total_mock, total_mock): def total_cost(pricing_service, *args, **kwargs): if pricing_service == self.pricing_service2: val = D(100) else: val = D(1000) return {pricing_service.id: (val, {})} def fixed_total_cost(pricing_service, *args, **kwargs): if pricing_service == self.pricing_service2: val = D(1000) else: val = D(100) return {pricing_service.id: (val, {})} total_mock.side_effect = total_cost fixed_total_mock.side_effect = fixed_total_cost result = PricingServicePlugin._get_pricing_service_costs( pricing_service=self.pricing_service1, date=self.today, forecast=False, ) self.assertEquals( result, { self.pricing_service1.id: (0, { self.pricing_service2.id: (-900, {}), self.pricing_service3.id: (900, {}), }) })
def test_get_pricing_service_costs_when_diff_key_exist( self, dependent_costs_mock, diff_costs_mock): self.usage_type1 = UsageTypeFactory() def dependent_costs(*args, **kwargs): return { self.pricing_service2.id: (100, { self.usage_type1.id: (100, {}), }), self.pricing_service3.id: (300, { self.usage_type1.id: (100, {}), }), } def diff_costs(pricing_service, *args, **kwargs): return { self.pricing_service2.id: (200, {}), } dependent_costs_mock.side_effect = dependent_costs diff_costs_mock.side_effect = diff_costs result = PricingServicePlugin._get_pricing_service_costs( pricing_service=self.pricing_service1, date=self.today, forecast=False, ) self.assertEquals( result, { self.pricing_service1.id: (600, { self.pricing_service2.id: (300, {}), self.pricing_service3.id: (300, { self.usage_type1.id: (100, {}), }), }) })
def test_get_service_extra_cost(self): result = PricingServicePlugin._get_service_extra_cost( self.today, forecast=False, service_environments=self.pricing_service1.service_environments, ) self.assertEquals(result, {self.extra_cost_type.id: (D('200'), {})})
def test_total_costs_for_all_service_environments(self): costs = PricingServicePlugin( type='total_cost', date=self.today, pricing_service=self.pricing_service1, forecast=True, for_all_service_environments=True, ) self.assertItemsEqual( costs, { self.pricing_service1.id: [ D('1010'), { self.pricing_service2.id: [ D('122'), { self.base_usage_type.id: [D('20'), {}], self.team.id: [D('2'), {}], self.extra_cost_type.id: [D('100'), {}] } ], self.base_usage_type.id: [D('80'), {}], self.regular_usage_type.id: [D('400'), {}], self.team.id: [D('8'), {}], self.extra_cost_type.id: [D('400'), {}] } ] })
def test_get_service_charging_by_diffs_error( self, fixed_total_mock, total_mock ): def total_cost(pricing_service, *args, **kwargs): if pricing_service == self.pricing_service2: return {pricing_service.id: (100, {})} raise KeyError() def fixed_total_cost(pricing_service, *args, **kwargs): if pricing_service == self.pricing_service2: return {pricing_service.id: (100, {})} raise AttributeError() total_mock.side_effect = total_cost fixed_total_mock.side_effect = fixed_total_cost result = PricingServicePlugin._get_service_charging_by_diffs( pricing_service=self.pricing_service1, date=self.today, forecast=False, ) self.assertEquals(result, { self.pricing_service2.id: (0, {}), })
def test_get_pricing_service_costs(self): costs = PricingServicePlugin._get_pricing_service_costs( date=self.today, pricing_service=self.pricing_service1, forecast=False, ) self.assertEquals(costs, { self.pricing_service1.id: ( D('505'), { self.base_usage_type.id: (D('40'), {}), self.regular_usage_type.id: (D('200'), {}), self.team.id: (D('4'), {}), self.extra_cost_type.id: (D('200'), {}), self.pricing_service2.id: [ D('61'), { self.base_usage_type.id: [D('10'), {}], self.team.id: [D('1'), {}], self.extra_cost_type.id: [D('50'), {}] } ] } ) })
def test_get_pricing_service_costs(self, fixed_total_mock, total_mock): def total_cost(pricing_service, *args, **kwargs): if pricing_service == self.pricing_service2: val = D(100) else: val = D(1000) return {pricing_service.id: (val, {})} def fixed_total_cost(pricing_service, *args, **kwargs): if pricing_service == self.pricing_service2: val = D(1000) else: val = D(100) return {pricing_service.id: (val, {})} total_mock.side_effect = total_cost fixed_total_mock.side_effect = fixed_total_cost result = PricingServicePlugin._get_pricing_service_costs( pricing_service=self.pricing_service1, date=self.today, forecast=False, ) self.assertEquals(result, { self.pricing_service1.id: (0, { self.pricing_service2.id: (-900, {}), self.pricing_service3.id: (900, {}), }) })
def test_get_service_base_usage_types_cost(self): result = PricingServicePlugin._get_service_base_usage_types_cost( self.today, pricing_service=self.pricing_service1, forecast=False, service_environments=self.pricing_service1.service_environments, ) self.assertEquals(result, {self.base_usage_type.id: (D('40'), {})})
def test_get_service_base_usage_types_cost(self): result = PricingServicePlugin._get_service_base_usage_types_cost( self.today, pricing_service=self.pricing_service1, forecast=False, service_environments=self.pricing_service1.service_environments, ) self.assertEquals(result, {self.base_usage_type.id: (D('40'), {})})
def test_get_dependent_services_cost_only_first_depth(self): result = PricingServicePlugin._get_dependent_services_cost( self.today, pricing_service=self.pricing_service1, forecast=False, service_environments=self.pricing_service1.service_environments, ) self.assertEquals(result, {self.pricing_service2.id: [D('61'), {}]})
def test_get_dependent_services_cost_only_first_depth(self): result = PricingServicePlugin._get_dependent_services_cost( self.today, pricing_service=self.pricing_service1, forecast=False, service_environments=self.pricing_service1.service_environments, ) self.assertEquals(result, { self.pricing_service2.id: [D('61'), {}] })
def test_total_costs(self): costs = PricingServicePlugin( type='total_cost', date=self.today, pricing_service=self.pricing_service1, service_environments=self.service_environments, forecast=True, ) self.assertItemsEqual(costs, {self.pricing_service1.id: (D('1010'), {})})
def test_get_pricing_service_costs_only_first_depth(self): costs = PricingServicePlugin._get_pricing_service_costs( date=self.today, pricing_service=self.pricing_service1, forecast=False, ) self.assertEquals( costs, { self.pricing_service1.id: (D('505'), { self.base_usage_type.id: (D('40'), {}), self.regular_usage_type.id: (D('200'), {}), self.team.id: (D('4'), {}), self.extra_cost_type.id: (D('200'), {}), self.pricing_service2.id: [D('61'), {}] }) })
def test_get_total_costs_from_costs(self): result = PricingServicePlugin._get_total_costs_from_costs( PRICING_SERVICE_COSTS) self.assertEquals( result, { 1: [ D(5100), { 2: [D(1800), {}], 3: [D(1600), {}], 4: [D(900), {}], 5: [D(800), {}], } ], 6: [D(300), { 2: [D(100), {}], 3: [D(200), {}], }] })
def test_get_pricing_service_costs2(self): # there are 4 daily pricing objects that are using pricing service 2: # 2 are in se1, 2 are in se6 # total cost of pricing service 1 (which has 2 daily pricing objects) # for one day (today) is 122: # base usage: 2 (dpo) * 10 (usage value) * 1 (cost per unit) = 20 # team: 10 (daily cost) * 0.2 (percent) = 2 # extra cost: 100 (daily cost) costs = PricingServicePlugin._get_pricing_service_costs( self.today, self.pricing_service2, forecast=False, ) self.assertEquals(costs, { self.pricing_service2.id: (D('122'), { self.base_usage_type.id: (D('20'), {}), self.team.id: (D('2'), {}), self.extra_cost_type.id: (D('100'), {}), }), })
def test_get_dependent_services_cost(self): result = PricingServicePlugin._get_dependent_services_cost( self.today, pricing_service=self.pricing_service1, forecast=False, service_environments=self.pricing_service1.service_environments, ) # daily pricing objects which are under pricing service 1 (practically # under se1) are using extacly half of pricing service resources, so # they will be charged with half of total amount self.assertEquals( result, { self.pricing_service2.id: [ D('61'), { self.base_usage_type.id: [D('10'), {}], self.team.id: [D('1'), {}], self.extra_cost_type.id: [D('50'), {}] } ] })
def test_get_dependent_services_cost(self): result = PricingServicePlugin._get_dependent_services_cost( self.today, pricing_service=self.pricing_service1, forecast=False, service_environments=self.pricing_service1.service_environments, ) # daily pricing objects which are under pricing service 1 (practically # under se1) are using extacly half of pricing service resources, so # they will be charged with half of total amount self.assertEquals(result, { self.pricing_service2.id: [ D('61'), { self.base_usage_type.id: [D('10'), {}], self.team.id: [D('1'), {}], self.extra_cost_type.id: [D('50'), {}] } ] })
def test_get_pricing_service_costs2(self): # there are 4 daily pricing objects that are using pricing service 2: # 2 are in se1, 2 are in se6 # total cost of pricing service 1 (which has 2 daily pricing objects) # for one day (today) is 122: # base usage: 2 (dpo) * 10 (usage value) * 1 (cost per unit) = 20 # team: 10 (daily cost) * 0.2 (percent) = 2 # extra cost: 100 (daily cost) costs = PricingServicePlugin._get_pricing_service_costs( self.today, self.pricing_service2, forecast=False, ) self.assertEquals( costs, { self.pricing_service2.id: (D('122'), { self.base_usage_type.id: (D('20'), {}), self.team.id: (D('2'), {}), self.extra_cost_type.id: (D('100'), {}), }), })
def test_get_service_charging_by_diffs_error(self, fixed_total_mock, total_mock): def total_cost(pricing_service, *args, **kwargs): if pricing_service == self.pricing_service2: return {pricing_service.id: (100, {})} raise KeyError() def fixed_total_cost(pricing_service, *args, **kwargs): if pricing_service == self.pricing_service2: return {pricing_service.id: (100, {})} raise AttributeError() total_mock.side_effect = total_cost fixed_total_mock.side_effect = fixed_total_cost result = PricingServicePlugin._get_service_charging_by_diffs( pricing_service=self.pricing_service1, date=self.today, forecast=False, ) self.assertEquals(result, { self.pricing_service2.id: (0, {}), })
def test_get_total_costs_from_costs(self): result = PricingServicePlugin._get_total_costs_from_costs( PRICING_SERVICE_COSTS ) self.assertEquals(result, { 1: [ D(5100), { 2: [D(1800), {}], 3: [D(1600), {}], 4: [D(900), {}], 5: [D(800), {}], } ], 6: [ D(300), { 2: [D(100), {}], 3: [D(200), {}], } ] })
def test_get_pricing_service_real_costs_diff( self, pricing_service_costs_mock, ): ps2 = PricingServiceFactory() self.pricing_service1.charge_diff_to_real_costs = ps2 self.pricing_service1.save() pricing_service_costs_mock.return_value = { self.pricing_service1.id: (D(100), { self.service_usage_types[0].id: (D(50), {}), self.service_usage_types[1].id: (D(50), {}), }) } result = PricingServicePlugin._get_service_charging_by_diffs( ps2, date=self.today, forecast=False, ) self.assertEqual(result, { self.pricing_service1.id: (D(-1100), {}) # 100 - 1200 })
def test_get_service_charging_by_diffs(self, fixed_total_mock, total_mock): def total_cost(pricing_service, *args, **kwargs): if pricing_service == self.pricing_service2: val = D(100) else: val = D(1000) return {pricing_service.id: (val, {})} def fixed_total_cost(pricing_service, *args, **kwargs): if pricing_service == self.pricing_service2: val = D(1000) else: val = D(100) return {pricing_service.id: (val, {})} total_mock.side_effect = total_cost fixed_total_mock.side_effect = fixed_total_cost result = PricingServicePlugin._get_service_charging_by_diffs( pricing_service=self.pricing_service1, date=self.today, forecast=False, ) self.assertEquals( result, { self.pricing_service2.id: (-900, {}), self.pricing_service3.id: (900, {}), }) calls = [ mock.call( date=self.today, pricing_service=x, for_all_service_environments=True, forecast=False, ) for x in (self.pricing_service2, self.pricing_service3) ] total_mock.assert_has_calls(calls, any_order=True) fixed_total_mock.assert_has_calls(calls, any_order=True)
def test_get_pricing_service_costs_when_diff_key_exist( self, dependent_costs_mock, diff_costs_mock ): self.usage_type1 = UsageTypeFactory() def dependent_costs(*args, **kwargs): return { self.pricing_service2.id: (100, { self.usage_type1.id: (100, {}), }), self.pricing_service3.id: (300, { self.usage_type1.id: (100, {}), }), } def diff_costs(pricing_service, *args, **kwargs): return { self.pricing_service2.id: (200, {}), } dependent_costs_mock.side_effect = dependent_costs diff_costs_mock.side_effect = diff_costs result = PricingServicePlugin._get_pricing_service_costs( pricing_service=self.pricing_service1, date=self.today, forecast=False, ) self.assertEquals(result, { self.pricing_service1.id: (600, { self.pricing_service2.id: (300, {}), self.pricing_service3.id: (300, { self.usage_type1.id: (100, {}), }), }) })
def test_get_service_charging_by_diffs(self, fixed_total_mock, total_mock): def total_cost(pricing_service, *args, **kwargs): if pricing_service == self.pricing_service2: val = D(100) else: val = D(1000) return {pricing_service.id: (val, {})} def fixed_total_cost(pricing_service, *args, **kwargs): if pricing_service == self.pricing_service2: val = D(1000) else: val = D(100) return {pricing_service.id: (val, {})} total_mock.side_effect = total_cost fixed_total_mock.side_effect = fixed_total_cost result = PricingServicePlugin._get_service_charging_by_diffs( pricing_service=self.pricing_service1, date=self.today, forecast=False, ) self.assertEquals(result, { self.pricing_service2.id: (-900, {}), self.pricing_service3.id: (900, {}), }) calls = [ mock.call( date=self.today, pricing_service=x, for_all_service_environments=True, forecast=False, ) for x in (self.pricing_service2, self.pricing_service3) ] total_mock.assert_has_calls(calls, any_order=True) fixed_total_mock.assert_has_calls(calls, any_order=True)
def test_pricing_dependent_services(self): """ Call costs for PS1, which dependent on PS2, which dependent of PS3. Check if all dependencies (and ) """ self._init() def dependent_services(self1, date, exclude=None): if self1 == self.ps1: return [self.ps2] elif self1 == self.ps2: return [self.ps3] return [] # get_dependent_services_mock.side_effect = dependent_services with mock.patch.object(models.service.PricingService, 'get_dependent_services', dependent_services): # noqa distribute_costs_orig = PricingServicePlugin._distribute_costs with mock.patch( 'ralph_scrooge.plugins.cost.pricing_service.PricingServiceBasePlugin._distribute_costs' ) as distribute_costs_mock: # noqa distribute_costs_mock.side_effect = distribute_costs_orig PricingServicePlugin.costs( pricing_service=self.ps1, date=self.today, service_environments=models.ServiceEnvironment.objects.all( ), # noqa forecast=False, pricing_services_calculated=None, ) calls = [ mock.call( self.today, # date self.ps3, # pricing service {self.ps3.id: (0, {})}, # costs - not important here self.ps3.serviceusagetypes_set.all(), # percentage excluded_services=set([ # from ps3 self.se5.service, ])), mock.call( self.today, self.ps2, {self.ps2.id: (0, {})}, self.ps2.serviceusagetypes_set.all(), excluded_services=set([ # from ps2 self.other_se[1].service, self.se3.service, self.se4.service, ])), mock.call( self.today, self.ps1, {self.ps1.id: (0, {})}, self.ps1.serviceusagetypes_set.all(), excluded_services=set([ # from ps1 self.other_se[0].service, self.se1.service, self.se2.service, ])), ] self.assertEquals(len(calls), len(distribute_costs_mock.call_args_list)) # comparing strings, because of django query sets in params for expected_call, actual_call in zip( calls, distribute_costs_mock.call_args_list): self.assertEquals(str(expected_call), str(actual_call))
def test_pricing_dependent_services(self): """ Call costs for PS1, which dependent on PS2, which dependent of PS3. Check if all dependencies (and ) """ self._init() def dependent_services(self1, date, exclude=None): if self1 == self.ps1: return [self.ps2] elif self1 == self.ps2: return [self.ps3] return [] # get_dependent_services_mock.side_effect = dependent_services with mock.patch.object(models.service.PricingService, 'get_dependent_services', dependent_services): # noqa distribute_costs_orig = PricingServicePlugin._distribute_costs with mock.patch('ralph_scrooge.plugins.cost.pricing_service.PricingServiceBasePlugin._distribute_costs') as distribute_costs_mock: # noqa distribute_costs_mock.side_effect = distribute_costs_orig PricingServicePlugin.costs( pricing_service=self.ps1, date=self.today, service_environments=models.ServiceEnvironment.objects.all(), # noqa forecast=False, pricing_services_calculated=None, ) calls = [ mock.call( self.today, # date self.ps3, # pricing service {self.ps3.id: (0, {})}, # costs - not important here self.ps3.serviceusagetypes_set.all(), # percentage excluded_services=set([ # from ps3 self.se5.service, ]) ), mock.call( self.today, self.ps2, {self.ps2.id: (0, {})}, self.ps2.serviceusagetypes_set.all(), excluded_services=set([ # from ps2 self.other_se[1].service, self.se3.service, self.se4.service, ]) ), mock.call( self.today, self.ps1, {self.ps1.id: (0, {})}, self.ps1.serviceusagetypes_set.all(), excluded_services=set([ # from ps1 self.other_se[0].service, self.se1.service, self.se2.service, ]) ), ] self.assertEquals( len(calls), len(distribute_costs_mock.call_args_list) ) # comparing strings, because of django query sets in params for expected_call, actual_call in zip( calls, distribute_costs_mock.call_args_list ): self.assertEquals(str(expected_call), str(actual_call))
def test_costs(self): costs = PricingServicePlugin( type='costs', date=self.today, pricing_service=self.pricing_service1, service_environments=self.service_environments, forecast=True, ) po1 = self.se4_dpo[0].pricing_object.id po2 = self.se4_dpo[1].pricing_object.id po3 = self.se5_dpo[0].pricing_object.id po4 = self.se5_dpo[1].pricing_object.id result = { self.service_environments[3].id: [ { 'cost': D('126.25'), 'pricing_object_id': po2, 'type_id': self.pricing_service1.id, '_children': [ { 'cost': D('10'), 'pricing_object_id': po2, 'type_id': self.base_usage_type.id, }, { 'cost': D('50'), 'pricing_object_id': po2, 'type_id': self.regular_usage_type.id, }, { 'cost': D('1'), 'pricing_object_id': po2, 'type_id': self.team.id, }, { 'cost': D('50'), 'pricing_object_id': po2, 'type_id': self.extra_cost_type.id, }, { 'cost': D('15.25'), 'pricing_object_id': po2, 'type_id': self.pricing_service2.id, '_children': [{ 'cost': D('2.5'), 'pricing_object_id': po2, 'type_id': self.base_usage_type.id, }, { 'cost': D('0.25'), 'pricing_object_id': po2, 'type_id': self.team.id, }, { 'cost': D('12.5'), 'pricing_object_id': po2, 'type_id': self.extra_cost_type.id, }], }, ], }, { 'cost': D('126.25'), 'pricing_object_id': po1, 'type_id': self.pricing_service1.id, '_children': [ { 'cost': D('10'), 'pricing_object_id': po1, 'type_id': self.base_usage_type.id, }, { 'cost': D('50'), 'pricing_object_id': po1, 'type_id': self.regular_usage_type.id, }, { 'cost': D('1'), 'pricing_object_id': po1, 'type_id': self.team.id, }, { 'cost': D('50'), 'pricing_object_id': po1, 'type_id': self.extra_cost_type.id, }, { 'cost': D('15.25'), 'pricing_object_id': po1, 'type_id': self.pricing_service2.id, '_children': [{ 'cost': D('2.5'), 'pricing_object_id': po1, 'type_id': self.base_usage_type.id, }, { 'cost': D('0.25'), 'pricing_object_id': po1, 'type_id': self.team.id, }, { 'cost': D('12.5'), 'pricing_object_id': po1, 'type_id': self.extra_cost_type.id, }], }, ], }, ], self.service_environments[4].id: [ { 'cost': D('378.75'), 'pricing_object_id': po4, 'type_id': self.pricing_service1.id, '_children': [{ 'cost': D('30'), 'pricing_object_id': po4, 'type_id': self.base_usage_type.id }, { 'cost': D('150'), 'pricing_object_id': po4, 'type_id': self.regular_usage_type.id, }, { 'cost': D('3'), 'pricing_object_id': po4, 'type_id': self.team.id, }, { 'cost': D('150'), 'pricing_object_id': po4, 'type_id': self.extra_cost_type.id, }, { 'cost': D('45.75'), 'pricing_object_id': po4, 'type_id': self.pricing_service2.id, '_children': [{ 'cost': D('7.5'), 'pricing_object_id': po4, 'type_id': self.base_usage_type.id, }, { 'cost': D('0.75'), 'pricing_object_id': po4, 'type_id': self.team.id, }, { 'cost': D('37.5'), 'pricing_object_id': po4, 'type_id': self.extra_cost_type.id, }], }] }, { 'cost': D('378.75'), 'pricing_object_id': po3, 'type_id': self.pricing_service1.id, '_children': [{ 'cost': D('30'), 'pricing_object_id': po3, 'type_id': self.base_usage_type.id }, { 'cost': D('150'), 'pricing_object_id': po3, 'type_id': self.regular_usage_type.id, }, { 'cost': D('3'), 'pricing_object_id': po3, 'type_id': self.team.id, }, { 'cost': D('150'), 'pricing_object_id': po3, 'type_id': self.extra_cost_type.id, }, { 'cost': D('45.75'), 'pricing_object_id': po3, 'type_id': self.pricing_service2.id, '_children': [{ 'cost': D('7.5'), 'pricing_object_id': po3, 'type_id': self.base_usage_type.id, }, { 'cost': D('0.75'), 'pricing_object_id': po3, 'type_id': self.team.id, }, { 'cost': D('37.5'), 'pricing_object_id': po3, 'type_id': self.extra_cost_type.id, }], }] }, ] } self.assertItemsEqual(costs, result)