2024-02-26 10:12:30 +00:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2024-02-26 13:57:19 +00:00
|
|
|
"errors"
|
2024-02-26 10:12:30 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
notesv1 "github.com/sundowndev/grpc-api-example/proto/notes/v1"
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
"google.golang.org/grpc/credentials/insecure"
|
2024-02-27 14:42:25 +00:00
|
|
|
"google.golang.org/grpc/status"
|
2024-02-26 13:57:19 +00:00
|
|
|
"google.golang.org/grpc/test/bufconn"
|
|
|
|
"io"
|
2024-02-27 14:42:25 +00:00
|
|
|
"log"
|
2024-02-26 13:57:19 +00:00
|
|
|
"net"
|
2024-02-26 10:12:30 +00:00
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
2024-02-26 13:57:19 +00:00
|
|
|
func newTestServer() (*Server, *grpc.ClientConn, error) {
|
2024-02-27 14:42:25 +00:00
|
|
|
srv, err := NewServer(insecure.NewCredentials())
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2024-02-26 13:57:19 +00:00
|
|
|
buffer := 101024 * 1024
|
|
|
|
lis := bufconn.Listen(buffer)
|
|
|
|
srv.listener = lis
|
|
|
|
go srv.grpcSrv.Serve(lis)
|
2024-02-26 10:12:30 +00:00
|
|
|
|
2024-02-26 13:57:19 +00:00
|
|
|
conn, err := grpc.DialContext(context.Background(), "",
|
|
|
|
grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) {
|
|
|
|
return lis.Dial()
|
|
|
|
}),
|
|
|
|
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
|
|
|
)
|
2024-02-26 10:12:30 +00:00
|
|
|
if err != nil {
|
2024-02-26 13:57:19 +00:00
|
|
|
_ = srv.Close()
|
|
|
|
return nil, nil, err
|
2024-02-26 10:12:30 +00:00
|
|
|
}
|
|
|
|
|
2024-02-26 13:57:19 +00:00
|
|
|
return srv, conn, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestNotesService_ListNotes(t *testing.T) {
|
|
|
|
testcases := []struct {
|
2024-02-27 14:42:25 +00:00
|
|
|
name string
|
|
|
|
notes []*notesv1.Note
|
|
|
|
wantErr string
|
2024-02-26 13:57:19 +00:00
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "test with no notes",
|
|
|
|
notes: []*notesv1.Note{},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "test with few notes",
|
|
|
|
notes: []*notesv1.Note{
|
2024-02-27 15:09:22 +00:00
|
|
|
{Title: "test note 1"},
|
|
|
|
{Title: "note 2"},
|
|
|
|
{Title: "note 3"},
|
2024-02-26 13:57:19 +00:00
|
|
|
},
|
|
|
|
},
|
2024-02-27 14:42:25 +00:00
|
|
|
{
|
|
|
|
name: "test with min_len validation error",
|
|
|
|
notes: []*notesv1.Note{
|
2024-02-27 15:09:22 +00:00
|
|
|
{Title: ""},
|
2024-02-27 14:42:25 +00:00
|
|
|
},
|
2024-02-28 10:58:35 +00:00
|
|
|
wantErr: "validation error:\n - title: value length must be at least 1 characters [string.min_len]",
|
2024-02-27 14:42:25 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "test with max_len validation error",
|
|
|
|
notes: []*notesv1.Note{
|
2024-02-27 15:09:22 +00:00
|
|
|
{Title: "this is a super long note title that can trigger a validation error"},
|
2024-02-27 14:42:25 +00:00
|
|
|
},
|
2024-02-28 10:58:35 +00:00
|
|
|
wantErr: "validation error:\n - title: value length must be at most 50 characters [string.max_len]",
|
2024-02-27 14:42:25 +00:00
|
|
|
},
|
2024-02-26 10:12:30 +00:00
|
|
|
}
|
|
|
|
|
2024-02-26 13:57:19 +00:00
|
|
|
for _, tt := range testcases {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
srv, conn, err := newTestServer()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
client := notesv1.NewNotesServiceClient(conn)
|
|
|
|
defer srv.Close()
|
|
|
|
defer conn.Close()
|
2024-02-26 10:12:30 +00:00
|
|
|
|
2024-02-26 13:57:19 +00:00
|
|
|
for _, note := range tt.notes {
|
|
|
|
_, err := client.AddNote(context.Background(), ¬esv1.AddNoteRequest{Title: note.Title})
|
2024-02-27 14:42:25 +00:00
|
|
|
if err != nil && tt.wantErr == "" {
|
2024-02-26 13:57:19 +00:00
|
|
|
t.Fatal(err)
|
2024-02-27 14:42:25 +00:00
|
|
|
} else {
|
|
|
|
// Retrieve the status from the rpc error
|
|
|
|
s, ok := status.FromError(err)
|
|
|
|
if ok {
|
|
|
|
assert.Equal(t, tt.wantErr, s.Message())
|
|
|
|
} else {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
return
|
2024-02-26 13:57:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
res, err := client.ListNotes(context.Background(), ¬esv1.ListNotesRequest{})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
notes := make([]*notesv1.Note, 0)
|
|
|
|
|
|
|
|
for {
|
|
|
|
recv, err := res.Recv()
|
|
|
|
if errors.Is(err, io.EOF) {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
notes = append(notes, recv.Note)
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Len(t, notes, len(tt.notes))
|
|
|
|
})
|
|
|
|
}
|
2024-02-26 10:12:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestNotesService_AddNote(t *testing.T) {
|
2024-02-26 13:57:19 +00:00
|
|
|
srv, conn, err := newTestServer()
|
2024-02-26 10:12:30 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2024-02-26 13:57:19 +00:00
|
|
|
client := notesv1.NewNotesServiceClient(conn)
|
|
|
|
defer srv.Close()
|
2024-02-26 10:12:30 +00:00
|
|
|
defer conn.Close()
|
|
|
|
|
2024-02-26 13:57:19 +00:00
|
|
|
res, err := client.AddNote(context.Background(), ¬esv1.AddNoteRequest{Title: "test note"})
|
2024-02-26 10:12:30 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.NotNil(t, res)
|
2024-02-26 13:57:19 +00:00
|
|
|
assert.Equal(t, "test note", res.Note.Title)
|
|
|
|
assert.Equal(t, false, res.Note.Archived)
|
2024-02-26 10:12:30 +00:00
|
|
|
}
|
2024-02-27 15:09:22 +00:00
|
|
|
|
|
|
|
func TestNotesService_EditNote(t *testing.T) {
|
|
|
|
srv, conn, err := newTestServer()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
client := notesv1.NewNotesServiceClient(conn)
|
|
|
|
defer srv.Close()
|
|
|
|
defer conn.Close()
|
|
|
|
|
|
|
|
res, err := client.AddNote(context.Background(), ¬esv1.AddNoteRequest{Title: "test note"})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
res.Note.Title = "january groceries"
|
|
|
|
res.Note.Archived = true
|
|
|
|
|
|
|
|
res2, err := client.EditNote(context.Background(), ¬esv1.EditNoteRequest{Note: res.Note})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Equal(t, "january groceries", res2.Note.Title)
|
|
|
|
assert.True(t, res2.Note.Archived)
|
|
|
|
}
|
2024-02-27 19:55:12 +00:00
|
|
|
|
|
|
|
func TestNotesService_EditNote_NotFound(t *testing.T) {
|
|
|
|
srv, conn, err := newTestServer()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
client := notesv1.NewNotesServiceClient(conn)
|
|
|
|
defer srv.Close()
|
|
|
|
defer conn.Close()
|
|
|
|
|
|
|
|
res, err := client.EditNote(context.Background(), ¬esv1.EditNoteRequest{
|
|
|
|
Note: ¬esv1.Note{Id: "5cbb1dab-4789-4f32-971d-bdcb60f190b1", Title: "test"},
|
|
|
|
})
|
|
|
|
|
|
|
|
assert.Nil(t, res)
|
|
|
|
|
|
|
|
// Retrieve the status from the rpc error
|
|
|
|
s, ok := status.FromError(err)
|
|
|
|
if ok {
|
|
|
|
assert.Equal(t, "couldn't find note with id: 5cbb1dab-4789-4f32-971d-bdcb60f190b1", s.Message())
|
|
|
|
} else {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|