Skip to content

Commit

Permalink
Support automatic updates of last_viewed_at
Browse files Browse the repository at this point in the history
  • Loading branch information
brendanv committed Aug 14, 2024
1 parent 1198c9a commit 37d0679
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 1 deletion.
22 changes: 22 additions & 0 deletions backend/lynx/lynx.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package lynx

import (
"log"
"net/http"
"time"

"github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase/apis"
Expand All @@ -25,4 +27,24 @@ func InitializePocketbase(app core.App) {

return nil
})

// Automatically update last_viewed_at when links are loaded
// individually. However, let the client control this behavior
// with a header.
app.OnRecordViewRequest("links").Add(func(e *core.RecordViewEvent) error {
updateHeader := e.HttpContext.Request().Header.Get("X-Lynx-Update-Last-Viewed")
if updateHeader != "true" {
return nil
}

e.Record.Set("last_viewed_at", time.Now().UTC().Format(time.RFC3339))

err := app.Dao().SaveRecord(e.Record)
if err != nil {
log.Printf("Failed to update last_viewed_at: %v", err)
return err
}

return nil
})
}
65 changes: 65 additions & 0 deletions backend/lynx/lynx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"net/http"
"strings"
"testing"
"time"

"github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase/core"
Expand Down Expand Up @@ -68,6 +69,70 @@ func TestHandleParseURL(t *testing.T) {
}
}

func TestOnRecordViewRequest(t *testing.T) {
setupTestApp := func(t *testing.T) *tests.TestApp {
testApp, err := tests.NewTestApp(testDataDir)
if err != nil {
t.Fatal(err)
}

InitializePocketbase(testApp)

return testApp
}

scenarios := []tests.ApiScenario{
{
Name: "View link without update header",
Method: http.MethodGet,
Url: "/api/collections/links/records/8n3iq8dt6vwi4ph",
RequestHeaders: map[string]string{
"Authorization": generateRecordToken("users", "test2@example.com"),
},
ExpectedStatus: 200,
ExpectedContent: []string{"8n3iq8dt6vwi4ph"},
ExpectedEvents: map[string]int{
"OnRecordViewRequest": 1,
},
TestAppFactory: setupTestApp,
},
{
Name: "View link with update header",
Method: http.MethodGet,
Url: "/api/collections/links/records/8n3iq8dt6vwi4ph",
RequestHeaders: map[string]string{
"Authorization": generateRecordToken("users", "test2@example.com"),
"X-Lynx-Update-Last-Viewed": "true",
},
ExpectedStatus: 200,
ExpectedContent: []string{"8n3iq8dt6vwi4ph"},
ExpectedEvents: map[string]int{
"OnRecordViewRequest": 1,
"OnModelBeforeUpdate": 1,
"OnModelAfterUpdate": 1,
},
AfterTestFunc: func(t *testing.T, app *tests.TestApp, res *http.Response) {
record, err := app.Dao().FindRecordById("links", "8n3iq8dt6vwi4ph")
if err != nil {
t.Fatal(err)
}
lastViewedAt := record.GetDateTime("last_viewed_at")
if lastViewedAt.IsZero() {
t.Fatal("last_viewed_at was not updated")
}
if time.Since(lastViewedAt.Time()) > time.Minute {
t.Fatal("last_viewed_at was not updated recently")
}
},
TestAppFactory: setupTestApp,
},
}

for _, scenario := range scenarios {
scenario.Test(t)
}
}

func generateRecordToken(collectionNameOrId string, email string) string {
app, err := tests.NewTestApp(testDataDir)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion backend/test_pb_data/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Test data users:

- `test@example.com`: Basic user with no related models.
- `test@example.com`: Basic user with no related models.
- `test2@example.com`: Basic user with a single link, ID `8n3iq8dt6vwi4ph`
Binary file modified backend/test_pb_data/data.db
Binary file not shown.
Binary file modified backend/test_pb_data/logs.db
Binary file not shown.

0 comments on commit 37d0679

Please sign in to comment.