From a5b51a8f76b9cc5753f7c952a1a2e8c12994d069 Mon Sep 17 00:00:00 2001
From: "Richard T. Carback III" <rick.carback@gmail.com>
Date: Sat, 24 Sep 2022 23:55:05 +0000
Subject: [PATCH] Fixed tests and implementation for indexedDB. Autoincrement
 and uuid return is working now

---
 indexedDb/implementation.go      | 58 ++++++++++++++++++++++++--------
 indexedDb/implementation_test.go | 19 ++++++++---
 indexedDb/init.go                |  5 +++
 indexedDb/model.go               |  9 ++---
 4 files changed, 69 insertions(+), 22 deletions(-)

diff --git a/indexedDb/implementation.go b/indexedDb/implementation.go
index 25da3099..b212eea7 100644
--- a/indexedDb/implementation.go
+++ b/indexedDb/implementation.go
@@ -83,7 +83,7 @@ func (w *wasmModel) JoinChannel(channel *cryptoBroadcast.Channel) {
 	}
 
 	// Perform the operation
-	_, err = store.Add(channelObj)
+	_, err = store.Put(channelObj)
 	if err != nil {
 		jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr,
 			"Unable to Add Channel: %+v", err))
@@ -260,8 +260,29 @@ func buildMessage(channelID, messageID, parentID []byte, nickname,
 	}
 }
 
+// // uuidHelper is ap rivate helper to determine an autoincremented
+// // uuid value for a given store. The way it works right now
+// // is by counting all the objects and returning count + 1, but
+// // there may be a better way to retrieve this value with the pkName
+// func (w *wasmModel) uuidHelper(pkName, storeName string) uint64 {
+// 	w.db.
+// 	// Prepare the Transaction
+// 	txn, err := w.db.Transaction(idb.TransactionReadWrite, messageStoreName)
+// 	if err != nil {
+// 		jww.
+// 		return 0, errors.Errorf("Unable to create Transaction: %+v",
+// 			err)
+// 	}
+// 	store, err := txn.ObjectStore(storeName)
+// 	if err != nil {
+// 		return 0, errors.Errorf("Unable to get ObjectStore: %+v", err)
+// 	}
+
+// }
+
 // receiveHelper is a private helper for receiving any sort of message.
