From 7c55f5c8c332b15ec300139b72a80addecaad270 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 18 May 2023 15:33:00 +0900 Subject: [PATCH] =?UTF-8?q?test:=20=E8=AA=8D=E8=A8=BC=E9=96=A2=E4=BF=82?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/model/hideout/dto/PostCreateDto.kt | 2 +- .../hideout/routing/api/internal/v1/Users.kt | 13 + src/main/resources/openapi/documentation.yaml | 365 ++++++++++++++++++ .../routing/activitypub/UsersAPTest.kt | 38 +- .../routing/api/internal/v1/PostsKtTest.kt | 2 +- .../ActivityPubFollowServiceImplTest.kt | 2 +- 6 files changed, 391 insertions(+), 31 deletions(-) create mode 100644 src/main/resources/openapi/documentation.yaml diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/PostCreateDto.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/PostCreateDto.kt index 272215a2..1869da21 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/PostCreateDto.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/PostCreateDto.kt @@ -5,7 +5,7 @@ import dev.usbharu.hideout.domain.model.hideout.entity.Visibility data class PostCreateDto( val text: String, val overview: String? = null, - val visibility: Visibility, + val visibility: Visibility = Visibility.PUBLIC, val repostId: Long? = null, val repolyId: Long? = null, val userId: Long diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt index a16f28b7..13917837 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt @@ -38,6 +38,19 @@ fun Route.users(userService: IUserService) { } route("/{name}") { + authenticate(TOKEN_AUTH, optional = true) { + get { + val userParameter = (call.parameters["name"] + ?: throw ParameterNotExistException("Parameter(name='userName@domain') does not exist.")) + if (userParameter.toLongOrNull() != null) { + return@get call.respond(userService.findById(userParameter.toLong())) + } else { + val acct = AcctUtil.parse(userParameter) + return@get call.respond(userService.findByNameAndDomain(acct.username, acct.domain)) + } + } + } + route("/followers") { get { val userParameter = call.parameters["name"] diff --git a/src/main/resources/openapi/documentation.yaml b/src/main/resources/openapi/documentation.yaml new file mode 100644 index 00000000..d4e6d624 --- /dev/null +++ b/src/main/resources/openapi/documentation.yaml @@ -0,0 +1,365 @@ +openapi: "3.0.3" +info: + title: "hideout API" + description: "hideout API" + version: "1.0.0" +servers: + - url: "https://hideout" +paths: + /.well-known/jwks.json: + get: + description: "" + responses: + "200": + description: "OK" + content: + application/json: + schema: + type: "string" + /auth-check: + get: + description: "" + responses: + "200": + description: "OK" + content: + text/plain: + schema: + type: "string" + examples: + Example#1: + value: "" + /login: + post: + description: "" + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/UserLogin" + required: true + responses: + "401": + description: "Unauthorized" + content: + '*/*': + schema: + type: "object" + "200": + description: "OK" + content: + '*/*': + schema: + $ref: "#/components/schemas/JwtToken" + /refresh-token: + post: + description: "" + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/RefreshToken" + required: true + responses: + "200": + description: "OK" + content: + '*/*': + schema: + $ref: "#/components/schemas/JwtToken" + /.well-known/webfinger: + get: + description: "" + parameters: + - name: "resource" + in: "query" + required: false + schema: + type: "string" + responses: + "200": + description: "OK" + content: + '*/*': + schema: + $ref: "#/components/schemas/WebFinger" + /api/internal/v1/posts: + get: + description: "" + parameters: + - name: "since" + in: "query" + required: false + schema: + type: "string" + - name: "until" + in: "query" + required: false + schema: + type: "string" + - name: "minId" + in: "query" + required: false + schema: + type: "number" + - name: "maxId" + in: "query" + required: false + schema: + type: "number" + - name: "limit" + in: "query" + required: false + schema: + type: "integer" + post: + description: "" + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/Post" + required: true + responses: + "200": + description: "OK" + content: + '*/*': + schema: + type: "object" + /inbox: + get: + description: "" + responses: + "405": + description: "Method Not Allowed" + content: + '*/*': + schema: + type: "object" + post: + description: "" + responses: + "200": + description: "OK" + content: + '*/*': + schema: + type: "string" + "501": + description: "Not Implemented" + content: + '*/*': + schema: + type: "object" + /outbox: + get: + description: "" + responses: + "501": + description: "Not Implemented" + content: + '*/*': + schema: + type: "object" + post: + description: "" + responses: + "501": + description: "Not Implemented" + content: + '*/*': + schema: + type: "object" + /users/{name}: + get: + description: "" + parameters: + - name: "name" + in: "path" + required: true + schema: + type: "string" + responses: + "200": + description: "OK" + content: + text/plain: + schema: + type: "string" + /users/{name}/inbox: + get: + description: "" + parameters: + - name: "name" + in: "path" + required: true + schema: + type: "string" + responses: + "405": + description: "Method Not Allowed" + content: + '*/*': + schema: + type: "object" + post: + description: "" + parameters: + - name: "name" + in: "path" + required: true + schema: + type: "string" + responses: + "200": + description: "OK" + content: + '*/*': + schema: + type: "string" + "501": + description: "Not Implemented" + content: + '*/*': + schema: + type: "object" + /users/{name}/outbox: + get: + description: "" + parameters: + - name: "name" + in: "path" + required: true + schema: + type: "string" + responses: + "501": + description: "Not Implemented" + content: + '*/*': + schema: + type: "object" + post: + description: "" + parameters: + - name: "name" + in: "path" + required: true + schema: + type: "string" + responses: + "501": + description: "Not Implemented" + content: + '*/*': + schema: + type: "object" + /: + get: + description: "" + responses: + "200": + description: "OK" + content: + text/html: + schema: + type: "string" + /register: + get: + description: "" + responses: + "200": + description: "OK" + content: + text/html: + schema: + type: "string" + post: + description: "" + parameters: + - name: "password" + in: "query" + required: false + schema: + type: "string" + - name: "username" + in: "query" + required: false + schema: + type: "string" + responses: + "200": + description: "OK
Redirect" + content: + text/plain: + schema: + type: "string" + examples: + Example#1: + value: "" + Example#2: + value: "/register" + Example#3: + value: "/register" + Example#4: + value: "/register" +components: + schemas: + UserLogin: + type: "object" + properties: + username: + type: "string" + password: + type: "string" + JwtToken: + type: "object" + properties: + token: + type: "string" + refreshToken: + type: "string" + RefreshToken: + type: "object" + properties: + refreshToken: + type: "string" + Link: + type: "object" + properties: + rel: + type: "string" + type: + type: "string" + href: + type: "string" + WebFinger: + type: "object" + properties: + subject: + type: "string" + links: + type: "array" + items: + $ref: "#/components/schemas/Link" + Post: + type: "object" + properties: + text: + type: "string" + overview: + type: "string" + visibility: + type: "string" + enum: + - "PUBLIC" + - "UNLISTED" + - "FOLLOWERS" + - "DIRECT" + repostId: + type: "integer" + format: "int64" + replyId: + type: "integer" + format: "int64" diff --git a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt index 03bf53a4..736ea065 100644 --- a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt @@ -10,18 +10,16 @@ import dev.usbharu.hideout.domain.model.ap.Image import dev.usbharu.hideout.domain.model.ap.Key import dev.usbharu.hideout.domain.model.ap.Person import dev.usbharu.hideout.domain.model.hideout.entity.User -import dev.usbharu.hideout.plugins.configureRouting import dev.usbharu.hideout.plugins.configureSerialization -import dev.usbharu.hideout.service.activitypub.ActivityPubService import dev.usbharu.hideout.service.activitypub.ActivityPubUserService import dev.usbharu.hideout.service.impl.IUserService -import dev.usbharu.hideout.service.signature.HttpSignatureVerifyService import dev.usbharu.hideout.util.HttpUtil.Activity import dev.usbharu.hideout.util.HttpUtil.JsonLd import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* import io.ktor.server.config.* +import io.ktor.server.routing.* import io.ktor.server.testing.* import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString @@ -64,8 +62,6 @@ class UsersAPTest { ) person.context = listOf("https://www.w3.org/ns/activitystreams") - val httpSignatureVerifyService = mock {} - val activityPubService = mock {} val userService = mock {} val activityPubUserService = mock { @@ -74,13 +70,9 @@ class UsersAPTest { application { configureSerialization() - configureRouting( - httpSignatureVerifyService, - activityPubService, - userService, - activityPubUserService, - mock() - ) + routing { + usersAP(activityPubUserService, userService) + } } client.get("/users/test") { accept(ContentType.Application.Activity) @@ -130,8 +122,6 @@ class UsersAPTest { ) person.context = listOf("https://www.w3.org/ns/activitystreams") - val httpSignatureVerifyService = mock {} - val activityPubService = mock {} val userService = mock {} val activityPubUserService = mock { @@ -140,13 +130,9 @@ class UsersAPTest { application { configureSerialization() - configureRouting( - httpSignatureVerifyService, - activityPubService, - userService, - activityPubUserService, - mock() - ) + routing { + usersAP(activityPubUserService, userService) + } } client.get("/users/test") { accept(ContentType.Application.JsonLd) @@ -205,13 +191,9 @@ class UsersAPTest { ) } application { - configureRouting( - mock(), - mock(), - userService, - mock(), - mock() - ) + routing { + usersAP(mock(), userService) + } } client.get("/users/test") { accept(ContentType.Text.Html) diff --git a/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/PostsKtTest.kt b/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/PostsKtTest.kt index de9e768a..a5143505 100644 --- a/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/PostsKtTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/PostsKtTest.kt @@ -78,7 +78,7 @@ class PostsKtTest { } argumentCaptor { verify(postService).create(capture()) - assertEquals(PostCreateDto("test", 1234), firstValue) + assertEquals(PostCreateDto("test", userId = 1234), firstValue) } } } diff --git a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt index 93dfec61..12e54893 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt @@ -115,7 +115,7 @@ class ActivityPubFollowServiceImplTest { createdAt = Instant.now() ) ) - onBlocking { addFollowers(any(), any()) } doReturn Unit + onBlocking { addFollowers(any(), any()) } doReturn false } val activityPubFollowService = ActivityPubFollowServiceImpl(