deeplink_test.go

  1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
  2//
  3// SPDX-License-Identifier: AGPL-3.0-or-later
  4
  5package deeplink_test
  6
  7import (
  8	"errors"
  9	"testing"
 10
 11	"git.secluded.site/lune/internal/deeplink"
 12)
 13
 14func TestParseID_Valid(t *testing.T) {
 15	t.Parallel()
 16
 17	const (
 18		uuidLower = "123e4567-e89b-12d3-a456-426614174000"
 19		uuidArea  = "3bbf1923-64ae-4bcf-96a9-9bb86c799dab"
 20		uuidGoal  = "9d79e922-9ca8-4b8c-9aa5-dd98bb2492b2"
 21	)
 22
 23	tests := []struct {
 24		name   string
 25		input  string
 26		wantID string
 27	}{
 28		{"UUID lowercase", uuidLower, uuidLower},
 29		{"UUID uppercase", "123E4567-E89B-12D3-A456-426614174000", uuidLower},
 30		{"deep link areas", "lunatask://areas/" + uuidArea, uuidArea},
 31		{"deep link goals", "lunatask://goals/" + uuidGoal, uuidGoal},
 32		{"deep link tasks", "lunatask://tasks/" + uuidArea, uuidArea},
 33		{"deep link notes", "lunatask://notes/" + uuidArea, uuidArea},
 34		{"deep link people", "lunatask://people/" + uuidArea, uuidArea},
 35		{"deep link notebooks", "lunatask://notebooks/" + uuidArea, uuidArea},
 36		{"with whitespace", "  " + uuidLower + "  ", uuidLower},
 37	}
 38
 39	for _, testCase := range tests {
 40		t.Run(testCase.name, func(t *testing.T) {
 41			t.Parallel()
 42
 43			id, err := deeplink.ParseID(testCase.input)
 44			if err != nil {
 45				t.Errorf("ParseID(%q) error = %v, want nil", testCase.input, err)
 46			}
 47
 48			if id != testCase.wantID {
 49				t.Errorf("ParseID(%q) = %q, want %q", testCase.input, id, testCase.wantID)
 50			}
 51		})
 52	}
 53}
 54
 55func TestParseID_Invalid(t *testing.T) {
 56	t.Parallel()
 57
 58	tests := []struct {
 59		name    string
 60		input   string
 61		wantErr error
 62	}{
 63		{"empty", "", deeplink.ErrInvalidReference},
 64		{"random text", "not-a-uuid", deeplink.ErrInvalidReference},
 65		{"invalid UUID", "123e4567-e89b-12d3-a456-42661417zzzz", deeplink.ErrInvalidReference},
 66		{"wrong scheme", "http://areas/123e4567-e89b-12d3-a456-426614174000", deeplink.ErrInvalidReference},
 67		{"invalid resource", "lunatask://habits/123e4567-e89b-12d3-a456-426614174000", deeplink.ErrUnsupportedResource},
 68		{"missing path", "lunatask://", deeplink.ErrInvalidReference},
 69		{"extra path", "lunatask://areas/foo/bar", deeplink.ErrInvalidReference},
 70	}
 71
 72	for _, testCase := range tests {
 73		t.Run(testCase.name, func(t *testing.T) {
 74			t.Parallel()
 75
 76			_, err := deeplink.ParseID(testCase.input)
 77			if !errors.Is(err, testCase.wantErr) {
 78				t.Errorf("ParseID(%q) error = %v, want %v", testCase.input, err, testCase.wantErr)
 79			}
 80		})
 81	}
 82}
 83
 84func TestBuild(t *testing.T) {
 85	t.Parallel()
 86
 87	const uuid = "3bbf1923-64ae-4bcf-96a9-9bb86c799dab"
 88
 89	tests := []struct {
 90		name     string
 91		resource deeplink.Resource
 92		id       string
 93		want     string
 94	}{
 95		{"area", deeplink.Area, uuid, "lunatask://areas/" + uuid},
 96		{"goal", deeplink.Goal, uuid, "lunatask://goals/" + uuid},
 97		{"task", deeplink.Task, uuid, "lunatask://tasks/" + uuid},
 98		{"note", deeplink.Note, uuid, "lunatask://notes/" + uuid},
 99		{"person", deeplink.Person, uuid, "lunatask://people/" + uuid},
100		{"notebook", deeplink.Notebook, uuid, "lunatask://notebooks/" + uuid},
101	}
102
103	for _, testCase := range tests {
104		t.Run(testCase.name, func(t *testing.T) {
105			t.Parallel()
106
107			got, err := deeplink.Build(testCase.resource, testCase.id)
108			if err != nil {
109				t.Errorf("Build(%v, %q) error = %v, want nil",
110					testCase.resource, testCase.id, err)
111			}
112
113			if got != testCase.want {
114				t.Errorf("Build(%v, %q) = %q, want %q",
115					testCase.resource, testCase.id, got, testCase.want)
116			}
117		})
118	}
119}
120
121func TestBuild_InvalidID(t *testing.T) {
122	t.Parallel()
123
124	_, err := deeplink.Build(deeplink.Area, "not-a-uuid")
125	if !errors.Is(err, deeplink.ErrInvalidReference) {
126		t.Errorf("Build(Area, \"not-a-uuid\") error = %v, want %v", err, deeplink.ErrInvalidReference)
127	}
128}