import unittest from pathlib import Path TEMPLATE_PATH = Path(__file__).resolve().parents[1] / "template.yaml" class TemplateTest(unittest.TestCase): @classmethod def setUpClass(cls): cls.template = TEMPLATE_PATH.read_text(encoding="utf-8") def resource_block(self, resource_name, next_resource_name): start = f"\n {resource_name}:" end = f"\n {next_resource_name}:" self.assertIn(start, self.template) self.assertIn(end, self.template) return self.template.split(start, 1)[1].split(end, 1)[0] def test_stack_contains_the_same_five_task_roles(self): for resource in ( "DispatcherFunction", "WorkerFunction", "ScoringFunction", "SummaryFunction", "WeeklyMetricsFunction", ): self.assertIn(f"\n {resource}:", self.template) self.assertEqual(5, self.template.count("Type: AWS::Serverless::Function")) self.assertNotIn("EffectiveSalesOwner", self.template) def test_resource_names_and_code_paths_are_latam_scoped(self): self.assertIn("FunctionName: LATAM-Tenants-Scoring-Task", self.template) self.assertIn("QueueName: LATAM-Tenants-Scoring-Queue", self.template) self.assertIn("Default: latam_tenant_events", self.template) self.assertIn( "database path is latam_regional_support", self.template, ) def test_queues_use_their_matching_dead_letter_queues(self): monitor = self.resource_block("MonitorQueue", "ScoringDeadLetterQueue") scoring = self.resource_block("ScoringQueue", "DispatcherFunction") self.assertIn("MonitorDeadLetterQueue.Arn", monitor) self.assertNotIn("ScoringDeadLetterQueue.Arn", monitor) self.assertIn("ScoringDeadLetterQueue.Arn", scoring) self.assertNotIn("MonitorDeadLetterQueue.Arn", scoring) def test_schedules_are_disabled_by_default(self): self.assertIn( "ScheduleState:\n Type: String\n Default: DISABLED", self.template, ) self.assertEqual(3, self.template.count("State: !Ref ScheduleState")) def test_schedule_defaults_favor_china_morning_hours(self): self.assertIn("Default: cron(5 0 * * ? *)", self.template) self.assertIn("Default: cron(0 2 * * ? *)", self.template) self.assertIn("Default: cron(0 4 ? * MON *)", self.template) def test_worker_receives_qwen_configuration_as_environment_variables(self): worker = self.resource_block("WorkerFunction", "ScoringFunction") for variable, parameter in ( ("API_KEY", "QwenAPIKey"), ("WORKSPACE_ID", "QwenWorkspaceID"), ("DASHSCOPE_ENDPOINT", "DashScopeEndpoint"), ("REGION", "QwenRegion"), ("QWEN_WEB_SEARCH_MODEL", "QwenWebSearchModel"), ): self.assertIn(f"{variable}: !Ref {parameter}", worker) self.assertNotIn("OPENAI_API_KEY", self.template) self.assertNotIn("OPENAI_WEB_SEARCH_MODEL", self.template) def test_scoring_receives_hubspot_writeback_configuration(self): scoring = self.resource_block("ScoringFunction", "WeeklyMetricsFunction") self.assertIn("Timeout: 180", scoring) self.assertIn("ScalingConfig:\n MaximumConcurrency: 2", scoring) self.assertIn( "HUBSPOT_WRITEBACK_TOKEN: !Ref HubSpotWritebackPrivateAppToken", scoring, ) self.assertIn( "HUBSPOT_WRITEBACK_PROPERTY_NAME: latam_pql_priority_tier", scoring, ) self.assertIn( "HUBSPOT_WRITEBACK_TIMEOUT_SECONDS: !Ref HubSpotRequestTimeoutSeconds", scoring, ) self.assertIn( "HUBSPOT_WRITEBACK_RETRY_COUNT: !Ref HubSpotRetryCount", scoring, ) parameter = self.template.split( "HubSpotWritebackPrivateAppToken:", 1 )[1].split("HubSpotRequestTimeoutSeconds:", 1)[0] self.assertIn("NoEcho: true", parameter) if __name__ == "__main__": unittest.main()