add: company; tests
This commit is contained in:
9
go.mod
9
go.mod
@@ -4,6 +4,9 @@ go 1.22.2
|
||||
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/go-playground/validator/v10 v10.22.0
|
||||
github.com/jbub/banking v0.8.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
gorm.io/driver/sqlite v1.5.6
|
||||
gorm.io/gorm v1.25.10
|
||||
@@ -14,13 +17,12 @@ require (
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.4 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.4 // in
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.22.0 // indirect
|
||||
github.com/goccy/go-json v0.10.3 // indirect
|
||||
github.com/jbub/banking v0.8.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
@@ -31,6 +33,7 @@ require (
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
|
||||
277
internal/controllers/user_controller_test.go
Normal file
277
internal/controllers/user_controller_test.go
Normal file
@@ -0,0 +1,277 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
"reflect"
|
||||
|
||||
"GoMembership/internal/config"
|
||||
"GoMembership/internal/database"
|
||||
"GoMembership/internal/models"
|
||||
"GoMembership/internal/repositories"
|
||||
"GoMembership/internal/services"
|
||||
"GoMembership/pkg/logger"
|
||||
)
|
||||
|
||||
type keyValuePair struct {
|
||||
value interface{}
|
||||
key string
|
||||
}
|
||||
|
||||
type test struct {
|
||||
name string
|
||||
wantResponse uint16
|
||||
userEmail string
|
||||
wantDBData []keyValuePair
|
||||
assert bool
|
||||
input string
|
||||
}
|
||||
|
||||
func TestUserController(t *testing.T) {
|
||||
err := database.InitDB("test.db")
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create DB: %#v", err)
|
||||
}
|
||||
|
||||
cfg := config.LoadConfig()
|
||||
emailService := services.NewEmailService(cfg.SMTP.Host, cfg.SMTP.Port, cfg.SMTP.User, cfg.SMTP.Password, cfg.SMTP.AdminEmail)
|
||||
var consentRepo repositories.ConsentRepositoryInterface = &repositories.ConsentRepository{}
|
||||
consentService := &services.ConsentService{Repo: consentRepo}
|
||||
|
||||
var bankAccountRepo repositories.BankAccountRepositoryInterface = &repositories.BankAccountRepository{}
|
||||
bankAccountService := &services.BankAccountService{Repo: bankAccountRepo}
|
||||
|
||||
var membershipRepo repositories.MembershipRepositoryInterface = &repositories.MembershipRepository{}
|
||||
var subscriptionRepo repositories.SubscriptionModelsRepositoryInterface = &repositories.SubscriptionModelsRepository{}
|
||||
membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo}
|
||||
|
||||
var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{}
|
||||
userService := &services.UserService{Repo: userRepo}
|
||||
|
||||
uc := UserController{Service: userService, EmailService: emailService, ConsentService: consentService, BankAccountService: bankAccountService, MembershipService: membershipService}
|
||||
|
||||
if err := initSubscriptionPlans(); err != nil {
|
||||
t.Errorf("Failed to init Susbcription plans: %#v", err)
|
||||
}
|
||||
|
||||
tests := getTestUsers()
|
||||
|
||||
for _, tt := range tests {
|
||||
c, _ := getMockedContext([]byte(tt.input))
|
||||
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
uc.RegisterUser(c)
|
||||
user, err := userRepo.FindUserByEmail(tt.userEmail)
|
||||
if err == gorm.ErrRecordNotFound && !tt.assert {
|
||||
//pass
|
||||
} else if err == nil && tt.assert {
|
||||
// check value:
|
||||
if tt.wantDBData != nil {
|
||||
for _, kvp := range tt.wantDBData {
|
||||
/* dbValue, err := getFieldValue(*user, kvp.key)
|
||||
if err != nil {
|
||||
t.Errorf("getFieldValue failed: %#v", err)
|
||||
} */
|
||||
dbValue, err := getAttr(&user, kvp.key)
|
||||
if err != nil {
|
||||
t.Errorf("Couldn't get Attribute: %#v", err)
|
||||
}
|
||||
if kvp.value != dbValue {
|
||||
// fail
|
||||
t.Errorf("Value is not expected: %v != %v", kvp.value, dbValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// fail
|
||||
t.Errorf("FindUserByEmail failed: %#v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
if err := deleteTestDB("test.db"); err != nil {
|
||||
t.Errorf("Failed to tear down DB: %#v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func initSubscriptionPlans() error {
|
||||
subscription := models.SubscriptionModel{
|
||||
Name: "basic",
|
||||
}
|
||||
result := database.DB.Create(&subscription)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getMockedContext(jsonStr []byte) (*gin.Context, *httptest.ResponseRecorder) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request, _ = http.NewRequest("POST", "/register", bytes.NewBuffer(jsonStr))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
return c, w
|
||||
}
|
||||
|
||||
func getAttr(obj interface{}, fieldName string) (interface{}, error) {
|
||||
pointToStruct := reflect.ValueOf(obj) // addressable
|
||||
curStruct := pointToStruct.Elem()
|
||||
if curStruct.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("expected a struct, but got %v", curStruct.Kind())
|
||||
}
|
||||
curField := curStruct.FieldByName(fieldName) // type: reflect.Value
|
||||
if !curField.IsValid() {
|
||||
return nil, fmt.Errorf("no such field: %s in user", fieldName)
|
||||
}
|
||||
return curField.Interface(), nil
|
||||
}
|
||||
|
||||
/* func getFieldValue(user models.User, fieldName string) (interface{}, error) {
|
||||
v := reflect.ValueOf(user)
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
if v.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("expected a struct, but got %v", v.Kind())
|
||||
}
|
||||
fieldVal := v.FieldByName(fieldName)
|
||||
if !fieldVal.IsValid() {
|
||||
return nil, fmt.Errorf("no such field: %s in user", fieldName)
|
||||
}
|
||||
return fieldVal.Interface(), nil
|
||||
} */
|
||||
|
||||
func deleteTestDB(dbPath string) error {
|
||||
err := os.Remove(dbPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TEST DATA:
|
||||
func generateUserJSON(user models.User) string {
|
||||
data, err := json.Marshal(user)
|
||||
if err != nil {
|
||||
logger.Error.Printf("couldn't generate Json from Uer: %#v\nERROR: %#v", user, err)
|
||||
return ""
|
||||
}
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func getTestUsers() []test {
|
||||
return []test{
|
||||
{
|
||||
name: "birthday < 18 should fail",
|
||||
wantResponse: http.StatusNotAcceptable,
|
||||
wantDBData: []keyValuePair{
|
||||
{
|
||||
key: "Email",
|
||||
value: "john.doe@example.com"},
|
||||
},
|
||||
assert: false,
|
||||
input: generateUserJSON(
|
||||
models.User{
|
||||
DateOfBirth: time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC),
|
||||
FirstName: "John",
|
||||
LastName: "Doe",
|
||||
Email: "john.doe@example.com",
|
||||
Address: "123 Main St",
|
||||
ZipCode: "12345",
|
||||
City: "Cityville",
|
||||
Phone: "123-456-7890",
|
||||
BankAccount: models.BankAccount{IBAN: "DE89370400440532013000"},
|
||||
Membership: models.Membership{SubscriptionModel: models.SubscriptionModel{Name: "Basic"}},
|
||||
ProfilePicture: "http://example.com/profile.jpg",
|
||||
Company: nil,
|
||||
Notes: nil,
|
||||
Password: "password123",
|
||||
ID: 1,
|
||||
PaymentStatus: 1,
|
||||
Status: 1,
|
||||
RoleID: 1,
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "FirstName empty, should fail",
|
||||
wantResponse: http.StatusNotAcceptable,
|
||||
wantDBData: []keyValuePair{
|
||||
{
|
||||
key: "Email",
|
||||
value: "john.doe@example.com"},
|
||||
},
|
||||
assert: false,
|
||||
input: generateUserJSON(
|
||||
models.User{
|
||||
DateOfBirth: time.Date(1990, time.January, 1, 0, 0, 0, 0, time.UTC),
|
||||
FirstName: "",
|
||||
LastName: "Doe",
|
||||
Email: "john.doe@example.com",
|
||||
Address: "123 Main St",
|
||||
ZipCode: "12345",
|
||||
City: "Cityville",
|
||||
Phone: "123-456-7890",
|
||||
BankAccount: models.BankAccount{IBAN: "DE89370400440532013000"},
|
||||
Membership: models.Membership{SubscriptionModel: models.SubscriptionModel{Name: "Basic"}},
|
||||
ProfilePicture: "http://example.com/profile.jpg",
|
||||
Company: nil,
|
||||
Notes: nil,
|
||||
Password: "password123",
|
||||
ID: 1,
|
||||
PaymentStatus: 1,
|
||||
Status: 1,
|
||||
RoleID: 1,
|
||||
}),
|
||||
},
|
||||
/* Vjjjjjjjj
|
||||
models.User {
|
||||
DateOfBirth: time.Date(1985, time.March, 15, 0, 0, 0, 0, time.UTC),
|
||||
FirstName: "Jane",
|
||||
LastName: "Smith",
|
||||
Email: "jane.smith@example.com",
|
||||
Address: "456 Oak St",
|
||||
ZipCode: "67890",
|
||||
City: "Townsville",
|
||||
Phone: "098-765-4321",
|
||||
BankAccount: models.BankAccount{IBAN: "FR7630006000011234567890189"},
|
||||
Membership: models.Membership{SubscriptionModel: SubscriptionModel{Name: "Premium", Details: "Premium Subscription", Conditions: "None", MonthlyFee: 19.99, HourlyRate: 25.00}},
|
||||
ProfilePicture: "http://example.com/profile2.jpg",
|
||||
Company: stringPtr("ExampleCorp"),
|
||||
Notes: stringPtr("Important client"),
|
||||
Password: "securepassword456",
|
||||
ID: 2,
|
||||
PaymentStatus: 0,
|
||||
Status: 2,
|
||||
RoleID: 2,
|
||||
},
|
||||
{
|
||||
DateOfBirth: time.Date(2000, time.July, 30, 0, 0, 0, 0, time.UTC),
|
||||
FirstName: "Alice",
|
||||
LastName: "Brown",
|
||||
Email: "alice.brown@example.com",
|
||||
Address: "789 Pine St",
|
||||
ZipCode: "11223",
|
||||
City: "Villageville",
|
||||
Phone: "555-555-5555",
|
||||
BankAccount: models.BankAccount{IBAN: "GB29NWBK60161331926819"},
|
||||
Membership: models.Membership{SubscriptionModel: SubscriptionModel{Name: "Standard", Details: "Standard Subscription", Conditions: "None", MonthlyFee: 14.99, HourlyRate: 20.00}},
|
||||
ProfilePicture: "",
|
||||
Company: stringPtr("AnotherCorp"),
|
||||
Notes: nil,
|
||||
Password: "mypassword789",
|
||||
ID: 3,
|
||||
PaymentStatus: 1,
|
||||
Status: 1,
|
||||
RoleID: 3,
|
||||
}, */
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"GoMembership/internal/controllers"
|
||||
)
|
||||
|
||||
func RegisterUserHandler(controller *controllers.UserController) http.Handler {
|
||||
return http.HandlerFunc(controller.RegisterUser)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ type User struct {
|
||||
DateOfBirth time.Time `gorm:"not null" json:"date_of_birth" validate:"required,age"`
|
||||
CreatedAt time.Time
|
||||
Salt *string `json:"-"`
|
||||
Company *string `json:"company" validate:"omitempty,omitnil"`
|
||||
Phone string `json:"phone" validate:"omitempty,omitnil"`
|
||||
Notes *string `json:"notes"`
|
||||
FirstName string `gorm:"not null" json:"first_name" validate:"required"`
|
||||
|
||||
Reference in New Issue
Block a user