From ee62ec56e6a6d4ebdbbe28ca3917e73d2b9f91a7 Mon Sep 17 00:00:00 2001 From: Hadia Date: Tue, 22 Jun 2021 00:20:02 +0200 Subject: [PATCH] =?UTF-8?q?NT-2058:Updates=20=E2=80=93=20Showing=20project?= =?UTF-8?q?=20comments=20instead=20of=20update's=20(#1298)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add get the post using update id query * Add getProjectUpdateComments * call getProjectUpdateComments * Add project id encoded to query * commentableId set to project or post id in comment envolpe to use it to create Post * commentableId set to project or update to post comment * Update test * Fix code comments --- app/src/main/graphql/fragments.graphql | 15 ++++++ app/src/main/graphql/project.graphql | 50 +++++++++++-------- .../mock/factories/CommentFactory.kt | 4 +- .../mock/services/MockApolloClient.kt | 17 +++++++ .../kickstarter/services/ApolloClientType.kt | 2 + .../kickstarter/services/KSApolloClient.kt | 50 ++++++++++++++++++- .../commentresponse/CommentEnvelope.kt | 7 ++- .../services/mutations/PostCommentData.kt | 4 +- .../kickstarter/ui/data/CommentCardData.kt | 7 ++- .../viewmodels/CommentsViewHolderViewModel.kt | 37 +++++++++----- .../viewmodels/CommentsViewModel.kt | 49 +++++++++++++----- .../CommentsViewHolderViewModelTest.kt | 4 ++ .../viewmodels/CommentsViewModelTest.kt | 50 +++++++++++++++++-- 13 files changed, 235 insertions(+), 61 deletions(-) diff --git a/app/src/main/graphql/fragments.graphql b/app/src/main/graphql/fragments.graphql index f1b121f1db..da7c971e0f 100644 --- a/app/src/main/graphql/fragments.graphql +++ b/app/src/main/graphql/fragments.graphql @@ -142,3 +142,18 @@ fragment payment on CreditCard { type state } + +fragment freeformPost on FreeformPost { + comments (first: $limit, after: $cursor) { + edges { + cursor + node { + ...comment + } + } + pageInfo { + ...pageInfo + } + totalCount + } +} \ No newline at end of file diff --git a/app/src/main/graphql/project.graphql b/app/src/main/graphql/project.graphql index f6b658b0c8..4fc302b156 100644 --- a/app/src/main/graphql/project.graphql +++ b/app/src/main/graphql/project.graphql @@ -46,29 +46,35 @@ mutation CreateComment($body: String!, $commentableId: ID!, $parentId: ID, $clie } } -query GetProjectComments($slug: String!, $limit: Int!, $cursor: String){ - project(slug: $slug) { - collaborators { - edges { - node { - id - name - } - } +query GetProjectComments($slug: String!, $limit: Int!, $cursor: String) { + project(slug: $slug) { + id + collaborators { + edges { + node { + id + name } - comments(first: $limit, after: $cursor) { - edges { - cursor - node { - authorBadges - ...comment - } - } - pageInfo { - ...pageInfo - } - totalCount + } + } + comments(first: $limit, after: $cursor) { + edges { + cursor + node { + ...comment } } - } + pageInfo { + ...pageInfo + } + totalCount + } + } +} +query GetProjectUpdateComments($id: ID!,$limit: Int!, $cursor: String){ + post(id: $id) { + id + ...freeformPost + } +} diff --git a/app/src/main/java/com/kickstarter/mock/factories/CommentFactory.kt b/app/src/main/java/com/kickstarter/mock/factories/CommentFactory.kt index a955264513..def0512d95 100644 --- a/app/src/main/java/com/kickstarter/mock/factories/CommentFactory.kt +++ b/app/src/main/java/com/kickstarter/mock/factories/CommentFactory.kt @@ -71,6 +71,7 @@ class CommentFactory { } fun liveCommentCardData(comment: String = "Some Comment", createdAt: DateTime, currentUser: User, isDelete: Boolean = false, repliesCount: Int = 0): CommentCardData { + val project = ProjectFactory.project().toBuilder().creator(UserFactory.creator().toBuilder().id(278438049).build()).build() return CommentCardData( Comment.builder() .body(comment) @@ -84,7 +85,8 @@ class CommentFactory { .author(currentUser) .build(), 0, - ProjectFactory.project().toBuilder().creator(UserFactory.creator().toBuilder().id(278438049).build()).build() + project.id().toString(), + project ) } diff --git a/app/src/main/java/com/kickstarter/mock/services/MockApolloClient.kt b/app/src/main/java/com/kickstarter/mock/services/MockApolloClient.kt index 3a4aec3920..7592e91db4 100644 --- a/app/src/main/java/com/kickstarter/mock/services/MockApolloClient.kt +++ b/app/src/main/java/com/kickstarter/mock/services/MockApolloClient.kt @@ -71,6 +71,23 @@ open class MockApolloClient : ApolloClientType { ) } + override fun getProjectUpdateComments( + updateId: String, + cursor: String?, + limit: Int + ): Observable { + return Observable.just( + CommentEnvelope.builder() + .pageInfoEnvelope( + PageInfoEnvelopeFactory.pageInfoEnvelope() + ) + .comments(listOf(CommentFactory.comment())) + .commentableId(updateId) + .totalCount(1) + .build() + ) + } + override fun getRepliesForComment(comment: Comment, cursor: String, pageSize: Int): Observable { return Observable.just(CommentEnvelopeFactory.emptyCommentsEnvelope()) } diff --git a/app/src/main/java/com/kickstarter/services/ApolloClientType.kt b/app/src/main/java/com/kickstarter/services/ApolloClientType.kt index e9f5239aee..f81d683707 100644 --- a/app/src/main/java/com/kickstarter/services/ApolloClientType.kt +++ b/app/src/main/java/com/kickstarter/services/ApolloClientType.kt @@ -36,6 +36,8 @@ interface ApolloClientType { fun getProjectComments(slug: String, cursor: String?, limit: Int = 25): Observable + fun getProjectUpdateComments(updateId: String, cursor: String?, limit: Int = 25): Observable + fun getRepliesForComment(comment: Comment, cursor: String = "", pageSize: Int = 25): Observable fun createComment(comment: PostCommentData): Observable diff --git a/app/src/main/java/com/kickstarter/services/KSApolloClient.kt b/app/src/main/java/com/kickstarter/services/KSApolloClient.kt index 1c1cc48d82..600067cc8f 100644 --- a/app/src/main/java/com/kickstarter/services/KSApolloClient.kt +++ b/app/src/main/java/com/kickstarter/services/KSApolloClient.kt @@ -218,6 +218,7 @@ class KSApolloClient(val service: ApolloClient) : ApolloClientType { } CommentEnvelope.builder() + .commentableId(project?.id()) .comments(comments) .totalCount(project?.comments()?.totalCount() ?: 0) .pageInfoEnvelope(createPageInfoObject(project?.comments()?.pageInfo()?.fragments()?.pageInfo())) @@ -235,6 +236,53 @@ class KSApolloClient(val service: ApolloClient) : ApolloClientType { }.subscribeOn(Schedulers.io()) } + override fun getProjectUpdateComments(updateId: String, cursor: String?, limit: Int): Observable { + return Observable.defer { + val ps = PublishSubject.create() + + this.service.query( + GetProjectUpdateCommentsQuery.builder() + .cursor(cursor) + .id(updateId) + .limit(limit) + .build() + ) + .enqueue(object : ApolloCall.Callback() { + override fun onFailure(e: ApolloException) { + ps.onError(e) + } + + override fun onResponse(response: Response) { + response.data?.let { data -> + Observable.just(data.post()) + .filter { it?.fragments()?.freeformPost()?.comments() != null } + .map { post -> + + val comments = post?.fragments()?.freeformPost()?.comments()?.edges()?.map { edge -> + createCommentObject(edge?.node()?.fragments()?.comment()).toBuilder() + .cursor(edge?.cursor()) + .build() + } + + CommentEnvelope.builder() + .comments(comments) + .commentableId(post?.id()) + .totalCount(post?.fragments()?.freeformPost()?.comments()?.totalCount() ?: 0) + .pageInfoEnvelope(createPageInfoObject(post?.fragments()?.freeformPost()?.comments()?.pageInfo()?.fragments()?.pageInfo())) + .build() + } + .filter { ObjectUtils.isNotNull(it) } + .subscribe { + ps.onNext(it) + ps.onCompleted() + } + } + } + }) + return@defer ps + }.subscribeOn(Schedulers.io()) + } + override fun getRepliesForComment(comment: Comment, cursor: String, pageSize: Int): Observable { return Observable.defer { val ps = PublishSubject.create() @@ -269,7 +317,7 @@ class KSApolloClient(val service: ApolloClient) : ApolloClientType { this.service.mutate( CreateCommentMutation.builder() .parentId(comment.parentId) - .commentableId(encodeRelayId(comment.project)) + .commentableId(comment.commentableId) .clientMutationId(comment.clientMutationId) .body(comment.body) .build() diff --git a/app/src/main/java/com/kickstarter/services/apiresponses/commentresponse/CommentEnvelope.kt b/app/src/main/java/com/kickstarter/services/apiresponses/commentresponse/CommentEnvelope.kt index 4cb332bda3..5206725bbc 100644 --- a/app/src/main/java/com/kickstarter/services/apiresponses/commentresponse/CommentEnvelope.kt +++ b/app/src/main/java/com/kickstarter/services/apiresponses/commentresponse/CommentEnvelope.kt @@ -9,6 +9,7 @@ import kotlinx.android.parcel.Parcelize @AutoGson class CommentEnvelope( val comments: List?, + val commentableId: String?, val pageInfoEnvelope: PageInfoEnvelope?, val totalCount: Int? ) : Parcelable { @@ -17,19 +18,21 @@ class CommentEnvelope( @AutoGson data class Builder( var comments: List? = null, + var commentableId: String? = null, var pageInfoEnvelope: PageInfoEnvelope? = null, var totalCount: Int? = 0 ) : Parcelable { fun comments(comments: List?) = apply { this.comments = comments } + fun commentableId(commentableId: String?) = apply { this.commentableId = commentableId } fun pageInfoEnvelope(pageInfoEnvelope: PageInfoEnvelope?) = apply { this.pageInfoEnvelope = pageInfoEnvelope } fun totalCount(totalCount: Int?) = apply { this.totalCount = totalCount } - fun build() = CommentEnvelope(comments, pageInfoEnvelope, totalCount) + fun build() = CommentEnvelope(comments, commentableId, pageInfoEnvelope, totalCount) } companion object { fun builder() = Builder() } - fun toBuilder() = Builder(this.comments, this.pageInfoEnvelope, this.totalCount) + fun toBuilder() = Builder(this.comments, this.commentableId, this.pageInfoEnvelope, this.totalCount) } diff --git a/app/src/main/java/com/kickstarter/services/mutations/PostCommentData.kt b/app/src/main/java/com/kickstarter/services/mutations/PostCommentData.kt index 719d612f75..af5ce8c784 100644 --- a/app/src/main/java/com/kickstarter/services/mutations/PostCommentData.kt +++ b/app/src/main/java/com/kickstarter/services/mutations/PostCommentData.kt @@ -1,10 +1,8 @@ package com.kickstarter.services.mutations -import com.kickstarter.models.Project - data class PostCommentData( val body: String, val parentId: String?, - val project: Project, + val commentableId: String, val clientMutationId: String? ) diff --git a/app/src/main/java/com/kickstarter/ui/data/CommentCardData.kt b/app/src/main/java/com/kickstarter/ui/data/CommentCardData.kt index fbeb47559c..26f2d5109f 100644 --- a/app/src/main/java/com/kickstarter/ui/data/CommentCardData.kt +++ b/app/src/main/java/com/kickstarter/ui/data/CommentCardData.kt @@ -9,6 +9,7 @@ import kotlinx.android.parcel.Parcelize class CommentCardData( val comment: Comment?, val commentCardState: Int, + val commentableId: String?, val project: Project? ) : Parcelable { @@ -16,17 +17,19 @@ class CommentCardData( data class Builder( var comment: Comment? = null, var commentCardState: Int = 0, + var commentableId: String? = null, var project: Project? = null ) : Parcelable { fun comment(comment: Comment?) = apply { this.comment = comment } fun commentCardState(commentCardState: Int) = apply { this.commentCardState = commentCardState } fun project(project: Project?) = apply { this.project = project } - fun build() = CommentCardData(comment, commentCardState, project) + fun commentableId(commentableId: String?) = apply { this.commentableId = commentableId } + fun build() = CommentCardData(comment, commentCardState, commentableId, project) } companion object { fun builder() = CommentCardData.Builder() } - fun toBuilder() = CommentCardData.Builder(this.comment, this.commentCardState, this.project) + fun toBuilder() = CommentCardData.Builder(this.comment, this.commentCardState, this.commentableId, this.project) } diff --git a/app/src/main/java/com/kickstarter/viewmodels/CommentsViewHolderViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/CommentsViewHolderViewModel.kt index 0f2e04d463..aa807ac151 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/CommentsViewHolderViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/CommentsViewHolderViewModel.kt @@ -141,8 +141,9 @@ interface CommentsViewHolderViewModel { .withLatestFrom(currentUser.loggedInUser()) { input, user -> Pair(input, user) } .filter { shouldCommentBePosted(it) } .map { - Pair(requireNotNull(it.first.comment?.body()), requireNotNull(it.first.project)) + Pair(requireNotNull(it.first), requireNotNull(it.first.project)) } + postComment(commentData, internalError) this.internalError @@ -247,11 +248,26 @@ interface CommentsViewHolderViewModel { * Handles the logic for posting comments (new ones, and the retry attempts) * @param commentData will emmit only in case we need to post a new comment */ - private fun postComment(commentData: Observable>, errorObservable: BehaviorSubject) { - commentData + private fun postComment(commentData: Observable>, errorObservable: BehaviorSubject) { + val postCommentData = commentData .map { - executePostCommentMutation(it, errorObservable) + Pair( + requireNotNull(it.first.commentableId), + requireNotNull(it.first?.comment?.body()) + ) } + .map { + PostCommentData( + commentableId = it.first, + body = it.second, + clientMutationId = null, + parentId = null + ) + } + + postCommentData.map { + executePostCommentMutation(it, errorObservable) + } .switchMap { it } @@ -262,7 +278,7 @@ interface CommentsViewHolderViewModel { } Observable - .combineLatest(onRetryViewClicked, commentData) { _, newData -> + .combineLatest(onRetryViewClicked, postCommentData) { _, newData -> return@combineLatest executePostCommentMutation(newData, errorObservable) }.switchMap { it @@ -300,19 +316,14 @@ interface CommentsViewHolderViewModel { /** * Function that will execute the PostCommentMutation - * @param commentData holds the comment body and the project to be posted + * @param postCommentData holds the comment body and the commentableId for project or update to be posted * // TODO: for the future threads wi will need to send to the mutation not just the body, * // TODO: we will need the entire comment plus very important the [parentId] * @return Observable */ - private fun executePostCommentMutation(commentData: Pair, errorObservable: BehaviorSubject) = + private fun executePostCommentMutation(postCommentData: PostCommentData, errorObservable: BehaviorSubject) = this.apolloClient.createComment( - PostCommentData( - project = commentData.second, - body = commentData.first, - clientMutationId = null, - parentId = null - ) + postCommentData ).doOnError { errorObservable.onNext(it) } diff --git a/app/src/main/java/com/kickstarter/viewmodels/CommentsViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/CommentsViewModel.kt index e8891bc021..4ce1fc1b10 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/CommentsViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/CommentsViewModel.kt @@ -103,6 +103,7 @@ interface CommentsViewModel { private val isFetchingData = BehaviorSubject.create() private var lastCommentCursor: String? = null + private var commentableId: String? = null override var loadMoreListData = mutableListOf() companion object { @@ -148,7 +149,9 @@ interface CommentsViewModel { { value: Project? -> Observable.just(value) }, { u: Update? -> client.fetchProject(u?.projectId().toString()).compose(Transformers.neverError()) } ) - }.map { requireNotNull(it) } + }.map { + requireNotNull(it) + } .share() initialProject @@ -160,7 +163,14 @@ interface CommentsViewModel { commentComposerStatus.onNext(composerStatus) } - loadCommentList(initialProject) + val projectOrUpdateComment = projectOrUpdate.map { + it as? Either + }.compose(combineLatestPair(initialProject)) + .map { + Pair(it.second, it.first?.right()) + } + + loadCommentListFromProjectOrUpdate(projectOrUpdateComment) this.insertNewCommentToList .distinctUntilChanged() @@ -181,6 +191,7 @@ interface CommentsViewModel { CommentCardData.builder() .comment(it.first.second) .project(it.second) + .commentableId(commentableId) .commentCardState(CommentCardStatus.TRYING_TO_POST.commentCardStatus) .build() ) @@ -298,18 +309,18 @@ interface CommentsViewModel { return this.loadMoreListData } - private fun loadCommentList(initialProject: Observable) { + private fun loadCommentListFromProjectOrUpdate(projectOrUpdate: Observable>) { // - First load for comments & handle initial load errors - getProjectComments(initialProject, INITIAL_LOAD) + getProjectOrUpdateComments(projectOrUpdate, INITIAL_LOAD) .compose(bindToLifecycle()) .subscribe { bindCommentList(it.first, LoadingType.NORMAL) } // - Load comments from pagination & Handle pagination errors - initialProject + projectOrUpdate .compose(Transformers.takeWhen(this.nextPage)) - .switchMap { getProjectComments(Observable.just(it), PAGE_LOAD) } + .switchMap { getProjectOrUpdateComments(Observable.just(it), PAGE_LOAD) } .compose(bindToLifecycle()) .subscribe { updatePaginatedData( @@ -321,7 +332,7 @@ interface CommentsViewModel { // - Handle pull to refresh and it's errors // - Pull to refresh cleans the entire list and makes a new request this.refresh - .compose(combineLatestPair(initialProject)) + .compose(combineLatestPair(projectOrUpdate)) .map { it.second } .doOnNext { this.isRefreshing.onNext(true) @@ -329,17 +340,24 @@ interface CommentsViewModel { lastCommentCursor = null this.loadMoreListData.clear() } - .switchMap { getProjectComments(Observable.just(it), PULL_LOAD) } + .switchMap { getProjectOrUpdateComments(Observable.just(it), PULL_LOAD) } .compose(bindToLifecycle()) .subscribe { bindCommentList(it.first, LoadingType.PULL_REFRESH) } } - private fun getProjectComments(project: Observable, state: Int): Observable, Int>> { + private fun getProjectOrUpdateComments( + projectOrUpdate: Observable>, + state: Int + ): Observable, Int>> { isFetchingData.onNext(state) - return project.switchMap { - return@switchMap apolloClient.getProjectComments(it.slug() ?: "", lastCommentCursor) + return projectOrUpdate.switchMap { + return@switchMap if (it.second?.id() != null) { + apolloClient.getProjectUpdateComments(it.second?.id().toString(), lastCommentCursor) + } else { + apolloClient.getProjectComments(it.first?.slug() ?: "", lastCommentCursor) + } }.doOnSubscribe { this.isLoadingMoreItems.onNext(true) }.doOnError { @@ -348,13 +366,18 @@ interface CommentsViewModel { } .onErrorResumeNext(Observable.empty()) .filter { ObjectUtils.isNotNull(it) } - .compose>(combineLatestPair(project)) + .compose>(combineLatestPair(projectOrUpdate.map { it.first })) + .doOnNext { commentableId = it.first.commentableId } // its either Project id or update post id .map { Pair(requireNotNull(mapToCommentCardDataList(it)), it.first.totalCount) } } private fun mapToCommentCardDataList(it: Pair) = it.first.comments?.map { comment: Comment -> - CommentCardData.builder().comment(comment).project(it.second).build() + CommentCardData.builder() + .comment(comment) + .project(it.second) + .commentableId(it.first.commentableId) + .build() } private fun buildCommentBody(it: Pair>): Comment { diff --git a/app/src/test/java/com/kickstarter/viewmodels/CommentsViewHolderViewModelTest.kt b/app/src/test/java/com/kickstarter/viewmodels/CommentsViewHolderViewModelTest.kt index 295e5a4cd5..5a23d3f0e8 100644 --- a/app/src/test/java/com/kickstarter/viewmodels/CommentsViewHolderViewModelTest.kt +++ b/app/src/test/java/com/kickstarter/viewmodels/CommentsViewHolderViewModelTest.kt @@ -316,10 +316,12 @@ class CommentsViewHolderViewModelTest : KSRobolectricTestCase() { val commentCardData = CommentCardData.builder() .comment(comment) .project(ProjectFactory.initialProject()) + .commentableId(ProjectFactory.initialProject().id().toString()) .commentCardState(CommentCardStatus.TRYING_TO_POST.commentCardStatus) .build() this.vm.inputs.configureWith(commentCardData) + testScheduler.advanceTimeBy(2, TimeUnit.SECONDS) this.vm.inputs.onRetryViewClicked() @@ -401,6 +403,7 @@ class CommentsViewHolderViewModelTest : KSRobolectricTestCase() { val commentCardData = CommentCardData.builder() .comment(comment) .project(ProjectFactory.initialProject()) + .commentableId(ProjectFactory.initialProject().id().toString()) .commentCardState(CommentCardStatus.TRYING_TO_POST.commentCardStatus) .build() @@ -461,6 +464,7 @@ class CommentsViewHolderViewModelTest : KSRobolectricTestCase() { val commentCardData = CommentCardData.builder() .comment(comment) .project(ProjectFactory.initialProject()) + .commentableId(ProjectFactory.initialProject().id().toString()) .commentCardState(CommentCardStatus.TRYING_TO_POST.commentCardStatus) .build() diff --git a/app/src/test/java/com/kickstarter/viewmodels/CommentsViewModelTest.kt b/app/src/test/java/com/kickstarter/viewmodels/CommentsViewModelTest.kt index bea7493091..d820cfa949 100644 --- a/app/src/test/java/com/kickstarter/viewmodels/CommentsViewModelTest.kt +++ b/app/src/test/java/com/kickstarter/viewmodels/CommentsViewModelTest.kt @@ -25,6 +25,7 @@ import rx.Observable import rx.observers.TestSubscriber import rx.schedulers.TestScheduler import rx.subjects.BehaviorSubject +import java.lang.Exception import java.util.concurrent.TimeUnit class CommentsViewModelTest : KSRobolectricTestCase() { @@ -163,6 +164,13 @@ class CommentsViewModelTest : KSRobolectricTestCase() { @Test fun testCommentsViewModel_EmptyState() { val env = environment().toBuilder().apolloClient(object : MockApolloClient() { + override fun getProjectUpdateComments( + updateId: String, + cursor: String?, + limit: Int + ): Observable { + return Observable.empty() + } override fun getProjectComments(slug: String, cursor: String?, limit: Int): Observable { return Observable.empty() } @@ -174,13 +182,25 @@ class CommentsViewModelTest : KSRobolectricTestCase() { // Start the view model with an update. vm.intent(Intent().putExtra(IntentKey.UPDATE, UpdateFactory.update())) commentsList.assertNoValues() + + // Start the view model with a project. + vm.intent(Intent().putExtra(IntentKey.PROJECT, ProjectFactory.project())) + commentsList.assertNoValues() } @Test fun testCommentsViewModel_InitialLoad_Error() { val env = environment().toBuilder().apolloClient(object : MockApolloClient() { + override fun getProjectUpdateComments( + updateId: String, + cursor: String?, + limit: Int + ): Observable { + return Observable.error(Exception()) + } + override fun getProjectComments(slug: String, cursor: String?, limit: Int): Observable { - return Observable.empty() + return Observable.error(Exception()) } }).build() val vm = CommentsViewModel.ViewModel(env) @@ -190,6 +210,10 @@ class CommentsViewModelTest : KSRobolectricTestCase() { // Start the view model with an update. vm.intent(Intent().putExtra(IntentKey.UPDATE, UpdateFactory.update())) commentsList.assertNoValues() + + // Start the view model with a project. + vm.intent(Intent().putExtra(IntentKey.PROJECT, ProjectFactory.project())) + commentsList.assertNoValues() } @Test @@ -207,12 +231,26 @@ class CommentsViewModelTest : KSRobolectricTestCase() { } /* - * test when no comment available - */ + * test when no comment available + */ + @Test fun testCommentsViewModel_EmptyCommentState() { val env = environment().toBuilder().apolloClient(object : MockApolloClient() { - override fun getProjectComments(slug: String, cursor: String?, limit: Int): Observable { + + override fun getProjectComments( + slug: String, + cursor: String?, + limit: Int + ): Observable { + return Observable.just(CommentEnvelopeFactory.emptyCommentsEnvelope()) + } + + override fun getProjectUpdateComments( + updateId: String, + cursor: String?, + limit: Int + ): Observable { return Observable.just(CommentEnvelopeFactory.emptyCommentsEnvelope()) } }).build() @@ -222,6 +260,10 @@ class CommentsViewModelTest : KSRobolectricTestCase() { // Start the view model with an update. vm.intent(Intent().putExtra(IntentKey.UPDATE, UpdateFactory.update())) showEmptyState.assertValue(true) + + // Start the view model with a project. + vm.intent(Intent().putExtra(IntentKey.PROJECT, ProjectFactory.project())) + showEmptyState.assertValue(true) } /*