package nats import ( "errors" "fmt" "log" "strings" "testing" "github.com/nats-io/nats.go" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*Adaptor)(nil) func connStub(options ...nats.Option) func() (*nats.Conn, error) { return func() (*nats.Conn, error) { opts := nats.DefaultOptions for _, opt := range options { if err := opt(&opts); err != nil { return nil, err } } c := &nats.Conn{Opts: opts} return c, nil } } func initTestNatsAdaptor() *Adaptor { a := NewAdaptor("localhost:4222", 19999) a.connect = func() (*nats.Conn, error) { c := &nats.Conn{} return c, nil } return a } func initTestNatsAdaptorWithAuth() *Adaptor { a := NewAdaptorWithAuth("localhost:4222", 29999, "user", "pass") a.connect = func() (*nats.Conn, error) { c := &nats.Conn{} return c, nil } return a } func initTestNatsAdaptorTLS(options ...nats.Option) *Adaptor { a := NewAdaptor("tls://localhost:4242", 39999, options...) a.connect = connStub(options...) return a } func TestNatsAdaptorName(t *testing.T) { a := initTestNatsAdaptor() gobottest.Assert(t, strings.HasPrefix(a.Name(), "NATS"), true) a.SetName("NewName") gobottest.Assert(t, a.Name(), "NewName") } func TestNatsAdaptorReturnsHost(t *testing.T) { a := initTestNatsAdaptor() gobottest.Assert(t, a.Host, "nats://localhost:4222") } func TestNatsAdaptorWithAuth(t *testing.T) { a := initTestNatsAdaptorWithAuth() gobottest.Assert(t, a.username, "user") gobottest.Assert(t, a.password, "pass") } func TestNatsAdapterSetsRootCAs(t *testing.T) { a := initTestNatsAdaptorTLS(nats.RootCAs("test_certs/catest.pem")) gobottest.Assert(t, a.Host, "tls://localhost:4242") _ = a.Connect() o := a.client.Opts casPool, err := o.RootCAsCB() gobottest.Assert(t, err, nil) gobottest.Refute(t, casPool, nil) gobottest.Assert(t, o.Secure, true) } func TestNatsAdapterSetsClientCerts(t *testing.T) { a := initTestNatsAdaptorTLS(nats.ClientCert("test_certs/client-cert.pem", "test_certs/client-key.pem")) gobottest.Assert(t, a.Host, "tls://localhost:4242") _ = a.Connect() cert, err := a.client.Opts.TLSCertCB() gobottest.Assert(t, err, nil) gobottest.Refute(t, cert, nil) gobottest.Refute(t, cert.Leaf, nil) gobottest.Assert(t, a.client.Opts.Secure, true) } func TestNatsAdapterSetsClientCertsWithUserInfo(t *testing.T) { a := initTestNatsAdaptorTLS(nats.ClientCert("test_certs/client-cert.pem", "test_certs/client-key.pem"), nats.UserInfo("test", "testwd")) gobottest.Assert(t, a.Host, "tls://localhost:4242") _ = a.Connect() cert, err := a.client.Opts.TLSCertCB() gobottest.Assert(t, err, nil) gobottest.Refute(t, cert, nil) gobottest.Refute(t, cert.Leaf, nil) gobottest.Assert(t, a.client.Opts.Secure, true) gobottest.Assert(t, a.client.Opts.User, "test") gobottest.Assert(t, a.client.Opts.Password, "testwd") } // TODO: implement this test without requiring actual server connection func TestNatsAdaptorPublishWhenConnected(t *testing.T) { t.Skip("TODO: implement this test without requiring actual server connection") a := initTestNatsAdaptor() _ = a.Connect() data := []byte("o") gobottest.Assert(t, a.Publish("test", data), true) } // TODO: implement this test without requiring actual server connection func TestNatsAdaptorOnWhenConnected(t *testing.T) { t.Skip("TODO: implement this test without requiring actual server connection") a := initTestNatsAdaptor() _ = a.Connect() gobottest.Assert(t, a.On("hola", func(msg Message) { fmt.Println("hola") }), true) } // TODO: implement this test without requiring actual server connection func TestNatsAdaptorPublishWhenConnectedWithAuth(t *testing.T) { t.Skip("TODO: implement this test without requiring actual server connection") a := NewAdaptorWithAuth("localhost:4222", 49999, "test", "testwd") _ = a.Connect() data := []byte("o") gobottest.Assert(t, a.Publish("test", data), true) } // TODO: implement this test without requiring actual server connection func TestNatsAdaptorOnWhenConnectedWithAuth(t *testing.T) { t.Skip("TODO: implement this test without requiring actual server connection") log.Println("###not skipped###") a := NewAdaptorWithAuth("localhost:4222", 59999, "test", "testwd") _ = a.Connect() gobottest.Assert(t, a.On("hola", func(msg Message) { fmt.Println("hola") }), true) } func TestNatsAdaptorFailedConnect(t *testing.T) { a := NewAdaptor("localhost:9999", 69999) err := a.Connect() if err != nil && strings.Contains(err.Error(), "cannot assign requested address") { t.Skip("FLAKY: Can not test, because IP or port is in use.") } gobottest.Assert(t, err, errors.New("nats: no servers available for connection")) } func TestNatsAdaptorFinalize(t *testing.T) { a := NewAdaptor("localhost:9999", 79999) gobottest.Assert(t, a.Finalize(), nil) } func TestNatsAdaptorCannotPublishUnlessConnected(t *testing.T) { a := NewAdaptor("localhost:9999", 89999) data := []byte("o") gobottest.Assert(t, a.Publish("test", data), false) } func TestNatsAdaptorCannotOnUnlessConnected(t *testing.T) { a := NewAdaptor("localhost:9999", 99999) gobottest.Assert(t, a.On("hola", func(msg Message) { fmt.Println("hola") }), false) }