func TestPaymentActions(t *testing.T) { test.LoadScenario("base") app := NewTestApp() defer app.Close() rh := NewRequestHelper(app) Convey("Payment Actions:", t, func() { Convey("GET /payments", func() { w := rh.Get("/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 4) }) Convey("GET /ledgers/:ledger_id/payments", func() { w := rh.Get("/ledgers/2/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 0) w = rh.Get("/ledgers/4/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 1) }) Convey("GET /accounts/:account_id/payments", func() { w := rh.Get("/accounts/gT9jHoPKoErFwXavCrDYLkSVcVd9oyVv94ydrq6FnPMXpKHPTA/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 1) test.LoadScenario("pathed_payment") w = rh.Get("/accounts/gsDu9aPmZy7uH5FzmfJKW7jWyXGHjSWbcb8k6UH743pYzaxWcWd/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 3) }) Convey("GET /transactions/:tx_id/payments", func() { test.LoadScenario("pathed_payment") w := rh.Get("/transactions/dffaa6b14246bb4cc3ab8ac414aec9cb93e86003cb22ff1297b3fe4623974d98/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 0) w = rh.Get("/transactions/ab38509dc9e16c08b084d7f7279fd45f5f4d348ab3b2ed9877c697beaa7e4108/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 1) }) }) }
func TestPaymentActions(t *testing.T) { test.LoadScenario("base") app := NewTestApp() defer app.Close() rh := NewRequestHelper(app) Convey("Payment Actions:", t, func() { Convey("GET /payments", func() { w := rh.Get("/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 4) }) Convey("GET /ledgers/:ledger_id/payments", func() { w := rh.Get("/ledgers/1/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 0) w = rh.Get("/ledgers/3/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 1) }) Convey("GET /accounts/:account_id/payments", func() { w := rh.Get("/accounts/GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 1) test.LoadScenario("pathed_payment") w = rh.Get("/accounts/GCQPYGH4K57XBDENKKX55KDTWOTK5WDWRQOH2LHEDX3EKVIQRLMESGBG/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 3) }) Convey("GET /transactions/:tx_id/payments", func() { test.LoadScenario("pathed_payment") w := rh.Get("/transactions/b90cc19c414426269ce9c245d7b079c34735a6d8a7afca594ce7cc362673269a/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 0) w = rh.Get("/transactions/c3399f16ed7edb2327fb8b44fe6af021eab1ab1f3d48bcca3ca4eb0fb4d47773/payments", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 1) }) }) }
func TestAccountActions(t *testing.T) { Convey("Account Actions:", t, func() { test.LoadScenario("base") app := NewTestApp() defer app.Close() rh := NewRequestHelper(app) Convey("GET /accounts/GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ", func() { w := rh.Get("/accounts/GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) var result AccountResource err := json.Unmarshal(w.Body.Bytes(), &result) So(err, ShouldBeNil) So(result.Sequence, ShouldEqual, 3) }) Convey("GET /accounts/100", func() { w := rh.Get("/accounts/100", test.RequestHelperNoop) So(w.Code, ShouldEqual, 404) }) Convey("GET /accounts", func() { w := rh.Get("/accounts", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 3) w = rh.Get("/accounts?limit=1", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 1) }) }) }
func TestHistoryAccountByAddressQuery(t *testing.T) { test.LoadScenario("base") Convey("AccountByAddress", t, func() { var account HistoryAccountRecord Convey("Existing record behavior", func() { address := "GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ" q := HistoryAccountByAddressQuery{ SqlQuery{history}, address, } err := Get(ctx, q, &account) So(err, ShouldBeNil) So(account.Id, ShouldEqual, 0) So(account.Address, ShouldEqual, address) }) Convey("Missing record behavior", func() { address := "not real" q := HistoryAccountByAddressQuery{ SqlQuery{history}, address, } err := Get(ctx, q, &account) So(err, ShouldEqual, ErrNoResults) }) }) }
func TestOperationByIdQuery(t *testing.T) { test.LoadScenario("base") Convey("OperationByIdQuery", t, func() { var op OperationRecord Convey("Existing record behavior", func() { id := int64(8589938688) q := OperationByIdQuery{ SqlQuery{history}, id, } err := Get(ctx, q, &op) So(err, ShouldBeNil) So(op.Id, ShouldEqual, id) So(op.TransactionId, ShouldEqual, id) }) Convey("Missing record behavior", func() { id := int64(0) q := OperationByIdQuery{ SqlQuery{history}, id, } err := Get(ctx, q, &op) So(err, ShouldEqual, ErrNoResults) }) }) }
func TestLedgerPageQuery(t *testing.T) { test.LoadScenario("base") var records []LedgerRecord Convey("LedgerPageQuery", t, func() { pq, err := NewPageQuery("", "asc", 2) So(err, ShouldBeNil) q := LedgerPageQuery{SqlQuery{history}, pq} err = Select(ctx, q, &records) So(err, ShouldBeNil) So(len(records), ShouldEqual, 2) So(records, ShouldBeOrderedAscending, func(r interface{}) int64 { return r.(LedgerRecord).Id }) lastLedger := records[len(records)-1] q.Cursor = lastLedger.PagingToken() err = Select(ctx, q, &records) So(err, ShouldBeNil) t.Log(records) So(len(records), ShouldEqual, 1) }) }
func TestAccountByAddressQuery(t *testing.T) { test.LoadScenario("non_native_payment") Convey("AccountByAddress", t, func() { var account AccountRecord notreal := "not_real" withtl := "GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON" notl := "GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ" q := AccountByAddressQuery{ Core: SqlQuery{core}, History: SqlQuery{history}, Address: withtl, } err := Get(ctx, q, &account) So(err, ShouldBeNil) So(account.Address, ShouldEqual, withtl) So(account.Seqnum, ShouldEqual, 8589934593) So(len(account.Trustlines), ShouldEqual, 1) q.Address = notl err = Get(ctx, q, &account) So(err, ShouldBeNil) So(len(account.Trustlines), ShouldEqual, 0) q.Address = notreal err = Get(ctx, q, &account) So(err, ShouldEqual, ErrNoResults) }) }
func TestLedgerBySequenceQuery(t *testing.T) { Convey("LedgerBySequenceQuery", t, func() { test.LoadScenario("base") var record LedgerRecord Convey("Existing record behavior", func() { sequence := int32(2) q := LedgerBySequenceQuery{ SqlQuery{history}, sequence, } err := Get(ctx, q, &record) So(err, ShouldBeNil) So(record.Sequence, ShouldEqual, sequence) }) Convey("Missing record behavior", func() { sequence := int32(-1) query := LedgerBySequenceQuery{ SqlQuery{history}, sequence, } err := Get(ctx, query, &record) So(err, ShouldEqual, ErrNoResults) }) }) }
func TestLedgerActions(t *testing.T) { test.LoadScenario("base") app := NewTestApp() defer app.Close() rh := NewRequestHelper(app) Convey("Ledger Actions:", t, func() { Convey("GET /ledgers/1", func() { w := rh.Get("/ledgers/1", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) var result LedgerResource err := json.Unmarshal(w.Body.Bytes(), &result) So(err, ShouldBeNil) So(result.Sequence, ShouldEqual, 1) }) Convey("GET /ledgers/100", func() { w := rh.Get("/ledgers/100", test.RequestHelperNoop) So(w.Code, ShouldEqual, 404) }) Convey("GET /ledgers", func() { Convey("With Default Params", func() { w := rh.Get("/ledgers", test.RequestHelperNoop) var result map[string]interface{} err := json.Unmarshal(w.Body.Bytes(), &result) So(err, ShouldBeNil) So(w.Code, ShouldEqual, 200) embedded := result["_embedded"].(map[string]interface{}) records := embedded["records"].([]interface{}) So(len(records), ShouldEqual, 4) }) Convey("With A Limit", func() { w := rh.Get("/ledgers?limit=1", test.RequestHelperNoop) var result map[string]interface{} err := json.Unmarshal(w.Body.Bytes(), &result) So(err, ShouldBeNil) So(w.Code, ShouldEqual, 200) embedded := result["_embedded"].(map[string]interface{}) records := embedded["records"].([]interface{}) So(len(records), ShouldEqual, 1) }) }) }) }
func TestCoreAccountByAddressQuery(t *testing.T) { test.LoadScenario("base") Convey("CoreAccountByAddress", t, func() { var account CoreAccountRecord Convey("Existing record behavior", func() { address := "gspbxqXqEUZkiCCEFFCN9Vu4FLucdjLLdLcsV6E82Qc1T7ehsTC" q := CoreAccountByAddressQuery{ SqlQuery{core}, address, } err := Get(ctx, q, &account) So(err, ShouldBeNil) So(account.Accountid, ShouldEqual, address) So(account.Balance, ShouldEqual, 99999996999999970) }) Convey("Missing record behavior", func() { address := "not real" q := CoreAccountByAddressQuery{ SqlQuery{core}, address, } err := Get(ctx, q, &account) So(err, ShouldEqual, ErrNoResults) }) }) }
func TestTransactionActions(t *testing.T) { Convey("Transactions Actions:", t, func() { test.LoadScenario("base") app := NewTestApp() defer app.Close() rh := NewRequestHelper(app) Convey("GET /transactions/99fd775e6eed3e331c7df84b540d955db4ece9f57d22980715918acb7ce5bbf4", func() { w := rh.Get("/transactions/99fd775e6eed3e331c7df84b540d955db4ece9f57d22980715918acb7ce5bbf4", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) var result TransactionResource err := json.Unmarshal(w.Body.Bytes(), &result) So(err, ShouldBeNil) So(result.Hash, ShouldEqual, "99fd775e6eed3e331c7df84b540d955db4ece9f57d22980715918acb7ce5bbf4") }) Convey("GET /transactions/not_real", func() { w := rh.Get("/transactions/not_real", test.RequestHelperNoop) So(w.Code, ShouldEqual, 404) }) Convey("GET /transactions", func() { w := rh.Get("/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 4) }) Convey("GET /ledgers/:ledger_id/transactions", func() { w := rh.Get("/ledgers/1/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 0) w = rh.Get("/ledgers/2/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 3) w = rh.Get("/ledgers/3/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 1) }) Convey("GET /accounts/:account_od/transactions", func() { w := rh.Get("/accounts/GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 3) w = rh.Get("/accounts/GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 1) w = rh.Get("/accounts/GCXKG6RN4ONIEPCMNFB732A436Z5PNDSRLGWK7GBLCMQLIFO4S7EYWVU/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 2) }) }) }
func TestTransactionActions(t *testing.T) { Convey("Transactions Actions:", t, func() { test.LoadScenario("base") app := NewTestApp() defer app.Close() rh := NewRequestHelper(app) Convey("GET /transactions/da3dae3d6baef2f56d53ff9fa4ddbc6cbda1ac798f0faa7de8edac9597c1dc0c", func() { w := rh.Get("/transactions/da3dae3d6baef2f56d53ff9fa4ddbc6cbda1ac798f0faa7de8edac9597c1dc0c", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) var result TransactionResource err := json.Unmarshal(w.Body.Bytes(), &result) So(err, ShouldBeNil) So(result.Hash, ShouldEqual, "da3dae3d6baef2f56d53ff9fa4ddbc6cbda1ac798f0faa7de8edac9597c1dc0c") }) Convey("GET /transactions/not_real", func() { w := rh.Get("/transactions/not_real", test.RequestHelperNoop) So(w.Code, ShouldEqual, 404) }) Convey("GET /transactions", func() { w := rh.Get("/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 4) }) Convey("GET /ledgers/:ledger_id/transactions", func() { w := rh.Get("/ledgers/2/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 0) w = rh.Get("/ledgers/3/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 3) w = rh.Get("/ledgers/4/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 1) }) Convey("GET /accounts/:account_od/transactions", func() { w := rh.Get("/accounts/gspbxqXqEUZkiCCEFFCN9Vu4FLucdjLLdLcsV6E82Qc1T7ehsTC/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 3) w = rh.Get("/accounts/gT9jHoPKoErFwXavCrDYLkSVcVd9oyVv94ydrq6FnPMXpKHPTA/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 1) w = rh.Get("/accounts/gsKuurNYgtBhTSFfsCaWqNb3Ze5Je9csKTSLfjo8Ko2b1f66ayZ/transactions", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 2) }) }) }
func TestRootAction(t *testing.T) { Convey("GET /", t, func() { test.LoadScenario("base") app := NewTestApp() defer app.Close() rh := NewRequestHelper(app) w := rh.Get("/", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) }) }
func TestLedgerState(t *testing.T) { test.LoadScenario("base") horizon := OpenTestDatabase() defer horizon.Close() core := OpenStellarCoreTestDatabase() defer core.Close() Convey("db.UpdateLedgerState", t, func() { So(horizonLedgerGauge.Value(), ShouldEqual, 0) So(stellarCoreLedgerGauge.Value(), ShouldEqual, 0) UpdateLedgerState(test.Context(), SqlQuery{horizon}, SqlQuery{core}) So(horizonLedgerGauge.Value(), ShouldEqual, 4) So(stellarCoreLedgerGauge.Value(), ShouldEqual, 4) }) }
func TestOfferActions(t *testing.T) { test.LoadScenario("trades") app := NewTestApp() defer app.Close() rh := NewRequestHelper(app) Convey("Offer Actions:", t, func() { Convey("GET /accounts/GAJFK65MU3WQW4PZYJXBS7LXLXHHZB2RNVX7EC6DUZYU2NE4VMANPX2W/offers", func() { w := rh.Get("/accounts/GAJFK65MU3WQW4PZYJXBS7LXLXHHZB2RNVX7EC6DUZYU2NE4VMANPX2W/offers", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.Body, ShouldBePageOf, 3) }) }) }
func TestLedgerStateQuery(t *testing.T) { test.LoadScenario("base") Convey("LedgerStateQuery", t, func() { var ls LedgerState q := LedgerStateQuery{ SqlQuery{history}, SqlQuery{core}, } err := Get(ctx, q, &ls) So(err, ShouldBeNil) So(ls.HorizonSequence, ShouldEqual, 4) So(ls.StellarCoreSequence, ShouldEqual, 4) }) }
func TestTransactionByHashQuery(t *testing.T) { Convey("TransactionByHashQuery", t, func() { test.LoadScenario("base") var record TransactionRecord Convey("Existing record behavior", func() { hash := "99fd775e6eed3e331c7df84b540d955db4ece9f57d22980715918acb7ce5bbf4" q := TransactionByHashQuery{SqlQuery{history}, hash} err := Get(ctx, q, &record) So(err, ShouldBeNil) So(record.TransactionHash, ShouldEqual, hash) }) Convey("Missing record behavior", func() { hash := "not_real" q := TransactionByHashQuery{SqlQuery{history}, hash} err := Get(ctx, q, &record) So(err, ShouldEqual, ErrNoResults) }) }) }
func TestTransactionByHashQuery(t *testing.T) { Convey("TransactionByHashQuery", t, func() { test.LoadScenario("base") var record TransactionRecord Convey("Existing record behavior", func() { hash := "da3dae3d6baef2f56d53ff9fa4ddbc6cbda1ac798f0faa7de8edac9597c1dc0c" q := TransactionByHashQuery{SqlQuery{history}, hash} err := Get(ctx, q, &record) So(err, ShouldBeNil) So(record.TransactionHash, ShouldEqual, hash) }) Convey("Missing record behavior", func() { hash := "not_real" q := TransactionByHashQuery{SqlQuery{history}, hash} err := Get(ctx, q, &record) So(err, ShouldEqual, ErrNoResults) }) }) }
func TestCoreTrustlinesByAddressQuery(t *testing.T) { test.LoadScenario("non_native_payment") Convey("CoreTrustlinesByAddress", t, func() { var tls []CoreTrustlineRecord withtl := "GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON" notl := "GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ" q := CoreTrustlinesByAddressQuery{ SqlQuery{core}, withtl, } err := Select(ctx, q, &tls) So(err, ShouldBeNil) So(len(tls), ShouldEqual, 1) tl := tls[0] So(tl.Accountid, ShouldEqual, withtl) So(tl.Issuer, ShouldEqual, "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO4") So(tl.Balance, ShouldEqual, 500000000) So(tl.Tlimit, ShouldEqual, 9223372036854775807) So(tl.Assetcode, ShouldEqual, "USD") q = CoreTrustlinesByAddressQuery{ SqlQuery{core}, notl, } err = Select(ctx, q, &tls) So(err, ShouldBeNil) t.Log(tls) So(len(tls), ShouldEqual, 0) }) }
func TestCoreTrustlinesByAddressQuery(t *testing.T) { test.LoadScenario("non_native_payment") Convey("CoreTrustlinesByAddress", t, func() { var tls []CoreTrustlineRecord withtl := "gqdUHrgHUp8uMb74HiQvYztze2ffLhVXpPwj7gEZiJRa4jhCXQ" notl := "gspbxqXqEUZkiCCEFFCN9Vu4FLucdjLLdLcsV6E82Qc1T7ehsTC" q := CoreTrustlinesByAddressQuery{ SqlQuery{core}, withtl, } err := Select(ctx, q, &tls) So(err, ShouldBeNil) So(len(tls), ShouldEqual, 1) tl := tls[0] So(tl.Accountid, ShouldEqual, withtl) So(tl.Issuer, ShouldEqual, "gsPsm67nNK8HtwMedJZFki3jAEKgg1s4nRKrHREFqTzT6ErzBiq") So(tl.Balance, ShouldEqual, 500000000) So(tl.Tlimit, ShouldEqual, 9223372036854775807) So(tl.Alphanumcurrency, ShouldEqual, "USD") q = CoreTrustlinesByAddressQuery{ SqlQuery{core}, notl, } err = Select(ctx, q, &tls) So(err, ShouldBeNil) t.Log(tls) So(len(tls), ShouldEqual, 0) }) }
func TestApp(t *testing.T) { Convey("NewApp establishes the app in its context", t, func() { app, err := NewApp(NewTestConfig()) So(err, ShouldBeNil) defer app.Close() found, ok := AppFromContext(app.ctx) So(ok, ShouldBeTrue) So(found, ShouldEqual, app) }) Convey("NewApp panics if the provided config's SentryDSN is invalid", t, func() { config := NewTestConfig() config.SentryDSN = "Not a url" So(func() { app, _ := NewApp(config) app.Close() }, ShouldPanic) }) Convey("NewApp adds a sentry hook when the provided config's SentryDSN is valid", t, func() { config := NewTestConfig() config.SentryDSN = "https://*****:*****@app.getsentry.com/44303" app, _ := NewApp(config) defer app.Close() // we have to use reflection to see if the hook is added :( r := reflect.ValueOf(app.log.Logger.Hooks) So(r.Kind(), ShouldEqual, reflect.Map) expectations := []struct { Level logrus.Level Assertion func(actual interface{}, options ...interface{}) string }{ {logrus.DebugLevel, shouldNotHaveASentryHook}, {logrus.InfoLevel, shouldNotHaveASentryHook}, {logrus.WarnLevel, shouldNotHaveASentryHook}, {logrus.ErrorLevel, shouldHaveASentryHook}, {logrus.PanicLevel, shouldHaveASentryHook}, {logrus.FatalLevel, shouldHaveASentryHook}, } for _, expectation := range expectations { hooks := r.MapIndex(reflect.ValueOf(expectation.Level)).Interface() So(hooks, expectation.Assertion) } }) Convey("NewApp does not add a sentry hook if config's SentryDSN is empty", t, func() { config := NewTestConfig() config.SentryDSN = "" app, _ := NewApp(config) defer app.Close() // we have to use reflection to see if the hook is added :( r := reflect.ValueOf(app.log.Logger.Hooks) So(r.Kind(), ShouldEqual, reflect.Map) expectations := []struct { Level logrus.Level Assertion func(actual interface{}, options ...interface{}) string }{ {logrus.DebugLevel, shouldNotHaveASentryHook}, {logrus.InfoLevel, shouldNotHaveASentryHook}, {logrus.WarnLevel, shouldNotHaveASentryHook}, {logrus.ErrorLevel, shouldNotHaveASentryHook}, {logrus.PanicLevel, shouldNotHaveASentryHook}, {logrus.FatalLevel, shouldNotHaveASentryHook}, } for _, expectation := range expectations { hooksv := r.MapIndex(reflect.ValueOf(expectation.Level)) var hooks []logrus.Hook if hooksv.IsValid() { hooks = hooksv.Interface().([]logrus.Hook) } else { hooks = nil } So(hooks, expectation.Assertion) } }) Convey("CORS support", t, func() { app := NewTestApp() defer app.Close() rh := NewRequestHelper(app) w := rh.Get("/", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) So(w.HeaderMap.Get("Access-Control-Allow-Origin"), ShouldEqual, "") w = rh.Get("/", func(r *http.Request) { r.Header.Set("Origin", "somewhere.com") }) So(w.Code, ShouldEqual, 200) So(w.HeaderMap.Get("Access-Control-Allow-Origin"), ShouldEqual, "somewhere.com") }) Convey("Trailing slash causes redirect", t, func() { test.LoadScenario("base") app := NewTestApp() defer app.Close() rh := NewRequestHelper(app) w := rh.Get("/accounts", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) w = rh.Get("/accounts/", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) }) }
func TestTransactionPageQuery(t *testing.T) { test.LoadScenario("base") Convey("TransactionPageQuery", t, func() { var records []TransactionRecord makeQuery := func(c string, o string, l int32) TransactionPageQuery { pq, err := NewPageQuery(c, o, l) So(err, ShouldBeNil) return TransactionPageQuery{ SqlQuery: SqlQuery{history}, PageQuery: pq, } } Convey("orders properly", func() { // asc orders ascending by id MustSelect(ctx, makeQuery("", "asc", 0), &records) So(records, ShouldBeOrderedAscending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, TransactionRecord{}) return r.(TransactionRecord).Id }) // desc orders descending by id MustSelect(ctx, makeQuery("", "desc", 0), &records) So(records, ShouldBeOrderedDescending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, TransactionRecord{}) return r.(TransactionRecord).Id }) }) Convey("limits properly", func() { // returns number specified MustSelect(ctx, makeQuery("", "asc", 3), &records) So(len(records), ShouldEqual, 3) // returns all rows if limit is higher MustSelect(ctx, makeQuery("", "asc", 10), &records) So(len(records), ShouldEqual, 4) }) Convey("cursor works properly", func() { var record TransactionRecord // lowest id if ordered ascending and no cursor MustGet(ctx, makeQuery("", "asc", 0), &record) So(record.Id, ShouldEqual, 8589938688) // highest id if ordered descending and no cursor MustGet(ctx, makeQuery("", "desc", 0), &record) So(record.Id, ShouldEqual, 12884905984) // starts after the cursor if ordered ascending MustGet(ctx, makeQuery("8589938688", "asc", 0), &record) So(record.Id, ShouldEqual, 8589942784) // starts before the cursor if ordered descending MustGet(ctx, makeQuery("12884905984", "desc", 0), &record) So(record.Id, ShouldEqual, 8589946880) }) Convey("restricts to address properly", func() { address := "GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ" q := makeQuery("", "asc", 0) q.AccountAddress = address MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 3) for _, r := range records { So(r.Account, ShouldEqual, address) } }) Convey("restricts to ledger properly", func() { q := makeQuery("", "asc", 0) q.LedgerSequence = 3 MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 1) for _, r := range records { So(r.LedgerSequence, ShouldEqual, q.LedgerSequence) } }) }) }
func TestTransactionPageQuery(t *testing.T) { test.LoadScenario("base") Convey("TransactionPageQuery", t, func() { var records []TransactionRecord makeQuery := func(c string, o string, l int32) TransactionPageQuery { pq, err := NewPageQuery(c, o, l) So(err, ShouldBeNil) return TransactionPageQuery{ SqlQuery: SqlQuery{history}, PageQuery: pq, } } Convey("orders properly", func() { // asc orders ascending by id MustSelect(ctx, makeQuery("", "asc", 0), &records) So(records, ShouldBeOrderedAscending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, TransactionRecord{}) return r.(TransactionRecord).Id }) // desc orders descending by id MustSelect(ctx, makeQuery("", "desc", 0), &records) So(records, ShouldBeOrderedDescending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, TransactionRecord{}) return r.(TransactionRecord).Id }) }) Convey("limits properly", func() { // returns number specified MustSelect(ctx, makeQuery("", "asc", 3), &records) So(len(records), ShouldEqual, 3) // returns all rows if limit is higher MustSelect(ctx, makeQuery("", "asc", 10), &records) So(len(records), ShouldEqual, 4) }) Convey("cursor works properly", func() { var record TransactionRecord // lowest id if ordered ascending and no cursor MustGet(ctx, makeQuery("", "asc", 0), &record) So(record.Id, ShouldEqual, 12884905984) // highest id if ordered descending and no cursor MustGet(ctx, makeQuery("", "desc", 0), &record) So(record.Id, ShouldEqual, 17179873280) // starts after the cursor if ordered ascending MustGet(ctx, makeQuery("12884905984", "asc", 0), &record) So(record.Id, ShouldEqual, 12884910080) // starts before the cursor if ordered descending MustGet(ctx, makeQuery("17179873280", "desc", 0), &record) So(record.Id, ShouldEqual, 12884914176) }) Convey("restricts to address properly", func() { address := "gspbxqXqEUZkiCCEFFCN9Vu4FLucdjLLdLcsV6E82Qc1T7ehsTC" q := makeQuery("", "asc", 0) q.AccountAddress = address MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 3) for _, r := range records { So(r.Account, ShouldEqual, address) } }) Convey("restricts to ledger properly", func() { q := makeQuery("", "asc", 0) q.LedgerSequence = 4 MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 1) for _, r := range records { So(r.LedgerSequence, ShouldEqual, q.LedgerSequence) } }) }) }
func TestOperationPageQuery(t *testing.T) { test.LoadScenario("base") Convey("OperationPageQuery", t, func() { var records []OperationRecord makeQuery := func(c string, o string, l int32) OperationPageQuery { pq, err := NewPageQuery(c, o, l) So(err, ShouldBeNil) return OperationPageQuery{ SqlQuery: SqlQuery{history}, PageQuery: pq, } } Convey("orders properly", func() { // asc orders ascending by id MustSelect(ctx, makeQuery("", "asc", 0), &records) So(records, ShouldBeOrderedAscending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, OperationRecord{}) return r.(OperationRecord).Id }) // desc orders descending by id MustSelect(ctx, makeQuery("", "desc", 0), &records) So(records, ShouldBeOrderedDescending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, OperationRecord{}) return r.(OperationRecord).Id }) }) Convey("limits properly", func() { // returns number specified MustSelect(ctx, makeQuery("", "asc", 3), &records) So(len(records), ShouldEqual, 3) // returns all rows if limit is higher MustSelect(ctx, makeQuery("", "asc", 10), &records) So(len(records), ShouldEqual, 4) }) Convey("cursor works properly", func() { var record OperationRecord // lowest id if ordered ascending and no cursor MustGet(ctx, makeQuery("", "asc", 0), &record) So(record.Id, ShouldEqual, 12884905984) // highest id if ordered descending and no cursor MustGet(ctx, makeQuery("", "desc", 0), &record) So(record.Id, ShouldEqual, 17179873280) // starts after the cursor if ordered ascending MustGet(ctx, makeQuery("12884905984", "asc", 0), &record) So(record.Id, ShouldEqual, 12884910080) // starts before the cursor if ordered descending MustGet(ctx, makeQuery("17179873280", "desc", 0), &record) So(record.Id, ShouldEqual, 12884914176) }) Convey("restricts to address properly", func() { address := "gqdUHrgHUp8uMb74HiQvYztze2ffLhVXpPwj7gEZiJRa4jhCXQ" q := makeQuery("", "asc", 0) q.AccountAddress = address MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 2) So(records[0].Id, ShouldEqual, 12884914176) So(records[1].Id, ShouldEqual, 17179873280) }) Convey("restricts to ledger properly", func() { q := makeQuery("", "asc", 0) q.LedgerSequence = 3 MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 3) for _, r := range records { toid := ParseTotalOrderId(r.TransactionId) So(toid.LedgerSequence, ShouldEqual, 3) } }) Convey("restricts to transaction properly", func() { q := makeQuery("", "asc", 0) q.TransactionHash = "da3dae3d6baef2f56d53ff9fa4ddbc6cbda1ac798f0faa7de8edac9597c1dc0c" MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 1) for _, r := range records { So(r.TransactionId, ShouldEqual, 12884905984) } }) Convey("errors if more than one filter is supplied", func() { table := []struct { Hash string Ledger int32 Address string }{ {"1", 1, "1"}, {"", 1, "1"}, {"1", 1, ""}, {"1", 0, "1"}, } for _, o := range table { q := makeQuery("", "asc", 0) q.TransactionHash = o.Hash q.LedgerSequence = o.Ledger q.AccountAddress = o.Address err := Select(ctx, q, &records) So(err, ShouldNotBeNil) } }) Convey("obeys the type filter", func() { test.LoadScenario("pathed_payment") q := makeQuery("", "asc", 0) q.TypeFilter = PaymentTypeFilter MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 10) }) }) }
func TestHistoryPageQuery(t *testing.T) { test.LoadScenario("base") Convey("HistoryAccountPageQuery", t, func() { var records []HistoryAccountRecord makeQuery := func(c string, o string, l int32) HistoryAccountPageQuery { pq, err := NewPageQuery(c, o, l) So(err, ShouldBeNil) return HistoryAccountPageQuery{ SqlQuery: SqlQuery{history}, PageQuery: pq, } } Convey("orders properly", func() { // asc orders ascending by id MustSelect(ctx, makeQuery("", "asc", 0), &records) So(records, ShouldBeOrderedAscending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, HistoryAccountRecord{}) return r.(HistoryAccountRecord).Id }) // desc orders descending by id MustSelect(ctx, makeQuery("", "desc", 0), &records) So(records, ShouldBeOrderedDescending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, HistoryAccountRecord{}) return r.(HistoryAccountRecord).Id }) }) Convey("limits properly", func() { // returns number specified MustSelect(ctx, makeQuery("", "asc", 2), &records) So(len(records), ShouldEqual, 2) // returns all rows if limit is higher MustSelect(ctx, makeQuery("", "asc", 10), &records) So(len(records), ShouldEqual, 3) }) Convey("cursor works properly", func() { var record HistoryAccountRecord // lowest id if ordered ascending and no cursor MustGet(ctx, makeQuery("", "asc", 0), &record) So(record.Id, ShouldEqual, 8589938688) // highest id if ordered descending and no cursor MustGet(ctx, makeQuery("", "desc", 0), &record) So(record.Id, ShouldEqual, 8589946880) // starts after the cursor if ordered ascending MustGet(ctx, makeQuery("8589938688", "asc", 0), &record) So(record.Id, ShouldEqual, 8589942784) // starts before the cursor if ordered descending MustGet(ctx, makeQuery("8589946880", "desc", 0), &record) So(record.Id, ShouldEqual, 8589942784) }) }) }
func TestDBPackage(t *testing.T) { test.LoadScenario("non_native_payment") Convey("db.Select", t, func() { Convey("overwrites the destination", func() { records := []mockResult{{1}, {2}} query := &mockQuery{5} err := Select(ctx, query, &records) So(err, ShouldBeNil) So(len(records), ShouldEqual, 5) }) Convey("works on []interface{} destinations", func() { var records []mockResult query := &mockQuery{5} err := Select(ctx, query, &records) So(err, ShouldBeNil) So(len(records), ShouldEqual, 5) }) Convey("returns an error when the provided destination is nil", func() { query := &mockQuery{5} err := Select(ctx, query, nil) So(err, ShouldEqual, ErrDestinationNil) }) Convey("returns an error when the provided destination is not a pointer", func() { var records []mockResult query := &mockQuery{5} err := Select(ctx, query, records) So(err, ShouldEqual, ErrDestinationNotPointer) }) Convey("returns an error when the provided destination is not a slice", func() { var records string query := &mockQuery{5} err := Select(ctx, query, &records) So(err, ShouldEqual, ErrDestinationNotSlice) }) Convey("returns an error when the provided destination is a slice of an invalid type", func() { var records []string query := &mockQuery{5} err := Select(ctx, query, &records) So(err, ShouldEqual, ErrDestinationIncompatible) }) }) Convey("db.Get", t, func() { var result mockResult Convey("returns the first record", func() { So(Get(ctx, &mockQuery{2}, &result), ShouldBeNil) So(result, ShouldResemble, mockResult{0}) }) Convey("Missing records returns nil", func() { So(Get(ctx, &mockQuery{0}, &result), ShouldEqual, ErrNoResults) }) Convey("Properly forwards non-RecordNotFound errors", func() { query := &BrokenQuery{errors.New("Some error")} So(Get(ctx, query, &result).Error(), ShouldEqual, "Some error") }) }) }
func TestOrderBookActions(t *testing.T) { test.LoadScenario("order_books") app := NewTestApp() defer app.Close() rh := NewRequestHelper(app) Convey("Order Book Actions:", t, func() { Convey("(no query args): GET /order_book", func() { w := rh.Get("/order_book", test.RequestHelperNoop) So(w.Code, ShouldEqual, 400) So(w.Body, ShouldBeProblem, problem.P{Type: "invalid_order_book"}) }) Convey("(missing currency): GET /order_book?selling_type=native", func() { w := rh.Get("/order_book?selling_type=native", test.RequestHelperNoop) So(w.Code, ShouldEqual, 400) So(w.Body, ShouldBeProblem, problem.P{Type: "invalid_order_book"}) }) Convey("(invalid type): GET /order_book?selling_type=native&buying_type=nothing", func() { w := rh.Get("/order_book?selling_type=native&buying_type=nothing", test.RequestHelperNoop) So(w.Code, ShouldEqual, 400) So(w.Body, ShouldBeProblem, problem.P{Type: "invalid_order_book"}) w = rh.Get("/order_book?selling_type=nothing&buying_type=native", test.RequestHelperNoop) So(w.Code, ShouldEqual, 400) So(w.Body, ShouldBeProblem, problem.P{Type: "invalid_order_book"}) }) Convey("(missing code): GET /order_book?selling_type=native&buying_type=credit_alphanum4&buying_issuer=123", func() { w := rh.Get("/order_book?selling_type=native&buying_type=credit_alphanum4&buying_issuer=123", test.RequestHelperNoop) So(w.Code, ShouldEqual, 400) So(w.Body, ShouldBeProblem, problem.P{Type: "invalid_order_book"}) w = rh.Get("/order_book?buying_type=native&selling_type=credit_alphanum4&selling_issuer=123", test.RequestHelperNoop) So(w.Code, ShouldEqual, 400) So(w.Body, ShouldBeProblem, problem.P{Type: "invalid_order_book"}) }) Convey("(missing issuer): GET /order_book?selling_type=native&buying_type=credit_alphanum4&buying_code=USD", func() { w := rh.Get("/order_book?selling_type=native&buying_type=credit_alphanum4&buying_code=USD", test.RequestHelperNoop) So(w.Code, ShouldEqual, 400) So(w.Body, ShouldBeProblem, problem.P{Type: "invalid_order_book"}) w = rh.Get("/order_book?buying_type=native&selling_type=credit_alphanum4&selling_code=USD", test.RequestHelperNoop) So(w.Code, ShouldEqual, 400) So(w.Body, ShouldBeProblem, problem.P{Type: "invalid_order_book"}) }) Convey("(same currency): GET /order_book?selling_type=native&buying_type=native", func() { w := rh.Get("/order_book?selling_type=native&buying_type=native", test.RequestHelperNoop) So(w.Code, ShouldEqual, 200) var result map[string]interface{} err := json.Unmarshal(w.Body.Bytes(), &result) So(err, ShouldBeNil) // ensure bids and asks are empty prices := result["asks"].([]interface{}) So(len(prices), ShouldEqual, 0) prices = result["bids"].([]interface{}) So(len(prices), ShouldEqual, 0) }) Convey("(incomplete currency): GET /order_book?selling_type=native&buying_type=credit_alphanum4&buying_code=USD", func() { w := rh.Get("/order_book?selling_type=native&buying_type=credit_alphanum4&buying_code=USD", test.RequestHelperNoop) So(w.Code, ShouldEqual, 400) So(w.Body, ShouldBeProblem, problem.P{Type: "invalid_order_book"}) }) Convey("(happy path): GET /order_book?selling_type=native&buying_type=credit_alphanum4&buying_code=USD&buying_issuer=GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO4", func() { w := rh.Get("/order_book?selling_type=native&buying_type=credit_alphanum4&buying_code=USD&buying_issuer=GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO4", test.RequestHelperNoop) t.Log(w.Body.String()) So(w.Code, ShouldEqual, 200) var result OrderBookSummaryResource err := json.Unmarshal(w.Body.Bytes(), &result) So(err, ShouldBeNil) So(result.Selling.AssetType, ShouldEqual, "native") So(result.Selling.AssetCode, ShouldEqual, "") So(result.Selling.AssetIssuer, ShouldEqual, "") So(result.Buying.AssetType, ShouldEqual, "credit_alphanum4") So(result.Buying.AssetCode, ShouldEqual, "USD") So(result.Buying.AssetIssuer, ShouldEqual, "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO4") So(len(result.Asks), ShouldEqual, 3) So(len(result.Bids), ShouldEqual, 3) }) }) }
func TestCoreOfferPageByAddressQuery(t *testing.T) { test.LoadScenario("trades") Convey("CoreOfferPageByAddressQuery", t, func() { makeQuery := func(c string, o string, l int32, a string) CoreOfferPageByAddressQuery { pq, err := NewPageQuery(c, o, l) So(err, ShouldBeNil) return CoreOfferPageByAddressQuery{ SqlQuery: SqlQuery{core}, PageQuery: pq, Address: a, } } var records []CoreOfferRecord Convey("works with native offers", func() { MustSelect(ctx, makeQuery("", "asc", 0, "GA4WKBJM5IA2IPHLGJUI5LQHVAYRPMF7UEU57LFELTFQMR5PNTKMU5L5"), &records) So(len(records), ShouldEqual, 1) }) Convey("filters properly", func() { MustSelect(ctx, makeQuery("", "desc", 0, "GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ"), &records) So(len(records), ShouldEqual, 0) MustSelect(ctx, makeQuery("", "asc", 0, "GAJFK65MU3WQW4PZYJXBS7LXLXHHZB2RNVX7EC6DUZYU2NE4VMANPX2W"), &records) So(len(records), ShouldEqual, 3) }) Convey("orders properly", func() { // asc orders ascending by id MustSelect(ctx, makeQuery("", "asc", 0, "GASH7FZ4JYEF2DWA3W5T4Z7HBLP5INYDOEEXQU2G7MR3M5V7R4LOBZ6X"), &records) So(records, ShouldBeOrderedAscending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, CoreOfferRecord{}) return r.(CoreOfferRecord).OfferID }) // desc orders descending by id MustSelect(ctx, makeQuery("", "desc", 0, "GASH7FZ4JYEF2DWA3W5T4Z7HBLP5INYDOEEXQU2G7MR3M5V7R4LOBZ6X"), &records) So(records, ShouldBeOrderedDescending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, CoreOfferRecord{}) return r.(CoreOfferRecord).OfferID }) }) Convey("limits properly", func() { // returns number specified MustSelect(ctx, makeQuery("", "asc", 2, "GAJFK65MU3WQW4PZYJXBS7LXLXHHZB2RNVX7EC6DUZYU2NE4VMANPX2W"), &records) So(len(records), ShouldEqual, 2) // returns all rows if limit is higher MustSelect(ctx, makeQuery("", "asc", 10, "GAJFK65MU3WQW4PZYJXBS7LXLXHHZB2RNVX7EC6DUZYU2NE4VMANPX2W"), &records) So(len(records), ShouldEqual, 3) }) Convey("cursor works properly", func() { var record CoreOfferRecord // lowest id if ordered ascending and no cursor MustGet(ctx, makeQuery("", "asc", 0, "GAJFK65MU3WQW4PZYJXBS7LXLXHHZB2RNVX7EC6DUZYU2NE4VMANPX2W"), &record) So(record.OfferID, ShouldEqual, 1) // highest id if ordered descending and no cursor MustGet(ctx, makeQuery("", "desc", 0, "GAJFK65MU3WQW4PZYJXBS7LXLXHHZB2RNVX7EC6DUZYU2NE4VMANPX2W"), &record) So(record.OfferID, ShouldEqual, 3) // starts after the cursor if ordered ascending MustGet(ctx, makeQuery("1", "asc", 0, "GAJFK65MU3WQW4PZYJXBS7LXLXHHZB2RNVX7EC6DUZYU2NE4VMANPX2W"), &record) So(record.OfferID, ShouldEqual, 2) // starts before the cursor if ordered descending MustGet(ctx, makeQuery("3", "desc", 0, "GAJFK65MU3WQW4PZYJXBS7LXLXHHZB2RNVX7EC6DUZYU2NE4VMANPX2W"), &record) So(record.OfferID, ShouldEqual, 2) }) }) }
func TestCoreOfferPageByCurrencyQuery(t *testing.T) { test.LoadScenario("order_books") Convey("CoreOfferPageByCurrencyQuery", t, func() { var records []CoreOfferRecord makeQuery := func(c string, o string, l int32) CoreOfferPageByCurrencyQuery { pq, err := NewPageQuery(c, o, l) So(err, ShouldBeNil) return CoreOfferPageByCurrencyQuery{ SqlQuery: SqlQuery{core}, PageQuery: pq, } } simpleQuery := makeQuery("", "asc", 0) simpleQuery.SellingAssetType = xdr.AssetTypeAssetTypeCreditAlphanum4 simpleQuery.SellingAssetCode = "USD" simpleQuery.SellingIssuer = "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO4" simpleQuery.BuyingAssetType = xdr.AssetTypeAssetTypeNative Convey("filters properly", func() { // native offers q := simpleQuery MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 3) // all non-native q.SellingAssetType = xdr.AssetTypeAssetTypeCreditAlphanum4 q.SellingAssetCode = "USD" q.SellingIssuer = "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO4" q.BuyingAssetType = xdr.AssetTypeAssetTypeCreditAlphanum4 q.BuyingAssetCode = "BTC" q.BuyingIssuer = "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO4" MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 3) // non-existent order book q.SellingAssetType = xdr.AssetTypeAssetTypeCreditAlphanum4 q.SellingAssetCode = "USD" q.SellingIssuer = "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO4" q.BuyingAssetType = xdr.AssetTypeAssetTypeCreditAlphanum4 q.BuyingAssetCode = "EUR" q.BuyingIssuer = "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO4" MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 0) }) Convey("orders properly", func() { // asc orders ascending by price q := simpleQuery MustSelect(ctx, q, &records) So(records, ShouldBeOrderedAscending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, CoreOfferRecord{}) return r.(CoreOfferRecord).Price }) // asc orders ascending by price q = simpleQuery q.PageQuery.Order = "desc" MustSelect(ctx, q, &records) So(records, ShouldBeOrderedDescending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, CoreOfferRecord{}) return r.(CoreOfferRecord).Price }) }) Convey("limits properly", func() { // returns number specified q := simpleQuery q.PageQuery.Limit = 2 MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 2) // returns all rows if limit is higher q = simpleQuery q.PageQuery.Limit = 10 MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 3) }) Convey("cursor works properly", func() { var record CoreOfferRecord // lowest price if ordered ascending and no cursor q := simpleQuery MustGet(ctx, q, &record) So(record.Price, ShouldEqual, 150000000) // highest id if ordered descending and no cursor q = simpleQuery q.PageQuery.Order = "desc" q.PageQuery.Cursor = fmt.Sprintf("%d", math.MaxInt64) MustGet(ctx, q, &record) So(record.Price, ShouldEqual, 500000000) // starts after the cursor if ordered ascending q = simpleQuery q.PageQuery.Cursor = "150000000" MustGet(ctx, q, &record) So(record.Price, ShouldEqual, 200000000) // starts before the cursor if ordered descending q = simpleQuery q.PageQuery.Order = "desc" q.PageQuery.Cursor = "500000000" MustGet(ctx, q, &record) So(record.Price, ShouldEqual, 200000000) }) }) }
func TestCoreOfferPageByCurrencyQuery(t *testing.T) { test.LoadScenario("order_books") Convey("CoreOfferPageByCurrencyQuery", t, func() { var records []CoreOfferRecord makeQuery := func(c string, o string, l int32) CoreOfferPageByCurrencyQuery { pq, err := NewPageQuery(c, o, l) So(err, ShouldBeNil) return CoreOfferPageByCurrencyQuery{ SqlQuery: SqlQuery{core}, PageQuery: pq, } } simpleQuery := makeQuery("", "asc", 0) simpleQuery.TakerGetsType = xdr.CurrencyTypeCurrencyTypeAlphanum simpleQuery.TakerGetsCode = "USD" simpleQuery.TakerGetsIssuer = "gsPsm67nNK8HtwMedJZFki3jAEKgg1s4nRKrHREFqTzT6ErzBiq" simpleQuery.TakerPaysType = xdr.CurrencyTypeCurrencyTypeNative Convey("filters properly", func() { // native offers q := simpleQuery MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 3) // all non-native q.TakerGetsType = xdr.CurrencyTypeCurrencyTypeAlphanum q.TakerGetsCode = "USD" q.TakerGetsIssuer = "gsPsm67nNK8HtwMedJZFki3jAEKgg1s4nRKrHREFqTzT6ErzBiq" q.TakerPaysType = xdr.CurrencyTypeCurrencyTypeAlphanum q.TakerPaysCode = "BTC" q.TakerPaysIssuer = "gsPsm67nNK8HtwMedJZFki3jAEKgg1s4nRKrHREFqTzT6ErzBiq" MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 3) // non-existent order book q.TakerGetsType = xdr.CurrencyTypeCurrencyTypeAlphanum q.TakerGetsCode = "USD" q.TakerGetsIssuer = "gsPsm67nNK8HtwMedJZFki3jAEKgg1s4nRKrHREFqTzT6ErzBiq" q.TakerPaysType = xdr.CurrencyTypeCurrencyTypeAlphanum q.TakerPaysCode = "EUR" q.TakerPaysIssuer = "gsPsm67nNK8HtwMedJZFki3jAEKgg1s4nRKrHREFqTzT6ErzBiq" MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 0) }) Convey("orders properly", func() { // asc orders ascending by price q := simpleQuery MustSelect(ctx, q, &records) So(records, ShouldBeOrderedAscending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, CoreOfferRecord{}) return r.(CoreOfferRecord).Price }) // asc orders ascending by price q = simpleQuery q.PageQuery.Order = "desc" MustSelect(ctx, q, &records) So(records, ShouldBeOrderedDescending, func(r interface{}) int64 { So(r, ShouldHaveSameTypeAs, CoreOfferRecord{}) return r.(CoreOfferRecord).Price }) }) Convey("limits properly", func() { // returns number specified q := simpleQuery q.PageQuery.Limit = 2 MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 2) // returns all rows if limit is higher q = simpleQuery q.PageQuery.Limit = 10 MustSelect(ctx, q, &records) So(len(records), ShouldEqual, 3) }) Convey("cursor works properly", func() { var record CoreOfferRecord // lowest price if ordered ascending and no cursor q := simpleQuery MustGet(ctx, q, &record) So(record.Price, ShouldEqual, 150000000) // highest id if ordered descending and no cursor q = simpleQuery q.PageQuery.Order = "desc" q.PageQuery.Cursor = fmt.Sprintf("%d", math.MaxInt64) MustGet(ctx, q, &record) So(record.Price, ShouldEqual, 500000000) // starts after the cursor if ordered ascending q = simpleQuery q.PageQuery.Cursor = "150000000" MustGet(ctx, q, &record) So(record.Price, ShouldEqual, 200000000) // starts before the cursor if ordered descending q = simpleQuery q.PageQuery.Order = "desc" q.PageQuery.Cursor = "500000000" MustGet(ctx, q, &record) So(record.Price, ShouldEqual, 200000000) }) }) }