Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions cmd/wasm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func RegisterCallbacks(api *api.Api) {
}),
"cloneCalendar": js.FuncOf(func(this js.Value, args []js.Value) any {
return wrapPromise(func() (any, error) {
return nil, api.CloneCalendar(args[0].String(), args[1].String())
return nil, api.CloneCalendar(args[0].String(), args[1].String(), args[2].Bool())
})
}),
"removeCalendar": js.FuncOf(func(this js.Value, args []js.Value) any {
Expand All @@ -52,7 +52,7 @@ func RegisterCallbacks(api *api.Api) {
}),
"updateRemote": js.FuncOf(func(this js.Value, args []js.Value) any {
return wrapPromise(func() (any, error) {
return nil, api.UpdateRemote(args[0].String(), args[1].String())
return nil, api.UpdateRemote(args[0].String(), args[1].String(), args[2].Bool())
})
}),
"createEvent": js.FuncOf(func(this js.Value, args []js.Value) any {
Expand Down Expand Up @@ -90,6 +90,21 @@ func RegisterCallbacks(api *api.Api) {
return api.GetEvents(args[0].String(), args[1].String())
})
}),
"createTag": js.FuncOf(func(this js.Value, args []js.Value) any {
return wrapPromise(func() (any, error) {
return api.CreateTag(args[0].String(), args[1].String())
})
}),
"updateTag": js.FuncOf(func(this js.Value, args []js.Value) any {
return wrapPromise(func() (any, error) {
return api.UpdateTag(args[0].String(), args[1].String())
})
}),
"removeTag": js.FuncOf(func(this js.Value, args []js.Value) any {
return wrapPromise(func() (any, error) {
return nil, api.RemoveTag(args[0].String(), args[1].String())
})
}),
"setCorsProxy": js.FuncOf(func(this js.Value, args []js.Value) any {
return wrapPromise(func() (any, error) {
return nil, api.SetCorsProxy(args[0].String())
Expand Down
4 changes: 3 additions & 1 deletion e2e/calendars_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"github.com/git-calendar/core/pkg/filesystem"
)

const TestCalendarName = "test"

func TestCreateCalendar(t *testing.T) {
c := core.NewCore()

Expand Down Expand Up @@ -98,7 +100,7 @@ func TestListCalendars_WithRemote(t *testing.T) {

remoteUrl := "https://github.com/git-calendar/calendar.git"

err = c.UpdateRemote(TestCalendarName, mustParseUrl(remoteUrl))
err = c.UpdateRemote(TestCalendarName, mustParseUrl(remoteUrl), false)
if err != nil {
t.Fatalf("failed to update remotes: %v", err)
}
Expand Down
8 changes: 3 additions & 5 deletions e2e/events_repeating_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
"github.com/google/uuid"
)

const TestCalendarName = "test"

func TestRepeatingEvent_GetEvents_UntilWeekly_GeneratesOccurrencesInRange(t *testing.T) {
c := newTestCore(t)

Expand Down Expand Up @@ -150,7 +148,7 @@ func TestRepeatingEvent_Update_Current_DetachesOnlyTargetChild(t *testing.T) {
if detached.Repeat != nil {
t.Fatalf("detached event should not repeat")
}
if detached.ParentId != uuid.Nil {
if detached.ParentId != nil {
t.Fatalf("detached event should not have parent id, got %s", detached.ParentId)
}
if detached.Title != updated.Title {
Expand Down Expand Up @@ -226,7 +224,7 @@ func TestRepeatingEvent_Update_Following_SplitsSeriesFromTargetChild(t *testing.
t.Fatalf("failed to update child event with Following strategy: %v", err)
}

if newParent.ParentId != uuid.Nil {
if newParent.ParentId != nil {
t.Fatalf("new event should be a parent, got ParentId %s", newParent.ParentId)
}
if newParent.Title != updated.Title {
Expand Down Expand Up @@ -282,7 +280,7 @@ func TestRepeatingEvent_Update_Following_SecondChild_DoesNotLeaveInvalidOldParen
if err != nil {
t.Fatalf("failed to update second child with Following strategy: %v", err)
}
if newParent.ParentId != uuid.Nil {
if newParent.ParentId != nil {
t.Fatalf("new event should be a parent, got ParentId %s", newParent.ParentId)
}

Expand Down
10 changes: 5 additions & 5 deletions e2e/git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ func TestUpdateRemote_ReplacesExistingRemote(t *testing.T) {
oldCalRemote := "https://github.com/git-calendar/old-calendar.git"
newCalRemote := "https://github.com/git-calendar/new-calendar.git"

err = c.UpdateRemote(TestCalendarName, mustParseUrl(oldCalRemote))
err = c.UpdateRemote(TestCalendarName, mustParseUrl(oldCalRemote), false)
if err != nil {
t.Fatalf("failed to set initial remotes: %v", err)
}

err = c.UpdateRemote(TestCalendarName, mustParseUrl(newCalRemote))
err = c.UpdateRemote(TestCalendarName, mustParseUrl(newCalRemote), false)
if err != nil {
t.Fatalf("failed to replace remotes: %v", err)
}
Expand Down Expand Up @@ -69,12 +69,12 @@ func TestUpdateRemote_DeletesWhenEmpty(t *testing.T) {
_ = c.RemoveCalendar(TestCalendarName)
})

err = c.UpdateRemote(TestCalendarName, mustParseUrl("https://github.com/git-calendar/calendar.git"))
err = c.UpdateRemote(TestCalendarName, mustParseUrl("https://github.com/git-calendar/calendar.git"), false)
if err != nil {
t.Fatalf("failed to set remotes: %v", err)
}

err = c.UpdateRemote(TestCalendarName, nil)
err = c.UpdateRemote(TestCalendarName, nil, false)
if err != nil {
t.Fatalf("failed to clear remotes: %v", err)
}
Expand Down Expand Up @@ -113,7 +113,7 @@ func TestUpdateRemote_MissingCalendar(t *testing.T) {
t.Fatal(err)
}

err = c.UpdateRemote(TestCalendarName, mustParseUrl("https://github.com/git-calendar/calendar.git"))
err = c.UpdateRemote(TestCalendarName, mustParseUrl("https://github.com/git-calendar/calendar.git"), false)
if err == nil {
t.Fatal("expected error, got nil")
}
Expand Down
204 changes: 204 additions & 0 deletions e2e/tags_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
package e2e

import (
"testing"

"github.com/git-calendar/core/pkg/core"
"github.com/google/uuid"
)

const TestTagName = "test"

func TestTag_CreateTag_CreatesTag(t *testing.T) {
c := newTestCore(t)

tag := newTestTag("work", "blue")

created, err := c.CreateTag(TestTagName, tag)
if err != nil {
t.Fatalf("CreateTag failed: %v", err)
}
if created == nil {
t.Fatalf("expected created tag")
}

assertTagEqual(t, tag, *created)
}

func TestTag_CreateTag_DuplicateReturnsError(t *testing.T) {
c := newTestCore(t)

tag := newTestTag("work", "blue")

if _, err := c.CreateTag(TestTagName, tag); err != nil {
t.Fatalf("CreateTag failed: %v", err)
}

created, err := c.CreateTag(TestTagName, tag)
if err == nil {
t.Fatalf("expected duplicate tag error")
}
if created != nil {
t.Fatalf("expected nil created tag, got %+v", created)
}
}

func TestTag_CreateTag_InvalidTagReturnsError(t *testing.T) {
c := newTestCore(t)

tag := core.Tag{
Name: "",
Color: "blue",
}

created, err := c.CreateTag(TestTagName, tag)
if err == nil {
t.Fatalf("expected invalid tag error")
}
if created != nil {
t.Fatalf("expected nil created tag, got %+v", created)
}
}

func TestTag_UpdateTag_UpdatesExistingTag(t *testing.T) {
c := newTestCore(t)

tag := newTestTag("work", "blue")

if _, err := c.CreateTag(TestTagName, tag); err != nil {
t.Fatalf("CreateTag failed: %v", err)
}

updated := core.Tag{
Id: tag.Id,
Name: "personal",
Color: "blue",
}

got, err := c.UpdateTag(TestTagName, updated)
if err != nil {
t.Fatalf("UpdateTag failed: %v", err)
}
if got == nil {
t.Fatalf("expected updated tag")
}

assertTagEqual(t, updated, *got)
}

func TestTag_UpdateTag_InvalidTagReturnsError(t *testing.T) {
c := newTestCore(t)

tag := core.Tag{
Name: "work",
Color: "red",
}

updated, err := c.UpdateTag(TestTagName, tag)
if err == nil {
t.Fatalf("expected invalid tag error")
}
if updated != nil {
t.Fatalf("expected nil updated tag, got %+v", updated)
}
}

func TestTag_UpdateTag_MissingTagReturnsErrorInsteadOfPanicking(t *testing.T) {
c := newTestCore(t)

tag := newTestTag("missing", "blue")

defer func() {
if r := recover(); r != nil {
t.Fatalf("expected error for missing tag, got panic: %v", r)
}
}()

updated, err := c.UpdateTag(TestTagName, tag)
if err == nil {
t.Fatalf("expected missing tag error")
}
if updated != nil {
t.Fatalf("expected nil updated tag, got %+v", updated)
}
}

func TestTag_RemoveTag_RemovesTag(t *testing.T) {
c := newTestCore(t)

tag := newTestTag("work", "blue")

if _, err := c.CreateTag(TestTagName, tag); err != nil {
t.Fatalf("CreateTag failed: %v", err)
}

if err := c.RemoveTag(TestTagName, tag.Id); err != nil {
t.Fatalf("RemoveTag failed: %v", err)
}

// creating the same id again proves it was removed from the in-memory tag list
recreated := core.Tag{
Id: tag.Id,
Name: "recreated",
Color: "blue",
}

got, err := c.CreateTag(TestTagName, recreated)
if err != nil {
t.Fatalf("CreateTag after RemoveTag failed: %v", err)
}
if got == nil {
t.Fatalf("expected recreated tag")
}

assertTagEqual(t, recreated, *got)
}

func TestTag_RemoveTag_InvalidIdReturnsError(t *testing.T) {
c := newTestCore(t)

err := c.RemoveTag(TestTagName, uuid.Nil)
if err == nil {
t.Fatalf("expected invalid tag id error")
}
}

func TestTag_InvalidCalendarReturnsError(t *testing.T) {
c := newTestCore(t)

tag := newTestTag("work", "green")

if _, err := c.CreateTag("missing", tag); err == nil {
t.Fatalf("expected CreateTag invalid calendar error")
}

if _, err := c.UpdateTag("missing", tag); err == nil {
t.Fatalf("expected UpdateTag invalid calendar error")
}

if err := c.RemoveTag("missing", tag.Id); err == nil {
t.Fatalf("expected RemoveTag invalid calendar error")
}
}

func newTestTag(name string, color string) core.Tag {
return core.Tag{
Id: uuid.New(),
Name: name,
Color: color,
}
}

func assertTagEqual(t *testing.T, want core.Tag, got core.Tag) {
t.Helper()

if got.Id != want.Id {
t.Fatalf("tag id mismatch: expected %s, got %s", want.Id, got.Id)
}
if got.Name != want.Name {
t.Fatalf("tag name mismatch: expected %q, got %q", want.Name, got.Name)
}
if got.Color != want.Color {
t.Fatalf("tag color mismatch: expected %q, got %q", want.Color, got.Color)
}
}
15 changes: 10 additions & 5 deletions notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
- [x] connect repeating event exceptions
- exception needs to have uuid
- time encoded inside uuidv8
- [ ] config file per repo
- [ ] config file per repo?
- tags
- [ ] better tests
- [x] load repositories
Expand All @@ -29,7 +29,7 @@
- github-pages?
- custom http file server?
- [x] encryption
- [x] storing a key (in opfs?)
- [x] storing a key
- values-only
- deterministic? (same input <=> same output)
- +good git diffs
Expand All @@ -44,25 +44,30 @@

```
.git-calendar-data/
├── main/
├── default/
│ ├── .git/
│ ├── events/
│ │ └── <UUID>.json
│ ├── tags/
│ │ └── <UUID>.json
│ ├── index.jsonl
│ └── index-rich.jsonl
├── shared/
│ ├── .git/
│ ├── events/
│ │ └── <UUID>.json
│ ├── tags/
│ │ └── <UUID>.json
│ ├── index.jsonl
│ └── index-rich.jsonl
├── main.key
├── default.key
├── shared.readonly
└── shared.key
```


### Testing Web/Wasm parts:
(there are no wasm only test at this time, but could be useful)
(there are no wasm-only tests at this time, but could be useful)

Install [wasmbrowsertest](https://github.com/agnivade/wasmbrowsertest):
```sh
Expand Down
Loading