mirror of
https://github.com/dnote/dnote
synced 2026-03-14 22:45:50 +01:00
3867 lines
189 KiB
Go
3867 lines
189 KiB
Go
/* Copyright (C) 2019, 2020, 2021, 2022, 2023, 2024, 2025 Dnote contributors
|
|
*
|
|
* This file is part of Dnote.
|
|
*
|
|
* Dnote is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Dnote is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/dnote/dnote/pkg/assert"
|
|
"github.com/dnote/dnote/pkg/cli/consts"
|
|
"github.com/dnote/dnote/pkg/cli/context"
|
|
cliDatabase "github.com/dnote/dnote/pkg/cli/database"
|
|
clitest "github.com/dnote/dnote/pkg/cli/testutils"
|
|
"github.com/dnote/dnote/pkg/clock"
|
|
"github.com/dnote/dnote/pkg/server/app"
|
|
"github.com/dnote/dnote/pkg/server/config"
|
|
"github.com/dnote/dnote/pkg/server/controllers"
|
|
"github.com/dnote/dnote/pkg/server/database"
|
|
"github.com/dnote/dnote/pkg/server/mailer"
|
|
apitest "github.com/dnote/dnote/pkg/server/testutils"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
var cliBinaryName string
|
|
var server *httptest.Server
|
|
var serverTime = time.Date(2017, time.March, 14, 21, 15, 0, 0, time.UTC)
|
|
|
|
var tmpDirPath string
|
|
var dnoteCmdOpts clitest.RunDnoteCmdOptions
|
|
var paths context.Paths
|
|
|
|
var testDir = "./tmp/.dnote"
|
|
|
|
func init() {
|
|
tmpDirPath = fmt.Sprintf("%s/tmp", testDir)
|
|
cliBinaryName = fmt.Sprintf("%s/test/cli/test-cli", testDir)
|
|
dnoteCmdOpts = clitest.RunDnoteCmdOptions{
|
|
Env: []string{
|
|
fmt.Sprintf("XDG_CONFIG_HOME=%s", tmpDirPath),
|
|
fmt.Sprintf("XDG_DATA_HOME=%s", tmpDirPath),
|
|
fmt.Sprintf("XDG_CACHE_HOME=%s", tmpDirPath),
|
|
},
|
|
}
|
|
|
|
paths = context.Paths{
|
|
Data: tmpDirPath,
|
|
Cache: tmpDirPath,
|
|
Config: tmpDirPath,
|
|
}
|
|
}
|
|
|
|
func clearTmp(t *testing.T) {
|
|
if err := os.RemoveAll(tmpDirPath); err != nil {
|
|
t.Fatal("cleaning tmp dir")
|
|
}
|
|
}
|
|
|
|
func TestMain(m *testing.M) {
|
|
// Set up server database
|
|
apitest.InitTestDB()
|
|
|
|
mockClock := clock.NewMock()
|
|
mockClock.SetNow(serverTime)
|
|
|
|
var err error
|
|
server, err = controllers.NewServer(&app.App{
|
|
Clock: mockClock,
|
|
EmailTemplates: mailer.Templates{},
|
|
EmailBackend: &apitest.MockEmailbackendImplementation{},
|
|
DB: apitest.DB,
|
|
Config: config.Config{
|
|
WebURL: os.Getenv("WebURL"),
|
|
},
|
|
})
|
|
if err != nil {
|
|
panic(errors.Wrap(err, "initializing router"))
|
|
}
|
|
|
|
defer server.Close()
|
|
|
|
// Build binaries
|
|
apiEndpoint := fmt.Sprintf("%s/api", server.URL)
|
|
ldflags := fmt.Sprintf("-X main.apiEndpoint=%s", apiEndpoint)
|
|
|
|
cmd := exec.Command("go", "build", "--tags", "fts5", "-o", cliBinaryName, "-ldflags", ldflags, "github.com/dnote/dnote/pkg/cli")
|
|
|
|
var stderr bytes.Buffer
|
|
cmd.Stderr = &stderr
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
log.Print(errors.Wrap(err, "building a CLI binary").Error())
|
|
log.Print(stderr.String())
|
|
os.Exit(1)
|
|
}
|
|
|
|
os.Exit(m.Run())
|
|
}
|
|
|
|
// helpers
|
|
func setupUser(t *testing.T, ctx *context.DnoteCtx) database.User {
|
|
user := apitest.SetupUserData()
|
|
apitest.SetupAccountData(user, "alice@example.com", "pass1234")
|
|
|
|
// log in the user in CLI
|
|
session := apitest.SetupSession(t, user)
|
|
cliDatabase.MustExec(t, "inserting session_key", ctx.DB, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemSessionKey, session.Key)
|
|
cliDatabase.MustExec(t, "inserting session_key_expiry", ctx.DB, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemSessionKeyExpiry, session.ExpiresAt.Unix())
|
|
|
|
return user
|
|
}
|
|
|
|
func apiCreateBook(t *testing.T, user database.User, name, message string) string {
|
|
res := doHTTPReq(t, "POST", "/v3/books", fmt.Sprintf(`{"name": "%s"}`, name), message, user)
|
|
|
|
var resp controllers.CreateBookResp
|
|
if err := json.NewDecoder(res.Body).Decode(&resp); err != nil {
|
|
t.Fatal(errors.Wrap(err, "decoding payload for adding book"))
|
|
return ""
|
|
}
|
|
|
|
return resp.Book.UUID
|
|
}
|
|
|
|
func apiPatchBook(t *testing.T, user database.User, uuid, payload, message string) {
|
|
doHTTPReq(t, "PATCH", fmt.Sprintf("/v3/books/%s", uuid), payload, message, user)
|
|
}
|
|
|
|
func apiDeleteBook(t *testing.T, user database.User, uuid, message string) {
|
|
doHTTPReq(t, "DELETE", fmt.Sprintf("/v3/books/%s", uuid), "", message, user)
|
|
}
|
|
|
|
func apiCreateNote(t *testing.T, user database.User, bookUUID, body, message string) string {
|
|
res := doHTTPReq(t, "POST", "/v3/notes", fmt.Sprintf(`{"book_uuid": "%s", "content": "%s"}`, bookUUID, body), message, user)
|
|
|
|
var resp controllers.CreateNoteResp
|
|
if err := json.NewDecoder(res.Body).Decode(&resp); err != nil {
|
|
t.Fatal(errors.Wrap(err, "decoding payload for adding note"))
|
|
return ""
|
|
}
|
|
|
|
return resp.Result.UUID
|
|
}
|
|
|
|
func apiPatchNote(t *testing.T, user database.User, noteUUID, payload, message string) {
|
|
doHTTPReq(t, "PATCH", fmt.Sprintf("/v3/notes/%s", noteUUID), payload, message, user)
|
|
}
|
|
|
|
func apiDeleteNote(t *testing.T, user database.User, noteUUID, message string) {
|
|
doHTTPReq(t, "DELETE", fmt.Sprintf("/v3/notes/%s", noteUUID), "", message, user)
|
|
}
|
|
|
|
func doHTTPReq(t *testing.T, method, path, payload, message string, user database.User) *http.Response {
|
|
apiEndpoint := fmt.Sprintf("%s/api", server.URL)
|
|
endpoint := fmt.Sprintf("%s%s", apiEndpoint, path)
|
|
|
|
req, err := http.NewRequest(method, endpoint, strings.NewReader(payload))
|
|
if err != nil {
|
|
panic(errors.Wrap(err, "constructing http request"))
|
|
}
|
|
|
|
res := apitest.HTTPAuthDo(t, req, user)
|
|
if res.StatusCode >= 400 {
|
|
bs, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
panic(errors.Wrap(err, "parsing response body for error"))
|
|
}
|
|
|
|
t.Errorf("%s. HTTP status %d. Message: %s", message, res.StatusCode, string(bs))
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
type setupFunc func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string
|
|
type assertFunc func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string)
|
|
|
|
func testSyncCmd(t *testing.T, fullSync bool, setup setupFunc, assert assertFunc) {
|
|
// clean up
|
|
apitest.ClearData(apitest.DB)
|
|
defer apitest.ClearData(apitest.DB)
|
|
|
|
clearTmp(t)
|
|
|
|
ctx := context.InitTestCtx(t, paths, nil)
|
|
defer context.TeardownTestCtx(t, ctx)
|
|
|
|
user := setupUser(t, &ctx)
|
|
ids := setup(t, ctx, user)
|
|
|
|
if fullSync {
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync", "-f")
|
|
} else {
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
}
|
|
|
|
assert(t, ctx, user, ids)
|
|
}
|
|
|
|
type systemState struct {
|
|
clientNoteCount int
|
|
clientBookCount int
|
|
clientLastMaxUSN int
|
|
clientLastSyncAt int64
|
|
serverNoteCount int64
|
|
serverBookCount int64
|
|
serverUserMaxUSN int
|
|
}
|
|
|
|
// checkState compares the state of the client and the server with the given system state
|
|
func checkState(t *testing.T, ctx context.DnoteCtx, user database.User, expected systemState) {
|
|
serverDB := apitest.DB
|
|
clientDB := ctx.DB
|
|
|
|
var clientBookCount, clientNoteCount int
|
|
cliDatabase.MustScan(t, "counting client notes", clientDB.QueryRow("SELECT count(*) FROM notes"), &clientNoteCount)
|
|
cliDatabase.MustScan(t, "counting client books", clientDB.QueryRow("SELECT count(*) FROM books"), &clientBookCount)
|
|
assert.Equal(t, clientNoteCount, expected.clientNoteCount, "client note count mismatch")
|
|
assert.Equal(t, clientBookCount, expected.clientBookCount, "client book count mismatch")
|
|
|
|
var clientLastMaxUSN int
|
|
var clientLastSyncAt int64
|
|
cliDatabase.MustScan(t, "finding system last_max_usn", clientDB.QueryRow("SELECT value FROM system WHERE key = ?", consts.SystemLastMaxUSN), &clientLastMaxUSN)
|
|
cliDatabase.MustScan(t, "finding system last_sync_at", clientDB.QueryRow("SELECT value FROM system WHERE key = ?", consts.SystemLastSyncAt), &clientLastSyncAt)
|
|
assert.Equal(t, clientLastMaxUSN, expected.clientLastMaxUSN, "client last_max_usn mismatch")
|
|
assert.Equal(t, clientLastSyncAt, expected.clientLastSyncAt, "client last_sync_at mismatch")
|
|
|
|
var serverBookCount, serverNoteCount int64
|
|
apitest.MustExec(t, serverDB.Model(&database.Note{}).Count(&serverNoteCount), "counting server notes")
|
|
apitest.MustExec(t, serverDB.Model(&database.Book{}).Count(&serverBookCount), "counting api notes")
|
|
assert.Equal(t, serverNoteCount, expected.serverNoteCount, "server note count mismatch")
|
|
assert.Equal(t, serverBookCount, expected.serverBookCount, "server book count mismatch")
|
|
var serverUser database.User
|
|
apitest.MustExec(t, serverDB.Where("id = ?", user.ID).First(&serverUser), "finding user")
|
|
assert.Equal(t, serverUser.MaxUSN, expected.serverUserMaxUSN, "user max_usn mismatch")
|
|
}
|
|
|
|
// tests
|
|
func TestSync_Empty(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
return map[string]string{}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
// Test
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 0,
|
|
clientBookCount: 0,
|
|
clientLastMaxUSN: 0,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 0,
|
|
serverBookCount: 0,
|
|
serverUserMaxUSN: 0,
|
|
})
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
}
|
|
|
|
func TestSync_oneway(t *testing.T) {
|
|
t.Run("cli to api only", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) {
|
|
apiDB := apitest.DB
|
|
apitest.MustExec(t, apiDB.Model(&user).Update("max_usn", 0), "updating user max_usn")
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js1")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "css", "-c", "css1")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js2")
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User) {
|
|
apiDB := apitest.DB
|
|
cliDB := ctx.DB
|
|
|
|
// test client
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 3,
|
|
clientBookCount: 2,
|
|
clientLastMaxUSN: 5,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 3,
|
|
serverBookCount: 2,
|
|
serverUserMaxUSN: 5,
|
|
})
|
|
|
|
var cliBookJS, cliBookCSS cliDatabase.Book
|
|
var cliNote1JS, cliNote2JS, cliNote1CSS cliDatabase.Note
|
|
cliDatabase.MustScan(t, "finding cli book js", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cli book css", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css"), &cliBookCSS.UUID, &cliBookCSS.Label, &cliBookCSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js1"), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote2JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js2"), &cliNote2JS.UUID, &cliNote2JS.Body, &cliNote2JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1CSS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "css1"), &cliNote1CSS.UUID, &cliNote1CSS.Body, &cliNote1CSS.USN)
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
assert.NotEqual(t, cliNote2JS.USN, 0, "cliNote2JS USN mismatch")
|
|
assert.NotEqual(t, cliNote1CSS.USN, 0, "cliNote1CSS USN mismatch")
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
assert.NotEqual(t, cliBookCSS.USN, 0, "cliBookCSS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote2JS.Body, "js2", "cliNote2JS Body mismatch")
|
|
assert.Equal(t, cliNote1CSS.Body, "css1", "cliNote1CSS Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookCSS.Label, "css", "cliBookCSS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliNote2JS.Deleted, false, "cliNote2JS Deleted mismatch")
|
|
assert.Equal(t, cliNote1CSS.Deleted, false, "cliNote1CSS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS.Deleted, false, "cliBookCSS Deleted mismatch")
|
|
|
|
// test server
|
|
var apiBookJS, apiBookCSS database.Book
|
|
var apiNote1JS, apiNote2JS, apiNote1CSS database.Note
|
|
apitest.MustExec(t, apiDB.Model(&database.Note{}).Where("uuid = ?", cliNote1JS.UUID).First(&apiNote1JS), "getting js1 note")
|
|
apitest.MustExec(t, apiDB.Model(&database.Note{}).Where("uuid = ?", cliNote2JS.UUID).First(&apiNote2JS), "getting js2 note")
|
|
apitest.MustExec(t, apiDB.Model(&database.Note{}).Where("uuid = ?", cliNote1CSS.UUID).First(&apiNote1CSS), "getting css1 note")
|
|
apitest.MustExec(t, apiDB.Model(&database.Book{}).Where("uuid = ?", cliBookJS.UUID).First(&apiBookJS), "getting js book")
|
|
apitest.MustExec(t, apiDB.Model(&database.Book{}).Where("uuid = ?", cliBookCSS.UUID).First(&apiBookCSS), "getting css book")
|
|
|
|
// assert usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS usn mismatch")
|
|
assert.NotEqual(t, apiNote2JS.USN, 0, "apiNote2JS usn mismatch")
|
|
assert.NotEqual(t, apiNote1CSS.USN, 0, "apiNote1CSS usn mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS usn mismatch")
|
|
assert.NotEqual(t, apiBookCSS.USN, 0, "apiBookCSS usn mismatch")
|
|
// client must have generated uuids
|
|
assert.NotEqual(t, apiNote1JS.UUID, "", "apiNote1JS UUID mismatch")
|
|
assert.NotEqual(t, apiNote2JS.UUID, "", "apiNote2JS UUID mismatch")
|
|
assert.NotEqual(t, apiNote1CSS.UUID, "", "apiNote1CSS UUID mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiNote2JS.Deleted, false, "apiNote2JS Deleted mismatch")
|
|
assert.Equal(t, apiNote1CSS.Deleted, false, "apiNote1CSS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS.Deleted, false, "apiBookCSS Deleted mismatch")
|
|
// assert on body and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote2JS.Body, "js2", "apiNote2JS Body mismatch")
|
|
assert.Equal(t, apiNote1CSS.Body, "css1", "apiNote1CSS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "css", "apiBookCSS Label mismatch")
|
|
}
|
|
|
|
t.Run("stepSync", func(t *testing.T) {
|
|
clearTmp(t)
|
|
defer apitest.ClearData(apitest.DB)
|
|
|
|
ctx := context.InitTestCtx(t, paths, nil)
|
|
defer context.TeardownTestCtx(t, ctx)
|
|
user := setupUser(t, &ctx)
|
|
setup(t, ctx, user)
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
assert(t, ctx, user)
|
|
})
|
|
|
|
t.Run("fullSync", func(t *testing.T) {
|
|
clearTmp(t)
|
|
defer apitest.ClearData(apitest.DB)
|
|
|
|
ctx := context.InitTestCtx(t, paths, nil)
|
|
defer context.TeardownTestCtx(t, ctx)
|
|
user := setupUser(t, &ctx)
|
|
setup(t, ctx, user)
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync", "-f")
|
|
|
|
assert(t, ctx, user)
|
|
})
|
|
})
|
|
|
|
t.Run("cli to api with edit and delete", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) {
|
|
apiDB := apitest.DB
|
|
apitest.MustExec(t, apiDB.Model(&user).Update("max_usn", 0), "updating user max_usn")
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js1")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "css", "-c", "css1")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js2")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js3")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "css", "-c", "css2")
|
|
|
|
var nid, nid2 string
|
|
cliDB := ctx.DB
|
|
cliDatabase.MustScan(t, "getting id of note to edit", cliDB.QueryRow("SELECT rowid FROM notes WHERE body = ?", "js3"), &nid)
|
|
cliDatabase.MustScan(t, "getting id of note to delete", cliDB.QueryRow("SELECT rowid FROM notes WHERE body = ?", "css2"), &nid2)
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "js", nid, "-c", "js3-edited")
|
|
clitest.WaitDnoteCmd(t, dnoteCmdOpts, clitest.UserConfirm, cliBinaryName, "remove", "css", nid2)
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "css", "-c", "css3")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "css", "-c", "css4")
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 6,
|
|
clientBookCount: 2,
|
|
clientLastMaxUSN: 8,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 6,
|
|
serverBookCount: 2,
|
|
serverUserMaxUSN: 8,
|
|
})
|
|
|
|
// test cli
|
|
var cliN1, cliN2, cliN3, cliN4, cliN5, cliN6 cliDatabase.Note
|
|
var cliB1, cliB2 cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliN1", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js1"), &cliN1.UUID, &cliN1.Body, &cliN1.USN)
|
|
cliDatabase.MustScan(t, "finding cliN2", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js2"), &cliN2.UUID, &cliN2.Body, &cliN2.USN)
|
|
cliDatabase.MustScan(t, "finding cliN3", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js3-edited"), &cliN3.UUID, &cliN3.Body, &cliN3.USN)
|
|
cliDatabase.MustScan(t, "finding cliN4", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "css1"), &cliN4.UUID, &cliN4.Body, &cliN4.USN)
|
|
cliDatabase.MustScan(t, "finding cliN5", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "css3"), &cliN5.UUID, &cliN5.Body, &cliN5.USN)
|
|
cliDatabase.MustScan(t, "finding cliN6", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "css4"), &cliN6.UUID, &cliN6.Body, &cliN6.USN)
|
|
cliDatabase.MustScan(t, "finding cliB1", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliB1.UUID, &cliB1.Label, &cliB1.USN)
|
|
cliDatabase.MustScan(t, "finding cliB2", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css"), &cliB2.UUID, &cliB2.Label, &cliB2.USN)
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, cliN1.USN, 0, "cliN1 USN mismatch")
|
|
assert.NotEqual(t, cliN2.USN, 0, "cliN2 USN mismatch")
|
|
assert.NotEqual(t, cliN3.USN, 0, "cliN3 USN mismatch")
|
|
assert.NotEqual(t, cliN4.USN, 0, "cliN4 USN mismatch")
|
|
assert.NotEqual(t, cliN5.USN, 0, "cliN5 USN mismatch")
|
|
assert.NotEqual(t, cliN6.USN, 0, "cliN6 USN mismatch")
|
|
assert.NotEqual(t, cliB1.USN, 0, "cliB1 USN mismatch")
|
|
assert.NotEqual(t, cliB2.USN, 0, "cliB2 USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliN1.Body, "js1", "cliN1 Body mismatch")
|
|
assert.Equal(t, cliN2.Body, "js2", "cliN2 Body mismatch")
|
|
assert.Equal(t, cliN3.Body, "js3-edited", "cliN3 Body mismatch")
|
|
assert.Equal(t, cliN4.Body, "css1", "cliN4 Body mismatch")
|
|
assert.Equal(t, cliN5.Body, "css3", "cliN5 Body mismatch")
|
|
assert.Equal(t, cliN6.Body, "css4", "cliN6 Body mismatch")
|
|
assert.Equal(t, cliB1.Label, "js", "cliB1 Label mismatch")
|
|
assert.Equal(t, cliB2.Label, "css", "cliB2 Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliN1.Deleted, false, "cliN1 Deleted mismatch")
|
|
assert.Equal(t, cliN2.Deleted, false, "cliN2 Deleted mismatch")
|
|
assert.Equal(t, cliN3.Deleted, false, "cliN3 Deleted mismatch")
|
|
assert.Equal(t, cliN4.Deleted, false, "cliN4 Deleted mismatch")
|
|
assert.Equal(t, cliN5.Deleted, false, "cliN5 Deleted mismatch")
|
|
assert.Equal(t, cliN6.Deleted, false, "cliN6 Deleted mismatch")
|
|
assert.Equal(t, cliB1.Deleted, false, "cliB1 Deleted mismatch")
|
|
assert.Equal(t, cliB2.Deleted, false, "cliB2 Deleted mismatch")
|
|
|
|
// test api
|
|
var apiN1, apiN2, apiN3, apiN4, apiN5, apiN6 database.Note
|
|
var apiB1, apiB2 database.Book
|
|
apitest.MustExec(t, apiDB.Where("uuid = ?", cliN1.UUID).First(&apiN1), "finding apiN1")
|
|
apitest.MustExec(t, apiDB.Where("uuid = ?", cliN2.UUID).First(&apiN2), "finding apiN2")
|
|
apitest.MustExec(t, apiDB.Where("uuid = ?", cliN3.UUID).First(&apiN3), "finding apiN3")
|
|
apitest.MustExec(t, apiDB.Where("uuid = ?", cliN4.UUID).First(&apiN4), "finding apiN4")
|
|
apitest.MustExec(t, apiDB.Where("uuid = ?", cliN5.UUID).First(&apiN5), "finding apiN5")
|
|
apitest.MustExec(t, apiDB.Where("uuid = ?", cliN6.UUID).First(&apiN6), "finding apiN6")
|
|
apitest.MustExec(t, apiDB.Where("uuid = ?", cliB1.UUID).First(&apiB1), "finding apiB1")
|
|
apitest.MustExec(t, apiDB.Where("uuid = ?", cliB2.UUID).First(&apiB2), "finding apiB2")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiN1.USN, 0, "apiN1 usn mismatch")
|
|
assert.NotEqual(t, apiN2.USN, 0, "apiN2 usn mismatch")
|
|
assert.NotEqual(t, apiN3.USN, 0, "apiN3 usn mismatch")
|
|
assert.NotEqual(t, apiN4.USN, 0, "apiN4 usn mismatch")
|
|
assert.NotEqual(t, apiN5.USN, 0, "apiN5 usn mismatch")
|
|
assert.NotEqual(t, apiN6.USN, 0, "apiN6 usn mismatch")
|
|
assert.NotEqual(t, apiB1.USN, 0, "apiB1 usn mismatch")
|
|
assert.NotEqual(t, apiB2.USN, 0, "apiB2 usn mismatch")
|
|
// client must have generated uuids
|
|
assert.NotEqual(t, apiN1.UUID, "", "apiN1 UUID mismatch")
|
|
assert.NotEqual(t, apiN2.UUID, "", "apiN2 UUID mismatch")
|
|
assert.NotEqual(t, apiN3.UUID, "", "apiN3 UUID mismatch")
|
|
assert.NotEqual(t, apiN4.UUID, "", "apiN4 UUID mismatch")
|
|
assert.NotEqual(t, apiN5.UUID, "", "apiN5 UUID mismatch")
|
|
assert.NotEqual(t, apiN6.UUID, "", "apiN6 UUID mismatch")
|
|
assert.NotEqual(t, apiB1.UUID, "", "apiB1 UUID mismatch")
|
|
assert.NotEqual(t, apiB2.UUID, "", "apiB2 UUID mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiN1.Deleted, false, "apiN1 Deleted mismatch")
|
|
assert.Equal(t, apiN2.Deleted, false, "apiN2 Deleted mismatch")
|
|
assert.Equal(t, apiN3.Deleted, false, "apiN3 Deleted mismatch")
|
|
assert.Equal(t, apiN4.Deleted, false, "apiN4 Deleted mismatch")
|
|
assert.Equal(t, apiN5.Deleted, false, "apiN5 Deleted mismatch")
|
|
assert.Equal(t, apiN6.Deleted, false, "apiN6 Deleted mismatch")
|
|
assert.Equal(t, apiB1.Deleted, false, "apiB1 Deleted mismatch")
|
|
assert.Equal(t, apiB2.Deleted, false, "apiB2 Deleted mismatch")
|
|
// assert on body and labels
|
|
assert.Equal(t, apiN1.Body, "js1", "apiN1 Body mismatch")
|
|
assert.Equal(t, apiN2.Body, "js2", "apiN2 Body mismatch")
|
|
assert.Equal(t, apiN3.Body, "js3-edited", "apiN3 Body mismatch")
|
|
assert.Equal(t, apiN4.Body, "css1", "apiN4 Body mismatch")
|
|
assert.Equal(t, apiN5.Body, "css3", "apiN5 Body mismatch")
|
|
assert.Equal(t, apiN6.Body, "css4", "apiN6 Body mismatch")
|
|
assert.Equal(t, apiB1.Label, "js", "apiB1 Label mismatch")
|
|
assert.Equal(t, apiB2.Label, "css", "apiB2 Label mismatch")
|
|
}
|
|
|
|
t.Run("stepSync", func(t *testing.T) {
|
|
clearTmp(t)
|
|
defer apitest.ClearData(apitest.DB)
|
|
|
|
ctx := context.InitTestCtx(t, paths, nil)
|
|
defer context.TeardownTestCtx(t, ctx)
|
|
user := setupUser(t, &ctx)
|
|
setup(t, ctx, user)
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
assert(t, ctx, user)
|
|
})
|
|
|
|
t.Run("fullSync", func(t *testing.T) {
|
|
clearTmp(t)
|
|
defer apitest.ClearData(apitest.DB)
|
|
|
|
ctx := context.InitTestCtx(t, paths, nil)
|
|
defer context.TeardownTestCtx(t, ctx)
|
|
user := setupUser(t, &ctx)
|
|
setup(t, ctx, user)
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync", "-f")
|
|
|
|
assert(t, ctx, user)
|
|
})
|
|
})
|
|
|
|
t.Run("api to cli", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
apiDB := apitest.DB
|
|
|
|
apitest.MustExec(t, apiDB.Model(&user).Update("max_usn", 0), "updating user max_usn")
|
|
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
cssBookUUID := apiCreateBook(t, user, "css", "adding css book")
|
|
cssNote1UUID := apiCreateNote(t, user, cssBookUUID, "css1", "adding css note 1")
|
|
jsNote2UUID := apiCreateNote(t, user, jsBookUUID, "js2", "adding js note 2")
|
|
cssNote2UUID := apiCreateNote(t, user, cssBookUUID, "css2", "adding css note 2")
|
|
linuxBookUUID := apiCreateBook(t, user, "linux", "adding linux book")
|
|
linuxNote1UUID := apiCreateNote(t, user, linuxBookUUID, "linux1", "adding linux note 1")
|
|
apiPatchNote(t, user, jsNote2UUID, fmt.Sprintf(`{"book_uuid": "%s"}`, linuxBookUUID), "moving js note 2 to linux")
|
|
apiDeleteNote(t, user, jsNote1UUID, "deleting js note 1")
|
|
cssNote3UUID := apiCreateNote(t, user, cssBookUUID, "css3", "adding css note 3")
|
|
bashBookUUID := apiCreateBook(t, user, "bash", "adding bash book")
|
|
bashNote1UUID := apiCreateNote(t, user, bashBookUUID, "bash1", "adding bash note 1")
|
|
|
|
// delete the linux book and its two notes
|
|
apiDeleteBook(t, user, linuxBookUUID, "deleting linux book")
|
|
|
|
apiPatchNote(t, user, cssNote2UUID, fmt.Sprintf(`{"content": "%s"}`, "css2-edited"), "editing css 2 body")
|
|
bashNote2UUID := apiCreateNote(t, user, bashBookUUID, "bash2", "adding bash note 2")
|
|
linuxBook2UUID := apiCreateBook(t, user, "linux", "adding new linux book")
|
|
linux2Note1UUID := apiCreateNote(t, user, linuxBookUUID, "linux-new-1", "adding linux note 1")
|
|
apiDeleteBook(t, user, jsBookUUID, "deleting js book")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
"jsNote2UUID": jsNote2UUID,
|
|
"cssBookUUID": cssBookUUID,
|
|
"cssNote1UUID": cssNote1UUID,
|
|
"cssNote2UUID": cssNote2UUID,
|
|
"cssNote3UUID": cssNote3UUID,
|
|
"linuxBookUUID": linuxBookUUID,
|
|
"linuxNote1UUID": linuxNote1UUID,
|
|
"bashBookUUID": bashBookUUID,
|
|
"bashNote1UUID": bashNote1UUID,
|
|
"bashNote2UUID": bashNote2UUID,
|
|
"linuxBook2UUID": linuxBook2UUID,
|
|
"linux2Note1UUID": linux2Note1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 6,
|
|
clientBookCount: 3,
|
|
clientLastMaxUSN: 21,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 9,
|
|
serverBookCount: 5,
|
|
serverUserMaxUSN: 21,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS, apiNote2JS, apiNote1CSS, apiNote2CSS, apiNote3CSS, apiNote1Bash, apiNote2Bash, apiNote1Linux, apiNote2Linux, apiNote1LinuxDup database.Note
|
|
var apiBookJS, apiBookCSS, apiBookBash, apiBookLinux, apiBookLinuxDup database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding api js note 1")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote2UUID"]).First(&apiNote2JS), "finding api js note 2")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssNote1UUID"]).First(&apiNote1CSS), "finding api css note 1")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssNote2UUID"]).First(&apiNote2CSS), "finding api css note 2")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssNote3UUID"]).First(&apiNote3CSS), "finding api css note 3")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["linuxNote1UUID"]).First(&apiNote1Linux), "finding api linux note 1")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote2UUID"]).First(&apiNote2Linux), "finding api linux note 2")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["bashNote1UUID"]).First(&apiNote1Bash), "finding api bash note 1")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["bashNote2UUID"]).First(&apiNote2Bash), "finding api bash note 2")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["linux2Note1UUID"]).First(&apiNote1LinuxDup), "finding api linux 2 note 1")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding api js book")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssBookUUID"]).First(&apiBookCSS), "finding api css book")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["bashBookUUID"]).First(&apiBookBash), "finding api bash book")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["linuxBookUUID"]).First(&apiBookLinux), "finding api linux book")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["linuxBook2UUID"]).First(&apiBookLinuxDup), "finding api linux book 2")
|
|
|
|
// assert on server Label
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiNote2JS.USN, 0, "apiNote2JS USN mismatch")
|
|
assert.NotEqual(t, apiNote1CSS.USN, 0, "apiNote1CSS USN mismatch")
|
|
assert.NotEqual(t, apiNote2CSS.USN, 0, "apiNote2CSS USN mismatch")
|
|
assert.NotEqual(t, apiNote3CSS.USN, 0, "apiNote3CSS USN mismatch")
|
|
assert.NotEqual(t, apiNote1Linux.USN, 0, "apiNote1Linux USN mismatch")
|
|
assert.NotEqual(t, apiNote2Linux.USN, 0, "apiNote2Linux USN mismatch")
|
|
assert.NotEqual(t, apiNote1Bash.USN, 0, "apiNote1Bash USN mismatch")
|
|
assert.NotEqual(t, apiNote2Bash.USN, 0, "apiNote2Bash USN mismatch")
|
|
assert.NotEqual(t, apiNote1LinuxDup.USN, 0, "apiNote1LinuxDup USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apibookJS USN mismatch")
|
|
assert.NotEqual(t, apiBookCSS.USN, 0, "apibookCSS USN mismatch")
|
|
assert.NotEqual(t, apiBookBash.USN, 0, "apibookBash USN mismatch")
|
|
assert.NotEqual(t, apiBookLinux.USN, 0, "apibookLinux USN mismatch")
|
|
assert.NotEqual(t, apiBookLinuxDup.USN, 0, "apiBookLinuxDup USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote2JS.Body, "", "apiNote2JS Body mismatch")
|
|
assert.Equal(t, apiNote1CSS.Body, "css1", "apiNote1CSS Body mismatch")
|
|
assert.Equal(t, apiNote2CSS.Body, "css2-edited", "apiNote2CSS Body mismatch")
|
|
assert.Equal(t, apiNote3CSS.Body, "css3", "apiNote3CSS Body mismatch")
|
|
assert.Equal(t, apiNote1Linux.Body, "", "apiNote1Linux Body mismatch")
|
|
assert.Equal(t, apiNote2Linux.Body, "", "apiNote2Linux Body mismatch")
|
|
assert.Equal(t, apiNote1Bash.Body, "bash1", "apiNote1Bash Body mismatch")
|
|
assert.Equal(t, apiNote2Bash.Body, "bash2", "apiNote2Bash Body mismatch")
|
|
assert.Equal(t, apiNote1LinuxDup.Body, "linux-new-1", "apiNote1LinuxDup Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "", "apibookJS Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "css", "apibookCSS Label mismatch")
|
|
assert.Equal(t, apiBookBash.Label, "bash", "apibookBash Label mismatch")
|
|
assert.Equal(t, apiBookLinux.Label, "", "apibookLinux Label mismatch")
|
|
assert.Equal(t, apiBookLinuxDup.Label, "linux", "apiBookLinuxDup Label mismatch")
|
|
// assert on uuids
|
|
assert.NotEqual(t, apiNote1JS.UUID, "", "apiNote1JS UUID mismatch")
|
|
assert.NotEqual(t, apiNote2JS.UUID, "", "apiNote2JS UUID mismatch")
|
|
assert.NotEqual(t, apiNote1CSS.UUID, "", "apiNote1CSS UUID mismatch")
|
|
assert.NotEqual(t, apiNote2CSS.UUID, "", "apiNote2CSS UUID mismatch")
|
|
assert.NotEqual(t, apiNote3CSS.UUID, "", "apiNote3CSS UUID mismatch")
|
|
assert.NotEqual(t, apiNote1Linux.UUID, "", "apiNote1Linux UUID mismatch")
|
|
assert.NotEqual(t, apiNote2Linux.UUID, "", "apiNote2Linux UUID mismatch")
|
|
assert.NotEqual(t, apiNote1Bash.UUID, "", "apiNote1Bash UUID mismatch")
|
|
assert.NotEqual(t, apiNote2Bash.UUID, "", "apiNote2Bash UUID mismatch")
|
|
assert.NotEqual(t, apiNote2Bash.UUID, "", "apiNote2Bash UUID mismatch")
|
|
assert.NotEqual(t, apiBookJS.UUID, "", "apibookJS UUID mismatch")
|
|
assert.NotEqual(t, apiBookCSS.UUID, "", "apibookCSS UUID mismatch")
|
|
assert.NotEqual(t, apiBookBash.UUID, "", "apibookBash UUID mismatch")
|
|
assert.NotEqual(t, apiBookLinux.UUID, "", "apibookLinux UUID mismatch")
|
|
assert.NotEqual(t, apiBookLinuxDup.UUID, "", "apiBookLinuxDup UUID mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, true, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiNote2JS.Deleted, true, "apiNote2JS Deleted mismatch")
|
|
assert.Equal(t, apiNote1CSS.Deleted, false, "apiNote1CSS Deleted mismatch")
|
|
assert.Equal(t, apiNote2CSS.Deleted, false, "apiNote2CSS Deleted mismatch")
|
|
assert.Equal(t, apiNote3CSS.Deleted, false, "apiNote3CSS Deleted mismatch")
|
|
assert.Equal(t, apiNote1Linux.Deleted, true, "apiNote1Linux Deleted mismatch")
|
|
assert.Equal(t, apiNote2Linux.Deleted, true, "apiNote2Linux Deleted mismatch")
|
|
assert.Equal(t, apiNote1Bash.Deleted, false, "apiNote1Bash Deleted mismatch")
|
|
assert.Equal(t, apiNote2Bash.Deleted, false, "apiNote2Bash Deleted mismatch")
|
|
assert.Equal(t, apiNote2Bash.Deleted, false, "apiNote2Bash Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, true, "apibookJS Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS.Deleted, false, "apibookCSS Deleted mismatch")
|
|
assert.Equal(t, apiBookBash.Deleted, false, "apibookBash Deleted mismatch")
|
|
assert.Equal(t, apiBookLinux.Deleted, true, "apibookLinux Deleted mismatch")
|
|
assert.Equal(t, apiBookLinuxDup.Deleted, false, "apiBookLinuxDup Deleted mismatch")
|
|
|
|
// test client
|
|
var cliBookCSS, cliBookBash, cliBookLinux cliDatabase.Book
|
|
var cliNote1CSS, cliNote2CSS, cliNote3CSS, cliNote1Bash, cliNote2Bash, cliNote1Linux cliDatabase.Note
|
|
cliDatabase.MustScan(t, "finding cli book css", cliDB.QueryRow("SELECT label FROM books WHERE uuid = ?", ids["cssBookUUID"]), &cliBookCSS.Label)
|
|
cliDatabase.MustScan(t, "finding cli book bash", cliDB.QueryRow("SELECT label FROM books WHERE uuid = ?", ids["bashBookUUID"]), &cliBookBash.Label)
|
|
cliDatabase.MustScan(t, "finding cli book linux2", cliDB.QueryRow("SELECT label FROM books WHERE uuid = ?", ids["linuxBook2UUID"]), &cliBookLinux.Label)
|
|
cliDatabase.MustScan(t, "finding cliNote1CSS", cliDB.QueryRow("SELECT body, usn FROM notes WHERE uuid = ?", apiNote1CSS.UUID), &cliNote1CSS.Body, &cliNote1CSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote2CSS", cliDB.QueryRow("SELECT body, usn FROM notes WHERE uuid = ?", apiNote2CSS.UUID), &cliNote2CSS.Body, &cliNote2CSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote3CSS", cliDB.QueryRow("SELECT body, usn FROM notes WHERE uuid = ?", apiNote3CSS.UUID), &cliNote3CSS.Body, &cliNote3CSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1Bash", cliDB.QueryRow("SELECT body, usn FROM notes WHERE uuid = ?", apiNote1Bash.UUID), &cliNote1Bash.Body, &cliNote1Bash.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote2Bash", cliDB.QueryRow("SELECT body, usn FROM notes WHERE uuid = ?", apiNote2Bash.UUID), &cliNote2Bash.Body, &cliNote2Bash.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote2Bash", cliDB.QueryRow("SELECT body, usn FROM notes WHERE uuid = ?", apiNote1LinuxDup.UUID), &cliNote1Linux.Body, &cliNote1Linux.USN)
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, cliNote1CSS.USN, 0, "cliNote1CSS usn mismatch")
|
|
assert.NotEqual(t, cliNote2CSS.USN, 0, "cliNote2CSS usn mismatch")
|
|
assert.NotEqual(t, cliNote3CSS.USN, 0, "cliNote3CSS usn mismatch")
|
|
assert.NotEqual(t, cliNote1Bash.USN, 0, "cliNote1Bash usn mismatch")
|
|
assert.NotEqual(t, cliNote2Bash.USN, 0, "cliNote2Bash usn mismatch")
|
|
assert.NotEqual(t, cliNote1Linux.USN, 0, "cliNote1Linux usn mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1CSS.Body, "css1", "cliNote1CSS Body mismatch")
|
|
assert.Equal(t, cliNote2CSS.Body, "css2-edited", "cliNote2CSS Body mismatch")
|
|
assert.Equal(t, cliNote3CSS.Body, "css3", "cliNote3CSS Body mismatch")
|
|
assert.Equal(t, cliNote1Bash.Body, "bash1", "cliNote1Bash Body mismatch")
|
|
assert.Equal(t, cliNote2Bash.Body, "bash2", "cliNote2Bash Body mismatch")
|
|
assert.Equal(t, cliNote1Linux.Body, "linux-new-1", "cliNote1Linux Body mismatch")
|
|
assert.Equal(t, cliBookCSS.Label, "css", "cliBookCSS Label mismatch")
|
|
assert.Equal(t, cliBookBash.Label, "bash", "cliBookBash Label mismatch")
|
|
assert.Equal(t, cliBookLinux.Label, "linux", "cliBookLinux Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1CSS.Deleted, false, "cliNote1CSS Deleted mismatch")
|
|
assert.Equal(t, cliNote2CSS.Deleted, false, "cliNote2CSS Deleted mismatch")
|
|
assert.Equal(t, cliNote3CSS.Deleted, false, "cliNote3CSS Deleted mismatch")
|
|
assert.Equal(t, cliNote1Bash.Deleted, false, "cliNote1Bash Deleted mismatch")
|
|
assert.Equal(t, cliNote2Bash.Deleted, false, "cliNote2Bash Deleted mismatch")
|
|
assert.Equal(t, cliNote1Linux.Deleted, false, "cliNote1Linux Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS.Deleted, false, "cliBookCSS Deleted mismatch")
|
|
assert.Equal(t, cliBookBash.Deleted, false, "cliBookBash Deleted mismatch")
|
|
assert.Equal(t, cliBookLinux.Deleted, false, "cliBookLinux Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
}
|
|
|
|
func TestSync_twoway(t *testing.T) {
|
|
t.Run("once", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
cliDB := ctx.DB
|
|
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
cssBookUUID := apiCreateBook(t, user, "css", "adding css book")
|
|
cssNote1UUID := apiCreateNote(t, user, cssBookUUID, "css1", "adding css note 1")
|
|
jsNote2UUID := apiCreateNote(t, user, jsBookUUID, "js2", "adding js note 2")
|
|
cssNote2UUID := apiCreateNote(t, user, cssBookUUID, "css2", "adding css note 2")
|
|
linuxBookUUID := apiCreateBook(t, user, "linux", "adding linux book")
|
|
linuxNote1UUID := apiCreateNote(t, user, linuxBookUUID, "linux1", "adding linux note 1")
|
|
apiPatchNote(t, user, jsNote2UUID, fmt.Sprintf(`{"book_uuid": "%s"}`, linuxBookUUID), "moving js note 2 to linux")
|
|
apiDeleteNote(t, user, jsNote1UUID, "deleting js note 1")
|
|
cssNote3UUID := apiCreateNote(t, user, cssBookUUID, "css3", "adding css note 3")
|
|
bashBookUUID := apiCreateBook(t, user, "bash", "adding bash book")
|
|
bashNote1UUID := apiCreateNote(t, user, bashBookUUID, "bash1", "adding bash note 1")
|
|
apiDeleteBook(t, user, linuxBookUUID, "deleting linux book")
|
|
apiPatchNote(t, user, cssNote2UUID, fmt.Sprintf(`{"content": "%s"}`, "css2-edited"), "editing css 2 body")
|
|
bashNote2UUID := apiCreateNote(t, user, bashBookUUID, "bash2", "adding bash note 2")
|
|
linuxBook2UUID := apiCreateBook(t, user, "linux", "adding new linux book")
|
|
linux2Note1UUID := apiCreateNote(t, user, linuxBookUUID, "linux-new-1", "adding linux note 1")
|
|
apiDeleteBook(t, user, jsBookUUID, "deleting js book")
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js3")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "algorithms", "-c", "algorithms1")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js4")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "algorithms", "-c", "algorithms2")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "math", "-c", "math1")
|
|
|
|
var nid string
|
|
cliDatabase.MustScan(t, "getting id of note to remove", cliDB.QueryRow("SELECT rowid FROM notes WHERE body = ?", "js3"), &nid)
|
|
|
|
clitest.WaitDnoteCmd(t, dnoteCmdOpts, clitest.UserConfirm, cliBinaryName, "remove", "algorithms")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "css", "-c", "css4")
|
|
clitest.WaitDnoteCmd(t, dnoteCmdOpts, clitest.UserConfirm, cliBinaryName, "remove", "js", nid)
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
"jsNote2UUID": jsNote2UUID,
|
|
"cssBookUUID": cssBookUUID,
|
|
"cssNote1UUID": cssNote1UUID,
|
|
"cssNote2UUID": cssNote2UUID,
|
|
"cssNote3UUID": cssNote3UUID,
|
|
"linuxBookUUID": linuxBookUUID,
|
|
"linuxNote1UUID": linuxNote1UUID,
|
|
"bashBookUUID": bashBookUUID,
|
|
"bashNote1UUID": bashNote1UUID,
|
|
"bashNote2UUID": bashNote2UUID,
|
|
"linuxBook2UUID": linuxBook2UUID,
|
|
"linux2Note1UUID": linux2Note1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 9,
|
|
clientBookCount: 6,
|
|
clientLastMaxUSN: 27,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 12,
|
|
serverBookCount: 8,
|
|
serverUserMaxUSN: 27,
|
|
})
|
|
|
|
// test client
|
|
var cliNote1CSS, cliNote2CSS, cliNote3CSS, cliNote1CSS2, cliNote1Bash, cliNote2Bash, cliNote1Linux, cliNote1Math, cliNote1JS cliDatabase.Note
|
|
var cliBookCSS, cliBookCSS2, cliBookBash, cliBookLinux, cliBookMath, cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1CSS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "css1"), &cliNote1CSS.UUID, &cliNote1CSS.Body, &cliNote1CSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote2CSS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "css2-edited"), &cliNote2CSS.UUID, &cliNote2CSS.Body, &cliNote2CSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote3CSS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "css3"), &cliNote3CSS.UUID, &cliNote3CSS.Body, &cliNote3CSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1CSS2", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "css4"), &cliNote1CSS2.UUID, &cliNote1CSS2.Body, &cliNote1CSS2.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1Bash", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "bash1"), &cliNote1Bash.UUID, &cliNote1Bash.Body, &cliNote1Bash.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote2Bash", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "bash2"), &cliNote2Bash.UUID, &cliNote2Bash.Body, &cliNote2Bash.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1Linux", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "linux-new-1"), &cliNote1Linux.UUID, &cliNote1Linux.Body, &cliNote1Linux.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1Math", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "math1"), &cliNote1Math.UUID, &cliNote1Math.Body, &cliNote1Math.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js4"), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookCSS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css"), &cliBookCSS.UUID, &cliBookCSS.Label, &cliBookCSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookCSS2", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css_2"), &cliBookCSS2.UUID, &cliBookCSS2.Label, &cliBookCSS2.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookBash", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "bash"), &cliBookBash.UUID, &cliBookBash.Label, &cliBookBash.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookLinux", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "linux"), &cliBookLinux.UUID, &cliBookLinux.Label, &cliBookLinux.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookMath", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "math"), &cliBookMath.UUID, &cliBookMath.Label, &cliBookMath.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1CSS.USN, 0, "cliNote1CSS USN mismatch")
|
|
assert.NotEqual(t, cliNote2CSS.USN, 0, "cliNote2CSS USN mismatch")
|
|
assert.NotEqual(t, cliNote3CSS.USN, 0, "cliNote3CSS USN mismatch")
|
|
assert.NotEqual(t, cliNote1CSS2.USN, 0, "cliNote1CSS2 USN mismatch")
|
|
assert.NotEqual(t, cliNote1Bash.USN, 0, "cliNote1Bash USN mismatch")
|
|
assert.NotEqual(t, cliNote2Bash.USN, 0, "cliNote2Bash USN mismatch")
|
|
assert.NotEqual(t, cliNote1Linux.USN, 0, "cliNote1Linux USN mismatch")
|
|
assert.NotEqual(t, cliNote1Math.USN, 0, "cliNote1Math USN mismatch")
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
assert.NotEqual(t, cliBookCSS.USN, 0, "cliBookCSS USN mismatch")
|
|
assert.NotEqual(t, cliBookCSS2.USN, 0, "cliBookCSS2 USN mismatch")
|
|
assert.NotEqual(t, cliBookBash.USN, 0, "cliBookBash USN mismatch")
|
|
assert.NotEqual(t, cliBookMath.USN, 0, "cliBookMath USN mismatch")
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1CSS.Body, "css1", "cliNote1CSS Body mismatch")
|
|
assert.Equal(t, cliNote2CSS.Body, "css2-edited", "cliNote2CSS Body mismatch")
|
|
assert.Equal(t, cliNote3CSS.Body, "css3", "cliNote3CSS Body mismatch")
|
|
assert.Equal(t, cliNote1CSS2.Body, "css4", "cliNote1CSS2 Body mismatch")
|
|
assert.Equal(t, cliNote1Bash.Body, "bash1", "cliNote1Bash Body mismatch")
|
|
assert.Equal(t, cliNote2Bash.Body, "bash2", "cliNote2Bash Body mismatch")
|
|
assert.Equal(t, cliNote1Linux.Body, "linux-new-1", "cliNote1Linux Body mismatch")
|
|
assert.Equal(t, cliNote1Math.Body, "math1", "cliNote1Math Body mismatch")
|
|
assert.Equal(t, cliNote1JS.Body, "js4", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliBookCSS.Label, "css", "cliBookCSS Label mismatch")
|
|
assert.Equal(t, cliBookCSS2.Label, "css_2", "cliBookCSS2 Label mismatch")
|
|
assert.Equal(t, cliBookBash.Label, "bash", "cliBookBash Label mismatch")
|
|
assert.Equal(t, cliBookMath.Label, "math", "cliBookMath Label mismatch")
|
|
assert.Equal(t, cliBookLinux.Label, "linux", "cliBookLinux Label mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1CSS.Deleted, false, "cliNote1CSS Deleted mismatch")
|
|
assert.Equal(t, cliNote2CSS.Deleted, false, "cliNote2CSS Deleted mismatch")
|
|
assert.Equal(t, cliNote3CSS.Deleted, false, "cliNote3CSS Deleted mismatch")
|
|
assert.Equal(t, cliNote1CSS2.Deleted, false, "cliNote1CSS2 Deleted mismatch")
|
|
assert.Equal(t, cliNote1Bash.Deleted, false, "cliNote1Bash Deleted mismatch")
|
|
assert.Equal(t, cliNote2Bash.Deleted, false, "cliNote2Bash Deleted mismatch")
|
|
assert.Equal(t, cliNote1Linux.Deleted, false, "cliNote1Linux Deleted mismatch")
|
|
assert.Equal(t, cliNote1Math.Deleted, false, "cliNote1Math Deleted mismatch")
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS.Deleted, false, "cliBookCSS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS2.Deleted, false, "cliBookCSS2 Deleted mismatch")
|
|
assert.Equal(t, cliBookBash.Deleted, false, "cliBookBash Deleted mismatch")
|
|
assert.Equal(t, cliBookMath.Deleted, false, "cliBookMath Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS, apiNote1CSS, apiNote2CSS, apiNote3CSS, apiNote1Linux, apiNote2Linux, apiNote1Bash, apiNote2Bash, apiNote1LinuxDup, apiNote1CSS2, apiNote1Math, apiNote1JS2 database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding api js note 1")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssNote1UUID"]).First(&apiNote1CSS), "finding api css note 1")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssNote2UUID"]).First(&apiNote2CSS), "finding api css note 2")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssNote3UUID"]).First(&apiNote3CSS), "finding api css note 3")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["linuxNote1UUID"]).First(&apiNote1Linux), "finding api linux note 1")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote2UUID"]).First(&apiNote2Linux), "finding api linux note 2")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["bashNote1UUID"]).First(&apiNote1Bash), "finding api bash note 1")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["bashNote2UUID"]).First(&apiNote2Bash), "finding api bash note 2")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["linux2Note1UUID"]).First(&apiNote1LinuxDup), "finding api linux 2 note 1")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1CSS2.UUID).First(&apiNote1CSS2), "finding apiNote1CSS2")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1Math.UUID).First(&apiNote1Math), "finding apiNote1Math")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1JS.UUID).First(&apiNote1JS2), "finding apiNote1JS2")
|
|
var apiBookJS, apiBookCSS, apiBookLinux, apiBookBash, apiBookLinuxDup, apiBookCSS2, apiBookMath, apiBookJS2 database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding api js book")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssBookUUID"]).First(&apiBookCSS), "finding api css book")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["bashBookUUID"]).First(&apiBookBash), "finding api bash book")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["linuxBookUUID"]).First(&apiBookLinux), "finding api linux book")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["linuxBook2UUID"]).First(&apiBookLinuxDup), "finding api linux book 2")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookCSS2.UUID).First(&apiBookCSS2), "finding apiBookCSS2")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookMath.UUID).First(&apiBookMath), "finding apiBookMath")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookJS.UUID).First(&apiBookJS2), "finding apiBookJS2")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS usn mismatch")
|
|
assert.NotEqual(t, apiNote1CSS.USN, 0, "apiNote1CSS usn mismatch")
|
|
assert.NotEqual(t, apiNote2CSS.USN, 0, "apiNote2CSS usn mismatch")
|
|
assert.NotEqual(t, apiNote3CSS.USN, 0, "apiNote3CSS usn mismatch")
|
|
assert.NotEqual(t, apiNote1Linux.USN, 0, "apiNote1Linux usn mismatch")
|
|
assert.NotEqual(t, apiNote2Linux.USN, 0, "apiNote2Linux usn mismatch")
|
|
assert.NotEqual(t, apiNote1Bash.USN, 0, "apiNote1Bash usn mismatch")
|
|
assert.NotEqual(t, apiNote2Bash.USN, 0, "apiNote2Bash usn mismatch")
|
|
assert.NotEqual(t, apiNote1LinuxDup.USN, 0, "apiNote1LinuxDup usn mismatch")
|
|
assert.NotEqual(t, apiNote1CSS2.USN, 0, "apiNoteCSS2 usn mismatch")
|
|
assert.NotEqual(t, apiNote1Math.USN, 0, "apiNote1Math usn mismatch")
|
|
assert.NotEqual(t, apiNote1JS2.USN, 0, "apiNote1JS2 usn mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS usn mismatch")
|
|
assert.NotEqual(t, apiBookCSS.USN, 0, "apiBookCSS usn mismatch")
|
|
assert.NotEqual(t, apiBookLinux.USN, 0, "apiBookLinux usn mismatch")
|
|
assert.NotEqual(t, apiBookBash.USN, 0, "apiBookBash usn mismatch")
|
|
assert.NotEqual(t, apiBookLinuxDup.USN, 0, "apiBookLinuxDup usn mismatch")
|
|
assert.NotEqual(t, apiBookCSS2.USN, 0, "apiBookCSS2 usn mismatch")
|
|
assert.NotEqual(t, apiBookMath.USN, 0, "apiBookMath usn mismatch")
|
|
assert.NotEqual(t, apiBookJS2.USN, 0, "apiBookJS2 usn mismatch")
|
|
// assert on note bodys
|
|
assert.Equal(t, apiNote1JS.Body, "", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1CSS.Body, "css1", "apiNote1CSS Body mismatch")
|
|
assert.Equal(t, apiNote2CSS.Body, "css2-edited", "apiNote2CSS Body mismatch")
|
|
assert.Equal(t, apiNote3CSS.Body, "css3", "apiNote3CSS Body mismatch")
|
|
assert.Equal(t, apiNote1Linux.Body, "", "apiNote1Linux Body mismatch")
|
|
assert.Equal(t, apiNote2Linux.Body, "", "apiNote2Linux Body mismatch")
|
|
assert.Equal(t, apiNote1Bash.Body, "bash1", "apiNote1Bash Body mismatch")
|
|
assert.Equal(t, apiNote2Bash.Body, "bash2", "apiNote2Bash Body mismatch")
|
|
assert.Equal(t, apiNote1LinuxDup.Body, "linux-new-1", "apiNote1LinuxDup Body mismatch")
|
|
assert.Equal(t, apiNote1CSS2.Body, "css4", "apiNote1CSS2 Body mismatch")
|
|
assert.Equal(t, apiNote1Math.Body, "math1", "apiNote1Math Body mismatch")
|
|
assert.Equal(t, apiNote1JS2.Body, "js4", "apiNote1JS2 Body mismatch")
|
|
// client must have generated uuids
|
|
assert.NotEqual(t, apiNote1CSS2.UUID, "", "apiNote1CSS2 uuid mismatch")
|
|
assert.NotEqual(t, apiNote1Math.UUID, "", "apiNote1Math uuid mismatch")
|
|
assert.NotEqual(t, apiNote1JS2.UUID, "", "apiNote1JS2 uuid mismatch")
|
|
// assert on labels
|
|
assert.Equal(t, apiBookJS.Label, "", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "css", "apiBookCSS Label mismatch")
|
|
assert.Equal(t, apiBookLinux.Label, "", "apiBookLinux Label mismatch")
|
|
assert.Equal(t, apiBookBash.Label, "bash", "apiBookBash Label mismatch")
|
|
assert.Equal(t, apiBookLinuxDup.Label, "linux", "apiBookLinuxDup Label mismatch")
|
|
assert.Equal(t, apiBookCSS2.Label, "css_2", "apiBookCSS2 Label mismatch")
|
|
assert.Equal(t, apiBookMath.Label, "math", "apiBookMath Label mismatch")
|
|
assert.Equal(t, apiBookJS2.Label, "js", "apiBookJS2 Label mismatch")
|
|
// assert on note deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, true, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiNote1CSS.Deleted, false, "apiNote1CSS Deleted mismatch")
|
|
assert.Equal(t, apiNote2CSS.Deleted, false, "apiNote2CSS Deleted mismatch")
|
|
assert.Equal(t, apiNote3CSS.Deleted, false, "apiNote3CSS Deleted mismatch")
|
|
assert.Equal(t, apiNote1Linux.Deleted, true, "apiNote1Linux Deleted mismatch")
|
|
assert.Equal(t, apiNote2Linux.Deleted, true, "apiNote2Linux Deleted mismatch")
|
|
assert.Equal(t, apiNote1Bash.Deleted, false, "apiNote1Bash Deleted mismatch")
|
|
assert.Equal(t, apiNote2Bash.Deleted, false, "apiNote2Bash Deleted mismatch")
|
|
assert.Equal(t, apiNote1LinuxDup.Deleted, false, "apiNote1LinuxDup Deleted mismatch")
|
|
assert.Equal(t, apiNote1CSS2.Deleted, false, "apiNote1CSS2 Deleted mismatch")
|
|
assert.Equal(t, apiNote1Math.Deleted, false, "apiNote1Math Deleted mismatch")
|
|
assert.Equal(t, apiNote1JS2.Deleted, false, "apiNote1JS2 Deleted mismatch")
|
|
// assert on book deleted
|
|
assert.Equal(t, apiBookJS.Deleted, true, "apiBookJS Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS.Deleted, false, "apiBookCSS Deleted mismatch")
|
|
assert.Equal(t, apiBookLinux.Deleted, true, "apiBookLinux Deleted mismatch")
|
|
assert.Equal(t, apiBookBash.Deleted, false, "apiBookBash Deleted mismatch")
|
|
assert.Equal(t, apiBookLinuxDup.Deleted, false, "apiBookLinuxDup Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS2.Deleted, false, "apiBookCSS2 Deleted mismatch")
|
|
assert.Equal(t, apiBookMath.Deleted, false, "apiBookMath Deleted mismatch")
|
|
assert.Equal(t, apiBookJS2.Deleted, false, "apiBookJS2 Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("twice", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
cssBookUUID := apiCreateBook(t, user, "css", "adding css book")
|
|
cssNote1UUID := apiCreateNote(t, user, cssBookUUID, "css1", "adding css note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js2")
|
|
clitest.WaitDnoteCmd(t, dnoteCmdOpts, clitest.UserConfirm, cliBinaryName, "remove", "js")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "math", "-c", "math1")
|
|
|
|
var nid string
|
|
cliDB := ctx.DB
|
|
cliDatabase.MustScan(t, "getting id of note to edit", cliDB.QueryRow("SELECT rowid FROM notes WHERE body = ?", "math1"), &nid)
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "math", nid, "-c", "math1-edited")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
scssBookUUID := apiCreateBook(t, user, "scss", "adding a scss book")
|
|
apiPatchNote(t, user, cssNote1UUID, fmt.Sprintf(`{"book_uuid": "%s"}`, scssBookUUID), "moving css note 1 to scss")
|
|
|
|
var n1UUID string
|
|
cliDatabase.MustScan(t, "getting math1-edited note UUID", cliDB.QueryRow("SELECT uuid FROM notes WHERE body = ?", "math1-edited"), &n1UUID)
|
|
apiPatchNote(t, user, n1UUID, fmt.Sprintf(`{"content": "%s", "public": true}`, "math1-edited"), "editing math1 note")
|
|
|
|
cssNote2UUID := apiCreateNote(t, user, cssBookUUID, "css2", "adding css note 2")
|
|
apiDeleteBook(t, user, cssBookUUID, "deleting css book")
|
|
|
|
bashBookUUID := apiCreateBook(t, user, "bash", "adding a bash book")
|
|
algorithmsBookUUID := apiCreateBook(t, user, "algorithms", "adding a algorithms book")
|
|
|
|
// 4. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js3")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "algorithms", "-c", "algorithms1")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
"cssBookUUID": cssBookUUID,
|
|
"scssBookUUID": scssBookUUID,
|
|
"cssNote1UUID": cssNote1UUID,
|
|
"cssNote2UUID": cssNote2UUID,
|
|
"bashBookUUID": bashBookUUID,
|
|
"algorithmsBookUUID": algorithmsBookUUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
apiDB := apitest.DB
|
|
cliDB := ctx.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 5,
|
|
clientBookCount: 6,
|
|
clientLastMaxUSN: 17,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 6,
|
|
serverBookCount: 7,
|
|
serverUserMaxUSN: 17,
|
|
})
|
|
|
|
// test client
|
|
var cliNote1JS, cliNote2JS, cliNote1SCSS, cliNote1Math, cliNote1Alg2 cliDatabase.Note
|
|
var cliBookJS, cliBookSCSS, cliBookMath, cliBookBash, cliBookAlg, cliBookAlg2 cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js1"), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote2JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js3"), &cliNote2JS.UUID, &cliNote2JS.Body, &cliNote2JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1SCSS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "css1"), &cliNote1SCSS.UUID, &cliNote1SCSS.Body, &cliNote1SCSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1Math", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "math1-edited"), &cliNote1Math.UUID, &cliNote1Math.Body, &cliNote1Math.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1Alg2", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "algorithms1"), &cliNote1Alg2.UUID, &cliNote1Alg2.Body, &cliNote1Alg2.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookSCSS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "scss"), &cliBookSCSS.UUID, &cliBookSCSS.Label, &cliBookSCSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookMath", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "math"), &cliBookMath.UUID, &cliBookMath.Label, &cliBookMath.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookBash", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "bash"), &cliBookBash.UUID, &cliBookBash.Label, &cliBookBash.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookAlg", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "algorithms"), &cliBookAlg.UUID, &cliBookAlg.Label, &cliBookAlg.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookAlg2", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "algorithms_2"), &cliBookAlg2.UUID, &cliBookAlg2.Label, &cliBookAlg2.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
assert.NotEqual(t, cliNote2JS.USN, 0, "cliNote2JS USN mismatch")
|
|
assert.NotEqual(t, cliNote1SCSS.USN, 0, "cliNote1SCSS USN mismatch")
|
|
assert.NotEqual(t, cliNote1Math.USN, 0, "cliNote1Math USN mismatch")
|
|
assert.NotEqual(t, cliNote1Alg2.USN, 0, "cliNote1Alg2 USN mismatch")
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
assert.NotEqual(t, cliBookSCSS.USN, 0, "cliBookSCSS USN mismatch")
|
|
assert.NotEqual(t, cliBookMath.USN, 0, "cliBookMath USN mismatch")
|
|
assert.NotEqual(t, cliBookBash.USN, 0, "cliBookBash USN mismatch")
|
|
assert.NotEqual(t, cliBookAlg.USN, 0, "cliBookAlg USN mismatch")
|
|
assert.NotEqual(t, cliBookAlg2.USN, 0, "cliBookAlg2 USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote2JS.Body, "js3", "cliNote2JS Body mismatch")
|
|
assert.Equal(t, cliNote1SCSS.Body, "css1", "cliNote1SCSS Body mismatch")
|
|
assert.Equal(t, cliNote1Math.Body, "math1-edited", "cliNote1Math Body mismatch")
|
|
assert.Equal(t, cliNote1Alg2.Body, "algorithms1", "cliNote1Alg2 Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookSCSS.Label, "scss", "cliBookSCSS Label mismatch")
|
|
assert.Equal(t, cliBookMath.Label, "math", "cliBookMath Label mismatch")
|
|
assert.Equal(t, cliBookBash.Label, "bash", "cliBookBash Label mismatch")
|
|
assert.Equal(t, cliBookAlg.Label, "algorithms", "cliBookAlg Label mismatch")
|
|
assert.Equal(t, cliBookAlg2.Label, "algorithms_2", "cliBookAlg2 Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliNote2JS.Deleted, false, "cliNote2JS Deleted mismatch")
|
|
assert.Equal(t, cliNote1SCSS.Deleted, false, "cliNote1SCSS Deleted mismatch")
|
|
assert.Equal(t, cliNote1Math.Deleted, false, "cliNote1Math Deleted mismatch")
|
|
assert.Equal(t, cliNote1Alg2.Deleted, false, "cliNote1Alg2 Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookSCSS.Deleted, false, "cliBookSCSS Deleted mismatch")
|
|
assert.Equal(t, cliBookMath.Deleted, false, "cliBookMath Deleted mismatch")
|
|
assert.Equal(t, cliBookBash.Deleted, false, "cliBookBash Deleted mismatch")
|
|
assert.Equal(t, cliBookAlg.Deleted, false, "cliBookAlg Deleted mismatch")
|
|
assert.Equal(t, cliBookAlg2.Deleted, false, "cliBookAlg2 Deleted mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS, apiNote2JS, apiNote1SCSS, apiNote2CSS, apiNote1Math, apiNote1Alg database.Note
|
|
var apiBookJS, apiBookCSS, apiBookSCSS, apiBookMath, apiBookBash, apiBookAlg, apiBookAlg2 database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssNote2UUID"]).First(&apiNote2CSS), "finding apiNote2CSS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote2JS.UUID).First(&apiNote2JS), "finding apiNote2JS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssNote1UUID"]).First(&apiNote1SCSS), "finding apiNote1SCSS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1Math.UUID).First(&apiNote1Math), "finding apiNote1Math")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1Alg2.UUID).First(&apiNote1Alg), "finding apiNote1Alg")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssBookUUID"]).First(&apiBookCSS), "finding apiBookCSS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["bashBookUUID"]).First(&apiBookBash), "finding apiBookBash")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["scssBookUUID"]).First(&apiBookSCSS), "finding apiBookSCSS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["algorithmsBookUUID"]).First(&apiBookAlg), "finding apiBookAlg")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookAlg2.UUID).First(&apiBookAlg2), "finding apiBookAlg2")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookMath.UUID).First(&apiBookMath), "finding apiBookMath")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS usn mismatch")
|
|
assert.NotEqual(t, apiNote2JS.USN, 0, "apiNote1JS usn mismatch")
|
|
assert.NotEqual(t, apiNote1SCSS.USN, 0, "apiNote1JS usn mismatch")
|
|
assert.NotEqual(t, apiNote2CSS.USN, 0, "apiNote1JS usn mismatch")
|
|
assert.NotEqual(t, apiNote1Math.USN, 0, "apiNote1JS usn mismatch")
|
|
assert.NotEqual(t, apiNote1Alg.USN, 0, "apiNote1JS usn mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBook1Alg usn mismatch")
|
|
assert.NotEqual(t, apiBookCSS.USN, 0, "apiBookCSS usn mismatch")
|
|
assert.NotEqual(t, apiBookSCSS.USN, 0, "apibookSCSS usn mismatch")
|
|
assert.NotEqual(t, apiBookMath.USN, 0, "apiBookMath usn mismatch")
|
|
assert.NotEqual(t, apiBookBash.USN, 0, "apiBookBash usn mismatch")
|
|
assert.NotEqual(t, apiBookAlg.USN, 0, "apiBookAlg usn mismatch")
|
|
assert.NotEqual(t, apiBookAlg2.USN, 0, "apiBookAlg2 usn mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote2JS.Body, "js3", "apiNote2JS Body mismatch")
|
|
assert.Equal(t, apiNote1SCSS.Body, "css1", "apiNote1SCSS Body mismatch")
|
|
assert.Equal(t, apiNote2CSS.Body, "", "apiNote2CSS Body mismatch")
|
|
assert.Equal(t, apiNote1Math.Body, "math1-edited", "apiNote1Math Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "", "apiBookCSS Label mismatch")
|
|
assert.Equal(t, apiBookSCSS.Label, "scss", "apiBookSCSS Label mismatch")
|
|
assert.Equal(t, apiBookMath.Label, "math", "apiBookMath Label mismatch")
|
|
assert.Equal(t, apiBookBash.Label, "bash", "apiBookBash Label mismatch")
|
|
assert.Equal(t, apiBookAlg.Label, "algorithms", "apiBookAlg Label mismatch")
|
|
assert.Equal(t, apiBookAlg2.Label, "algorithms_2", "apiBookAlg2 Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiNote2JS.Deleted, false, "apiNote2JS Deleted mismatch")
|
|
assert.Equal(t, apiNote1SCSS.Deleted, false, "apiNote1SCSS Deleted mismatch")
|
|
assert.Equal(t, apiNote2CSS.Deleted, true, "apiNote2CSS Deleted mismatch")
|
|
assert.Equal(t, apiNote1Math.Deleted, false, "apiNote1Math Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS.Deleted, true, "apiBookCSS Deleted mismatch")
|
|
assert.Equal(t, apiBookSCSS.Deleted, false, "apiBookSCSS Deleted mismatch")
|
|
assert.Equal(t, apiBookMath.Deleted, false, "apiBookMath Deleted mismatch")
|
|
assert.Equal(t, apiBookBash.Deleted, false, "apiBookBash Deleted mismatch")
|
|
assert.Equal(t, apiBookAlg.Deleted, false, "apiBookAlg Deleted mismatch")
|
|
assert.Equal(t, apiBookAlg2.Deleted, false, "apiBookAlg2 Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("three times", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "css", "-c", "css1")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
goBookUUID := apiCreateBook(t, user, "go", "adding a go book")
|
|
goNote1UUID := apiCreateNote(t, user, goBookUUID, "go1", "adding go note 1")
|
|
|
|
// 4. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "html", "-c", "html1")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
"goBookUUID": goBookUUID,
|
|
"goNote1UUID": goNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 4,
|
|
clientBookCount: 4,
|
|
clientLastMaxUSN: 8,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 4,
|
|
serverBookCount: 4,
|
|
serverUserMaxUSN: 8,
|
|
})
|
|
|
|
// test client
|
|
var cliNote1JS, cliNote1CSS, cliNote1Go, cliNote1HTML cliDatabase.Note
|
|
var cliBookJS, cliBookCSS, cliBookGo, cliBookHTML cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js1"), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1CSS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "css1"), &cliNote1CSS.UUID, &cliNote1CSS.Body, &cliNote1CSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1Go", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "go1"), &cliNote1Go.UUID, &cliNote1Go.Body, &cliNote1Go.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1HTML", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "html1"), &cliNote1HTML.UUID, &cliNote1HTML.Body, &cliNote1HTML.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookCSS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css"), &cliBookCSS.UUID, &cliBookCSS.Label, &cliBookCSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookGo", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "go"), &cliBookGo.UUID, &cliBookGo.Label, &cliBookGo.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookHTML", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "html"), &cliBookHTML.UUID, &cliBookHTML.Label, &cliBookHTML.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
assert.NotEqual(t, cliNote1CSS.USN, 0, "cliNote1CSS USN mismatch")
|
|
assert.NotEqual(t, cliNote1Go.USN, 0, "cliNote1Go USN mismatch")
|
|
assert.NotEqual(t, cliNote1HTML.USN, 0, "cliNote1HTML USN mismatch")
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
assert.NotEqual(t, cliBookCSS.USN, 0, "cliBookCSS USN mismatch")
|
|
assert.NotEqual(t, cliBookGo.USN, 0, "cliBookGo USN mismatch")
|
|
assert.NotEqual(t, cliBookHTML.USN, 0, "cliBookHTML USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1CSS.Body, "css1", "cliNote1CSS Body mismatch")
|
|
assert.Equal(t, cliNote1Go.Body, "go1", "cliNote1Go Body mismatch")
|
|
assert.Equal(t, cliNote1HTML.Body, "html1", "cliNote1HTML Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookCSS.Label, "css", "cliBookCSS Label mismatch")
|
|
assert.Equal(t, cliBookGo.Label, "go", "cliBookGo Label mismatch")
|
|
assert.Equal(t, cliBookHTML.Label, "html", "cliBookHTML Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliNote1CSS.Deleted, false, "cliNote1CSS Deleted mismatch")
|
|
assert.Equal(t, cliNote1Go.Deleted, false, "cliNote1Go Deleted mismatch")
|
|
assert.Equal(t, cliNote1HTML.Deleted, false, "cliNote1HTML Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS.Deleted, false, "cliBookCSS Deleted mismatch")
|
|
assert.Equal(t, cliBookGo.Deleted, false, "cliBookGo Deleted mismatch")
|
|
assert.Equal(t, cliBookHTML.Deleted, false, "cliBookHTML Deleted mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS, apiNote1CSS, apiNote1Go, apiNote1HTML database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["goNote1UUID"]).First(&apiNote1Go), "finding apiNote1Go")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1CSS.UUID).First(&apiNote1CSS), "finding apiNote1CSS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1HTML.UUID).First(&apiNote1HTML), "finding apiNote1HTML")
|
|
var apiBookJS, apiBookCSS, apiBookGo, apiBookHTML database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["goBookUUID"]).First(&apiBookGo), "finding apiBookGo")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookCSS.UUID).First(&apiBookCSS), "finding apiBookCSS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookHTML.UUID).First(&apiBookHTML), "finding apiBookHTML")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiNote1CSS.USN, 0, "apiNote1CSS USN mismatch")
|
|
assert.NotEqual(t, apiNote1Go.USN, 0, "apiNote1Go USN mismatch")
|
|
assert.NotEqual(t, apiNote1HTML.USN, 0, "apiNote1HTM USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
assert.NotEqual(t, apiBookGo.USN, 0, "apiBookGo USN mismatch")
|
|
assert.NotEqual(t, apiBookCSS.USN, 0, "apiBookCSS USN mismatch")
|
|
assert.NotEqual(t, apiBookHTML.USN, 0, "apiBookHTML USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1CSS.Body, "css1", "apiNote1CSS Body mismatch")
|
|
assert.Equal(t, apiNote1Go.Body, "go1", "apiNote1Go Body mismatch")
|
|
assert.Equal(t, apiNote1HTML.Body, "html1", "apiNote1HTM Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookGo.Label, "go", "apiBookGo Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "css", "apiBookCSS Label mismatch")
|
|
assert.Equal(t, apiBookHTML.Label, "html", "apiBookHTML Label mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
}
|
|
|
|
func TestSync(t *testing.T) {
|
|
t.Run("client adds a book and a note", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js1")
|
|
|
|
return map[string]string{}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 2,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 2,
|
|
})
|
|
|
|
// test client
|
|
// assert on bodys and labels
|
|
var cliNote1JS cliDatabase.Note
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js1"), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1JS.UUID).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookJS.UUID).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client deletes a book", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
clitest.WaitDnoteCmd(t, dnoteCmdOpts, clitest.UserConfirm, cliBinaryName, "remove", "js")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 0,
|
|
clientBookCount: 0,
|
|
clientLastMaxUSN: 5,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 5,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, true, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, true, "apiBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client deletes a note", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
cliDB := ctx.DB
|
|
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
var nid string
|
|
cliDatabase.MustScan(t, "getting id of note to remove", cliDB.QueryRow("SELECT rowid FROM notes WHERE uuid = ?", jsNote1UUID), &nid)
|
|
clitest.WaitDnoteCmd(t, dnoteCmdOpts, clitest.UserConfirm, cliBinaryName, "remove", "js", nid)
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 0,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 3,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 3,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, true, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE label = ?", "js"), &cliBookJS.Label, &cliBookJS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client edits a note", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
cliDB := ctx.DB
|
|
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
var nid string
|
|
cliDatabase.MustScan(t, "getting id of note to edit", cliDB.QueryRow("SELECT rowid FROM notes WHERE uuid = ?", jsNote1UUID), &nid)
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "js", nid, "-c", "js1-edited")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 3,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 3,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1-edited", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliNote1JS cliDatabase.Note
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT body, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1-edited", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client edits a book by renaming it", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "js", "-n", "js-edited")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 3,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 3,
|
|
})
|
|
|
|
// test client
|
|
var cliBookJS cliDatabase.Book
|
|
var cliNote1JS cliDatabase.Note
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, book_uuid, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.BookUUID, &cliNote1JS.USN)
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1JS.BookUUID, cliBookJS.UUID, "cliNote1JS BookUUID mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js-edited", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
// assert on dirty
|
|
assert.Equal(t, cliNote1JS.Dirty, false, "cliNote1JS Dirty mismatch")
|
|
assert.Equal(t, cliBookJS.Dirty, false, "cliBookJS Dirty mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js-edited", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server adds a book", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 0,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 1,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 0,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 1,
|
|
})
|
|
|
|
// test server
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
// assert on bodys and labels
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE label = ?", "js"), &cliBookJS.Label, &cliBookJS.USN)
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server edits a book by renaming it", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
apiPatchBook(t, user, jsBookUUID, fmt.Sprintf(`{"name": "%s"}`, "js-new-label"), "editing js book")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 0,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 2,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 0,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 2,
|
|
})
|
|
|
|
// test server
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiBookJS.Label, "js-new-label", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
// assert on bodys and labels
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
assert.Equal(t, cliBookJS.Label, "js-new-label", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server deletes a book", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
apiDeleteBook(t, user, jsBookUUID, "deleting js book")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 0,
|
|
clientBookCount: 0,
|
|
clientLastMaxUSN: 2,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 0,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 2,
|
|
})
|
|
|
|
// test server
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiBookJS.Label, "", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiBookJS.Deleted, true, "apiBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server adds a note", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 2,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 2,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["jsBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliNote1JS cliDatabase.Note
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT body, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server edits a note body", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
apiPatchNote(t, user, jsNote1UUID, fmt.Sprintf(`{"content": "%s"}`, "js1-edited"), "editing js note 1")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 3,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 3,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1-edited", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["jsBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliNote1JS cliDatabase.Note
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT body, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1-edited", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server moves a note to another book", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
cssBookUUID := apiCreateBook(t, user, "css", "adding css book")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
apiPatchNote(t, user, jsNote1UUID, fmt.Sprintf(`{"book_uuid": "%s"}`, cssBookUUID), "moving js note 1 to css book")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
"cssBookUUID": cssBookUUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 2,
|
|
clientLastMaxUSN: 4,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 2,
|
|
serverUserMaxUSN: 4,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS, apiBookCSS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssBookUUID"]).First(&apiBookCSS), "finding apiBookCSS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
assert.NotEqual(t, apiBookCSS.USN, 0, "apiBookCSS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["cssBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "css", "apiBookCSS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS.Deleted, false, "apiBookCSS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliNote1JS cliDatabase.Note
|
|
var cliBookJS, cliBookCSS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT body, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookCSS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["cssBookUUID"]), &cliBookCSS.Label, &cliBookCSS.USN)
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookCSS.Label, "css", "cliBookCSS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS.Deleted, false, "cliBookCSS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server deletes a note", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
apiDeleteNote(t, user, jsNote1UUID, "deleting js note 1")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 0,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 3,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 3,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["jsBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, true, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client and server deletes the same book", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
apiDeleteBook(t, user, jsBookUUID, "deleting js book")
|
|
|
|
// 4. on cli
|
|
clitest.WaitDnoteCmd(t, dnoteCmdOpts, clitest.UserConfirm, cliBinaryName, "remove", "js")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 0,
|
|
clientBookCount: 0,
|
|
clientLastMaxUSN: 6,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 6,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["jsBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, true, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, true, "apiBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client and server deletes the same note", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
cliDB := ctx.DB
|
|
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
apiDeleteNote(t, user, jsNote1UUID, "deleting js note 1")
|
|
|
|
// 4. on cli
|
|
var nid string
|
|
cliDatabase.MustScan(t, "getting id of note to remove", cliDB.QueryRow("SELECT rowid FROM notes WHERE body = ?", "js1"), &nid)
|
|
clitest.WaitDnoteCmd(t, dnoteCmdOpts, clitest.UserConfirm, cliBinaryName, "remove", "js", nid)
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
apiDB := apitest.DB
|
|
cliDB := ctx.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 0,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 4,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 4,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["jsBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, true, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server and client adds a note with same body", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 4. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js1")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 2,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 3,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 2,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 3,
|
|
})
|
|
|
|
// test client
|
|
var cliNote1JS, cliNote2JS cliDatabase.Note
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote2JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ? and uuid != ?", "js1", ids["jsNote1UUID"]), &cliNote2JS.UUID, &cliNote2JS.Body, &cliNote2JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote2JS.Body, "js1", "cliNote2JS Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliNote2JS.Deleted, false, "cliNote2JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS, apiNote2JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote2JS.UUID).First(&apiNote2JS), "finding apiNote2JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiNote2JS.USN, 0, "apiNote2JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote2JS.Body, "js1", "apiNote2JS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server and client adds a book with same label", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js1")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 2,
|
|
clientBookCount: 2,
|
|
clientLastMaxUSN: 4,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 2,
|
|
serverBookCount: 2,
|
|
serverUserMaxUSN: 4,
|
|
})
|
|
|
|
// test client
|
|
var cliNote1JS, cliNote1JS2 cliDatabase.Note
|
|
var cliBookJS, cliBookJS2 cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1JS2",
|
|
cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ? AND uuid !=?", "js1", ids["jsNote1UUID"]), &cliNote1JS2.UUID, &cliNote1JS2.Body, &cliNote1JS2.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS2", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js_2"), &cliBookJS2.UUID, &cliBookJS2.Label, &cliBookJS2.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1JS2.Body, "js1", "cliNote1JS2 Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookJS2.Label, "js_2", "cliBookJS2 Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliNote1JS2.Deleted, false, "cliNote1JS2 Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS2.Deleted, false, "cliBookJS2 Deleted mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS, apiNote1JS2 database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1JS2.UUID).First(&apiNote1JS2), "finding apiNote1JS2")
|
|
var apiBookJS, apiBookJS2 database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookJS2.UUID).First(&apiBookJS2), "finding apiBookJS2")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiNote1JS2.USN, 0, "apiNote1JS2 USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS2.USN, 0, "apiBookJS2 USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS2.Body, "js1", "apiNote1JS2 Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookJS2.Label, "js_2", "apiBookJS2 Label mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server and client adds two sets of books with same labels", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
cssBookUUID := apiCreateBook(t, user, "css", "adding css book")
|
|
cssNote1UUID := apiCreateNote(t, user, cssBookUUID, "css1", "adding css note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js1")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "css", "-c", "css1")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
"cssBookUUID": cssBookUUID,
|
|
"cssNote1UUID": cssNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 4,
|
|
clientBookCount: 4,
|
|
clientLastMaxUSN: 8,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 4,
|
|
serverBookCount: 4,
|
|
serverUserMaxUSN: 8,
|
|
})
|
|
|
|
// test client
|
|
var cliNote1JS, cliNote1JS2, cliNote1CSS, cliNote1CSS2 cliDatabase.Note
|
|
var cliBookJS, cliBookJS2, cliBookCSS, cliBookCSS2 cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1JS2",
|
|
cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ? AND uuid != ?", "js1", ids["jsNote1UUID"]), &cliNote1JS2.UUID, &cliNote1JS2.Body, &cliNote1JS2.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1CSS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE uuid = ?", ids["cssNote1UUID"]), &cliNote1CSS.UUID, &cliNote1CSS.Body, &cliNote1CSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1CSS2",
|
|
cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ? AND uuid != ?", "css1", ids["cssNote1UUID"]), &cliNote1CSS2.UUID, &cliNote1CSS2.Body, &cliNote1CSS2.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS2", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js_2"), &cliBookJS2.UUID, &cliBookJS2.Label, &cliBookJS2.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookCSS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css"), &cliBookCSS.UUID, &cliBookCSS.Label, &cliBookCSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookCSS2", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css_2"), &cliBookCSS2.UUID, &cliBookCSS2.Label, &cliBookCSS2.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1JS2.Body, "js1", "cliNote1JS2 Body mismatch")
|
|
assert.Equal(t, cliNote1CSS.Body, "css1", "cliNote1CSS Body mismatch")
|
|
assert.Equal(t, cliNote1CSS2.Body, "css1", "cliNote1CSS2 Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookJS2.Label, "js_2", "cliBookJS2 Label mismatch")
|
|
assert.Equal(t, cliBookCSS.Label, "css", "cliBookCSS Label mismatch")
|
|
assert.Equal(t, cliBookCSS2.Label, "css_2", "cliBookCSS2 Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliNote1JS2.Deleted, false, "cliNote1JS2 Deleted mismatch")
|
|
assert.Equal(t, cliNote1CSS.Deleted, false, "cliNote1CSS Deleted mismatch")
|
|
assert.Equal(t, cliNote1CSS2.Deleted, false, "cliNote1CSS2 Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS2.Deleted, false, "cliBookJS2 Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS.Deleted, false, "cliBookCSS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS2.Deleted, false, "cliBookCSS2 Deleted mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS, apiNote1JS2, apiNote1CSS, apiNote1CSS2 database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1JS2.UUID).First(&apiNote1JS2), "finding apiNote1JS2")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssNote1UUID"]).First(&apiNote1CSS), "finding apiNote1CSS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1CSS2.UUID).First(&apiNote1CSS2), "finding apiNote1CSS2")
|
|
var apiBookJS, apiBookJS2, apiBookCSS, apiBookCSS2 database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookJS2.UUID).First(&apiBookJS2), "finding apiBookJS2")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssBookUUID"]).First(&apiBookCSS), "finding apiBookCSS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookCSS2.UUID).First(&apiBookCSS2), "finding apiBookCSS2")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiNote1JS2.USN, 0, "apiNote1JS2 USN mismatch")
|
|
assert.NotEqual(t, apiNote1CSS.USN, 0, "apiNote1CSS USN mismatch")
|
|
assert.NotEqual(t, apiNote1CSS2.USN, 0, "apiNote1CSS2 USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS2.USN, 0, "apiBookJS2 USN mismatch")
|
|
assert.NotEqual(t, apiBookCSS.USN, 0, "apiBookCSS USN mismatch")
|
|
assert.NotEqual(t, apiBookCSS2.USN, 0, "apiBookCSS2 USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS2.Body, "js1", "apiNote1JS2 Body mismatch")
|
|
assert.Equal(t, apiNote1CSS.Body, "css1", "apiNote1CSS2 Body mismatch")
|
|
assert.Equal(t, apiNote1CSS2.Body, "css1", "apiNote1CSS2 Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookJS2.Label, "js_2", "apiBookJS2 Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "css", "apiBookCSS Label mismatch")
|
|
assert.Equal(t, apiBookCSS2.Label, "css_2", "apiBookCSS2 Label mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server and client adds notes to the same book", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 4. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js2")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 2,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 3,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 2,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 3,
|
|
})
|
|
|
|
// test client
|
|
var cliNote1JS, cliNote2JS cliDatabase.Note
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js1"), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote2JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js2"), &cliNote2JS.UUID, &cliNote2JS.Body, &cliNote2JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote2JS.Body, "js2", "cliNote2JS Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliNote2JS.Deleted, false, "cliNote2JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS, apiNote2JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote2JS.UUID).First(&apiNote2JS), "finding apiNote2JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiNote2JS.USN, 0, "apiNote2JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote2JS.Body, "js2", "apiNote2JS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server and client adds a book with the same label and notes in it", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "js", "-c", "js2")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 2,
|
|
clientBookCount: 2,
|
|
clientLastMaxUSN: 4,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 2,
|
|
serverBookCount: 2,
|
|
serverUserMaxUSN: 4,
|
|
})
|
|
|
|
// test client
|
|
var cliNote1JS, cliNote2JS cliDatabase.Note
|
|
var cliBookJS, cliBookJS2 cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js1"), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote2JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js2"), &cliNote2JS.UUID, &cliNote2JS.Body, &cliNote2JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS2", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js_2"), &cliBookJS2.UUID, &cliBookJS2.Label, &cliBookJS2.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote2JS.Body, "js2", "cliNote2JS Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookJS2.Label, "js_2", "cliBookJS2 Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliNote2JS.Deleted, false, "cliNote2JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS2.Deleted, false, "cliBookJS2 Deleted mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS, apiNote2JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote2JS.UUID).First(&apiNote2JS), "finding apiNote2JS")
|
|
var apiBookJS, apiBookJS2 database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookJS2.UUID).First(&apiBookJS2), "finding apiBookJS2")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiNote2JS.USN, 0, "apiNote2JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS2.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote2JS.Body, "js2", "apiNote2JS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookJS2.Label, "js_2", "apiBookJS2 USN mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client and server edits bodys of the same note", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
cliDB := ctx.DB
|
|
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
var nid string
|
|
cliDatabase.MustScan(t, "getting id of note to edit", cliDB.QueryRow("SELECT rowid FROM notes WHERE uuid = ?", jsNote1UUID), &nid)
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "js", nid, "-c", "js1-edited-from-client")
|
|
|
|
// 3. on server
|
|
apiPatchNote(t, user, jsNote1UUID, fmt.Sprintf(`{"content": "%s"}`, "js1-edited-from-server"), "editing js note 1")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
resolvedBody := "<<<<<<< Local\njs1-edited-from-client\n=======\njs1-edited-from-server\n>>>>>>> Server\n"
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 4,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 4,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, resolvedBody, "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliNote1JS cliDatabase.Note
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT body, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, resolvedBody, "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("clients deletes a note and server edits its body", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
cliDB := ctx.DB
|
|
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
var nid string
|
|
cliDatabase.MustScan(t, "getting id of note to remove", cliDB.QueryRow("SELECT rowid FROM notes WHERE uuid = ?", jsNote1UUID), &nid)
|
|
clitest.WaitDnoteCmd(t, dnoteCmdOpts, clitest.UserConfirm, cliBinaryName, "remove", "js", nid)
|
|
|
|
// 3. on server
|
|
apiPatchNote(t, user, jsNote1UUID, fmt.Sprintf(`{"content": "%s"}`, "js1-edited"), "editing js note 1")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 3,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 3,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1-edited", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliNote1JS cliDatabase.Note
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT body, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1-edited", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("clients deletes a note and server moves it to another book", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
cliDB := ctx.DB
|
|
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
cssBookUUID := apiCreateBook(t, user, "css", "adding css book")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
var nid string
|
|
cliDatabase.MustScan(t, "getting id of note to remove", cliDB.QueryRow("SELECT rowid FROM notes WHERE uuid = ?", jsNote1UUID), &nid)
|
|
clitest.WaitDnoteCmd(t, dnoteCmdOpts, clitest.UserConfirm, cliBinaryName, "remove", "js", nid)
|
|
|
|
// 3. on server
|
|
apiPatchNote(t, user, jsNote1UUID, fmt.Sprintf(`{"book_uuid": "%s"}`, cssBookUUID), "moving js note 1 to css book")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
"cssBookUUID": cssBookUUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 2,
|
|
clientLastMaxUSN: 4,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 2,
|
|
serverUserMaxUSN: 4,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS, apiBookCSS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssBookUUID"]).First(&apiBookCSS), "finding apiBookCSS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
assert.NotEqual(t, apiBookCSS.USN, 0, "apiBookCSS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["cssBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "css", "apiBookCSS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS.Deleted, false, "apiBookCSS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliNote1JS cliDatabase.Note
|
|
var cliBookJS, cliBookCSS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT body, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookCSS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["cssBookUUID"]), &cliBookCSS.Label, &cliBookCSS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1JS.BookUUID, ids["cssNote1UUID"], "cliNote1JS BookUUID mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookCSS.Label, "css", "cliBookCSS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS.Deleted, false, "cliBookCSS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server deletes a note and client edits it", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
cliDB := ctx.DB
|
|
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
apiDeleteNote(t, user, jsNote1UUID, "deleting js note 1")
|
|
|
|
// 4. on cli
|
|
var nid string
|
|
cliDatabase.MustScan(t, "getting id of note to edit", cliDB.QueryRow("SELECT rowid FROM notes WHERE body = ?", "js1"), &nid)
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "js", nid, "-c", "js1-edited")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 4,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 4,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1-edited", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["jsBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliNote1JS cliDatabase.Note
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT body, book_uuid, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.Body, &cliNote1JS.BookUUID, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1-edited", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1JS.BookUUID, ids["jsBookUUID"], "cliNote1JS BookUUID mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server deletes a book and client edits it by renaming it", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
apiDeleteNote(t, user, jsNote1UUID, "deleting js note 1")
|
|
|
|
// 4. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "js", "-n", "js-edited")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 0,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 4,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 4,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["jsBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js-edited", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, true, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliBookJS.Label, "js-edited", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("server deletes a book and client edits a note in it", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
cliDB := ctx.DB
|
|
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
apiDeleteBook(t, user, jsBookUUID, "deleting js book")
|
|
|
|
// 4. on cli
|
|
var nid string
|
|
cliDatabase.MustScan(t, "getting id of note to edit", cliDB.QueryRow("SELECT rowid FROM notes WHERE body = ?", "js1"), &nid)
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "js", nid, "-c", "js1-edited")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 6,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 6,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1-edited", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["jsBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliNote1JS cliDatabase.Note
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT body, book_uuid, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.Body, &cliNote1JS.BookUUID, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1-edited", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1JS.BookUUID, ids["jsBookUUID"], "cliNote1JS BookUUID mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client deletes a book and server edits it by renaming it", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
clitest.WaitDnoteCmd(t, dnoteCmdOpts, clitest.UserConfirm, cliBinaryName, "remove", "js")
|
|
|
|
// 3. on server
|
|
apiPatchBook(t, user, jsBookUUID, fmt.Sprintf(`{"name": "%s"}`, "js-edited"), "editing js book")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 0,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 5,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 5,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["jsBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js-edited", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, true, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliBookJS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.Label, &cliBookJS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliBookJS.Label, "js-edited", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client deletes a book and server edits a note in it", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
apiPatchNote(t, user, jsNote1UUID, fmt.Sprintf(`{"content": "%s"}`, "js1-edited"), "editing js1 note")
|
|
|
|
// 4. on cli
|
|
clitest.WaitDnoteCmd(t, dnoteCmdOpts, clitest.UserConfirm, cliBinaryName, "remove", "js")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 0,
|
|
clientBookCount: 0,
|
|
clientLastMaxUSN: 6,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 6,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["jsBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, true, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, true, "apiBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client and server edit a book by renaming it to a same name", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "js", "-n", "js-edited")
|
|
|
|
// 3. on server
|
|
apiPatchBook(t, user, jsBookUUID, fmt.Sprintf(`{"name": "%s"}`, "js-edited"), "editing js book")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 4,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 4,
|
|
})
|
|
|
|
// test client
|
|
var cliBookJS cliDatabase.Book
|
|
var cliNote1JS cliDatabase.Note
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, book_uuid, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.BookUUID, &cliNote1JS.USN)
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1JS.BookUUID, cliBookJS.UUID, "cliNote1JS BookUUID mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js-edited", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
// assert on dirty
|
|
assert.Equal(t, cliNote1JS.Dirty, false, "cliNote1JS Dirty mismatch")
|
|
assert.Equal(t, cliBookJS.Dirty, false, "cliBookJS Dirty mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js-edited", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client and server edit a book by renaming it to different names", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "js", "-n", "js-edited-client")
|
|
|
|
// 3. on server
|
|
apiPatchBook(t, user, jsBookUUID, fmt.Sprintf(`{"name": "%s"}`, "js-edited-server"), "editing js book")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
// In this case, server's change wins and overwrites that of client's
|
|
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 1,
|
|
clientLastMaxUSN: 4,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 1,
|
|
serverUserMaxUSN: 4,
|
|
})
|
|
|
|
// test client
|
|
var cliBookJS cliDatabase.Book
|
|
var cliNote1JS cliDatabase.Note
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE uuid = ?", ids["jsBookUUID"]), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, book_uuid, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.BookUUID, &cliNote1JS.USN)
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1JS.BookUUID, cliBookJS.UUID, "cliNote1JS BookUUID mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js-edited-server", "cliBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
// assert on dirty
|
|
assert.Equal(t, cliNote1JS.Dirty, false, "cliNote1JS Dirty mismatch")
|
|
assert.Equal(t, cliBookJS.Dirty, false, "cliBookJS Dirty mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js-edited-server", "apiBookJS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client moves a note", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
cssBookUUID := apiCreateBook(t, user, "css", "adding a css book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "1", "-b", "css")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"cssBookUUID": cssBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 2,
|
|
clientLastMaxUSN: 4,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 2,
|
|
serverUserMaxUSN: 4,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS, apiBookCSS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssBookUUID"]).First(&apiBookCSS), "finding apiBookCSS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["cssBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "css", "apiBookCSS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS.Deleted, false, "apiBookCSS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliBookJS, cliBookCSS cliDatabase.Book
|
|
var cliNote1JS cliDatabase.Note
|
|
cliDatabase.MustScan(t, "finding cli book js", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cli book css", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css"), &cliBookCSS.UUID, &cliBookCSS.Label, &cliBookCSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, book_uuid, body, usn FROM notes WHERE body = ?", "js1"), &cliNote1JS.UUID, &cliNote1JS.BookUUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
assert.NotEqual(t, cliBookCSS.USN, 0, "cliBookCSS USN mismatch")
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1JS.BookUUID, cliBookCSS.UUID, "cliNote1JS BookUUID mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookCSS.Label, "css", "cliBookCSS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS.Deleted, false, "cliBookCSS Deleted mismatch")
|
|
// assert on dirty
|
|
assert.Equal(t, cliNote1JS.Dirty, false, "cliNote1JS Dirty mismatch")
|
|
assert.Equal(t, cliBookJS.Dirty, false, "cliBookJS Dirty mismatch")
|
|
assert.Equal(t, cliBookCSS.Dirty, false, "cliBookCSS Dirty mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client and server each moves a note to a same book", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
cssBookUUID := apiCreateBook(t, user, "css", "adding a css book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
apiPatchNote(t, user, jsNote1UUID, fmt.Sprintf(`{"book_uuid": "%s"}`, cssBookUUID), "moving js note 1 to css book")
|
|
|
|
// 3. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "1", "-b", "css")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"cssBookUUID": cssBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 2,
|
|
clientLastMaxUSN: 5,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 2,
|
|
serverUserMaxUSN: 5,
|
|
})
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS, apiBookCSS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssBookUUID"]).First(&apiBookCSS), "finding apiBookCSS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, ids["cssBookUUID"], "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "css", "apiBookCSS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS.Deleted, false, "apiBookCSS Deleted mismatch")
|
|
|
|
// test client
|
|
var cliBookJS, cliBookCSS cliDatabase.Book
|
|
var cliNote1JS cliDatabase.Note
|
|
cliDatabase.MustScan(t, "finding cli book js", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cli book css", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css"), &cliBookCSS.UUID, &cliBookCSS.Label, &cliBookCSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, book_uuid, body, usn FROM notes WHERE body = ?", "js1"), &cliNote1JS.UUID, &cliNote1JS.BookUUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
assert.NotEqual(t, cliBookCSS.USN, 0, "cliBookCSS USN mismatch")
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1JS.BookUUID, cliBookCSS.UUID, "cliNote1JS BookUUID mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookCSS.Label, "css", "cliBookCSS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS.Deleted, false, "cliBookCSS Deleted mismatch")
|
|
// assert on dirty
|
|
assert.Equal(t, cliNote1JS.Dirty, false, "cliNote1JS Dirty mismatch")
|
|
assert.Equal(t, cliBookJS.Dirty, false, "cliBookJS Dirty mismatch")
|
|
assert.Equal(t, cliBookCSS.Dirty, false, "cliBookCSS Dirty mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client and server each moves a note to different books", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
cssBookUUID := apiCreateBook(t, user, "css", "adding a css book")
|
|
linuxBookUUID := apiCreateBook(t, user, "linux", "adding a linux book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
apiPatchNote(t, user, jsNote1UUID, fmt.Sprintf(`{"book_uuid": "%s"}`, cssBookUUID), "moving js note 1 to css book")
|
|
|
|
// 3. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "1", "-b", "linux")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"cssBookUUID": cssBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
"linuxBookUUID": linuxBookUUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
expectedNote1JSBody := `<<<<<<< Local
|
|
Moved to the book linux
|
|
=======
|
|
Moved to the book css
|
|
>>>>>>> Server
|
|
|
|
js1`
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 1,
|
|
clientBookCount: 4,
|
|
clientLastMaxUSN: 7,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 1,
|
|
serverBookCount: 4,
|
|
serverUserMaxUSN: 7,
|
|
})
|
|
|
|
// test client
|
|
var cliBookJS, cliBookCSS, cliBookLinux, cliBookConflicts cliDatabase.Book
|
|
var cliNote1JS cliDatabase.Note
|
|
cliDatabase.MustScan(t, "finding cli book js", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cli book css", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css"), &cliBookCSS.UUID, &cliBookCSS.Label, &cliBookCSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookLinux", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "linux"), &cliBookLinux.UUID, &cliBookLinux.Label, &cliBookLinux.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookConflicts", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "conflicts"), &cliBookConflicts.UUID, &cliBookConflicts.Label, &cliBookConflicts.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, book_uuid, body, usn FROM notes WHERE uuid = ?", ids["jsNote1UUID"]), &cliNote1JS.UUID, &cliNote1JS.BookUUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
assert.NotEqual(t, cliBookCSS.USN, 0, "cliBookCSS USN mismatch")
|
|
assert.NotEqual(t, cliBookLinux.USN, 0, "cliBookLinux USN mismatch")
|
|
assert.NotEqual(t, cliBookConflicts.USN, 0, "cliBookConflicts USN mismatch")
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, expectedNote1JSBody, "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1JS.BookUUID, cliBookConflicts.UUID, "cliNote1JS BookUUID mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookCSS.Label, "css", "cliBookCSS Label mismatch")
|
|
assert.Equal(t, cliBookLinux.Label, "linux", "cliBookLinux Label mismatch")
|
|
assert.Equal(t, cliBookConflicts.Label, "conflicts", "cliBookConflicts Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS.Deleted, false, "cliBookCSS Deleted mismatch")
|
|
assert.Equal(t, cliBookLinux.Deleted, false, "cliBookLinux Deleted mismatch")
|
|
assert.Equal(t, cliBookConflicts.Deleted, false, "cliBookConflicts Deleted mismatch")
|
|
// assert on dirty
|
|
assert.Equal(t, cliNote1JS.Dirty, false, "cliNote1JS Dirty mismatch")
|
|
assert.Equal(t, cliBookJS.Dirty, false, "cliBookJS Dirty mismatch")
|
|
assert.Equal(t, cliBookCSS.Dirty, false, "cliBookCSS Dirty mismatch")
|
|
assert.Equal(t, cliBookLinux.Dirty, false, "cliBookLinux Dirty mismatch")
|
|
assert.Equal(t, cliBookConflicts.Dirty, false, "cliBookConflicts Dirty mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
var apiBookJS, apiBookCSS, apiBookLinux, apiBookConflicts database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssBookUUID"]).First(&apiBookCSS), "finding apiBookCSS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["linuxBookUUID"]).First(&apiBookLinux), "finding apiBookLinux")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookConflicts.UUID).First(&apiBookConflicts), "finding apiBookConflicts")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
assert.NotEqual(t, apiBookCSS.USN, 0, "apiBookCSS USN mismatch")
|
|
assert.NotEqual(t, apiBookConflicts.USN, 0, "apiBookConflicts USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, expectedNote1JSBody, "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, apiBookConflicts.UUID, "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "css", "apiBookCSS Label mismatch")
|
|
assert.Equal(t, apiBookLinux.Label, "linux", "apiBookLinux Label mismatch")
|
|
assert.Equal(t, apiBookConflicts.Label, "conflicts", "apiBookConflicts Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS.Deleted, false, "apiBookCSS Deleted mismatch")
|
|
assert.Equal(t, apiBookLinux.Deleted, false, "apiBookLinux Deleted mismatch")
|
|
assert.Equal(t, apiBookConflicts.Deleted, false, "apiBookConflicts Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client adds a new book and moves a note into it", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "css", "-c", "css1")
|
|
|
|
cliDB := ctx.DB
|
|
var nid string
|
|
cliDatabase.MustScan(t, "getting id of note to edit", cliDB.QueryRow("SELECT rowid FROM notes WHERE body = ?", "js1"), &nid)
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", "js", nid, "-b", "css")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 2,
|
|
clientBookCount: 2,
|
|
clientLastMaxUSN: 5,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 2,
|
|
serverBookCount: 2,
|
|
serverUserMaxUSN: 5,
|
|
})
|
|
|
|
// test client
|
|
var cliBookJS, cliBookCSS cliDatabase.Book
|
|
var cliNote1JS, cliNote1CSS cliDatabase.Note
|
|
cliDatabase.MustScan(t, "finding cli book js", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cli book css", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css"), &cliBookCSS.UUID, &cliBookCSS.Label, &cliBookCSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, book_uuid, body, usn FROM notes WHERE body = ?", "js1"), &cliNote1JS.UUID, &cliNote1JS.BookUUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1CSS", cliDB.QueryRow("SELECT uuid, book_uuid, body, usn FROM notes WHERE body = ?", "css1"), &cliNote1CSS.UUID, &cliNote1CSS.BookUUID, &cliNote1CSS.Body, &cliNote1CSS.USN)
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
assert.NotEqual(t, cliBookCSS.USN, 0, "cliBookCSS USN mismatch")
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
assert.NotEqual(t, cliNote1CSS.USN, 0, "cliNote1CSS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1JS.BookUUID, cliBookCSS.UUID, "cliNote1JS BookUUID mismatch")
|
|
assert.Equal(t, cliNote1CSS.Body, "css1", "cliNote1CSS Body mismatch")
|
|
assert.Equal(t, cliNote1CSS.BookUUID, cliBookCSS.UUID, "cliNote1CSS BookUUID mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookCSS.Label, "css", "cliBookCSS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliNote1CSS.Deleted, false, "cliNote1CSS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS.Deleted, false, "cliBookCSS Deleted mismatch")
|
|
// assert on dirty
|
|
assert.Equal(t, cliNote1JS.Dirty, false, "cliNote1JS Dirty mismatch")
|
|
assert.Equal(t, cliNote1CSS.Dirty, false, "cliNote1CSS Dirty mismatch")
|
|
assert.Equal(t, cliBookJS.Dirty, false, "cliBookJS Dirty mismatch")
|
|
assert.Equal(t, cliBookCSS.Dirty, false, "cliBookCSS Dirty mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS, apiNote1CSS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1CSS.UUID).First(&apiNote1CSS), "finding apiNote1CSS")
|
|
var apiBookJS, apiBookCSS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookCSS.UUID).First(&apiBookCSS), "finding apiBookCSS")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiNote1CSS.USN, 0, "apiNote1CSS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
assert.NotEqual(t, apiBookCSS.USN, 0, "apiBookCSS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, apiBookCSS.UUID, "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiNote1CSS.Body, "css1", "apiNote1CSS Body mismatch")
|
|
assert.Equal(t, apiNote1CSS.BookUUID, apiBookCSS.UUID, "apiNote1CSS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "css", "apiBookCSS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiNote1CSS.Deleted, false, "apiNote1CSS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS.Deleted, false, "apiBookCSS Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
|
|
t.Run("client adds a duplicate book and moves a note into it", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
// 1. on server
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
// 2. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
|
|
// 3. on server
|
|
cssBookUUID := apiCreateBook(t, user, "css", "adding a css book")
|
|
|
|
// 3. on cli
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "css", "-c", "css1")
|
|
|
|
var nid string
|
|
cliDatabase.MustScan(t, "getting id of note to edit", ctx.DB.QueryRow("SELECT rowid FROM notes WHERE body = ?", "js1"), &nid)
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "edit", nid, "-b", "css")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"cssBookUUID": cssBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 2,
|
|
clientBookCount: 3,
|
|
clientLastMaxUSN: 6,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 2,
|
|
serverBookCount: 3,
|
|
serverUserMaxUSN: 6,
|
|
})
|
|
|
|
// test client
|
|
var cliBookJS, cliBookCSS, cliBookCSS2 cliDatabase.Book
|
|
var cliNote1JS, cliNote1CSS cliDatabase.Note
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookCSS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css"), &cliBookCSS.UUID, &cliBookCSS.Label, &cliBookCSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookCSS2", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css_2"), &cliBookCSS2.UUID, &cliBookCSS2.Label, &cliBookCSS2.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, book_uuid, usn FROM notes WHERE body = ?", "js1"), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.BookUUID, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1CSS", cliDB.QueryRow("SELECT uuid, body, book_uuid, usn FROM notes WHERE body = ?", "css1"), &cliNote1CSS.UUID, &cliNote1CSS.Body, &cliNote1CSS.BookUUID, &cliNote1CSS.USN)
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
assert.NotEqual(t, cliBookCSS.USN, 0, "cliBookCSS USN mismatch")
|
|
assert.NotEqual(t, cliBookCSS2.USN, 0, "cliBookCSS2 USN mismatch")
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
assert.NotEqual(t, cliNote1CSS.USN, 0, "cliNote1CSS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1JS.BookUUID, cliBookCSS2.UUID, "cliNote1JS BookUUID mismatch")
|
|
assert.Equal(t, cliNote1CSS.Body, "css1", "cliNote1CSS Body mismatch")
|
|
assert.Equal(t, cliNote1CSS.BookUUID, cliBookCSS2.UUID, "cliNote1CSS BookUUID mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookCSS.Label, "css", "cliBookCSS Label mismatch")
|
|
assert.Equal(t, cliBookCSS2.Label, "css_2", "cliBookCSS2 Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliNote1CSS.Deleted, false, "cliNote1CSS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS.Deleted, false, "cliBookCSS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS2.Deleted, false, "cliBookCSS2 Deleted mismatch")
|
|
// assert on dirty
|
|
assert.Equal(t, cliNote1JS.Dirty, false, "cliNote1JS Dirty mismatch")
|
|
assert.Equal(t, cliNote1CSS.Dirty, false, "cliNote1CSS Dirty mismatch")
|
|
assert.Equal(t, cliBookJS.Dirty, false, "cliBookJS Dirty mismatch")
|
|
assert.Equal(t, cliBookCSS.Dirty, false, "cliBookCSS Dirty mismatch")
|
|
assert.Equal(t, cliBookCSS2.Dirty, false, "cliBookCSS2 Dirty mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS, apiNote1CSS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding apiNote1JS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1CSS.UUID).First(&apiNote1CSS), "finding apiNote1CSS")
|
|
var apiBookJS, apiBookCSS, apiBookCSS2 database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding apiBookJS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["cssBookUUID"]).First(&apiBookCSS), "finding apiBookCSS")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookCSS2.UUID).First(&apiBookCSS2), "finding apiBookCSS2")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS USN mismatch")
|
|
assert.NotEqual(t, apiNote1CSS.USN, 0, "apiNote1CSS USN mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS USN mismatch")
|
|
assert.NotEqual(t, apiBookCSS.USN, 0, "apiBookCSS USN mismatch")
|
|
assert.NotEqual(t, apiBookCSS2.USN, 0, "apiBookCSS2 USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1JS.BookUUID, apiBookCSS2.UUID, "apiNote1JS BookUUID mismatch")
|
|
assert.Equal(t, apiNote1CSS.Body, "css1", "apiNote1CSS Body mismatch")
|
|
assert.Equal(t, apiNote1CSS.BookUUID, apiBookCSS2.UUID, "apiNote1CSS BookUUID mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "css", "apiBookCSS Label mismatch")
|
|
assert.Equal(t, apiBookCSS2.Label, "css_2", "apiBookCSS2 Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiNote1CSS.Deleted, false, "apiNote1CSS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS.Deleted, false, "apiBookCSS Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS2.Deleted, false, "apiBookCSS2 Deleted mismatch")
|
|
}
|
|
|
|
testSyncCmd(t, false, setup, assert)
|
|
testSyncCmd(t, true, setup, assert)
|
|
})
|
|
}
|
|
|
|
func TestFullSync(t *testing.T) {
|
|
t.Run("consecutively with stepSync", func(t *testing.T) {
|
|
setup := func(t *testing.T, ctx context.DnoteCtx, user database.User) map[string]string {
|
|
jsBookUUID := apiCreateBook(t, user, "js", "adding a js book")
|
|
jsNote1UUID := apiCreateNote(t, user, jsBookUUID, "js1", "adding js note 1")
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "add", "css", "-c", "css1")
|
|
|
|
return map[string]string{
|
|
"jsBookUUID": jsBookUUID,
|
|
"jsNote1UUID": jsNote1UUID,
|
|
}
|
|
}
|
|
|
|
assert := func(t *testing.T, ctx context.DnoteCtx, user database.User, ids map[string]string) {
|
|
cliDB := ctx.DB
|
|
apiDB := apitest.DB
|
|
|
|
checkState(t, ctx, user, systemState{
|
|
clientNoteCount: 2,
|
|
clientBookCount: 2,
|
|
clientLastMaxUSN: 4,
|
|
clientLastSyncAt: serverTime.Unix(),
|
|
serverNoteCount: 2,
|
|
serverBookCount: 2,
|
|
serverUserMaxUSN: 4,
|
|
})
|
|
|
|
// test client
|
|
var cliNote1JS, cliNote1CSS cliDatabase.Note
|
|
var cliBookJS, cliBookCSS cliDatabase.Book
|
|
cliDatabase.MustScan(t, "finding cliNote1JS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "js1"), &cliNote1JS.UUID, &cliNote1JS.Body, &cliNote1JS.USN)
|
|
cliDatabase.MustScan(t, "finding cliNote1CSS", cliDB.QueryRow("SELECT uuid, body, usn FROM notes WHERE body = ?", "css1"), &cliNote1CSS.UUID, &cliNote1CSS.Body, &cliNote1CSS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookJS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "js"), &cliBookJS.UUID, &cliBookJS.Label, &cliBookJS.USN)
|
|
cliDatabase.MustScan(t, "finding cliBookCSS", cliDB.QueryRow("SELECT uuid, label, usn FROM books WHERE label = ?", "css"), &cliBookCSS.UUID, &cliBookCSS.Label, &cliBookCSS.USN)
|
|
|
|
// test usn
|
|
assert.NotEqual(t, cliNote1JS.USN, 0, "cliNote1JS USN mismatch")
|
|
assert.NotEqual(t, cliNote1CSS.USN, 0, "cliNote1CSS USN mismatch")
|
|
assert.NotEqual(t, cliBookJS.USN, 0, "cliBookJS USN mismatch")
|
|
assert.NotEqual(t, cliBookCSS.USN, 0, "cliBookCSS USN mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, cliNote1JS.Body, "js1", "cliNote1JS Body mismatch")
|
|
assert.Equal(t, cliNote1CSS.Body, "css1", "cliNote1CSS Body mismatch")
|
|
assert.Equal(t, cliBookJS.Label, "js", "cliBookJS Label mismatch")
|
|
assert.Equal(t, cliBookCSS.Label, "css", "cliBookCSS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, cliNote1JS.Deleted, false, "cliNote1JS Deleted mismatch")
|
|
assert.Equal(t, cliNote1CSS.Deleted, false, "cliNote1CSS Deleted mismatch")
|
|
assert.Equal(t, cliBookJS.Deleted, false, "cliBookJS Deleted mismatch")
|
|
assert.Equal(t, cliBookCSS.Deleted, false, "cliBookCSS Deleted mismatch")
|
|
|
|
// test server
|
|
var apiNote1JS, apiNote1CSS database.Note
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsNote1UUID"]).First(&apiNote1JS), "finding api js note 1")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliNote1CSS.UUID).First(&apiNote1CSS), "finding api css note 1")
|
|
var apiBookJS, apiBookCSS database.Book
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, ids["jsBookUUID"]).First(&apiBookJS), "finding api js book")
|
|
apitest.MustExec(t, apiDB.Where("user_id = ? AND uuid = ?", user.ID, cliBookCSS.UUID).First(&apiBookCSS), "finding api css book")
|
|
|
|
// assert on usn
|
|
assert.NotEqual(t, apiNote1JS.USN, 0, "apiNote1JS usn mismatch")
|
|
assert.NotEqual(t, apiNote1CSS.USN, 0, "apiNote1CSS usn mismatch")
|
|
assert.NotEqual(t, apiBookJS.USN, 0, "apiBookJS usn mismatch")
|
|
assert.NotEqual(t, apiBookCSS.USN, 0, "apiBookCSS usn mismatch")
|
|
// assert on bodys and labels
|
|
assert.Equal(t, apiNote1JS.Body, "js1", "apiNote1JS Body mismatch")
|
|
assert.Equal(t, apiNote1CSS.Body, "css1", "apiNote1CSS Body mismatch")
|
|
assert.Equal(t, apiBookJS.Label, "js", "apiBookJS Label mismatch")
|
|
assert.Equal(t, apiBookCSS.Label, "css", "apiBookCSS Label mismatch")
|
|
// assert on deleted
|
|
assert.Equal(t, apiNote1JS.Deleted, false, "apiNote1JS Deleted mismatch")
|
|
assert.Equal(t, apiNote1CSS.Deleted, false, "apiNote1CSS Deleted mismatch")
|
|
assert.Equal(t, apiBookJS.Deleted, false, "apiBookJS Deleted mismatch")
|
|
assert.Equal(t, apiBookCSS.Deleted, false, "apiBookCSS Deleted mismatch")
|
|
}
|
|
|
|
t.Run("stepSync then fullSync", func(t *testing.T) {
|
|
// clean up
|
|
os.RemoveAll(tmpDirPath)
|
|
apitest.ClearData(apitest.DB)
|
|
defer apitest.ClearData(apitest.DB)
|
|
|
|
ctx := context.InitTestCtx(t, paths, nil)
|
|
defer context.TeardownTestCtx(t, ctx)
|
|
user := setupUser(t, &ctx)
|
|
ids := setup(t, ctx, user)
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
assert(t, ctx, user, ids)
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync", "-f")
|
|
assert(t, ctx, user, ids)
|
|
})
|
|
|
|
t.Run("fullSync then stepSync", func(t *testing.T) {
|
|
// clean up
|
|
os.RemoveAll(tmpDirPath)
|
|
apitest.ClearData(apitest.DB)
|
|
defer apitest.ClearData(apitest.DB)
|
|
|
|
ctx := context.InitTestCtx(t, paths, nil)
|
|
defer context.TeardownTestCtx(t, ctx)
|
|
|
|
user := setupUser(t, &ctx)
|
|
ids := setup(t, ctx, user)
|
|
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync", "-f")
|
|
assert(t, ctx, user, ids)
|
|
clitest.RunDnoteCmd(t, dnoteCmdOpts, cliBinaryName, "sync")
|
|
assert(t, ctx, user, ids)
|
|
})
|
|
})
|
|
}
|