Issue 13813 -- Use messenger ns for browser CRUD (#2801)

* Move browser CRUD to messenger ns

* Remove tests

* Create new endpoints for browsers CRUD

* Move tests to correct ns

* Lintil soup

* Fix tests

* Lint

* Bump status-go

Co-authored-by: Ibrahem Khalil <33176106+vampirekiddo@users.noreply.github.com>
This commit is contained in:
Ibrahem Khalil 2022-08-24 16:05:35 +02:00 committed by GitHub
parent 1f64bf1cfe
commit 5949ed2a44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 331 additions and 222 deletions

View File

@ -1 +1 @@
0.105.1
0.106.1

View File

@ -0,0 +1,19 @@
package protocol
import (
"context"
"github.com/status-im/status-go/services/browsers"
)
func (m *Messenger) AddBrowser(ctx context.Context, browser browsers.Browser) error {
return m.persistence.AddBrowser(browser)
}
func (m *Messenger) GetBrowsers(ctx context.Context) (browsers []*browsers.Browser, err error) {
return m.persistence.GetBrowsers()
}
func (m *Messenger) DeleteBrowser(ctx context.Context, id string) error {
return m.persistence.DeleteBrowser(id)
}

View File

@ -0,0 +1,155 @@
package protocol
import (
"context"
"crypto/ecdsa"
"sort"
"testing"
"github.com/stretchr/testify/suite"
"go.uber.org/zap"
gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/protocol/tt"
"github.com/status-im/status-go/services/browsers"
"github.com/status-im/status-go/waku"
)
func TestBrowserSuite(t *testing.T) {
suite.Run(t, new(BrowserSuite))
}
type BrowserSuite struct {
suite.Suite
m *Messenger // main instance of Messenger
privateKey *ecdsa.PrivateKey // private key for the main instance of Messenger
// If one wants to send messages between different instances of Messenger,
// a single waku service should be shared.
shh types.Waku
logger *zap.Logger
}
func (s *BrowserSuite) SetupTest() {
s.logger = tt.MustCreateTestLogger()
config := waku.DefaultConfig
config.MinimumAcceptedPoW = 0
shh := waku.New(&config, s.logger)
s.shh = gethbridge.NewGethWakuWrapper(shh)
s.Require().NoError(shh.Start())
s.m = s.newMessenger()
s.privateKey = s.m.identity
_, err := s.m.Start()
s.Require().NoError(err)
}
func (s *BrowserSuite) TearDownTest() {
s.Require().NoError(s.m.Shutdown())
}
func (s *BrowserSuite) newMessenger() *Messenger {
privateKey, err := crypto.GenerateKey()
s.Require().NoError(err)
messenger, err := newMessengerWithKey(s.shh, privateKey, s.logger, nil)
s.Require().NoError(err)
return messenger
}
func (s *MessengerBackupSuite) TestBrowsersOrderedNewestFirst() {
msngr := s.newMessenger()
testBrowsers := []*browsers.Browser{
{
ID: "1",
Name: "first",
Dapp: true,
Timestamp: 10,
},
{
ID: "2",
Name: "second",
Dapp: true,
Timestamp: 50,
},
{
ID: "3",
Name: "third",
Dapp: true,
Timestamp: 100,
HistoryIndex: 0,
History: []string{"zero"},
},
}
for i := 0; i < len(testBrowsers); i++ {
s.Require().NoError(msngr.AddBrowser(context.TODO(), *testBrowsers[i]))
}
sort.Slice(testBrowsers, func(i, j int) bool {
return testBrowsers[i].Timestamp > testBrowsers[j].Timestamp
})
rst, err := msngr.GetBrowsers(context.TODO())
s.Require().NoError(err)
s.Require().Equal(testBrowsers, rst)
}
func (s *MessengerBackupSuite) TestBrowsersHistoryIncluded() {
msngr := s.newMessenger()
browser := &browsers.Browser{
ID: "1",
Name: "first",
Dapp: true,
Timestamp: 10,
HistoryIndex: 1,
History: []string{"one", "two"},
}
s.Require().NoError(msngr.AddBrowser(context.TODO(), *browser))
rst, err := msngr.GetBrowsers(context.TODO())
s.Require().NoError(err)
s.Require().Len(rst, 1)
s.Require().Equal(browser, rst[0])
}
func (s *MessengerBackupSuite) TestBrowsersReplaceOnUpdate() {
msngr := s.newMessenger()
browser := &browsers.Browser{
ID: "1",
Name: "first",
Dapp: true,
Timestamp: 10,
History: []string{"one", "two"},
}
s.Require().NoError(msngr.AddBrowser(context.TODO(), *browser))
browser.Dapp = false
browser.History = []string{"one", "three"}
browser.Timestamp = 107
s.Require().NoError(msngr.AddBrowser(context.TODO(), *browser))
rst, err := msngr.GetBrowsers(context.TODO())
s.Require().NoError(err)
s.Require().Len(rst, 1)
s.Require().Equal(browser, rst[0])
}
func (s *MessengerBackupSuite) TestDeleteBrowser() {
msngr := s.newMessenger()
browser := &browsers.Browser{
ID: "1",
Name: "first",
Dapp: true,
Timestamp: 10,
History: []string{"one", "two"},
}
s.Require().NoError(msngr.AddBrowser(context.TODO(), *browser))
rst, err := msngr.GetBrowsers(context.TODO())
s.Require().NoError(err)
s.Require().Len(rst, 1)
s.Require().NoError(msngr.DeleteBrowser(context.TODO(), browser.ID))
rst, err = msngr.GetBrowsers(context.TODO())
s.Require().NoError(err)
s.Require().Len(rst, 0)
}

View File

@ -1176,6 +1176,87 @@ func (db *sqlitePersistence) AddBookmark(bookmark browsers.Bookmark) (browsers.B
return bookmark, err
}
func (db *sqlitePersistence) AddBrowser(browser browsers.Browser) (err error) {
tx, err := db.db.Begin()
if err != nil {
return
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
_ = tx.Rollback()
}()
insert, err := tx.Prepare("INSERT OR REPLACE INTO browsers(id, name, timestamp, dapp, historyIndex) VALUES(?, ?, ?, ?, ?)")
if err != nil {
return
}
_, err = insert.Exec(browser.ID, browser.Name, browser.Timestamp, browser.Dapp, browser.HistoryIndex)
insert.Close()
if err != nil {
return
}
if len(browser.History) == 0 {
return
}
bhInsert, err := tx.Prepare("INSERT INTO browsers_history(browser_id, history) VALUES(?, ?)")
if err != nil {
return
}
defer bhInsert.Close()
for _, history := range browser.History {
_, err = bhInsert.Exec(browser.ID, history)
if err != nil {
return
}
}
return
}
func (db *sqlitePersistence) InsertBrowser(browser browsers.Browser) (err error) {
tx, err := db.db.Begin()
if err != nil {
return
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
_ = tx.Rollback()
}()
bInsert, err := tx.Prepare("INSERT OR REPLACE INTO browsers(id, name, timestamp, dapp, historyIndex) VALUES(?, ?, ?, ?, ?)")
if err != nil {
return
}
_, err = bInsert.Exec(browser.ID, browser.Name, browser.Timestamp, browser.Dapp, browser.HistoryIndex)
bInsert.Close()
if err != nil {
return
}
if len(browser.History) == 0 {
return
}
bhInsert, err := tx.Prepare("INSERT INTO browsers_history(browser_id, history) VALUES(?, ?)")
if err != nil {
return
}
defer bhInsert.Close()
for _, history := range browser.History {
_, err = bhInsert.Exec(browser.ID, history)
if err != nil {
return
}
}
return
}
func (db *sqlitePersistence) RemoveBookmark(url string, deletedAt uint64) error {
tx, err := db.db.Begin()
if err != nil {
@ -1193,6 +1274,61 @@ func (db *sqlitePersistence) RemoveBookmark(url string, deletedAt uint64) error
return err
}
func (db *sqlitePersistence) GetBrowsers() (rst []*browsers.Browser, err error) {
tx, err := db.db.Begin()
if err != nil {
return
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
_ = tx.Rollback()
}()
// FULL and RIGHT joins are not supported
bRows, err := tx.Query("SELECT id, name, timestamp, dapp, historyIndex FROM browsers ORDER BY timestamp DESC")
if err != nil {
return
}
defer bRows.Close()
browsersArr := map[string]*browsers.Browser{}
for bRows.Next() {
browser := browsers.Browser{}
err = bRows.Scan(&browser.ID, &browser.Name, &browser.Timestamp, &browser.Dapp, &browser.HistoryIndex)
if err != nil {
return nil, err
}
browsersArr[browser.ID] = &browser
rst = append(rst, &browser)
}
bhRows, err := tx.Query("SELECT browser_id, history from browsers_history")
if err != nil {
return
}
defer bhRows.Close()
var (
id string
history string
)
for bhRows.Next() {
err = bhRows.Scan(&id, &history)
if err != nil {
return
}
browsersArr[id].History = append(browsersArr[id].History, history)
}
return rst, nil
}
func (db *sqlitePersistence) DeleteBrowser(id string) error {
_, err := db.db.Exec("DELETE from browsers WHERE id = ?", id)
return err
}
func (db *sqlitePersistence) GetBookmarkByURL(url string) (*browsers.Bookmark, error) {
bookmark := browsers.Bookmark{}
err := db.db.QueryRow(`SELECT url, name, image_url, removed, clock, deleted_at FROM bookmarks WHERE url = ?`, url).Scan(&bookmark.URL, &bookmark.Name, &bookmark.ImageURL, &bookmark.Removed, &bookmark.Clock, &bookmark.DeletedAt)

View File

@ -15,18 +15,6 @@ type API struct {
db *Database
}
func (api *API) AddBrowser(ctx context.Context, browser Browser) error {
return api.db.InsertBrowser(browser)
}
func (api *API) GetBrowsers(ctx context.Context) ([]*Browser, error) {
return api.db.GetBrowsers()
}
func (api *API) DeleteBrowser(ctx context.Context, id string) error {
return api.db.DeleteBrowser(id)
}
func (api *API) GetBookmarks(ctx context.Context) ([]*Bookmark, error) {
log.Debug("call to get bookmarks")
rst, err := api.db.GetBookmarks()

View File

@ -4,7 +4,6 @@ import (
"context"
"io/ioutil"
"os"
"sort"
"testing"
"github.com/stretchr/testify/require"
@ -28,109 +27,6 @@ func setupTestAPI(t *testing.T) (*API, func()) {
return &API{db: db}, cancel
}
func TestBrowsersOrderedNewestFirst(t *testing.T) {
api, cancel := setupTestAPI(t)
defer cancel()
browsers := []*Browser{
{
ID: "1",
Name: "first",
Dapp: true,
Timestamp: 10,
},
{
ID: "2",
Name: "second",
Dapp: true,
Timestamp: 50,
},
{
ID: "3",
Name: "third",
Dapp: true,
Timestamp: 100,
HistoryIndex: 0,
History: []string{"zero"},
},
}
for i := 0; i < len(browsers); i++ {
require.NoError(t, api.AddBrowser(context.TODO(), *browsers[i]))
}
sort.Slice(browsers, func(i, j int) bool {
return browsers[i].Timestamp > browsers[j].Timestamp
})
rst, err := api.GetBrowsers(context.TODO())
require.NoError(t, err)
require.Equal(t, browsers, rst)
}
func TestBrowsersHistoryIncluded(t *testing.T) {
api, cancel := setupTestAPI(t)
defer cancel()
browser := &Browser{
ID: "1",
Name: "first",
Dapp: true,
Timestamp: 10,
HistoryIndex: 1,
History: []string{"one", "two"},
}
require.NoError(t, api.AddBrowser(context.TODO(), *browser))
rst, err := api.GetBrowsers(context.TODO())
require.NoError(t, err)
require.Len(t, rst, 1)
require.Equal(t, browser, rst[0])
}
func TestBrowsersReplaceOnUpdate(t *testing.T) {
api, cancel := setupTestAPI(t)
defer cancel()
browser := &Browser{
ID: "1",
Name: "first",
Dapp: true,
Timestamp: 10,
History: []string{"one", "two"},
}
require.NoError(t, api.AddBrowser(context.TODO(), *browser))
browser.Dapp = false
browser.History = []string{"one", "three"}
browser.Timestamp = 107
require.NoError(t, api.AddBrowser(context.TODO(), *browser))
rst, err := api.GetBrowsers(context.TODO())
require.NoError(t, err)
require.Len(t, rst, 1)
require.Equal(t, browser, rst[0])
}
func TestDeleteBrowser(t *testing.T) {
api, cancel := setupTestAPI(t)
defer cancel()
browser := &Browser{
ID: "1",
Name: "first",
Dapp: true,
Timestamp: 10,
History: []string{"one", "two"},
}
require.NoError(t, api.AddBrowser(context.TODO(), *browser))
rst, err := api.GetBrowsers(context.TODO())
require.NoError(t, err)
require.Len(t, rst, 1)
require.NoError(t, api.DeleteBrowser(context.TODO(), browser.ID))
rst, err = api.GetBrowsers(context.TODO())
require.NoError(t, err)
require.Len(t, rst, 0)
}
func TestBookmarks(t *testing.T) {
api, cancel := setupTestAPI(t)
defer cancel()

View File

@ -23,111 +23,6 @@ func NewDB(db *sql.DB) *Database {
return &Database{db: db}
}
type Browser struct {
ID string `json:"browser-id"`
Name string `json:"name"`
Timestamp uint64 `json:"timestamp"`
Dapp bool `json:"dapp?"`
HistoryIndex int `json:"history-index"`
History []string `json:"history,omitempty"`
}
func (db *Database) InsertBrowser(browser Browser) (err error) {
tx, err := db.db.Begin()
if err != nil {
return
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
_ = tx.Rollback()
}()
bInsert, err := tx.Prepare("INSERT OR REPLACE INTO browsers(id, name, timestamp, dapp, historyIndex) VALUES(?, ?, ?, ?, ?)")
if err != nil {
return
}
_, err = bInsert.Exec(browser.ID, browser.Name, browser.Timestamp, browser.Dapp, browser.HistoryIndex)
bInsert.Close()
if err != nil {
return
}
if len(browser.History) == 0 {
return
}
bhInsert, err := tx.Prepare("INSERT INTO browsers_history(browser_id, history) VALUES(?, ?)")
if err != nil {
return
}
defer bhInsert.Close()
for _, history := range browser.History {
_, err = bhInsert.Exec(browser.ID, history)
if err != nil {
return
}
}
return
}
func (db *Database) GetBrowsers() (rst []*Browser, err error) {
tx, err := db.db.Begin()
if err != nil {
return
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
_ = tx.Rollback()
}()
// FULL and RIGHT joins are not supported
bRows, err := tx.Query("SELECT id, name, timestamp, dapp, historyIndex FROM browsers ORDER BY timestamp DESC")
if err != nil {
return
}
defer bRows.Close()
browsers := map[string]*Browser{}
for bRows.Next() {
browser := Browser{}
err = bRows.Scan(&browser.ID, &browser.Name, &browser.Timestamp, &browser.Dapp, &browser.HistoryIndex)
if err != nil {
return nil, err
}
browsers[browser.ID] = &browser
rst = append(rst, &browser)
}
bhRows, err := tx.Query("SELECT browser_id, history from browsers_history")
if err != nil {
return
}
defer bhRows.Close()
var (
id string
history string
)
for bhRows.Next() {
err = bhRows.Scan(&id, &history)
if err != nil {
return
}
browsers[id].History = append(browsers[id].History, history)
}
return rst, nil
}
func (db *Database) DeleteBrowser(id string) error {
_, err := db.db.Exec("DELETE from browsers WHERE id = ?", id)
return err
}
type BookmarksType string
type Bookmark struct {
@ -138,6 +33,14 @@ type Bookmark struct {
Clock uint64 `json:"-"` //used to sync
DeletedAt uint64 `json:"deletedAt,omitempty"`
}
type Browser struct {
ID string `json:"browser-id"`
Name string `json:"name"`
Timestamp uint64 `json:"timestamp"`
Dapp bool `json:"dapp?"`
HistoryIndex int `json:"history-index"`
History []string `json:"history,omitempty"`
}
func (db *Database) GetBookmarks() ([]*Bookmark, error) {
rows, err := db.db.Query(`SELECT url, name, image_url, removed, deleted_at FROM bookmarks`)

View File

@ -813,6 +813,18 @@ func (api *PublicAPI) AddBookmark(ctx context.Context, bookmark browsers.Bookmar
return api.service.messenger.AddBookmark(ctx, bookmark)
}
func (api *PublicAPI) AddBrowser(ctx context.Context, browser browsers.Browser) error {
return api.service.messenger.AddBrowser(ctx, browser)
}
func (api *PublicAPI) GetBrowsers(ctx context.Context) (browsers []*browsers.Browser, err error) {
return api.service.messenger.GetBrowsers(ctx)
}
func (api *PublicAPI) DeleteBrowser(ctx context.Context, id string) error {
return api.service.messenger.DeleteBrowser(ctx, id)
}
func (api *PublicAPI) RemoveBookmark(ctx context.Context, url string) error {
return api.service.messenger.RemoveBookmark(ctx, url)
}