added explicit errors when trying to truncate view collections or deleting view records
This commit is contained in:
parent
2c2246ecb9
commit
c09cd8364a
|
@ -1,3 +1,11 @@
|
||||||
|
## v0.23.0-rc4 (WIP)
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> **This is a prerelease intended for test and experimental purposes only!**
|
||||||
|
|
||||||
|
- Added more user friendly view collection truncate error message.
|
||||||
|
|
||||||
|
|
||||||
## v0.23.0-rc3
|
## v0.23.0-rc3
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
|
|
|
@ -169,6 +169,10 @@ func collectionTruncate(e *core.RequestEvent) error {
|
||||||
return e.NotFoundError("", err)
|
return e.NotFoundError("", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if collection.IsView() {
|
||||||
|
return e.BadRequestError("View collections cannot be truncated since they don't store their own records.", nil)
|
||||||
|
}
|
||||||
|
|
||||||
err = e.App.TruncateCollection(collection)
|
err = e.App.TruncateCollection(collection)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return e.BadRequestError("Failed to truncate collection (most likely due to required cascade delete record references).", err)
|
return e.BadRequestError("Failed to truncate collection (most likely due to required cascade delete record references).", err)
|
||||||
|
|
|
@ -1493,6 +1493,17 @@ func TestCollectionTruncate(t *testing.T) {
|
||||||
"OnRecordAfterUpdateError": 2,
|
"OnRecordAfterUpdateError": 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "authorized as superuser trying to truncate view collection",
|
||||||
|
Method: http.MethodDelete,
|
||||||
|
URL: "/api/collections/view2/truncate",
|
||||||
|
Headers: map[string]string{
|
||||||
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
||||||
|
},
|
||||||
|
ExpectedStatus: 400,
|
||||||
|
ExpectedContent: []string{`"data":{}`},
|
||||||
|
ExpectedEvents: map[string]int{"*": 0},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, scenario := range scenarios {
|
for _, scenario := range scenarios {
|
||||||
|
|
|
@ -176,6 +176,10 @@ func (app *BaseApp) FindCollectionReferences(collection *Collection, excludeIds
|
||||||
// Note that this method will also trigger the records related
|
// Note that this method will also trigger the records related
|
||||||
// cascade and file delete actions.
|
// cascade and file delete actions.
|
||||||
func (app *BaseApp) TruncateCollection(collection *Collection) error {
|
func (app *BaseApp) TruncateCollection(collection *Collection) error {
|
||||||
|
if collection.IsView() {
|
||||||
|
return errors.New("view collections cannot be truncated since they don't store their own records.")
|
||||||
|
}
|
||||||
|
|
||||||
return app.RunInTransaction(func(txApp App) error {
|
return app.RunInTransaction(func(txApp App) error {
|
||||||
records := make([]*Record, 0, 500)
|
records := make([]*Record, 0, 500)
|
||||||
|
|
||||||
|
|
|
@ -299,6 +299,18 @@ func TestFindCollectionTruncate(t *testing.T) {
|
||||||
return len(entries), err
|
return len(entries), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.Run("truncate view", func(t *testing.T) {
|
||||||
|
view2, err := app.FindCollectionByNameOrId("view2")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = app.TruncateCollection(view2)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("Expected truncate to fail because view collections can't be truncated")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("truncate failure", func(t *testing.T) {
|
t.Run("truncate failure", func(t *testing.T) {
|
||||||
demo3, err := app.FindCollectionByNameOrId("demo3")
|
demo3, err := app.FindCollectionByNameOrId("demo3")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -378,7 +378,13 @@ func (app *BaseApp) registerRecordHooks() {
|
||||||
e.Context,
|
e.Context,
|
||||||
e.App,
|
e.App,
|
||||||
InterceptorActionDelete,
|
InterceptorActionDelete,
|
||||||
e.Next,
|
func() error {
|
||||||
|
if e.Record.Collection().IsView() {
|
||||||
|
return errors.New("view records cannot be deleted")
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.Next()
|
||||||
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
Priority: -99,
|
Priority: -99,
|
||||||
|
|
|
@ -1841,9 +1841,21 @@ func TestRecordDelete(t *testing.T) {
|
||||||
|
|
||||||
// delete unsaved record
|
// delete unsaved record
|
||||||
// ---
|
// ---
|
||||||
rec0 := core.NewRecord(demoCollection)
|
newRec := core.NewRecord(demoCollection)
|
||||||
if err := app.Delete(rec0); err == nil {
|
if err := app.Delete(newRec); err == nil {
|
||||||
t.Fatal("(rec0) Didn't expect to succeed deleting unsaved record")
|
t.Fatal("(newRec) Didn't expect to succeed deleting unsaved record")
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete view record
|
||||||
|
// ---
|
||||||
|
viewRec, _ := app.FindRecordById("view2", "84nmscqy84lsi1t")
|
||||||
|
if err := app.Delete(viewRec); err == nil {
|
||||||
|
t.Fatal("(viewRec) Didn't expect to succeed deleting view record")
|
||||||
|
}
|
||||||
|
// check if it still exists
|
||||||
|
viewRec, _ = app.FindRecordById(viewRec.Collection().Id, viewRec.Id)
|
||||||
|
if viewRec == nil {
|
||||||
|
t.Fatal("(viewRec) Expected view record to still exists")
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete existing record + external auths
|
// delete existing record + external auths
|
||||||
|
|
Loading…
Reference in New Issue