Skip to content
This repository was archived by the owner on Oct 2, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions BankAccount/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module bankacc

go 1.13

require (
github.com/go-sql-driver/mysql v1.5.0
github.com/stretchr/testify v1.4.0
)
13 changes: 13 additions & 0 deletions BankAccount/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
79 changes: 79 additions & 0 deletions BankAccount/pkg/store/transactionhistory.go
Original file line number Diff line number Diff line change
@@ -1 +1,80 @@
package store

import (
"bankacc/pkg/entities"
"database/sql"
"fmt"
"time"
)

type TransactionHistoryStore interface {
Insert(userId int, accountId int, amount float64, action string) (entities.TransactionHistory, error)
GetTransactionsById(id int) ([]entities.TransactionHistory, error)
GetTransactionsByIdFromToDate(id int, fromDate time.Time, toDate time.Time) ([]entities.TransactionHistory, error)
}

type TransactionHistoryModel struct {
Db *sql.DB
}

func NewTransactionHistoryStoreModel(db *sql.DB) *TransactionHistoryModel {
return &TransactionHistoryModel{
Db: db,
}
}

func (store *TransactionHistoryModel) Insert(userId int, accountId int, amount float64, action string) (entities.TransactionHistory, error) {
now := time.Now()

result, err := store.Db.Exec("INSERT INTO TransactionHistory(user_id, account_id, amount, action, created_at) VALUES(?, ?, ?, ?, ?)", userId, accountId, amount, action, now)
if err != nil {
fmt.Println(err)
}
res, err := result.LastInsertId()
if err != nil {
fmt.Println(err)
}
transaction := entities.TransactionHistory{
Id: int(res),
UserId: userId,
AccountId: accountId,
Amount: amount,
Action: action,
CreatedAt: now,
}
return transaction, nil
}

func (store *TransactionHistoryModel) GetTransactionsById(id int) ([]entities.TransactionHistory, error) {
var transactions []entities.TransactionHistory
result, err := store.Db.Query("SELECT * FROM TransactionHistory WHERE user_id = ?", id)
if err != nil {
return nil, err
}
var transaction entities.TransactionHistory
for result.Next() {
err := result.Scan(&transaction.Id, &transaction.UserId, &transaction.AccountId, &transaction.Amount, &transaction.Action, &transaction.CreatedAt)
if err != nil {
return nil, err
}
transactions = append(transactions, transaction)
}
return transactions, nil
}

func (store *TransactionHistoryModel) GetTransactionsByIdFromToDate(id int, fromDate time.Time, toDate time.Time) ([]entities.TransactionHistory, error) {
var transactions []entities.TransactionHistory
result, err := store.Db.Query("SELECT * FROM TransactionHistory WHERE user_id = ? and created_at BETWEEN ? and ?", id, fromDate, toDate)
if err != nil {
return nil, err
}
var transaction entities.TransactionHistory
for result.Next() {
err := result.Scan(&transaction.Id, &transaction.UserId, &transaction.AccountId, &transaction.Amount, &transaction.Action, &transaction.CreatedAt)
if err != nil {
return nil, err
}
transactions = append(transactions, transaction)
}
return transactions, nil
}
213 changes: 213 additions & 0 deletions BankAccount/pkg/tests/transactionhistorystore_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
package tests

import (
"bankacc/pkg/entities"
"bankacc/pkg/store"
"database/sql"
"log"
"testing"
"time"

_ "github.com/go-sql-driver/mysql"
"github.com/stretchr/testify/suite"
)

func MySQLInit() *sql.DB {
dbDriver := "mysql"
dbUser := "root"
dbPass := "Password1!"
dbName := "BankAccount?parseTime=true"
db, err := sql.Open(dbDriver, dbUser+":"+dbPass+"@/"+dbName)
if err != nil {
log.Println(err)
}
return db
}

type TearDownTestSuite interface {
TearDownTest()
}

type TransactionHistoryTestSuite struct {
suite.Suite
Transaction entities.TransactionHistory
Transactions []entities.TransactionHistory
TransactionStore store.TransactionHistoryModel
Db *sql.DB
}

func (suite *TransactionHistoryTestSuite) SetupTest() {
var err error
suite.Db = MySQLInit()
transaction := store.NewTransactionHistoryStoreModel(suite.Db)
suite.Transactions = []entities.TransactionHistory{
{
UserId: 1,
AccountId: 1,
Amount: 100,
Action: "Deposit",
},
{
UserId: 1,
AccountId: 1,
Amount: 100,
Action: "Withdraw",
},
{
UserId: 1,
AccountId: 2,
Amount: 44,
Action: "Deposit",
},
{
UserId: 2,
AccountId: 1,
Amount: 741,
Action: "Withdraw",
},
}

for i, current := range suite.Transactions {
suite.Transaction, err = transaction.Insert(current.UserId, current.AccountId, current.Amount, current.Action)
if err != nil {
suite.T().Fatal("Unable to run InsertTransactionHistory store func")
}
suite.Transactions[i] = suite.Transaction
}
}

