abstract backend; add mock backend and testing (#57)
abstract backend; add mock backend and testing move bookmarks to backend wrapper move bookmarks to backend wrapper move bookmarks to backend wrapper working version cleanup add mock backend add nimble task & test folder add evn.sh make test run; implement bookmark method in the mock add nim unit test removing duplicated statement that was causing tests to run twice re-enable other initilizations in the status object; support specifying backend in the constructor update bookmark test update bookmark test update nimble and makefile update nimble and makefile update bookmarks test remove old browser file
This commit is contained in:
parent
bcc242a3cf
commit
5285cf7d8c
|
@ -2,3 +2,4 @@
|
|||
nimcache
|
||||
vendor/.nimble
|
||||
/bottles/
|
||||
/test_nim/build
|
||||
|
|
9
Makefile
9
Makefile
|
@ -22,7 +22,8 @@ BUILD_SYSTEM_DIR := vendor/nimbus-build-system
|
|||
status-go \
|
||||
update \
|
||||
build_ctest \
|
||||
ctest
|
||||
ctest \
|
||||
test
|
||||
|
||||
ifeq ($(NIM_PARAMS),)
|
||||
# "variables.mk" was not included, so we update the submodules.
|
||||
|
@ -64,7 +65,6 @@ else
|
|||
LIBSTATUS_EXT := so
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(detected_OS),Darwin)
|
||||
bottles/openssl:
|
||||
./scripts/fetch-brew-bottle.sh openssl
|
||||
|
@ -97,7 +97,9 @@ NIM_PARAMS += --outdir:./build
|
|||
|
||||
STATUSGO := vendor/status-go/build/bin/libstatus.$(LIBSTATUS_EXT)
|
||||
STATUSGO_LIBDIR := $(shell pwd)/$(shell dirname "$(STATUSGO)")
|
||||
export STATUSGO
|
||||
export STATUSGO_LIBDIR
|
||||
export LIBSTATUS_EXT
|
||||
|
||||
status-go: $(STATUSGO)
|
||||
$(STATUSGO): | deps
|
||||
|
@ -128,4 +130,7 @@ ctest: | build_ctest
|
|||
clean: | clean-common
|
||||
rm -rf bin/* node_modules bottles/* pkg/* tmp/* $(STATUSGO)
|
||||
|
||||
test:
|
||||
$(ENV_SCRIPT) nimble tests
|
||||
|
||||
endif # "variables.mk" was not included
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import backend_type
|
||||
|
||||
import backend_wrapper
|
||||
export backend_wrapper
|
||||
|
||||
from statusgo/types as statusgo_types import StatusGoBackend
|
||||
from mock/types as mock_types import MockBackend
|
||||
export StatusGoBackend
|
||||
export MockBackend
|
||||
|
||||
import base/bookmarks
|
||||
|
||||
import statusgo/statusgo_instance
|
||||
export newStatusGoBackendInstance
|
||||
|
||||
import mock/mock_instance
|
||||
export newMockBackendInstance
|
||||
|
||||
import statusgo/bookmark as statusgo_bookmark
|
||||
import mock/bookmark as mock_bookmark
|
||||
|
||||
from bookmarks as bookmarks_methods import storeBookmark, updateBookmark, getBookmarks, deleteBookmark
|
||||
export storeBookmark, updateBookmark, getBookmarks, deleteBookmark
|
||||
|
||||
method loadBackend*(self: BackendWrapper, name: string) =
|
||||
if name == "statusgo":
|
||||
self.backend = newStatusGoBackendInstance()
|
||||
if name == "mock":
|
||||
self.backend = newMockBackendInstance()
|
||||
else:
|
||||
raise newException(ValueError, "unknown backend")
|
|
@ -0,0 +1 @@
|
|||
type Backend* = ref object of RootObj
|
|
@ -0,0 +1,7 @@
|
|||
import backend_type
|
||||
|
||||
type BackendWrapper* = ref object
|
||||
backend*: Backend
|
||||
|
||||
proc newBackendWrapperInstance*(): BackendWrapper =
|
||||
result = BackendWrapper()
|
|
@ -0,0 +1,14 @@
|
|||
import ../../types/[bookmark]
|
||||
import ../backend_type
|
||||
|
||||
method storeBookmark*(self: Backend, bookmark: Bookmark): Bookmark =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method updateBookmark*(self: Backend, originalUrl: string, bookmark: Bookmark) =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getBookmarks*(self: Backend): seq[Bookmark] =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method deleteBookmark*(self: Backend, url: string) =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -0,0 +1,2 @@
|
|||
import bookmark
|
||||
export bookmark
|
|
@ -0,0 +1,15 @@
|
|||
import backend_type, backend_wrapper
|
||||
import base/bookmarks
|
||||
import ../types/[bookmark]
|
||||
|
||||
proc storeBookmark*(self: BackendWrapper, bookmark: Bookmark): Bookmark =
|
||||
self.backend.storeBookmark(bookmark)
|
||||
|
||||
proc updateBookmark*(self: BackendWrapper, originalUrl: string, bookmark: Bookmark) =
|
||||
self.backend.updateBookmark(originalUrl, bookmark)
|
||||
|
||||
proc getBookmarks*(self: BackendWrapper): seq[Bookmark] =
|
||||
self.backend.getBookmarks()
|
||||
|
||||
proc deleteBookmark*(self: BackendWrapper, url: string) =
|
||||
self.backend.deleteBookmark(url)
|
|
@ -0,0 +1,23 @@
|
|||
import tables, sequtils
|
||||
import types
|
||||
import ../../types/[bookmark], json, chronicles
|
||||
import ../backend_type
|
||||
|
||||
var bookmarks_storage_mock = initTable[string, Bookmark]()
|
||||
|
||||
method storeBookmark*(self: MockBackend, bookmark: Bookmark): Bookmark =
|
||||
result = bookmark
|
||||
bookmarks_storage_mock[bookmark.url] = bookmark
|
||||
|
||||
method updateBookmark*(self: MockBackend, originalUrl: string, bookmark: Bookmark) =
|
||||
bookmarks_storage_mock.del(originalUrl)
|
||||
bookmarks_storage_mock[bookmark.url] = bookmark
|
||||
|
||||
method getBookmarks*(self: MockBackend): seq[Bookmark] =
|
||||
var bookmarks: seq[Bookmark] = @[]
|
||||
for b in bookmarks_storage_mock.values:
|
||||
bookmarks.add(b)
|
||||
result = bookmarks
|
||||
|
||||
method deleteBookmark*(self: MockBackend, url: string) =
|
||||
bookmarks_storage_mock.del(url)
|
|
@ -0,0 +1,8 @@
|
|||
import types
|
||||
|
||||
proc newMockBackendInstance*(): MockBackend =
|
||||
result = MockBackend()
|
||||
|
||||
export types
|
||||
# import bookmark
|
||||
# export bookmark
|
|
@ -0,0 +1,5 @@
|
|||
import types
|
||||
|
||||
proc newMockBackendInstance*(): MockBackend =
|
||||
result = MockBackend()
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import ../backend_type
|
||||
|
||||
type MockBackend* = ref object of Backend
|
|
@ -1,6 +1,6 @@
|
|||
import json, chronicles
|
||||
import core
|
||||
import ../types/[bookmark]
|
||||
import types
|
||||
import core, ../../types/[bookmark], json, chronicles
|
||||
import ../backend_type
|
||||
|
||||
proc storeBookmark*(bookmark: Bookmark): Bookmark =
|
||||
let payload = %* [{"url": bookmark.url, "name": bookmark.name}]
|
|
@ -0,0 +1,58 @@
|
|||
import json, nimcrypto, chronicles
|
||||
import status_go, ../../status/utils
|
||||
|
||||
logScope:
|
||||
topics = "rpc"
|
||||
|
||||
proc callRPC*(inputJSON: string): string =
|
||||
return $status_go.callRPC(inputJSON)
|
||||
|
||||
proc callPrivateRPCRaw*(inputJSON: string): string =
|
||||
return $status_go.callPrivateRPC(inputJSON)
|
||||
|
||||
proc callPrivateRPC*(methodName: string, payload = %* []): string =
|
||||
try:
|
||||
let inputJSON = %* {
|
||||
"jsonrpc": "2.0",
|
||||
"method": methodName,
|
||||
"params": %payload
|
||||
}
|
||||
debug "callPrivateRPC", rpc_method=methodName
|
||||
let response = status_go.callPrivateRPC($inputJSON)
|
||||
result = $response
|
||||
if parseJSON(result).hasKey("error"):
|
||||
error "rpc response error", result, payload, methodName
|
||||
except Exception as e:
|
||||
error "error doing rpc request", methodName = methodName, exception=e.msg
|
||||
|
||||
# proc sendTransaction*(inputJSON: string, password: string): string =
|
||||
# var hashed_password = "0x" & $keccak_256.digest(password)
|
||||
# return $status_go.sendTransaction(inputJSON, hashed_password)
|
||||
|
||||
# proc startMessenger*() =
|
||||
# discard callPrivateRPC("startMessenger".prefix)
|
||||
|
||||
# proc addPeer*(peer: string) =
|
||||
# discard callPrivateRPC("admin_addPeer", %* [peer])
|
||||
|
||||
# proc removePeer*(peer: string) =
|
||||
# discard callPrivateRPC("admin_removePeer", %* [peer])
|
||||
|
||||
# proc markTrustedPeer*(peer: string) =
|
||||
# discard callPrivateRPC("markTrustedPeer".prefix(false), %* [peer])
|
||||
|
||||
# proc getBlockByNumber*(blockNumber: string): string =
|
||||
# result = callPrivateRPC("eth_getBlockByNumber", %* [blockNumber, false])
|
||||
|
||||
# proc getTransfersByAddress*(address: string, toBlock: string, limit: string, fetchMore: bool = false): string =
|
||||
# let toBlockParsed = if not fetchMore: newJNull() else: %toBlock
|
||||
# result = callPrivateRPC("wallet_getTransfersByAddress", %* [address, toBlockParsed, limit, fetchMore])
|
||||
|
||||
# proc signMessage*(rpcParams: string): string =
|
||||
# return $status_go.signMessage(rpcParams)
|
||||
|
||||
# proc signTypedData*(data: string, address: string, password: string): string =
|
||||
# return $status_go.signTypedData(data, address, password)
|
||||
|
||||
# proc getBloomFilter*(): string =
|
||||
# return $callPrivateRPC("bloomFilter".prefix, %* []).parseJSON()["result"].getStr
|
|
@ -0,0 +1,8 @@
|
|||
import types
|
||||
|
||||
proc newStatusGoBackendInstance*(): StatusGoBackend =
|
||||
result = StatusGoBackend()
|
||||
|
||||
export types
|
||||
import bookmark
|
||||
export bookmark
|
|
@ -0,0 +1,4 @@
|
|||
import types
|
||||
|
||||
proc newStatusGoBackendInstance*(): StatusGoBackend =
|
||||
result = StatusGoBackend()
|
|
@ -0,0 +1,3 @@
|
|||
import ../backend_type
|
||||
|
||||
type StatusGoBackend* = ref object of Backend
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# We use ${BASH_SOURCE[0]} instead of $0 to allow sourcing this file
|
||||
# and we fall back to a Zsh-specific special var to also support Zsh.
|
||||
REL_PATH="$(dirname ${BASH_SOURCE[0]:-${(%):-%x}})"
|
||||
ABS_PATH="$(cd ${REL_PATH}; pwd)"
|
||||
source ${ABS_PATH}/vendor/nimbus-build-system/scripts/env.sh
|
|
@ -7,3 +7,46 @@ license = "MIT"
|
|||
skipDirs = @["test"]
|
||||
|
||||
requires "nim >= 1.2.0"
|
||||
|
||||
import strutils
|
||||
|
||||
const release_opts =
|
||||
" --define:danger" &
|
||||
" --define:strip" &
|
||||
" --hints:off" &
|
||||
" --opt:size" &
|
||||
" --passC:-flto" &
|
||||
" --passL:-flto"
|
||||
|
||||
const debug_opts =
|
||||
" --debugger:native" &
|
||||
" --define:chronicles_line_numbers" &
|
||||
" --define:debug" &
|
||||
" --linetrace:on" &
|
||||
" --stacktrace:on"
|
||||
|
||||
proc buildAndRun(name: string,
|
||||
srcDir = "test_nim/",
|
||||
outDir = "test_nim/build/",
|
||||
params = "",
|
||||
cmdParams = "",
|
||||
lang = "c") =
|
||||
mkDir outDir
|
||||
exec "nim " &
|
||||
lang &
|
||||
(if getEnv("RELEASE").strip != "false": release_opts else: debug_opts) &
|
||||
" --define:ssl" &
|
||||
" --passL:" & getEnv("STATUSGO") & "" &
|
||||
# " --passL:" & "vendor/status-go/build/bin/libstatus.dylib" & "" &
|
||||
" --out:" & outDir & name &
|
||||
" " &
|
||||
srcDir & name & ".nim"
|
||||
if defined(macosx):
|
||||
exec "install_name_tool -add_rpath " & getEnv("STATUSGO_LIBDIR") & " " & outDir & name
|
||||
exec "install_name_tool -change " & "libstatus." & getEnv("LIBSTATUS_EXT") & " @rpath/libstatus." & getEnv("LIBSTATUS_EXT") & " " & outDir & name
|
||||
if getEnv("RUN_AFTER_BUILD").strip != "false":
|
||||
exec outDir & name
|
||||
|
||||
task tests, "Build and run all tests":
|
||||
rmDir "test_nim/build/"
|
||||
buildAndRun "test_all"
|
||||
|
|
|
@ -1,23 +1,28 @@
|
|||
import statusgo_backend/browser as status_browser
|
||||
# import statusgo_backend/browser as status_browser
|
||||
import ../eventemitter
|
||||
import ./types/[bookmark]
|
||||
|
||||
import ../types/[bookmark]
|
||||
|
||||
import ../backends/backend
|
||||
|
||||
type
|
||||
BrowserModel* = ref object
|
||||
events*: EventEmitter
|
||||
backend*: BackendWrapper
|
||||
|
||||
proc newBrowserModel*(events: EventEmitter): BrowserModel =
|
||||
proc newBrowserModel*(events: EventEmitter, backend: BackendWrapper): BrowserModel =
|
||||
result = BrowserModel()
|
||||
result.events = events
|
||||
result.backend = backend
|
||||
|
||||
proc storeBookmark*(self: BrowserModel, bookmark: Bookmark): Bookmark =
|
||||
return status_browser.storeBookmark(bookmark)
|
||||
return self.backend.storeBookmark(bookmark)
|
||||
|
||||
proc updateBookmark*(self: BrowserModel, originalUrl: string, bookmark: Bookmark) =
|
||||
status_browser.updateBookmark(originalUrl, bookmark)
|
||||
self.backend.updateBookmark(originalUrl, bookmark)
|
||||
|
||||
proc getBookmarks*(self: BrowserModel): seq[Bookmark] =
|
||||
result = status_browser.getBookmarks()
|
||||
result = self.backend.getBookmarks()
|
||||
|
||||
proc deleteBookmark*(self: BrowserModel, url: string) =
|
||||
status_browser.deleteBookmark(url)
|
||||
self.backend.deleteBookmark(url)
|
||||
|
|
|
@ -7,9 +7,12 @@ import ../eventemitter
|
|||
import bitops, stew/byteutils, chronicles
|
||||
import ./types/[setting]
|
||||
|
||||
import ../backends/backend
|
||||
|
||||
export chat, accounts, node, messages, contacts, profile, network, permissions, fleet, eventemitter
|
||||
|
||||
type Status* = ref object
|
||||
backend*: BackendWrapper
|
||||
events*: EventEmitter
|
||||
fleet*: FleetModel
|
||||
chat*: ChatModel
|
||||
|
@ -30,8 +33,10 @@ type Status* = ref object
|
|||
provider*: ProviderModel
|
||||
osnotifications*: OsNotifications
|
||||
|
||||
proc newStatusInstance*(fleetConfig: string): Status =
|
||||
proc newStatusInstance*(fleetConfig: string, backendName:string = "statusgo"): Status =
|
||||
result = Status()
|
||||
result.backend = newBackendWrapperInstance()
|
||||
result.backend.loadBackend(backendName)
|
||||
result.events = createEventEmitter()
|
||||
result.fleet = fleet.newFleetModel(fleetConfig)
|
||||
result.chat = chat.newChatModel(result.events)
|
||||
|
@ -48,7 +53,7 @@ proc newStatusInstance*(fleetConfig: string): Status =
|
|||
result.permissions = permissions.newPermissionsModel(result.events)
|
||||
result.settings = settings.newSettingsModel(result.events)
|
||||
result.mailservers = mailservers.newMailserversModel(result.events)
|
||||
result.browser = browser.newBrowserModel(result.events)
|
||||
result.browser = browser.newBrowserModel(result.events, result.backend)
|
||||
result.tokens = tokens.newTokensModel(result.events)
|
||||
result.provider = provider.newProviderModel(result.events, result.permissions, result.wallet)
|
||||
result.osnotifications = newOsNotifications(result.events)
|
||||
|
|
|
@ -221,6 +221,6 @@ proc onAsyncFetchCryptoServices*(self: Wallet2Model, response: string) =
|
|||
|
||||
self.events.emit("wallet2_cryptoServicesFetched", CryptoServicesArg(services: responseArray))
|
||||
|
||||
proc toggleNetwork*(self: StatusWalletController, network: Network) =
|
||||
proc toggleNetwork*(self: Wallet2Model, network: Network) =
|
||||
network.enabled = not network.enabled
|
||||
status_network.upsertNetwork(network)
|
||||
status_network.upsertNetwork(network)
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
import # std libs
|
||||
std/[json, options, os, unittest]
|
||||
|
||||
import ../status/status
|
||||
import ../status/browser
|
||||
import ../types/[bookmark]
|
||||
|
||||
suite "#Bookmarks":
|
||||
setup:
|
||||
let fleetConfig = "{\"fleets\":{\"eth.prod\":{\"boot\":{\"boot-01.ac-cn-hongkong-c.eth.prod\":\"enode://6e6554fb3034b211398fcd0f0082cbb6bd13619e1a7e76ba66e1809aaa0c5f1ac53c9ae79cf2fd4a7bacb10d12010899b370c75fed19b991d9c0cdd02891abad@47.75.99.169:443\"},\"mail\":{\"mail-01.ac-cn-hongkong-c.eth.prod\":\"enode://606ae04a71e5db868a722c77a21c8244ae38f1bd6e81687cc6cfe88a3063fa1c245692232f64f45bd5408fed5133eab8ed78049332b04f9c110eac7f71c1b429@47.75.247.214:443\"},\"rendezvous\":{\"boot-01.ac-cn-hongkong-c.eth.prod\":\"/ip4/47.75.99.169/tcp/30703/ethv4/16Uiu2HAmV8Hq9e3zm9TMVP4zrVHo3BjqW5D6bDVV6VQntQd687e4\"},\"whisper\":{\"node-01.ac-cn-hongkong-c.eth.prod\":\"enode://b957e51f41e4abab8382e1ea7229e88c6e18f34672694c6eae389eac22dab8655622bbd4a08192c321416b9becffaab11c8e2b7a5d0813b922aa128b82990dab@47.75.222.178:443\"}}},\"meta\":{\"hostname\":\"node-01.do-ams3.proxy.misc\",\"timestamp\":\"2021-09-09T00:00:14.760436\"}}";
|
||||
let statuslib_instance = newStatusInstance(fleetConfig, "mock")
|
||||
|
||||
test "storeBookmark: should store a bookmark":
|
||||
let new_bookmark = Bookmark(name: "status", url: "https://status.im")
|
||||
let returned_bookmark = statuslib_instance.browser.storeBookmark(new_bookmark)
|
||||
check(returned_bookmark.name == "status")
|
||||
check(returned_bookmark.url == "https://status.im")
|
||||
let stored_bookmarks = statuslib_instance.browser.getBookmarks()
|
||||
check(stored_bookmarks[0].name == "status")
|
||||
check(stored_bookmarks[0].url == "https://status.im")
|
||||
|
||||
test "getBookmarks: should get list of stored bookmarks":
|
||||
let new_bookmark = Bookmark(name: "status2", url: "https://status2.im")
|
||||
let returned_bookmark = statuslib_instance.browser.storeBookmark(new_bookmark)
|
||||
check(returned_bookmark.name == "status2")
|
||||
check(returned_bookmark.url == "https://status2.im")
|
||||
let stored_bookmarks = statuslib_instance.browser.getBookmarks()
|
||||
check(stored_bookmarks.len == 2)
|
||||
check(stored_bookmarks[0].name == "status")
|
||||
check(stored_bookmarks[0].url == "https://status.im")
|
||||
check(stored_bookmarks[1].name == "status2")
|
||||
check(stored_bookmarks[1].url == "https://status2.im")
|
||||
|
||||
test "deleteBookmark: should delete an existing bookmark":
|
||||
statuslib_instance.browser.deleteBookmark("https://status.im")
|
||||
|
||||
let stored_bookmarks = statuslib_instance.browser.getBookmarks()
|
||||
check(stored_bookmarks.len == 1)
|
||||
check(stored_bookmarks[0].name == "status2")
|
||||
check(stored_bookmarks[0].url == "https://status2.im")
|
||||
|
||||
test "updateBookmark: should update an existing bookmark":
|
||||
let new_bookmark = Bookmark(name: "status3", url: "https://status3.im")
|
||||
statuslib_instance.browser.updateBookmark("https://status2.im", new_bookmark)
|
||||
|
||||
let stored_bookmarks = statuslib_instance.browser.getBookmarks()
|
||||
check(stored_bookmarks.len == 1)
|
||||
check(stored_bookmarks[0].name == "status3")
|
||||
check(stored_bookmarks[0].url == "https://status3.im")
|
|
@ -0,0 +1,2 @@
|
|||
import
|
||||
./bookmarks
|
|
@ -1,7 +1,5 @@
|
|||
{.used.}
|
||||
|
||||
type Bookmark* = ref object
|
||||
name*: string
|
||||
url*: string
|
||||
imageUrl*: string
|
||||
|
Loading…
Reference in New Issue