add: company; tests

This commit is contained in:
$(pass /github/name)
2024-07-16 17:52:37 +02:00
parent a1a43f1f32
commit eeeabd5ad3
4 changed files with 284 additions and 14 deletions

View 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,
}, */
}
}