@@ -1911,4 +1911,212 @@ private function createToken(array $features = []): StorageApiToken
19111911 'test-token ' ,
19121912 );
19131913 }
1914+
1915+ public function resolveJobTypeDataProvider (): Generator
1916+ {
1917+ yield 'row container with explicit standard type ' => [
1918+ 'componentId ' => 'keboola.ex-db-snowflake ' ,
1919+ 'jobData ' => [
1920+ 'parallelism ' => '5 ' , // This would normally make it a ROW_CONTAINER
1921+ 'type ' => 'standard ' , // But the explicit type should override
1922+ ],
1923+ 'expectedType ' => JobType::STANDARD ,
1924+ ];
1925+
1926+ yield 'standard with explicit row container type ' => [
1927+ 'componentId ' => 'keboola.ex-db-snowflake ' ,
1928+ 'jobData ' => [
1929+ 'parallelism ' => '0 ' , // This would normally make it a STANDARD
1930+ 'type ' => 'container ' , // But the explicit type should override
1931+ ],
1932+ 'expectedType ' => JobType::ROW_CONTAINER ,
1933+ ];
1934+
1935+ yield 'orchestrator with explicit row container type ' => [
1936+ 'componentId ' => JobFactory::ORCHESTRATOR_COMPONENT ,
1937+ 'jobData ' => [
1938+ 'type ' => 'container ' , // Override the orchestration container type
1939+ ],
1940+ 'expectedType ' => JobType::ROW_CONTAINER ,
1941+ ];
1942+
1943+ yield 'phase with explicit orchestration container type ' => [
1944+ 'componentId ' => JobFactory::ORCHESTRATOR_COMPONENT ,
1945+ 'jobData ' => [
1946+ 'configData ' => [
1947+ 'phaseId ' => '123 ' , // This would normally make it a PHASE_CONTAINER
1948+ ],
1949+ 'type ' => 'orchestrationContainer ' , // But the explicit type should override
1950+ ],
1951+ 'expectedType ' => JobType::ORCHESTRATION_CONTAINER ,
1952+ ];
1953+
1954+ yield 'flow with explicit phase container type ' => [
1955+ 'componentId ' => JobFactory::FLOW_COMPONENT ,
1956+ 'jobData ' => [
1957+ 'type ' => 'phaseContainer ' , // Override the orchestration container type
1958+ ],
1959+ 'expectedType ' => JobType::PHASE_CONTAINER ,
1960+ ];
1961+
1962+ // Test all possible enum values with explicit type only
1963+ yield 'explicit type standard ' => [
1964+ 'componentId ' => 'keboola.ex-db-snowflake ' ,
1965+ 'jobData ' => [
1966+ 'type ' => 'standard ' ,
1967+ ],
1968+ 'expectedType ' => JobType::STANDARD ,
1969+ ];
1970+
1971+ yield 'explicit type container ' => [
1972+ 'componentId ' => 'keboola.ex-db-snowflake ' ,
1973+ 'jobData ' => [
1974+ 'type ' => 'container ' ,
1975+ ],
1976+ 'expectedType ' => JobType::ROW_CONTAINER ,
1977+ ];
1978+
1979+ yield 'explicit type orchestration ' => [
1980+ 'componentId ' => 'keboola.ex-db-snowflake ' ,
1981+ 'jobData ' => [
1982+ 'type ' => 'orchestrationContainer ' ,
1983+ ],
1984+ 'expectedType ' => JobType::ORCHESTRATION_CONTAINER ,
1985+ ];
1986+
1987+ yield 'explicit type phase ' => [
1988+ 'componentId ' => 'keboola.ex-db-snowflake ' ,
1989+ 'jobData ' => [
1990+ 'type ' => 'phaseContainer ' ,
1991+ ],
1992+ 'expectedType ' => JobType::PHASE_CONTAINER ,
1993+ ];
1994+
1995+ // Test cases for parallelism condition
1996+ yield 'parallelism numeric positive ' => [
1997+ 'componentId ' => 'keboola.ex-db-snowflake ' ,
1998+ 'jobData ' => [
1999+ 'parallelism ' => '10 ' ,
2000+ ],
2001+ 'expectedType ' => JobType::ROW_CONTAINER ,
2002+ ];
2003+
2004+ yield 'parallelism infinity ' => [
2005+ 'componentId ' => 'keboola.ex-db-snowflake ' ,
2006+ 'jobData ' => [
2007+ 'parallelism ' => 'infinity ' ,
2008+ ],
2009+ 'expectedType ' => JobType::ROW_CONTAINER ,
2010+ ];
2011+
2012+ yield 'parallelism zero ' => [
2013+ 'componentId ' => 'keboola.ex-db-snowflake ' ,
2014+ 'jobData ' => [
2015+ 'parallelism ' => '0 ' ,
2016+ ],
2017+ 'expectedType ' => JobType::STANDARD ,
2018+ ];
2019+
2020+ yield 'parallelism null ' => [
2021+ 'componentId ' => 'keboola.ex-db-snowflake ' ,
2022+ 'jobData ' => [
2023+ 'parallelism ' => null ,
2024+ ],
2025+ 'expectedType ' => JobType::STANDARD ,
2026+ ];
2027+
2028+ // Test cases for component-specific conditions
2029+ yield 'flow component without explicit type ' => [
2030+ 'componentId ' => JobFactory::FLOW_COMPONENT ,
2031+ 'jobData ' => [],
2032+ 'expectedType ' => JobType::ORCHESTRATION_CONTAINER ,
2033+ ];
2034+
2035+ yield 'orchestrator component without explicit type or phaseId ' => [
2036+ 'componentId ' => JobFactory::ORCHESTRATOR_COMPONENT ,
2037+ 'jobData ' => [],
2038+ 'expectedType ' => JobType::ORCHESTRATION_CONTAINER ,
2039+ ];
2040+
2041+ yield 'orchestrator component with phaseId ' => [
2042+ 'componentId ' => JobFactory::ORCHESTRATOR_COMPONENT ,
2043+ 'jobData ' => [
2044+ 'configData ' => [
2045+ 'phaseId ' => '123 ' ,
2046+ ],
2047+ ],
2048+ 'expectedType ' => JobType::PHASE_CONTAINER ,
2049+ ];
2050+
2051+ yield 'orchestrator component with empty string phaseId ' => [
2052+ 'componentId ' => JobFactory::ORCHESTRATOR_COMPONENT ,
2053+ 'jobData ' => [
2054+ 'configData ' => [
2055+ 'phaseId ' => '' ,
2056+ ],
2057+ ],
2058+ 'expectedType ' => JobType::ORCHESTRATION_CONTAINER ,
2059+ ];
2060+
2061+ yield 'standard component with no special configuration ' => [
2062+ 'componentId ' => 'keboola.ex-db-snowflake ' ,
2063+ 'jobData ' => [],
2064+ 'expectedType ' => JobType::STANDARD ,
2065+ ];
2066+ }
2067+
2068+ /**
2069+ * @dataProvider resolveJobTypeDataProvider
2070+ */
2071+ public function testResolveJobType (string $ componentId , array $ customJobData , JobType $ expectedType ): void
2072+ {
2073+ $ baseJobData = [
2074+ 'id ' => '123456456 ' ,
2075+ 'runId ' => '123456456 ' ,
2076+ 'componentId ' => $ componentId ,
2077+ 'mode ' => 'run ' ,
2078+ 'status ' => 'created ' ,
2079+ 'desiredStatus ' => 'processing ' ,
2080+ 'projectId ' => '123 ' ,
2081+ 'tokenId ' => '456 ' ,
2082+ '#tokenString ' => 'KBC::ProjectSecure::token ' ,
2083+ 'branchId ' => 'default ' ,
2084+ 'backend ' => null ,
2085+ ];
2086+
2087+ $ jobData = array_merge ($ baseJobData , $ customJobData );
2088+
2089+ $ componentData = [
2090+ 'type ' => 'dummy-component-type ' ,
2091+ 'id ' => $ componentId ,
2092+ 'data ' => [
2093+ 'definition ' => [
2094+ 'tag ' => '9.9.9 ' ,
2095+ ],
2096+ ],
2097+ ];
2098+
2099+ $ storageClient = self ::createMock (BranchAwareClient::class);
2100+ $ storageClient ->expects (self ::exactly (1 ))->method ('apiGet ' )
2101+ ->with (sprintf ('components/%s ' , $ componentId ))
2102+ ->willReturn ($ componentData );
2103+
2104+ $ clientWrapperMock = self ::createMock (ClientWrapper::class);
2105+ $ clientWrapperMock ->method ('getBranchClient ' )->willReturn ($ storageClient );
2106+ $ storageClientFactoryMock = self ::createMock (StorageClientPlainFactory::class);
2107+ $ storageClientFactoryMock
2108+ ->expects (self ::exactly (1 ))
2109+ ->method ('createClientWrapper ' )
2110+ ->willReturn ($ clientWrapperMock );
2111+
2112+ $ jobRuntimeResolver = new JobRuntimeResolver ($ storageClientFactoryMock );
2113+
2114+ $ resolvedJobData = $ jobRuntimeResolver ->resolveJobData ($ jobData , $ this ->createToken ([]));
2115+
2116+ self ::assertSame (
2117+ $ expectedType ->value ,
2118+ $ resolvedJobData ['type ' ],
2119+ sprintf ('Failed asserting job type for component "%s" ' , $ componentId ),
2120+ );
2121+ }
19142122}
0 commit comments