Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinGallauner committed Jul 8, 2024
1 parent e031a6c commit 7148985
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 47 deletions.
2 changes: 1 addition & 1 deletion internal/client/client.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package internal
package client

import (
"encoding/json"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,48 +1,59 @@
package server
package collections

import (
"github.com/martingallauner/bookclub/internal"
//"github.com/martingallauner/bookclub/internal/client"

"github.com/martingallauner/bookclub/internal/repository"
"github.com/martingallauner/bookclub/internal/client"
)

type Service struct {
userRepository repository.UserRepository
bookRepository repository.BookRepository
linkRepository repository.LinkRepository
client client.Client
}

func New(userRepository repository.UserRepository, bookRepository repository.BookRepository, linkRepository repository.LinkRepository, client client.Client) *Service {
return &Service{userRepository: userRepository, bookRepository: bookRepository, linkRepository: linkRepository}
}

// Adds book to user's collection
func (cfg *BookclubServer) AddBookToCollection(isbn string, userId uint) (internal.Book, error) {
user, err := cfg.UserRepository.Get(userId)
func (srv *Service) AddBookToCollection(isbn string, userId uint) (internal.Book, error) {
user, err := srv.userRepository.Get(userId)
if err != nil {
return internal.Book{}, err
}

var book internal.Book
book, err = cfg.BookRepository.GetBook(isbn)
book, err = srv.bookRepository.GetBook(isbn)
if err != nil {
return internal.Book{}, err
}
if book.ISBN == "" {
book, err = cfg.Client.FetchBook(isbn)
book, err = srv.client.FetchBook(isbn)
if err != nil {
return internal.Book{}, err
}
}
user.Books = append(user.Books, book)
err = cfg.UserRepository.Save(&user)
err = srv.userRepository.Save(&user)
if err != nil {
return internal.Book{}, err
}
return book, nil
}

// Searches for the given book within the network of the given user.
func (cfg *BookclubServer) SearchBookInNetwork(userId uint, isbn string) ([]internal.User, error) {
func (cfg *Service) SearchBookInNetwork(userId uint, isbn string) ([]internal.User, error) {

//get linked users
links, err := cfg.LinkRepository.GetAcceptedById(userId)
links, err := cfg.linkRepository.GetAcceptedById(userId)
if err != nil {
return nil, err
}

// filter user for searched book
users, err := cfg.UserRepository.SearchBook(isbn)
users, err := cfg.userRepository.SearchBook(isbn)
if err != nil {
return nil, err
}
Expand All @@ -67,4 +78,4 @@ func (cfg *BookclubServer) SearchBookInNetwork(userId uint, isbn string) ([]inte
type SearchRequest struct {
UserId uint `json:"user_id"`
ISBN string `json:"isbn"`
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package internal
package collections

import (
"bytes"
Expand All @@ -9,10 +9,72 @@ import (
"net/http/httptest"
"strings"
"testing"
internal "github.com/martingallauner/bookclub/internal"
server "github.com/martingallauner/bookclub/internal/server"
"github.com/martingallauner/bookclub/internal"
"github.com/martingallauner/bookclub/internal/client"
"github.com/martingallauner/bookclub/internal/server"
"github.com/martingallauner/bookclub/test"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/modules/postgres"
"github.com/testcontainers/testcontainers-go/wait"
"context"
"log"
)

func setupTest() (*server.BookclubServer, error) {
container, err := CreatePostgresContainer()
if err != nil {
log.Fatal(err)
}

db, err := internal.SetupDatabaseWithDSN(container.ConnectionString)
if err != nil {
log.Fatal(err)
}

client := client.Client{}
bookRepository := &repository.PostgresBookRepository{Database: db}
userRepository := &repository.PostgresUserRepository{Database: db}
linkRepository := &repository.PostgresLinkRepository{Database: db}
collectionService := New(userRepository, bookRepository, linkRepository, client)

s := server.New(client, bookRepository, userRepository, linkRepository, &MockAuthService{}, &MockJwtService{}, collectionService)
return s, err
}

var (
ctx = context.Background()
)

type PostgresContainer struct {
*postgres.PostgresContainer
ConnectionString string
}

func CreatePostgresContainer() (*PostgresContainer, error) {
postgresContainer, err := postgres.RunContainer(ctx,
testcontainers.WithImage("docker.io/postgres:15.2-alpine"),
postgres.WithDatabase("bookclub-db"),
postgres.WithUsername("postgres"),
postgres.WithPassword("password"),
testcontainers.WithWaitStrategy(
wait.ForLog("database system is ready to accept connections").
WithOccurrence(2).
WithStartupTimeout(5*time.Second)),
)
if err != nil {
return nil, err
}

connStr, err := postgresContainer.ConnectionString(ctx, "sslmode=disable")
if err != nil {
return nil, err
}
return &PostgresContainer{
PostgresContainer: postgresContainer,
ConnectionString: connStr,
}, nil
}

// Tests if a saved book can be added to the collection of an existing user.
func TestAddBookToUser(t *testing.T) {
//given
Expand All @@ -33,7 +95,7 @@ func TestAddBookToUser(t *testing.T) {
s.ServeHTTP(response, request)

//then
assertStatus(t, response.Code, http.StatusOK)
test.AssertStatus(t, response.Code, http.StatusOK)
user, err := s.UserRepository.Get(1)

if len(user.Books) == 0 {
Expand Down Expand Up @@ -61,9 +123,10 @@ func TestAddBookToUnknownUser(t *testing.T) {
s.ServeHTTP(response, request)

//then
assertStatus(t, response.Code, http.StatusBadRequest)
test.AssertStatus(t, response.Code, http.StatusBadRequest)
}


// Tests search function when one user has the book
func TestSearchBookInNetwork(t *testing.T) {
//given
Expand All @@ -72,7 +135,7 @@ func TestSearchBookInNetwork(t *testing.T) {
userWithBook, err := s.CreateUser("Book Owner", "[email protected]")
book := &internal.Book{ISBN: "1234567890", URL: "https://...", Title: "Test Book"}
s.BookRepository.Save(*book)
_, err = s.AddBookToCollection(book.ISBN, userWithBook.ID)
_, err = s.Service.AddBookToCollection(book.ISBN, userWithBook.ID)

userWithoutBooks, err := s.CreateUser("Reader", "[email protected]")

Expand All @@ -87,6 +150,7 @@ func TestSearchBookInNetwork(t *testing.T) {
}

//when

requestBody := server.SearchRequest{UserId: uint(1), ISBN: "1234567890"}
jsonBody, err := json.Marshal(requestBody)
if err != nil {
Expand All @@ -106,5 +170,5 @@ func TestSearchBookInNetwork(t *testing.T) {

assert.Equal(t, got.Isbn, "1234567890", "Did we search for the wrong book?")
assert.Equal(t, len(got.Users), 1, ". Expected a different number of book owners.")
assertStatus(t, response.Code, http.StatusOK)
test.AssertStatus(t, response.Code, http.StatusOK)
}
2 changes: 1 addition & 1 deletion internal/server/handler_add_book.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (cfg *BookclubServer) handlerAddBook(w http.ResponseWriter, r *http.Request
RespondWithError(w, http.StatusBadRequest, fmt.Sprintf("Error decoding parameters: %s", err))
return
}
book, err := cfg.AddBookToCollection(body.ISBN, body.UserId)
book, err := cfg.service.AddBookToCollection(body.ISBN, body.UserId)

Check failure on line 18 in internal/server/handler_add_book.go

View workflow job for this annotation

GitHub Actions / build

cfg.service undefined (type *BookclubServer has no field or method service, but does have Service)

if err != nil {
RespondWithError(w, http.StatusBadRequest, "Unable to add the requested book")
Expand Down
2 changes: 1 addition & 1 deletion internal/server/handler_search.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func (cfg *BookclubServer) handlerSearch(w http.ResponseWriter, r *http.Request)
return
}
//TODO: remove ID from user response
users, err := cfg.SearchBookInNetwork(body.UserId, body.ISBN)
users, err := cfg.service.SearchBookInNetwork(body.UserId, body.ISBN)

Check failure on line 19 in internal/server/handler_search.go

View workflow job for this annotation

GitHub Actions / build

cfg.service undefined (type *BookclubServer has no field or method service, but does have Service)
if err != nil {
RespondWithError(w, http.StatusNotFound, "Book is not available in the users network.")
}
Expand Down
8 changes: 6 additions & 2 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import (
"os"
"strings"
"time"

"github.com/golang-jwt/jwt/v5"
_ "github.com/martingallauner/bookclub/docs"
internal "github.com/martingallauner/bookclub/internal"
client "github.com/martingallauner/bookclub/internal/client"
"github.com/martingallauner/bookclub/internal/collections"
repository "github.com/martingallauner/bookclub/internal/repository"
internal "github.com/martingallauner/bookclub/internal"
httpSwagger "github.com/swaggo/http-swagger"
)

Expand All @@ -38,16 +40,18 @@ type BookclubServer struct {
AuthService internal.AuthService
JwtService internal.JwtService
http.Handler
Service *collections.Service
}

func NewBookclubServer(client client.Client, bookRepository repository.BookRepository, userRepository repository.UserRepository, linkRepository repository.LinkRepository, authService internal.AuthService, jwtService internal.JwtService) *BookclubServer {
func New(client client.Client, bookRepository repository.BookRepository, userRepository repository.UserRepository, linkRepository repository.LinkRepository, authService internal.AuthService, jwtService internal.JwtService, service *collections.Service) *BookclubServer {
s := new(BookclubServer)
s.BookRepository = bookRepository
s.UserRepository = userRepository
s.LinkRepository = linkRepository
s.Client = client
s.AuthService = authService
s.JwtService = jwtService
s.Service = service
router := http.NewServeMux() //TODO: add jwtMiddleware to all concerned handler
router.Handle("/api/search", http.HandlerFunc(s.handlerSearch))
router.Handle("/api/collections", http.HandlerFunc(s.handlerAddBook))
Expand Down
31 changes: 19 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,25 @@ package main

import (
//"github.com/joho/godotenv"
"log"
"time"

internal "github.com/martingallauner/bookclub/internal"
"github.com/martingallauner/bookclub/internal/auth"
. "github.com/martingallauner/bookclub/internal/client"
"github.com/martingallauner/bookclub/internal/collections"
repository "github.com/martingallauner/bookclub/internal/repository"
bcServer "github.com/martingallauner/bookclub/internal/server"
"log"
"time"
)

func main() {
/* err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
} */
/* err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
} */

auth.NewAuth()


dbConfig, err := internal.ReadDatabaseConfig()
if err != nil {
log.Fatal(err)
Expand All @@ -30,13 +31,19 @@ func main() {
}
client := NewClient(5 * time.Second)

server := bcServer.NewBookclubServer(
bookRepository := &repository.PostgresBookRepository{Database: db}
userRepository := &repository.PostgresUserRepository{Database: db}
linkRepository := &repository.PostgresLinkRepository{Database: db}


server := bcServer.New(
client,
&repository.PostgresBookRepository{Database: db},
&repository.PostgresUserRepository{Database: db},
&repository.PostgresLinkRepository{Database: db},
bookRepository,
userRepository,
linkRepository,
&internal.GothicAuthService{},
&internal.JwtServiceImpl{})
&internal.JwtServiceImpl{},
collections.New(userRepository, bookRepository, linkRepository, client))
err = bcServer.StartServer(server)
if err != nil {
log.Fatal(err)
Expand Down
29 changes: 19 additions & 10 deletions test/test_helper.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
package internal
package test

import (
"context"
"log"
"net/http"
"testing"
"time"
"github.com/markbates/goth"
internal "github.com/martingallauner/bookclub/internal"
client "github.com/martingallauner/bookclub/internal/client"
repository "github.com/martingallauner/bookclub/internal/repository"
server "github.com/martingallauner/bookclub/internal/server"
internal "github.com/martingallauner/bookclub/internal"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/modules/postgres"
"github.com/testcontainers/testcontainers-go/wait"
"log"
"net/http"
"testing"
"time"
)

func assertResponseBody(t testing.TB, got, want string) {
func AssertResponseBody(t testing.TB, got, want string) {
t.Helper()
if got != want {
t.Errorf("response body is wrong, got %q want %q", got, want)
}
}

func assertStatus(t testing.TB, got, want int) {
func AssertStatus(t testing.TB, got, want int) { //TODO: consider removing that helper and assert inline
t.Helper()
if got != want {
t.Errorf("did not get correct status, got %d, want %d", got, want)
Expand All @@ -36,7 +36,7 @@ type PostgresContainer struct {
}

// helper method to run for each test //TODO: please don't start a new container for each test
func setupTest() (*server.BookclubServer, error) {
func SetupTest() (*server.BookclubServer, error) {
container, err := CreatePostgresContainer()
if err != nil {
log.Fatal(err)
Expand All @@ -47,10 +47,19 @@ func setupTest() (*server.BookclubServer, error) {
log.Fatal(err)
}

s := server.NewBookclubServer(client.Client{}, &repository.PostgresBookRepository{Database: db}, &repository.PostgresUserRepository{Database: db}, &repository.PostgresLinkRepository{Database: db}, &MockAuthService{}, &MockJwtService{})
client := client.Client{}
bookRepository := &repository.PostgresBookRepository{Database: db}
userRepository := &repository.PostgresUserRepository{Database: db}
linkRepository := &repository.PostgresLinkRepository{Database: db}
collectionService := collections.New(userRepository, bookRepository, linkRepository, client)

s := server.New(client, bookRepository, userRepository, linkRepository, &MockAuthService{}, &MockJwtService{}, collectionService)
return s, err
}




type MockAuthService struct{}

func (svc *MockAuthService) CompleteUserAuth(w http.ResponseWriter, r *http.Request) (goth.User, error) {
Expand Down
2 changes: 1 addition & 1 deletion test/user_service_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package internal
package test

import (
"bytes"
Expand Down

0 comments on commit 7148985

Please sign in to comment.