From 7d547e827962b1ccc91b08ce908af23002f68c99 Mon Sep 17 00:00:00 2001
From: Damien Coraboeuf <damien.coraboeuf@gmail.com>
Date: Sun, 15 Dec 2024 18:38:30 +0100
Subject: [PATCH] #1236 Environment build count (0) if not deployed anywhere

---
 ...EnvironmentsBuildPromotionInfoExtension.kt | 12 +++-
 ...vironmentsBuildPromotionInfoExtensionIT.kt | 64 ++++++++++++++++++-
 ...sBuildPromotionInfoExtensionTestSupport.kt | 27 +++++---
 ...ntsBuildPromotionInfoExtensionGraphQLIT.kt |  2 +-
 4 files changed, 89 insertions(+), 16 deletions(-)

diff --git a/ontrack-extension-environments/src/main/java/net/nemerosa/ontrack/extension/environments/promotions/EnvironmentsBuildPromotionInfoExtension.kt b/ontrack-extension-environments/src/main/java/net/nemerosa/ontrack/extension/environments/promotions/EnvironmentsBuildPromotionInfoExtension.kt
index f47c9de90d..6152ae5514 100644
--- a/ontrack-extension-environments/src/main/java/net/nemerosa/ontrack/extension/environments/promotions/EnvironmentsBuildPromotionInfoExtension.kt
+++ b/ontrack-extension-environments/src/main/java/net/nemerosa/ontrack/extension/environments/promotions/EnvironmentsBuildPromotionInfoExtension.kt
@@ -54,6 +54,8 @@ class EnvironmentsBuildPromotionInfoExtension(
         val slotPipeline = slotService.findSlotPipelinesWhereBuildIsLastDeployed(build).firstOrNull()
         if (slotPipeline != null) {
             items.add(0, buildPromotionInfoItemForDeployedSlotPipeline(slotPipeline))
+        } else {
+            items.add(0, buildPromotionInfoItemForDeployedSlotCount(build, 0))
         }
     }
 
