diff --git a/database/client.go b/database/client.go index 3188d56..9501b90 100644 --- a/database/client.go +++ b/database/client.go @@ -26,6 +26,14 @@ type Client struct { userService UserService } +// Service represents a service for interacting with the database. +type Service interface { + Read() error + Write() error + Records() []user.Item + AddRecord(user.Item) +} + // NewClient returns a new database client. func NewClient(path string) *Client { c := &Client{ @@ -88,5 +96,15 @@ func (c *Client) Write() error { return err } +// AddRecord adds a record to the database. +func (c *Client) AddRecord(rec user.Item) { + c.data.Records = append(c.data.Records, rec) +} + +// Records retrieves all records from the database. +func (c *Client) Records() []user.Item { + return c.data.Records +} + // UserService returns the user service associated with the client. func (c *Client) UserService() user.Service { return &c.userService } diff --git a/database/client_mock.go b/database/client_mock.go new file mode 100644 index 0000000..a971636 --- /dev/null +++ b/database/client_mock.go @@ -0,0 +1,38 @@ +package database + +import ( + "sync" + + "github.com/josephspurrier/gocleanarchitecture/domain/user" +) + +// MockService represents a service for managing users. +type MockService struct { + records []user.Item + mutex sync.RWMutex +} + +// Reads reads database. +func (c *MockService) Read() error { + return nil +} + +// Write saves the database. +func (c *MockService) Write() error { + return nil +} + +// AddRecord adds a record to the database. +func (c *MockService) AddRecord(rec user.Item) { + c.mutex.Lock() + c.records = append(c.records, rec) + c.mutex.Unlock() +} + +// Records retrieves all records from the database. +func (c *MockService) Records() []user.Item { + c.mutex.RLock() + r := c.records + c.mutex.RUnlock() + return r +} diff --git a/database/client_mock_test.go b/database/client_mock_test.go new file mode 100644 index 0000000..123afd8 --- /dev/null +++ b/database/client_mock_test.go @@ -0,0 +1,23 @@ +package database_test + +import ( + "testing" + + "github.com/josephspurrier/gocleanarchitecture/database" + "github.com/josephspurrier/gocleanarchitecture/domain/user" +) + +// TestMockService ensures the mock service works correctly. +func TestMockService(t *testing.T) { + // Test the reading and writing. + s := new(database.MockService) + AssertEqual(t, s.Read(), nil) + AssertEqual(t, s.Write(), nil) + + // Test adding a record and reading it. + u := new(user.Item) + u.Email = "jdoe@example.com" + u.Password = "Pa$$w0rd" + s.AddRecord(*u) + AssertEqual(t, len(s.Records()), 1) +} diff --git a/database/client_test.go b/database/client_test.go index 0be8269..576a744 100644 --- a/database/client_test.go +++ b/database/client_test.go @@ -7,20 +7,6 @@ import ( "github.com/josephspurrier/gocleanarchitecture/database" ) -// AssertEqual throws an error if the two values are not equal. -func AssertEqual(t *testing.T, actualValue interface{}, expectedValue interface{}) { - if actualValue != expectedValue { - t.Errorf("\n got: %v\nwant: %v", actualValue, expectedValue) - } -} - -// AssertNotNil throws an error if the value is nil. -func AssertNotNil(t *testing.T, actualValue interface{}) { - if actualValue == nil { - t.Errorf("\n got: %v\ndidn't want: %v", actualValue, nil) - } -} - // TestNew ensures the NewClient function works properly. func TestNewClient(t *testing.T) { c := database.NewClient("db.json") diff --git a/database/user_service.go b/database/user_service.go index ec3e954..a27e516 100644 --- a/database/user_service.go +++ b/database/user_service.go @@ -8,7 +8,7 @@ import ( // UserService represents a service for managing users. type UserService struct { - client *Client + client Service } // Authenticate returns an error if the email and password don't match. @@ -20,7 +20,7 @@ func (s *UserService) Authenticate(d *user.Item) error { } // Determine if the record exists. - for _, v := range s.client.data.Records { + for _, v := range s.client.Records() { if v.Email == d.Email { if v.Password == d.Password { return nil @@ -43,7 +43,7 @@ func (s *UserService) User(email string) (*user.Item, error) { } // Determine if the record exists. - for _, v := range s.client.data.Records { + for _, v := range s.client.Records() { if v.Email == email { // Return the record. return &v, nil @@ -61,7 +61,7 @@ func (s *UserService) CreateUser(d *user.Item) error { } // Check if the user already exists - for _, v := range s.client.data.Records { + for _, v := range s.client.Records() { if strings.ToLower(v.Email) == strings.ToLower(d.Email) { // Return an error since the record exists. return user.ErrAlreadyExist @@ -69,7 +69,7 @@ func (s *UserService) CreateUser(d *user.Item) error { } // Add the record. - s.client.data.Records = append(s.client.data.Records, *d) + s.client.AddRecord(*d) // Save the record to the database. return s.client.Write() diff --git a/database/util_test.go b/database/util_test.go new file mode 100644 index 0000000..4313e76 --- /dev/null +++ b/database/util_test.go @@ -0,0 +1,17 @@ +package database_test + +import "testing" + +// AssertEqual throws an error if the two values are not equal. +func AssertEqual(t *testing.T, actualValue interface{}, expectedValue interface{}) { + if actualValue != expectedValue { + t.Errorf("\n got: %v\nwant: %v", actualValue, expectedValue) + } +} + +// AssertNotNil throws an error if the value is nil. +func AssertNotNil(t *testing.T, actualValue interface{}) { + if actualValue == nil { + t.Errorf("\n got: %v\ndidn't want: %v", actualValue, nil) + } +}