Spaces:
Running
Running
| """Fast regression checks for dataset-first generation. | |
| These tests do not call Snowflake or ThoughtSpot. They validate that the | |
| dataset-first builders produce coherent table bundles and relationship-bearing | |
| DDL before the slower browser quality suite runs against the test Space. | |
| """ | |
| from demoprep_app.dataset.generators.retail_sales import RetailSalesDatasetGenerator | |
| from demoprep_app.scenario.extractor import ExtractedScenario | |
| from demoprep_app.pipeline import dataset_first | |
| from demoprep_app.pipeline.dataset_first import build_dataset_first_demo, infer_scenario_type | |
| from demoprep_app.dataset.quality import validate_dataset_quality | |
| from demoprep_app.scenario.contract import DimensionSpec, ScenarioContract | |
| from demoprep_app.scenario.families import SCENARIO_FAMILIES | |
| def test_saas_sales_specialized_builder_has_expected_shape(): | |
| build = build_dataset_first_demo( | |
| company_name="Datadog", | |
| company_url="https://datadog.com", | |
| use_case="Software as a Service Sales", | |
| vertical="Technology", | |
| function="Sales", | |
| row_count_guidance=100, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == "saas_sales" | |
| assert [table.name for table in build.dataset.tables] == [ | |
| "MONTHS", | |
| "ACCOUNTS", | |
| "PRODUCTS", | |
| "SALES_REPS", | |
| "SALES_PIPELINE", | |
| ] | |
| assert build.ddl.count("CREATE TABLE") == 5 | |
| assert build.ddl.count("FOREIGN KEY") == 4 | |
| pipeline = build.dataset.table_map()["SALES_PIPELINE"] | |
| sample = pipeline.rows[:25] | |
| assert sample | |
| for row in sample: | |
| assert 0 <= row["PROBABILITY_PCT"] <= 100 | |
| assert row["EXPECTED_ARR_USD"] == round(row["PIPELINE_AMOUNT_USD"] * row["PROBABILITY_PCT"] / 100.0, 2) | |
| if row["SALES_STAGE"] == "Closed Won": | |
| assert row["WON_ARR_USD"] == row["PIPELINE_AMOUNT_USD"] | |
| assert row["LOST_ARR_USD"] == 0.0 | |
| if row["SALES_STAGE"] == "Closed Lost": | |
| assert row["LOST_ARR_USD"] == row["PIPELINE_AMOUNT_USD"] | |
| assert row["WON_ARR_USD"] == 0.0 | |
| def test_all_scenario_families_generate_relationship_ddl(): | |
| failures = [] | |
| for scenario_type in SCENARIO_FAMILIES: | |
| research_context = "" | |
| if scenario_type == "retail_sales": | |
| research_context = ( | |
| "Retail sales products include running shoes, basketball shoes, training apparel, " | |
| "hoodies, shorts, jerseys, sneakers, backpacks, and performance socks. " | |
| "Channels include retail stores, online, mobile app, outlet, and retail partners." | |
| ) | |
| build = build_dataset_first_demo( | |
| company_name="Acme", | |
| company_url="https://example.com", | |
| use_case=scenario_type.replace("_", " "), | |
| vertical="", | |
| function="", | |
| row_count_guidance=25, | |
| research_context=research_context, | |
| ) | |
| if build is None: | |
| failures.append(f"{scenario_type}: no build") | |
| continue | |
| fact_tables = [table for table in build.dataset.tables if table.is_fact] | |
| expected_fk_count = max(0, len(build.dataset.tables) - 2) | |
| actual_fk_count = build.ddl.count("FOREIGN KEY") | |
| if not fact_tables: | |
| failures.append(f"{scenario_type}: no fact table") | |
| if build.ddl.count("CREATE TABLE") != len(build.dataset.tables): | |
| failures.append(f"{scenario_type}: DDL table count mismatch") | |
| if actual_fk_count < expected_fk_count: | |
| failures.append(f"{scenario_type}: only {actual_fk_count} foreign keys, expected at least {expected_fk_count}") | |
| assert not failures, "\n".join(failures) | |
| def test_custom_dataset_first_refuses_weak_fallback_when_llm_contract_required(monkeypatch): | |
| def fake_extract_dataset_scenario(**kwargs): | |
| return ExtractedScenario( | |
| scenario_type="professional_services_engagements", | |
| business_domain="professional services engagements", | |
| fact_grain="client-service-line-sector-month", | |
| confidence=0.55, | |
| source="fallback", | |
| constraints=["LLM extraction failed: ConnectionError: connection failed"], | |
| ) | |
| monkeypatch.setattr(dataset_first, "extract_dataset_scenario", fake_extract_dataset_scenario) | |
| try: | |
| build_dataset_first_demo( | |
| company_name="Accenture", | |
| company_url="https://accenture.com", | |
| use_case="Demo analytics for Accenture's technology and management consulting business.", | |
| vertical="* CUSTOM *", | |
| function="", | |
| row_count_guidance=100, | |
| use_llm_contract=True, | |
| ) | |
| except ValueError as exc: | |
| message = str(exc) | |
| else: | |
| raise AssertionError("Expected weak fallback contract to be refused") | |
| assert "AI dataset contract unavailable" in message | |
| assert "Refusing weak fallback contract" in message | |
| def test_custom_sports_venue_without_explicit_tables_does_not_use_canned_template(): | |
| use_case = ( | |
| "A live entertainment arena needs analytics across its basketball teams, " | |
| "Downtown Center, Uptown Theater, concerts, fan demographics, ticket tiers, " | |
| "attendance, suites, sponsorships, and email marketing channel. Include " | |
| "Team Alpha and Team Beta as teams." | |
| ) | |
| build = build_dataset_first_demo( | |
| company_name="Example Arena Group", | |
| company_url="https://example.com", | |
| use_case=use_case, | |
| vertical="* CUSTOM *", | |
| function=None, | |
| row_count_guidance=100, | |
| ) | |
| assert build is None | |
| def test_custom_professional_services_without_explicit_tables_does_not_use_canned_template(): | |
| use_case = ( | |
| "Build a professional services demo for EY's assurance and consulting lines. " | |
| "Track billable hours vs. budget, revenue per sector, staff pyramid health, " | |
| "and cross-sell rate from audit to advisory. KPIs: realized rate, " | |
| "engagement margin, repeat client revenue %." | |
| ) | |
| build = build_dataset_first_demo( | |
| company_name="EY US", | |
| company_url="https://ey.com", | |
| use_case=use_case, | |
| vertical="* CUSTOM *", | |
| function=None, | |
| row_count_guidance=100, | |
| ) | |
| assert build is None | |
| def test_quality_pool_domains_do_not_fall_back_to_generic_templates(): | |
| cases = [ | |
| ("FedEx", "fedex.com", "Transportation & Logistics", "Shipping", "Sales", "shipping_sales", "SHIPMENT_SALES", {"SHIPMENTS", "NET_REVENUE_USD", "ON_TIME_RATE_PCT"}), | |
| ("Stellantis", "stellantis.com", "Manufacturing", "Automotive", "Sales", "automotive_sales", "VEHICLE_SALES", {"VEHICLES_SOLD", "INCENTIVE_SPEND_USD", "DAYS_SUPPLY"}), | |
| ("Marriott", "marriott.com", "Travel & Hospitality", "Hotels", "Finance", "hotel_finance", "HOTEL_FINANCIALS", {"OCCUPANCY_PCT", "ADR_USD", "REVPAR_USD"}), | |
| ("PVH", "pvh.com", "Retail & Consumer Goods", "Fashion/Apparel", "Marketing", "apparel_marketing", "APPAREL_MARKETING", {"MARKDOWN_USD", "ROAS", "RETURN_RATE_PCT"}), | |
| ] | |
| for company, url, vertical, line, function, scenario_type, fact_table, expected_columns in cases: | |
| build = build_dataset_first_demo( | |
| company_name=company, | |
| company_url=f"https://{url}", | |
| use_case=f"{line} {function}", | |
| vertical=vertical, | |
| function=function, | |
| row_count_guidance=100, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == scenario_type | |
| table = build.dataset.table_map()[fact_table] | |
| column_names = {column.name for column in table.columns} | |
| assert expected_columns <= column_names | |
| def test_shipping_sales_dimensions_are_demo_safe_and_not_numbered_placeholders(): | |
| build = build_dataset_first_demo( | |
| company_name="Echo Global", | |
| company_url="https://echo.com", | |
| use_case="Shipping Sales", | |
| vertical="Transportation & Logistics", | |
| function="Sales", | |
| row_count_guidance=100, | |
| ) | |
| assert build is not None | |
| table_map = build.dataset.table_map() | |
| for table_name, column_name in [ | |
| ("ACCOUNTS", "ACCOUNT_NAME"), | |
| ("SERVICES", "SERVICE_NAME"), | |
| ("ROUTES", "ROUTE_NAME"), | |
| ("SALES_REPS", "SALES_REP_NAME"), | |
| ]: | |
| values = [row[column_name] for row in table_map[table_name].rows] | |
| assert values | |
| assert not any(" 0" in value or value.endswith(tuple(str(i).zfill(2) for i in range(1, 40))) for value in values) | |
| assert not any("Sales Rep " in value or "Account " in value or "Service " in value or "Route " in value for value in values) | |
| assert validate_dataset_quality(build.dataset).ok | |
| def test_retail_sales_store_names_are_demo_safe_and_not_numbered_placeholders(): | |
| build = build_dataset_first_demo( | |
| company_name="Nike", | |
| company_url="https://nike.com", | |
| use_case="Retail Sales", | |
| vertical="Retail & Consumer Goods", | |
| function="Sales", | |
| row_count_guidance=100, | |
| research_context=( | |
| "Nike retail sales products include running shoes, basketball shoes, training shoes, " | |
| "Dri-FIT performance apparel, hoodies, shorts, jerseys, sneakers, backpacks, and performance socks." | |
| ), | |
| ) | |
| assert build is not None | |
| table_map = build.dataset.table_map() | |
| values = [row["STORE_NAME"] for row in table_map["STORES"].rows] | |
| assert len(values) == 36 | |
| assert "Nike Fifth Avenue Flagship" in values | |
| assert not any(value.endswith(tuple(str(i).zfill(2) for i in range(1, 40))) for value in values) | |
| assert not any(" Metro " in value or " Outlet " in value for value in values) | |
| assert validate_dataset_quality(build.dataset).ok | |
| def test_retail_product_expansion_uses_named_variants_not_numbered_placeholders(): | |
| scenario = ScenarioContract( | |
| company_name="Sonos", | |
| company_url="https://sonos.com", | |
| use_case="Consumer Electronics Sales", | |
| scenario_type="retail_sales", | |
| fact_grain="store-product-channel-day", | |
| dimensions=[ | |
| DimensionSpec(name="PRODUCTS", semantic_role="product", values=["Soundbars", "Speakers", "Accessories", "Streaming"]), | |
| ], | |
| metadata={"seed": 123}, | |
| ) | |
| dataset = RetailSalesDatasetGenerator().generate(scenario, row_count=100) | |
| values = [row["PRODUCT_NAME"] for row in dataset.table_map()["PRODUCTS"].rows] | |
| assert len(values) == 36 | |
| assert not any("Variant " in value for value in values) | |
| assert not any(value.endswith(tuple(str(i).zfill(2) for i in range(1, 40))) for value in values) | |
| assert validate_dataset_quality(dataset).ok | |
| def test_retail_contract_uses_researched_products_before_generation(): | |
| build = build_dataset_first_demo( | |
| company_name="Nike", | |
| company_url="https://nike.com", | |
| use_case="Retail Sales", | |
| vertical="Retail & Consumer Goods", | |
| function="Sales", | |
| row_count_guidance=100, | |
| research_context=( | |
| "Nike retail sales demo products include running shoes, basketball shoes, " | |
| "training shoes, soccer boots, Dri-FIT performance apparel, hoodies, shorts, and jerseys. " | |
| "Channels include Nike stores, Nike.com, mobile app, outlet, and retail partners." | |
| ), | |
| ) | |
| assert build is not None | |
| table_map = build.dataset.table_map() | |
| products = [row["PRODUCT_NAME"] for row in table_map["PRODUCTS"].rows] | |
| product_prices = [row["LIST_PRICE"] for row in table_map["PRODUCTS"].rows] | |
| channels = {row["CHANNEL"] for row in table_map["SALES_FACT"].rows} | |
| fact_columns = {column.name for column in table_map["SALES_FACT"].columns} | |
| assert "Running Shoes" in products | |
| assert "Basketball Shoes" in products | |
| assert "Dri-FIT" in products | |
| assert "Streaming Platform" not in channels | |
| assert "Promotional Offer" not in channels | |
| assert "ACTIVE_ACCOUNTS" not in fact_columns | |
| assert "PLATFORM_USAGE_HOURS" not in fact_columns | |
| assert min(product_prices) >= 18 | |
| assert max(product_prices) <= 219 | |
| assert build.scenario.metadata["company_contract_sources"]["PRODUCTS"] == "fallback" | |
| assert validate_dataset_quality(build.dataset).ok | |
| def test_retail_contract_blocks_incompatible_research_terms_before_generation(): | |
| try: | |
| build_dataset_first_demo( | |
| company_name="Nike", | |
| company_url="https://nike.com", | |
| use_case="Fashion/Apparel Sales", | |
| vertical="Retail & Consumer Goods", | |
| function="Sales", | |
| row_count_guidance=100, | |
| research_context="Bad extracted terms should not drive products: soundbars, streaming, smart tv.", | |
| ) | |
| except ValueError as exc: | |
| message = str(exc) | |
| else: | |
| raise AssertionError("Expected company contract failure") | |
| assert "Company data contract failed" in message | |
| assert "incompatible product terms" in message | |
| def test_retail_contract_repairs_thin_research_instead_of_failing_run(): | |
| build = build_dataset_first_demo( | |
| company_name="Nike", | |
| company_url="https://nike.com", | |
| use_case="Retail Sales", | |
| vertical="Retail & Consumer Goods", | |
| function="Sales", | |
| row_count_guidance=100, | |
| research_context=None, | |
| ) | |
| assert build is not None | |
| table_map = build.dataset.table_map() | |
| products = [row["PRODUCT_NAME"] for row in table_map["PRODUCTS"].rows] | |
| channels = {row["CHANNEL"] for row in table_map["SALES_FACT"].rows} | |
| warnings = build.scenario.metadata["company_contract_warnings"] | |
| assert any("too few researched" in warning for warning in warnings) | |
| assert len(products) == 36 | |
| assert any("Shoe" in product or "Sneaker" in product or "Runner" in product for product in products) | |
| assert "Streaming Platform" not in channels | |
| assert validate_dataset_quality(build.dataset).ok | |
| def test_sonos_retail_contract_allows_consumer_electronics_products(): | |
| build = build_dataset_first_demo( | |
| company_name="Sonos", | |
| company_url="https://sonos.com", | |
| use_case="Consumer Electronics Sales", | |
| vertical="Retail & Consumer Goods", | |
| function="Sales", | |
| row_count_guidance=100, | |
| research_context="Sonos sells speakers, soundbars, portable audio, home theater, and accessories.", | |
| ) | |
| assert build is not None | |
| products = [row["PRODUCT_NAME"] for row in build.dataset.table_map()["PRODUCTS"].rows] | |
| assert "Soundbars" in products | |
| assert "Speakers" in products | |
| assert build.scenario.metadata["company_contract_sources"]["PRODUCTS"] == "fallback" | |
| assert validate_dataset_quality(build.dataset).ok | |
| def test_transportation_function_routing_keeps_sales_and_finance_distinct(): | |
| cases = [ | |
| ("Shipping", "Sales", "shipping_sales"), | |
| ("Shipping", "Marketing", "marketing_funnel"), | |
| ("Shipping", "HR", "workforce_hr"), | |
| ("Shipping", "IT", "it_operations"), | |
| ("Shipping", "Legal", "legal_matter_management"), | |
| ("Trucking", "Sales", "sales_pipeline"), | |
| ("Trucking", "Marketing", "marketing_funnel"), | |
| ("Trucking", "Finance", "trucking_finance"), | |
| ("Trucking", "HR", "workforce_hr"), | |
| ("Trucking", "IT", "it_operations"), | |
| ("Trucking", "Legal", "legal_matter_management"), | |
| ("Air Transport", "Sales", "airline_route_operations"), | |
| ("Air Transport", "Finance", "airline_finance"), | |
| ("Air Transport", "HR", "workforce_hr"), | |
| ("Air Transport", "Legal", "legal_matter_management"), | |
| ] | |
| for line, function, expected in cases: | |
| assert infer_scenario_type( | |
| use_case=f"{line} {function}", | |
| vertical="Transportation & Logistics", | |
| function=function, | |
| ) == expected | |
| def test_trucking_sales_does_not_route_to_trucking_finance(): | |
| build = build_dataset_first_demo( | |
| company_name="Linxup", | |
| company_url="https://www.linxup.com/", | |
| use_case="Trucking Sales", | |
| vertical="Transportation & Logistics", | |
| function="Sales", | |
| row_count_guidance=100, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == "sales_pipeline" | |
| assert "SALES_PIPELINE" in build.dataset.table_map() | |
| assert "TRUCKING_FINANCIALS" not in build.dataset.table_map() | |
| def test_ad_yield_arpu_routes_to_ad_monetization_not_sales_pipeline(): | |
| build = build_dataset_first_demo( | |
| company_name="Vizio", | |
| company_url="https://www.vizio.com/", | |
| use_case=( | |
| "Focus on Ad yield and ARPU, optimizing revenue through SmartCast users " | |
| "across CTV placements, FAST channels, ad requests, eCPM, fill rate, " | |
| "completion rate, watch time, and audience cohorts." | |
| ), | |
| vertical="Media & Entertainment", | |
| function="Revenue", | |
| row_count_guidance=100, | |
| use_llm_contract=True, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == "ad_monetization" | |
| table_map = build.dataset.table_map() | |
| assert "AD_MONETIZATION" in table_map | |
| assert "SALES_PIPELINE" not in table_map | |
| fact_columns = {column.name for column in table_map["AD_MONETIZATION"].columns} | |
| assert { | |
| "AD_REVENUE_USD", | |
| "ARPU_USD", | |
| "ECPM_USD", | |
| "FILL_RATE_PCT", | |
| "AD_YIELD_PER_WATCH_HOUR_USD", | |
| "REVENUE_LEAKAGE_USD", | |
| }.issubset(fact_columns) | |
| assert validate_dataset_quality(build.dataset).ok | |
| def test_grocery_finance_routes_to_cpg_financials_not_sales_fact(): | |
| build = build_dataset_first_demo( | |
| company_name="General Mills", | |
| company_url="https://generalmills.com", | |
| use_case="Grocery Finance", | |
| vertical="Retail & Consumer Goods", | |
| function="Finance", | |
| row_count_guidance=100, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == "cpg_finance" | |
| table_map = build.dataset.table_map() | |
| assert "CPG_FINANCIALS" in table_map | |
| assert "SALES_FACT" not in table_map | |
| fact_columns = {column.name for column in table_map["CPG_FINANCIALS"].columns} | |
| assert { | |
| "CASES_SHIPPED", | |
| "TRADE_SPEND_USD", | |
| "NET_SALES_USD", | |
| "COGS_USD", | |
| "FREIGHT_COST_USD", | |
| "GROSS_MARGIN_USD", | |
| "FORECAST_VARIANCE_PCT", | |
| } <= fact_columns | |
| assert "CAC_USD" not in fact_columns | |
| assert "LTV_USD" not in fact_columns | |
| def test_baker_hughes_chart_post_merger_keywords_do_not_trigger_nine_table_template(): | |
| use_case = ( | |
| "Baker Hughes acquired Chart Industries and needs a post-merger integration " | |
| "demo for supplier spend consolidation, aftermarket attach rate on Chart's " | |
| "installed base, cross-selling, customer invoicing, AR aging, DSO, and cash flow." | |
| ) | |
| build = build_dataset_first_demo( | |
| company_name="Baker Hughes + Chart Industries", | |
| company_url="https://www.bakerhughes.com", | |
| use_case=use_case, | |
| vertical="* CUSTOM *", | |
| function=None, | |
| row_count_guidance=200, | |
| ) | |
| assert build is None | |
| def test_explicit_table_prompt_overrides_post_merger_template_for_ar_aging(): | |
| use_case = """ | |
| Customer Invoicing & AR Aging | |
| Generate synthetic accounts receivable and invoicing data for a Baker Hughes + Chart Industries cash flow demo. | |
| The request is intentionally scoped to the following tables only. | |
| Tables | |
| dim_customer (~200 rows) | |
| Customer ID, customer name, industry, country, region, customer tier, legacy org, contracted payment terms. | |
| dim_invoice_category (~20 rows) | |
| Category ID, category name, business unit, order type. | |
| fact_invoices (~25,000 rows, Jan 2025 - Jun 2026) | |
| Invoice ID, invoice date, due date, customer ID, invoice category ID, invoice amount USD, | |
| payment received date, amount paid USD, dispute flag, dispute reason, collector assigned, legacy org. | |
| Anomalies to Seed | |
| APAC and Middle East Chart customers averaging 75-90 days to pay vs BKR benchmark of 45 days. | |
| Large LNG project invoices sitting 60-90 days overdue. | |
| """ | |
| build = build_dataset_first_demo( | |
| company_name="Baker Hughes + Chart Industries", | |
| company_url="https://www.bakerhughes.com", | |
| use_case=use_case, | |
| vertical="* CUSTOM *", | |
| function=None, | |
| row_count_guidance=1000, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == "explicit_table_contract" | |
| assert [table.name for table in build.dataset.tables] == [ | |
| "DIM_CUSTOMER", | |
| "DIM_INVOICE_CATEGORY", | |
| "FACT_INVOICES", | |
| ] | |
| assert build.ddl.count("CREATE TABLE") == 3 | |
| assert build.ddl.count("FOREIGN KEY") >= 2 | |
| tables = build.dataset.table_map() | |
| assert len(tables["DIM_CUSTOMER"].rows) == 200 | |
| assert len(tables["DIM_INVOICE_CATEGORY"].rows) == 20 | |
| assert len(tables["FACT_INVOICES"].rows) == 1000 | |
| assert {"DAYS_OUTSTANDING", "AGING_BUCKET", "PAST_DUE_AMOUNT_USD"} <= { | |
| column.name for column in tables["FACT_INVOICES"].columns | |
| } | |
| assert any(row["AGING_BUCKET"] in {"60-90 Days", "90+ Days"} for row in tables["FACT_INVOICES"].rows) | |
| def test_saas_finance_routes_to_subscription_revenue_not_generic_unit_economics(): | |
| build = build_dataset_first_demo( | |
| company_name="NetSuite", | |
| company_url="https://netsuite.com", | |
| use_case="SaaS Finance", | |
| vertical="Technology", | |
| function="Finance", | |
| row_count_guidance=100, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == "subscription_revenue" | |
| table_map = build.dataset.table_map() | |
| assert "SUBSCRIPTION_REVENUE" in table_map | |
| assert "UNIT_ECONOMICS" not in table_map | |
| fact_columns = {column.name for column in table_map["SUBSCRIPTION_REVENUE"].columns} | |
| assert { | |
| "STARTING_ARR_USD", | |
| "NEW_LOGO_ARR_USD", | |
| "EXPANSION_ARR_USD", | |
| "CONTRACTION_ARR_USD", | |
| "CHURNED_ARR_USD", | |
| "ENDING_ARR_USD", | |
| "MRR_USD", | |
| "NRR_PCT", | |
| } <= fact_columns | |
| assert validate_dataset_quality(build.dataset).ok | |
| def test_hotel_and_trucking_finance_pass_domain_quality_contracts(): | |
| cases = [ | |
| ("Wyndham", "https://wyndham.com", "Hotel Finance", "Travel & Hospitality", "Finance", "hotel_finance"), | |
| ("J.B. Hunt", "https://jbhunt.com", "Trucking Finance", "Transportation & Logistics", "Finance", "trucking_finance"), | |
| ] | |
| for company, url, use_case, vertical, function, scenario_type in cases: | |
| build = build_dataset_first_demo( | |
| company_name=company, | |
| company_url=url, | |
| use_case=use_case, | |
| vertical=vertical, | |
| function=function, | |
| row_count_guidance=100, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == scenario_type | |
| assert validate_dataset_quality(build.dataset).ok | |
| def test_automotive_supplier_sales_routes_to_supplier_programs(): | |
| build = build_dataset_first_demo( | |
| company_name="BorgWarner", | |
| company_url="https://borgwarner.com", | |
| use_case="Automotive Sales", | |
| vertical="Manufacturing", | |
| function="Sales", | |
| row_count_guidance=100, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == "automotive_supplier_sales" | |
| table_map = build.dataset.table_map() | |
| assert "SUPPLIER_PROGRAM_SALES" in table_map | |
| assert "VEHICLE_SALES" not in table_map | |
| fact_columns = {column.name for column in table_map["SUPPLIER_PROGRAM_SALES"].columns} | |
| assert { | |
| "RFQS_RECEIVED", | |
| "QUOTED_REVENUE_USD", | |
| "AWARDED_REVENUE_USD", | |
| "BACKLOG_USD", | |
| "TOOLING_RECOVERY_USD", | |
| "WARRANTY_RESERVE_USD", | |
| "PROGRAM_MARGIN_USD", | |
| "DEFECT_PPM", | |
| } <= fact_columns | |
| assert "DEALER_HOLDBACK_USD" not in fact_columns | |
| assert "TEST_DRIVES" not in fact_columns | |
| def test_vehicle_oem_sales_stays_on_automotive_sales(): | |
| build = build_dataset_first_demo( | |
| company_name="Stellantis", | |
| company_url="https://stellantis.com", | |
| use_case="Automotive Sales", | |
| vertical="Manufacturing", | |
| function="Sales", | |
| row_count_guidance=100, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == "automotive_sales" | |
| assert "VEHICLE_SALES" in build.dataset.table_map() | |
| def test_function_specific_routing_overrides_industry_terms(): | |
| cases = [ | |
| ("Financial Services", "Banking", "HR", "workforce_hr"), | |
| ("Financial Services", "Banking", "Legal", "legal_matter_management"), | |
| ("Travel & Hospitality", "Restaurants/Catering", "Marketing", "marketing_funnel"), | |
| ("Technology", "Hardware", "Sales", "retail_sales"), | |
| ("Healthcare & Life Sciences", "Healthcare Providers", "Sales", "sales_pipeline"), | |
| ("Retail & Consumer Goods", "Grocery", "Finance", "cpg_finance"), | |
| ("Retail & Consumer Goods", "Consumer Electronics", "IT", "it_operations"), | |
| ("Transportation & Logistics", "Warehousing", "Sales", "inventory_supply_chain"), | |
| ("Transportation & Logistics", "Supply Chain", "Sales", "inventory_supply_chain"), | |
| ("Manufacturing", "Automotive", "Finance", "finance_unit_economics"), | |
| ("Manufacturing", "Electronics Manufacturing", "IT", "it_operations"), | |
| ("Manufacturing", "Electronics Manufacturing", "Sales", "sales_pipeline"), | |
| ("Travel & Hospitality", "Restaurants/Catering", "Finance", "finance_unit_economics"), | |
| ("Travel & Hospitality", "Travel/Tourism", "Finance", "finance_unit_economics"), | |
| ] | |
| for vertical, line, function, expected in cases: | |
| assert infer_scenario_type( | |
| use_case=f"{line} {function}", | |
| vertical=vertical, | |
| function=function, | |
| ) == expected | |
| def test_it_operations_has_two_year_hourly_calendar(): | |
| build = build_dataset_first_demo( | |
| company_name="Microsoft", | |
| company_url="https://microsoft.com", | |
| use_case="Software as a Service IT operations reliability", | |
| vertical="Technology", | |
| function="IT", | |
| row_count_guidance=100, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == "it_operations" | |
| hours = build.dataset.table_map()["HOURS"] | |
| assert len(hours.rows) == 24 * 730 | |
| assert {"MONTH_NUM", "YEAR_NUM", "QUARTER_NUM"} <= {column.name for column in hours.columns} | |
| fact = build.dataset.table_map()["IT_OPERATIONS"] | |
| assert {"P1_INCIDENTS", "IMPACTED_USERS", "ERROR_BUDGET_BURN_PCT"} <= {column.name for column in fact.columns} | |
| assert max(row["DOWNTIME_HOURS"] for row in fact.rows[:100]) <= 1.0 | |
| assert max(row["INCIDENTS"] for row in fact.rows[:100]) <= 10 | |
| def test_medical_device_inventory_dimensions_are_not_numbered_fillers(): | |
| build = build_dataset_first_demo( | |
| company_name="Intuitive Surgical", | |
| company_url="https://www.intuitive.com", | |
| use_case="Medical device manufacturing operations inventory and warehouse supply chain", | |
| vertical="Manufacturing", | |
| function="Operations", | |
| row_count_guidance=100, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == "inventory_supply_chain" | |
| table_map = build.dataset.table_map() | |
| products = [row["PRODUCT_NAME"] for row in table_map["PRODUCTS"].rows] | |
| warehouses = [row["WAREHOUSE_NAME"] for row in table_map["WAREHOUSES"].rows] | |
| suppliers = [row["SUPPLIER_NAME"] for row in table_map["SUPPLIERS"].rows] | |
| regions = [row["REGION_NAME"] for row in table_map["REGIONS"].rows] | |
| assert len(products) == 36 | |
| assert len(warehouses) == 24 | |
| assert len(suppliers) == 24 | |
| assert "da Vinci 5 Surgical System" in products | |
| assert "Sunnyvale Final Assembly" in warehouses | |
| assert "Precision Motion Components" in suppliers | |
| assert "Manufacturing Sites" in regions | |
| generated_names = products + warehouses + suppliers | |
| assert not any("Product 29" in name or "Warehouse 21" in name or "Supplier 19" in name for name in generated_names) | |
| assert not any(name.rsplit(" ", 1)[-1].isdigit() for name in generated_names) | |
| def test_higher_education_enrollment_dimensions_are_not_numbered_fillers(): | |
| build = build_dataset_first_demo( | |
| company_name="Wake Forest University", | |
| company_url="https://www.wfu.edu", | |
| use_case="Student Success Enrollment", | |
| vertical="Education", | |
| function="Operations", | |
| row_count_guidance=100, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == "education_enrollment" | |
| table_map = build.dataset.table_map() | |
| programs = [row["PROGRAM_NAME"] for row in table_map["PROGRAMS"].rows] | |
| campuses = [row["CAMPUS_NAME"] for row in table_map["CAMPUSES"].rows] | |
| segments = [row["STUDENT_SEGMENT_NAME"] for row in table_map["STUDENT_SEGMENTS"].rows] | |
| terms = [row["TERM_NAME"] for row in table_map["TERMS"].rows] | |
| assert len(programs) == 18 | |
| assert len(campuses) == 18 | |
| assert len(segments) == 18 | |
| assert len(terms) == 8 | |
| assert "School of Business" in programs | |
| assert "Reynolda Campus" in campuses | |
| assert "First-Generation Students" in segments | |
| assert "Fall Early Decision I" in terms | |
| generated_names = programs + campuses + segments + terms | |
| assert not any("Program 17" in name or "Campus 18" in name or "Student Segment 14" in name or "Term 07" in name for name in generated_names) | |
| assert not any(name.rsplit(" ", 1)[-1].isdigit() for name in generated_names) | |
| def test_new_quality_pool_domains_are_not_generic_finance_or_pipeline(): | |
| cases = [ | |
| ("J.B. Hunt", "jbhunt.com", "Transportation & Logistics", "Trucking Finance", "Finance", "trucking_finance", "TRUCKING_FINANCIALS", {"LOADS", "REVENUE_PER_LOADED_MILE_USD", "EMPTY_MILE_PCT"}), | |
| ("Delta Air Lines", "delta.com", "Transportation & Logistics", "Air Transport Finance", "Finance", "airline_finance", "AIRLINE_FINANCIALS", {"RASM_CENTS", "CASM_CENTS", "FUEL_COST_USD"}), | |
| ("Johnson & Johnson", "jnj.com", "Healthcare & Life Sciences", "Life Sciences Sales", "Sales", "life_sciences_sales", "LIFE_SCIENCES_SALES", {"REBATE_USD", "GROSS_TO_NET_DEDUCTION_PCT", "PROCEDURES_OR_SCRIPTS"}), | |
| ] | |
| for company, url, vertical, use_case, function, scenario_type, fact_table, expected_columns in cases: | |
| build = build_dataset_first_demo( | |
| company_name=company, | |
| company_url=f"https://{url}", | |
| use_case=use_case, | |
| vertical=vertical, | |
| function=function, | |
| row_count_guidance=100, | |
| ) | |
| assert build is not None | |
| assert build.scenario.scenario_type == scenario_type | |
| table = build.dataset.table_map()[fact_table] | |
| assert expected_columns <= {column.name for column in table.columns} | |