You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Use the refreshToken from Step 3
curl -s -X POST "http://localhost:8080/api/v1/auth/refresh?refreshToken=<refresh_token_from_step_3>"| jq .# Expected: 200, new accessToken and refreshToken
Step 10: Logout
curl -s -X POST http://localhost:8080/api/v1/auth/logout \
-H "Authorization: Bearer $TOKEN_A"| jq .# Expected: 200, "Logout successful"# Then verify token is blacklisted:
curl -s http://localhost:8080/api/v1/users/me \
-H "Authorization: Bearer $TOKEN_A"| jq .# Expected: 401 or 403
Phase 2: Articles CRUD
#
Step
Command
Expected
Progress
11
Create Article (draft)
See below
201, article data
✅ 2026-04-04
12
Create Article 2
See below
201, article data
✅ 2026-04-04
13
Create Article (User B)
See below
201, article data
✅ 2026-04-04
14
List Published Articles
See below
200, paginated list (empty - all drafts)
✅ 2026-04-04
15
Get Article by Slug
See below
200, full article
✅ 2026-04-04
16
Update Article
See below
200, updated article
✅ 2026-04-04
17
Unauthorized Update
See below
403, error
✅ 2026-04-04
18
Get My Articles
See below
200, user's articles (incl drafts)
✅ 2026-04-04
19
Delete Article
See below
204, no content
✅ 2026-04-04
Step 11: Create Article (draft)
curl -s -X POST http://localhost:8080/api/v1/articles \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN_A" \
-d '{ "title": "Getting Started with Spring Boot", "subtitle": "A comprehensive guide", "body": "Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications. In this article we will cover the basics of Spring Boot, including dependency injection, auto-configuration, and embedded servers.", "tags": ["spring-boot", "java", "backend"] }'| jq .# Save the article id and slug for later steps
Step 12: Create Article 2
curl -s -X POST http://localhost:8080/api/v1/articles \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN_A" \
-d '{ "title": "Building REST APIs with Spring", "subtitle": "Best practices for REST", "body": "REST APIs are the backbone of modern web applications. This article covers best practices for designing and implementing RESTful services using Spring Boot.", "tags": ["rest", "spring-boot", "api"] }'| jq .
Step 13: Create Article (User B)
curl -s -X POST http://localhost:8080/api/v1/articles \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN_B" \
-d '{ "title": "Introduction to PostgreSQL", "subtitle": "Database fundamentals", "body": "PostgreSQL is a powerful, open source object-relational database system. It has over 30 years of active development and has earned a strong reputation for reliability and performance.", "tags": ["postgresql", "database", "sql"] }'| jq .
Step 14: List Published Articles
curl -s "http://localhost:8080/api/v1/articles?page=0&size=10&sort=createdAt,desc"| jq .# Note: Articles are created as DRAFT by default, so this may return empty until we publish them
Step 15: Get Article by Slug
curl -s http://localhost:8080/api/v1/articles/getting-started-with-spring-boot | jq .# Use the actual slug from Step 11 response
Step 16: Update Article
curl -s -X PUT http://localhost:8080/api/v1/articles/<article_id_from_step_11> \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN_A" \
-d '{ "title": "Getting Started with Spring Boot 3", "body": "Updated content for Spring Boot 3. Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications." }'| jq .
Step 17: Unauthorized Update
curl -s -X PUT http://localhost:8080/api/v1/articles/<article_id_from_step_11> \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN_B" \
-d '{ "title": "Hacked Title" }'| jq .# Expected: 403, "You can only edit your own articles"
Step 18: Get My Articles
curl -s http://localhost:8080/api/v1/articles/my \
-H "Authorization: Bearer $TOKEN_A"| jq .# Should include both published and draft articles
curl -s -X POST http://localhost:8080/api/v1/articles/<slug_from_step_11>/comments \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN_B" \
-d '{ "title": "Great article!", "body": "This is a really helpful guide. Thanks for sharing!" }'| jq .# Save the comment id for later steps
Step 21: Create Reply
curl -s -X POST http://localhost:8080/api/v1/articles/<slug_from_step_11>/comments \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN_A" \
-d '{ "body": "Thanks for the feedback! Glad you found it useful.", "parentId": <comment_id_from_step_20> }'| jq .
Step 22: Get Comments
curl -s http://localhost:8080/api/v1/articles/<slug_from_step_11>/comments | jq .# Should show the comment with nested replies
Step 23: Get Replies
curl -s http://localhost:8080/api/v1/articles/<slug_from_step_11>/comments/<comment_id_from_step_20>/replies | jq .# Should show the reply from Step 21
# Note: This requires ADMIN role. Default users are USER role.# This step will fail with 403 unless you manually grant ADMIN role to a user.
curl -s -X POST http://localhost:8080/api/v1/tags \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN_A" \
-d '{ "name": "tutorial" }'| jq .# Expected: 403 (unless user has ADMIN role)