-func (w *wasmModel) receiveHelper(newMessage *Message) (uint64, error) {
+func (w *wasmModel) receiveHelper(newMessage *Message) (uint64,
+	error) {
 	// Convert to jsObject
 	newMessageJson, err := json.Marshal(newMessage)
 	if err != nil {
@@ -272,6 +293,13 @@ func (w *wasmModel) receiveHelper(newMessage *Message) (uint64, error) {
 		return 0, errors.Errorf("Unable to marshal Message: %+v", err)
 	}
 
+	// NOTE: This is weird, but correct. When the "ID" field is 0, we
+	// unset it from the JSValue so that it is auto-populated and
+	// incremented
+	if newMessage.ID == 0 {
+		messageObj.JSValue().Delete("id")
+	}
+
 	// Prepare the Transaction
 	txn, err := w.db.Transaction(idb.TransactionReadWrite, messageStoreName)
 	if err != nil {
@@ -284,7 +312,7 @@ func (w *wasmModel) receiveHelper(newMessage *Message) (uint64, error) {
 	}
 
 	// Perform the upsert (put) operation
-	putReq, err := store.Put(messageObj)
+	addReq, err := store.Put(messageObj)
 	if err != nil {
 		return 0, errors.Errorf("Unable to upsert Message: %+v", err)
 	}
@@ -296,11 +324,12 @@ func (w *wasmModel) receiveHelper(newMessage *Message) (uint64, error) {
 	if err != nil {
 		return 0, errors.Errorf("Upserting Message failed: %+v", err)
 	}
-	res, _ := putReq.Result()
+	res, _ := addReq.Result()
 	uuid := uint64(res.Int())
 	jww.DEBUG.Printf(
 		"Successfully stored message from %s, id %d",
 		newMessage.Codename, uuid)
+
 	return uuid, nil
 }
 
@@ -368,16 +397,17 @@ func (w *wasmModel) dump(objectStoreName string) ([]string, error) {
 	jww.DEBUG.Printf("%s values:", objectStoreName)
 	results := make([]string, 0)
 	ctx, cancel := newContext()
-	err = cursorRequest.Iter(ctx, func(cursor *idb.CursorWithValue) error {
-		value, err := cursor.Value()
-		if err != nil {
-			return err
-		}
-		valueStr := utils.JsToJson(value)
-		results = append(results, valueStr)
-		jww.DEBUG.Printf("- %v", valueStr)
-		return nil
-	})
+	err = cursorRequest.Iter(ctx,
+		func(cursor *idb.CursorWithValue) error {
+			value, err := cursor.Value()
+			if err != nil {
+				return err
+			}
+			valueStr := utils.JsToJson(value)
+			results = append(results, valueStr)
+			jww.DEBUG.Printf("- %v", valueStr)
+			return nil
+		})
 	cancel()
 	if err != nil {
 		return nil, errors.WithMessagef(parentErr,
diff --git a/indexedDb/implementation_test.go b/indexedDb/implementation_test.go
index d8c7e255..e6479da1 100644
--- a/indexedDb/implementation_test.go
+++ b/indexedDb/implementation_test.go
@@ -11,6 +11,7 @@ package indexedDb
 
 import (
 	"encoding/json"
+	"fmt"
 	"os"
 	"testing"
 	"time"
@@ -125,21 +126,29 @@ func TestWasmModel_JoinChannel_LeaveChannel(t *testing.T) {
 
 // Test wasmModel.UpdateSentStatus happy path and ensure fields don't change.
 func TestWasmModel_UUIDTest(t *testing.T) {
-	testString := "test"
+	testString := "testHello"
 	testMsgId := channel.MakeMessageID([]byte(testString))
 	eventModel, err := newWasmModel(testString)
 	if err != nil {
 		t.Fatalf("%+v", err)
 	}
 
-	cid := channel.Identity{}
+	cid := channel.Identity{
+		Codename:       "codename123",
+		PubKey:         []byte{8, 6, 7, 5},
+		Color:          "#FFFFFF",
+		Extension:      "gif",
+		CodesetVersion: 0,
+	}
 
 	uuids := make([]uint64, 10)
 
 	for i := 0; i < 10; i++ {
 		// Store a test message
-		testMsg := buildMessage([]byte(testString), testMsgId.Bytes(),
-			nil, testString, testString, cid, time.Now(),
+		testMsg := buildMessage([]byte(testString),
+			testMsgId.Bytes(),
+			nil, testString, testString+fmt.Sprintf("%d", i), cid,
+			time.Now(),
 			time.Second, channels.Sent)
 		uuid, err := eventModel.receiveHelper(testMsg)
 		if err != nil {
@@ -148,6 +157,8 @@ func TestWasmModel_UUIDTest(t *testing.T) {
 		uuids[i] = uuid
 	}
 
+	eventModel.dump(messageStoreName)
+
 	for i := 0; i < 10; i++ {
 		for j := i + 1; j < 10; j++ {
 			if uuids[i] == uuids[j] {
diff --git a/indexedDb/init.go b/indexedDb/init.go
index 593d66c7..8b8b7b30 100644
--- a/indexedDb/init.go
+++ b/indexedDb/init.go
@@ -82,6 +82,11 @@ func v1Upgrade(db *idb.Database) error {
 	if err != nil {
 		return err
 	}
+	_, err = messageStore.CreateIndex(messageStoreMessageIndex,
+		js.ValueOf(messageStoreMessage), indexOpts)
+	if err != nil {
+		return err
+	}
 	_, err = messageStore.CreateIndex(messageStoreChannelIndex,
 		js.ValueOf(messageStoreChannel), indexOpts)
 	if err != nil {
diff --git a/indexedDb/model.go b/indexedDb/model.go
index b276557e..80dcfeae 100644
--- a/indexedDb/model.go
+++ b/indexedDb/model.go
@@ -30,6 +30,7 @@ const (
 	messageStorePubkeyIndex    = "pubkey_index"
 
 	// Message keyPath names (must match json struct tags).
+	messageStoreMessage   = "channel_id"
 	messageStoreChannel   = "channel_id"
 	messageStoreParent    = "parent_message_id"
 	messageStoreTimestamp = "timestamp"
@@ -59,10 +60,10 @@ type Message struct {
 	Text            string        `json:"text"`
 
 	// User cryptographic IDentity struct -- could be pulled out
-	Pubkey         []byte `json:"pubkey"` // Index
-	Honorific      string `json:"honorific"`
-	Adjective      string `json:"adjective"`
-	Noun           string `json:"noun"`
+	Pubkey []byte `json:"pubkey"` // Index
+	// Honorific      string `json:"honorific"`
+	// Adjective      string `json:"adjective"`
+	// Noun           string `json:"noun"`
 	Codename       string `json:"codename"`
 	Color          string `json:"color"`
 	Extension      string `json:"extension"`
-- 
GitLab