362 lines
8.5 KiB
Bash
Executable File
362 lines
8.5 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Unit tests for branch.sh script
|
|
# Run from project root: ./tools/test_branch.sh
|
|
#
|
|
|
|
# Don't exit on error - we want to run all tests
|
|
set +e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Test counters
|
|
TESTS_RUN=0
|
|
TESTS_PASSED=0
|
|
TESTS_FAILED=0
|
|
|
|
# Save current branch
|
|
ORIGINAL_BRANCH=$(git branch --show-current)
|
|
|
|
# Cleanup function
|
|
cleanup() {
|
|
# Remove test user cache files
|
|
rm -f ~/.qtx_branch_last_user 2>/dev/null || true
|
|
|
|
# Return to original branch
|
|
git checkout "$ORIGINAL_BRANCH" 2>/dev/null || git checkout develop 2>/dev/null || true
|
|
|
|
# Delete test branches
|
|
git branch 2>/dev/null | grep -E "(testuser|cached_user|user123|typetest|nametest|secureuser|validationtest)" | xargs -r git branch -D 2>/dev/null || true
|
|
}
|
|
|
|
# Setup
|
|
trap cleanup EXIT
|
|
|
|
echo "========================================"
|
|
echo " Branch Script Unit Tests"
|
|
echo "========================================"
|
|
echo ""
|
|
|
|
# Test helper function - pass test
|
|
pass_test() {
|
|
local test_name="$1"
|
|
TESTS_RUN=$((TESTS_RUN + 1))
|
|
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
echo -e "${GREEN}✓${NC} PASS: $test_name"
|
|
}
|
|
|
|
# Test helper function - fail test
|
|
fail_test() {
|
|
local test_name="$1"
|
|
local reason="$2"
|
|
TESTS_RUN=$((TESTS_RUN + 1))
|
|
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
echo -e "${RED}✗${NC} FAIL: $test_name${reason:+ - $reason}"
|
|
}
|
|
|
|
echo "Running tests..."
|
|
echo ""
|
|
|
|
# ====================
|
|
# Test 1: Valid branch creation
|
|
# ====================
|
|
echo "Test Suite 1: Valid Branch Creation"
|
|
echo "------------------------------------"
|
|
|
|
cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
|
|
1
|
|
testuser
|
|
123
|
|
valid branch
|
|
EOF
|
|
|
|
if git rev-parse --verify "feature/testuser/SKL-123/valid_branch" &>/dev/null; then
|
|
pass_test "Create valid feature branch"
|
|
else
|
|
fail_test "Create valid feature branch" "Branch not found"
|
|
fi
|
|
|
|
if [[ "$(git branch --show-current)" == "feature/testuser/SKL-123/valid_branch" ]]; then
|
|
pass_test "Checkout to created branch"
|
|
else
|
|
fail_test "Checkout to created branch" "Not on expected branch"
|
|
fi
|
|
|
|
git checkout develop &>/dev/null
|
|
echo ""
|
|
|
|
# ====================
|
|
# Test 2: User cache functionality
|
|
# ====================
|
|
echo "Test Suite 2: User Cache Functionality"
|
|
echo "---------------------------------------"
|
|
|
|
# Create cache file
|
|
rm -f ~/.qtx_branch_last_user
|
|
cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
|
|
6
|
|
cached_user
|
|
456
|
|
using cache
|
|
EOF
|
|
|
|
if [[ -f ~/.qtx_branch_last_user ]]; then
|
|
pass_test "User cache file created"
|
|
else
|
|
fail_test "User cache file created" "File not found"
|
|
fi
|
|
|
|
# Check permissions
|
|
PERMS=$(stat -f "%Lp" ~/.qtx_branch_last_user 2>/dev/null || stat -c "%a" ~/.qtx_branch_last_user 2>/dev/null)
|
|
if [[ "$PERMS" == "600" ]]; then
|
|
pass_test "User cache has secure permissions (600)"
|
|
else
|
|
fail_test "User cache has secure permissions (600)" "Got $PERMS"
|
|
fi
|
|
|
|
if grep -q "cached_user" ~/.qtx_branch_last_user; then
|
|
pass_test "User cache contains correct value"
|
|
else
|
|
fail_test "User cache contains correct value"
|
|
fi
|
|
|
|
git checkout develop &>/dev/null
|
|
echo ""
|
|
|
|
# ====================
|
|
# Test 3: Input validation
|
|
# ====================
|
|
echo "Test Suite 3: Input Validation"
|
|
echo "-------------------------------"
|
|
|
|
# Test invalid username with special characters
|
|
OUTPUT=$(cat << 'EOF' 2>/dev/null | timeout 5 ./tools/branch.sh 2>&1 || true
|
|
1
|
|
user@invalid
|
|
EOF
|
|
)
|
|
|
|
if echo "$OUTPUT" | grep -q "Error: user must be alphanumeric"; then
|
|
pass_test "Reject username with special characters"
|
|
else
|
|
fail_test "Reject username with special characters"
|
|
fi
|
|
|
|
# Test non-numeric issue number
|
|
OUTPUT=$(cat << 'EOF' 2>/dev/null | timeout 5 ./tools/branch.sh 2>&1 || true
|
|
1
|
|
validationtest
|
|
abc123
|
|
EOF
|
|
)
|
|
|
|
if echo "$OUTPUT" | grep -q "Error: issue number must be numeric"; then
|
|
pass_test "Reject non-numeric issue number"
|
|
else
|
|
fail_test "Reject non-numeric issue number"
|
|
fi
|
|
|
|
# Test empty summary
|
|
OUTPUT=$(cat << 'EOF' 2>/dev/null | timeout 5 ./tools/branch.sh 2>&1 || true
|
|
1
|
|
validationtest
|
|
999
|
|
|
|
EOF
|
|
)
|
|
|
|
if echo "$OUTPUT" | grep -q "Error: summary is required"; then
|
|
pass_test "Reject empty summary"
|
|
else
|
|
fail_test "Reject empty summary"
|
|
fi
|
|
|
|
# Test summary too long (over 100 chars)
|
|
LONG_SUMMARY="this is a very long summary that exceeds one hundred characters and should be rejected by the validation"
|
|
OUTPUT=$(cat << EOF 2>/dev/null | timeout 5 ./tools/branch.sh 2>&1 || true
|
|
1
|
|
validationtest
|
|
999
|
|
$LONG_SUMMARY
|
|
EOF
|
|
)
|
|
|
|
if echo "$OUTPUT" | grep -q "Error: summary too long"; then
|
|
pass_test "Reject summary over 100 characters"
|
|
else
|
|
fail_test "Reject summary over 100 characters"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# ====================
|
|
# Test 4: ISSUE_PREFIX extraction
|
|
# ====================
|
|
echo "Test Suite 4: ISSUE_PREFIX Extraction"
|
|
echo "--------------------------------------"
|
|
|
|
# Backup original Makefile.common
|
|
cp Makefile.common Makefile.common.backup
|
|
|
|
# Test with different prefix
|
|
cat > Makefile.common << 'EOF'
|
|
ISSUE_PREFIX := TEST
|
|
GOPATH ?= $(shell go env GOPATH)
|
|
EOF
|
|
|
|
cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
|
|
1
|
|
user123
|
|
789
|
|
different prefix
|
|
EOF
|
|
|
|
# Restore original
|
|
mv Makefile.common.backup Makefile.common
|
|
|
|
if git rev-parse --verify "feature/user123/TEST-789/different_prefix" &>/dev/null; then
|
|
pass_test "Create branch with custom ISSUE_PREFIX"
|
|
else
|
|
fail_test "Create branch with custom ISSUE_PREFIX" "Branch not found with TEST prefix"
|
|
fi
|
|
|
|
git checkout develop &>/dev/null
|
|
echo ""
|
|
|
|
# ====================
|
|
# Test 5: Branch name formatting
|
|
# ====================
|
|
echo "Test Suite 5: Branch Name Formatting"
|
|
echo "-------------------------------------"
|
|
|
|
# Spaces should become underscores
|
|
BRANCH_OUTPUT=$(cat << 'EOF' | timeout 10 ./tools/branch.sh 2>&1
|
|
2
|
|
nametest
|
|
111
|
|
spaces in summary here
|
|
EOF
|
|
)
|
|
|
|
if echo "$BRANCH_OUTPUT" | grep -q "hotfix/nametest/SKL-111/spaces_in_summary_here"; then
|
|
pass_test "Spaces converted to underscores in branch name"
|
|
else
|
|
fail_test "Spaces converted to underscores in branch name"
|
|
fi
|
|
|
|
git branch -D "hotfix/nametest/SKL-111/spaces_in_summary_here" &>/dev/null || true
|
|
git checkout develop &>/dev/null
|
|
echo ""
|
|
|
|
# ====================
|
|
# Test 6: Different branch types
|
|
# ====================
|
|
echo "Test Suite 6: All Branch Types"
|
|
echo "-------------------------------"
|
|
|
|
# Test feature type
|
|
cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
|
|
1
|
|
typetest
|
|
301
|
|
test feature
|
|
EOF
|
|
|
|
if git rev-parse --verify "feature/typetest/SKL-301/test_feature" &>/dev/null; then
|
|
pass_test "Branch type 'feature' works"
|
|
git branch -D "feature/typetest/SKL-301/test_feature" &>/dev/null
|
|
else
|
|
fail_test "Branch type 'feature' works"
|
|
fi
|
|
|
|
# Test hotfix type
|
|
cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
|
|
2
|
|
typetest
|
|
302
|
|
test hotfix
|
|
EOF
|
|
|
|
if git rev-parse --verify "hotfix/typetest/SKL-302/test_hotfix" &>/dev/null; then
|
|
pass_test "Branch type 'hotfix' works"
|
|
git branch -D "hotfix/typetest/SKL-302/test_hotfix" &>/dev/null
|
|
else
|
|
fail_test "Branch type 'hotfix' works"
|
|
fi
|
|
|
|
# Test fix type
|
|
cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
|
|
6
|
|
typetest
|
|
306
|
|
test fix
|
|
EOF
|
|
|
|
if git rev-parse --verify "fix/typetest/SKL-306/test_fix" &>/dev/null; then
|
|
pass_test "Branch type 'fix' works"
|
|
git branch -D "fix/typetest/SKL-306/test_fix" &>/dev/null
|
|
else
|
|
fail_test "Branch type 'fix' works"
|
|
fi
|
|
|
|
git checkout develop &>/dev/null
|
|
echo ""
|
|
|
|
# ====================
|
|
# Test 7: Symlink attack prevention
|
|
# ====================
|
|
echo "Test Suite 7: Security - Symlink Prevention"
|
|
echo "--------------------------------------------"
|
|
|
|
# Create a symlink as the user file
|
|
USER_CACHE=~/.qtx_branch_last_user
|
|
TEMP_TARGET=$(mktemp)
|
|
rm -f "$USER_CACHE"
|
|
ln -s "$TEMP_TARGET" "$USER_CACHE"
|
|
|
|
cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
|
|
1
|
|
secureuser
|
|
999
|
|
security test
|
|
EOF
|
|
|
|
# Check if symlink was removed and replaced with regular file
|
|
if [[ -L "$USER_CACHE" ]]; then
|
|
fail_test "Symlink removed before writing" "Symlink still exists (security risk)"
|
|
else
|
|
pass_test "Symlink removed before writing (secure)"
|
|
fi
|
|
|
|
rm -f "$TEMP_TARGET"
|
|
git branch -D "feature/secureuser/SKL-999/security_test" &>/dev/null || true
|
|
git checkout develop &>/dev/null
|
|
echo ""
|
|
|
|
# ====================
|
|
# Summary
|
|
# ====================
|
|
echo "========================================"
|
|
echo " Test Summary"
|
|
echo "========================================"
|
|
echo -e "Total: $TESTS_RUN"
|
|
echo -e "${GREEN}Passed: $TESTS_PASSED${NC}"
|
|
if [[ $TESTS_FAILED -gt 0 ]]; then
|
|
echo -e "${RED}Failed: $TESTS_FAILED${NC}"
|
|
else
|
|
echo -e "Failed: $TESTS_FAILED"
|
|
fi
|
|
echo ""
|
|
|
|
if [[ $TESTS_FAILED -eq 0 ]]; then
|
|
echo -e "${GREEN}✓ All tests passed!${NC}"
|
|
exit 0
|
|
else
|
|
echo -e "${RED}✗ Some tests failed!${NC}"
|
|
exit 1
|
|
fi
|