mirror of
https://github.com/pocketbase/pocketbase.git
synced 2025-01-10 00:43:36 +02:00
721 lines
19 KiB
Go
721 lines
19 KiB
Go
package forms_test
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
validation "github.com/go-ozzo/ozzo-validation/v4"
|
|
"github.com/labstack/echo/v5"
|
|
"github.com/pocketbase/pocketbase/core"
|
|
"github.com/pocketbase/pocketbase/daos"
|
|
"github.com/pocketbase/pocketbase/forms"
|
|
"github.com/pocketbase/pocketbase/models"
|
|
"github.com/pocketbase/pocketbase/tests"
|
|
"github.com/pocketbase/pocketbase/tools/list"
|
|
)
|
|
|
|
func TestRecordUpsertPanic1(t *testing.T) {
|
|
defer func() {
|
|
if recover() == nil {
|
|
t.Fatal("The form did not panic")
|
|
}
|
|
}()
|
|
|
|
forms.NewRecordUpsert(nil, nil)
|
|
}
|
|
|
|
func TestRecordUpsertPanic2(t *testing.T) {
|
|
app, _ := tests.NewTestApp()
|
|
defer app.Cleanup()
|
|
|
|
defer func() {
|
|
if recover() == nil {
|
|
t.Fatal("The form did not panic")
|
|
}
|
|
}()
|
|
|
|
forms.NewRecordUpsert(app, nil)
|
|
}
|
|
|
|
func TestNewRecordUpsert(t *testing.T) {
|
|
app, _ := tests.NewTestApp()
|
|
defer app.Cleanup()
|
|
|
|
collection, _ := app.Dao().FindCollectionByNameOrId("demo")
|
|
record := models.NewRecord(collection)
|
|
record.SetDataValue("title", "test_value")
|
|
|
|
form := forms.NewRecordUpsert(app, record)
|
|
|
|
val := form.Data["title"]
|
|
if val != "test_value" {
|
|
t.Errorf("Expected record data to be loaded, got %v", form.Data)
|
|
}
|
|
}
|
|
|
|
func TestRecordUpsertLoadDataUnsupported(t *testing.T) {
|
|
app, _ := tests.NewTestApp()
|
|
defer app.Cleanup()
|
|
|
|
collection, _ := app.Dao().FindCollectionByNameOrId("demo4")
|
|
record, err := app.Dao().FindFirstRecordByData(collection, "id", "054f9f24-0a0a-4e09-87b1-bc7ff2b336a2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testData := "title=test123"
|
|
|
|
form := forms.NewRecordUpsert(app, record)
|
|
req := httptest.NewRequest(http.MethodGet, "/", strings.NewReader(testData))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationForm)
|
|
|
|
if err := form.LoadData(req); err == nil {
|
|
t.Fatal("Expected LoadData to fail, got nil")
|
|
}
|
|
}
|
|
|
|
func TestRecordUpsertLoadDataJson(t *testing.T) {
|
|
app, _ := tests.NewTestApp()
|
|
defer app.Cleanup()
|
|
|
|
collection, _ := app.Dao().FindCollectionByNameOrId("demo4")
|
|
record, err := app.Dao().FindFirstRecordByData(collection, "id", "054f9f24-0a0a-4e09-87b1-bc7ff2b336a2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testData := map[string]any{
|
|
"id": "test_id",
|
|
"title": "test123",
|
|
"unknown": "test456",
|
|
// file fields unset/delete
|
|
"onefile": nil,
|
|
"manyfiles.0": "",
|
|
"manyfiles.1": "test.png", // should be ignored
|
|
"onlyimages": nil,
|
|
}
|
|
|
|
form := forms.NewRecordUpsert(app, record)
|
|
jsonBody, _ := json.Marshal(testData)
|
|
req := httptest.NewRequest(http.MethodGet, "/", bytes.NewReader(jsonBody))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
loadErr := form.LoadData(req)
|
|
if loadErr != nil {
|
|
t.Fatal(loadErr)
|
|
}
|
|
|
|
if form.Id != "test_id" {
|
|
t.Fatalf("Expect id field to be %q, got %q", "test_id", form.Id)
|
|
}
|
|
|
|
if v, ok := form.Data["title"]; !ok || v != "test123" {
|
|
t.Fatalf("Expect title field to be %q, got %q", "test123", v)
|
|
}
|
|
|
|
if v, ok := form.Data["unknown"]; ok {
|
|
t.Fatalf("Didn't expect unknown field to be set, got %v", v)
|
|
}
|
|
|
|
onefile, ok := form.Data["onefile"]
|
|
if !ok {
|
|
t.Fatal("Expect onefile field to be set")
|
|
}
|
|
if onefile != "" {
|
|
t.Fatalf("Expect onefile field to be empty string, got %v", onefile)
|
|
}
|
|
|
|
manyfiles, ok := form.Data["manyfiles"]
|
|
if !ok || manyfiles == nil {
|
|
t.Fatal("Expect manyfiles field to be set")
|
|
}
|
|
manyfilesRemains := len(list.ToUniqueStringSlice(manyfiles))
|
|
if manyfilesRemains != 1 {
|
|
t.Fatalf("Expect only 1 manyfiles to remain, got \n%v", manyfiles)
|
|
}
|
|
|
|
onlyimages := form.Data["onlyimages"]
|
|
if len(list.ToUniqueStringSlice(onlyimages)) != 0 {
|
|
t.Fatalf("Expect onlyimages field to be deleted, got \n%v", onlyimages)
|
|
}
|
|
}
|
|
|
|
func TestRecordUpsertLoadDataMultipart(t *testing.T) {
|
|
app, _ := tests.NewTestApp()
|
|
defer app.Cleanup()
|
|
|
|
collection, _ := app.Dao().FindCollectionByNameOrId("demo4")
|
|
record, err := app.Dao().FindFirstRecordByData(collection, "id", "054f9f24-0a0a-4e09-87b1-bc7ff2b336a2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
formData, mp, err := tests.MockMultipartData(map[string]string{
|
|
"id": "test_id",
|
|
"title": "test123",
|
|
"unknown": "test456",
|
|
// file fields unset/delete
|
|
"onefile": "",
|
|
"manyfiles.0": "", // delete by index
|
|
"manyfiles.b635c395-6837-49e5-8535-b0a6ebfbdbf3.png": "", // delete by name
|
|
"manyfiles.1": "test.png", // should be ignored
|
|
"onlyimages": "",
|
|
}, "onlyimages")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form := forms.NewRecordUpsert(app, record)
|
|
req := httptest.NewRequest(http.MethodGet, "/", formData)
|
|
req.Header.Set(echo.HeaderContentType, mp.FormDataContentType())
|
|
loadErr := form.LoadData(req)
|
|
if loadErr != nil {
|
|
t.Fatal(loadErr)
|
|
}
|
|
|
|
if form.Id != "test_id" {
|
|
t.Fatalf("Expect id field to be %q, got %q", "test_id", form.Id)
|
|
}
|
|
|
|
if v, ok := form.Data["title"]; !ok || v != "test123" {
|
|
t.Fatalf("Expect title field to be %q, got %q", "test123", v)
|
|
}
|
|
|
|
if v, ok := form.Data["unknown"]; ok {
|
|
t.Fatalf("Didn't expect unknown field to be set, got %v", v)
|
|
}
|
|
|
|
onefile, ok := form.Data["onefile"]
|
|
if !ok {
|
|
t.Fatal("Expect onefile field to be set")
|
|
}
|
|
if onefile != "" {
|
|
t.Fatalf("Expect onefile field to be empty string, got %v", onefile)
|
|
}
|
|
|
|
manyfiles, ok := form.Data["manyfiles"]
|
|
if !ok || manyfiles == nil {
|
|
t.Fatal("Expect manyfiles field to be set")
|
|
}
|
|
manyfilesRemains := len(list.ToUniqueStringSlice(manyfiles))
|
|
if manyfilesRemains != 0 {
|
|
t.Fatalf("Expect 0 manyfiles to remain, got %v", manyfiles)
|
|
}
|
|
|
|
onlyimages, ok := form.Data["onlyimages"]
|
|
if !ok || onlyimages == nil {
|
|
t.Fatal("Expect onlyimages field to be set")
|
|
}
|
|
onlyimagesRemains := len(list.ToUniqueStringSlice(onlyimages))
|
|
expectedRemains := 1 // -2 removed + 1 new upload
|
|
if onlyimagesRemains != expectedRemains {
|
|
t.Fatalf("Expect onlyimages to be %d, got %d (%v)", expectedRemains, onlyimagesRemains, onlyimages)
|
|
}
|
|
}
|
|
|
|
func TestRecordUpsertValidateFailure(t *testing.T) {
|
|
app, _ := tests.NewTestApp()
|
|
defer app.Cleanup()
|
|
|
|
collection, _ := app.Dao().FindCollectionByNameOrId("demo4")
|
|
record, err := app.Dao().FindFirstRecordByData(collection, "id", "054f9f24-0a0a-4e09-87b1-bc7ff2b336a2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// try with invalid test data to check whether the RecordDataValidator is triggered
|
|
formData, mp, err := tests.MockMultipartData(map[string]string{
|
|
"id": "",
|
|
"unknown": "test456", // should be ignored
|
|
"title": "a",
|
|
"onerel": "00000000-84ab-4057-a592-4604a731f78f",
|
|
}, "manyfiles", "manyfiles")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expectedErrors := []string{"title", "onerel", "manyfiles"}
|
|
|
|
form := forms.NewRecordUpsert(app, record)
|
|
req := httptest.NewRequest(http.MethodGet, "/", formData)
|
|
req.Header.Set(echo.HeaderContentType, mp.FormDataContentType())
|
|
form.LoadData(req)
|
|
|
|
result := form.Validate()
|
|
|
|
// parse errors
|
|
errs, ok := result.(validation.Errors)
|
|
if !ok && result != nil {
|
|
t.Fatalf("Failed to parse errors %v", result)
|
|
}
|
|
|
|
// check errors
|
|
if len(errs) > len(expectedErrors) {
|
|
t.Fatalf("Expected error keys %v, got %v", expectedErrors, errs)
|
|
}
|
|
for _, k := range expectedErrors {
|
|
if _, ok := errs[k]; !ok {
|
|
t.Errorf("Missing expected error key %q in %v", k, errs)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRecordUpsertValidateSuccess(t *testing.T) {
|
|
app, _ := tests.NewTestApp()
|
|
defer app.Cleanup()
|
|
|
|
collection, _ := app.Dao().FindCollectionByNameOrId("demo4")
|
|
record, err := app.Dao().FindFirstRecordByData(collection, "id", "054f9f24-0a0a-4e09-87b1-bc7ff2b336a2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
formData, mp, err := tests.MockMultipartData(map[string]string{
|
|
"id": record.Id,
|
|
"unknown": "test456", // should be ignored
|
|
"title": "abc",
|
|
"onerel": "054f9f24-0a0a-4e09-87b1-bc7ff2b336a2",
|
|
}, "manyfiles", "onefile")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form := forms.NewRecordUpsert(app, record)
|
|
req := httptest.NewRequest(http.MethodGet, "/", formData)
|
|
req.Header.Set(echo.HeaderContentType, mp.FormDataContentType())
|
|
form.LoadData(req)
|
|
|
|
result := form.Validate()
|
|
if result != nil {
|
|
t.Fatal(result)
|
|
}
|
|
}
|
|
|
|
func TestRecordUpsertDrySubmitFailure(t *testing.T) {
|
|
app, _ := tests.NewTestApp()
|
|
defer app.Cleanup()
|
|
|
|
collection, _ := app.Dao().FindCollectionByNameOrId("demo4")
|
|
recordBefore, err := app.Dao().FindFirstRecordByData(collection, "id", "054f9f24-0a0a-4e09-87b1-bc7ff2b336a2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
formData, mp, err := tests.MockMultipartData(map[string]string{
|
|
"title": "a",
|
|
"onerel": "00000000-84ab-4057-a592-4604a731f78f",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form := forms.NewRecordUpsert(app, recordBefore)
|
|
req := httptest.NewRequest(http.MethodGet, "/", formData)
|
|
req.Header.Set(echo.HeaderContentType, mp.FormDataContentType())
|
|
form.LoadData(req)
|
|
|
|
callbackCalls := 0
|
|
|
|
// ensure that validate is triggered
|
|
// ---
|
|
result := form.DrySubmit(func(txDao *daos.Dao) error {
|
|
callbackCalls++
|
|
return nil
|
|
})
|
|
if result == nil {
|
|
t.Fatal("Expected error, got nil")
|
|
}
|
|
if callbackCalls != 0 {
|
|
t.Fatalf("Expected callbackCalls to be 0, got %d", callbackCalls)
|
|
}
|
|
|
|
// ensure that the record changes weren't persisted
|
|
// ---
|
|
recordAfter, err := app.Dao().FindFirstRecordByData(collection, "id", recordBefore.Id)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if recordAfter.GetStringDataValue("title") == "a" {
|
|
t.Fatalf("Expected record.title to be %v, got %v", recordAfter.GetStringDataValue("title"), "a")
|
|
}
|
|
|
|
if recordAfter.GetStringDataValue("onerel") == "00000000-84ab-4057-a592-4604a731f78f" {
|
|
t.Fatalf("Expected record.onerel to be %s, got %s", recordBefore.GetStringDataValue("onerel"), recordAfter.GetStringDataValue("onerel"))
|
|
}
|
|
}
|
|
|
|
func TestRecordUpsertDrySubmitSuccess(t *testing.T) {
|
|
app, _ := tests.NewTestApp()
|
|
defer app.Cleanup()
|
|
|
|
collection, _ := app.Dao().FindCollectionByNameOrId("demo4")
|
|
recordBefore, err := app.Dao().FindFirstRecordByData(collection, "id", "054f9f24-0a0a-4e09-87b1-bc7ff2b336a2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
formData, mp, err := tests.MockMultipartData(map[string]string{
|
|
"title": "dry_test",
|
|
"onefile": "",
|
|
}, "manyfiles")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form := forms.NewRecordUpsert(app, recordBefore)
|
|
req := httptest.NewRequest(http.MethodGet, "/", formData)
|
|
req.Header.Set(echo.HeaderContentType, mp.FormDataContentType())
|
|
form.LoadData(req)
|
|
|
|
callbackCalls := 0
|
|
|
|
result := form.DrySubmit(func(txDao *daos.Dao) error {
|
|
callbackCalls++
|
|
return nil
|
|
})
|
|
if result != nil {
|
|
t.Fatalf("Expected nil, got error %v", result)
|
|
}
|
|
|
|
// ensure callback was called
|
|
if callbackCalls != 1 {
|
|
t.Fatalf("Expected callbackCalls to be 1, got %d", callbackCalls)
|
|
}
|
|
|
|
// ensure that the record changes weren't persisted
|
|
// ---
|
|
recordAfter, err := app.Dao().FindFirstRecordByData(collection, "id", recordBefore.Id)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if recordAfter.GetStringDataValue("title") == "dry_test" {
|
|
t.Fatalf("Expected record.title to be %v, got %v", recordAfter.GetStringDataValue("title"), "dry_test")
|
|
}
|
|
if recordAfter.GetStringDataValue("onefile") == "" {
|
|
t.Fatal("Expected record.onefile to be set, got empty string")
|
|
}
|
|
|
|
// file wasn't removed
|
|
if !hasRecordFile(app, recordAfter, recordAfter.GetStringDataValue("onefile")) {
|
|
t.Fatal("onefile file should not have been deleted")
|
|
}
|
|
}
|
|
|
|
func TestRecordUpsertSubmitFailure(t *testing.T) {
|
|
app, _ := tests.NewTestApp()
|
|
defer app.Cleanup()
|
|
|
|
collection, _ := app.Dao().FindCollectionByNameOrId("demo4")
|
|
recordBefore, err := app.Dao().FindFirstRecordByData(collection, "id", "054f9f24-0a0a-4e09-87b1-bc7ff2b336a2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
formData, mp, err := tests.MockMultipartData(map[string]string{
|
|
"title": "a",
|
|
"onefile": "",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form := forms.NewRecordUpsert(app, recordBefore)
|
|
req := httptest.NewRequest(http.MethodGet, "/", formData)
|
|
req.Header.Set(echo.HeaderContentType, mp.FormDataContentType())
|
|
form.LoadData(req)
|
|
|
|
interceptorCalls := 0
|
|
interceptor := func(next forms.InterceptorNextFunc) forms.InterceptorNextFunc {
|
|
return func() error {
|
|
interceptorCalls++
|
|
return next()
|
|
}
|
|
}
|
|
|
|
// ensure that validate is triggered
|
|
// ---
|
|
result := form.Submit(interceptor)
|
|
if result == nil {
|
|
t.Fatal("Expected error, got nil")
|
|
}
|
|
|
|
// check interceptor calls
|
|
// ---
|
|
if interceptorCalls != 0 {
|
|
t.Fatalf("Expected interceptor to be called 0 times, got %d", interceptorCalls)
|
|
}
|
|
|
|
// ensure that the record changes weren't persisted
|
|
// ---
|
|
recordAfter, err := app.Dao().FindFirstRecordByData(collection, "id", recordBefore.Id)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if recordAfter.GetStringDataValue("title") == "a" {
|
|
t.Fatalf("Expected record.title to be %v, got %v", recordAfter.GetStringDataValue("title"), "a")
|
|
}
|
|
|
|
if recordAfter.GetStringDataValue("onefile") == "" {
|
|
t.Fatal("Expected record.onefile to be set, got empty string")
|
|
}
|
|
|
|
// file wasn't removed
|
|
if !hasRecordFile(app, recordAfter, recordAfter.GetStringDataValue("onefile")) {
|
|
t.Fatal("onefile file should not have been deleted")
|
|
}
|
|
}
|
|
|
|
func TestRecordUpsertSubmitSuccess(t *testing.T) {
|
|
app, _ := tests.NewTestApp()
|
|
defer app.Cleanup()
|
|
|
|
collection, _ := app.Dao().FindCollectionByNameOrId("demo4")
|
|
recordBefore, err := app.Dao().FindFirstRecordByData(collection, "id", "054f9f24-0a0a-4e09-87b1-bc7ff2b336a2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
formData, mp, err := tests.MockMultipartData(map[string]string{
|
|
"title": "test_save",
|
|
"onefile": "",
|
|
"onlyimages": "",
|
|
}, "manyfiles.1", "manyfiles") // replace + new file
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form := forms.NewRecordUpsert(app, recordBefore)
|
|
req := httptest.NewRequest(http.MethodGet, "/", formData)
|
|
req.Header.Set(echo.HeaderContentType, mp.FormDataContentType())
|
|
form.LoadData(req)
|
|
|
|
interceptorCalls := 0
|
|
interceptor := func(next forms.InterceptorNextFunc) forms.InterceptorNextFunc {
|
|
return func() error {
|
|
interceptorCalls++
|
|
return next()
|
|
}
|
|
}
|
|
|
|
result := form.Submit(interceptor)
|
|
if result != nil {
|
|
t.Fatalf("Expected nil, got error %v", result)
|
|
}
|
|
|
|
// check interceptor calls
|
|
// ---
|
|
if interceptorCalls != 1 {
|
|
t.Fatalf("Expected interceptor to be called 1 time, got %d", interceptorCalls)
|
|
}
|
|
|
|
// ensure that the record changes were persisted
|
|
// ---
|
|
recordAfter, err := app.Dao().FindFirstRecordByData(collection, "id", recordBefore.Id)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if recordAfter.GetStringDataValue("title") != "test_save" {
|
|
t.Fatalf("Expected record.title to be %v, got %v", recordAfter.GetStringDataValue("title"), "test_save")
|
|
}
|
|
|
|
if hasRecordFile(app, recordAfter, recordAfter.GetStringDataValue("onefile")) {
|
|
t.Fatal("Expected record.onefile to be deleted")
|
|
}
|
|
|
|
onlyimages := (recordAfter.GetStringSliceDataValue("onlyimages"))
|
|
if len(onlyimages) != 0 {
|
|
t.Fatalf("Expected all onlyimages files to be deleted, got %d (%v)", len(onlyimages), onlyimages)
|
|
}
|
|
|
|
manyfiles := (recordAfter.GetStringSliceDataValue("manyfiles"))
|
|
if len(manyfiles) != 3 {
|
|
t.Fatalf("Expected 3 manyfiles, got %d (%v)", len(manyfiles), manyfiles)
|
|
}
|
|
for _, f := range manyfiles {
|
|
if !hasRecordFile(app, recordAfter, f) {
|
|
t.Fatalf("Expected file %q to exist", f)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRecordUpsertSubmitInterceptors(t *testing.T) {
|
|
app, _ := tests.NewTestApp()
|
|
defer app.Cleanup()
|
|
|
|
collection, _ := app.Dao().FindCollectionByNameOrId("demo4")
|
|
record, err := app.Dao().FindFirstRecordByData(collection, "id", "054f9f24-0a0a-4e09-87b1-bc7ff2b336a2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form := forms.NewRecordUpsert(app, record)
|
|
form.Data["title"] = "test_new"
|
|
|
|
testErr := errors.New("test_error")
|
|
interceptorRecordTitle := ""
|
|
|
|
interceptor1Called := false
|
|
interceptor1 := func(next forms.InterceptorNextFunc) forms.InterceptorNextFunc {
|
|
return func() error {
|
|
interceptor1Called = true
|
|
return next()
|
|
}
|
|
}
|
|
|
|
interceptor2Called := false
|
|
interceptor2 := func(next forms.InterceptorNextFunc) forms.InterceptorNextFunc {
|
|
return func() error {
|
|
interceptorRecordTitle = record.GetStringDataValue("title") // to check if the record was filled
|
|
interceptor2Called = true
|
|
return testErr
|
|
}
|
|
}
|
|
|
|
submitErr := form.Submit(interceptor1, interceptor2)
|
|
if submitErr != testErr {
|
|
t.Fatalf("Expected submitError %v, got %v", testErr, submitErr)
|
|
}
|
|
|
|
if !interceptor1Called {
|
|
t.Fatalf("Expected interceptor1 to be called")
|
|
}
|
|
|
|
if !interceptor2Called {
|
|
t.Fatalf("Expected interceptor2 to be called")
|
|
}
|
|
|
|
if interceptorRecordTitle != form.Data["title"].(string) {
|
|
t.Fatalf("Expected the form model to be filled before calling the interceptors")
|
|
}
|
|
}
|
|
|
|
func hasRecordFile(app core.App, record *models.Record, filename string) bool {
|
|
fs, _ := app.NewFilesystem()
|
|
defer fs.Close()
|
|
|
|
fileKey := filepath.Join(
|
|
record.Collection().Id,
|
|
record.Id,
|
|
filename,
|
|
)
|
|
|
|
exists, _ := fs.Exists(fileKey)
|
|
|
|
return exists
|
|
}
|
|
|
|
func TestRecordUpsertWithCustomId(t *testing.T) {
|
|
app, _ := tests.NewTestApp()
|
|
defer app.Cleanup()
|
|
|
|
collection, _ := app.Dao().FindCollectionByNameOrId("demo3")
|
|
existingRecord, err := app.Dao().FindFirstRecordByData(collection, "id", "2c542824-9de1-42fe-8924-e57c86267760")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
scenarios := []struct {
|
|
name string
|
|
data map[string]string
|
|
record *models.Record
|
|
expectError bool
|
|
}{
|
|
{
|
|
"empty data",
|
|
map[string]string{},
|
|
models.NewRecord(collection),
|
|
false,
|
|
},
|
|
{
|
|
"empty id",
|
|
map[string]string{"id": ""},
|
|
models.NewRecord(collection),
|
|
false,
|
|
},
|
|
{
|
|
"id < 15 chars",
|
|
map[string]string{"id": "a23"},
|
|
models.NewRecord(collection),
|
|
true,
|
|
},
|
|
{
|
|
"id > 15 chars",
|
|
map[string]string{"id": "a234567890123456"},
|
|
models.NewRecord(collection),
|
|
true,
|
|
},
|
|
{
|
|
"id = 15 chars (invalid chars)",
|
|
map[string]string{"id": "a@3456789012345"},
|
|
models.NewRecord(collection),
|
|
true,
|
|
},
|
|
{
|
|
"id = 15 chars (valid chars)",
|
|
map[string]string{"id": "a23456789012345"},
|
|
models.NewRecord(collection),
|
|
false,
|
|
},
|
|
{
|
|
"changing the id of an existing record",
|
|
map[string]string{"id": "b23456789012345"},
|
|
existingRecord,
|
|
true,
|
|
},
|
|
{
|
|
"using the same existing record id",
|
|
map[string]string{"id": existingRecord.Id},
|
|
existingRecord,
|
|
false,
|
|
},
|
|
{
|
|
"skipping the id for existing record",
|
|
map[string]string{},
|
|
existingRecord,
|
|
false,
|
|
},
|
|
}
|
|
|
|
for _, scenario := range scenarios {
|
|
formData, mp, err := tests.MockMultipartData(scenario.data)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form := forms.NewRecordUpsert(app, scenario.record)
|
|
req := httptest.NewRequest(http.MethodGet, "/", formData)
|
|
req.Header.Set(echo.HeaderContentType, mp.FormDataContentType())
|
|
form.LoadData(req)
|
|
|
|
dryErr := form.DrySubmit(nil)
|
|
hasDryErr := dryErr != nil
|
|
|
|
submitErr := form.Submit()
|
|
hasSubmitErr := submitErr != nil
|
|
|
|
if hasDryErr != hasSubmitErr {
|
|
t.Errorf("[%s] Expected hasDryErr and hasSubmitErr to have the same value, got %v vs %v", scenario.name, hasDryErr, hasSubmitErr)
|
|
}
|
|
|
|
if hasSubmitErr != scenario.expectError {
|
|
t.Errorf("[%s] Expected hasSubmitErr to be %v, got %v (%v)", scenario.name, scenario.expectError, hasSubmitErr, submitErr)
|
|
}
|
|
|
|
if id, ok := scenario.data["id"]; ok && id != "" && !hasSubmitErr {
|
|
_, err := app.Dao().FindRecordById(collection, id, nil)
|
|
if err != nil {
|
|
t.Errorf("[%s] Expected to find record with id %s, got %v", scenario.name, id, err)
|
|
}
|
|
}
|
|
}
|
|
}
|