Fix #1047: fix platform lookup and add unit tests
diff --git a/pkg/apis/camel/v1alpha1/integrationplatform_types.go b/pkg/apis/camel/v1alpha1/integrationplatform_types.go
index 3e17daf..72aaea7 100644
--- a/pkg/apis/camel/v1alpha1/integrationplatform_types.go
+++ b/pkg/apis/camel/v1alpha1/integrationplatform_types.go
@@ -91,6 +91,8 @@
 	TraitProfileKubernetes = "Kubernetes"
 	// TraitProfileKnative is used by default on OpenShift/Kubernetes clusters powered by Knative
 	TraitProfileKnative = "Knative"
+	// DefaultTraitProfile is the trait profile used as default when no other profile is set
+	DefaultTraitProfile = TraitProfileKubernetes
 )
 
 // AllTraitProfiles contains all allowed profiles
diff --git a/pkg/controller/build/build_controller.go b/pkg/controller/build/build_controller.go
index 71e2cf0..b6d227d 100644
--- a/pkg/controller/build/build_controller.go
+++ b/pkg/controller/build/build_controller.go
@@ -14,6 +14,7 @@
 See the License for the specific language governing permissions and
 limitations under the License.
 */
+
 package build
 
 import (
@@ -151,7 +152,7 @@
 	targetLog := rlog.ForBuild(target)
 
 	if target.Status.Phase == v1alpha1.BuildPhaseNone || target.Status.Phase == v1alpha1.BuildPhaseWaitingForPlatform {
-		pl, err := platform.GetOrLookup(ctx, r.client, target.Namespace, target.Status.Platform)
+		pl, err := platform.GetOrLookupCurrent(ctx, r.client, target.Namespace, target.Status.Platform)
 		if err != nil || pl.Status.Phase != v1alpha1.IntegrationPlatformPhaseReady {
 			target.Status.Phase = v1alpha1.BuildPhaseWaitingForPlatform
 		} else {
diff --git a/pkg/controller/integrationkit/integrationkit_controller.go b/pkg/controller/integrationkit/integrationkit_controller.go
index fa4c13d..ed84f1d 100644
--- a/pkg/controller/integrationkit/integrationkit_controller.go
+++ b/pkg/controller/integrationkit/integrationkit_controller.go
@@ -185,7 +185,7 @@
 	targetLog := rlog.ForIntegrationKit(target)
 
 	if target.Status.Phase == v1alpha1.IntegrationKitPhaseNone || target.Status.Phase == v1alpha1.IntegrationKitPhaseWaitingForPlatform {
-		pl, err := platform.GetOrLookup(ctx, r.client, target.Namespace, target.Status.Platform)
+		pl, err := platform.GetOrLookupCurrent(ctx, r.client, target.Namespace, target.Status.Platform)
 		if err != nil || pl.Status.Phase != v1alpha1.IntegrationPlatformPhaseReady {
 			target.Status.Phase = v1alpha1.IntegrationKitPhaseWaitingForPlatform
 		} else {
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index b9b4dad..83c2e82 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -32,8 +32,8 @@
 	DefaultPlatformName = "camel-k"
 )
 
-// GetOrLookup --
-func GetOrLookup(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1alpha1.IntegrationPlatform, error) {
+// GetOrLookupCurrent --
+func GetOrLookupCurrent(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1alpha1.IntegrationPlatform, error) {
 	if name != "" {
 		return Get(ctx, c, namespace, name)
 	}
@@ -41,6 +41,15 @@
 	return GetCurrentPlatform(ctx, c, namespace)
 }
 
+// GetOrLookupAny returns the named platform or any other platform in the namespace
+func GetOrLookupAny(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1alpha1.IntegrationPlatform, error) {
+	if name != "" {
+		return Get(ctx, c, namespace, name)
+	}
+
+	return getAnyPlatform(ctx, c, namespace, false)
+}
+
 // Get returns the currently installed platform
 func Get(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1alpha1.IntegrationPlatform, error) {
 	return kubernetes.GetIntegrationPlatform(ctx, c, name, namespace)
@@ -48,6 +57,11 @@
 
 // GetCurrentPlatform returns the currently installed platform
 func GetCurrentPlatform(ctx context.Context, c k8sclient.Reader, namespace string) (*v1alpha1.IntegrationPlatform, error) {
+	return getAnyPlatform(ctx, c, namespace, true)
+}
+
+// getAnyPlatform returns the currently installed platform or any platform existing in the namespace
+func getAnyPlatform(ctx context.Context, c k8sclient.Reader, namespace string, active bool) (*v1alpha1.IntegrationPlatform, error) {
 	lst, err := ListPlatforms(ctx, c, namespace)
 	if err != nil {
 		return nil, err
@@ -59,6 +73,13 @@
 			return &platform, nil
 		}
 	}
+
+	if !active && len(lst.Items) > 0 {
+		// does not require the platform to be active, just return one if present
+		res := lst.Items[0]
+		return &res, nil
+	}
+
 	return nil, k8serrors.NewNotFound(v1alpha1.Resource("IntegrationPlatform"), DefaultPlatformName)
 }
 
diff --git a/pkg/trait/platform.go b/pkg/trait/platform.go
index 2f4da53..06d4872 100644
--- a/pkg/trait/platform.go
+++ b/pkg/trait/platform.go
@@ -92,7 +92,7 @@
 }
 
 func (t *platformTrait) getOrCreatePlatform(e *Environment) (*v1alpha1.IntegrationPlatform, error) {
-	pl, err := platform.GetOrLookup(t.ctx, t.client, e.Integration.Namespace, e.Integration.Status.Platform)
+	pl, err := platform.GetOrLookupAny(t.ctx, t.client, e.Integration.Namespace, e.Integration.Status.Platform)
 	if err != nil && k8serrors.IsNotFound(err) {
 		if t.CreateDefault != nil && *t.CreateDefault {
 			platformName := e.Integration.Status.Platform
diff --git a/pkg/trait/platform_test.go b/pkg/trait/platform_test.go
new file mode 100644
index 0000000..d9de1f3
--- /dev/null
+++ b/pkg/trait/platform_test.go
@@ -0,0 +1,171 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package trait
+
+import (
+	"testing"
+
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/platform"
+	"github.com/apache/camel-k/pkg/util/kubernetes"
+	"github.com/apache/camel-k/pkg/util/test"
+	"github.com/stretchr/testify/assert"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func TestPlatformTraitChangeStatus(t *testing.T) {
+
+	table := []struct {
+		name         string
+		initialPhase v1alpha1.IntegrationPhase
+	}{
+		{
+			name:         "Setup from [none]",
+			initialPhase: v1alpha1.IntegrationPhaseNone,
+		},
+		{
+			name:         "Setup from WaitingForPlatform",
+			initialPhase: v1alpha1.IntegrationPhaseWaitingForPlatform,
+		},
+	}
+
+	for _, entry := range table {
+		input := entry
+		t.Run(input.name, func(t *testing.T) {
+			e := Environment{
+				Resources: kubernetes.NewCollection(),
+				Integration: &v1alpha1.Integration{
+					Status: v1alpha1.IntegrationStatus{
+						Phase: input.initialPhase,
+					},
+				},
+			}
+
+			trait := newPlatformTrait()
+			createPlatform := false
+			trait.CreateDefault = &createPlatform
+
+			var err error
+			trait.client, err = test.NewFakeClient()
+			assert.Nil(t, err)
+
+			enabled, err := trait.Configure(&e)
+			assert.Nil(t, err)
+			assert.True(t, enabled)
+
+			err = trait.Apply(&e)
+			assert.Nil(t, err)
+
+			assert.Equal(t, v1alpha1.IntegrationPhaseWaitingForPlatform, e.Integration.Status.Phase)
+			assert.Empty(t, e.Resources.Items())
+		})
+	}
+}
+
+func TestPlatformTraitCreatesDefaultPlatform(t *testing.T) {
+	e := Environment{
+		Resources: kubernetes.NewCollection(),
+		Integration: &v1alpha1.Integration{
+			ObjectMeta: v1.ObjectMeta{
+				Namespace: "ns1",
+				Name:      "xx",
+			},
+			Status: v1alpha1.IntegrationStatus{
+				Phase: v1alpha1.IntegrationPhaseNone,
+			},
+		},
+	}
+
+	trait := newPlatformTrait()
+	createPlatform := true
+	trait.CreateDefault = &createPlatform
+
+	var err error
+	trait.client, err = test.NewFakeClient()
+	assert.Nil(t, err)
+
+	enabled, err := trait.Configure(&e)
+	assert.Nil(t, err)
+	assert.True(t, enabled)
+
+	err = trait.Apply(&e)
+	assert.Nil(t, err)
+
+	assert.Equal(t, v1alpha1.IntegrationPhaseWaitingForPlatform, e.Integration.Status.Phase)
+	assert.Equal(t, 1, len(e.Resources.Items()))
+	defPlatform := v1alpha1.NewIntegrationPlatform("ns1", platform.DefaultPlatformName)
+	assert.Contains(t, e.Resources.Items(), &defPlatform)
+}
+
+func TestPlatformTraitExisting(t *testing.T) {
+
+	table := []struct {
+		name          string
+		platformPhase v1alpha1.IntegrationPlatformPhase
+		expectedPhase v1alpha1.IntegrationPhase
+	}{
+		{
+			name:          "Wait existing",
+			platformPhase: "",
+			expectedPhase: v1alpha1.IntegrationPhaseWaitingForPlatform,
+		},
+		{
+			name:          "Move state",
+			platformPhase: v1alpha1.IntegrationPlatformPhaseReady,
+			expectedPhase: v1alpha1.IntegrationPhaseInitialization,
+		},
+	}
+
+	for _, entry := range table {
+		input := entry
+		t.Run(input.name, func(t *testing.T) {
+			e := Environment{
+				Resources: kubernetes.NewCollection(),
+				Integration: &v1alpha1.Integration{
+					ObjectMeta: v1.ObjectMeta{
+						Namespace: "ns1",
+						Name:      "xx",
+					},
+					Status: v1alpha1.IntegrationStatus{
+						Phase: v1alpha1.IntegrationPhaseNone,
+					},
+				},
+			}
+
+			trait := newPlatformTrait()
+			createPlatform := true
+			trait.CreateDefault = &createPlatform
+
+			var err error
+			existingPlatform := v1alpha1.NewIntegrationPlatform("ns1", "existing")
+			existingPlatform.Status.Phase = input.platformPhase
+			trait.client, err = test.NewFakeClient(&existingPlatform)
+			assert.Nil(t, err)
+
+			enabled, err := trait.Configure(&e)
+			assert.Nil(t, err)
+			assert.True(t, enabled)
+
+			err = trait.Apply(&e)
+			assert.Nil(t, err)
+
+			assert.Equal(t, input.expectedPhase, e.Integration.Status.Phase)
+			assert.Empty(t, e.Resources.Items())
+		})
+	}
+}
diff --git a/pkg/trait/trait_catalog.go b/pkg/trait/trait_catalog.go
index 6088506..32d5faa 100644
--- a/pkg/trait/trait_catalog.go
+++ b/pkg/trait/trait_catalog.go
@@ -221,7 +221,7 @@
 		}
 	}
 
-	return c.allTraits()
+	return nil
 }
 
 func (c *Catalog) apply(environment *Environment) error {
diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go
index cd7dafe..e21829a 100644
--- a/pkg/trait/trait_types.go
+++ b/pkg/trait/trait_types.go
@@ -220,7 +220,8 @@
 	if e.Platform != nil {
 		return platform.GetProfile(e.Platform)
 	}
-	return ""
+
+	return v1alpha1.DefaultTraitProfile
 }
 
 // DetermineControllerStrategy determines the type of controller that should be used for the integration