def test_etsy_missing_title(self): """ Test verifies, that invalid data from Etsy - missing title - don't cause syncShop task to be suspended. See HIVE-845 for more info """ expected_db_task_queue = [['1', 'syncShop', '2', 'done', ''], ['2', 'downloadProduct', '1', 'done', '']] expected_db_product_properties = [[ '1', '2', 't', 'Title cannot be empty' ]] self.stop_all() self.set_etsy_testcase('listings_missing_title') run_sql('HIVE', 'listings_10', retry=2) setup_rabbit() self.restart_all() # check that sync task is done wait_for_assert(expected_db_task_queue, lambda: run_sql('HIVE', 'select_operations', True), 'syncShop task was not completed as expected') # check that product was marked as invalid and check the reason why data_db_product_properties = run_sql('HIVE', 'select_product_properties', True) assert expected_db_product_properties == data_db_product_properties
def test_sync_description(self): """ Tests that data is written to the database when [Sync Updates] is clicked """ expected_data = [['1', 'invisible gloves New Description']] d = self.driver select_listings_to_edit(d) bp = BulkPage(d) row = bp.listing_row('First something 1234 (1)') description = row.find_element_by_css_selector( 'div.body span.description') click(description) sleep(1) form = row.find_element_by_css_selector('div.body form > textarea') click(form) send_keys(form, ' New Description') click( d.find_element_by_css_selector('bulk-edit-dashboard-op-container')) sleep(1) click(bp.sync_updates_button()) wait_for_assert( expected_data, lambda: run_sql('HIVE', 'select_description_modified', True), 'Unexpected data in DB')
def test_sync_updates_tags(self): """ Tests that data is written to the database when [Sync Updates] is clicked """ expected_data = [['1', '{Tag01,AAA,BBB,CCC}'], ['2', '{Tag01,AAA,BBB,CCC}'], ['3', '{Tag01,AAA,BBB,CCC}']] select_listings_to_edit(self.driver) d = self.driver bp = BulkPage(d) send_keys(bp.operation_input(), 'AAA,BBB ,CCC') click(bp.operation_apply()) # Check apply button assert bp.operation_apply().is_enabled( ) is False, 'Apply button is enabled' click(bp.sync_updates_button()) # Check updated data in DB wait_for_assert(expected_data, lambda: run_sql('HIVE', 'select_tags_modified', True), 'Unexpected tags data in DB')
def test_import_taxonomy_id(self): """ Test verifies that taxonomy ID is correctly imported from Etsy (taxonomy_path or deprecated category_path are no longer used). Note: In API communication only taxonomy is used, but the text in UI is still called "Category". """ expected_db_task_queue = [ ['1', 'syncShop', '2', 'done', ''], ['2', 'downloadProduct', '1', 'done', ''] ] expected_taxonomy_id = [['1', '2390']] self.stop_all() self.set_etsy_testcase('listings_sync_category') run_sql('HIVE', 'listings_10', retry=2) self.restart_all() # after restart the listing is synced from etsy emulator # with different taxonomy path than before # check that syncShop task and download product tasks are done wait_for_assert( expected_db_task_queue, lambda: run_sql('HIVE', 'select_operations', True), 'syncShop task was not completed as expected') # check that taxonomy path and id were imported correctly taxonomy_id = run_sql('HIVE', 'select_taxonomy_id', True) assert taxonomy_id == expected_taxonomy_id
def test_edit_single_category(self): """ Tests that a single category can be edited """ expected_listings_01 = [ 'First something 1234 (1)\nClothing\nMen\'s Clothing\nSocks\nChoose Category', 'Second something 1235 (2)\nClothing\nMen\'s Clothing\nSocks\nChoose Category', 'Third something LG-512a (3)\nClothing\nMen\'s Clothing\nPants' ] expected_data = [['1', '1761']] self.select_listings_to_edit() d = self.driver bp = BulkPage(d) actual_listings = bp.listing_rows_texts_sorted() assert actual_listings == expected_listings_01 # update category of the 1st listing row = bp.listing_row('First something 1234 (1)') bp.select_category(['Accessories', 'Costume Accessories', 'Costume Tails & Ears', 'Costume Ears'], row, True) click(bp.sync_updates_button()) wait_for_assert(expected_data, lambda: run_sql('HIVE', 'select_taxonomy_id_modified', True), 'Unexpected taxonomy ID in DB')
def test_sync_updates_title(self): """ Tests that data is written to the database when [Sync Updates] is clicked It also tests that data are correctly processed in more than one batch (see HIVE-1216). """ # Configure Hive to process changes in batches of two listings # Env variable must be set before Hive is started os.environ['SYNC_UPDATES_BATCH_SIZE'] = '2' expected_data = [['1', 'hello First something 1234 (1)'], ['2', 'hello Second something 1235 (2)'], ['3', 'hello Third something LG-512a (3)']] select_listings_to_edit(self.driver) bp = BulkPage(self.driver) input_field = bp.operation_input() send_keys(input_field, 'hello ') # click on Apply and check Apply button click(bp.operation_apply()) wait_for_web_assert(False, bp.operation_apply().is_enabled, 'Apply button is enabled') # Sync changes click(bp.sync_updates_button()) # Check data in DB wait_for_assert(expected_data, lambda: run_sql('HIVE', 'select_title_modified', True), 'Unexpected title data in DB')
def test_etsy_listing_unavailable(self): """ Test verifies that shopSync task finishes correctly when a listing has status 'unavailable'. Such a listing does not contain all fields that listing should contain, i.e. title, price, quantity, therefore it is marked as invalid. See HIVE-1038 and HIVE-1046 for more info """ expected_db_task_queue = [['1', 'syncShop', '2', 'done', ''], ['2', 'downloadProduct', '1', 'done', '']] expected_db_product_properties = [[ '1', '2', 't', 'Unsupported listing state: unavailable' ]] self.stop_all() self.set_etsy_testcase('listings_status_unavailable') run_sql('HIVE', 'listings_10', retry=2) setup_rabbit() self.restart_all() # check that sync task is done wait_for_assert(expected_db_task_queue, lambda: run_sql('HIVE', 'select_operations', True), 'syncShop task was not completed as expected') # check that product was marked as invalid and check the reason why data_db_product_properties = run_sql('HIVE', 'select_product_properties', True) assert expected_db_product_properties == data_db_product_properties
def test_etsy_invalid_section(self): """ Test verifies, that invalid data from Etsy - null title in section - don't cause syncShop task to be failed. See HIVE-934 for more info. """ expected_db_data = [ ['1', 'syncShop', '2', 'done', ''], ] expected_db_data_sections = [['1', '2', '15183328', 'On Sale'], ['2', '2', '15180189', 'Holiday Gifts'], ['3', '2', '17365192', 'Summer Sale'], ['4', '2', '18790753', 'de'], ['5', '2', '18787742', 'bbbaa'], ['6', '2', '18790755', 'eeee']] self.stop_all() self.set_etsy_testcase('listings_invalid_section') run_sql('HIVE', 'listings_10', retry=2) setup_rabbit() self.restart_all() # check that sync task is done wait_for_assert(expected_db_data, lambda: run_sql('HIVE', 'select_operations', True), 'syncShop task was not completed as expected') # check that sections are synced correctly - invalid section is ignored data = run_sql('HIVE', 'select_sections', True) assert data == expected_db_data_sections
def wait_for_synced(self): log("Waiting for changes to be uploaded to Etsy") wait_for_assert('up_to_date', lambda: self.db.get_shop_status(self.shop_id), 'Shop not synced', retries=SHOP_SYNC_TIMEOUT) log("Shop synced")
def check_db_state(expected_product_offerings, expected_variation_properties, expected_variation_options): wait_for_assert(expected_product_offerings, lambda: run_sql('HIVE', 'select_product_offerings_short', True), 'Product offerings in DB are incorrect') variation_properties = run_sql('HIVE', 'select_variation_properties', True) assert variation_properties == expected_variation_properties variation_options = run_sql('HIVE', 'select_variation_options', True) assert variation_options == expected_variation_options
def wait_for_shop_up_to_date(self, timeout_sec: int): logging.info('Waiting for shop to be up to date') try: testing.wait_for_assert(ShopSyncStatus.UP_TO_DATE.value, lambda: self._get_current_sync_status(), retries=int(timeout_sec / 5) - 1, delay_sec=5, print_data=False) except AssertionError: raise DBControlTimeoutError('Shop is not up to date, timeout reached') else: return True finally: logging.info('Shop sync state: {} Last Sync Time: {}'.format(self.sync_status, self.last_sync_timestamp))
def check_etsy_emulator_requests(expected_api_calls): emulator_interface = EtsyEmulatorInterface() # wait for the changes to synchronize to etsy (emulator) wait_for_assert(True, lambda: len(emulator_interface.get_api_calls()) >= 8, "Not enough calls made to Etsy emulator", retries=30) expected_db_shop_status = [['GetvelaTest2', 'up_to_date', 'f', '']] wait_for_assert(expected_db_shop_status, lambda: run_sql('HIVE', 'select_shop_status', True), "Shop not synced", retries=30) # Check Etsy API calls emulator_interface.validate_api_calls(expected_api_calls, sort=True, normalize_func=emulator_interface.normalize_update_api_calls, message='Unexpected API PUT requests')
def wait_for_shop_to_sync(last_sync_time: arrow.Arrow = None, expected_status: str = None, timeout_sec: int = 30): """ Waits for shop under test to sync, either according to shop status or according to last sync timestamp. :param last_sync_time: timestamp of previous sync of the shop, as an Arrow object :param expected_status: expected end status of the shop :param timeout_sec: timeout for the wait operation """ assert last_sync_time or expected_status, 'Choose at least one parameter' # if we are importing a shop, should might not have a record yet in the shops table, wait for it wait_for_assert(1, lambda: len(run_sql('HIVE', 'select_shop_status', True))) if last_sync_time: wait_for_assert(last_sync_time, get_shop_last_sync_time, oper=operator.lt, delay_sec=1, retries=timeout_sec, message='Shop not synced') if expected_status: expected_db_shop_status = [expected_status, 'f', ''] wait_for_assert( expected_db_shop_status, lambda: run_sql('HIVE', 'select_shop_status', True)[0][1:], "Shop sync not finished", delay_sec=1, retries=timeout_sec)
def wait_for_web_assert(expected_data: Any, function: (), message: str = '', retries: int = 5, delay_sec: int = 1, oper=operator.eq): """ Function that permits to assert a condition with a timeout. Ignores WedDriver exceptions. :param expected_data: Data that are expected in the assert :param function: Function that returns data to be compared with expected data :param message: Error message for failed assert :param retries: Number of retries :param delay_sec: Delay between retries in seconds :param oper: operator to be used when comparing data """ wait_for_assert(expected_data, function, message=message, retries=retries, delay_sec=delay_sec, oper=oper, exceptions=[WebDriverException])
def test_etsy_duplicate_sections(self): """ Test verifies the situation when section is defined in Etsy then user creates the same section in VELA and synces - section must not be duplicated in our DB, its etsy ID should be updated only. For more info see HIVE-996. """ expected_db_data_queue = [ ['1', 'syncShop', '2', 'done', ''] ] expected_db_data_sections = [ ['1', '2', '15183328', 'On Sale'], ['2', '2', '15180189', 'Holiday Gifts'], ['3', '2', '17365192', 'Summer Sale'], ['4', '2', '18790753', 'de'], ['5', '2', '18787742', 'bbbaa'], ['6', '2', '18790755', 'eeee'] ] self.stop_all() self.set_etsy_testcase('listings_10') run_sql('HIVE', 'listings_10', retry=2) db = HiveDatabase(HIVE_DATABASE_URL) # set section etsy ID to NULL in test data # TODO: This should be reworked, section should be deleted from test data and created in UI as new db.change_section_etsy_id(None, 'eeee') self.restart_all() # check that sync task is done wait_for_assert( expected_db_data_queue, lambda: run_sql('HIVE', 'select_operations', True), 'syncShop task was not completed as expected') # check that sections are synced correctly, there are no duplicates data = run_sql('HIVE', 'select_sections', True) assert data == expected_db_data_sections
def check_db_state(expected_holiday): wait_for_assert(expected_holiday, lambda: run_sql('HIVE', 'select_holiday', True), 'Holiday data in DB are incorrect')
def check_db_state(expected_occasion): wait_for_assert(expected_occasion, lambda: run_sql('HIVE', 'select_occasion', True), 'Occasion data in DB are incorrect')