From b612d21e9d86529356f6ca62c12cf78bc4ef3391 Mon Sep 17 00:00:00 2001
From: Jono Wenger <jono@elixxir.io>
Date: Fri, 16 Dec 2022 17:30:40 +0000
Subject: [PATCH] Fix error reporting in UpdateSentStatus and make Get check if
 the result is undefined

---
 indexedDb/channels/implementation.go      |  5 ++
 indexedDb/channels/implementation_test.go |  5 ++
 indexedDb/utils.go                        |  6 ++
 indexedDb/utils_test.go                   | 80 +++++++++++++++++++++++
 4 files changed, 96 insertions(+)
 create mode 100644 indexedDb/utils_test.go

diff --git a/indexedDb/channels/implementation.go b/indexedDb/channels/implementation.go
index 721021de..f867e4b2 100644
--- a/indexedDb/channels/implementation.go
+++ b/indexedDb/channels/implementation.go
@@ -288,6 +288,8 @@ func (w *wasmModel) UpdateSentStatus(uuid uint64,
 	// Use the key to get the existing Message
 	currentMsg, err := indexedDb.Get(w.db, messageStoreName, key)
 	if err != nil {
+		jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr,
+			"Unable to get message: %+v", err))
 		return
 	}
 
@@ -295,8 +297,11 @@ func (w *wasmModel) UpdateSentStatus(uuid uint64,
 	newMessage := &Message{}
 	err = json.Unmarshal([]byte(utils.JsToJson(currentMsg)), newMessage)
 	if err != nil {
+		jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr,
+			"Could not JSON unmarshal message: %+v", err))
 		return
 	}
