diff --git a/core/config.go b/core/config.go index 85f9b72..055b37a 100644 --- a/core/config.go +++ b/core/config.go @@ -19,7 +19,6 @@ var ( slashRegex = regexp.MustCompile(`/+$`) ) - // ConfigInterface settings data structure type ConfigInterface interface { GetVersion() string @@ -170,11 +169,6 @@ func (c Config) GetUpdateInterval() int { return c.UpdateInterval } -// IsDebug debug state -func (c Config) IsDebug() bool { - return c.Debug -} - // GetName transport name func (t Info) GetName() string { return t.Name diff --git a/core/config_test.go b/core/config_test.go new file mode 100644 index 0000000..c1b939b --- /dev/null +++ b/core/config_test.go @@ -0,0 +1,119 @@ +package core + +import ( + "io/ioutil" + "os" + "path" + "testing" + + "github.com/op/go-logging" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +var testConfigFile = path.Join(os.TempDir(), "config_test.yml") + +type ConfigTest struct { + suite.Suite + config *Config + data []byte +} + +func (c *ConfigTest) SetupTest() { + c.data = []byte(` +version: 3.2.1 + +database: + connection: postgres://user:password@host:5432/dbname?sslmode=disable + +http_server: + host: example.com + listen: :3001 + +transport_info: + name: Transport + code: mg-transport + logo_path: /static/logo.svg + +sentry_dsn: dsn string +log_level: 5 +debug: true +update_interval: 24 + +config_aws: + access_key_id: key + secret_access_key: secret + region: region + bucket: bucket + folder_name: folder + content_type: image/jpeg`) + err := ioutil.WriteFile(testConfigFile, c.data, os.ModePerm) + require.Nil(c.T(), err) + + c.config = NewConfig(testConfigFile) +} + +func (c *ConfigTest) Test_GetConfigData() { + assert.Equal(c.T(), c.data, c.config.GetConfigData(testConfigFile)) +} + +func (c *ConfigTest) Test_GetVersion() { + assert.Equal(c.T(), "3.2.1", c.config.GetVersion()) +} + +func (c *ConfigTest) Test_GetDBConfig() { + assert.Equal(c.T(), "postgres://user:password@host:5432/dbname?sslmode=disable", c.config.GetDBConfig().Connection) +} + +func (c *ConfigTest) Test_GetHttpServer() { + assert.Equal(c.T(), "example.com", c.config.GetHTTPConfig().Host) + assert.Equal(c.T(), ":3001", c.config.GetHTTPConfig().Listen) +} + +func (c *ConfigTest) Test_GetTransportInfo() { + assert.Equal(c.T(), "Transport", c.config.GetTransportInfo().GetName()) + assert.Equal(c.T(), "mg-transport", c.config.GetTransportInfo().GetCode()) + assert.Equal(c.T(), "/static/logo.svg", c.config.GetTransportInfo().GetLogoPath()) +} + +func (c *ConfigTest) Test_GetSentryDSN() { + assert.Equal(c.T(), "dsn string", c.config.GetSentryDSN()) +} + +func (c *ConfigTest) Test_GetLogLevel() { + assert.Equal(c.T(), logging.Level(5), c.config.GetLogLevel()) +} + +func (c *ConfigTest) Test_GetDebug() { + assert.Equal(c.T(), true, c.config.GetDebug()) +} + +func (c *ConfigTest) Test_GetUpdateInterval() { + assert.Equal(c.T(), 24, c.config.GetUpdateInterval()) +} + +func (c *ConfigTest) Test_GetConfigAWS() { + assert.Equal(c.T(), "key", c.config.GetAWSConfig().AccessKeyID) + assert.Equal(c.T(), "secret", c.config.GetAWSConfig().SecretAccessKey) + assert.Equal(c.T(), "region", c.config.GetAWSConfig().Region) + assert.Equal(c.T(), "bucket", c.config.GetAWSConfig().Bucket) + assert.Equal(c.T(), "folder", c.config.GetAWSConfig().FolderName) + assert.Equal(c.T(), "image/jpeg", c.config.GetAWSConfig().ContentType) +} + +func (c *ConfigTest) TearDownTest() { + _ = os.Remove(testConfigFile) +} + +func TestConfig_Suite(t *testing.T) { + suite.Run(t, new(ConfigTest)) +} + +func TestConfig_NoFile(t *testing.T) { + defer func() { + assert.NotNil(t, recover()) + }() + + _ = NewConfig(path.Join(os.TempDir(), "file_which_should_not_exist_anyway")) +} diff --git a/core/engine.go b/core/engine.go index 56fbb48..fbb8a04 100644 --- a/core/engine.go +++ b/core/engine.go @@ -36,14 +36,14 @@ func New() *Engine { } func (e *Engine) initGin() { - if !e.Config.IsDebug() { + if !e.Config.GetDebug() { gin.SetMode(gin.ReleaseMode) } r := gin.New() r.Use(gin.Recovery()) - if e.Config.IsDebug() { + if e.Config.GetDebug() { r.Use(gin.Logger()) } @@ -76,9 +76,8 @@ func (e *Engine) Prepare() *Engine { e.LoadTranslations() e.createDB(e.Config.GetDBConfig()) e.createRavenClient(e.Config.GetSentryDSN()) - e.resetUtils(e.Config.GetAWSConfig(), e.Config.IsDebug(), 0) + e.resetUtils(e.Config.GetAWSConfig(), e.Config.GetDebug(), 0) e.Logger = NewLogger(e.Config.GetTransportInfo().GetCode(), e.Config.GetLogLevel(), e.LogFormatter) - e.Utils.Localizer = &e.Localizer e.Sentry.Localizer = &e.Localizer e.Utils.Logger = e.Logger e.Sentry.Logger = e.Logger diff --git a/core/error_test.go b/core/error_test.go new file mode 100644 index 0000000..8915dd8 --- /dev/null +++ b/core/error_test.go @@ -0,0 +1,29 @@ +package core + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestError_GetErrorResponse(t *testing.T) { + code, resp := GetErrorResponse(http.StatusBadRequest, "error string") + + assert.Equal(t, http.StatusBadRequest, code) + assert.Equal(t, "error string", resp.(ErrorResponse).Error) +} + +func TestError_BadRequest(t *testing.T) { + code, resp := BadRequest("error string") + + assert.Equal(t, http.StatusBadRequest, code) + assert.Equal(t, "error string", resp.(ErrorResponse).Error) +} + +func TestError_InternalServerError(t *testing.T) { + code, resp := InternalServerError("error string") + + assert.Equal(t, http.StatusInternalServerError, code) + assert.Equal(t, "error string", resp.(ErrorResponse).Error) +} diff --git a/core/localizer_test.go b/core/localizer_test.go new file mode 100644 index 0000000..e2e5251 --- /dev/null +++ b/core/localizer_test.go @@ -0,0 +1,101 @@ +package core + +import ( + "io/ioutil" + "net/http" + "os" + "path" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "golang.org/x/text/language" +) + +var ( + testTranslationsDir = path.Join(os.TempDir(), "translations_test_dir") + testLangFile = path.Join(testTranslationsDir, "translate.en.yml") +) + +type LocalizerTest struct { + suite.Suite + localizer *Localizer +} + +func (l *LocalizerTest) SetupTest() { + if _, err := os.Stat(testTranslationsDir); err != nil && os.IsNotExist(err) { + err := os.Mkdir(testTranslationsDir, os.ModePerm) + require.Nil(l.T(), err) + data := []byte("message: Test message\nmessage_template: Test message with {{.data}}") + err = ioutil.WriteFile(testLangFile, data, os.ModePerm) + require.Nil(l.T(), err) + } + + l.localizer = NewLocalizer(language.English, DefaultLocalizerBundle(), DefaultLocalizerMatcher(), testTranslationsDir) +} + +func (l *LocalizerTest) Test_SetLocale() { + defer func() { + require.Nil(l.T(), recover()) + }() + + l.localizer.SetLocale("en") +} + +func (l *LocalizerTest) Test_LocalizationMiddleware() { + assert.NotNil(l.T(), l.localizer.LocalizationMiddleware()) +} + +func (l *LocalizerTest) Test_LocalizationFuncMap() { + functions := l.localizer.LocalizationFuncMap() + _, ok := functions["trans"] + assert.True(l.T(), ok) +} + +func (l *LocalizerTest) Test_GetLocalizedMessage() { + defer func() { + require.Nil(l.T(), recover()) + }() + + message := l.localizer.GetLocalizedMessage("message") + assert.Equal(l.T(), "Test message", message) +} + +func (l *LocalizerTest) Test_GetLocalizedTemplateMessage() { + defer func() { + require.Nil(l.T(), recover()) + }() + + message := l.localizer.GetLocalizedTemplateMessage("message_template", map[string]interface{}{"data": "template"}) + assert.Equal(l.T(), "Test message with template", message) +} + +func (l *LocalizerTest) Test_BadRequestLocalized() { + status, resp := l.localizer.BadRequestLocalized("message") + + assert.Equal(l.T(), http.StatusBadRequest, status) + assert.Equal(l.T(), "Test message", resp.(ErrorResponse).Error) +} + +func (l *LocalizerTest) TearDownTest() { + err := os.RemoveAll(testTranslationsDir) + require.Nil(l.T(), err) +} + +func TestLocalizer_Suite(t *testing.T) { + suite.Run(t, new(LocalizerTest)) +} + +func TestLocalizer_NoDirectory(t *testing.T) { + defer func() { + assert.NotNil(t, recover()) + }() + + _ = NewLocalizer( + language.English, + DefaultLocalizerBundle(), + DefaultLocalizerMatcher(), + path.Join(os.TempDir(), "this directory should not exist"), + ) +} diff --git a/core/logger_test.go b/core/logger_test.go new file mode 100644 index 0000000..879fbd8 --- /dev/null +++ b/core/logger_test.go @@ -0,0 +1,21 @@ +package core + +import ( + "testing" + + "github.com/op/go-logging" + "github.com/stretchr/testify/assert" +) + +func TestLogger_NewLogger(t *testing.T) { + logger := NewLogger("code", logging.DEBUG, DefaultLogFormatter()) + + assert.NotNil(t, logger) +} + +func TestLogger_DefaultLogFormatter(t *testing.T) { + formatter := DefaultLogFormatter() + + assert.NotNil(t, formatter) + assert.IsType(t, logging.MustStringFormatter(`%{message}`), formatter) +} diff --git a/core/migrate_test.go b/core/migrate_test.go new file mode 100644 index 0000000..831d735 --- /dev/null +++ b/core/migrate_test.go @@ -0,0 +1,144 @@ +package core + +import ( + "database/sql" + "regexp" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/jinzhu/gorm" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "gopkg.in/gormigrate.v1" +) + +type TestModel struct { + Name string `gorm:"column:name; type:varchar(70)"` +} + +func (TestModel) TableName() string { + return "test_model" +} + +type MigrateTest struct { + suite.Suite + DB *gorm.DB + Migrate *Migrate + mock sqlmock.Sqlmock +} + +func (m *MigrateTest) SetupSuite() { + var ( + db *sql.DB + err error + ) + + require.NotEmpty(m.T(), (MigrationInfo{}).TableName()) + + db, m.mock, err = sqlmock.New() + require.NoError(m.T(), err) + + m.DB, err = gorm.Open("postgres", db) + require.NoError(m.T(), err) + + m.DB.LogMode(true) + m.RefreshMigrate() + m.Migrate.SetDB(m.DB) +} + +func (m *MigrateTest) RefreshMigrate() { + m.Migrate = &Migrate{ + db: m.DB, + prepared: false, + migrations: map[string]*gormigrate.Migration{}, + } +} + +func (m *MigrateTest) Migration_TestModel() *gormigrate.Migration { + return &gormigrate.Migration{ + ID: "1", + Migrate: func(db *gorm.DB) error { + return db.AutoMigrate(TestModel{}).Error + }, + Rollback: func(db *gorm.DB) error { + return db.DropTable(TestModel{}).Error + }, + } +} + +func (m *MigrateTest) Test_Add() { + m.RefreshMigrate() + m.Migrate.Add(nil) + m.Migrate.Add(m.Migration_TestModel()) + + assert.Equal(m.T(), 1, len(m.Migrate.migrations)) + i, ok := m.Migrate.migrations["1"] + require.True(m.T(), ok) + assert.Equal(m.T(), "1", i.ID) +} + +func (m *MigrateTest) Test_prepareMigrations_NilDB() { + m.RefreshMigrate() + m.Migrate.db = nil + err := m.Migrate.prepareMigrations() + + require.Error(m.T(), err) + assert.Equal(m.T(), "db must not be nil", err.Error()) +} + +func (m *MigrateTest) Test_prepareMigrations_AlreadyPrepared() { + m.RefreshMigrate() + m.Migrate.prepared = true + err := m.Migrate.prepareMigrations() + + require.NoError(m.T(), err) + assert.Nil(m.T(), m.Migrate.GORMigrate) +} + +func (m *MigrateTest) Test_prepareMigrations_OK() { + m.RefreshMigrate() + m.Migrate.Add(m.Migration_TestModel()) + err := m.Migrate.prepareMigrations() + + require.NoError(m.T(), err) + assert.True(m.T(), m.Migrate.prepared) + assert.NotNil(m.T(), m.Migrate.GORMigrate) +} + +func (m *MigrateTest) Test_Migrate() { + m.RefreshMigrate() + m.Migrate.Add(m.Migration_TestModel()) + + m.mock.ExpectBegin() + m.mock. + ExpectExec(regexp.QuoteMeta(`CREATE TABLE migrations (id VARCHAR(255) PRIMARY KEY)`)). + WillReturnResult(sqlmock.NewResult(1, 1)) + m.mock. + ExpectQuery(regexp.QuoteMeta(`SELECT id FROM migrations`)). + WillReturnRows(sqlmock.NewRows([]string{"1"})) + m.mock. + ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "migrations" WHERE (id = $1)`)). + WithArgs("1"). + WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(0)) + m.mock. + ExpectExec(regexp.QuoteMeta(`CREATE TABLE "test_model" ("name" varchar(70) )`)). + WillReturnResult(sqlmock.NewResult(1, 1)) + m.mock. + ExpectExec(regexp.QuoteMeta(`INSERT INTO migrations (id) VALUES ($1)`)). + WithArgs("1"). + WillReturnResult(sqlmock.NewResult(1, 1)) + m.mock.ExpectCommit() + + err := m.Migrate.Migrate() + + assert.NoError(m.T(), err) +} + +func TestMigrate_Migrate(t *testing.T) { + assert.NotNil(t, Migrations()) +} + +func TestMigrate_Suite(t *testing.T) { + suite.Run(t, new(MigrateTest)) +} diff --git a/core/utils.go b/core/utils.go index 6412296..35fefc2 100644 --- a/core/utils.go +++ b/core/utils.go @@ -25,18 +25,16 @@ import ( type Utils struct { IsDebug bool ConfigAWS ConfigAWS - Localizer *Localizer Logger *logging.Logger TokenCounter uint32 slashRegex *regexp.Regexp } // NewUtils will create new Utils instance -func NewUtils(awsConfig ConfigAWS, localizer *Localizer, logger *logging.Logger, debug bool) *Utils { +func NewUtils(awsConfig ConfigAWS, logger *logging.Logger, debug bool) *Utils { return &Utils{ IsDebug: debug, ConfigAWS: awsConfig, - Localizer: localizer, Logger: logger, TokenCounter: 0, slashRegex: slashRegex, @@ -141,6 +139,11 @@ func (u *Utils) UploadUserAvatar(url string) (picURLs3 string, err error) { return } +// RemoveTrailingSlash will remove slash at the end of any string +func (u *Utils) RemoveTrailingSlash(crmURL string) string { + return u.slashRegex.ReplaceAllString(crmURL, ``) +} + // GetMGItemData will upload file to MG by URL and return information about attachable item func GetMGItemData(client *v1.MgClient, url string, caption string) (v1.Item, int, error) { item := v1.Item{} @@ -160,11 +163,6 @@ func GetMGItemData(client *v1.MgClient, url string, caption string) (v1.Item, in return item, st, err } -// RemoveTrailingSlash will remove slash at the end of any string -func (u *Utils) RemoveTrailingSlash(crmURL string) string { - return u.slashRegex.ReplaceAllString(crmURL, ``) -} - // GetEntitySHA1 will serialize any value to JSON and return SHA1 hash of this JSON func GetEntitySHA1(v interface{}) (hash string, err error) { res, _ := json.Marshal(v) diff --git a/core/utils_test.go b/core/utils_test.go new file mode 100644 index 0000000..bcda9c7 --- /dev/null +++ b/core/utils_test.go @@ -0,0 +1,252 @@ +package core + +import ( + "encoding/json" + "net/http" + "testing" + "time" + + "github.com/h2non/gock" + "github.com/op/go-logging" + v5 "github.com/retailcrm/api-client-go/v5" + v1 "github.com/retailcrm/mg-transport-api-client-go/v1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +var ( + testCRMURL = "https://fake-uri.retailcrm.ru" + testMGURL = "https://mg-url.example.com" +) + +type UtilsTest struct { + suite.Suite + utils *Utils +} + +func mgClient() *v1.MgClient { + return v1.New(testMGURL, "token") +} + +func (u *UtilsTest) SetupTest() { + logger := NewLogger("code", logging.DEBUG, DefaultLogFormatter()) + awsConfig := ConfigAWS{ + AccessKeyID: "access key id (will be removed)", + SecretAccessKey: "secret access key", + Region: "region", + Bucket: "bucket", + FolderName: "folder", + ContentType: "image/jpeg", + } + + u.utils = NewUtils(awsConfig, logger, false) + u.utils.TokenCounter = 12345 +} + +func (u *UtilsTest) Test_ResetUtils() { + assert.Equal(u.T(), "access key id (will be removed)", u.utils.ConfigAWS.AccessKeyID) + assert.Equal(u.T(), uint32(12345), u.utils.TokenCounter) + assert.False(u.T(), u.utils.IsDebug) + + awsConfig := u.utils.ConfigAWS + awsConfig.AccessKeyID = "access key id" + u.utils.resetUtils(awsConfig, true, 0) + + assert.Equal(u.T(), "access key id", u.utils.ConfigAWS.AccessKeyID) + assert.Equal(u.T(), uint32(0), u.utils.TokenCounter) + assert.True(u.T(), u.utils.IsDebug) +} + +func (u *UtilsTest) Test_GenerateToken() { + u.utils.TokenCounter = 12345 + token := u.utils.GenerateToken() + assert.NotEmpty(u.T(), token) + assert.Equal(u.T(), uint32(12346), u.utils.TokenCounter) +} + +func (u *UtilsTest) Test_GetAPIClient_FailRuntime() { + defer gock.Off() + gock.New(testCRMURL) + + _, status, err := u.utils.GetAPIClient(testCRMURL, "key") + assert.Equal(u.T(), http.StatusInternalServerError, status) + assert.NotNil(u.T(), err) +} + +func (u *UtilsTest) Test_GetAPIClient_FailAPI() { + defer gock.Off() + gock.New(testCRMURL). + Get("/credentials"). + Reply(http.StatusBadRequest). + BodyString(`{"success": false, "errorMsg": "error message"}`) + + _, status, err := u.utils.GetAPIClient(testCRMURL, "key") + assert.Equal(u.T(), http.StatusBadRequest, status) + if assert.NotNil(u.T(), err) { + assert.Equal(u.T(), "invalid credentials", err.Error()) + } +} + +func (u *UtilsTest) Test_GetAPIClient_FailAPICredentials() { + resp := v5.CredentialResponse{ + Success: true, + Credentials: []string{}, + SiteAccess: "all", + SitesAvailable: []string{}, + } + + data, _ := json.Marshal(resp) + + defer gock.Off() + gock.New(testCRMURL). + Get("/credentials"). + Reply(http.StatusOK). + BodyString(string(data)) + + _, status, err := u.utils.GetAPIClient(testCRMURL, "key") + assert.Equal(u.T(), http.StatusBadRequest, status) + if assert.NotNil(u.T(), err) { + assert.Equal(u.T(), "missing credentials", err.Error()) + } +} + +func (u *UtilsTest) Test_GetAPIClient_Success() { + resp := v5.CredentialResponse{ + Success: true, + Credentials: []string{ + "/api/integration-modules/{code}", + "/api/integration-modules/{code}/edit", + }, + SiteAccess: "all", + SitesAvailable: []string{"site"}, + } + + data, _ := json.Marshal(resp) + + defer gock.Off() + gock.New(testCRMURL). + Get("/credentials"). + Reply(http.StatusOK). + BodyString(string(data)) + + _, status, err := u.utils.GetAPIClient(testCRMURL, "key") + require.NoError(u.T(), err) + assert.Equal(u.T(), 0, status) +} + +func (u *UtilsTest) Test_UploadUserAvatar_FailGet() { + defer gock.Off() + gock.New("https://example.com") + + uri, err := u.utils.UploadUserAvatar("https://example.com/image.jpg") + assert.Empty(u.T(), uri) + assert.Error(u.T(), err) +} + +func (u *UtilsTest) Test_UploadUserAvatar_FailBadRequest() { + defer gock.Off() + gock.New("https://example.com"). + Get("/image.jpg"). + Reply(200). + BodyString(`no image here`) + + uri, err := u.utils.UploadUserAvatar("https://example.com/image.jpg") + assert.Empty(u.T(), uri) + assert.Error(u.T(), err) +} + +func (u *UtilsTest) Test_RemoveTrailingSlash() { + assert.Equal(u.T(), testCRMURL, u.utils.RemoveTrailingSlash(testCRMURL+"/")) + assert.Equal(u.T(), testCRMURL, u.utils.RemoveTrailingSlash(testCRMURL)) +} + +func TestUtils_GetMGItemData_FailRuntime_GetImage(t *testing.T) { + defer gock.Off() + gock.New(testMGURL) + gock.New("https://example.com/") + + _, status, err := GetMGItemData(mgClient(), "https://example.com/item.jpg", "") + assert.Error(t, err) + assert.Equal(t, 0, status) +} + +func TestUtils_GetMGItemData_FailAPI(t *testing.T) { + defer gock.Off() + + gock.New("https://example.com/"). + Get("/item.jpg"). + Reply(200). + BodyString(`fake data`) + + gock.New(testMGURL). + Post("/files/upload_by_url"). + Reply(400). + BodyString(`{"errors": ["error text"]}`) + + _, status, err := GetMGItemData(mgClient(), "https://example.com/item.jpg", "") + assert.Error(t, err) + assert.Equal(t, http.StatusBadRequest, status) + assert.Equal(t, "error text", err.Error()) +} + +func TestUtils_GetMGItemData_Success(t *testing.T) { + fileID := "file id" + size := 40 + uri := "file uri" + resp := v1.UploadFileResponse{ + ID: fileID, + Hash: "file hash", + Type: "image/jpeg", + Meta: v1.FileMeta{ + Width: &size, + Height: &size, + }, + MimeType: "image/jpeg", + Size: 250, + Url: &uri, + CreatedAt: time.Now(), + } + + data, _ := json.Marshal(resp) + + defer gock.Off() + + gock.New("https://example.com/"). + Get("/item.jpg"). + Reply(200). + BodyString(`fake data`) + + gock.New(testMGURL). + Post("/files/upload_by_url"). + Reply(200). + BodyString(string(data)) + + response, status, err := GetMGItemData(mgClient(), "https://example.com/item.jpg", "caption") + require.NoError(t, err) + assert.Equal(t, http.StatusOK, status) + assert.Equal(t, fileID, response.ID) + assert.Equal(t, "caption", response.Caption) +} + +func TestUtils_GetEntitySHA1(t *testing.T) { + entity := struct { + Field string + }{ + Field: "value", + } + + hash, err := GetEntitySHA1(entity) + require.NoError(t, err) + assert.Equal(t, "751b56fb98c9fd803140e8287b4236675554a668", hash) +} + +func TestUtils_ReplaceMarkdownSymbols(t *testing.T) { + test := "this *is* _test_ `string` [markdown" + expected := "this \\*is\\* \\_test\\_ \\`string\\` \\[markdown" + assert.Equal(t, expected, ReplaceMarkdownSymbols(test)) +} + +func TestUtils_Suite(t *testing.T) { + suite.Run(t, new(UtilsTest)) +} diff --git a/go.mod b/go.mod index c16d2bd..d92686d 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/retailcrm/mg-transport-core go 1.12 require ( + github.com/DATA-DOG/go-sqlmock v1.3.3 github.com/aws/aws-sdk-go v1.23.9 github.com/certifi/gocertifi v0.0.0-20190506164543-d2eda7129713 // indirect github.com/denisenkom/go-mssqldb v0.0.0-20190830225923-3302f0226fbd // indirect @@ -10,9 +11,11 @@ require ( github.com/gin-contrib/multitemplate v0.0.0-20180827023943-5799bbbb6dce github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-gonic/gin v1.3.0 + github.com/gobuffalo/packd v0.3.0 github.com/gobuffalo/packr/v2 v2.6.0 github.com/golang/protobuf v1.3.2 // indirect github.com/google/go-querystring v1.0.0 // indirect + github.com/h2non/gock v1.0.10 github.com/jinzhu/gorm v1.9.10 github.com/lib/pq v1.2.0 // indirect github.com/mattn/go-isatty v0.0.9 // indirect @@ -22,12 +25,12 @@ require ( github.com/pkg/errors v0.8.1 github.com/retailcrm/api-client-go v1.1.1 github.com/retailcrm/mg-transport-api-client-go v1.1.31 - github.com/stretchr/testify v1.4.0 // indirect + github.com/stretchr/testify v1.4.0 github.com/ugorji/go v1.1.7 // indirect golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 // indirect golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 golang.org/x/tools v0.0.0-20190830082254-f340ed3ae274 // indirect gopkg.in/go-playground/validator.v8 v8.18.2 - gopkg.in/gormigrate.v1 v1.6.0 // indirect + gopkg.in/gormigrate.v1 v1.6.0 gopkg.in/yaml.v2 v2.2.2 ) diff --git a/go.sum b/go.sum index abb9f4e..7c3e624 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7h github.com/BurntSushi/toml v0.3.0 h1:e1/Ivsx3Z0FVTV0NSOv/aVgbUWyQuzj7DDnFblkRvsY= github.com/BurntSushi/toml v0.3.0/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08= +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -50,9 +52,13 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU= github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/logger v1.0.0 h1:xw9Ko9EcC5iAFprrjJ6oZco9UpzS5MQ4jAwghsLHdy4= github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= +github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4= github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= +github.com/gobuffalo/packr/v2 v2.6.0 h1:EMUzJIb5rof6r087PtGmgdzdLKpRBESJ/8jyL9MexfY= github.com/gobuffalo/packr/v2 v2.6.0/go.mod h1:sgEE1xNZ6G0FNN5xn9pevVu4nywaxHvgup67xisti08= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -77,6 +83,8 @@ github.com/google/wire v0.3.0/go.mod h1:i1DMg/Lu8Sz5yYl25iOdmc5CT5qusaa+zmRWs167 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/h2non/gock v1.0.10 h1:EzHYzKKSLN4xk0w193uAy3tp8I3+L1jmaI2Mjg4lCgU= +github.com/h2non/gock v1.0.10/go.mod h1:CZMcB0Lg5IWnr9bF79pPMg9WeV6WumxQiUJ1UvdO1iE= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -95,9 +103,11 @@ github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M= github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/karrick/godirwalk v1.10.12 h1:BqUm+LuJcXjGv1d2mj3gBiQyrQ57a0rYoAmhvJQ7RDU= github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -150,9 +160,11 @@ github.com/retailcrm/api-client-go v1.1.1/go.mod h1:QRoPE2SM6ST7i2g0yEdqm7Iw98y7 github.com/retailcrm/mg-transport-api-client-go v1.1.31 h1:21pE1JhT49rvbMLDYJa0iiqbb/roz+eSp27fPck4uUw= github.com/retailcrm/mg-transport-api-client-go v1.1.31/go.mod h1:AWV6BueE28/6SCoyfKURTo4lF0oXYoOKmHTzehd5vAI= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -179,6 +191,7 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A= golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=