WIP: Keep writing projectS
Signed-off-by: Nikolai Rodionov <iam@allanger.xyz>
This commit is contained in:
@@ -10,8 +10,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrAlreadyExists = errors.New("entry already exists")
|
||||
ErrNotFound = errors.New("entry not found")
|
||||
ErrAlreadyExists = errors.New("entry already exists")
|
||||
ErrCheckNotPassed = errors.New("sql checks not passed")
|
||||
ErrNotFound = errors.New("entry not found")
|
||||
)
|
||||
|
||||
type AccountData struct {
|
||||
|
||||
@@ -3,7 +3,11 @@ package repository
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgerrcode"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
)
|
||||
|
||||
type ProjectData struct {
|
||||
@@ -13,7 +17,7 @@ type ProjectData struct {
|
||||
Description string
|
||||
CreatedBy string
|
||||
CreatedAt time.Time
|
||||
ArchivedAt sql.NullTime
|
||||
ClosedAt sql.NullTime
|
||||
Blocked bool
|
||||
UpdatedAt time.Time
|
||||
UpdatedBy string
|
||||
@@ -23,18 +27,67 @@ type ProjectData struct {
|
||||
func CreateProject(ctx context.Context, db *sql.DB, data *ProjectData) error {
|
||||
query := `
|
||||
INSERT INTO projects
|
||||
(uuid, name, slug, )
|
||||
(uuid, name, slug, description, owner_user_id, billing_account_id, created_by, created_at, updated_by, updated_at)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||
`
|
||||
|
||||
if _, err := db.ExecContext(ctx, query,
|
||||
data.UUID, data.Name, data.Slug, data.Description, data.CreatedBy,
|
||||
data.CreatedBy, data.CreatedBy, data.CreatedAt, data.CreatedBy, data.CreatedAt); err != nil {
|
||||
var pgErr *pgconn.PgError
|
||||
if errors.As(err, &pgErr) {
|
||||
switch pgErr.Code {
|
||||
case pgerrcode.UniqueViolation:
|
||||
return ErrAlreadyExists
|
||||
case pgerrcode.CheckViolation:
|
||||
return ErrCheckNotPassed
|
||||
}
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetProjectByID returns a project from the database
|
||||
func GetProjectByID(ctx context.Context, db *sql.DB, projectID string) (data *ProjectData, err error) {
|
||||
return nil, nil
|
||||
func GetProjectByID(ctx context.Context, db *sql.DB, projectID string) (*ProjectData, error) {
|
||||
data := &ProjectData{}
|
||||
query := `
|
||||
SELECT uuid, name, slug, description, owner_user_id, closed_at, created_at
|
||||
FROM projects
|
||||
WHERE uuid=$1`
|
||||
|
||||
if err := db.QueryRowContext(ctx, query, projectID).Scan(
|
||||
&data.UUID,
|
||||
&data.Name,
|
||||
&data.Slug,
|
||||
&data.Description,
|
||||
&data.CreatedBy,
|
||||
&data.ClosedAt,
|
||||
&data.CreatedAt,
|
||||
); err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// UpdateProject change editable project data
|
||||
func UpdateProject(ctx context.Context, db *sql.DB, data *ProjectData) error {
|
||||
query := `
|
||||
UPDATE projects
|
||||
SET
|
||||
name = $2,
|
||||
description = $3,
|
||||
updated_at = $4,
|
||||
updated_by = $5
|
||||
WHERE uuid = $1;`
|
||||
if _, err := db.Query(query, data.UUID, data.Name, data.Description, data.UpdatedAt, data.UpdatedBy); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -7,20 +7,127 @@ import (
|
||||
|
||||
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/repository"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestProjectsRepository_Success(t *testing.T) {
|
||||
func TestIntegrationProjectsCreate_Success(t *testing.T) {
|
||||
createdBy := uuid.NewString()
|
||||
_ = &repository.ProjectData{
|
||||
project := &repository.ProjectData{
|
||||
UUID: uuid.NewString(),
|
||||
Name: "test-1",
|
||||
Slug: "test_1",
|
||||
Slug: uuid.NewString(),
|
||||
Description: "Test Project Number 1",
|
||||
CreatedBy: createdBy,
|
||||
CreatedAt: time.Now(),
|
||||
ArchivedAt: sql.NullTime{Time: time.Now()},
|
||||
ClosedAt: sql.NullTime{Time: time.Now()},
|
||||
Blocked: false,
|
||||
UpdatedAt: time.Now(),
|
||||
UpdatedBy: createdBy,
|
||||
}
|
||||
|
||||
assert.NoError(t, repository.CreateProject(t.Context(), newTestDBConnection(t.Context()), project))
|
||||
}
|
||||
|
||||
func TestIntegrationProjectsCreate_CheckFailed(t *testing.T) {
|
||||
createdBy := uuid.NewString()
|
||||
project := &repository.ProjectData{
|
||||
UUID: uuid.NewString(),
|
||||
Name: "test-2",
|
||||
Slug: "test_2",
|
||||
Description: "Test Project Number 1",
|
||||
CreatedBy: createdBy,
|
||||
CreatedAt: time.Now(),
|
||||
ClosedAt: sql.NullTime{Time: time.Now()},
|
||||
Blocked: false,
|
||||
UpdatedAt: time.Now(),
|
||||
UpdatedBy: createdBy,
|
||||
}
|
||||
assert.Error(t, repository.CreateProject(t.Context(), newTestDBConnection(t.Context()), project), repository.ErrCheckNotPassed)
|
||||
}
|
||||
|
||||
func TestIntegrationProjectsCreate_AlreadyExistsFail(t *testing.T) {
|
||||
createdBy := uuid.NewString()
|
||||
project := &repository.ProjectData{
|
||||
UUID: uuid.NewString(),
|
||||
Name: "test-3",
|
||||
Slug: uuid.NewString(),
|
||||
Description: "Test Project Number 1",
|
||||
CreatedBy: createdBy,
|
||||
CreatedAt: time.Now(),
|
||||
ClosedAt: sql.NullTime{Time: time.Now()},
|
||||
Blocked: false,
|
||||
UpdatedAt: time.Now(),
|
||||
UpdatedBy: createdBy,
|
||||
}
|
||||
|
||||
assert.NoError(t, repository.CreateProject(t.Context(), newTestDBConnection(t.Context()), project))
|
||||
assert.Error(t, repository.CreateProject(t.Context(), newTestDBConnection(t.Context()), project), repository.ErrAlreadyExists)
|
||||
}
|
||||
|
||||
func TestIntegrationProjectsCreateAndGet_Success(t *testing.T) {
|
||||
createdBy := uuid.NewString()
|
||||
project := &repository.ProjectData{
|
||||
UUID: uuid.NewString(),
|
||||
Name: "test-4",
|
||||
Slug: uuid.NewString(),
|
||||
Description: "Test Project Number 1",
|
||||
CreatedBy: createdBy,
|
||||
CreatedAt: time.Now(),
|
||||
Blocked: false,
|
||||
UpdatedAt: time.Now(),
|
||||
UpdatedBy: createdBy,
|
||||
}
|
||||
|
||||
assert.NoError(t, repository.CreateProject(t.Context(), newTestDBConnection(t.Context()), project))
|
||||
data, err := repository.GetProjectByID(t.Context(), newTestDBConnection(t.Context()), project.UUID)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, project.Name, data.Name)
|
||||
assert.Equal(t, project.Slug, data.Slug)
|
||||
assert.Equal(t, project.Description, data.Description)
|
||||
assert.Equal(t, project.CreatedBy, data.CreatedBy)
|
||||
assert.Equal(t, project.ClosedAt.Time.Truncate(time.Second), data.ClosedAt.Time.Truncate(time.Second))
|
||||
assert.Equal(t, project.CreatedAt.Truncate(time.Second), data.CreatedAt.Truncate(time.Second))
|
||||
}
|
||||
|
||||
func TestIntegrationProjectsCreateAndGet_NotFound(t *testing.T) {
|
||||
data, err := repository.GetProjectByID(t.Context(), newTestDBConnection(t.Context()), uuid.NewString())
|
||||
assert.ErrorIs(t, err, repository.ErrNotFound)
|
||||
assert.Nil(t, data)
|
||||
}
|
||||
|
||||
func TestIntegrationProjectsCreateUpdateAndGet_Success(t *testing.T) {
|
||||
createdBy := uuid.NewString()
|
||||
project := &repository.ProjectData{
|
||||
UUID: uuid.NewString(),
|
||||
Name: "test-5",
|
||||
Slug: uuid.NewString(),
|
||||
Description: "Test Project Number 1",
|
||||
CreatedBy: createdBy,
|
||||
CreatedAt: time.Now(),
|
||||
Blocked: false,
|
||||
UpdatedAt: time.Now(),
|
||||
UpdatedBy: createdBy,
|
||||
}
|
||||
|
||||
assert.NoError(t, repository.CreateProject(t.Context(), newTestDBConnection(t.Context()), project))
|
||||
data, err := repository.GetProjectByID(t.Context(), newTestDBConnection(t.Context()), project.UUID)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, project.Name, data.Name)
|
||||
assert.Equal(t, project.Slug, data.Slug)
|
||||
assert.Equal(t, project.Description, data.Description)
|
||||
assert.Equal(t, project.CreatedBy, data.CreatedBy)
|
||||
assert.Equal(t, project.ClosedAt.Time.Truncate(time.Second), data.ClosedAt.Time.Truncate(time.Second))
|
||||
assert.Equal(t, project.CreatedAt.Truncate(time.Second), data.CreatedAt.Truncate(time.Second))
|
||||
|
||||
project.UpdatedBy = uuid.NewString()
|
||||
project.UpdatedAt = time.Now()
|
||||
project.Description = "Updated description"
|
||||
project.Name = "update name"
|
||||
|
||||
assert.NoError(t, repository.UpdateProject(t.Context(), newTestDBConnection(t.Context()), project))
|
||||
data, err = repository.GetProjectByID(t.Context(), newTestDBConnection(t.Context()), project.UUID)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, project.Name, data.Name)
|
||||
assert.Equal(t, project.Slug, data.Slug)
|
||||
assert.Equal(t, project.Description, data.Description)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user