+
 	newMessage.Status = uint8(status)
 	if !messageID.Equals(cryptoChannel.MessageID{}) {
 		newMessage.MessageID = messageID.Bytes()
diff --git a/indexedDb/channels/implementation_test.go b/indexedDb/channels/implementation_test.go
index 6f10169e..769cc3f0 100644
--- a/indexedDb/channels/implementation_test.go
+++ b/indexedDb/channels/implementation_test.go
@@ -38,6 +38,7 @@ func dummyCallback(uint64, *id.ID, bool) {}
 
 // Happy path, insert message and look it up
 func TestWasmModel_msgIDLookup(t *testing.T) {
+	storage.GetLocalStorage().Clear()
 	testString := "test"
 	testMsgId := channel.MakeMessageID([]byte(testString), &id.ID{1})
 	eventModel, err := newWASMModel(testString, nil, dummyCallback)
@@ -64,6 +65,7 @@ func TestWasmModel_msgIDLookup(t *testing.T) {
 
 // Test wasmModel.UpdateSentStatus happy path and ensure fields don't change.
 func Test_wasmModel_UpdateSentStatus(t *testing.T) {
+	storage.GetLocalStorage().Clear()
 	testString := "test"
 	testMsgId := channel.MakeMessageID([]byte(testString), &id.ID{1})
 	eventModel, err := newWASMModel(testString, nil, dummyCallback)
@@ -158,6 +160,7 @@ func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) {
 
 // Test UUID gets returned when different messages are added.
 func Test_wasmModel_UUIDTest(t *testing.T) {
+	storage.GetLocalStorage().Clear()
 	testString := "testHello"
 	eventModel, err := newWASMModel(testString, nil, dummyCallback)
 	if err != nil {
@@ -224,6 +227,7 @@ func Test_wasmModel_DuplicateReceives(t *testing.T) {
 // Happy path: Inserts many messages, deletes some, and checks that the final
 // result is as expected.
 func Test_wasmModel_deleteMsgByChannel(t *testing.T) {
+	storage.GetLocalStorage().Clear()
 	testString := "test_deleteMsgByChannel"
 	totalMessages := 10
 	expectedMessages := 5
@@ -280,6 +284,7 @@ func Test_wasmModel_deleteMsgByChannel(t *testing.T) {
 // This test is designed to prove the behavior of unique indexes.
 // Inserts will not fail, they simply will not happen.
 func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) {
+	storage.GetLocalStorage().Clear()
 	testString := "test_receiveHelper_UniqueIndex"
 	eventModel, err := newWASMModel(testString, nil, dummyCallback)
 	if err != nil {
diff --git a/indexedDb/utils.go b/indexedDb/utils.go
index e11c8e10..1aa6ff45 100644
--- a/indexedDb/utils.go
+++ b/indexedDb/utils.go
@@ -61,6 +61,9 @@ func Get(db *idb.Database, objectStoreName string, key js.Value) (js.Value, erro
 	if err != nil {
 		return js.Undefined(), errors.WithMessagef(parentErr,
 			"Unable to get from ObjectStore: %+v", err)
+	} else if resultObj.IsUndefined() {
+		return js.Undefined(), errors.WithMessage(parentErr,
+			"Unable to get from ObjectStore: result is undefined")
 	}
 
 	// Process result into string
@@ -107,6 +110,9 @@ func GetIndex(db *idb.Database, objectStoreName string,
 	if err != nil {
 		return js.Undefined(), errors.WithMessagef(parentErr,
 			"Unable to get from ObjectStore: %+v", err)
+	} else if resultObj.IsUndefined() {
+		return js.Undefined(), errors.WithMessage(parentErr,
+			"Unable to get from ObjectStore: result is undefined")
 	}
 
 	// Process result into string
diff --git a/indexedDb/utils_test.go b/indexedDb/utils_test.go
new file mode 100644
index 00000000..1c657ebd
--- /dev/null
+++ b/indexedDb/utils_test.go
@@ -0,0 +1,80 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright © 2022 xx foundation                                             //
+//                                                                            //
+// Use of this source code is governed by a license that can be found in the  //
+// LICENSE file.                                                              //
+////////////////////////////////////////////////////////////////////////////////
+
+//go:build js && wasm
+
+package indexedDb
+
+import (
+	"github.com/hack-pad/go-indexeddb/idb"
+	"strings"
+	"syscall/js"
+	"testing"
+)
+
+// Error path: Tests that Get returns an error when trying to get a message that
+// does not exist.
+func TestGet_NoMessageError(t *testing.T) {
+	db := newTestDB("messages", "index", t)
+
+	_, err := Get(db, "messages", js.ValueOf(5))
+	if err == nil || !strings.Contains(err.Error(), "undefined") {
+		t.Errorf("Did not get expected error when getting a message that "+
+			"does not exist: %+v", err)
+	}
+}
+
+// Error path: Tests that GetIndex returns an error when trying to get a message
+// that does not exist.
+func TestGetIndex_NoMessageError(t *testing.T) {
+	db := newTestDB("messages", "index", t)
+
+	_, err := GetIndex(db, "messages", "index", js.ValueOf(5))
+	if err == nil || !strings.Contains(err.Error(), "undefined") {
+		t.Errorf("Did not get expected error when getting a message that "+
+			"does not exist: %+v", err)
+	}
+}
+
+// newTestDB creates a new idb.Database for testing.
+func newTestDB(name, index string, t *testing.T) *idb.Database {
+	// Attempt to open database object
+	ctx, cancel := NewContext()
+	defer cancel()
+	openRequest, err := idb.Global().Open(ctx, "databaseName", 0,
+		func(db *idb.Database, _ uint, _ uint) error {
+			storeOpts := idb.ObjectStoreOptions{
+				KeyPath:       js.ValueOf("id"),
+				AutoIncrement: true,
+			}
+
+			// Build Message ObjectStore and Indexes
+			messageStore, err := db.CreateObjectStore(name, storeOpts)
+			if err != nil {
+				return err
+			}
+
+			_, err = messageStore.CreateIndex(
+				index, js.ValueOf("id"), idb.IndexOptions{})
+			if err != nil {
+				return err
+			}
+
+			return nil
+		})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Wait for database open to finish
+	db, err := openRequest.Await(ctx)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	return db
+}
-- 
GitLab