cli + tui to publish to leaflet (wip) & manage tasks, notes & watch/read lists 馃崈
charm leaflet readability golang
29
fork

Configure Feed

Select the types of activity you want to include in your feed.

at b5d8851190fc9c722d4e5dcc977e58042fbdec81 253 lines 6.5 kB view raw
1package main 2 3import ( 4 "context" 5 "strings" 6 "testing" 7 8 "github.com/stormlightlabs/noteleaf/internal/handlers" 9) 10 11func createTestPublicationHandler(t *testing.T) (*handlers.PublicationHandler, func()) { 12 cleanup := setupCommandTest(t) 13 handler, err := handlers.NewPublicationHandler() 14 if err != nil { 15 cleanup() 16 t.Fatalf("Failed to create test publication handler: %v", err) 17 } 18 return handler, func() { 19 handler.Close() 20 cleanup() 21 } 22} 23 24func TestPublicationCommand(t *testing.T) { 25 t.Run("CommandGroup Interface", func(t *testing.T) { 26 handler, cleanup := createTestPublicationHandler(t) 27 defer cleanup() 28 29 var _ CommandGroup = NewPublicationCommand(handler) 30 }) 31 32 t.Run("Create", func(t *testing.T) { 33 t.Run("creates command with correct structure", func(t *testing.T) { 34 handler, cleanup := createTestPublicationHandler(t) 35 defer cleanup() 36 37 cmd := NewPublicationCommand(handler).Create() 38 39 if cmd == nil { 40 t.Fatal("Create returned nil") 41 } 42 if cmd.Use != "pub" { 43 t.Errorf("Expected Use to be 'pub', got '%s'", cmd.Use) 44 } 45 if cmd.Short != "Manage leaflet publication sync" { 46 t.Errorf("Expected Short to be 'Manage leaflet publication sync', got '%s'", cmd.Short) 47 } 48 if !cmd.HasSubCommands() { 49 t.Error("Expected command to have subcommands") 50 } 51 }) 52 53 t.Run("has all expected subcommands", func(t *testing.T) { 54 handler, cleanup := createTestPublicationHandler(t) 55 defer cleanup() 56 57 cmd := NewPublicationCommand(handler).Create() 58 subcommands := cmd.Commands() 59 subcommandNames := make([]string, len(subcommands)) 60 for i, subcmd := range subcommands { 61 subcommandNames[i] = subcmd.Use 62 } 63 64 expectedSubcommands := []string{ 65 "auth [handle]", 66 "pull", 67 "list [--published|--draft|--all]", 68 "status", 69 } 70 71 for _, expected := range expectedSubcommands { 72 if !findSubcommand(subcommandNames, expected) { 73 t.Errorf("Expected subcommand '%s' not found in %v", expected, subcommandNames) 74 } 75 } 76 }) 77 }) 78 79 t.Run("Status Command", func(t *testing.T) { 80 t.Run("shows not authenticated initially", func(t *testing.T) { 81 handler, cleanup := createTestPublicationHandler(t) 82 defer cleanup() 83 84 cmd := NewPublicationCommand(handler).Create() 85 cmd.SetArgs([]string{"status"}) 86 err := cmd.Execute() 87 88 if err != nil { 89 t.Errorf("status command failed: %v", err) 90 } 91 }) 92 }) 93 94 t.Run("List Command", func(t *testing.T) { 95 t.Run("default filter", func(t *testing.T) { 96 handler, cleanup := createTestPublicationHandler(t) 97 defer cleanup() 98 99 cmd := NewPublicationCommand(handler).Create() 100 cmd.SetArgs([]string{"list"}) 101 err := cmd.Execute() 102 103 if err != nil { 104 t.Errorf("list command failed: %v", err) 105 } 106 }) 107 108 t.Run("with published flag", func(t *testing.T) { 109 handler, cleanup := createTestPublicationHandler(t) 110 defer cleanup() 111 112 cmd := NewPublicationCommand(handler).Create() 113 cmd.SetArgs([]string{"list", "--published"}) 114 err := cmd.Execute() 115 116 if err != nil { 117 t.Errorf("list --published failed: %v", err) 118 } 119 }) 120 121 t.Run("with draft flag", func(t *testing.T) { 122 handler, cleanup := createTestPublicationHandler(t) 123 defer cleanup() 124 125 cmd := NewPublicationCommand(handler).Create() 126 cmd.SetArgs([]string{"list", "--draft"}) 127 err := cmd.Execute() 128 129 if err != nil { 130 t.Errorf("list --draft failed: %v", err) 131 } 132 }) 133 134 t.Run("with all flag", func(t *testing.T) { 135 handler, cleanup := createTestPublicationHandler(t) 136 defer cleanup() 137 138 cmd := NewPublicationCommand(handler).Create() 139 cmd.SetArgs([]string{"list", "--all"}) 140 err := cmd.Execute() 141 142 if err != nil { 143 t.Errorf("list --all failed: %v", err) 144 } 145 }) 146 147 t.Run("published takes precedence over draft", func(t *testing.T) { 148 handler, cleanup := createTestPublicationHandler(t) 149 defer cleanup() 150 151 cmd := NewPublicationCommand(handler).Create() 152 cmd.SetArgs([]string{"list", "--published", "--draft"}) 153 err := cmd.Execute() 154 155 if err != nil { 156 t.Errorf("list with multiple flags failed: %v", err) 157 } 158 }) 159 }) 160 161 t.Run("Pull Command", func(t *testing.T) { 162 t.Run("fails when not authenticated", func(t *testing.T) { 163 handler, cleanup := createTestPublicationHandler(t) 164 defer cleanup() 165 166 cmd := NewPublicationCommand(handler).Create() 167 cmd.SetArgs([]string{"pull"}) 168 err := cmd.Execute() 169 170 if err == nil { 171 t.Error("Expected pull to fail when not authenticated") 172 } 173 if err != nil && !strings.Contains(err.Error(), "not authenticated") { 174 t.Errorf("Expected 'not authenticated' error, got: %v", err) 175 } 176 }) 177 }) 178 179 t.Run("Command Help", func(t *testing.T) { 180 t.Run("root help", func(t *testing.T) { 181 handler, cleanup := createTestPublicationHandler(t) 182 defer cleanup() 183 184 cmd := NewPublicationCommand(handler).Create() 185 cmd.SetArgs([]string{"help"}) 186 err := cmd.Execute() 187 188 if err != nil { 189 t.Errorf("help command failed: %v", err) 190 } 191 }) 192 193 t.Run("auth help", func(t *testing.T) { 194 handler, cleanup := createTestPublicationHandler(t) 195 defer cleanup() 196 197 cmd := NewPublicationCommand(handler).Create() 198 cmd.SetArgs([]string{"auth", "--help"}) 199 err := cmd.Execute() 200 201 if err != nil { 202 t.Errorf("auth help failed: %v", err) 203 } 204 }) 205 }) 206 207 t.Run("Command Aliases", func(t *testing.T) { 208 t.Run("list alias ls works", func(t *testing.T) { 209 handler, cleanup := createTestPublicationHandler(t) 210 defer cleanup() 211 212 cmd := NewPublicationCommand(handler).Create() 213 cmd.SetArgs([]string{"ls"}) 214 err := cmd.Execute() 215 216 if err != nil { 217 t.Errorf("list alias 'ls' failed: %v", err) 218 } 219 }) 220 }) 221 222 t.Run("Handler Validation", func(t *testing.T) { 223 t.Run("auth validates empty handle", func(t *testing.T) { 224 handler, cleanup := createTestPublicationHandler(t) 225 defer cleanup() 226 227 ctx := context.Background() 228 err := handler.Auth(ctx, "", "password") 229 230 if err == nil { 231 t.Error("Expected error for empty handle") 232 } 233 if !strings.Contains(err.Error(), "handle is required") { 234 t.Errorf("Expected 'handle is required' error, got: %v", err) 235 } 236 }) 237 238 t.Run("auth validates empty password", func(t *testing.T) { 239 handler, cleanup := createTestPublicationHandler(t) 240 defer cleanup() 241 242 ctx := context.Background() 243 err := handler.Auth(ctx, "test.bsky.social", "") 244 245 if err == nil { 246 t.Error("Expected error for empty password") 247 } 248 if !strings.Contains(err.Error(), "password is required") { 249 t.Errorf("Expected 'password is required' error, got: %v", err) 250 } 251 }) 252 }) 253}