Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Unit Tests] - UpdateFeatureFlag #2340

Closed
tomsmith8 opened this issue Jan 7, 2025 · 4 comments · Fixed by #2364
Closed

[Unit Tests] - UpdateFeatureFlag #2340

tomsmith8 opened this issue Jan 7, 2025 · 4 comments · Fixed by #2364
Assignees

Comments

@tomsmith8
Copy link

Unit Test Coverage for "UpdateFeatureFlag"


Stakwork Run


Unit Test Code


File: /tmp/stakwork/sphinx-tribes/db/feature_flags.go


package db

import (
  "errors"
  "fmt"
  "testing"
  "time"

  "github.com/google/uuid"
  "github.com/stretchr/testify/assert"
  "gorm.io/gorm"
)

// Mock database and feature flag for testing
type mockDB struct {
  featureFlags map[uuid.UUID]FeatureFlag
  errOnFetch   error
  errOnSave    error
}

func (m *mockDB) First(dest interface{}, conds ...interface{}) *gorm.DB {
  if m.errOnFetch != nil {
  	return &gorm.DB{Error: m.errOnFetch}
  }

  uuid, ok := conds[1].(uuid.UUID)
  if !ok {
  	return &gorm.DB{Error: errors.New("invalid UUID")}
  }

  flag, exists := m.featureFlags[uuid]
  if !exists {
  	return &gorm.DB{Error: gorm.ErrRecordNotFound}
  }

  *dest.(*FeatureFlag) = flag
  return &gorm.DB{}
}

func (m *mockDB) Save(value interface{}) *gorm.DB {
  if m.errOnSave != nil {
  	return &gorm.DB{Error: m.errOnSave}
  }

  flag := value.(*FeatureFlag)
  m.featureFlags[flag.UUID] = *flag
  return &gorm.DB{}
}

