Skip to content

Commit

Permalink
Merge pull request #5 from daltemen/release/0.1.0
Browse files Browse the repository at this point in the history
Release/0.1.0
  • Loading branch information
daltemen authored Jan 22, 2020
2 parents f75395d + 0a03046 commit 407e419
Show file tree
Hide file tree
Showing 28 changed files with 1,172 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# === Echo Variables
PORT=1323

# === Database credentials

DB_HOST=fance-db
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=supersecret
DB_NAME=fance
13 changes: 13 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM golang:1.12

ENV GOPATH=/go
ENV GO111MODULE=on

ENV APP=/fance
ENV PROJECT_ROOT=$APP

WORKDIR $APP
COPY . $APP

RUN go get ./...
RUN go get github.com/githubnemo/CompileDaemon
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,25 @@
# fance
Go Echo Gorm Example

## Postman Collection
Test the services:

[Collection](https://www.getpostman.com/collections/a29532030d3671157ec8)

### Prerequisites

to run this project do you need:
* Docker and docker compose

### Run with docker
To run this repository just run

```bash
docker-compose up
```

### How to run the tests (With Go and go modules)

```bash
go test ./...
```
11 changes: 11 additions & 0 deletions app/cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import (
"fance/app/deliveries"
"log"
)

func main() {
log.SetFlags(log.LstdFlags | log.Lshortfile)
deliveries.RunRestServer()
}
42 changes: 42 additions & 0 deletions app/datasources/db.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package datasources

import (
"fance/app/tasks/repositories"
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"os"
)

// Add gorm models to be auto migrated at the moment of build
func Migrate(db *gorm.DB) {
db.AutoMigrate(
&repositories.DbTask{},
)
}

// Format the string to add database init params
func dbParams(params ...string) string {
return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=True", params[0], params[1], params[2], params[3], params[4])
}

// Connect with mysql database
func ConnectDb() *gorm.DB {
dbUsername := os.Getenv("DB_USERNAME")
dbPassword := os.Getenv("DB_PASSWORD")
dbHost := os.Getenv("DB_HOST")
dbPort := os.Getenv("DB_PORT")
dbName := os.Getenv("DB_NAME")

db, err := gorm.Open("mysql", dbParams(dbUsername,
dbPassword,
dbHost,
dbPort,
dbName))

if err != nil {
fmt.Println(err)
panic("failed to connect database")
}
return db
}
26 changes: 26 additions & 0 deletions app/deliveries/rest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package deliveries

import (
"fance/app/datasources"
"fance/app/tasks/managers"
"fance/app/tasks/repositories"
"fance/app/tasks/rest"
"os"

"github.com/labstack/echo/v4"
)

func RunRestServer() {
// -- init db
db := datasources.ConnectDb()
datasources.Migrate(db)
// -- conn Interfaces
repository := repositories.NewSqlTasksRepository(db)
reader := managers.NewReaderManager(repository)
writer := managers.NewWriterManager(repository)
restMethods := rest.NewRest(reader, writer)
// -- init rest server
e := echo.New()
rest.RegisterRoutes(e, restMethods)
e.Logger.Fatal(e.Start(":" + os.Getenv("PORT")))
}
47 changes: 47 additions & 0 deletions app/tasks/domain/task.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package domain

import (
"github.com/gofrs/uuid"
)

type StatusTask string
const (
ToDo StatusTask = "TODO"
Doing StatusTask = "DOING"
Done StatusTask = "DONE"
)

func (s *StatusTask) String() string {
return string(*s)
}

func NewStatus(status string) StatusTask {
switch status {
case string(ToDo):
return ToDo
case string(Doing):
return Doing
case string(Done):
return Done
default:
return ""
}
}

// Task Domain struct for manage tasks
type Task struct {
Id string
Title string
Description string
Status StatusTask
}

func NewTask(title string, description string, status StatusTask) *Task {
id, _ := uuid.NewV4()
return &Task{
Id: id.String(),
Title: title,
Description: description,
Status: status,
}
}
35 changes: 35 additions & 0 deletions app/tasks/managers/mocks/Reader.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 72 additions & 0 deletions app/tasks/managers/mocks/Writer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions app/tasks/managers/reader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package managers

import "context"

type Reader interface {
RetrieveAll(ctx context.Context, page int, limit int) ([]TaskInfo, error)
}
36 changes: 36 additions & 0 deletions app/tasks/managers/reader_manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package managers

import (
"context"
"fance/app/tasks/domain"
"fance/app/tasks/repositories"
)

type readerManager struct {
repo repositories.Repository
}

func NewReaderManager(repository repositories.Repository) Reader {
return &readerManager{repo: repository}
}

func (r *readerManager) RetrieveAll(ctx context.Context, page int, limit int) ([]TaskInfo, error) {
result, err := r.repo.GetAll(ctx, page, limit)
if err != nil {
return nil, err
}
return r.mapDomainToTaskInfo(result), nil
}

func (r *readerManager) mapDomainToTaskInfo(tasks []domain.Task) []TaskInfo {
result := make([]TaskInfo, len(tasks))
for i, task := range tasks {
result[i] = TaskInfo{
Id: task.Id,
Title: task.Title,
Description: task.Description,
Status: task.Status.String(),
}
}
return result
}
47 changes: 47 additions & 0 deletions app/tasks/managers/reader_manager_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package managers

import (
"context"
"errors"
"fance/app/tasks/domain"
"fance/app/tasks/repositories/mocks"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
"testing"
)

type readerManagerSuite struct {
suite.Suite
repository *mocks.Repository
ctx context.Context
reader Reader
}

func (suite *readerManagerSuite) SetupTest() {
suite.ctx = context.Background()
suite.repository = new(mocks.Repository)
suite.reader = NewReaderManager(suite.repository)
}

func TestReaderManager(t *testing.T) {
suite.Run(t, &readerManagerSuite{})
}

var (
tasks0 = []domain.Task{task0}
tasksInfo0 = []TaskInfo{taskInfo0}
)

func (suite *readerManagerSuite) TestReaderManager_RetrieveAll_Success() {
suite.repository.Mock.On("GetAll", mock.Anything, mock.Anything, mock.Anything).Return(tasks0, nil).Once()
result, err := suite.reader.RetrieveAll(suite.ctx, 1, 1)
suite.NoError(err)
suite.Equal(tasksInfo0, result)
}

func (suite *readerManagerSuite) TestReaderManager_RetrieveAll_Failed() {
suite.repository.Mock.On("GetAll", mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.New("failed")).Once()
result, err := suite.reader.RetrieveAll(suite.ctx, 2, 1)
suite.Error(err)
suite.Nil(result)
}
8 changes: 8 additions & 0 deletions app/tasks/managers/task_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package managers

type TaskInfo struct {
Id string
Title string
Description string
Status string
}
Loading

0 comments on commit 407e419

Please sign in to comment.