1
0
mirror of https://github.com/aclindsa/moneygo.git synced 2024-12-26 23:42:29 -05:00

testing: Improve testing CRUD for reports

Ensure we don't get silent errors if the Lua code is longer than the
database column, don't leave out the first report from testing, test
fetching multiple reports.
This commit is contained in:
Aaron Lindsay 2017-11-03 20:50:19 -04:00
parent 72cbcca965
commit 5504d37482
4 changed files with 87 additions and 6 deletions

View File

@ -13,6 +13,8 @@ import (
"strings" "strings"
) )
const luaMaxLengthBuffer int = 4096
func GetDbMap(db *sql.DB, dbtype config.DbType) (*gorp.DbMap, error) { func GetDbMap(db *sql.DB, dbtype config.DbType) (*gorp.DbMap, error) {
var dialect gorp.Dialect var dialect gorp.Dialect
if dbtype == config.SQLite { if dbtype == config.SQLite {
@ -36,7 +38,8 @@ func GetDbMap(db *sql.DB, dbtype config.DbType) (*gorp.DbMap, error) {
dbmap.AddTableWithName(handlers.Transaction{}, "transactions").SetKeys(true, "TransactionId") dbmap.AddTableWithName(handlers.Transaction{}, "transactions").SetKeys(true, "TransactionId")
dbmap.AddTableWithName(handlers.Split{}, "splits").SetKeys(true, "SplitId") dbmap.AddTableWithName(handlers.Split{}, "splits").SetKeys(true, "SplitId")
dbmap.AddTableWithName(handlers.Price{}, "prices").SetKeys(true, "PriceId") dbmap.AddTableWithName(handlers.Price{}, "prices").SetKeys(true, "PriceId")
dbmap.AddTableWithName(handlers.Report{}, "reports").SetKeys(true, "ReportId") rtable := dbmap.AddTableWithName(handlers.Report{}, "reports").SetKeys(true, "ReportId")
rtable.ColMap("Lua").SetMaxSize(handlers.LuaMaxLength + luaMaxLengthBuffer)
err := dbmap.CreateTablesIfNotExists() err := dbmap.CreateTablesIfNotExists()
if err != nil { if err != nil {

View File

@ -39,6 +39,10 @@ type Report struct {
Lua string Lua string
} }
// The maximum length (in bytes) the Lua code may be. This is used to set the
// max size of the database columns (with an added fudge factor)
const LuaMaxLength int = 65536
func (r *Report) Write(w http.ResponseWriter) error { func (r *Report) Write(w http.ResponseWriter) error {
enc := json.NewEncoder(w) enc := json.NewEncoder(w)
return enc.Encode(r) return enc.Encode(r)
@ -234,6 +238,10 @@ func ReportHandler(r *http.Request, tx *Tx) ResponseWriterWriter {
report.ReportId = -1 report.ReportId = -1
report.UserId = user.UserId report.UserId = user.UserId
if len(report.Lua) >= LuaMaxLength {
return NewError(3 /*Invalid Request*/)
}
err = InsertReport(tx, &report) err = InsertReport(tx, &report)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
@ -292,6 +300,10 @@ func ReportHandler(r *http.Request, tx *Tx) ResponseWriterWriter {
} }
report.UserId = user.UserId report.UserId = user.UserId
if len(report.Lua) >= LuaMaxLength {
return NewError(3 /*Invalid Request*/)
}
err = UpdateReport(tx, &report) err = UpdateReport(tx, &report)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -50,7 +50,7 @@ func deleteReport(client *http.Client, r *handlers.Report) error {
func TestCreateReport(t *testing.T) { func TestCreateReport(t *testing.T) {
RunWith(t, &data[0], func(t *testing.T, d *TestData) { RunWith(t, &data[0], func(t *testing.T, d *TestData) {
for i := 1; i < len(data[0].reports); i++ { for i := 0; i < len(data[0].reports); i++ {
orig := data[0].reports[i] orig := data[0].reports[i]
r := d.reports[i] r := d.reports[i]
@ -63,13 +63,26 @@ func TestCreateReport(t *testing.T) {
if r.Lua != orig.Lua { if r.Lua != orig.Lua {
t.Errorf("Lua doesn't match") t.Errorf("Lua doesn't match")
} }
r.Lua = string(make([]byte, handlers.LuaMaxLength+1))
_, err := createReport(d.clients[orig.UserId], &r)
if err == nil {
t.Fatalf("Expected error creating report with too-long Lua")
}
if herr, ok := err.(*handlers.Error); ok {
if herr.ErrorId != 3 { // Invalid requeset
t.Fatalf("Unexpected API error creating report with too-long Lua: %s", herr)
}
} else {
t.Fatalf("Unexpected error creating report with too-long Lua")
}
} }
}) })
} }
func TestGetReport(t *testing.T) { func TestGetReport(t *testing.T) {
RunWith(t, &data[0], func(t *testing.T, d *TestData) { RunWith(t, &data[0], func(t *testing.T, d *TestData) {
for i := 1; i < len(data[0].reports); i++ { for i := 0; i < len(data[0].reports); i++ {
orig := data[0].reports[i] orig := data[0].reports[i]
curr := d.reports[i] curr := d.reports[i]
@ -87,9 +100,49 @@ func TestGetReport(t *testing.T) {
}) })
} }
func TestGetReports(t *testing.T) {
RunWith(t, &data[0], func(t *testing.T, d *TestData) {
rl, err := getReports(d.clients[0])
if err != nil {
t.Fatalf("Error fetching reports: %s\n", err)
}
numreports := 0
foundIds := make(map[int64]bool)
for i := 0; i < len(data[0].reports); i++ {
orig := data[0].reports[i]
curr := d.reports[i]
if curr.UserId != d.users[0].UserId {
continue
}
numreports += 1
found := false
for _, r := range *rl.Reports {
if orig.Name == r.Name && orig.Lua == r.Lua {
if _, ok := foundIds[r.ReportId]; ok {
continue
}
foundIds[r.ReportId] = true
found = true
break
}
}
if !found {
t.Errorf("Unable to find matching report: %+v", orig)
}
}
if numreports != len(*rl.Reports) {
t.Fatalf("Expected %d reports, received %d", numreports, len(*rl.Reports))
}
})
}
func TestUpdateReport(t *testing.T) { func TestUpdateReport(t *testing.T) {
RunWith(t, &data[0], func(t *testing.T, d *TestData) { RunWith(t, &data[0], func(t *testing.T, d *TestData) {
for i := 1; i < len(data[0].reports); i++ { for i := 0; i < len(data[0].reports); i++ {
orig := data[0].reports[i] orig := data[0].reports[i]
curr := d.reports[i] curr := d.reports[i]
@ -110,13 +163,26 @@ func TestUpdateReport(t *testing.T) {
if r.Lua != curr.Lua { if r.Lua != curr.Lua {
t.Errorf("Lua doesn't match") t.Errorf("Lua doesn't match")
} }
r.Lua = string(make([]byte, handlers.LuaMaxLength+1))
_, err = updateReport(d.clients[orig.UserId], r)
if err == nil {
t.Fatalf("Expected error updating report with too-long Lua")
}
if herr, ok := err.(*handlers.Error); ok {
if herr.ErrorId != 3 { // Invalid requeset
t.Fatalf("Unexpected API error updating report with too-long Lua: %s", herr)
}
} else {
t.Fatalf("Unexpected error updating report with too-long Lua")
}
} }
}) })
} }
func TestDeleteReport(t *testing.T) { func TestDeleteReport(t *testing.T) {
RunWith(t, &data[0], func(t *testing.T, d *TestData) { RunWith(t, &data[0], func(t *testing.T, d *TestData) {
for i := 1; i < len(data[0].reports); i++ { for i := 0; i < len(data[0].reports); i++ {
orig := data[0].reports[i] orig := data[0].reports[i]
curr := d.reports[i] curr := d.reports[i]

View File

@ -321,7 +321,7 @@ var data = []TestData{
reports: []handlers.Report{ reports: []handlers.Report{
handlers.Report{ handlers.Report{
UserId: 0, UserId: 0,
Name: "", Name: "Monthly Expenses",
Lua: ` Lua: `
function account_series_map(accounts, tabulation) function account_series_map(accounts, tabulation)
map = {} map = {}