package neo4j import ( "context" "fmt" "testing" "time" "github.com/stretchr/testify/assert" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" ) func TestNewNeo4J(t *testing.T) { tests := []struct { name string conf *Config expected *Config }{ { name: "valid configuration", conf: &Config{ URI: "neo4j://localhost:7687", Username: "neo4j", Password: "password", LogLevel: "info", MaxConnectionLifetime: time.Minute * 5, MaxConnectionPoolSize: 10, ConnectionTimeout: time.Second * 5, }, expected: &Config{ URI: "neo4j://localhost:7687", Username: "neo4j", Password: "password", LogLevel: "info", }, }, { name: "empty URI", conf: &Config{ URI: "", Username: "neo4j", Password: "password", LogLevel: "info", MaxConnectionLifetime: time.Minute * 5, MaxConnectionPoolSize: 10, ConnectionTimeout: time.Second * 5, }, expected: &Config{ URI: "", Username: "neo4j", Password: "password", LogLevel: "info", }, }, { name: "empty username and password", conf: &Config{ URI: "neo4j://localhost:7687", Username: "", Password: "", LogLevel: "info", MaxConnectionLifetime: time.Minute * 5, MaxConnectionPoolSize: 10, ConnectionTimeout: time.Second * 5, }, expected: &Config{ URI: "neo4j://localhost:7687", Username: "", Password: "", LogLevel: "info", }, }, { name: "custom log level", conf: &Config{ URI: "neo4j://localhost:7687", Username: "neo4j", Password: "password", LogLevel: "debug", MaxConnectionLifetime: time.Minute * 5, MaxConnectionPoolSize: 10, ConnectionTimeout: time.Second * 5, }, expected: &Config{ URI: "neo4j://localhost:7687", Username: "neo4j", Password: "password", LogLevel: "debug", }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { client := NewNeo4J(tt.conf) assert.NotNil(t, client) assert.Equal(t, tt.expected.URI, client.serviceConf.URI) assert.Equal(t, tt.expected.Username, client.serviceConf.Username) assert.Equal(t, tt.expected.Password, client.serviceConf.Password) assert.Equal(t, tt.expected.LogLevel, client.serviceConf.LogLevel) }) } } func TestConn(t *testing.T) { ctx := context.Background() neo4jContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: testcontainers.ContainerRequest{ Image: "neo4j:latest", ExposedPorts: []string{"7687/tcp"}, Env: map[string]string{ "NEO4J_AUTH": "neo4j/yyyytttt", }, WaitingFor: wait.ForLog("Started"), }, Started: true, }) if err != nil { t.Fatal(err) } defer neo4jContainer.Terminate(ctx) host, _ := neo4jContainer.Host(ctx) port, _ := neo4jContainer.MappedPort(ctx, "7687") uri := fmt.Sprintf("bolt://%s:%s", host, port.Port()) t.Log("Neo4j running at:", uri) tests := []struct { name string conf *Config shouldFail bool }{ { name: "successful connection", conf: &Config{ URI: uri, Username: "neo4j", Password: "yyyytttt", LogLevel: "info", MaxConnectionLifetime: time.Minute * 5, MaxConnectionPoolSize: 10, ConnectionTimeout: time.Second * 5, }, shouldFail: false, }, { name: "failed connection due to invalid URI", conf: &Config{ URI: uri, Username: "neo4j", Password: "wrongpassword", LogLevel: "info", MaxConnectionLifetime: time.Minute * 5, MaxConnectionPoolSize: 10, ConnectionTimeout: time.Second * 5, }, shouldFail: true, }, { name: "failed connection due to missing URI", conf: &Config{ URI: "", Username: "neo4j", Password: "password", LogLevel: "info", MaxConnectionLifetime: time.Minute * 5, MaxConnectionPoolSize: 10, ConnectionTimeout: time.Second * 5, }, shouldFail: true, }, { name: "failed connection due to missing username and password", conf: &Config{ URI: uri, Username: "", Password: "", LogLevel: "info", MaxConnectionLifetime: time.Minute * 5, MaxConnectionPoolSize: 10, ConnectionTimeout: time.Second * 5, }, shouldFail: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { client := NewNeo4J(tt.conf) driver, err := client.Conn() if tt.shouldFail { assert.Error(t, err) assert.Nil(t, driver) } else { assert.NoError(t, err) assert.NotNil(t, driver) // Close the driver after test defer func() { err := driver.Close(context.Background()) assert.NoError(t, err) }() } }) } }