diff --git a/cmd/import.go b/cmd/import.go index 1f270433..c9400feb 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -177,11 +177,13 @@ func NewImportCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command f = filepath.Clean(f) // Upsert entry. - watchCfg.UpsertEntry(config.WatchEntry{ + if err := watchCfg.UpsertEntry(config.WatchEntry{ FilePath: f, Context: []string{globalClientOpts.Context}, MainArtifact: mainArtifact, - }) + }); err != nil { + return errors.Wrap(errors.KindEnvironment, err) + } // Write watch file. if err := config.WriteLocalWatchConfig(*watchCfg, watchFile); err != nil { diff --git a/cmd/login_test.go b/cmd/login_test.go index 141ad415..73e83902 100644 --- a/cmd/login_test.go +++ b/cmd/login_test.go @@ -111,7 +111,9 @@ func TestLoginHonorsConfigFlag(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/api/keycloak/config" { w.Header().Set("Content-Type", "application/json") - _, _ = w.Write([]byte(`{"enabled": false}`)) + if _, err := w.Write([]byte(`{"enabled": false}`)); err != nil { + t.Errorf("writing Keycloak config response: %v", err) + } return } http.NotFound(w, r) @@ -147,7 +149,9 @@ func TestLoginHonorsConfigFlagWithCustomContextName(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/api/keycloak/config" { w.Header().Set("Content-Type", "application/json") - _, _ = w.Write([]byte(`{"enabled": false}`)) + if _, err := w.Write([]byte(`{"enabled": false}`)); err != nil { + t.Errorf("writing Keycloak config response: %v", err) + } return } http.NotFound(w, r) @@ -174,7 +178,9 @@ func TestLoginPreservesExistingContextsInCustomConfig(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/api/keycloak/config" { w.Header().Set("Content-Type", "application/json") - _, _ = w.Write([]byte(`{"enabled": false}`)) + if _, err := w.Write([]byte(`{"enabled": false}`)); err != nil { + t.Errorf("writing Keycloak config response: %v", err) + } return } http.NotFound(w, r) diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 1ea511fc..ecfba279 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -446,11 +446,11 @@ func TestWatchConfig(t *testing.T) { assert.Equal(t, "file1.yaml", loadedWCfg.Entries[0].FilePath) // 4. Upsert entry (new path) - loadedWCfg.UpsertEntry(WatchEntry{FilePath: "file2.yaml", Context: []string{"ctx2"}, MainArtifact: false}) + assert.NoError(t, loadedWCfg.UpsertEntry(WatchEntry{FilePath: "file2.yaml", Context: []string{"ctx2"}, MainArtifact: false})) assert.Len(t, loadedWCfg.Entries, 2) // 5. Upsert entry (existing path, append context) - loadedWCfg.UpsertEntry(WatchEntry{FilePath: "file1.yaml", Context: []string{"ctx3"}, MainArtifact: true}) + assert.NoError(t, loadedWCfg.UpsertEntry(WatchEntry{FilePath: "file1.yaml", Context: []string{"ctx3"}, MainArtifact: true})) assert.Len(t, loadedWCfg.Entries, 2) for _, e := range loadedWCfg.Entries { if e.FilePath == "file1.yaml" { diff --git a/pkg/config/localconfig.go b/pkg/config/localconfig.go index ac7dd870..2423a497 100644 --- a/pkg/config/localconfig.go +++ b/pkg/config/localconfig.go @@ -386,7 +386,11 @@ func (l *LocalConfig) RemoveAuth(server string) bool { } // UpsertEntry upserts a watch entry. -func (w *WatchConfig) UpsertEntry(entry WatchEntry) { +func (w *WatchConfig) UpsertEntry(entry WatchEntry) error { + if len(entry.Context) == 0 { + return fmt.Errorf("watch entry context must not be empty") + } + for i, e := range w.Entries { if e.FilePath == entry.FilePath { contexts := w.Entries[i].Context @@ -394,10 +398,11 @@ func (w *WatchConfig) UpsertEntry(entry WatchEntry) { entry.Context = append(entry.Context, contexts...) } w.Entries[i] = entry - return + return nil } } w.Entries = append(w.Entries, entry) + return nil } // ReadLocalWatchConfig loads up the local watch configuration file. Returns nil if config does not exist diff --git a/pkg/config/localconfig_test.go b/pkg/config/localconfig_test.go index 420432b3..cc48ecc0 100644 --- a/pkg/config/localconfig_test.go +++ b/pkg/config/localconfig_test.go @@ -69,3 +69,23 @@ func TestRemoveInstance_NoDuplicatesAfterRecreate(t *testing.T) { } } } + +func TestWatchConfigEmptyContext(t *testing.T) { + watchConfig := &WatchConfig{} + + if err := watchConfig.UpsertEntry(WatchEntry{ + FilePath: "petstore.yaml", + Context: []string{"default"}, + }); err != nil { + t.Fatalf("expected valid watch entry to be accepted: %v", err) + } + if err := watchConfig.UpsertEntry(WatchEntry{ + FilePath: "petstore.yaml", + Context: nil, + }); err == nil { + t.Fatal("expected empty watch entry context to return an error") + } + if len(watchConfig.Entries) != 1 { + t.Fatalf("expected invalid watch entry not to be persisted, got %d entries", len(watchConfig.Entries)) + } +}