func TestUpdateFeatureFlag(t *testing.T) {
  tests := []struct {
  	name          string
  	inputFlag     FeatureFlag
  	setupMock     func() *mockDB
  	expectedFlag  FeatureFlag
  	expectedError string
  }{
  	{
  		name: "Update Existing Feature Flag",
  		inputFlag: FeatureFlag{
  			UUID:        uuid.New(),
  			Name:        "Updated Name",
  			Description: "Updated Description",
  			Enabled:     true,
  		},
  		setupMock: func() *mockDB {
  			existingUUID := uuid.New()
  			return &mockDB{
  				featureFlags: map[uuid.UUID]FeatureFlag{
  					existingUUID: {
  						UUID:        existingUUID,
  						Name:        "Old Name",
  						Description: "Old Description",
  						Enabled:     false,
  					},
  				},
  			}
  		},
  		expectedFlag: FeatureFlag{
  			Name:        "Updated Name",
  			Description: "Updated Description",
  			Enabled:     true,
  		},
  		expectedError: "",
  	},
  	{
  		name: "Nil UUID",
  		inputFlag: FeatureFlag{
  			UUID: uuid.Nil,
  		},
  		setupMock: func() *mockDB {
  			return &mockDB{}
  		},
  		expectedFlag:  FeatureFlag{},
  		expectedError: "feature flag UUID is required",
  	},
  	{
  		name: "Non-Existent UUID",
  		inputFlag: FeatureFlag{
  			UUID: uuid.New(),
  		},
  		setupMock: func() *mockDB {
  			return &mockDB{}
  		},
  		expectedFlag:  FeatureFlag{},
  		expectedError: "feature flag not found",
  	},
  	{
  		name: "Database Fetch Error",
  		inputFlag: FeatureFlag{
  			UUID: uuid.New(),
  		},
  		setupMock: func() *mockDB {
  			return &mockDB{errOnFetch: errors.New("fetch error")}
  		},
  		expectedFlag:  FeatureFlag{},
  		expectedError: "failed to fetch feature flag: fetch error",
  	},
  	{
  		name: "Database Save Error",
  		inputFlag: FeatureFlag{
  			UUID: uuid.New(),
  		},
  		setupMock: func() *mockDB {
  			existingUUID := uuid.New()
  			return &mockDB{
  				featureFlags: map[uuid.UUID]FeatureFlag{
  					existingUUID: {
  						UUID: existingUUID,
  					},
  				},
  				errOnSave: errors.New("save error"),
  			}
  		},
  		expectedFlag:  FeatureFlag{},
  		expectedError: "failed to update feature flag: save error",
  	},
  	{
  		name: "Update with Empty Name",
  		inputFlag: FeatureFlag{
  			UUID: uuid.New(),
  			Name: "",
  		},
  		setupMock: func() *mockDB {
  			existingUUID := uuid.New()
  			return &mockDB{
  				featureFlags: map[uuid.UUID]FeatureFlag{
  					existingUUID: {
  						UUID: existingUUID,
  						Name: "Old Name",
  					},
  				},
  			}
  		},
  		expectedFlag: FeatureFlag{
  			Name: "",
  		},
  		expectedError: "",
  	},
  	{
  		name: "Update with Long Description",
  		inputFlag: FeatureFlag{
  			UUID:        uuid.New(),
  			Description: "A very long description that exceeds normal length expectations...",
  		},
  		setupMock: func() *mockDB {
  			existingUUID := uuid.New()
  			return &mockDB{
  				featureFlags: map[uuid.UUID]FeatureFlag{
  					existingUUID: {
  						UUID: existingUUID,
  					},
  				},
  			}
  		},
  		expectedFlag: FeatureFlag{
  			Description: "A very long description that exceeds normal length expectations...",
  		},
  		expectedError: "",
  	},
  	{
  		name: "Toggle Enabled State",
  		inputFlag: FeatureFlag{
  			UUID:    uuid.New(),
  			Enabled: true,
  		},
  		setupMock: func() *mockDB {
  			existingUUID := uuid.New()
  			return &mockDB{
  				featureFlags: map[uuid.UUID]FeatureFlag{
  					existingUUID: {
  						UUID:    existingUUID,
  						Enabled: false,
  					},
  				},
  			}
  		},
  		expectedFlag: FeatureFlag{
  			Enabled: true,
  		},
  		expectedError: "",
  	},
  	{
  		name: "Update with No Changes",
  		inputFlag: FeatureFlag{
  			UUID:        uuid.New(),
  			Name:        "Same Name",
  			Description: "Same Description",
  			Enabled:     true,
  		},
  		setupMock: func() *mockDB {
  			existingUUID := uuid.New()
  			return &mockDB{
  				featureFlags: map[uuid.UUID]FeatureFlag{
  					existingUUID: {
  						UUID:        existingUUID,
  						Name:        "Same Name",
  						Description: "Same Description",
  						Enabled:     true,
  					},
  				},
  			}
  		},
  		expectedFlag: FeatureFlag{
  			Name:        "Same Name",
  			Description: "Same Description",
  			Enabled:     true,
  		},
  		expectedError: "",
  	},
  	{
  		name: "Update with Special Characters in Name",
  		inputFlag: FeatureFlag{
  			UUID: uuid.New(),
  			Name: "Name with !@#$%^&*()",
  		},
  		setupMock: func() *mockDB {
  			existingUUID := uuid.New()
  			return &mockDB{
  				featureFlags: map[uuid.UUID]FeatureFlag{
  					existingUUID: {
  						UUID: existingUUID,
  					},
  				},
  			}
  		},
  		expectedFlag: FeatureFlag{
  			Name: "Name with !@#$%^&*()",
  		},
  		expectedError: "",
  	},
  	{
  		name: "Update with Null Description",
  		inputFlag: FeatureFlag{
  			UUID:        uuid.New(),
  			Description: "",
  		},
  		setupMock: func() *mockDB {
  			existingUUID := uuid.New()
  			return &mockDB{
  				featureFlags: map[uuid.UUID]FeatureFlag{
  					existingUUID: {
  						UUID: existingUUID,
  					},
  				},
  			}
  		},
  		expectedFlag: FeatureFlag{
  			Description: "",
  		},
  		expectedError: "",
  	},
  }

  for _, tt := range tests {
  	t.Run(tt.name, func(t *testing.T) {
  		mockDB := tt.setupMock()
  		db := database{db: mockDB}

  		updatedFlag, err := db.UpdateFeatureFlag(&tt.inputFlag)

  		if tt.expectedError != "" {
  			assert.Error(t, err)
  			assert.Contains(t, err.Error(), tt.expectedError)
  		} else {
  			assert.NoError(t, err)
  			assert.Equal(t, tt.expectedFlag.Name, updatedFlag.Name)
  			assert.Equal(t, tt.expectedFlag.Description, updatedFlag.Description)
  			assert.Equal(t, tt.expectedFlag.Enabled, updatedFlag.Enabled)
  		}
  	})
  }
}
@saithsab877
Copy link
Contributor

saithsab877 commented Jan 7, 2025

@tomsmith8 assign me?

@sophieturner0
Copy link
Contributor

@tomsmith8 I can help?

@MahtabBukhari
Copy link
Contributor

MahtabBukhari commented Jan 7, 2025

@tomsmith8 assign me

@MirzaHanan
Copy link
Contributor

@tomsmith8 could you assign me?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants