예제 #1
0
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)
		})
	})
}
예제 #9
0
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)
		})

	})
}
예제 #13
0
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)
	})
}
예제 #14
0
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)
	})
}
예제 #15
0
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)
		})

	})
}
예제 #16
0
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)
	})
}
예제 #21
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)
		})

	})
}
예제 #26
0
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)
		})

	})
}