123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- package activity
- import (
- "context"
- "fmt"
- "net/http/httptest"
- "os"
- "reflect"
- "testing"
- "github.com/qor5/admin/presets"
- "github.com/qor5/admin/presets/gorm2op"
- "github.com/qor5/web"
- "gorm.io/driver/postgres"
- "gorm.io/gorm"
- )
- var (
- db *gorm.DB
- pb = presets.New()
- pageModel = pb.Model(&Page{})
- widgetModel = pb.Model(&Widget{})
- )
- type (
- Page struct {
- ID uint `gorm:"primary_key"`
- VersionName string
- Title string
- Description string
- Widgets Widgets
- }
- Widgets []Widget
- Widget struct {
- Name string
- Title string
- }
- TestActivityLog struct {
- ActivityLog
- }
- TestActivityModel struct {
- ID uint `gorm:"primary_key"`
- VersionName string
- Title string
- Description string
- }
- )
- func init() {
- var err error
- db, err = gorm.Open(postgres.Open(os.Getenv("DBURL")), &gorm.Config{})
- if err != nil {
- panic(err)
- }
- if err = db.AutoMigrate(&TestActivityModel{}); err != nil {
- panic(err)
- }
- }
- func resetDB() {
- db.Exec("delete from test_activity_logs;")
- db.Exec("delete from test_activity_models;")
- }
- func TestModelKeys(t *testing.T) {
- builder := New(pb, db, &TestActivityLog{})
- builder.RegisterModel(pageModel).AddKeys("ID", "VersionName")
- resetDB()
- builder.AddCreateRecord("creator a", Page{ID: 1, VersionName: "v1", Title: "test"}, db)
- record := builder.NewLogModelData().(ActivityLogInterface)
- if err := db.First(record).Error; err != nil {
- t.Fatal(err)
- }
- if record.GetModelKeys() != "1:v1" {
- t.Errorf("want the keys %v, but got %v", "1:v1", record.GetModelKeys())
- }
- resetDB()
- builder.RegisterModel(widgetModel).AddKeys("Name")
- builder.AddCreateRecord("b", Widget{Name: "Text 01", Title: "123"}, db)
- record2 := builder.NewLogModelData().(ActivityLogInterface)
- if err := db.First(record2).Error; err != nil {
- t.Fatal(err)
- }
- if record2.GetModelKeys() != "Text 01" {
- t.Errorf("want the keys %v, but got %v", "Text 01", record2.GetModelKeys())
- }
- }
- func TestModelLink(t *testing.T) {
- builder := New(pb, db, &TestActivityLog{})
- builder.RegisterModel(pageModel).SetLink(func(v interface{}) string {
- page := v.(Page)
- return fmt.Sprintf("/admin/pages/%d?version=%s", page.ID, page.VersionName)
- })
- resetDB()
- builder.AddCreateRecord("a", Page{ID: 1, VersionName: "v1", Title: "test"}, db)
- record := builder.NewLogModelData().(ActivityLogInterface)
- if err := db.First(record).Error; err != nil {
- t.Fatal(err)
- }
- if record.GetModelLink() != "/admin/pages/1?version=v1" {
- t.Errorf("want the link %v, but got %v", "/admin/pages/1?version=v1", record.GetModelLink())
- }
- }
- func TestModelTypeHanders(t *testing.T) {
- builder := New(pb, db, &TestActivityLog{})
- builder.RegisterModel(pageModel).AddTypeHanders(Widgets{}, func(old, now interface{}, prefixField string) (diffs []Diff) {
- oldWidgets := old.(Widgets)
- nowWidgets := now.(Widgets)
- var (
- oldLen = len(oldWidgets)
- nowLen = len(nowWidgets)
- minLen int
- added bool
- deleted bool
- )
- if oldLen > nowLen {
- minLen = nowLen
- deleted = true
- }
- if oldLen < nowLen {
- minLen = oldLen
- added = true
- }
- if oldLen == nowLen {
- minLen = oldLen
- }
- for i := 0; i < minLen; i++ {
- if oldWidgets[i].Name != nowWidgets[i].Name {
- newPrefixField := fmt.Sprintf("%s.%d", prefixField, i)
- diffs = append(diffs, Diff{Field: newPrefixField, Old: oldWidgets[i].Name, Now: nowWidgets[i].Name})
- }
- }
- if added {
- for i := minLen; i < nowLen; i++ {
- newPrefixField := fmt.Sprintf("%s.%d", prefixField, i)
- diffs = append(diffs, Diff{Field: newPrefixField, Old: "", Now: nowWidgets[i].Name})
- }
- }
- if deleted {
- for i := minLen; i < oldLen; i++ {
- newPrefixField := fmt.Sprintf("%s.%d", prefixField, i)
- diffs = append(diffs, Diff{Field: newPrefixField, Old: oldWidgets[i].Name, Now: ""})
- }
- }
- return diffs
- })
- resetDB()
- builder.AddEditRecordWithOld("a",
- Page{ID: 1, VersionName: "v1", Title: "test",
- Widgets: []Widget{
- {Name: "Text 01", Title: "test1"},
- {Name: "HeroBanner 02", Title: "banner 1"},
- {Name: "Card 03", Title: "cards 1"},
- }},
- Page{ID: 1, VersionName: "v2", Title: "test1",
- Widgets: []Widget{
- {Name: "Text 011", Title: "test1"},
- {Name: "HeroBanner 022", Title: "banner 1"},
- {Name: "Card 03", Title: "cards 1"},
- {Name: "Video 03", Title: "video 1"},
- },
- }, db)
- record := builder.NewLogModelData().(ActivityLogInterface)
- if err := db.First(record).Error; err != nil {
- t.Fatal(err)
- }
- wants := `[{"Field":"VersionName","Old":"v1","Now":"v2"},{"Field":"Title","Old":"test","Now":"test1"},{"Field":"Widgets.0","Old":"Text 01","Now":"Text 011"},{"Field":"Widgets.1","Old":"HeroBanner 02","Now":"HeroBanner 022"},{"Field":"Widgets.3","Old":"","Now":"Video 03"}]`
- if record.GetModelDiffs() != wants {
- t.Errorf("want the diffs %v, but got %v", wants, record.GetModelDiffs())
- }
- }
- func TestCreator(t *testing.T) {
- builder := New(pb, db, &TestActivityLog{})
- builder.RegisterModel(pageModel)
- resetDB()
- builder.AddCreateRecord("user a", Page{ID: 1, VersionName: "v1", Title: "test"}, db)
- record := builder.NewLogModelData().(ActivityLogInterface)
- if err := db.First(record).Error; err != nil {
- t.Fatal(err)
- }
- if record.GetCreator() != "user a" {
- t.Errorf("want the creator %v, but got %v", "a", record.GetCreator())
- }
- }
- type user struct {
- }
- func (u user) GetID() uint {
- return 10
- }
- func (u user) GetName() string {
- return "user a"
- }
- func TestCreatorInferface(t *testing.T) {
- builder := New(pb, db, &TestActivityLog{})
- builder.RegisterModel(pageModel)
- resetDB()
- builder.AddCreateRecord(user{}, Page{ID: 1, VersionName: "v1", Title: "test"}, db)
- record := builder.NewLogModelData().(ActivityLogInterface)
- if err := db.First(record).Error; err != nil {
- t.Fatal(err)
- }
- if record.GetCreator() != "user a" {
- t.Errorf("want the creator %v, but got %v", "a", record.GetCreator())
- }
- if record.GetUserID() != 10 {
- t.Errorf("want the creator id %v, but got %v", 10, record.GetUserID())
- }
- }
- func TestGetActivityLogs(t *testing.T) {
- builder := New(pb, db, &TestActivityLog{})
- builder.RegisterModel(pageModel).AddKeys("ID", "VersionName")
- resetDB()
- builder.AddCreateRecord("creator a", Page{ID: 1, VersionName: "v1", Title: "test"}, db)
- builder.AddEditRecordWithOld("creator a", Page{ID: 1, VersionName: "v1", Title: "test"}, Page{ID: 1, VersionName: "v1", Title: "test1"}, db)
- builder.AddEditRecordWithOld("creator a", Page{ID: 1, VersionName: "v1", Title: "test1"}, Page{ID: 1, VersionName: "v1", Title: "test2"}, db)
- builder.AddEditRecordWithOld("creator a", Page{ID: 2, VersionName: "v1", Title: "test1"}, Page{ID: 2, VersionName: "v1", Title: "test2"}, db)
- logs := builder.GetCustomizeActivityLogs(Page{ID: 1, VersionName: "v1"}, db)
- testlogs, ok := logs.(*[]*TestActivityLog)
- if !ok {
- t.Errorf("want the logs type %v, but got %v", "*[]*TestActivityLog", reflect.TypeOf(logs))
- }
- if len(*testlogs) != 3 {
- t.Errorf("want the logs length %v, but got %v", 3, len(*testlogs))
- }
- if (*testlogs)[0].Action != "Create" || (*testlogs)[0].ModelName != "Page" || (*testlogs)[0].ModelKeys != "1:v1" || (*testlogs)[0].Creator != "creator a" {
- t.Errorf("want the logs %v, but got %+v", "Create:Page:1:v1:creator a", (*testlogs)[0])
- }
- if (*testlogs)[1].Action != "Edit" || (*testlogs)[1].ModelName != "Page" || (*testlogs)[1].ModelKeys != "1:v1" || (*testlogs)[1].Creator != "creator a" {
- t.Errorf("want the logs %v, but got %v", "Edit:Page:1:v1:creator a", (*testlogs)[1])
- }
- if (*testlogs)[2].Action != "Edit" || (*testlogs)[2].ModelName != "Page" || (*testlogs)[2].ModelKeys != "1:v1" || (*testlogs)[2].Creator != "creator a" {
- t.Errorf("want the logs %v, but got %v", "Edit:Page:1:v1:creator a", (*testlogs)[2])
- }
- }
- func TestMutliModelBuilder(t *testing.T) {
- builder := New(pb, db, &TestActivityLog{}).SetCreatorContextKey("creator")
- pb.DataOperator(gorm2op.DataOperator(db))
- pageModel2 := pb.Model(&TestActivityModel{}).URIName("page-02").Label("Page-02")
- pageModel3 := pb.Model(&TestActivityModel{}).URIName("page-03").Label("Page-03")
- builder.RegisterModel(&TestActivityModel{}).SetKeys("ID")
- builder.RegisterModel(pageModel2).SetKeys("ID").SkipDelete().AddIgnoredFields("VersionName")
- builder.RegisterModel(pageModel3).SetKeys("ID").SkipCreate().AddIgnoredFields("Description")
- data1 := &TestActivityModel{ID: 1, VersionName: "v1", Title: "test1", Description: "Description1"}
- data2 := &TestActivityModel{ID: 2, VersionName: "v2", Title: "test2", Description: "Description3"}
- data3 := &TestActivityModel{ID: 3, VersionName: "v3", Title: "test3", Description: "Description3"}
- resetDB()
- // add create record
- db.Create(data1)
- builder.AddCreateRecord("Test User", data1, db)
- pageModel2.Editing().Saver(data2, "2", &web.EventContext{R: httptest.NewRequest("POST", "/admin/page-01/2", nil).WithContext(context.WithValue(context.Background(), "creator", "Test User"))})
- pageModel3.Editing().Saver(data3, "3", &web.EventContext{R: httptest.NewRequest("POST", "/admin/page-02/3", nil).WithContext(context.WithValue(context.Background(), "creator", "Test User"))})
- {
- for _, id := range []string{"1", "2"} {
- var log TestActivityLog
- if db.Where("action = ? AND model_name = ? AND model_keys = ?", "Create", "TestActivityModel", id).Find(&log); log.ID == 0 {
- t.Errorf("want the log %v, but got %v", "TestActivityModel:"+id, log)
- }
- }
- var log TestActivityLog
- if db.Where("action = ? AND model_name = ? AND model_keys = ?", "Create", "TestActivityModel", 3).Find(&log); log.ID != 0 {
- t.Errorf("want skip the create, but still got the record %v", log)
- }
- }
- // add edit record
- data1.Title = "test1-1"
- data1.Description = "Description1-1"
- builder.AddEditRecord("Test User", data1, db)
- db.Save(data1)
- data2.Title = "test2-1"
- data2.Description = "Description2-1"
- pageModel2.Editing().Saver(data2, "2", &web.EventContext{R: httptest.NewRequest("POST", "/admin/page-01/2", nil).WithContext(context.WithValue(context.Background(), "creator", "Test User"))})
- data3.Title = "test3-1"
- data3.Description = "Description3-1"
- pageModel3.Editing().Saver(data3, "3", &web.EventContext{R: httptest.NewRequest("POST", "/admin/page-02/3", nil).WithContext(context.WithValue(context.Background(), "creator", "Test User"))})
- {
- var log1 TestActivityLog
- if db.Where("action = ? AND model_name = ? AND model_keys = ?", "Edit", "TestActivityModel", "1").Find(&log1); log1.ID == 0 {
- t.Errorf("want the log %v, but got %v", "TestActivityModel:1", log1)
- }
- if log1.GetModelDiffs() != `[{"Field":"Title","Old":"test1","Now":"test1-1"},{"Field":"Description","Old":"Description1","Now":"Description1-1"}]` {
- t.Errorf("want the log %v, but got %v", `[{"Field":"Title","Old":"test1","Now":"test1-1"},{"Field":"Description","Old":"Description1","Now":"Description1-1"}]`, log1.GetModelDiffs())
- }
- var log2 TestActivityLog
- if db.Where("action = ? AND model_name = ? AND model_keys = ?", "Edit", "TestActivityModel", "2").Find(&log2); log2.ID == 0 {
- t.Errorf("want the log %v, but got %v", "TestActivityModel:2", log2)
- }
- if log2.GetModelDiffs() != `[{"Field":"Title","Old":"test2","Now":"test2-1"},{"Field":"Description","Old":"Description3","Now":"Description2-1"}]` {
- t.Errorf("want the log %v, but got %v", `[{"Field":"Title","Old":"test2","Now":"test2-1"},{"Field":"Description","Old":"Description3","Now":"Description2-1"}]`, log1.GetModelDiffs())
- }
- if log2.ModelLabel != "page-02" {
- t.Errorf("want the log %v, but got %v", "page-02", log2.ModelLabel)
- }
- var log3 TestActivityLog
- if db.Where("action = ? AND model_name = ? AND model_keys = ?", "Edit", "TestActivityModel", "3").Find(&log3); log3.ID == 0 {
- t.Errorf("want the log %v, but got %v", "TestActivityModel:3", log3)
- }
- if log3.GetModelDiffs() != `[{"Field":"Title","Old":"test3","Now":"test3-1"}]` {
- t.Errorf("want the log %v, but got %v", `[{"Field":"Title","Old":"test3","Now":"test3-1"}]`, log1.GetModelDiffs())
- }
- if log3.ModelLabel != "page-03" {
- t.Errorf("want the log %v, but got %v", "page-03", log2.ModelLabel)
- }
- }
- // // add delete record
- builder.AddDeleteRecord("Test User", data1, db)
- db.Delete(data1)
- pageModel2.Editing().Deleter(data2, "2", &web.EventContext{R: httptest.NewRequest("POST", "/admin/page-01/2", nil).WithContext(context.WithValue(context.Background(), "creator", "Test User"))})
- pageModel3.Editing().Deleter(data3, "3", &web.EventContext{R: httptest.NewRequest("POST", "/admin/page-02/3", nil).WithContext(context.WithValue(context.Background(), "creator", "Test User"))})
- {
- for _, id := range []string{"1", "3"} {
- var log TestActivityLog
- if db.Where("action = ? AND model_name = ? AND model_keys = ?", "Delete", "TestActivityModel", id).Find(&log); log.ID == 0 {
- t.Errorf("want the log %v, but got %v", "TestActivityModel:"+id, log)
- }
- }
- var log TestActivityLog
- if db.Where("action = ? AND model_name = ? AND model_keys = ?", "Delete", "TestActivityModel", "2").Find(&log); log.ID != 0 {
- t.Errorf("want skip the create, but still got the record %v", log)
- }
- }
- }
|