From 5cab29c3448f29b8bbbf907e3273b5b3f3586165 Mon Sep 17 00:00:00 2001 From: H0llyW00dzZ Date: Fri, 24 Jan 2025 12:34:51 +0000 Subject: [PATCH] Implement [Client] "ListMailboxes" (#14) - [+] feat(README.md): add functionality to list available mailboxes in the package description and usage examples - [+] feat(client): implement ListMailboxes method to retrieve all available mailboxes for the connected user - [+] test(client): add unit test for ListMailboxes method to validate mailbox retrieval functionality Reviewed-on: https://git.b0zal.io/H0llyW00dzZ/imap/pulls/14 Co-authored-by: H0llyW00dzZ Co-committed-by: H0llyW00dzZ --- README.md | 58 +++++++++++++++++++++++++++++++++++++++- client/docs.go | 37 ++++++++++++++++++++++++- client/imap_test.go | 29 ++++++++++++++++++++ client/list_mailboxes.go | 33 +++++++++++++++++++++++ 4 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 client/list_mailboxes.go diff --git a/README.md b/README.md index 318e367..3e587bd 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Go Reference](https://pkg.go.dev/badge/git.b0zal.io/H0llyW00dzZ/imap.svg)](https://pkg.go.dev/git.b0zal.io/H0llyW00dzZ/imap) [![Go Report Card](https://goreportcard.com/badge/git.b0zal.io/H0llyW00dzZ/imap)](https://goreportcard.com/report/git.b0zal.io/H0llyW00dzZ/imap) -This package provides a simple interface to manage IMAP connections for single or multiple users. It allows you to connect to an IMAP server, list messages, export messages, and manage multiple user accounts. +This package provides a simple interface to manage IMAP connections for single or multiple users. It allows you to connect to an IMAP server, list messages, export messages, manage multiple user accounts, and list available mailboxes. ## Features @@ -10,6 +10,7 @@ This package provides a simple interface to manage IMAP connections for single o - List messages in a specified mailbox - Export messages to various formats - Manage multiple users with separate IMAP clients +- **New**: List all available mailboxes ## Installation @@ -51,6 +52,13 @@ func main() { } defer imapClient.Disconnect() + // New: List all available mailboxes + mailboxes, err := imapClient.ListMailboxes() + if err != nil { + log.Fatalf("Failed to list mailboxes: %v", err) + } + fmt.Println("Mailboxes:", mailboxes) + messageConfig := client.MessageConfig{ GrabID: true, GrabFrom: true, @@ -93,6 +101,17 @@ func main() { } defer multiUserIMAP.DisconnectUser("user1@example.com") + // New: List all available mailboxes for user1 + client, err := multiUserIMAP.GetClient("user1@example.com") + if err != nil { + log.Fatalf("Failed to get client for user1: %v", err) + } + mailboxes, err := client.ListMailboxes() + if err != nil { + log.Fatalf("Failed to list mailboxes for user1: %v", err) + } + fmt.Println("User1 Mailboxes:", mailboxes) + messageConfig := client.MessageConfig{ GrabID: true, GrabFrom: true, @@ -161,6 +180,43 @@ func main() { } ``` +### List All Available Mailboxes + +```go +package main + +import ( + "fmt" + "log" + + "git.b0zal.io/H0llyW00dzZ/imap/client" +) + +func main() { + config := &client.Config{ + Username: "user@example.com", + Password: "password", + Server: "imap.example.com:993", + InsecureSkipVerify: true, + } + + imapClient := client.NewIMAP(config) + + err := imapClient.Connect() + if err != nil { + log.Fatalf("Failed to connect: %v", err) + } + defer imapClient.Disconnect() + + // List all available mailboxes + mailboxes, err := imapClient.ListMailboxes() + if err != nil { + log.Fatalf("Failed to list mailboxes: %v", err) + } + fmt.Println("Mailboxes:", mailboxes) +} +``` + ## TODO - Implement functionality to send emails. diff --git a/client/docs.go b/client/docs.go index 3646412..3c5b70d 100644 --- a/client/docs.go +++ b/client/docs.go @@ -5,13 +5,14 @@ // Package client provides a simple interface to manage IMAP connections // for single or multiple users. It allows you to connect to an IMAP server, -// list messages, export messages, and manage multiple user accounts. +// list messages, export messages, manage multiple user accounts, and list available mailboxes. // // # Features // - Connect and disconnect from an IMAP server // - List messages in a specified mailbox // - Export messages to various formats // - Manage multiple users with separate IMAP clients +// - List all available mailboxes // // # Usage // @@ -59,6 +60,40 @@ // } // } // +// List All Available Mailboxes Example: +// +// package main +// +// import ( +// "fmt" +// "log" +// +// "git.b0zal.io/H0llyW00dzZ/imap/client" +// ) +// +// func main() { +// config := &client.Config{ +// Username: "user@example.com", +// Password: "password", +// Server: "imap.example.com:993", +// InsecureSkipVerify: true, +// } +// +// imapClient := client.NewIMAP(config) +// +// err := imapClient.Connect() +// if err != nil { +// log.Fatalf("Failed to connect: %v", err) +// } +// defer imapClient.Disconnect() +// +// mailboxes, err := imapClient.ListMailboxes() +// if err != nil { +// log.Fatalf("Failed to list mailboxes: %v", err) +// } +// fmt.Println("Mailboxes:", mailboxes) +// } +// // Multiple Users Example: // // package main diff --git a/client/imap_test.go b/client/imap_test.go index 128cb96..1bde203 100644 --- a/client/imap_test.go +++ b/client/imap_test.go @@ -123,3 +123,32 @@ func TestListMessages(t *testing.T) { assert.Equal(t, expectedBody, messages[0][client.KeyBody], "Unexpected body content") } + +func TestListMailboxes(t *testing.T) { + listener, srv := setupTestServer() + defer listener.Close() + defer srv.Close() // Ensure the server is closed properly + + // Use the existing user in the memory backend + config := &client.Config{ + Username: "username", + Password: "password", + Server: listener.Addr().String(), + InsecureSkipVerify: true, + } + + imapClient := client.NewIMAP(config) + + // Connect to the server + err := imapClient.Connect() + assert.NoError(t, err, "Failed to connect") + defer imapClient.Disconnect() + + // List mailboxes + mailboxes, err := imapClient.ListMailboxes() + assert.NoError(t, err, "Failed to list mailboxes") + + // Validate the mailboxes + expectedMailboxes := []string{"INBOX"} + assert.ElementsMatch(t, expectedMailboxes, mailboxes, "Unexpected mailboxes") +} diff --git a/client/list_mailboxes.go b/client/list_mailboxes.go new file mode 100644 index 0000000..eacf62d --- /dev/null +++ b/client/list_mailboxes.go @@ -0,0 +1,33 @@ +package client + +import ( + "fmt" + + "github.com/emersion/go-imap" +) + +// ListMailboxes retrieves all available mailboxes for the connected user +func (c *IMAPClient) ListMailboxes() ([]string, error) { + if c.client == nil { + return nil, fmt.Errorf("client is not connected") + } + + mailboxes := make(chan *imap.MailboxInfo, 10) + done := make(chan error, 1) + + // Start listing mailboxes + go func() { + done <- c.client.List("", "*", mailboxes) + }() + + var mailboxNames []string + for m := range mailboxes { + mailboxNames = append(mailboxNames, m.Name) + } + + if err := <-done; err != nil { + return nil, fmt.Errorf("failed to list mailboxes: %v", err) + } + + return mailboxNames, nil +}