func (suite *TransactionHistoryTestSuite) TestGetTransactionById() {
store := store.NewTransactionHistoryStoreModel(suite.Db)
var err error
var transaction []entities.TransactionHistory
var transactionsUserIDOne []entities.TransactionHistory
var transactionsUserIDTwo []entities.TransactionHistory
var transactionsUserIDFive []entities.TransactionHistory
now := time.Now()

transaction, err = store.GetTransactionsById(1)
if err != nil {
suite.T().Fatal("Unable to run GetTransactionsById store func")
}
for i, current := range suite.Transactions {
current.CreatedAt = now
if len(transaction) > i {
transaction[i].CreatedAt = now
}

if current.UserId == 1 {
transactionsUserIDOne = append(transactionsUserIDOne, current)
}
}
suite.Equal(transactionsUserIDOne, transaction, "Users with ID 1 not equal")

transaction, err = store.GetTransactionsById(2)
if err != nil {
suite.T().Fatal("Unable to run GetTransactionsById store func")
}
for i, current := range suite.Transactions {
current.CreatedAt = now
if len(transaction) > i {
transaction[i].CreatedAt = now
}
if current.UserId == 2 {
transactionsUserIDTwo = append(transactionsUserIDTwo, current)
}
}
suite.Equal(transactionsUserIDTwo, transaction, "Users with ID 2 not equal")

transaction, err = store.GetTransactionsById(5)
if err != nil {
suite.T().Fatal("Unable to run GetTransactionsById store func")
}
for i, current := range suite.Transactions {
current.CreatedAt = now
if len(transaction) > i {
transaction[i].CreatedAt = now
}
if current.UserId == 5 {
transactionsUserIDFive = append(transactionsUserIDFive, current)
}
}
suite.Equal(transactionsUserIDFive, transaction, "GetTransactionById should return empty struct")
}

func (suite *TransactionHistoryTestSuite) TestGetTransactionByIdFromToDate() {
store := store.NewTransactionHistoryStoreModel(suite.Db)
var err error
var transaction []entities.TransactionHistory
var transactionsUserIDOne []entities.TransactionHistory
var transactionsUserIDTwo []entities.TransactionHistory
var transactionsUserIDFive []entities.TransactionHistory
var now time.Time

for _, current := range suite.Transactions {
var k int
for k = current.CreatedAt.Nanosecond(); k >= 10; k = k / 10 {
}
if k >= 5 {
current.CreatedAt = suite.Transactions[0].CreatedAt.Add(time.Second * 1)
}
current.CreatedAt, _ = time.Parse("2006-01-02 15:04:05", current.CreatedAt.UTC().Format("2006-01-02 15:04:05"))
now = current.CreatedAt
}

transaction, err = store.GetTransactionsByIdFromToDate(1, now, now)
if err != nil {
suite.T().Fatal("Unable to run GetTransactionsById store func")
}
for i, current := range suite.Transactions {
current.CreatedAt = now
if len(transaction) > i {
transaction[i].CreatedAt = now
}

if current.UserId == 1 {
transactionsUserIDOne = append(transactionsUserIDOne, current)
}
}
suite.Equal(transactionsUserIDOne, transaction, "Users with ID 1 not equal")

transaction, err = store.GetTransactionsByIdFromToDate(2, now, now)
if err != nil {
suite.T().Fatal("Unable to run GetTransactionsById store func")
}
for i, current := range suite.Transactions {
current.CreatedAt = now
if len(transaction) > i {
transaction[i].CreatedAt = now
}
if current.UserId == 2 {
transactionsUserIDTwo = append(transactionsUserIDTwo, current)
}
}
suite.Equal(transactionsUserIDTwo, transaction, "Users with ID 2 not equal")

transaction, err = store.GetTransactionsByIdFromToDate(5, now, now)
if err != nil {
suite.T().Fatal("Unable to run GetTransactionsById store func")
}
for i, current := range suite.Transactions {
current.CreatedAt = now
if len(transaction) > i {
transaction[i].CreatedAt = now
}
if current.UserId == 5 {
transactionsUserIDFive = append(transactionsUserIDFive, current)
}
}
suite.Equal(transactionsUserIDFive, transaction, "GetTransactionById should return empty struct")
}

func TestTransactionHistoryTestSuite(t *testing.T) {
suite.Run(t, new(TransactionHistoryTestSuite))
}

func (suite *TransactionHistoryTestSuite) TearDownTest() {
for i := 0; i < len(suite.Transactions); i++ {
_, err := suite.Db.Exec("DELETE FROM TransactionHistory WHERE id=?", suite.Transactions[i].Id)
if err != nil {
suite.T().Fatal("Unable to run delete query")
}
}
}