@@ -62,9 +64,13 @@ class EnvironmentsBuildPromotionInfoExtension(
         build: Build
     ) {
         val slotPipelines = slotService.findSlotPipelinesWhereBuildIsLastDeployed(build)
-        items.addAll(0, slotPipelines.map { slotPipeline ->
-            buildPromotionInfoItemForDeployedSlotPipeline(slotPipeline)
-        })
+        if (slotPipelines.isNotEmpty()) {
+            items.addAll(0, slotPipelines.map { slotPipeline ->
+                buildPromotionInfoItemForDeployedSlotPipeline(slotPipeline)
+            })
+        } else {
+            items.add(0, buildPromotionInfoItemForDeployedSlotCount(build, 0))
+        }
     }
 
     private fun buildPromotionInfoItemForDeployedSlotPipeline(
diff --git a/ontrack-extension-environments/src/test/java/net/nemerosa/ontrack/extension/environments/promotions/EnvironmentsBuildPromotionInfoExtensionIT.kt b/ontrack-extension-environments/src/test/java/net/nemerosa/ontrack/extension/environments/promotions/EnvironmentsBuildPromotionInfoExtensionIT.kt
index 40dac3bb74..20e2b62625 100644
--- a/ontrack-extension-environments/src/test/java/net/nemerosa/ontrack/extension/environments/promotions/EnvironmentsBuildPromotionInfoExtensionIT.kt
+++ b/ontrack-extension-environments/src/test/java/net/nemerosa/ontrack/extension/environments/promotions/EnvironmentsBuildPromotionInfoExtensionIT.kt
@@ -43,12 +43,12 @@ class EnvironmentsBuildPromotionInfoExtensionIT : AbstractDSLTestSupport() {
 
             info.items[index++].apply {
                 assertNull(promotionLevel)
-                assertEquals(eligibleSlotWithSilverPromotionRulePipeline.id, (data as SlotPipeline).id)
+                assertEquals(eligibleSlotWithSilverPromotionRulePipeline?.id, (data as SlotPipeline).id)
             }
 
             info.items[index++].apply {
                 assertNull(promotionLevel)
-                assertEquals(eligibleSlotWithNoPromotionRulePipeline.id, (data as SlotPipeline).id)
+                assertEquals(eligibleSlotWithNoPromotionRulePipeline?.id, (data as SlotPipeline).id)
             }
 
             // Then the promotions & their promotion runs
@@ -105,7 +105,65 @@ class EnvironmentsBuildPromotionInfoExtensionIT : AbstractDSLTestSupport() {
 
             info.items[index++].apply {
                 assertEquals(null, promotionLevel)
-                assertEquals(eligibleSlotWithSilverPromotionRulePipeline.id, (data as SlotPipeline).id)
+                assertEquals(eligibleSlotWithSilverPromotionRulePipeline?.id, (data as SlotPipeline).id)
+            }
+
+            // Then the promotions & their promotion runs
+
+            info.items[index++].apply {
+                assertEquals(gold, promotionLevel)
+                assertEquals(gold, data)
+            }
+
+            info.items[index++].apply {
+                assertEquals(silver, promotionLevel)
+                assertEquals(runSilver.id, (data as PromotionRun).id)
+            }
+
+            info.items[index++].apply {
+                assertEquals(bronze, promotionLevel)
+                assertEquals(runBronze2.id, (data as PromotionRun).id)
+            }
+
+            info.items[index].apply {
+                assertEquals(bronze, promotionLevel)
+                assertEquals(runBronze1.id, (data as PromotionRun).id)
+            }
+        }
+    }
+
+    @Test
+    fun `Getting the promotion info for a build with display option being HIGHEST and not deployed anywhere`() {
+        environmentsBuildPromotionInfoExtensionTestSupport.withSetup(
+            buildDisplayOption = EnvironmentsSettingsBuildDisplayOption.HIGHEST,
+            deployed = false,
+        ) { test ->
+
+            val (
+                build,
+                info,
+                bronze,
+                silver,
+                gold,
+                runBronze1,
+                runBronze2,
+                runSilver,
+                _,
+                _,
+                _,
+                _,
+            ) = test
+
+
+            // Checking all items have been collected
+            assertEquals(5, info.items.size)
+            var index = 0
+
+            // First, the slot where the build is deployed
+
+            info.items[index++].apply {
+                assertEquals(null, promotionLevel)
+                assertEquals(EnvironmentBuildCount(build, count = 0), data)
             }
 
             // Then the promotions & their promotion runs
diff --git a/ontrack-extension-environments/src/test/java/net/nemerosa/ontrack/extension/environments/promotions/EnvironmentsBuildPromotionInfoExtensionTestSupport.kt b/ontrack-extension-environments/src/test/java/net/nemerosa/ontrack/extension/environments/promotions/EnvironmentsBuildPromotionInfoExtensionTestSupport.kt
index 949929ca76..2c5472f3cf 100644
--- a/ontrack-extension-environments/src/test/java/net/nemerosa/ontrack/extension/environments/promotions/EnvironmentsBuildPromotionInfoExtensionTestSupport.kt
+++ b/ontrack-extension-environments/src/test/java/net/nemerosa/ontrack/extension/environments/promotions/EnvironmentsBuildPromotionInfoExtensionTestSupport.kt
@@ -31,6 +31,7 @@ class EnvironmentsBuildPromotionInfoExtensionTestSupport : AbstractDSLTestSuppor
 
     fun withSetup(
         buildDisplayOption: EnvironmentsSettingsBuildDisplayOption,
+        deployed: Boolean = true,
         test: (info: TestInfo) -> Unit,
     ) {
         asAdmin {
@@ -80,24 +81,32 @@ class EnvironmentsBuildPromotionInfoExtensionTestSupport : AbstractDSLTestSuppor
                             val runBronze2 = promote(bronze)
                             val runSilver = promote(silver)
 
-                            val eligibleSlotWithNoPromotionRulePipeline = slotService.startPipeline(
-                                slot = eligibleSlotWithNoPromotionRule,
-                                build = this,
-                            ).apply {
-                                slotTestSupport.startAndDeployPipeline(this)
+                            val eligibleSlotWithNoPromotionRulePipeline = if (deployed) {
+                                slotService.startPipeline(
+                                    slot = eligibleSlotWithNoPromotionRule,
+                                    build = this,
+                                ).apply {
+                                    slotTestSupport.startAndDeployPipeline(this)
+                                }
+                            } else {
+                                null
                             }
 
-                            val eligibleSlotWithSilverPromotionRulePipeline =
+                            val eligibleSlotWithSilverPromotionRulePipeline = if (deployed) {
                                 slotService.startPipeline(
                                     slot = eligibleSlotWithSilverPromotionRule,
                                     build = this,
                                 ).apply {
                                     slotTestSupport.startAndDeployPipeline(this)
                                 }
+                            } else {
+                                null
+                            }
 
                             // Checking that everything is marked as deployed
                             val pipelines = slotService.findSlotPipelinesWhereBuildIsLastDeployed(this)
-                            assertEquals(2, pipelines.size, "All pipelines deployed")
+                            val count = if (deployed) 2 else 0
+                            assertEquals(count, pipelines.size, "All pipelines deployed")
 
                             val info = buildPromotionInfoService.getBuildPromotionInfo(this)
 
@@ -135,9 +144,9 @@ class EnvironmentsBuildPromotionInfoExtensionTestSupport : AbstractDSLTestSuppor
         val runBronze2: PromotionRun,
         val runSilver: PromotionRun,
         val eligibleSlotWithNoPromotionRule: Slot,
-        val eligibleSlotWithNoPromotionRulePipeline: SlotPipeline,
+        val eligibleSlotWithNoPromotionRulePipeline: SlotPipeline?,
         val eligibleSlotWithSilverPromotionRule: Slot,
-        val eligibleSlotWithSilverPromotionRulePipeline: SlotPipeline,
+        val eligibleSlotWithSilverPromotionRulePipeline: SlotPipeline?,
     )
 
 }
\ No newline at end of file
diff --git a/ontrack-extension-environments/src/test/java/net/nemerosa/ontrack/extension/environments/ui/EnvironmentsBuildPromotionInfoExtensionGraphQLIT.kt b/ontrack-extension-environments/src/test/java/net/nemerosa/ontrack/extension/environments/ui/EnvironmentsBuildPromotionInfoExtensionGraphQLIT.kt
index 3b2b0fb1e2..f8ebeba2d2 100644
--- a/ontrack-extension-environments/src/test/java/net/nemerosa/ontrack/extension/environments/ui/EnvironmentsBuildPromotionInfoExtensionGraphQLIT.kt
+++ b/ontrack-extension-environments/src/test/java/net/nemerosa/ontrack/extension/environments/ui/EnvironmentsBuildPromotionInfoExtensionGraphQLIT.kt
@@ -79,7 +79,7 @@ class EnvironmentsBuildPromotionInfoExtensionGraphQLIT : AbstractQLKTITSupport()
                                         "promotionLevel" to null,
                                         "data" to mapOf(
                                             "__typename" to "SlotPipeline",
-                                            "id" to eligibleSlotWithSilverPromotionRulePipeline.id
+                                            "id" to eligibleSlotWithSilverPromotionRulePipeline?.id
                                         )
                                     ),
                                     mapOf(