mirror of
https://github.com/sartoopjj/thefeed.git
synced 2026-05-19 10:34:34 +03:00
264 lines
7.2 KiB
Go
264 lines
7.2 KiB
Go
package e2e_test
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/sartoopjj/thefeed/internal/client"
|
|
"github.com/sartoopjj/thefeed/internal/protocol"
|
|
)
|
|
|
|
func TestE2E_FetchMetadataThroughDNS(t *testing.T) {
|
|
domain := "feed.example.com"
|
|
passphrase := "test-secret-key-123"
|
|
channels := []string{"news", "tech"}
|
|
|
|
msgs := map[int][]protocol.Message{
|
|
1: {
|
|
{ID: 100, Timestamp: 1700000000, Text: "Hello from news"},
|
|
{ID: 101, Timestamp: 1700000001, Text: "Second news"},
|
|
},
|
|
2: {
|
|
{ID: 200, Timestamp: 1700000010, Text: "Tech update"},
|
|
},
|
|
}
|
|
|
|
resolver, cancel := startDNSServer(t, domain, passphrase, channels, msgs)
|
|
defer cancel()
|
|
|
|
fetcher, err := client.NewFetcher(domain, passphrase, []string{resolver})
|
|
if err != nil {
|
|
t.Fatalf("create fetcher: %v", err)
|
|
}
|
|
fetcher.SetActiveResolvers([]string{resolver})
|
|
|
|
meta, err := fetcher.FetchMetadata(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("fetch metadata: %v", err)
|
|
}
|
|
|
|
if len(meta.Channels) != 2 {
|
|
t.Fatalf("expected 2 channels, got %d", len(meta.Channels))
|
|
}
|
|
if meta.Channels[0].Name != "news" {
|
|
t.Errorf("channel 0 name = %q, want %q", meta.Channels[0].Name, "news")
|
|
}
|
|
if meta.Channels[1].Name != "tech" {
|
|
t.Errorf("channel 1 name = %q, want %q", meta.Channels[1].Name, "tech")
|
|
}
|
|
if meta.Channels[0].LastMsgID != 100 {
|
|
t.Errorf("channel 0 lastMsgID = %d, want 100", meta.Channels[0].LastMsgID)
|
|
}
|
|
}
|
|
|
|
func TestE2E_FetchChannelMessages(t *testing.T) {
|
|
domain := "feed.example.com"
|
|
passphrase := "e2e-pass-456"
|
|
channels := []string{"updates"}
|
|
|
|
msgs := map[int][]protocol.Message{
|
|
1: {
|
|
{ID: 1, Timestamp: 1700000000, Text: "First message"},
|
|
{ID: 2, Timestamp: 1700000001, Text: "Second message"},
|
|
{ID: 3, Timestamp: 1700000002, Text: "Third message"},
|
|
},
|
|
}
|
|
|
|
resolver, cancel := startDNSServer(t, domain, passphrase, channels, msgs)
|
|
defer cancel()
|
|
|
|
fetcher, err := client.NewFetcher(domain, passphrase, []string{resolver})
|
|
if err != nil {
|
|
t.Fatalf("create fetcher: %v", err)
|
|
}
|
|
fetcher.SetActiveResolvers([]string{resolver})
|
|
|
|
meta, err := fetcher.FetchMetadata(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("fetch metadata: %v", err)
|
|
}
|
|
|
|
blockCount := int(meta.Channels[0].Blocks)
|
|
if blockCount <= 0 {
|
|
t.Fatal("expected blocks > 0")
|
|
}
|
|
|
|
fetchedMsgs, err := fetcher.FetchChannel(context.Background(), 1, blockCount)
|
|
if err != nil {
|
|
t.Fatalf("fetch channel: %v", err)
|
|
}
|
|
|
|
if len(fetchedMsgs) != 3 {
|
|
t.Fatalf("expected 3 messages, got %d", len(fetchedMsgs))
|
|
}
|
|
|
|
for i, want := range msgs[1] {
|
|
got := fetchedMsgs[i]
|
|
if got.ID != want.ID || got.Text != want.Text {
|
|
t.Errorf("message %d: got {ID:%d Text:%q}, want {ID:%d Text:%q}",
|
|
i, got.ID, got.Text, want.ID, want.Text)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestE2E_FetchWithDoubleLabel(t *testing.T) {
|
|
domain := "feed.example.com"
|
|
passphrase := "double-label-test"
|
|
channels := []string{"channel1"}
|
|
|
|
msgs := map[int][]protocol.Message{
|
|
1: {{ID: 10, Timestamp: 1700000000, Text: "Double label message"}},
|
|
}
|
|
|
|
resolver, cancel := startDNSServer(t, domain, passphrase, channels, msgs)
|
|
defer cancel()
|
|
|
|
fetcher, err := client.NewFetcher(domain, passphrase, []string{resolver})
|
|
if err != nil {
|
|
t.Fatalf("create fetcher: %v", err)
|
|
}
|
|
fetcher.SetActiveResolvers([]string{resolver})
|
|
fetcher.SetQueryMode(protocol.QueryMultiLabel)
|
|
|
|
meta, err := fetcher.FetchMetadata(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("fetch metadata: %v", err)
|
|
}
|
|
|
|
fetchedMsgs, err := fetcher.FetchChannel(context.Background(), 1, int(meta.Channels[0].Blocks))
|
|
if err != nil {
|
|
t.Fatalf("fetch channel: %v", err)
|
|
}
|
|
|
|
if len(fetchedMsgs) != 1 {
|
|
t.Fatalf("expected 1 message, got %d", len(fetchedMsgs))
|
|
}
|
|
if fetchedMsgs[0].Text != "Double label message" {
|
|
t.Errorf("message text = %q, want %q", fetchedMsgs[0].Text, "Double label message")
|
|
}
|
|
}
|
|
|
|
func TestE2E_WrongPassphrase(t *testing.T) {
|
|
domain := "feed.example.com"
|
|
channels := []string{"ch1"}
|
|
|
|
msgs := map[int][]protocol.Message{
|
|
1: {{ID: 1, Timestamp: 1700000000, Text: "secret"}},
|
|
}
|
|
|
|
resolver, cancel := startDNSServer(t, domain, "server-key", channels, msgs)
|
|
defer cancel()
|
|
|
|
fetcher, err := client.NewFetcher(domain, "wrong-key", []string{resolver})
|
|
if err != nil {
|
|
t.Fatalf("create fetcher: %v", err)
|
|
}
|
|
fetcher.SetActiveResolvers([]string{resolver})
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
|
defer cancel()
|
|
_, err = fetcher.FetchMetadata(ctx)
|
|
if err == nil {
|
|
t.Fatal("expected error with wrong passphrase, got nil")
|
|
}
|
|
}
|
|
|
|
func TestE2E_LargeMessages(t *testing.T) {
|
|
domain := "feed.example.com"
|
|
passphrase := "large-msg-test"
|
|
channels := []string{"big"}
|
|
|
|
longText := strings.Repeat("A", 500)
|
|
msgs := map[int][]protocol.Message{
|
|
1: {
|
|
{ID: 1, Timestamp: 1700000000, Text: longText},
|
|
{ID: 2, Timestamp: 1700000001, Text: "Short"},
|
|
},
|
|
}
|
|
|
|
resolver, cancel := startDNSServer(t, domain, passphrase, channels, msgs)
|
|
defer cancel()
|
|
|
|
fetcher, err := client.NewFetcher(domain, passphrase, []string{resolver})
|
|
if err != nil {
|
|
t.Fatalf("create fetcher: %v", err)
|
|
}
|
|
fetcher.SetActiveResolvers([]string{resolver})
|
|
|
|
meta, err := fetcher.FetchMetadata(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("fetch metadata: %v", err)
|
|
}
|
|
|
|
fetchedMsgs, err := fetcher.FetchChannel(context.Background(), 1, int(meta.Channels[0].Blocks))
|
|
if err != nil {
|
|
t.Fatalf("fetch channel: %v", err)
|
|
}
|
|
|
|
if len(fetchedMsgs) != 2 {
|
|
t.Fatalf("expected 2 messages, got %d", len(fetchedMsgs))
|
|
}
|
|
if fetchedMsgs[0].Text != longText {
|
|
t.Errorf("long message length = %d, want %d", len(fetchedMsgs[0].Text), len(longText))
|
|
}
|
|
}
|
|
|
|
func TestE2E_AdminAllowManage(t *testing.T) {
|
|
domain := "manage.example.com"
|
|
passphrase := "manage-test"
|
|
channels := []string{"moderated"}
|
|
|
|
msgs := map[int][]protocol.Message{
|
|
1: {{ID: 1, Timestamp: 1700000000, Text: "Existing"}},
|
|
}
|
|
|
|
resolver, cancel := startDNSServerWithManage(t, domain, passphrase, true, channels, msgs)
|
|
defer cancel()
|
|
|
|
fetcher, err := client.NewFetcher(domain, passphrase, []string{resolver})
|
|
if err != nil {
|
|
t.Fatalf("create fetcher: %v", err)
|
|
}
|
|
fetcher.SetActiveResolvers([]string{resolver})
|
|
|
|
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer ctxCancel()
|
|
|
|
result, err := fetcher.SendAdminCommand(ctx, protocol.AdminCmdListChannels, "")
|
|
if err != nil {
|
|
t.Fatalf("expected admin command to succeed with allow-manage, got: %v", err)
|
|
}
|
|
if !strings.Contains(result, "moderated") {
|
|
t.Errorf("expected channel list to contain 'moderated', got: %q", result)
|
|
}
|
|
}
|
|
|
|
func TestE2E_AdminNoManage(t *testing.T) {
|
|
domain := "nomanage.example.com"
|
|
passphrase := "no-manage-test"
|
|
channels := []string{"public"}
|
|
|
|
msgs := map[int][]protocol.Message{
|
|
1: {{ID: 1, Timestamp: 1700000000, Text: "Public msg"}},
|
|
}
|
|
|
|
resolver, cancel := startDNSServer(t, domain, passphrase, channels, msgs)
|
|
defer cancel()
|
|
|
|
fetcher, err := client.NewFetcher(domain, passphrase, []string{resolver})
|
|
if err != nil {
|
|
t.Fatalf("create fetcher: %v", err)
|
|
}
|
|
fetcher.SetActiveResolvers([]string{resolver})
|
|
|
|
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer ctxCancel()
|
|
|
|
_, err = fetcher.SendAdminCommand(ctx, protocol.AdminCmdListChannels, "")
|
|
if err == nil {
|
|
t.Error("expected error when server has allow-manage disabled, got nil")
|
|
}
|
|
}
|