mirror of
https://github.com/retailcrm/mg-transport-core.git
synced 2024-11-25 14:46:02 +03:00
All retailCRM currencies support (#16)
* all currencies supported in retailCRM" * function which allows to pick currency symbol without interacting with map * tweak for new function test * check for undefined currency code * increase timeout for failing test * refactored test to WaitGroup, which resulted in finding and fixing actual data race in the job object
This commit is contained in:
parent
1de2e5626f
commit
ac9e7e768e
@ -8,7 +8,7 @@ go:
|
||||
before_install:
|
||||
- go mod tidy
|
||||
script:
|
||||
- go test ./... -v -cpu 2 -timeout 2m -race -cover -coverprofile=coverage.txt -covermode=atomic
|
||||
- go test ./... -v -cpu 2 -timeout 10s -race -cover -coverprofile=coverage.txt -covermode=atomic
|
||||
- go get -v -u github.com/axw/gocov/gocov
|
||||
- gocov convert ./coverage.txt | gocov report
|
||||
after_success:
|
||||
|
@ -27,6 +27,7 @@ type Job struct {
|
||||
ErrorHandler JobErrorHandler
|
||||
PanicHandler JobPanicHandler
|
||||
Interval time.Duration
|
||||
writeLock sync.RWMutex
|
||||
Regular bool
|
||||
active bool
|
||||
stopChannel chan bool
|
||||
@ -86,10 +87,18 @@ func (j *Job) getWrappedTimerFunc(name string, log JobLogFunc) func(chan bool) {
|
||||
|
||||
// run job
|
||||
func (j *Job) run(name string, log JobLogFunc) *Job {
|
||||
j.writeLock.RLock()
|
||||
|
||||
if j.Regular && j.Interval > 0 && !j.active {
|
||||
j.writeLock.RUnlock()
|
||||
defer j.writeLock.Unlock()
|
||||
j.writeLock.Lock()
|
||||
|
||||
j.stopChannel = make(chan bool)
|
||||
go j.getWrappedTimerFunc(name, log)(j.stopChannel)
|
||||
j.active = true
|
||||
} else {
|
||||
j.writeLock.RUnlock()
|
||||
}
|
||||
|
||||
return j
|
||||
@ -97,11 +106,18 @@ func (j *Job) run(name string, log JobLogFunc) *Job {
|
||||
|
||||
// stop running job
|
||||
func (j *Job) stop() *Job {
|
||||
j.writeLock.RLock()
|
||||
|
||||
if j.active && j.stopChannel != nil {
|
||||
j.writeLock.RUnlock()
|
||||
go func() {
|
||||
defer j.writeLock.Unlock()
|
||||
j.writeLock.Lock()
|
||||
j.stopChannel <- true
|
||||
j.active = false
|
||||
}()
|
||||
} else {
|
||||
j.writeLock.RUnlock()
|
||||
}
|
||||
|
||||
return j
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -28,7 +29,7 @@ type JobTest struct {
|
||||
type JobManagerTest struct {
|
||||
suite.Suite
|
||||
manager *JobManager
|
||||
runnerFlag chan bool
|
||||
runnerWG sync.WaitGroup
|
||||
syncRunnerFlag bool
|
||||
}
|
||||
|
||||
@ -308,15 +309,17 @@ func (t *JobManagerTest) SetupSuite() {
|
||||
t.manager = NewJobManager()
|
||||
}
|
||||
|
||||
func (t *JobManagerTest) ranFlag() bool {
|
||||
if t.runnerFlag == nil {
|
||||
return false
|
||||
}
|
||||
func (t *JobManagerTest) WaitForJob() bool {
|
||||
c := make(chan bool)
|
||||
go func() {
|
||||
t.runnerWG.Wait()
|
||||
c <- true
|
||||
}()
|
||||
|
||||
select {
|
||||
case c := <-t.runnerFlag:
|
||||
return c
|
||||
case <-time.After(time.Millisecond):
|
||||
case <-c:
|
||||
return true
|
||||
case <-time.After(time.Second):
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -349,7 +352,7 @@ func (t *JobManagerTest) Test_RegisterJob() {
|
||||
require.NotNil(t.T(), t.manager.jobs)
|
||||
err := t.manager.RegisterJob("job", &Job{
|
||||
Command: func(log JobLogFunc) error {
|
||||
t.runnerFlag <- true
|
||||
t.runnerWG.Done()
|
||||
return nil
|
||||
},
|
||||
ErrorHandler: DefaultJobErrorHandler(),
|
||||
@ -358,7 +361,7 @@ func (t *JobManagerTest) Test_RegisterJob() {
|
||||
assert.NoError(t.T(), err)
|
||||
err = t.manager.RegisterJob("job_regular", &Job{
|
||||
Command: func(log JobLogFunc) error {
|
||||
t.runnerFlag <- true
|
||||
t.runnerWG.Done()
|
||||
return nil
|
||||
},
|
||||
ErrorHandler: DefaultJobErrorHandler(),
|
||||
@ -431,15 +434,17 @@ func (t *JobManagerTest) Test_RunJobDoesntExist() {
|
||||
assert.EqualError(t.T(), err, "cannot find job `doesn't exist`")
|
||||
}
|
||||
|
||||
func (t *JobManagerTest) Test_RunJob() {
|
||||
func (t *JobManagerTest) Test_RunJob_RunJobOnce() {
|
||||
require.NotNil(t.T(), t.manager.jobs)
|
||||
t.runnerFlag = make(chan bool)
|
||||
err := t.manager.RunJob("job_regular")
|
||||
err := t.manager.StopJob("job_regular")
|
||||
require.NoError(t.T(), err)
|
||||
time.Sleep(time.Millisecond * 5)
|
||||
assert.True(t.T(), <-t.runnerFlag)
|
||||
t.runnerWG.Add(1)
|
||||
err = t.manager.RunJobOnce("job_regular")
|
||||
require.NoError(t.T(), err)
|
||||
time.Sleep(time.Millisecond)
|
||||
err = t.manager.StopJob("job_regular")
|
||||
require.NoError(t.T(), err)
|
||||
assert.True(t.T(), t.WaitForJob(), "Job was not executed in time")
|
||||
}
|
||||
|
||||
func (t *JobManagerTest) Test_RunJobOnceDoesntExist() {
|
||||
@ -448,15 +453,6 @@ func (t *JobManagerTest) Test_RunJobOnceDoesntExist() {
|
||||
assert.EqualError(t.T(), err, "cannot find job `doesn't exist`")
|
||||
}
|
||||
|
||||
func (t *JobManagerTest) Test_RunJobOnce() {
|
||||
require.NotNil(t.T(), t.manager.jobs)
|
||||
go func() { t.runnerFlag <- false }()
|
||||
err := t.manager.RunJobOnce("job")
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
require.NoError(t.T(), err)
|
||||
assert.True(t.T(), t.ranFlag())
|
||||
}
|
||||
|
||||
func (t *JobManagerTest) Test_RunJobOnceSyncDoesntExist() {
|
||||
require.NotNil(t.T(), t.manager.jobs)
|
||||
err := t.manager.RunJobOnceSync("doesn't exist")
|
||||
|
@ -21,6 +21,58 @@ import (
|
||||
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
|
||||
)
|
||||
|
||||
var defaultCurrencies = map[string]string{
|
||||
"rub": "₽",
|
||||
"uah": "₴",
|
||||
"byn": "Br",
|
||||
"kzt": "₸",
|
||||
"usd": "$",
|
||||
"eur": "€",
|
||||
"prb": "PRB",
|
||||
"mdl": "L",
|
||||
"kgs": "с",
|
||||
"pln": "zł",
|
||||
"azn": "₼",
|
||||
"amd": "֏",
|
||||
"thb": "฿",
|
||||
"aed": "AED",
|
||||
"nok": "kr",
|
||||
"cad": "C$",
|
||||
"czk": "Kč",
|
||||
"sek": "kr",
|
||||
"dkk": "kr",
|
||||
"ron": "lei",
|
||||
"uzs": "So'm",
|
||||
"aud": "$",
|
||||
"chf": "₣",
|
||||
"inr": "₹",
|
||||
"bgn": "лв",
|
||||
"ngn": "₦",
|
||||
"huf": "ƒ",
|
||||
"ils": "₪",
|
||||
"try": "₺",
|
||||
"stn": "₡",
|
||||
"ars": "$",
|
||||
"bob": "Bs",
|
||||
"ves": "Bs",
|
||||
"gtq": "Q",
|
||||
"hnl": "L",
|
||||
"dop": "RD$",
|
||||
"cop": "COL$",
|
||||
"crc": "₡",
|
||||
"cup": "$MN",
|
||||
"mxn": "NP$",
|
||||
"nio": "C$",
|
||||
"pab": "B/",
|
||||
"pyg": "₲",
|
||||
"pen": "S/",
|
||||
"svc": "₡",
|
||||
"uyu": "$U",
|
||||
"clp": "Ch$",
|
||||
"gel": "₾",
|
||||
"gbp": "£",
|
||||
}
|
||||
|
||||
// Utils service object
|
||||
type Utils struct {
|
||||
IsDebug bool
|
||||
@ -201,12 +253,15 @@ func ReplaceMarkdownSymbols(s string) string {
|
||||
|
||||
// DefaultCurrencies will return default currencies list for all bots
|
||||
func DefaultCurrencies() map[string]string {
|
||||
return map[string]string{
|
||||
"rub": "₽",
|
||||
"uah": "₴",
|
||||
"byr": "Br",
|
||||
"kzt": "₸",
|
||||
"usd": "$",
|
||||
"eur": "€",
|
||||
}
|
||||
return defaultCurrencies
|
||||
}
|
||||
|
||||
// GetCurrencySymbol returns currency symbol by it's ISO 4127 code.
|
||||
// It returns provided currency code in uppercase if currency symbol cannot be found
|
||||
func GetCurrencySymbol(code string) string {
|
||||
if i, ok := DefaultCurrencies()[strings.ToLower(code)]; ok {
|
||||
return i
|
||||
}
|
||||
|
||||
return strings.ToUpper(code)
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package core
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -241,6 +242,18 @@ func TestUtils_GetEntitySHA1(t *testing.T) {
|
||||
assert.Equal(t, "751b56fb98c9fd803140e8287b4236675554a668", hash)
|
||||
}
|
||||
|
||||
func TestUtils_GetCurrencySymbol(t *testing.T) {
|
||||
for code, _ := range DefaultCurrencies() {
|
||||
if strings.ToUpper(code) == defaultCurrencies[code] {
|
||||
continue
|
||||
}
|
||||
|
||||
assert.NotEqual(t, strings.ToUpper(code), GetCurrencySymbol(code))
|
||||
}
|
||||
|
||||
assert.Equal(t, "XAG", GetCurrencySymbol("xag"))
|
||||
}
|
||||
|
||||
func TestUtils_ReplaceMarkdownSymbols(t *testing.T) {
|
||||
test := "this *is* _test_ `string` [markdown"
|
||||
expected := "this \\*is\\* \\_test\\_ \\`string\\` \\[markdown"
|
||||
|
Loading…
Reference in New Issue
Block a user