fetcher_test.go

  1package fetcher
  2
  3import (
  4	"testing"
  5
  6	"github.com/floatpane/matcha/config"
  7)
  8
  9// TestFetchEmails is an integration test that requires a live IMAP server and valid credentials.
 10// NOTE: This test will be skipped if it cannot load a configuration file,
 11// making it safe to run in a CI environment without credentials.
 12// To run this test locally, ensure you have a valid `config.json` file.
 13func TestFetchEmails(t *testing.T) {
 14	// Attempt to load the configuration.
 15	cfg, err := config.LoadConfig()
 16	if err != nil {
 17		// If config doesn't exist, skip the test. This is useful for CI environments.
 18		t.Skipf("Skipping TestFetchEmails: could not load config: %v", err)
 19	}
 20
 21	// Check if there are any accounts configured
 22	if !cfg.HasAccounts() {
 23		t.Skip("Skipping TestFetchEmails: no accounts configured.")
 24	}
 25
 26	// Get the first account
 27	account := cfg.GetFirstAccount()
 28	if account == nil {
 29		t.Skip("Skipping TestFetchEmails: no accounts available.")
 30	}
 31
 32	// If the password is a placeholder, skip the test to avoid failed auth attempts.
 33	if account.Password == "" || account.Password == "supersecret" {
 34		t.Skip("Skipping TestFetchEmails: placeholder or empty password found in config.")
 35	}
 36
 37	emails, err := FetchEmails(account, 10, 10)
 38	if err != nil {
 39		t.Fatalf("FetchEmails() failed with error: %v", err)
 40	}
 41
 42	if len(emails) == 0 {
 43		// This is not necessarily a failure, but we can log it.
 44		t.Log("FetchEmails() returned 0 emails. This might be expected.")
 45	}
 46
 47	// Check that the emails are sorted from newest to oldest.
 48	// Skip emails with zero/invalid dates when checking sort order.
 49	if len(emails) > 1 {
 50		var validEmails []Email
 51		for _, e := range emails {
 52			if !e.Date.IsZero() {
 53				validEmails = append(validEmails, e)
 54			}
 55		}
 56		if len(validEmails) > 1 {
 57			if validEmails[0].Date.Before(validEmails[len(validEmails)-1].Date) {
 58				t.Error("Emails do not appear to be sorted from newest to oldest.")
 59			}
 60		}
 61	}
 62
 63	// Check a sample email for expected content.
 64	for _, email := range emails {
 65		if email.Subject == "" && email.From == "" {
 66			t.Errorf("Fetched email has empty subject and from fields: %+v", email)
 67		}
 68	}
 69
 70	// Verify that AccountID is set on fetched emails
 71	for _, email := range emails {
 72		if email.AccountID != account.ID {
 73			t.Errorf("Expected AccountID %s, got %s", account.ID, email.AccountID)
 74		}
 75	}
 76}
 77
 78// TestFetchEmailsWithCustomServer tests fetching with a custom server configuration.
 79// This test is skipped unless a custom account is configured.
 80func TestFetchEmailsWithCustomServer(t *testing.T) {
 81	// Attempt to load the configuration.
 82	cfg, err := config.LoadConfig()
 83	if err != nil {
 84		t.Skipf("Skipping TestFetchEmailsWithCustomServer: could not load config: %v", err)
 85	}
 86
 87	// Look for a custom account
 88	var customAccount *config.Account
 89	for i := range cfg.Accounts {
 90		if cfg.Accounts[i].ServiceProvider == "custom" {
 91			customAccount = &cfg.Accounts[i]
 92			break
 93		}
 94	}
 95
 96	if customAccount == nil {
 97		t.Skip("Skipping TestFetchEmailsWithCustomServer: no custom account configured.")
 98	}
 99
100	if customAccount.Password == "" || customAccount.Password == "supersecret" {
101		t.Skip("Skipping TestFetchEmailsWithCustomServer: placeholder or empty password found.")
102	}
103
104	if customAccount.IMAPServer == "" {
105		t.Skip("Skipping TestFetchEmailsWithCustomServer: no IMAP server configured.")
106	}
107
108	emails, err := FetchEmails(customAccount, 5, 0)
109	if err != nil {
110		t.Fatalf("FetchEmails() with custom server failed: %v", err)
111	}
112
113	t.Logf("Fetched %d emails from custom server %s", len(emails), customAccount.IMAPServer)
114}