495 lines
13 KiB
Go
495 lines
13 KiB
Go
package services
|
|
|
|
import (
|
|
"database/sql"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"authentication/db"
|
|
|
|
"github.com/DATA-DOG/go-sqlmock"
|
|
)
|
|
|
|
func setupMockDB(t *testing.T) (sqlmock.Sqlmock, func()) {
|
|
mockDB, mock, err := sqlmock.New()
|
|
if err != nil {
|
|
t.Fatalf("Failed to create mock database: %v", err)
|
|
}
|
|
|
|
originalDB := db.DB
|
|
db.DB = mockDB
|
|
|
|
cleanup := func() {
|
|
mockDB.Close()
|
|
db.DB = originalDB
|
|
}
|
|
|
|
return mock, cleanup
|
|
}
|
|
|
|
func TestGetUser(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "test@example.com"
|
|
expectedID := "user123"
|
|
|
|
rows := sqlmock.NewRows([]string{"user_id"}).
|
|
AddRow(expectedID)
|
|
|
|
mock.ExpectQuery(`SELECT user_id FROM users WHERE email_address = \? AND is_deleted = 0 LIMIT 1;`).
|
|
WithArgs(email).
|
|
WillReturnRows(rows)
|
|
|
|
}
|
|
|
|
func TestGetUserNotFound(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "nonexistent@example.com"
|
|
|
|
mock.ExpectQuery(`SELECT user_id FROM users WHERE email_address = \? AND is_deleted = 0 LIMIT 1;`).
|
|
WithArgs(email).
|
|
WillReturnError(sql.ErrNoRows)
|
|
|
|
id, err := GetUserID(email)
|
|
|
|
if err != sql.ErrNoRows {
|
|
t.Errorf("Expected sql.ErrNoRows, got: %v", err)
|
|
}
|
|
|
|
if id != "" {
|
|
t.Errorf("Expected empty ID, got %s", id)
|
|
}
|
|
}
|
|
|
|
func TestGetUserNullNames(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "test@example.com"
|
|
expectedID := "user456"
|
|
|
|
rows := sqlmock.NewRows([]string{"user_id"}).
|
|
AddRow(expectedID)
|
|
|
|
mock.ExpectQuery(`SELECT user_id FROM users WHERE email_address = \? AND is_deleted = 0 LIMIT 1;`).
|
|
WithArgs(email).
|
|
WillReturnRows(rows)
|
|
|
|
id, err := GetUserID(email)
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got: %v", err)
|
|
}
|
|
|
|
if id != expectedID {
|
|
t.Errorf("Expected ID %s, got %s", expectedID, id)
|
|
}
|
|
|
|
}
|
|
|
|
func TestGetUserID(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "test@example.com"
|
|
expectedID := "user789"
|
|
|
|
rows := sqlmock.NewRows([]string{"user_id"}).
|
|
AddRow(expectedID)
|
|
|
|
mock.ExpectQuery(`SELECT user_id FROM users WHERE email_address = \? AND is_deleted = 0 LIMIT 1;`).
|
|
WithArgs(email).
|
|
WillReturnRows(rows)
|
|
|
|
id, err := GetUserID(email)
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got: %v", err)
|
|
}
|
|
|
|
if id != expectedID {
|
|
t.Errorf("Expected ID %s, got %s", expectedID, id)
|
|
}
|
|
}
|
|
|
|
func TestCheckEmailInDB(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "existing@example.com"
|
|
|
|
rows := sqlmock.NewRows([]string{"exists"}).
|
|
AddRow(true)
|
|
|
|
mock.ExpectQuery(`SELECT EXISTS \( SELECT 1 FROM users WHERE email_address = \? AND is_deleted = 0\)`).
|
|
WithArgs(email).
|
|
WillReturnRows(rows)
|
|
|
|
exists, err := CheckEmailInDB(email)
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got: %v", err)
|
|
}
|
|
|
|
if !exists {
|
|
t.Error("Expected email to exist")
|
|
}
|
|
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Errorf("Unfulfilled expectations: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestCheckEmailInDBNotExists(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "nonexistent@example.com"
|
|
|
|
rows := sqlmock.NewRows([]string{"exists"}).
|
|
AddRow(false)
|
|
|
|
mock.ExpectQuery(`SELECT EXISTS \( SELECT 1 FROM users WHERE email_address = \? AND is_deleted = 0\)`).
|
|
WithArgs(email).
|
|
WillReturnRows(rows)
|
|
|
|
exists, err := CheckEmailInDB(email)
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got: %v", err)
|
|
}
|
|
|
|
if exists {
|
|
t.Error("Expected email to not exist")
|
|
}
|
|
}
|
|
|
|
func TestCheckEmailInDBError(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "error@example.com"
|
|
|
|
mock.ExpectQuery(`SELECT EXISTS \( SELECT 1 FROM users WHERE email_address = \? AND is_deleted = 0\)`).
|
|
WithArgs(email).
|
|
WillReturnError(sql.ErrConnDone)
|
|
|
|
exists, err := CheckEmailInDB(email)
|
|
|
|
if err == nil {
|
|
t.Error("Expected error, got nil")
|
|
}
|
|
|
|
if exists {
|
|
t.Error("Expected false when error occurs")
|
|
}
|
|
}
|
|
|
|
func TestGetUserIDFromEmail(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "test@example.com"
|
|
expectedID := "user999"
|
|
|
|
rows := sqlmock.NewRows([]string{"id"}).
|
|
AddRow(expectedID)
|
|
|
|
mock.ExpectQuery(`SELECT user_id FROM \( SELECT user_id, 1 AS priority FROM users WHERE email_address = \? AND is_deleted = 0 \) t ORDER BY priority ASC LIMIT 1;`).
|
|
WithArgs(email).
|
|
WillReturnRows(rows)
|
|
|
|
id, err := GetUserIDFromEmail(email)
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got: %v", err)
|
|
}
|
|
|
|
if id != expectedID {
|
|
t.Errorf("Expected ID %s, got %s", expectedID, id)
|
|
}
|
|
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Errorf("Unfulfilled expectations: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestGetUserIDFromEmailNotFound(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "notfound@example.com"
|
|
|
|
mock.ExpectQuery(`SELECT user_id FROM \( SELECT user_id, 1 AS priority FROM users WHERE email_address = \? AND is_deleted = 0 \) t ORDER BY priority ASC LIMIT 1;`).
|
|
WithArgs(email).
|
|
WillReturnError(sql.ErrNoRows)
|
|
|
|
id, err := GetUserIDFromEmail(email)
|
|
|
|
if err == nil {
|
|
t.Error("Expected error, got nil")
|
|
}
|
|
|
|
if id != "" {
|
|
t.Errorf("Expected empty ID on error, got %s", id)
|
|
}
|
|
}
|
|
|
|
func TestGetUserIDFromEmailDBError(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "error@example.com"
|
|
|
|
mock.ExpectQuery(`SELECT user_id FROM \( SELECT user_id, 1 AS priority FROM users WHERE email_address = \? AND is_deleted = 0 \) t ORDER BY priority ASC LIMIT 1;`).
|
|
WithArgs(email).
|
|
WillReturnError(sql.ErrConnDone)
|
|
|
|
id, err := GetUserIDFromEmail(email)
|
|
|
|
if err == nil {
|
|
t.Error("Expected error, got nil")
|
|
}
|
|
|
|
if err != sql.ErrConnDone {
|
|
t.Errorf("Expected sql.ErrConnDone, got: %v", err)
|
|
}
|
|
|
|
if id != "" {
|
|
t.Errorf("Expected empty ID on error, got %s", id)
|
|
}
|
|
}
|
|
|
|
func TestGetUserMultipleEmails(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
testCases := []struct {
|
|
email string
|
|
userID string
|
|
hasNames bool
|
|
}{
|
|
{"user1@example.com", "id1", true},
|
|
{"user2@example.com", "id2", false},
|
|
{"user3@example.com", "id3", true},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.email, func(t *testing.T) {
|
|
rows := sqlmock.NewRows([]string{"user_id"}).
|
|
AddRow(tc.userID)
|
|
|
|
mock.ExpectQuery(`SELECT user_id FROM users WHERE email_address = \? AND is_deleted = 0 LIMIT 1;`).
|
|
WithArgs(tc.email).
|
|
WillReturnRows(rows)
|
|
|
|
id, err := GetUserID(tc.email)
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got: %v", err)
|
|
}
|
|
|
|
if id != tc.userID {
|
|
t.Errorf("Expected ID %s, got %s", tc.userID, id)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCheckEmailInDBVariousEmails(t *testing.T) {
|
|
testEmails := []string{
|
|
"normal@example.com",
|
|
"with+plus@example.com",
|
|
"with.dot@example.com",
|
|
"with-dash@example.com",
|
|
}
|
|
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
for i, email := range testEmails {
|
|
exists := i%2 == 0 // Alternate between true and false
|
|
|
|
rows := sqlmock.NewRows([]string{"exists"}).
|
|
AddRow(exists)
|
|
|
|
mock.ExpectQuery(`SELECT EXISTS \( SELECT 1 FROM users WHERE email_address = \? AND is_deleted = 0\)`).
|
|
WithArgs(email).
|
|
WillReturnRows(rows)
|
|
|
|
result, err := CheckEmailInDB(email)
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected no error for %s, got: %v", email, err)
|
|
}
|
|
|
|
if result != exists {
|
|
t.Errorf("Expected %v for %s, got %v", exists, email, result)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetRoleIDsFromEmail(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "roles@example.com"
|
|
expectedRoleIDs := []int{2, 4, 8}
|
|
|
|
globalRows := sqlmock.NewRows([]string{"role_id"}).
|
|
AddRow(2).
|
|
AddRow(8)
|
|
|
|
projectRows := sqlmock.NewRows([]string{"role_id"}).
|
|
AddRow(4).
|
|
AddRow(8).
|
|
AddRow(2)
|
|
|
|
mock.ExpectQuery(`SELECT DISTINCT ur\.role_id\s+FROM uess_user_management\.users u\s+JOIN uess_user_management\.user_roles ur ON u\.users_id = ur\.users_id\s+WHERE u\.email_address = \?\s+AND u\.is_deleted = 0\s+AND ur\.role_id IS NOT NULL`).
|
|
WithArgs(email).
|
|
WillReturnRows(globalRows)
|
|
|
|
mock.ExpectQuery(`SELECT DISTINCT pa\.role_id\s+FROM uess_user_management\.users u\s+JOIN uess_project_management\.project_assignment pa ON u\.users_id = pa\.users_id\s+WHERE u\.email_address = \?\s+AND u\.is_deleted = 0\s+AND pa\.is_active = 1\s+AND pa\.role_id IS NOT NULL`).
|
|
WithArgs(email).
|
|
WillReturnRows(projectRows)
|
|
|
|
roleIDs, err := GetRoleIDsFromEmail(email)
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got: %v", err)
|
|
}
|
|
|
|
if !reflect.DeepEqual(roleIDs, expectedRoleIDs) {
|
|
t.Errorf("Expected role IDs %v, got %v", expectedRoleIDs, roleIDs)
|
|
}
|
|
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Errorf("Unfulfilled expectations: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestGetRoleIDsFromEmailQueryError(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "roles-error@example.com"
|
|
|
|
mock.ExpectQuery(`SELECT DISTINCT ur\.role_id\s+FROM uess_user_management\.users u\s+JOIN uess_user_management\.user_roles ur ON u\.users_id = ur\.users_id\s+WHERE u\.email_address = \?\s+AND u\.is_deleted = 0\s+AND ur\.role_id IS NOT NULL`).
|
|
WithArgs(email).
|
|
WillReturnError(sql.ErrConnDone)
|
|
|
|
roleIDs, err := GetRoleIDsFromEmail(email)
|
|
if err == nil {
|
|
t.Error("Expected error, got nil")
|
|
}
|
|
|
|
if roleIDs != nil {
|
|
t.Errorf("Expected nil role IDs on error, got %v", roleIDs)
|
|
}
|
|
}
|
|
|
|
func TestGetRoleIDsFromEmailNoRowsReturnsEmptySlice(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "no-roles@example.com"
|
|
|
|
globalRows := sqlmock.NewRows([]string{"role_id"})
|
|
projectRows := sqlmock.NewRows([]string{"role_id"})
|
|
|
|
mock.ExpectQuery(`SELECT DISTINCT ur\.role_id\s+FROM uess_user_management\.users u\s+JOIN uess_user_management\.user_roles ur ON u\.users_id = ur\.users_id\s+WHERE u\.email_address = \?\s+AND u\.is_deleted = 0\s+AND ur\.role_id IS NOT NULL`).
|
|
WithArgs(email).
|
|
WillReturnRows(globalRows)
|
|
|
|
mock.ExpectQuery(`SELECT DISTINCT pa\.role_id\s+FROM uess_user_management\.users u\s+JOIN uess_project_management\.project_assignment pa ON u\.users_id = pa\.users_id\s+WHERE u\.email_address = \?\s+AND u\.is_deleted = 0\s+AND pa\.is_active = 1\s+AND pa\.role_id IS NOT NULL`).
|
|
WithArgs(email).
|
|
WillReturnRows(projectRows)
|
|
|
|
roleIDs, err := GetRoleIDsFromEmail(email)
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got: %v", err)
|
|
}
|
|
|
|
if roleIDs == nil {
|
|
t.Error("Expected empty slice, got nil")
|
|
}
|
|
|
|
if len(roleIDs) != 0 {
|
|
t.Errorf("Expected empty slice, got %v", roleIDs)
|
|
}
|
|
}
|
|
|
|
func TestParseRoleIDsCSV(t *testing.T) {
|
|
roleIDs, err := parseRoleIDsCSV("1, 12,3")
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got: %v", err)
|
|
}
|
|
|
|
expected := []int{1, 12, 3}
|
|
if !reflect.DeepEqual(roleIDs, expected) {
|
|
t.Fatalf("Expected %v, got %v", expected, roleIDs)
|
|
}
|
|
}
|
|
|
|
func TestParseRoleIDsCSVEmpty(t *testing.T) {
|
|
roleIDs, err := parseRoleIDsCSV("")
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got: %v", err)
|
|
}
|
|
|
|
if roleIDs == nil {
|
|
t.Fatal("Expected empty slice, got nil")
|
|
}
|
|
|
|
if len(roleIDs) != 0 {
|
|
t.Fatalf("Expected empty slice, got %v", roleIDs)
|
|
}
|
|
}
|
|
|
|
func TestFetchUserByEmail(t *testing.T) {
|
|
mock, cleanup := setupMockDB(t)
|
|
defer cleanup()
|
|
|
|
email := "d.israel.psa@gmail.com"
|
|
|
|
userRows := sqlmock.NewRows([]string{
|
|
"users_id", "first_name", "middle_initial", "last_name", "suffix", "role_ids", "office_id", "email_address", "MIS", "CAPI", "CAWI", "DPS", "sex", "status_of_employment", "home_address", "contact_number", "user_type",
|
|
}).AddRow(
|
|
"U0000000001", "AAAAAAAA", "A", "Israel", "", "1", 103, email, 1, 1, 1, 1, nil, "COSW", "Quezon City", "09171234567", nil,
|
|
)
|
|
|
|
mock.ExpectQuery(`SELECT u\.users_id, u\.first_name, u\.middle_initial, u\.last_name, u\.suffix, GROUP_CONCAT\(DISTINCT ur\.role_id ORDER BY ur\.role_id\) AS role_ids, u\.office_id, u\.email_address, MAX\(ur\.MIS\), MAX\(ur\.CAPI\), MAX\(ur\.CAWI\), MAX\(ur\.DPS\),\s+u\.sex, u\.status_of_employment, u\.home_address, u\.contact_number, u\.user_type\s+FROM uess_user_management\.users u\s+LEFT JOIN uess_user_management\.user_roles ur\s+ON u\.users_id = ur\.users_id\s+WHERE u\.email_address = \?\s+GROUP BY u\.users_id, u\.first_name, u\.middle_initial, u\.last_name, u\.suffix, u\.office_id, u\.email_address, u\.sex, u\.status_of_employment, u\.home_address, u\.contact_number, u\.user_type`).
|
|
WithArgs(email).
|
|
WillReturnRows(userRows)
|
|
|
|
projectRows := sqlmock.NewRows([]string{"project_id", "alias", "role_ids", "office_id"}).
|
|
AddRow(1, "TTT", "1,12", 103)
|
|
|
|
mock.ExpectQuery(`SELECT pa\.project_id, p\.alias, GROUP_CONCAT\(DISTINCT pa\.role_id ORDER BY pa\.role_id\) AS role_ids, u\.office_id\s+FROM uess_user_management\.users u\s+LEFT JOIN uess_project_management\.project_assignment pa\s+ON u\.users_id = pa\.users_id AND pa\.is_active = 1\s+LEFT JOIN uess_project_management\.project p\s+ON pa\.project_id = p\.project_id\s+WHERE u\.email_address = \? AND pa\.project_id IS NOT NULL\s+GROUP BY pa\.project_id, p\.alias, u\.office_id`).
|
|
WithArgs(email).
|
|
WillReturnRows(projectRows)
|
|
|
|
user, err := FetchUserByEmail(email)
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got: %v", err)
|
|
}
|
|
|
|
if user.RoleID == nil || *user.RoleID != 1 {
|
|
t.Fatalf("Expected RoleID=1, got %v", user.RoleID)
|
|
}
|
|
|
|
if user.Projects == nil || len(*user.Projects) != 1 {
|
|
t.Fatalf("Expected 1 project, got %v", user.Projects)
|
|
}
|
|
|
|
if !reflect.DeepEqual((*user.Projects)[0].RoleID, []int{1, 12}) {
|
|
t.Fatalf("Expected project roles [1 12], got %v", (*user.Projects)[0].RoleID)
|
|
}
|
|
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("Unfulfilled expectations: %v", err)
|
|
}
|
|
}
|