from collections import namedtuple from urllib.parse import urlparse from bs4 import BeautifulSoup from flask import render_template, url_for from atlas_um.pgdb import Product from atlas_um.dna_accounts.forms import product_form_factory from tests.atlas_um.factories import ( ClaimNameFactory, ClaimValueFactory, DNAAccountFactory, ) from . import helpers class TestEditProduct: def test_titles(self, app, pgdb_session): context = self.build_render_context(pgdb_session) with app.test_request_context( self.url_for_this(app, context.account, context.product.code) ): pgdb_session.add(context.account) pgdb_session.commit() form = product_form_factory(context.product) page = self.render_soup(form=form, **context._asdict()) account = context.account product_name = context.product.name assert ( page.title.get_text(strip=True) == f"{account.given_name} {account.family_name}: {product_name}" ) page_head = page.find(id="subnav-header") vip_text = "VIP" if account.is_vip else "" assert ( page_head.get_text(strip=True) == f"{account.given_name} {account.family_name}" f"{vip_text}{account.status}EXTERNAL" ) subheader = page.find(class_="details-header-with-extra") assert subheader.get_text(strip=True) == product_name def test_sidebar(self, app, pgdb_session): context = self.build_render_context(pgdb_session) with app.test_request_context( self.url_for_this(app, context.account, context.product.code) ): pgdb_session.add(context.account) pgdb_session.commit() form = product_form_factory(context.product) page = self.render_soup(form=form, **context._asdict()) sidebar = page.find(class_="left-sidebar") assert sidebar is not None for group, _ in context.account.resource_groups_with_status: url = url_for( "dna_accounts.show_product", account_id=context.account.id, product_code=group.id, ) actual_link = sidebar.find("a", attrs={"href": url}) assert actual_link is not None assert actual_link.get_text(strip=True) == group.name def test_claims(self, app, pgdb_session): context = self.build_render_context(pgdb_session) with app.test_request_context( self.url_for_this(app, context.account, context.product.code) ): pgdb_session.add(context.account) pgdb_session.commit() form = product_form_factory(context.product) page = self.render_soup(form=form, **context._asdict()) for claim_name, claim_values in context.product.claims.items(): actual_friendly = page.select_one( f"[data-element-name={claim_name.internal_name}]>label" ).get_text(strip=True) assert actual_friendly == claim_name.friendly def test_status_active(self, app, pgdb_session, faker): context = self.build_render_context(pgdb_session) product = context.product product.is_disabled = False product.created_at = faker.date_time() product.updated_at = faker.date_time() with app.test_request_context( self.url_for_this(app, context.account, context.product.code) ): pgdb_session.add(context.account) pgdb_session.commit() form = product_form_factory(context.product) page = self.render_soup(form=form, **context._asdict()) disable_button = page.find(class_="disable-button") assert disable_button is not None created_at = page.find(id="created_at") assert created_at.get_text(strip=True) == product.created_at.strftime( "%m/%d/%y, %-I:%M %p" ) created_at_label = page.select_one( "[data-element-name=created_at]>label" ) assert created_at_label.get_text(strip=True) == "Enabled" updated_at = page.find(id="updated_at") assert updated_at.get_text(strip=True) == product.updated_at.strftime( "%m/%d/%y, %-I:%M %p" ) updated_at_label = page.select_one( "[data-element-name=updated_at]>label" ) assert updated_at_label.get_text(strip=True) == "Last modified" def test_status_disabled(self, app, pgdb_session, faker): context = self.build_render_context(pgdb_session) product = context.product product.is_disabled = True product.created_at = faker.date_time() product.updated_at = faker.date_time() with app.test_request_context( self.url_for_this(app, context.account, context.product.code) ): pgdb_session.add(context.account) pgdb_session.commit() form = product_form_factory(context.product) page = self.render_soup(form=form, **context._asdict()) disable_button = page.find(class_="disable-button") assert disable_button is None created_at = page.find(id="created_at") assert created_at.get_text(strip=True) == product.created_at.strftime( "%m/%d/%y, %-I:%M %p" ) created_at_label = page.select_one( "[data-element-name=created_at]>label" ) assert created_at_label.get_text(strip=True) == "First enabled" updated_at = page.find(id="updated_at") assert updated_at.get_text(strip=True) == product.updated_at.strftime( "%m/%d/%y, %-I:%M %p" ) updated_at_label = page.select_one( "[data-element-name=updated_at]>label" ) assert updated_at_label.get_text(strip=True) == "Disabled" def test_copyright_notice( self, app, pgdb_session, expected_copyright_notice ): context = self.build_render_context(pgdb_session) with app.test_request_context( self.url_for_this(app, context.account, context.product.code) ): pgdb_session.add(context.account) pgdb_session.commit() form = product_form_factory(context.product) page = self.render_soup(form=form, **context._asdict()) footer = page.find("footer") copyright_notice = footer.find(id="copyright-notice") assert ( copyright_notice.get_text(strip=True) == expected_copyright_notice ) def test_frontend_libs_are_added( self, app, pgdb_session, expected_copyright_notice ): context = self.build_render_context(pgdb_session) with app.test_request_context( self.url_for_this(app, context.account, context.product.code) ): pgdb_session.add(context.account) pgdb_session.commit() form = product_form_factory(context.product) page = self.render_soup(form=form, **context._asdict()) assert all(helpers.added_frontend_libs(page)) # Helpers def build_render_context(self, pgdb_session): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() claim_name = ClaimNameFactory.build( claim_values_serializer="BooleanAnd" ) claim_value = ClaimValueFactory.build( claim_name=claim_name, components={"value1": 1} ) pgdb_session.add(claim_value) account.claim_values = [claim_value] product = Product( resource_group=claim_name.resource_group, account=account ) Context = namedtuple("Context", "account product") return Context(account, product) def url_for_this(self, app, account, product_code, **kwargs): kwargs["endpoint"] = "dna_accounts.edit_product" kwargs["account_id"] = account.id kwargs["product_code"] = product_code with app.app_context(): u = url_for(**kwargs) return u def urlspec_for_this(self, app, **kwargs): u = urlparse(self.url_for_this(app, **kwargs)) return u._replace(scheme="", netloc="") def render_soup(self, **kwargs): rt = render_template("dna_accounts/edit_product.html", **kwargs) return BeautifulSoup(rt, "html.parser")