package database import ( "fmt" "testing" "time" "reichard.io/antholume/config" "reichard.io/antholume/utils" ) type databaseTest struct { *testing.T dbm *DBManager } var userID string = "testUser" var userPass string = "testPass" var deviceID string = "testDevice" var deviceName string = "testDeviceName" var documentID string = "testDocument" var documentTitle string = "testTitle" var documentAuthor string = "testAuthor" func TestNewMgr(t *testing.T) { cfg := config.Config{ DBType: "memory", } dbm := NewMgr(&cfg) if dbm == nil { t.Fatalf(`Expected: *DBManager, Got: nil`) } t.Run("Database", func(t *testing.T) { dt := databaseTest{t, dbm} dt.TestUser() dt.TestDocument() dt.TestDevice() dt.TestActivity() dt.TestDailyReadStats() }) } func (dt *databaseTest) TestUser() { dt.Run("User", func(t *testing.T) { // Generate Auth Hash rawAuthHash, err := utils.GenerateToken(64) if err != nil { t.Fatalf(`Expected: %v, Got: %v, Error: %v`, nil, err, err) } changed, err := dt.dbm.Queries.CreateUser(dt.dbm.Ctx, CreateUserParams{ ID: userID, Pass: &userPass, AuthHash: fmt.Sprintf("%x", rawAuthHash), }) if err != nil || changed != 1 { t.Fatalf(`Expected: %v, Got: %v, Error: %v`, 1, changed, err) } user, err := dt.dbm.Queries.GetUser(dt.dbm.Ctx, userID) if err != nil || *user.Pass != userPass { t.Fatalf(`Expected: %v, Got: %v, Error: %v`, userPass, *user.Pass, err) } }) } func (dt *databaseTest) TestDocument() { dt.Run("Document", func(t *testing.T) { doc, err := dt.dbm.Queries.UpsertDocument(dt.dbm.Ctx, UpsertDocumentParams{ ID: documentID, Title: &documentTitle, Author: &documentAuthor, }) if err != nil { t.Fatalf(`Expected: Document, Got: %v, Error: %v`, doc, err) } if doc.ID != documentID { t.Fatalf(`Expected: %v, Got: %v`, documentID, doc.ID) } if *doc.Title != documentTitle { t.Fatalf(`Expected: %v, Got: %v`, documentTitle, *doc.Title) } if *doc.Author != documentAuthor { t.Fatalf(`Expected: %v, Got: %v`, documentAuthor, *doc.Author) } }) } func (dt *databaseTest) TestDevice() { dt.Run("Device", func(t *testing.T) { device, err := dt.dbm.Queries.UpsertDevice(dt.dbm.Ctx, UpsertDeviceParams{ ID: deviceID, UserID: userID, DeviceName: deviceName, }) if err != nil { t.Fatalf(`Expected: Device, Got: %v, Error: %v`, device, err) } if device.ID != deviceID { t.Fatalf(`Expected: %v, Got: %v`, deviceID, device.ID) } if device.UserID != userID { t.Fatalf(`Expected: %v, Got: %v`, userID, device.UserID) } if device.DeviceName != deviceName { t.Fatalf(`Expected: %v, Got: %v`, deviceName, device.DeviceName) } }) } func (dt *databaseTest) TestActivity() { dt.Run("Progress", func(t *testing.T) { // 10 Activities, 10 Days end := time.Now() start := end.AddDate(0, 0, -9) var counter int64 = 0 for d := start; d.After(end) == false; d = d.AddDate(0, 0, 1) { counter += 1 // Add Item activity, err := dt.dbm.Queries.AddActivity(dt.dbm.Ctx, AddActivityParams{ DocumentID: documentID, DeviceID: deviceID, UserID: userID, StartTime: d.UTC().Format(time.RFC3339), Duration: 60, StartPercentage: float64(counter) / 100.0, EndPercentage: float64(counter+1) / 100.0, }) // Validate No Error if err != nil { t.Fatalf(`expected: rawactivity, got: %v, error: %v`, activity, err) } // Validate Auto Increment Working if activity.ID != counter { t.Fatalf(`Expected: %v, Got: %v`, counter, activity.ID) } } // Initiate Cache dt.dbm.CacheTempTables() // Validate Exists existsRows, err := dt.dbm.Queries.GetActivity(dt.dbm.Ctx, GetActivityParams{ UserID: userID, Offset: 0, Limit: 50, }) if err != nil { t.Fatalf(`Expected: []GetActivityRow, Got: %v, Error: %v`, existsRows, err) } if len(existsRows) != 10 { t.Fatalf(`Expected: %v, Got: %v`, 10, len(existsRows)) } // Validate Doesn't Exist doesntExistsRows, err := dt.dbm.Queries.GetActivity(dt.dbm.Ctx, GetActivityParams{ UserID: userID, DocumentID: "unknownDoc", DocFilter: true, Offset: 0, Limit: 50, }) if err != nil { t.Fatalf(`Expected: []GetActivityRow, Got: %v, Error: %v`, doesntExistsRows, err) } if len(doesntExistsRows) != 0 { t.Fatalf(`Expected: %v, Got: %v`, 0, len(doesntExistsRows)) } }) } func (dt *databaseTest) TestDailyReadStats() { dt.Run("DailyReadStats", func(t *testing.T) { readStats, err := dt.dbm.Queries.GetDailyReadStats(dt.dbm.Ctx, userID) if err != nil { t.Fatalf(`Expected: []GetDailyReadStatsRow, Got: %v, Error: %v`, readStats, err) } // Validate 30 Days Stats if len(readStats) != 30 { t.Fatalf(`Expected: %v, Got: %v`, 30, len(readStats)) } // Validate 1 Minute / Day - Last 10 Days for i := 0; i < 10; i++ { stat := readStats[i] if stat.MinutesRead != 1 { t.Fatalf(`Day: %v, Expected: %v, Got: %v`, stat.Date, 1, stat.MinutesRead) } } // Validate 0 Minute / Day - Remaining 20 Days for i := 10; i < 30; i++ { stat := readStats[i] if stat.MinutesRead != 0 { t.Fatalf(`Day: %v, Expected: %v, Got: %v`, stat.Date, 0, stat.MinutesRead) } } }) }