def test_availability_from_bottom_fails_if_no_products_in_bath(self): expected_case_result = 0 matches, scene = self.create_scif_matches_stitch_groups_data_mocks([7]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name(toolbox.template_data, TestConsts.KPI_BATH) if series.size != 0: general_filters = toolbox.get_general_filters(series) res = toolbox.calculate_availability_from_bottom(**general_filters) self.assertEquals(res, expected_case_result)
def test_calculate_eye_level_fails_if_no_products(self): expected_case_result = 0 matches, scene = self.create_scif_matches_stitch_groups_data_mocks([4]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name( toolbox.template_data, TestConsts.KPI_EYE_LEVEL) if series.size != 0: general_filters = toolbox.get_general_filters(series) num_result, denominator_result, atomic_score = toolbox.calculate_eye_level( **general_filters) self.assertEquals(round(atomic_score, 2), expected_case_result) else: self.assertFalse(series.empty, True)
def set_up(self): super(TestCBCDAIRYIL, self).set_up() self.mock_data_provider() # self.data_provider_mock = MagicMock() self.data_provider_mock.project_name = 'Test_Project_1' # self.data_provider_mock.rds_conn = MagicMock() self.PSProjectConnector = self.mock_object( 'PSProjectConnector', path='KPIUtils_v2.DB.PsProjectConnector') self.common = self.mock_common() self.old_common = self.mock_object('oldCommon') self.output = MagicMock() self.rds_conn = MagicMock() self.survey = self.mock_survey() self.block = self.mock_block() self.scif = self.get_made_up_scif() # self.general_toolbox = self.mock_general_toolbox() self.mock_parse_template_data() self.tool_box = CBCDAIRYILToolBox(self.data_provider_mock, MagicMock())
class Generator: def __init__(self, data_provider, output): self.data_provider = data_provider self.output = output self.project_name = data_provider.project_name self.tool_box = CBCDAIRYILToolBox(self.data_provider, self.output) @log_runtime('Total Calculations', log_start=True) def main_function(self): """ This is the main KPI calculation function - where the magic happens. It calculates the score for every KPI and saves it to the DB. """ if self.tool_box.scif.empty: Log.warning('Scene item facts is empty for this session') return self.tool_box.main_calculation() self.tool_box.common.commit_results_data() self.tool_box.old_common.commit_results_data()
def test_min_2_availability_failes_if_only_have_1_facing(self): expected_case_result = (0, 1, 0) matches, scene = self.create_scif_matches_stitch_groups_data_mocks([8]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name(toolbox.template_data, TestConsts.KPI_MIN_2) if series.size != 0: general_filters = toolbox.get_general_filters(series) toolbox.calculate_availability(**general_filters) res = toolbox.calculate_min_2_availability(**general_filters) self.assertEquals(res, expected_case_result)
def __init__(self, data_provider, output): self.data_provider = data_provider self.output = output self.project_name = data_provider.project_name self.tool_box = CBCDAIRYILToolBox(self.data_provider, self.output)
class TestCBCDAIRYIL(TestFunctionalCase): TEST_CASE = get_test_case_template_all_tests() SCIF, MATCHES, PROBE_GROUPS = get_scif_matches_stich_groups(TEST_CASE) @property def import_path(self): return 'Projects.CBCDAIRYIL.Utils.KPIToolBox' def set_up(self): super(TestCBCDAIRYIL, self).set_up() self.mock_data_provider() # self.data_provider_mock = MagicMock() self.data_provider_mock.project_name = 'Test_Project_1' # self.data_provider_mock.rds_conn = MagicMock() self.PSProjectConnector = self.mock_object( 'PSProjectConnector', path='KPIUtils_v2.DB.PsProjectConnector') self.common = self.mock_common() self.old_common = self.mock_object('oldCommon') self.output = MagicMock() self.rds_conn = MagicMock() self.survey = self.mock_survey() self.block = self.mock_block() self.scif = self.get_made_up_scif() # self.general_toolbox = self.mock_general_toolbox() self.mock_parse_template_data() self.tool_box = CBCDAIRYILToolBox(self.data_provider_mock, MagicMock()) def mock_parse_template_data(self): template_mock = self.mock_object( 'CBCDAIRYILToolBox.parse_template_data') template_data = parse_template(os.path.join( os.path.dirname(os.path.realpath(__file__)), 'Data', 'test_template.xlsx'), Consts.KPI_SHEET, lower_headers_row_index=1) template_mock.return_value = template_data def mock_data_provider(self): self.data_provider_mock = MagicMock() # return self._data_provider self.data_provider_data_mock = {} def get_item(key): return self.data_provider_data_mock[ key] if key in self.data_provider_data_mock else MagicMock() self.data_provider_mock.__getitem__.side_effect = get_item def mock_scene_item_facts(self, data): self.data_provider_data_mock['scene_item_facts'] = data.where( data.notnull(), None) def mock_match_product_in_scene(self, data): self.data_provider_data_mock['matches'] = data.where( data.notnull(), None) def create_scif_matches_stitch_groups_data_mocks(self, scenes_list): scif_test_case = self.SCIF matches_test_case = self.MATCHES scif_scene = scif_test_case[scif_test_case['scene_fk'].isin( scenes_list)] matches_scene = matches_test_case[matches_test_case['scene_fk'].isin( scenes_list)] self.mock_scene_item_facts(scif_scene) self.mock_match_product_in_scene(matches_scene) return matches_scene, scif_scene @staticmethod def get_made_up_scif(): d = { 'scene_id': [1, 2, 3, 4], 'template_name': [ TestConsts.OUT_CAT_FRIDGE, TestConsts.OUT_CAT_FRIDGE, TestConsts.RETAILER_FRIDGE, 'SOME_TEMPLATE' ], 'template_group': ['', '', '', ''] } df = pd.DataFrame(data=d) return df def mock_common(self): return self.mock_object('Common') def mock_survey(self): return self.mock_object('Survey') def mock_block(self): return self.mock_object('Block') def mock_general_toolbox(self): return self.mock_object('GENERALToolBox') def test_current_project_template(self): """ This test is check the validation of the current project's template! """ # Columns tests expected_columns = { 'Atomic Name', 'KPI Name', 'KPI Set', 'store_type', 'additional_attribute_1', 'additional_attribute_2', 'additional_attribute_3', 'additional_attribute_6', 'additional_attribute_7', 'Template Name', 'Template group', 'KPI Family', 'Score Type', 'Param Type (1)/ Numerator', 'Param (1) Values', 'Param Type (2)/ Denominator', 'Param (2) Values', 'Param Type (3)', 'Param (3) Values', 'Weight', 'Target', 'Split Score' } template = pd.read_excel(TestConsts.PROJECT_TEMPLATE_PATH, skiprows=1) if expected_columns.difference(template.columns): # Gives it another shot - Maybe the redundant top row was removed template = pd.read_excel(TestConsts.PROJECT_TEMPLATE_PATH, skiprows=0) self.assertEqual( set(), expected_columns.difference(template.columns), msg="The template's columns are different than the expected ones!") # Template's attributes Test self.assertTrue(self._check_template_instances(template), msg="One of template's attributes has nan value!") @staticmethod def _check_template_instances(template): columns_to_check = [ 'additional_attribute_6', 'Weight', 'KPI Family', 'KPI Set' ] for col in columns_to_check: attribute_values = template[col].unique().tolist() for value in attribute_values: if isinstance(value, float) and math.isnan(value): print "ERROR! There is a empty value in the following column: {}".format( col) return False return True def test_kpi_percentage_games(self): """ This is a test for the weights' games in Tara""" regular_percentage_1 = ([(100, 0.3), (100, 0.4), (0, 0.3)], 70) regular_percentage_2 = ([(50, 0.2), (10, 0.4), (0, 0.1), (0, 0.3)], 14) missing_percentage_1 = ([(100, 0.5), (0, 0.3)], 60) missing_percentage_2 = ([(100, 0.1), (0, 0.1)], 50) missing_percentage_3 = ([(50, 0.3), (20, 0.2)], 36.5) percentage_with_nones_1 = ([(100, 0.5), (0, None), (100, None), (100, 0.4)], 75) percentage_with_nones_2 = ([(10, 0.5), (0, None), (10, 0.1), (10, 0.1), (10, None)], 8) test_cases_list = [ regular_percentage_1, regular_percentage_2, missing_percentage_1, missing_percentage_2, missing_percentage_3, percentage_with_nones_1, percentage_with_nones_2 ] for test_values, expected_result in test_cases_list: self.assertEqual( expected_result, self.tool_box.calculate_kpi_result_by_weight( test_values, 1.0, False)) def test_scif_scenes_filters(self): """This test checks the scene filters by template_name and template_group""" params_1 = (pd.Series( [TestConsts.RETAILER_FRIDGE, ''], index=[Consts.TEMPLATE_NAME, Consts.TEMPLATE_GROUP]), [3]) params_2 = (pd.Series( [TestConsts.OUT_CAT_FRIDGE, ''], index=[Consts.TEMPLATE_NAME, Consts.TEMPLATE_GROUP]), [1, 2]) params_3 = (pd.Series( ['', ''], index=[Consts.TEMPLATE_NAME, Consts.TEMPLATE_GROUP]), [1, 2, 3, 4]) params_4 = (pd.Series( ['', TestConsts.RETAILER_FRIDGE], index=[Consts.TEMPLATE_NAME, Consts.TEMPLATE_GROUP]), []) test_cases = [params_1, params_2, params_3, params_4] for test_case_params, expected_result in test_cases: self.tool_box.scif = self.get_made_up_scif() scenes_list = self.tool_box.get_relevant_scenes_by_params( test_case_params) self.assertEqual(expected_result, scenes_list) def test_get_number_of_facings_per_product_dict(self): """ This is a test for get_number_of_facings_per_product_dict function""" my_df = { Consts.EAN_CODE: [1, 2, 3, 4], Consts.FACINGS: [2, 2, 3, 3], Consts.FACINGS_IGN_STACK: [1, 1, 0, 0] } my_df = pd.DataFrame(data=my_df) dict_add_stack = self.tool_box.get_number_of_facings_per_product_dict( my_df, ignore_stack=False) dict_ignore_stack = self.tool_box.get_number_of_facings_per_product_dict( my_df, ignore_stack=True) self.assertEqual(4, len(dict_add_stack)) self.assertEqual(2, len(dict_ignore_stack)) self.assertEqual([1, 2, 3, 4], dict_add_stack.keys()) self.assertEqual([1, 2], dict_ignore_stack.keys()) def test_filter_df_by_shelves_top_bottom_max_match(self): df_3_shelves = { Consts.SCENE_FK: [1, 1, 1, 1, 1, 1, 1, 1], Consts.SHELF_NUM_FROM_BOTTOM: [1, 1, 2, 2, 2, 3, 3, 3], Consts.SHELF_NUM: [3, 3, 2, 2, 2, 1, 1, 1] } merged_df_3 = { Consts.SCENE_FK: [1, 1, 1, 1, 1, 1], Consts.SHELF_NUM_FROM_BOTTOM: [1, 2, 2, 2, 3, 3], Consts.SHELF_NUM: [3, 2, 2, 2, 1, 1] } df_no_shelves = { Consts.SCENE_FK: [], Consts.SHELF_NUM_FROM_BOTTOM: [], Consts.SHELF_NUM: [] } merged_df_no_shelves = { Consts.SCENE_FK: [], Consts.SHELF_NUM_FROM_BOTTOM: [], Consts.SHELF_NUM: [] } df_2_shelves = { Consts.SCENE_FK: [1, 1, 2, 2], Consts.SHELF_NUM_FROM_BOTTOM: [1, 2, 1, 2], Consts.SHELF_NUM: [2, 1, 2, 1] } merged_df_2 = { Consts.SCENE_FK: [1, 1], Consts.SHELF_NUM_FROM_BOTTOM: [1, 2], Consts.SHELF_NUM: [2, 1] } df_2_shelves_2 = { Consts.SCENE_FK: [1, 1, 2, 2], Consts.SHELF_NUM_FROM_BOTTOM: [1, 2, 1, 2], Consts.SHELF_NUM: [2, 1, 2, 1] } merged_df_2_2 = { Consts.SCENE_FK: [1], Consts.SHELF_NUM_FROM_BOTTOM: [1], Consts.SHELF_NUM: [2] } df_6_shelves = { Consts.SCENE_FK: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], Consts.SHELF_NUM_FROM_BOTTOM: [6, 5, 4, 4, 3, 3, 3, 2, 2, 3, 2, 1], Consts.SHELF_NUM: [1, 2, 3, 3, 4, 4, 4, 5, 5, 4, 5, 6] } merged_df_6 = { Consts.SCENE_FK: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], Consts.SHELF_NUM_FROM_BOTTOM: [6, 5, 4, 4, 3, 3, 3, 2, 2, 3, 2, 1], Consts.SHELF_NUM: [1, 2, 3, 3, 4, 4, 4, 5, 5, 4, 5, 6] } df_8_shelves = { Consts.SCENE_FK: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], Consts.SHELF_NUM_FROM_BOTTOM: [8, 7, 7, 6, 6, 5, 7, 4, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1], Consts.SHELF_NUM: [1, 2, 2, 3, 3, 4, 2, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8] } merged_df_8 = { Consts.SCENE_FK: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], Consts.SHELF_NUM_FROM_BOTTOM: [8, 7, 6, 5, 7, 4, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1], Consts.SHELF_NUM: [1, 2, 3, 4, 2, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8] } potential_dfs_list = [(merged_df_3, df_3_shelves, [1, 2], 5), (merged_df_no_shelves, df_no_shelves, [], 0), (merged_df_2, df_2_shelves, [1, 2], 2), (merged_df_2_2, df_2_shelves_2, [2], 1), (merged_df_6, df_6_shelves, [2, 3, 4], 7), (merged_df_8, df_8_shelves, [3, 4, 5, 6], 9)] for d, d_full, expected_shelves, exp_length in potential_dfs_list: df = pd.DataFrame(data=d) df_full = pd.DataFrame(data=d_full) filtered_df = self.tool_box.filter_df_by_shelves( df, df_full, Consts.EYE_LEVEL_PER_SHELF) eye_lvl_shelves = filtered_df[Consts.SHELF_NUM].unique().tolist() self.assertItemsEqual(expected_shelves, eye_lvl_shelves) self.assertEqual(exp_length, len(filtered_df)) def _get_param_series_by_atomic_name(self, df, atomic_name): df = df.loc[df['Atomic Name'].str.encode('utf-8') == atomic_name.encode('utf-8')] if not df.empty: df = df.iloc[0] return df def test_calculate_eye_level_passes_if_75_percent_product_on_eye_level( self): expected_case_result = 100 matches, scene = self.create_scif_matches_stitch_groups_data_mocks([1]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name( toolbox.template_data, TestConsts.KPI_EYE_LEVEL) if series.size != 0: general_filters = toolbox.get_general_filters(series) num_result, denominator_result, atomic_score = toolbox.calculate_eye_level( **general_filters) self.assertEquals(atomic_score, expected_case_result) else: self.assertFalse(series.empty, True) def test_calculate_eye_level_fails_if_not_75_percent_product_on_eye_level( self): expected_case_result = 66.67 matches, scene = self.create_scif_matches_stitch_groups_data_mocks([2]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name( toolbox.template_data, TestConsts.KPI_EYE_LEVEL) if series.size != 0: general_filters = toolbox.get_general_filters(series) num_result, denominator_result, atomic_score = toolbox.calculate_eye_level( **general_filters) self.assertEquals(round(atomic_score, 2), expected_case_result) else: self.assertFalse(series.empty, True) def test_calculate_eye_level_fails_if_no_product_on_eye_level(self): expected_case_result = 0 matches, scene = self.create_scif_matches_stitch_groups_data_mocks([3]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name( toolbox.template_data, TestConsts.KPI_EYE_LEVEL) if series.size != 0: general_filters = toolbox.get_general_filters(series) num_result, denominator_result, atomic_score = toolbox.calculate_eye_level( **general_filters) self.assertEquals(round(atomic_score, 2), expected_case_result) else: self.assertFalse(series.empty, True) def test_calculate_eye_level_fails_if_no_products(self): expected_case_result = 0 matches, scene = self.create_scif_matches_stitch_groups_data_mocks([4]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name( toolbox.template_data, TestConsts.KPI_EYE_LEVEL) if series.size != 0: general_filters = toolbox.get_general_filters(series) num_result, denominator_result, atomic_score = toolbox.calculate_eye_level( **general_filters) self.assertEquals(round(atomic_score, 2), expected_case_result) else: self.assertFalse(series.empty, True) def test_availability_from_bottom_fails_if_product_not_in_bath_exist(self): expected_case_result = 0 matches, scene = self.create_scif_matches_stitch_groups_data_mocks([5]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name(toolbox.template_data, TestConsts.KPI_BATH) if series.size != 0: general_filters = toolbox.get_general_filters(series) res = toolbox.calculate_availability_from_bottom(**general_filters) self.assertEquals(res, expected_case_result) def test_availability_from_bottom_passes_if_all_products_in_bath(self): expected_case_result = 100 matches, scene = self.create_scif_matches_stitch_groups_data_mocks([6]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name(toolbox.template_data, TestConsts.KPI_BATH) if series.size != 0: general_filters = toolbox.get_general_filters(series) res = toolbox.calculate_availability_from_bottom(**general_filters) self.assertEquals(res, expected_case_result) def test_availability_from_bottom_fails_if_no_products_in_bath(self): expected_case_result = 0 matches, scene = self.create_scif_matches_stitch_groups_data_mocks([7]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name(toolbox.template_data, TestConsts.KPI_BATH) if series.size != 0: general_filters = toolbox.get_general_filters(series) res = toolbox.calculate_availability_from_bottom(**general_filters) self.assertEquals(res, expected_case_result) def test_availability_from_bottom_passes_if_products_in_bath_ignore_others( self): expected_case_result = 100 matches, scene = self.create_scif_matches_stitch_groups_data_mocks([8]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name(toolbox.template_data, TestConsts.KPI_BATH) if series.size != 0: general_filters = toolbox.get_general_filters(series) res = toolbox.calculate_availability_from_bottom(**general_filters) self.assertEquals(res, expected_case_result) def test_min_2_availability_failes_if_only_have_1_facing(self): expected_case_result = (0, 1, 0) matches, scene = self.create_scif_matches_stitch_groups_data_mocks([8]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name(toolbox.template_data, TestConsts.KPI_MIN_2) if series.size != 0: general_filters = toolbox.get_general_filters(series) toolbox.calculate_availability(**general_filters) res = toolbox.calculate_min_2_availability(**general_filters) self.assertEquals(res, expected_case_result) def test_min_2_availability_failes_if_products_have_2_facing_in_stacking_only( self): expected_case_result = (0, 1, 0) matches, scene = self.create_scif_matches_stitch_groups_data_mocks([9]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name(toolbox.template_data, TestConsts.KPI_MIN_2) if series.size != 0: general_filters = toolbox.get_general_filters(series) toolbox.calculate_availability(**general_filters) res = toolbox.calculate_min_2_availability(**general_filters) self.assertEquals(res, expected_case_result) def test_min_2_availability_passes_if_products_have_2_facing(self): expected_case_result = (1, 1, 100) matches, scene = self.create_scif_matches_stitch_groups_data_mocks( [10]) toolbox = CBCDAIRYILToolBox(self.data_provider_mock, self.output) series = self._get_param_series_by_atomic_name(toolbox.template_data, TestConsts.KPI_MIN_2) if series.size != 0: general_filters = toolbox.get_general_filters(series) toolbox.calculate_availability(**general_filters) res = toolbox.calculate_min_2_availability(**general_filters) self.assertEquals(res, expected_case_result)