from itertools import zip_longest from urllib.parse import urlsplit from behave import step from nose.tools import assert_equal, assert_is_not_none, assert_in from webtest.forms import Text from atlas_um import pgdb from steps.helpers import add_dynamic_field @step("I click the search box") def step_click_the_search_box(context): context.response = context.atlas_um_client.get("/accounts/search") @step('I enter "{search_text}" into the search box') def step_enter_into_the_search_box(context, search_text): context.response = context.atlas_um_client.get( "/accounts/search", {"search_term": search_text} ) @step('I submit "{search_text}" into the accounts search box') def step_submit_into_accounts_search_box(context, search_text): search_form = context.response.forms["search-form"] search_form["search_term"] = search_text context.response = search_form.submit() @step("I should see the following accounts in recent searches") def step_should_see_accounts_in_recent_searches(context): searches = context.response.html.select_one( ".recent-searches .items-container" ) for (expected, actual) in zip_longest( context.table, searches(class_="item") ): actual_name = actual.get_text(strip=True) assert_equal(expected["name"], actual_name) @step("I should see the following accounts in modal search results") def step_should_see_accounts_in_modal_search_results(context): tbody = context.response.html.find(class_="search-results").find("tbody") for (expected, actual) in zip_longest(context.table, tbody("tr")): actual_name = actual.find(class_="account-name").get_text(strip=True) assert_equal(expected["name"], actual_name) actual_email = actual.find(class_="account-email").get_text(strip=True) assert_equal(expected["email"], actual_email) @step('I follow the link "{linkid}"') def step_follow_the_link(context, linkid): context.response = context.response.click(linkid=linkid) @step('I follow the link containing "{link_text}"') def step_follow_link_containing(context, link_text): context.response = context.response.click(description=link_text) @step('I should see "{search_text}" in the search box') def step_should_see_in_the_search_box(context, search_text): search_form = context.response.forms["search-form"] assert_equal(search_form["account_query"].value, search_text) @step('I should see "{search_text}" in the DNA account search box') def step_should_see_in_the_dna_search_box(context, search_text): search_form = context.response.forms["search-form"] assert_equal(search_form["search_term"].value, search_text) @step("I should see the following accounts") def step_should_see_following_accounts(context): """Table expected to have keys: name, email, status""" tbody = context.response.html.find(id="accounts-table").find("tbody") for (expected, actual) in zip_longest(context.table, tbody("tr")): first_name, last_name = expected["name"].split() actual_name = actual.find(class_="account-first-name").get_text( strip=True ) assert_equal(first_name, actual_name) actual_name = actual.find(class_="account-last-name").get_text( strip=True ) assert_equal(last_name, actual_name) actual_email = actual.find(class_="account-email").get_text(strip=True) assert_equal(expected["email"], actual_email) if "status" in context.table.headings: actual_status = actual.find(class_="account-status").get_text( strip=True ) assert_equal(expected["status"], actual_status) @step("I should be redirected to the userinfo page") def step_should_be_redirected_to_userinfo_page(context): assert_equal(context.response.status_code, 302) assert_equal( urlsplit(context.response.headers["Location"]).path, "/userinfo" ) @step('I should see the account detail "Given Name" as "{given_name}"') def step_should_see_account_detail_given_name(context, given_name): given_name_detail = context.response.html.find( id="account-detail-given-name" ) assert_equal(given_name, given_name_detail.get_text(strip=True)) @step('I should see the account detail "Family Name" as "{family_name}"') def step_should_see_family_name(context, family_name): family_name_detail = context.response.html.find( id="account-detail-family-name" ) assert_equal(family_name, family_name_detail.get_text(strip=True)) @step('I should see the account detail "Email" as "{email}"') def step_should_see_email(context, email): email_detail = context.response.html.find(id="account-detail-email") assert_equal(email, email_detail.get_text(strip=True)) @step('I should see "{account_owner}" account editing page') def step_should_see_account_editing_page(context, account_owner): context.extra_lookup_values["job_category"].id subnav_header = ( context.response.html.find(id="subnav-header") .find(recursive=False, text=True) .strip() ) assert_equal(account_owner, subnav_header) editing_form = context.response.html.find(id="account-editing-form") assert_is_not_none(editing_form) @step("I update data and save") def step_update_data_and_save(context): editing_form = context.response.forms["account-editing-form"] # checking over the field that is available for all account types editing_form["job_category"] = context.extra_lookup_values[ "job_category" ].id context.response = editing_form.submit() @step('I should see "{account_owner}" account page with updated data') def step_should_see_page_with_updated_data(context, account_owner): assert_equal(context.response.status_code, 302) account_page = context.response.follow() subnav_header = ( account_page.html.find(id="subnav-header") .find(recursive=False, text=True) .strip() ) assert_equal(account_owner, subnav_header) updated_job_category = account_page.html.find( id="account-detail-job-category" ) assert_equal( updated_job_category.get_text(strip=True), context.extra_lookup_values["job_category"].name, ) @step('I should see "{product_name}" show product page for "{account_owner}"') def step_should_see_show_product_page(context, product_name, account_owner): details_header = context.response.html.find( class_="details-header-with-extra" ) assert_equal(details_header.get_text(strip=True), product_name) subnav_header = ( context.response.html.find(id="subnav-header") .find(recursive=False, text=True) .strip() ) assert_equal(account_owner, subnav_header) @step('I should see left sidebar with "{product_name}" product link') def step_should_see_left_sidebar_with_link(context, product_name): left_menu_product_link = context.response.html.select_one( ".left-menu a.item" ).get_text(strip=True) assert_equal(left_menu_product_link, product_name) @step('I should see edit button with text "{button_text}"') def step_should_edit_button_with(context, button_text): edit_button = context.response.html.select_one("#edit-button") assert_equal(edit_button.get_text(strip=True), button_text) @step("I should see the following readonly claim values") def step_should_see_the_following_readonly_claim_values(context): for claim_name, claim_value in context.table: claim_name_instance = pgdb.ClaimName.query.filter_by( friendly=claim_name ).first() actual_label = context.response.html.select_one( f".product-details " f"[data-element-name=claim_{claim_name_instance.id}] " f"label" ).get_text(strip=True) assert_equal(actual_label, claim_name_instance.friendly) actual_value = context.response.html.select_one( f".product-details " f"[data-element-name=claim_{claim_name_instance.id}] " f".value" ).get_text(strip=True) assert_equal(actual_value, claim_value) @step("I should see the following editable claim values") def step_should_see_the_following_editable_claim_values(context): for claim_name, claim_value in context.table: claim_name_instance = pgdb.ClaimName.query.filter_by( friendly=claim_name ).first() actual_label = context.response.html.select_one( f".product-details " f"[data-element-name=claim_{claim_name_instance.id}] " f"label" ).get_text(strip=True) assert_equal(actual_label, claim_name_instance.friendly) actual_value = "".join( el.get_text(strip=True) for el in context.response.html.select( f".product-details " f"[data-element-name=claim_{claim_name_instance.id}] " f"select#claim_{claim_name_instance.id} option[selected]" ) ) assert_equal(actual_value, "".join(claim_value.split(", "))) @step( 'I should see timestamps section with fields "{created_at}" "{updated_at}"' ) def step_i_should_see_timestamps_section(context, created_at, updated_at): created_label = context.response.html.select_one( ".product-details " "[data-element-name=created_at] " "label" ).get_text(strip=True) assert_equal(created_label, created_at) updated_label = context.response.html.select_one( ".product-details " "[data-element-name=updated_at] " "label" ).get_text(strip=True) assert_equal(updated_label, updated_at) @step('I should see "{product_name}" edit product page for "{account_owner}"') def step_should_see_edit_product_page(context, product_name, account_owner): details_header = context.response.html.find( class_="details-header-with-extra" ) assert_equal(details_header.get_text(strip=True), product_name) subnav_header = ( context.response.html.find(id="subnav-header") .find(recursive=False, text=True) .strip() ) assert_equal(account_owner, subnav_header) save_button = context.response.html.select_one("button[value=SAVE]") assert_equal(save_button.get_text(strip=True), "Save") @step("I update and save the following claim values") def step_update_and_save_the_following_claim_values(context): claims_form = context.response.forms["product-editing-form"] for claim_name, claim_values in context.table: claim_name_instance = pgdb.ClaimName.query.filter_by( friendly=claim_name ).first() if claim_name_instance.multiple_values_allowed: value = [ v[0] for v in pgdb.pgdb.session.query(pgdb.ClaimValue.id).filter( pgdb.ClaimValue.claim_name == claim_name_instance, pgdb.ClaimValue.friendly.in_(claim_values.split(", ")), ) ] else: value = ( pgdb.pgdb.session.query(pgdb.ClaimValue.id) .filter( pgdb.ClaimValue.claim_name == claim_name_instance, pgdb.ClaimValue.friendly == claim_values, ) .scalar() ) claims_form[f"claim_{claim_name_instance.id}"] = value context.response = claims_form.submit() @step("I should see product disable button") def step_should_see_product_disable_button(context): disable_button = context.response.html.find(class_="disable-button") assert_equal(disable_button.get_text(strip=True), "Disable") @step("I disable the product") def step_disable_the_product(context): claims_form = context.response.forms["product-editing-form"] context.response = claims_form.submit(name="action", value="DISABLE") @step('I should receive response with "{status_code}" status') def step_should_receive_response_with_status(context, status_code): assert_equal(context.response.status_code, int(status_code)) @step("I should see the account creation page") def step_should_see_the_account_creation_page(context): title = context.response.html.title.get_text(strip=True) assert_equal(title, "Create New User") details_header = context.response.html.find( class_="details-header-with-extra" ) assert_equal(details_header.get_text(strip=True), "User Details") subnav_header = ( context.response.html.find(id="subnav-header") .find(recursive=False, text=True) .strip() ) assert_equal(subnav_header, "Create New User") save_button = context.response.html.select_one("button[value=SAVE]") assert_is_not_none(save_button, "Save") assert_is_not_none(context.response.html.find(id="account-editing-form")) @step("Submit the following user details") def step_submit_the_following_user_details(context): form = context.response.forms["account-editing-form"] for field, value in context.table: form[field] = value form["job_category"] = form["job_category"].options[1][0] context.response = form.submit() context.submitted_details_table = context.table @step("I should be redirected to products page for created account") def step_should_be_redirected_to_products_page(context): assert_equal(context.response.status_code, 302) dna_account = pgdb.DNAAccount.query.filter_by( **{k: v for k, v in context.submitted_details_table} ).first() products_url = f"/accounts/{dna_account.id}/products" redirect_url = urlsplit(context.response.location)[2] assert_equal(products_url, redirect_url) @step("I should download CSV file matching the following content") def step_should_download_csv_file_matching_the_content(context): context.response.status_code = 200 assert_equal(context.response.content_type, "text/csv") assert_equal( context.response.headers["Content-Disposition"], "attachment; filename=users.csv", ) expected_content_list = context.text.splitlines() actual_content_list = context.response.testbody.splitlines() for actual_line, expected_line in zip( actual_content_list, expected_content_list ): for actual_field, expected_field in zip( actual_line.split(","), expected_line.split(",") ): if expected_field == "_": continue assert_equal(actual_field, expected_field) @step("I should be redirected to the first admin settings page") def step_should_be_redirected_to_the_first_admin_settings_page(context): assert_equal(context.response.status_code, 302) assert_in( "/settings/global_settings/resource_groups", context.response.location ) @step('I should see the following "{items_type}" user details items') def step_i_should_see_the_following_user_details_items(context, items_type): assert_equal( context.response.html.select_one( ".ui.main.container.content h4" ).get_text(strip=True), items_type, ) for name, is_active in context.table: assert any( el.get_text(strip=True) == name for el in context.response.html.select( ".settings-field.name .item-repr" ) ) @step('I should see the exact "{items_type}" user details items') def step_i_should_see_the_exact_user_details_items(context, items_type): assert_equal( context.response.html.select_one( ".ui.main.container.content h4" ).get_text(strip=True), items_type, ) expected = [item[0] for item in context.table] actual = [ el.get_text(strip=True) for el in context.response.html.select( ".settings-field.name .item-repr" ) ] assert_equal(all([e == a for e, a in zip(expected, actual)]), True) @step('I should see the exact "{items_type}" claim names items') def step_i_should_see_the_exact_claim_names_items(context, items_type): assert_equal( context.response.html.select_one( ".ui.main.container.content h4" ).get_text(strip=True), items_type, ) expected = [item[0] for item in context.table] actual = [ el.get_text(strip=True) for el in context.response.html.select( ".settings-field.friendly .item-repr" ) ] assert_equal(all([e == a for e, a in zip(expected, actual)]), True) @step('I should see the exact "{items_type}" claim values items') def step_i_should_see_the_exact_claim_values_items(context, items_type): assert_equal( context.response.html.select_one( ".ui.main.container.content h4" ).get_text(strip=True), items_type, ) expected = [item[0] for item in context.table] actual = [ el.get_text(strip=True) for el in context.response.html.select( ".settings-field.friendly .item-repr" ) ] assert_equal(all([e == a for e, a in zip(expected, actual)]), True) @step('I search the following "{items_type}" item "{item_search_term}"') def step_i_search_the_following_user_details_item( context, items_type, item_search_term ): form = context.response.forms["search-item-form"] add_dynamic_field(form, "item_search_term", item_search_term) context.response = form.submit() @step("I should see the following resource groups in the sidebar") def step_i_should_see_the_following_resource_groups_in_the_sidebar(context): for resource_group in context.table: assert any( el.get_text(strip=True) == resource_group[0] for el in context.response.html.select(".left-menu .header.item") ) @step("I should see the following resource groups items") def step_i_should_see_the_following_user_resource_groups_items(context): assert_equal( context.response.html.select_one( ".ui.main.container.content h4" ).get_text(strip=True), "Resource Groups", ) for resource_group in context.table: assert any( el.get_text(strip=True) == resource_group[0] for el in context.response.html.select( ".settings-field.name .item-repr" ) ) @step("I should see the following Claim Names items") def step_i_should_see_the_following_user_claim_names_items(context): assert_in( "Claim Names", context.response.html.select_one( ".ui.main.container.content h4" ).get_text(strip=True), ) for clain_name in context.table: assert any( el.get_text(strip=True) == clain_name[0] for el in context.response.html.select( ".settings-field.friendly .item-repr" ) ) @step("I should see the following Claim Names in the sidebar") def step_i_should_see_the_following_claim_names_in_the_sidebar(context): for claim_name in context.table: assert any( el.get_text(strip=True) == claim_name[0] for el in context.response.html.select(".left-menu .item") ) @step('I should see the following Claim Values items for "{claim_name}"') def step_i_should_see_the_following_user_claim_values_items( context, claim_name ): assert_in( claim_name, context.response.html.select_one( ".ui.main.container.content h4" ).get_text(strip=True), ) for clain_name in context.table: assert any( el.get_text(strip=True) == clain_name[0] for el in context.response.html.select( ".settings-field.friendly .item-repr" ) ) @step('I add new user settings item with "{field_name}" "{unit_name}"') def i_add_new_new_user_settings_item(context, field_name, unit_name): form = context.response.forms["new-item-form"] field = Text(form, "input", field_name, 1, unit_name) form.fields[field_name] = [field] form.field_order.append((field_name, field)) form[field_name] = unit_name context.response = form.submit()