# Blog API End-to-End Manual Test Guide
**Linear Task:** 09-152
**Time Estimate:** 15 minutes
**Status:** Ready for Testing

## Prerequisites

1. **Laravel server running:**
   ```bash
   php artisan serve --port=8000
   ```

2. **Admin credentials:** You need valid admin credentials to test protected endpoints
   - Email: `admin@showprima.com` (or your admin email)
   - Password: `admin123` (or your admin password)

3. **Tools needed:**
   - `curl` (command line)
   - `jq` (for JSON formatting - install with `brew install jq`)
   - OR use Postman/Insomnia for easier testing

## Test Sequence

### Step 1: ✅ Get Admin Token

```bash
curl -X POST http://localhost:8000/api/admin/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@showprima.com",
    "password": "admin123"
  }' | jq '.'
```

**Expected Result:**
```json
{
  "success": true,
  "data": {
    "token": "eyJ0eXAiOiJKV1QiLCJhbGc..."
  }
}
```

**Save the token for next steps:**
```bash
export TOKEN="your-token-here"
```

---

### Step 2: ✅ Get Blog Categories

```bash
curl -X GET http://localhost:8000/api/admin/blog-categories \
  -H "Authorization: Bearer $TOKEN" | jq '.'
```

**Expected Result:**
```json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "name": "Technology",
      "slug": "technology",
      "status": 1,
      ...
    }
  ]
}
```

**Save a category ID:**
```bash
export CATEGORY_ID=1
```

---

### Step 3: ✅ Create Blog with Image

**First, create a test image:**
```bash
# Using ImageMagick
convert -size 100x100 xc:blue /tmp/test_blog.png

# OR using Python
python3 -c "from PIL import Image; Image.new('RGB', (100,100), 'blue').save('/tmp/test_blog.png')"
```

**Then create the blog:**
```bash
curl -X POST http://localhost:8000/api/admin/blogs \
  -H "Authorization: Bearer $TOKEN" \
  -F "category_id=$CATEGORY_ID" \
  -F "title=My Test Blog Article $(date +%s)" \
  -F "description=This is a comprehensive test blog article with all fields and image upload." \
  -F "image=@/tmp/test_blog.png" \
  -F "is_published=1" \
  -F "show_on_homepage=1" \
  -F "status=1" | jq '.'
```

**Expected Result:**
```json
{
  "success": true,
  "data": {
    "id": 1,
    "category_id": 1,
    "title": "My Test Blog Article",
    "slug": "my-test-blog-article",  // ✅ Auto-generated
    "description": "This is a comprehensive...",
    "image": "blogs/1696348293123456.png",  // ✅ Stored in blogs/
    "is_published": 1,
    "show_on_homepage": 1,
    "status": 1,
    "blog_views": 0,
    ...
  },
  "message": "Blog created successfully"
}
```

**Save the blog ID and slug:**
```bash
export BLOG_ID=1
export BLOG_SLUG="my-test-blog-article"
```

**✅ Verify:** Slug auto-generated from title
**✅ Verify:** Image path starts with `blogs/`

---

### Step 4: ✅ List Blogs

```bash
curl -X GET http://localhost:8000/api/admin/blogs \
  -H "Authorization: Bearer $TOKEN" | jq '.data.data[] | {id, title, slug, image}'
```

**Expected Result:**
```json
[
  {
    "id": 1,
    "title": "My Test Blog Article",
    "slug": "my-test-blog-article",
    "image": "blogs/1696348293123456.png"
  }
]
```

**✅ Verify:** Created blog appears in list

---

### Step 5: ✅ Update Blog

**Create a new test image:**
```bash
convert -size 100x100 xc:red /tmp/test_blog_updated.png
```

**Update the blog:**
```bash
curl -X POST http://localhost:8000/api/admin/blogs/$BLOG_ID \
  -H "Authorization: Bearer $TOKEN" \
  -F "title=Updated Test Blog Article" \
  -F "description=This blog has been updated with new content and a new image." \
  -F "image=@/tmp/test_blog_updated.png" | jq '.'
```

**Expected Result:**
```json
{
  "success": true,
  "data": {
    "id": 1,
    "title": "Updated Test Blog Article",
    "slug": "updated-test-blog-article",  // ✅ New slug
    "image": "blogs/1696348295789012.png",  // ✅ New image
    ...
  },
  "message": "Blog updated successfully"
}
```

**✅ Verify:** Old image deleted from `storage/app/public/blogs/`
**✅ Verify:** New image exists in storage

---

### Step 6: ✅ Toggle Status

**Toggle status OFF:**
```bash
curl -X POST http://localhost:8000/api/admin/blogs/$BLOG_ID/toggle-status \
  -H "Authorization: Bearer $TOKEN" | jq '.data.status'
```

**Expected Result:** `0` (status is now OFF)

**Toggle status ON:**
```bash
curl -X POST http://localhost:8000/api/admin/blogs/$BLOG_ID/toggle-status \
  -H "Authorization: Bearer $TOKEN" | jq '.data.status'
```

**Expected Result:** `1` (status is now ON)

---

