diff --git a/assets/invalid-config.toml b/assets/invalid-config.toml new file mode 100644 index 0000000..e466dcb --- /dev/null +++ b/assets/invalid-config.toml @@ -0,0 +1 @@ +invalid \ No newline at end of file diff --git a/assets/invalid-json.json b/assets/invalid-json.json new file mode 100644 index 0000000..bec6f91 --- /dev/null +++ b/assets/invalid-json.json @@ -0,0 +1 @@ +not valid \ No newline at end of file diff --git a/assets/valid-config.toml b/assets/valid-config.toml new file mode 100644 index 0000000..5bf28d6 --- /dev/null +++ b/assets/valid-config.toml @@ -0,0 +1,15 @@ +state-path = "cosmos-proposals-checker-state.json" +mutes-path = "cosmos-proposals-checker-mutes.json" +interval = "@hourly" + +[[chains]] +name = "bitsong" +pretty-name = "Bitsong" +keplr-name = "bitsong" +mintscan-prefix = "bitsong" +lcd-endpoints = ["https://lcd-bitsong-app.cosmostation.io"] +wallets = [ + { address = "bitsong14rvn7anf22e00vj5x3al4w50ns78s7n4t8yxcy", alias = "Validator wallet" }, +] +type = "cosmos" +proposals-type = "v1beta1" diff --git a/assets/valid-mutes.json b/assets/valid-mutes.json new file mode 100644 index 0000000..cd37329 --- /dev/null +++ b/assets/valid-mutes.json @@ -0,0 +1 @@ +{"Mutes":[{"Chain":"","ProposalID":"","Expires":"2023-12-15T06:08:45.972192+03:00","Comment":"Muted using cosmos-proposals-checker for 14h0m0s by Sergey | 🐹 Quokka Stake"}]} \ No newline at end of file diff --git a/pkg/fs/test_fs.go b/pkg/fs/test_fs.go index 0980c41..09a625e 100644 --- a/pkg/fs/test_fs.go +++ b/pkg/fs/test_fs.go @@ -1,30 +1,59 @@ package fs import ( + "errors" + "main/assets" "os" ) -type TestFS struct{} +type TestFS struct { + WithWriteError bool + WithCreateError bool + + WithFileWriteError bool + WithFileCloseError bool +} type TestFile struct { + WithFileWriteError bool + WithFileCloseError bool } func (f *TestFile) Write(p []byte) (int, error) { + if f.WithFileWriteError { + return 0, errors.New("stub error") + } + return 0, nil } func (f *TestFile) Close() error { + if f.WithFileCloseError { + return errors.New("stub error") + } + return nil } func (fs *TestFS) ReadFile(name string) ([]byte, error) { - return []byte{}, nil + return assets.EmbedFS.ReadFile(name) } func (fs *TestFS) WriteFile(name string, data []byte, perms os.FileMode) error { + if fs.WithWriteError { + return errors.New("stub error") + } + return nil } func (fs *TestFS) Create(path string) (File, error) { - return &TestFile{}, nil // go + if fs.WithCreateError { + return nil, errors.New("stub error") + } + + return &TestFile{ + WithFileWriteError: fs.WithFileWriteError, + WithFileCloseError: fs.WithFileCloseError, + }, nil } diff --git a/pkg/load_config.go b/pkg/load_config.go index b538c8a..8b923c2 100644 --- a/pkg/load_config.go +++ b/pkg/load_config.go @@ -3,7 +3,6 @@ package pkg import ( "fmt" "main/pkg/fs" - "main/pkg/logger" "main/pkg/types" "github.com/BurntSushi/toml" @@ -23,9 +22,7 @@ func GetConfig(filesystem fs.FS, path string) (*types.Config, error) { return nil, err } - if err := defaults.Set(configStruct); err != nil { - logger.GetDefaultLogger().Fatal().Err(err).Msg("Error setting default config values") - } + defaults.MustSet(configStruct) for _, chain := range configStruct.Chains { if chain.MintscanPrefix != "" { diff --git a/pkg/load_config_test.go b/pkg/load_config_test.go new file mode 100644 index 0000000..b447d63 --- /dev/null +++ b/pkg/load_config_test.go @@ -0,0 +1,48 @@ +package pkg + +import ( + "main/pkg/fs" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestLoadConfigNotExistingFile(t *testing.T) { + t.Parallel() + + filesystem := &fs.TestFS{} + + config, err := GetConfig(filesystem, "notexisting.toml") + + assert.Nil(t, config) + require.Error(t, err) +} + +func TestLoadConfigInvalidToml(t *testing.T) { + t.Parallel() + + filesystem := &fs.TestFS{} + + config, err := GetConfig(filesystem, "invalid-config.toml") + + assert.Nil(t, config) + require.Error(t, err) +} + +func TestLoadConfigValidToml(t *testing.T) { + t.Parallel() + + filesystem := &fs.TestFS{} + + config, err := GetConfig(filesystem, "valid-config.toml") + + require.NoError(t, err) + assert.NotNil(t, config) + require.Len(t, config.Chains, 1) + + firstChain := config.Chains[0] + require.NotNil(t, firstChain.Explorer) + require.Equal(t, "https://mintscan.io/bitsong/proposals/%s", firstChain.Explorer.ProposalLinkPattern) + require.Equal(t, "https://mintscan.io/bitsong/account/%s", firstChain.Explorer.WalletLinkPattern) +} diff --git a/pkg/mutes/manager_test.go b/pkg/mutes/manager_test.go new file mode 100644 index 0000000..79d50fb --- /dev/null +++ b/pkg/mutes/manager_test.go @@ -0,0 +1,132 @@ +package mutesmanager + +import ( + "main/pkg/fs" + "main/pkg/logger" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestMuteManagerLoadWithoutPath(t *testing.T) { + t.Parallel() + + log := logger.GetNopLogger() + filesystem := &fs.TestFS{} + + manager := NewMutesManager("", filesystem, log) + manager.Load() + + assert.Empty(t, manager.Mutes.Mutes) +} + +func TestMuteManagerLoadNotExistingPath(t *testing.T) { + t.Parallel() + + log := logger.GetNopLogger() + filesystem := &fs.TestFS{} + + manager := NewMutesManager("not-existing.json", filesystem, log) + manager.Load() + + assert.Empty(t, manager.Mutes.Mutes) +} + +func TestMuteManagerLoadInvalidJson(t *testing.T) { + t.Parallel() + + log := logger.GetNopLogger() + filesystem := &fs.TestFS{} + + manager := NewMutesManager("invalid-json.json", filesystem, log) + manager.Load() + + assert.Empty(t, manager.Mutes.Mutes) +} + +func TestMuteManagerLoadValidJson(t *testing.T) { + t.Parallel() + + log := logger.GetNopLogger() + filesystem := &fs.TestFS{} + + manager := NewMutesManager("valid-mutes.json", filesystem, log) + manager.Load() + + assert.NotEmpty(t, manager.Mutes.Mutes) +} + +func TestMuteManagerSaveWithoutPath(t *testing.T) { + t.Parallel() + + log := logger.GetNopLogger() + filesystem := &fs.TestFS{} + + manager := NewMutesManager("", filesystem, log) + manager.Load() + manager.Save() + + assert.Empty(t, manager.Mutes.Mutes) +} + +func TestMuteManagerSaveWithError(t *testing.T) { + t.Parallel() + + log := logger.GetNopLogger() + filesystem := &fs.TestFS{WithWriteError: true} + + manager := NewMutesManager("out.json", filesystem, log) + manager.Load() + manager.Save() + + assert.Empty(t, manager.Mutes.Mutes) +} + +func TestMuteManagerSaveWithoutError(t *testing.T) { + t.Parallel() + + log := logger.GetNopLogger() + filesystem := &fs.TestFS{} + + manager := NewMutesManager("out.json", filesystem, log) + manager.Load() + manager.Save() + + assert.Empty(t, manager.Mutes.Mutes) +} + +func TestMuteManagerAddMuteIsMuted(t *testing.T) { + t.Parallel() + + log := logger.GetNopLogger() + filesystem := &fs.TestFS{} + + manager := NewMutesManager("out.json", filesystem, log) + manager.Load() + + manager.AddMute(&Mute{ + Chain: "chain", + Expires: time.Now().Add(time.Hour), + }) + + assert.True(t, manager.IsMuted("chain", "proposal")) + assert.False(t, manager.IsMuted("chain2", "proposal")) +} + +func TestMuteManagerIsMutedNoPath(t *testing.T) { + t.Parallel() + + log := logger.GetNopLogger() + filesystem := &fs.TestFS{} + + manager := NewMutesManager("", filesystem, log) + manager.Load() + + manager.AddMute(&Mute{ + Chain: "chain", + Expires: time.Now().Add(time.Hour), + }) + + assert.False(t, manager.IsMuted("chain", "proposal")) +}