From 45d7f4b288c9a494b9e359a0394aef1a60b28deb Mon Sep 17 00:00:00 2001 From: Alexander Kriventsev Date: Wed, 28 Oct 2020 20:09:52 +0300 Subject: [PATCH] add test --- card.go | 61 +++++++++++++++-- card_test.go | 189 ++++++++++++++++++++++++++++++++++++++++++++++++--- go.mod | 2 +- luhn.go | 2 +- luhn_test.go | 2 +- 5 files changed, 241 insertions(+), 15 deletions(-) diff --git a/card.go b/card.go index ac919e3..84a2541 100644 --- a/card.go +++ b/card.go @@ -1,8 +1,10 @@ -package gocard +package card import ( "fmt" "strconv" + "strings" + "time" ) type Card struct { @@ -14,13 +16,64 @@ type Card struct { cardHolder string } +func (c *Card) Number() string { + return strings.Trim(strings.Join(strings.Fields(fmt.Sprint(c.number)), ""), "[]") +} + +func (c *Card) MaskedNumber(headlen int, taillen int) string { + + hl := headlen + tl := taillen + if (hl < 0) || (hl > len(c.number)) { + hl = 6 + } + if (tl < 0) || (tl > len(c.number)) { + tl = 4 + } + head := c.number[:hl] + tail := c.number[len(c.number)-tl:] + + maskednumber := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(head)), ""), "[]") + masklen := len(c.number) - len(head) - len(tail) + maskednumber = maskednumber + strings.Repeat("*", masklen) + maskednumber = maskednumber + strings.Trim(strings.Join(strings.Fields(fmt.Sprint(tail)), ""), "[]") + return maskednumber +} + +func (c *Card) Cvv() string { + return c.cvv +} + +func (c *Card) Month() int { + return c.month +} + +func (c *Card) Year() int { + return c.year +} + +func (c *Card) CardHolder() string { + return c.cardHolder +} + +func (c *Card) Expired() bool { + + now := time.Now() + expirationDate := time.Date(c.year, time.Month(c.month), 1, 0, 0, 0, 0, now.Location()) + expirationDate.AddDate(0, 1, 0) + return expirationDate.Before(now) + +} + // Company holds a short and long names of who has issued the credit card type PaymentSystem struct { Short, Full string } -func NewCard(number string, cvv string, month int, year int) (*Card, error) { - if (len(number) < 13) || (len(number) > 19) { +func NewCard(number string, cvv string, month int, year int, cardHolder string) (*Card, error) { + length := len(number) + + if (length < 14) || (length > 19) { return nil, fmt.Errorf("Invalid number length") } if (month > 12) || (month < 0) || (year < 0) { @@ -39,7 +92,7 @@ func NewCard(number string, cvv string, month int, year int) (*Card, error) { return nil, fmt.Errorf("Card number is not valid") } - c := &Card{number: digits, cvv: cvv, month: month, year: year} + c := &Card{number: digits, cvv: cvv, month: month, year: year, cardHolder: cardHolder} return c, nil } diff --git a/card_test.go b/card_test.go index 19488c6..025ba48 100644 --- a/card_test.go +++ b/card_test.go @@ -1,16 +1,20 @@ -package gocard +package card import ( "reflect" "testing" ) +var testCard = &Card{number: []int{4, 7, 1, 6, 3, 3, 9, 2, 3, 9, 4, 6, 6, 8, 9, 8}, cvv: "334", month: 12, year: 2023, cardHolder: "Ivanov Ivan"} +var expiredCard = &Card{number: []int{4, 7, 1, 6, 3, 3, 9, 2, 3, 9, 4, 6, 6, 8, 9, 8}, cvv: "334", month: 12, year: 2019, cardHolder: "Ivanov Ivan"} + func TestNewCard(t *testing.T) { type args struct { - number string - cvv string - month int - year int + number string + cvv string + month int + year int + cardHolder string } tests := []struct { name string @@ -20,8 +24,8 @@ func TestNewCard(t *testing.T) { }{ // TODO: Add test cases. {name: "VISA valid test", - args: args{number: "4716339239466898", cvv: "334", year: 2023, month: 12}, - want: &Card{number: []int{4, 7, 1, 6, 3, 3, 9, 2, 3, 9, 4, 6, 6, 8, 9, 8}, cvv: "334", month: 12, year: 2023}, + args: args{number: "4716339239466898", cvv: "334", year: 2023, month: 12, cardHolder: "Ivanov Ivan"}, + want: testCard, wantErr: false, }, {name: "VISA invalid number charactertest", @@ -49,10 +53,20 @@ func TestNewCard(t *testing.T) { want: nil, wantErr: true, }, + {name: "VISA invalid number length over 19", + args: args{number: "471633923946689811111", cvv: "334", year: 2023, month: 12}, + want: nil, + wantErr: true, + }, + {name: "VISA invalid number length lower than 14", + args: args{number: "4716339239466", cvv: "334", year: 2023, month: 12}, + want: nil, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewCard(tt.args.number, tt.args.cvv, tt.args.month, tt.args.year) + got, err := NewCard(tt.args.number, tt.args.cvv, tt.args.month, tt.args.year, tt.args.cardHolder) if (err != nil) != tt.wantErr { t.Errorf("NewCard() error = %v, wantErr %v", err, tt.wantErr) return @@ -63,3 +77,162 @@ func TestNewCard(t *testing.T) { }) } } + +func TestCard_Number(t *testing.T) { + tests := []struct { + name string + c *Card + want string + }{ + // TODO: Add test cases. + {name: "Test number getter", + c: testCard, + want: "4716339239466898", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.c.Number(); got != tt.want { + t.Errorf("Card.Number() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestCard_Cvv(t *testing.T) { + tests := []struct { + name string + c *Card + want string + }{ + { + name: "Test cvv getter", + c: testCard, + want: "334", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.c.Cvv(); got != tt.want { + t.Errorf("Card.Cvv() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestCard_Month(t *testing.T) { + tests := []struct { + name string + c *Card + want int + }{ + { + name: "Test cvv getter", + c: testCard, + want: 12, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.c.Month(); got != tt.want { + t.Errorf("Card.Month() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestCard_Year(t *testing.T) { + tests := []struct { + name string + c *Card + want int + }{ + { + name: "Test cvv getter", + c: testCard, + want: 2023, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.c.Year(); got != tt.want { + t.Errorf("Card.Year() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestCard_CardHolder(t *testing.T) { + tests := []struct { + name string + c *Card + want string + }{ + { + name: "Test cvv getter", + c: testCard, + want: "Ivanov Ivan", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.c.CardHolder(); got != tt.want { + t.Errorf("Card.CardHolder() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestCard_MaskedNumber(t *testing.T) { + type args struct { + headlen int + taillen int + } + tests := []struct { + name string + c *Card + args args + want string + }{ + // TODO: Add test cases. + { + name: "Test cvv getter", + c: testCard, + args: args{headlen: 6, taillen: 4}, + want: "471633******6898", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.c.MaskedNumber(tt.args.headlen, tt.args.taillen); got != tt.want { + t.Errorf("Card.MaskedNumber() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestCard_Expired(t *testing.T) { + tests := []struct { + name string + c *Card + want bool + }{ + { + name: "Test not expired card", + c: testCard, + want: false, + }, + { + name: "Test expired card", + c: expiredCard, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.c.Expired(); got != tt.want { + t.Errorf("Card.Expired() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/go.mod b/go.mod index 3b457ec..d791c9b 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ -module forvard.me/octopus/go-card +module github.com/anaximen/go-card go 1.15 diff --git a/luhn.go b/luhn.go index acdc48a..d7a279d 100644 --- a/luhn.go +++ b/luhn.go @@ -1,4 +1,4 @@ -package gocard +package card // CalculateLuhn return the check number func CalculateLuhn(digits []int) int { diff --git a/luhn_test.go b/luhn_test.go index 54f3819..7be4de6 100644 --- a/luhn_test.go +++ b/luhn_test.go @@ -1,4 +1,4 @@ -package gocard +package card import "testing"