diff --git a/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabMemberDTO.kt b/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabMemberDTO.kt index 2ae5332e3dd5..aee036963746 100644 --- a/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabMemberDTO.kt +++ b/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabMemberDTO.kt @@ -1,30 +1,49 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.plugins.gitlab.api.dto +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.deser.std.StdDeserializer import com.intellij.collaboration.api.dto.GraphQLFragment import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.diagnostic.logger import org.jetbrains.plugins.gitlab.api.data.GitLabAccessLevel + +@JsonDeserialize(using = GitLabMemberDTODeserializer::class) @GraphQLFragment("graphql/fragment/member.graphql") class GitLabMemberDTO( val id: String, val user: GitLabUserDTO, - accessLevel: AccessLevel -) { - val accessLevel: GitLabAccessLevel = parseAccessLevel(accessLevel.stringValue) + val accessLevel: GitLabAccessLevel +) - class AccessLevel(val stringValue: String) +class GitLabMemberDTODeserializer : StdDeserializer(GitLabMemberDTO::class.java) { + override fun deserialize(jsonParser: JsonParser, context: DeserializationContext): GitLabMemberDTO? { + val codec = jsonParser.codec + val node: JsonNode = codec.readTree(jsonParser) - companion object { - private val logger: Logger = logger() - - private fun parseAccessLevel(accessLevel: String) = try { - GitLabAccessLevel.valueOf(accessLevel) - } - catch (_: IllegalArgumentException) { - logger.error("Unable to parse access level") - GitLabAccessLevel.NO_ACCESS + return if (node.isEmpty) null + else { + //codec.treeToValue(node, GitLabMemberDTO::class.java) leads to SOE + val id: String = node["id"].asText() + val user: GitLabUserDTO = codec.treeToValue(node["user"], GitLabUserDTO::class.java) + val accessLevel = node["accessLevel"]["stringValue"].asText().let(::parseAccessLevel) + GitLabMemberDTO(id, user, accessLevel) } } + + private fun parseAccessLevel(accessLevel: String) = try { + GitLabAccessLevel.valueOf(accessLevel) + } + catch (_: IllegalArgumentException) { + LOG.error("Unable to parse access level") + GitLabAccessLevel.NO_ACCESS + } + + companion object { + private val LOG: Logger = logger() + } } \ No newline at end of file diff --git a/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/request/GitLabProjectApi.kt b/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/request/GitLabProjectApi.kt index 710b10fbf4f7..03eef00dc82f 100644 --- a/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/request/GitLabProjectApi.kt +++ b/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/request/GitLabProjectApi.kt @@ -29,10 +29,10 @@ suspend fun GitLabApi.getAllProjectMembers(project: GitLabProjectCoordinates): L ) val request = gqlQuery(project.serverPath.gqlApiUri, GitLabGQLQueries.getProjectMembers, parameters) loadGQLResponse(request, ProjectMembersConnection::class.java, "project", "projectMembers").body() - }.map { it.nodes }.foldToList() + }.map { it.nodes }.foldToList().filterNotNull() private class LabelConnection(pageInfo: GraphQLCursorPageInfoDTO, nodes: List) : GraphQLConnectionDTO(pageInfo, nodes) -private class ProjectMembersConnection(pageInfo: GraphQLCursorPageInfoDTO, nodes: List) - : GraphQLConnectionDTO(pageInfo, nodes) \ No newline at end of file +private class ProjectMembersConnection(pageInfo: GraphQLCursorPageInfoDTO, nodes: List) + : GraphQLConnectionDTO(pageInfo, nodes) \ No newline at end of file diff --git a/plugins/gitlab/test/org/jetbrains/plugins/gitlab/mergerequest/ui/list/GitLabMergeRequestsFiltersViewModelImplTest.kt b/plugins/gitlab/test/org/jetbrains/plugins/gitlab/mergerequest/ui/list/GitLabMergeRequestsFiltersViewModelImplTest.kt index 54a0442eae43..a11ba9a1fc45 100644 --- a/plugins/gitlab/test/org/jetbrains/plugins/gitlab/mergerequest/ui/list/GitLabMergeRequestsFiltersViewModelImplTest.kt +++ b/plugins/gitlab/test/org/jetbrains/plugins/gitlab/mergerequest/ui/list/GitLabMergeRequestsFiltersViewModelImplTest.kt @@ -7,7 +7,6 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.test.runTest import org.jetbrains.plugins.gitlab.api.data.GitLabAccessLevel import org.jetbrains.plugins.gitlab.api.dto.GitLabMemberDTO -import org.jetbrains.plugins.gitlab.api.dto.GitLabMemberDTO.AccessLevel import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO import org.jetbrains.plugins.gitlab.mergerequest.data.loaders.GitLabMergeRequestsListLoader import org.jetbrains.plugins.gitlab.mergerequest.ui.filters.GitLabMergeRequestsFiltersValue @@ -115,7 +114,7 @@ internal class GitLabMergeRequestsFiltersViewModelImplTest { loaderSupplier = loaderSupplierMock) val user = GitLabUserDTO(id = "", username = "", name = "", avatarUrl = "", webUrl = "") - val member = GitLabMemberDTO(id = "", user = user, accessLevel = AccessLevel(GitLabAccessLevel.GUEST.name)) + val member = GitLabMemberDTO(id = "", user = user, accessLevel = GitLabAccessLevel.GUEST) verifyFilterParticipantSelect(filterVm, loaderSupplierMock, GitLabMergeRequestsFiltersValue( state = MergeRequestStateFilterValue.OPENED, author = MergeRequestsAuthorFilterValue(member.user.username, member.user.name) @@ -184,11 +183,11 @@ internal class GitLabMergeRequestsFiltersViewModelImplTest { fun `available participants for merge request filters`() = runTest { val cs = childScope() - val guest = GitLabMemberDTO(id = "guest", mock(), accessLevel = AccessLevel(GitLabAccessLevel.GUEST.name)) - val reporter = GitLabMemberDTO(id = "reporter", mock(), accessLevel = AccessLevel(GitLabAccessLevel.REPORTER.name)) - val developer = GitLabMemberDTO(id = "developer", mock(), accessLevel = AccessLevel(GitLabAccessLevel.DEVELOPER.name)) - val maintainer = GitLabMemberDTO(id = "maintainer", mock(), accessLevel = AccessLevel(GitLabAccessLevel.MAINTAINER.name)) - val owner = GitLabMemberDTO(id = "owner", mock(), accessLevel = AccessLevel(GitLabAccessLevel.OWNER.name)) + val guest = GitLabMemberDTO(id = "guest", mock(), accessLevel = GitLabAccessLevel.GUEST) + val reporter = GitLabMemberDTO(id = "reporter", mock(), accessLevel = GitLabAccessLevel.REPORTER) + val developer = GitLabMemberDTO(id = "developer", mock(), accessLevel = GitLabAccessLevel.DEVELOPER) + val maintainer = GitLabMemberDTO(id = "maintainer", mock(), accessLevel = GitLabAccessLevel.MAINTAINER) + val owner = GitLabMemberDTO(id = "owner", mock(), accessLevel = GitLabAccessLevel.OWNER) val members = listOf(guest, reporter, developer, maintainer, owner) val filterVm = GitLabMergeRequestsFiltersViewModelImpl(scope = cs, historyModel = mock(), currentUser = mockedUser,