feat: Create user usecase
This commit is contained in:
parent
4546665461
commit
7b8abf8e5c
39
README.md
39
README.md
@ -198,9 +198,46 @@ type User struct {
|
||||
|
||||
Use Buffalo pop `Soda CLI` to create database migrations.
|
||||
|
||||
### 2024/10/07
|
||||
### 2024/10/06
|
||||
|
||||
Implement the architecture design for User entity.
|
||||
|
||||
Checked out OpenAPI, and found that it was not that simple at all. It needs
|
||||
a whole package of knowledge about the web development!
|
||||
|
||||
For the test-driven part,
|
||||
|
||||
- model layer: just model designs, **nothing to test**
|
||||
- infra: routes and db connections, it works when it works. Nothing to test.
|
||||
- registry: Just return some structs, no logic. **Not worth testing**
|
||||
- adapter:
|
||||
- input-port (controller) test: it is about testing parsing the input
|
||||
value, and the output results writing. The unit test of controller is to
|
||||
**make sure that they behave as defined in the API documentation**. To
|
||||
test, we have to mock the **business service**.
|
||||
- output-port (repo) test: it is about testing converting business model
|
||||
to database model and the interaction with the database. If we are going
|
||||
to test them, it's about simulating different type of database behaviour
|
||||
(success, timeout, etc.). To test, we have to mock the
|
||||
**database connection**.
|
||||
- usecase: This is the core part to test, it's about the core business.
|
||||
We provide the data input and we check the data output in a fake repository.
|
||||
|
||||
With this design, although it may seem overkill for this little project, fits
|
||||
perfectly well with the TDD method.
|
||||
|
||||
Concretely, I will do the TDD for my usecase level development, and for the
|
||||
rest, I just put unit tests aside for later.
|
||||
|
||||
#### Workflow
|
||||
|
||||
1. OAS Definition
|
||||
2. (Integration/Validation test)
|
||||
3. Usecase unit test cases
|
||||
4. Usecase development
|
||||
5. Refactor (2-3-4)
|
||||
6. Input-port/Output-port
|
||||
|
||||
That should be the correct workflow. But to save time, I will cut off the
|
||||
integration test part (the 2nd point).
|
||||
|
||||
|
68
internal/howmuch/adapter/repo/db.go
Normal file
68
internal/howmuch/adapter/repo/db.go
Normal file
@ -0,0 +1,68 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/usecase/repo"
|
||||
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/log"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
type dbRepository struct {
|
||||
db *pgx.Conn
|
||||
}
|
||||
|
||||
func NewDBRepository(db *pgx.Conn) repo.DBRepository {
|
||||
return &dbRepository{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: Do I need rollback? in which cases?
|
||||
|
||||
func (dr *dbRepository) Transaction(
|
||||
ctx context.Context,
|
||||
txFunc func(txCtx context.Context, tx interface{}) (interface{}, error),
|
||||
) (interface{}, error) {
|
||||
tx, err := dr.db.Begin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if p := recover(); p != nil {
|
||||
tx.Rollback(ctx)
|
||||
log.PanicLog("transaction panicked!")
|
||||
} else if err != nil {
|
||||
tx.Rollback(ctx)
|
||||
log.ErrorLog("transaction failed!", "err", err)
|
||||
} else {
|
||||
err = tx.Commit(ctx)
|
||||
}
|
||||
}()
|
||||
|
||||
data, err := txFunc(ctx, tx)
|
||||
return data, err
|
||||
}
|
91
internal/howmuch/adapter/repo/user.go
Normal file
91
internal/howmuch/adapter/repo/user.go
Normal file
@ -0,0 +1,91 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/adapter/repo/sqlc"
|
||||
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/model"
|
||||
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/usecase/repo"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
// Get business service model, convert to the DB model (generated by sqlc)
|
||||
// To test repo's methods, I have to mock a pgx.Conn
|
||||
|
||||
type userRepository struct {
|
||||
db *pgx.Conn
|
||||
}
|
||||
|
||||
const insertTimeout = 1 * time.Second
|
||||
|
||||
func NewUserRepository(db *pgx.Conn) repo.UserRepository {
|
||||
return &userRepository{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
// Create
|
||||
func (ur *userRepository) Create(
|
||||
ctx context.Context,
|
||||
transaction interface{},
|
||||
u *model.User,
|
||||
) (*model.User, error) {
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, insertTimeout)
|
||||
defer cancel()
|
||||
|
||||
args := sqlc.InsertUserParams{
|
||||
Email: u.Email,
|
||||
FirstName: u.FirstName,
|
||||
LastName: u.LastName,
|
||||
Password: u.Password,
|
||||
CreatedAt: pgtype.Timestamp{Time: time.Now(), Valid: true},
|
||||
UpdatedAt: pgtype.Timestamp{Time: time.Now(), Valid: true},
|
||||
}
|
||||
|
||||
tx, ok := transaction.(*pgx.Conn)
|
||||
if !ok {
|
||||
return nil, errors.New("transaction is not a *pgx.Conn")
|
||||
}
|
||||
|
||||
queries := sqlc.New(tx)
|
||||
|
||||
userDB, err := queries.InsertUser(timeoutCtx, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &model.User{
|
||||
ID: int(userDB.ID),
|
||||
Email: userDB.Email,
|
||||
FirstName: userDB.FirstName,
|
||||
LastName: userDB.LastName,
|
||||
Password: userDB.Password,
|
||||
CreatedAt: userDB.CreatedAt.Time,
|
||||
UpdatedAt: userDB.CreatedAt.Time,
|
||||
}, nil
|
||||
}
|
36
internal/howmuch/model/user.go
Normal file
36
internal/howmuch/model/user.go
Normal file
@ -0,0 +1,36 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// User model
|
||||
type User struct {
|
||||
ID int `json:"id"`
|
||||
Email string `json:"email"`
|
||||
FirstName string `json:"first_name"`
|
||||
LastName string `json:"last_name"`
|
||||
Password string `json:"password"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
@ -24,7 +24,7 @@ package registry
|
||||
|
||||
import (
|
||||
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/adapter/controller"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
// registry is an implementation of Registry interface.
|
||||
@ -32,7 +32,7 @@ import (
|
||||
// It might holds other drivers when the projects grows. For example
|
||||
// the object needed to connect to Redis or Kafka.
|
||||
type registry struct {
|
||||
db *pgxpool.Pool
|
||||
db *pgx.Conn
|
||||
}
|
||||
|
||||
// Registry returns a new app controller that will be used by main()/run()
|
||||
@ -43,7 +43,7 @@ type Registry interface {
|
||||
}
|
||||
|
||||
// NewRegistry returns a new Registry's implementation.
|
||||
func NewRegistry(db *pgxpool.Pool) Registry {
|
||||
func NewRegistry(db *pgx.Conn) Registry {
|
||||
return ®istry{db: db}
|
||||
}
|
||||
|
||||
|
32
internal/howmuch/usecase/repo/db.go
Normal file
32
internal/howmuch/usecase/repo/db.go
Normal file
@ -0,0 +1,32 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package repo
|
||||
|
||||
import "context"
|
||||
|
||||
type DBRepository interface {
|
||||
Transaction(
|
||||
ctx context.Context,
|
||||
txFunc func(txCtx context.Context, tx interface{}) (interface{}, error),
|
||||
) (interface{}, error)
|
||||
}
|
34
internal/howmuch/usecase/repo/testdb.go
Normal file
34
internal/howmuch/usecase/repo/testdb.go
Normal file
@ -0,0 +1,34 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package repo
|
||||
|
||||
import "context"
|
||||
|
||||
type TestDBRepository struct{}
|
||||
|
||||
func (tdr *TestDBRepository) Transaction(
|
||||
ctx context.Context,
|
||||
txFunc func(txCtx context.Context, tx interface{}) (interface{}, error),
|
||||
) (interface{}, error) {
|
||||
return txFunc(ctx, nil)
|
||||
}
|
42
internal/howmuch/usecase/repo/testuser.go
Normal file
42
internal/howmuch/usecase/repo/testuser.go
Normal file
@ -0,0 +1,42 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/model"
|
||||
)
|
||||
|
||||
type TestUserRepository struct{}
|
||||
|
||||
func (tur *TestUserRepository) Create(
|
||||
ctx context.Context,
|
||||
transaction interface{},
|
||||
u *model.User,
|
||||
) (*model.User, error) {
|
||||
user := *u
|
||||
|
||||
user.ID = 123
|
||||
return &user, nil
|
||||
}
|
33
internal/howmuch/usecase/repo/user.go
Normal file
33
internal/howmuch/usecase/repo/user.go
Normal file
@ -0,0 +1,33 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/model"
|
||||
)
|
||||
|
||||
type UserRepository interface {
|
||||
Create(ctx context.Context, transaction interface{}, u *model.User) (*model.User, error)
|
||||
}
|
78
internal/howmuch/usecase/usecase/user.go
Normal file
78
internal/howmuch/usecase/usecase/user.go
Normal file
@ -0,0 +1,78 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/model"
|
||||
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/usecase/repo"
|
||||
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/log"
|
||||
)
|
||||
|
||||
type userUsecase struct {
|
||||
userRepo repo.UserRepository
|
||||
dbRepo repo.DBRepository
|
||||
}
|
||||
|
||||
type User interface {
|
||||
Create(ctx context.Context, u *model.User) (*model.User, error)
|
||||
}
|
||||
|
||||
func NewUserUsecase(r repo.UserRepository, d repo.DBRepository) User {
|
||||
return &userUsecase{
|
||||
userRepo: r,
|
||||
dbRepo: d,
|
||||
}
|
||||
}
|
||||
|
||||
func (uuc *userUsecase) Create(ctx context.Context, u *model.User) (*model.User, error) {
|
||||
data, err := uuc.dbRepo.Transaction(
|
||||
ctx,
|
||||
func(txCtx context.Context, tx interface{}) (interface{}, error) {
|
||||
u, err := uuc.userRepo.Create(txCtx, tx, u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: App log, maybe can be sent to some third party service.
|
||||
log.InfoLog(
|
||||
"created new user",
|
||||
"email",
|
||||
u.Email,
|
||||
"name",
|
||||
fmt.Sprintf("%s %s", u.FirstName, u.LastName),
|
||||
)
|
||||
|
||||
return u, err
|
||||
},
|
||||
)
|
||||
user := data.(*model.User)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
49
internal/howmuch/usecase/usecase/user_test.go
Normal file
49
internal/howmuch/usecase/usecase/user_test.go
Normal file
@ -0,0 +1,49 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/model"
|
||||
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/usecase/repo"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCreateUser(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
userUsecase := NewUserUsecase(&repo.TestUserRepository{}, &repo.TestDBRepository{})
|
||||
input := &model.User{
|
||||
Email: "a@b.c",
|
||||
FirstName: "James",
|
||||
LastName: "Bond",
|
||||
Password: "verystrong",
|
||||
}
|
||||
want := input
|
||||
want.ID = 123
|
||||
|
||||
got, err := userUsecase.Create(ctx, input)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, want, got)
|
||||
}
|
Loading…
Reference in New Issue
Block a user