### Step 7: ✅ Public View (Increment Views)

**First access:**
```bash
curl -X GET http://localhost:8000/api/blogs/$BLOG_SLUG | jq '.data | {title, slug, blog_views}'
```

**Expected Result:**
```json
{
  "title": "Updated Test Blog Article",
  "slug": "updated-test-blog-article",
  "blog_views": 1  // ✅ First view
}
```

**Second access:**
```bash
curl -X GET http://localhost:8000/api/blogs/$BLOG_SLUG | jq '.data.blog_views'
```

**Expected Result:** `2` (views incremented)

**Third access:**
```bash
curl -X GET http://localhost:8000/api/blogs/$BLOG_SLUG | jq '.data.blog_views'
```

**Expected Result:** `3` (views incremented again)

**✅ Verify:** `blog_views` increments on each public access

---

### Step 8: ✅ Verify Image Accessibility

**Get the image filename from the blog:**
```bash
IMAGE_PATH=$(curl -s -X GET http://localhost:8000/api/admin/blogs/$BLOG_ID \
  -H "Authorization: Bearer $TOKEN" | jq -r '.data.image')

echo "Image path: $IMAGE_PATH"
```

**Access the image via public URL:**
```bash
curl -I http://localhost:8000/storage/$IMAGE_PATH
```

**Expected Result:**
```
HTTP/1.1 200 OK
Content-Type: image/png
...
```

**OR test in browser:**
```
http://localhost:8000/storage/blogs/{filename}
```

**✅ Verify:** Image accessible via `/storage/blogs/{filename}`

**Note:** If you get 404, run:
```bash
php artisan storage:link
```

---

### Step 9: ✅ Delete Blog

```bash
curl -X DELETE http://localhost:8000/api/admin/blogs/$BLOG_ID \
  -H "Authorization: Bearer $TOKEN" | jq '.'
```

**Expected Result:**
```json
{
  "success": true,
  "message": "Blog deleted successfully"
}
```

**Verify deletion:**
```bash
curl -X GET http://localhost:8000/api/admin/blogs/$BLOG_ID \
  -H "Authorization: Bearer $TOKEN" | jq '.'
```

**Expected Result:**
```json
{
  "success": false,
  "message": "Blog not found"
}
```

**Verify image deleted:**
```bash
curl -I http://localhost:8000/storage/$IMAGE_PATH
```

**Expected Result:** `404 Not Found`

**✅ Verify:** Blog deleted from database
**✅ Verify:** Image file deleted from storage

---

## Test Checklist

### Expected Results Summary:

- [x] **1. Get categories** - Returns proper JSON with blog categories
- [x] **2. Create blog** - Returns success with blog data and image stored
- [x] **3. List blogs** - Returns paginated list including created blog
- [x] **4. Update blog** - Returns success with updated data
- [x] **5. Toggle status** - Status toggles between 0 and 1
- [x] **6. Public view** - Blog views increment on each access
- [x] **7. Delete blog** - Blog and image removed from system

### File System Checks:

- [x] **Image stored in:** `storage/app/public/blogs/`
- [x] **Image accessible via:** `/storage/blogs/{filename}`
- [x] **Slug auto-generated** from title
- [x] **Old image deleted** when blog updated with new image

---

## Alternative: Using Postman/Insomnia

### Import Collection:

Create a Postman collection with these endpoints:

1. **POST** `{{baseUrl}}/admin/login` - Get Token
2. **GET** `{{baseUrl}}/admin/blog-categories` - List Categories
3. **POST** `{{baseUrl}}/admin/blogs` - Create Blog (form-data)
4. **GET** `{{baseUrl}}/admin/blogs` - List Blogs
5. **POST** `{{baseUrl}}/admin/blogs/{{blogId}}` - Update Blog
6. **POST** `{{baseUrl}}/admin/blogs/{{blogId}}/toggle-status` - Toggle Status
7. **GET** `{{baseUrl}}/blogs/{{slug}}` - Public View
8. **DELETE** `{{baseUrl}}/admin/blogs/{{blogId}}` - Delete Blog

### Environment Variables:
```
baseUrl: http://localhost:8000/api
token: (set after login)
blogId: (set after create)
slug: (set after create)
```

---

## Troubleshooting

### 401 Unauthorized
- Check token is valid and not expired
- Ensure `Authorization: Bearer {token}` header is set

### 404 Not Found on Images
- Run `php artisan storage:link`
- Check file exists in `storage/app/public/blogs/`

### 422 Validation Error
- Check all required fields are provided
- Verify image file is valid (jpeg, png, jpg, gif)
- Image must be under 2MB

### 500 Internal Server Error
- Check Laravel logs: `tail -f storage/logs/laravel.log`
- Verify database connection is working
- Check file permissions on storage directory

---

## Success Criteria

✅ All endpoints return proper JSON responses
✅ Image stored in `storage/app/public/blogs/`
✅ Image accessible via `/storage/blogs/{filename}`
✅ Slug auto-generated from title
✅ Blog views increment on public access
✅ Old image deleted when blog updated with new image

**Status:** All tests should pass within 15 minutes.
