Skip to content

Commit

Permalink
added event on command and fixed some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
JulesFaucherre committed Aug 1, 2023
1 parent c71d485 commit 1e32523
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 137 deletions.
2 changes: 2 additions & 0 deletions cmd/create_telemetry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ func TestLoadTelemetrySettings(t *testing.T) {
},
telemetryEvents: []telemetry.Event{
{Object: "cli-telemetry", Action: "disabled", Properties: map[string]interface{}{
"UUID": "cli-anonymous-telemetry",
"is_self_hosted": false,
}},
},
Expand Down Expand Up @@ -182,6 +183,7 @@ func TestLoadTelemetrySettings(t *testing.T) {
fileNotCreated: true,
telemetryEvents: []telemetry.Event{
{Object: "cli-telemetry", Action: "disabled_default", Properties: map[string]interface{}{
"UUID": "cli-anonymous-telemetry",
"is_self_hosted": false,
}},
},
Expand Down
17 changes: 13 additions & 4 deletions cmd/telemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"os"

"github.com/CircleCI-Public/circleci-cli/settings"
"github.com/CircleCI-Public/circleci-cli/telemetry"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
Expand All @@ -14,17 +15,25 @@ func newTelemetryCommand(config *settings.Config) *cobra.Command {
telemetryEnable := &cobra.Command{
Use: "enable",
Short: "Allow telemetry events to be sent to CircleCI servers",
RunE: func(_ *cobra.Command, _ []string) error {
return setIsTelemetryActive(apiClient, true)
RunE: func(cmd *cobra.Command, _ []string) error {
err := setIsTelemetryActive(apiClient, true)
if telemetryClient, ok := telemetry.FromContext(cmd.Context()); ok {
_ = telemetryClient.Track(telemetry.CreateChangeTelemetryStatusEvent("enabled", "telemetry-command", err))
}
return err
},
Args: cobra.ExactArgs(0),
}

telemetryDisable := &cobra.Command{
Use: "disable",
Short: "Make sure no telemetry events is sent to CircleCI servers",
RunE: func(_ *cobra.Command, _ []string) error {
return setIsTelemetryActive(apiClient, false)
RunE: func(cmd *cobra.Command, _ []string) error {
err := setIsTelemetryActive(apiClient, false)
if telemetryClient, ok := telemetry.FromContext(cmd.Context()); ok {
_ = telemetryClient.Track(telemetry.CreateChangeTelemetryStatusEvent("disabled", "telemetry-command", err))
}
return err
},
Args: cobra.ExactArgs(0),
}
Expand Down
173 changes: 44 additions & 129 deletions cmd/telemetry_test.go
Original file line number Diff line number Diff line change
@@ -1,143 +1,58 @@
package cmd
package cmd_test

import (
"path/filepath"
"testing"
"fmt"
"os/exec"

"github.com/CircleCI-Public/circleci-cli/settings"
"github.com/spf13/afero"
"gotest.tools/v3/assert"
)

func TestSetIsTelemetryActive(t *testing.T) {
type args struct {
apiClient TelemetryAPIClient
isActive bool
settings *settings.TelemetrySettings
}
type want struct {
settings *settings.TelemetrySettings
}
"github.com/CircleCI-Public/circleci-cli/clitest"
"github.com/CircleCI-Public/circleci-cli/telemetry"
"github.com/onsi/gomega/gexec"

type testCase struct {
name string
args args
want want
}
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

userId := "user-id"
uniqueId := "unique-id"
var _ = Describe("Telemetry events on telemetry commands", func() {
var (
tempSettings *clitest.TempSettings
command *exec.Cmd
)

testCases := []testCase{
{
name: "Enabling telemetry with settings should just update the is active field",
args: args{
apiClient: telemetryTestAPIClient{},
isActive: true,
settings: &settings.TelemetrySettings{
IsEnabled: false,
HasAnsweredPrompt: true,
UniqueID: uniqueId,
UserID: userId,
},
},
want: want{
settings: &settings.TelemetrySettings{
IsEnabled: true,
HasAnsweredPrompt: true,
UniqueID: uniqueId,
UserID: userId,
},
},
},
{
name: "Enabling telemetry without settings should fill the settings fields",
args: args{
apiClient: telemetryTestAPIClient{id: userId, err: nil},
isActive: true,
settings: nil,
},
want: want{
settings: &settings.TelemetrySettings{
IsEnabled: true,
HasAnsweredPrompt: true,
UniqueID: uniqueId,
UserID: userId,
},
},
},
{
name: "Disabling telemetry with settings should just update the is active field",
args: args{
apiClient: telemetryTestAPIClient{},
isActive: false,
settings: &settings.TelemetrySettings{
IsEnabled: true,
HasAnsweredPrompt: true,
UniqueID: uniqueId,
UserID: userId,
},
},
want: want{
settings: &settings.TelemetrySettings{
IsEnabled: false,
HasAnsweredPrompt: true,
UniqueID: uniqueId,
UserID: userId,
},
},
},
{
name: "Enabling telemetry without settings should fill the settings fields",
args: args{
apiClient: telemetryTestAPIClient{id: userId, err: nil},
isActive: false,
settings: nil,
},
want: want{
settings: &settings.TelemetrySettings{
IsEnabled: false,
HasAnsweredPrompt: true,
UniqueID: uniqueId,
UserID: userId,
},
},
},
}
BeforeEach(func() {
tempSettings = clitest.WithTempSettings()
})

// Mock create UUID
oldUUIDCreate := CreateUUID
CreateUUID = func() string { return uniqueId }
defer (func() { CreateUUID = oldUUIDCreate })()
AfterEach(func() {
tempSettings.Close()
})

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
// Mock FS
oldFS := settings.FS.Fs
settings.FS.Fs = afero.NewMemMapFs()
defer (func() { settings.FS.Fs = oldFS })()
Describe("telemetry enable", func() {
It("should send an event", func() {
command = exec.Command(pathCLI, "telemetry", "enable")
command.Env = append(command.Env, fmt.Sprintf("MOCK_TELEMETRY=%s", tempSettings.TelemetryDestPath))

if tt.args.settings != nil {
err := tt.args.settings.Write()
assert.NilError(t, err)
}
session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ShouldNot(HaveOccurred())
Eventually(session).Should(gexec.Exit(0))

err := setIsTelemetryActive(tt.args.apiClient, tt.args.isActive)
assert.NilError(t, err)
clitest.CompareTelemetryEvent(tempSettings, []telemetry.Event{
telemetry.CreateChangeTelemetryStatusEvent("enabled", "telemetry-command", nil),
})
})
})

exist, err := settings.FS.Exists(filepath.Join(settings.SettingsPath(), "telemetry.yml"))
assert.NilError(t, err)
if tt.want.settings == nil {
assert.Equal(t, exist, false)
} else {
assert.Equal(t, exist, true)
Describe("telemetry disable", func() {
It("should send an event", func() {
command = exec.Command(pathCLI, "telemetry", "disable")
command.Env = append(command.Env, fmt.Sprintf("MOCK_TELEMETRY=%s", tempSettings.TelemetryDestPath))

loadedSettings := &settings.TelemetrySettings{}
err := loadedSettings.Load()
assert.NilError(t, err)
session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ShouldNot(HaveOccurred())
Eventually(session).Should(gexec.Exit(0))

assert.DeepEqual(t, tt.want.settings, loadedSettings)
}
clitest.CompareTelemetryEvent(tempSettings, []telemetry.Event{
telemetry.CreateChangeTelemetryStatusEvent("disabled", "telemetry-command", nil),
})
})
}
}
})
})
143 changes: 143 additions & 0 deletions cmd/telemetry_unit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package cmd

import (
"path/filepath"
"testing"

"github.com/CircleCI-Public/circleci-cli/settings"
"github.com/spf13/afero"
"gotest.tools/v3/assert"
)

func TestSetIsTelemetryActive(t *testing.T) {
type args struct {
apiClient TelemetryAPIClient
isActive bool
settings *settings.TelemetrySettings
}
type want struct {
settings *settings.TelemetrySettings
}

type testCase struct {
name string
args args
want want
}

userId := "user-id"
uniqueId := "unique-id"

testCases := []testCase{
{
name: "Enabling telemetry with settings should just update the is active field",
args: args{
apiClient: telemetryTestAPIClient{},
isActive: true,
settings: &settings.TelemetrySettings{
IsEnabled: false,
HasAnsweredPrompt: true,
UniqueID: uniqueId,
UserID: userId,
},
},
want: want{
settings: &settings.TelemetrySettings{
IsEnabled: true,
HasAnsweredPrompt: true,
UniqueID: uniqueId,
UserID: userId,
},
},
},
{
name: "Enabling telemetry without settings should fill the settings fields",
args: args{
apiClient: telemetryTestAPIClient{id: userId, err: nil},
isActive: true,
settings: nil,
},
want: want{
settings: &settings.TelemetrySettings{
IsEnabled: true,
HasAnsweredPrompt: true,
UniqueID: uniqueId,
UserID: userId,
},
},
},
{
name: "Disabling telemetry with settings should just update the is active field",
args: args{
apiClient: telemetryTestAPIClient{},
isActive: false,
settings: &settings.TelemetrySettings{
IsEnabled: true,
HasAnsweredPrompt: true,
UniqueID: uniqueId,
UserID: userId,
},
},
want: want{
settings: &settings.TelemetrySettings{
IsEnabled: false,
HasAnsweredPrompt: true,
UniqueID: uniqueId,
UserID: userId,
},
},
},
{
name: "Enabling telemetry without settings should fill the settings fields",
args: args{
apiClient: telemetryTestAPIClient{id: userId, err: nil},
isActive: false,
settings: nil,
},
want: want{
settings: &settings.TelemetrySettings{
IsEnabled: false,
HasAnsweredPrompt: true,
UniqueID: uniqueId,
UserID: userId,
},
},
},
}

// Mock create UUID
oldUUIDCreate := CreateUUID
CreateUUID = func() string { return uniqueId }
defer (func() { CreateUUID = oldUUIDCreate })()

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
// Mock FS
oldFS := settings.FS.Fs
settings.FS.Fs = afero.NewMemMapFs()
defer (func() { settings.FS.Fs = oldFS })()

if tt.args.settings != nil {
err := tt.args.settings.Write()
assert.NilError(t, err)
}

err := setIsTelemetryActive(tt.args.apiClient, tt.args.isActive)
assert.NilError(t, err)

exist, err := settings.FS.Exists(filepath.Join(settings.SettingsPath(), "telemetry.yml"))
assert.NilError(t, err)
if tt.want.settings == nil {
assert.Equal(t, exist, false)
} else {
assert.Equal(t, exist, true)

loadedSettings := &settings.TelemetrySettings{}
err := loadedSettings.Load()
assert.NilError(t, err)

assert.DeepEqual(t, tt.want.settings, loadedSettings)
}
})
}
}
Loading

0 comments on commit 1e32523

Please sign in to comment.