mirror of
https://github.com/pawelorzech/Swoosh.git
synced 2026-03-31 20:15:41 +00:00
feat: add Pages API model, endpoints, and model tests
Introduce GhostPage, PagesResponse, PageWrapper data classes for Ghost CMS static pages. Add CRUD endpoints (getPages, createPage, updatePage, deletePage) to GhostApiService. Include comprehensive unit tests for serialization and default values.
This commit is contained in:
parent
0891013df6
commit
d83309f8bc
3 changed files with 212 additions and 0 deletions
|
|
@ -1,5 +1,7 @@
|
|||
package com.swoosh.microblog.data.api
|
||||
|
||||
import com.swoosh.microblog.data.model.PageWrapper
|
||||
import com.swoosh.microblog.data.model.PagesResponse
|
||||
import com.swoosh.microblog.data.model.PostWrapper
|
||||
import com.swoosh.microblog.data.model.PostsResponse
|
||||
import okhttp3.MultipartBody
|
||||
|
|
@ -40,6 +42,28 @@ interface GhostApiService {
|
|||
@GET("ghost/api/admin/users/me/")
|
||||
suspend fun getCurrentUser(): Response<UsersResponse>
|
||||
|
||||
// --- Pages ---
|
||||
|
||||
@GET("ghost/api/admin/pages/")
|
||||
suspend fun getPages(
|
||||
@Query("limit") limit: String = "all",
|
||||
@Query("formats") formats: String = "html,plaintext,mobiledoc"
|
||||
): Response<PagesResponse>
|
||||
|
||||
@POST("ghost/api/admin/pages/")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun createPage(@Body body: PageWrapper): Response<PagesResponse>
|
||||
|
||||
@PUT("ghost/api/admin/pages/{id}/")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun updatePage(
|
||||
@Path("id") id: String,
|
||||
@Body body: PageWrapper
|
||||
): Response<PagesResponse>
|
||||
|
||||
@DELETE("ghost/api/admin/pages/{id}/")
|
||||
suspend fun deletePage(@Path("id") id: String): Response<Unit>
|
||||
|
||||
@Multipart
|
||||
@POST("ghost/api/admin/images/upload/")
|
||||
suspend fun uploadImage(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package com.swoosh.microblog.data.model
|
||||
|
||||
data class PagesResponse(
|
||||
val pages: List<GhostPage>,
|
||||
val meta: Meta?
|
||||
)
|
||||
|
||||
data class PageWrapper(
|
||||
val pages: List<GhostPage>
|
||||
)
|
||||
|
||||
data class GhostPage(
|
||||
val id: String? = null,
|
||||
val title: String? = null,
|
||||
val slug: String? = null,
|
||||
val url: String? = null,
|
||||
val html: String? = null,
|
||||
val plaintext: String? = null,
|
||||
val mobiledoc: String? = null,
|
||||
val status: String? = null,
|
||||
val feature_image: String? = null,
|
||||
val custom_excerpt: String? = null,
|
||||
val created_at: String? = null,
|
||||
val updated_at: String? = null,
|
||||
val published_at: String? = null
|
||||
)
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
package com.swoosh.microblog.data.model
|
||||
|
||||
import com.google.gson.Gson
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Test
|
||||
|
||||
class PageModelsTest {
|
||||
|
||||
private val gson = Gson()
|
||||
|
||||
// --- GhostPage defaults ---
|
||||
|
||||
@Test
|
||||
fun `GhostPage all fields default to null`() {
|
||||
val page = GhostPage()
|
||||
assertNull(page.id)
|
||||
assertNull(page.title)
|
||||
assertNull(page.slug)
|
||||
assertNull(page.url)
|
||||
assertNull(page.html)
|
||||
assertNull(page.plaintext)
|
||||
assertNull(page.mobiledoc)
|
||||
assertNull(page.status)
|
||||
assertNull(page.feature_image)
|
||||
assertNull(page.custom_excerpt)
|
||||
assertNull(page.created_at)
|
||||
assertNull(page.updated_at)
|
||||
assertNull(page.published_at)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GhostPage stores all fields correctly`() {
|
||||
val page = GhostPage(
|
||||
id = "page-1",
|
||||
title = "About",
|
||||
slug = "about",
|
||||
url = "https://blog.example.com/about/",
|
||||
html = "<p>About us</p>",
|
||||
plaintext = "About us",
|
||||
mobiledoc = """{"version":"0.3.1"}""",
|
||||
status = "published",
|
||||
feature_image = "https://blog.example.com/img.jpg",
|
||||
custom_excerpt = "Learn more about us",
|
||||
created_at = "2024-01-01T00:00:00.000Z",
|
||||
updated_at = "2024-06-15T12:00:00.000Z",
|
||||
published_at = "2024-01-02T00:00:00.000Z"
|
||||
)
|
||||
assertEquals("page-1", page.id)
|
||||
assertEquals("About", page.title)
|
||||
assertEquals("about", page.slug)
|
||||
assertEquals("https://blog.example.com/about/", page.url)
|
||||
assertEquals("<p>About us</p>", page.html)
|
||||
assertEquals("About us", page.plaintext)
|
||||
assertEquals("published", page.status)
|
||||
assertEquals("https://blog.example.com/img.jpg", page.feature_image)
|
||||
assertEquals("Learn more about us", page.custom_excerpt)
|
||||
assertEquals("2024-01-01T00:00:00.000Z", page.created_at)
|
||||
assertEquals("2024-06-15T12:00:00.000Z", page.updated_at)
|
||||
assertEquals("2024-01-02T00:00:00.000Z", page.published_at)
|
||||
}
|
||||
|
||||
// --- GSON serialization ---
|
||||
|
||||
@Test
|
||||
fun `GhostPage serializes to JSON correctly`() {
|
||||
val page = GhostPage(
|
||||
id = "abc123",
|
||||
title = "Contact",
|
||||
slug = "contact",
|
||||
status = "published"
|
||||
)
|
||||
val json = gson.toJson(page)
|
||||
assertTrue(json.contains("\"id\":\"abc123\""))
|
||||
assertTrue(json.contains("\"title\":\"Contact\""))
|
||||
assertTrue(json.contains("\"slug\":\"contact\""))
|
||||
assertTrue(json.contains("\"status\":\"published\""))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GhostPage deserializes from JSON correctly`() {
|
||||
val json = """{"id":"xyz","title":"FAQ","slug":"faq","status":"draft"}"""
|
||||
val page = gson.fromJson(json, GhostPage::class.java)
|
||||
assertEquals("xyz", page.id)
|
||||
assertEquals("FAQ", page.title)
|
||||
assertEquals("faq", page.slug)
|
||||
assertEquals("draft", page.status)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GhostPage deserializes with missing optional fields`() {
|
||||
val json = """{"id":"test"}"""
|
||||
val page = gson.fromJson(json, GhostPage::class.java)
|
||||
assertEquals("test", page.id)
|
||||
assertNull(page.title)
|
||||
assertNull(page.slug)
|
||||
assertNull(page.html)
|
||||
assertNull(page.status)
|
||||
}
|
||||
|
||||
// --- PagesResponse ---
|
||||
|
||||
@Test
|
||||
fun `PagesResponse deserializes with pages and pagination`() {
|
||||
val json = """{
|
||||
"pages": [{"id": "1", "title": "About"}, {"id": "2", "title": "Contact"}],
|
||||
"meta": {"pagination": {"page": 1, "limit": 15, "pages": 1, "total": 2, "next": null, "prev": null}}
|
||||
}"""
|
||||
val response = gson.fromJson(json, PagesResponse::class.java)
|
||||
assertEquals(2, response.pages.size)
|
||||
assertEquals("1", response.pages[0].id)
|
||||
assertEquals("About", response.pages[0].title)
|
||||
assertEquals("2", response.pages[1].id)
|
||||
assertEquals("Contact", response.pages[1].title)
|
||||
assertEquals(1, response.meta?.pagination?.page)
|
||||
assertEquals(2, response.meta?.pagination?.total)
|
||||
assertNull(response.meta?.pagination?.next)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PagesResponse deserializes with empty pages list`() {
|
||||
val json = """{"pages": [], "meta": null}"""
|
||||
val response = gson.fromJson(json, PagesResponse::class.java)
|
||||
assertTrue(response.pages.isEmpty())
|
||||
assertNull(response.meta)
|
||||
}
|
||||
|
||||
// --- PageWrapper ---
|
||||
|
||||
@Test
|
||||
fun `PageWrapper wraps pages for API request`() {
|
||||
val wrapper = PageWrapper(listOf(GhostPage(title = "New Page", status = "draft")))
|
||||
val json = gson.toJson(wrapper)
|
||||
assertTrue(json.contains("\"pages\""))
|
||||
assertTrue(json.contains("\"New Page\""))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PageWrapper serializes single page correctly`() {
|
||||
val page = GhostPage(
|
||||
title = "About Us",
|
||||
slug = "about-us",
|
||||
status = "published",
|
||||
mobiledoc = """{"version":"0.3.1","atoms":[],"cards":[],"markups":[],"sections":[[1,"p",[[0,[],0,"Welcome"]]]]}"""
|
||||
)
|
||||
val wrapper = PageWrapper(listOf(page))
|
||||
val json = gson.toJson(wrapper)
|
||||
assertTrue(json.contains("\"title\":\"About Us\""))
|
||||
assertTrue(json.contains("\"slug\":\"about-us\""))
|
||||
assertTrue(json.contains("\"status\":\"published\""))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GhostPage updated_at is preserved for PUT requests`() {
|
||||
val page = GhostPage(
|
||||
id = "page-1",
|
||||
title = "Updated Title",
|
||||
updated_at = "2024-06-15T12:00:00.000Z"
|
||||
)
|
||||
val json = gson.toJson(page)
|
||||
assertTrue(json.contains("\"updated_at\":\"2024-06-15T12:00:00.000Z\""))
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue