Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(tests): improve reactions tests using go mock #1091

Merged
merged 12 commits into from
Mar 22, 2023

Conversation

dadamu
Copy link
Contributor

@dadamu dadamu commented Mar 10, 2023

Description

Closes: #XXXX
This PR improves the x/reactions tests using gomock.


Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • included the correct type prefix in the PR title
  • added ! to the type prefix if API or client breaking change
  • targeted the correct branch (see PR Targeting)
  • provided a link to the relevant issue or specification
  • followed the guidelines for building modules
  • included the necessary unit and integration tests
  • added a changelog entry to CHANGELOG.md
  • included comments for documenting Go code
  • updated the relevant documentation or specification
  • reviewed "Files changed" and left comments if necessary
  • confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed ! in the type prefix if API or client breaking change
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic
  • reviewed API design and naming
  • reviewed documentation is accurate
  • reviewed tests and test coverage
  • manually tested (if applicable)

@dadamu dadamu requested a review from a team as a code owner March 10, 2023 13:40
@codecov
Copy link

codecov bot commented Mar 10, 2023

Codecov Report

Patch coverage: 91.66% and project coverage change: +0.10 🎉

Comparison is base (ed8b761) 80.76% compared to head (221b247) 80.86%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1091      +/-   ##
==========================================
+ Coverage   80.76%   80.86%   +0.10%     
==========================================
  Files         185      186       +1     
  Lines       16618    16659      +41     
==========================================
+ Hits        13421    13472      +51     
+ Misses       2610     2604       -6     
+ Partials      587      583       -4     
Impacted Files Coverage Δ
x/reactions/types/models.go 77.48% <ø> (ø)
x/posts/keeper/polls.go 97.70% <90.00%> (-2.30%) ⬇️
x/reactions/legacy/v3/store.go 91.42% <91.42%> (ø)
x/posts/abci.go 100.00% <100.00%> (+6.25%) ⬆️
x/posts/keeper/attachments.go 100.00% <100.00%> (ø)
x/reactions/keeper/alias_functions.go 77.16% <100.00%> (+3.93%) ⬆️
x/subspaces/types/permissions.go 77.77% <100.00%> (ø)

... and 7 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

Comment on lines 146 to 148
if !isTally {
k.AfterPollAnswerDeleted(ctx, subspaceID, postID, pollID, user)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AfterPollAnswerDeleted should not be called if the deletion is from tally operation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this decided? I believe we can call it safely in every occasion: if we are removing a user answer from the store, we should notify it anyway. It will be the listener's job to decide whether to handle it or not. And since the tally emits a custom event, it should be easy enough to distinguish the two cases if the listener wants

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dadamu I only have this comment left. Once this is solved, we can merge this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my side, we can avoid from calling redundant AfterPollAnswerDeleted hooks since AfterPollVotingPeriodEnded handles the everything.

For example, when calling AfterPollAnswerDeleted, the listener can remove a user answer, like DELETE FROM user_answer WHERE user_address = "cosmos....". In the other hand, AfterPollVotingPeriodEnded can remove all the answers with DELETE FROM user_answer WHERE poll_id = 1.

Additionally, it is better performance if the listener module wants to handle the tallied poll only and no executions with answers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The listener module handling the tallied poll only and no execution with answers in the current way will be like:

func (h Hooks) AfterPollAnswerDeleted(sdk.Context, subspaceID uint64, postID uint64, pollID uint32, user string) {
    if !IsTalliedPoll(ctx, subspaceID, postID, pollID) {
        handleAnswer(ctx, subspaceID, postID, pollID)
    }
}

We need to check the poll is tallied or not in every answer deleted action, which costs O(N) redundantly where N = the amount of answers in the poll.

Copy link
Contributor

@RiccardoM RiccardoM Mar 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, it makes sense. Then I would ask you if we could change one thing: instead of passing isTally to this function, which is only used to emit the event to the listener, can we instead move the call of k.AfterPollAnswerDeleted(ctx, subspaceID, postID, pollID, user) inside the Tally function direclty? This way we don't have to edit the signature of DeleteUserAnswer and we can keep it as it was before.

So, we remove this code from DeleteUserAnswer:

if !isTally {
     k.AfterPollAnswerDeleted(ctx, subspaceID, postID, pollID, user)
}

And we edit the Tally function to have the following lines inside the IteratePollUserAnswers:

k.DeleteUserAnswer(ctx, answer.SubspaceID, answer.PostID, answer.PollID, answer.User, true)
k.AfterPollAnswerDeleted(ctx, answer.SubspaceID, answer.PostID, answer.PollID, answer.User)

Copy link
Contributor Author

@dadamu dadamu Mar 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RiccardoM Tally function should not call AfterPollAnswerDeleted from my side. The main thing is to avoid passing isTally to DeleteUserAnswer, right?
If so, I think the best way is to have a new function deleteUserAnswer only deletes user answer inside database.

Copy link
Contributor

@RiccardoM RiccardoM Mar 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dadamu I'm honestly not convinced of this change to remove the call of AfterPollAnswerDeleted from DeleteUserAnswer. I think it's not logically correct: we are removing a user answer, so why not emit the event? Also, I think this is out of scope for this PR. I would like to ask you to revert this change and open another PR where we can have a discussion about this change without blocking this PR (that should only be related to tests and not breaking changes - like this one)

Copy link
Contributor Author

@dadamu dadamu Mar 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with you, will open another PR. Reverted.

@dadamu dadamu force-pushed the paul/improve-reactions-tests branch from 10d1b96 to 523c1cd Compare March 10, 2023 14:01
Comment on lines +66 to +85
// EndPoll tallies the poll then update it inside storage
func (k Keeper) EndPoll(ctx sdk.Context, poll types.Attachment) {
// Compute the poll results
results := k.Tally(ctx, poll.SubspaceID, poll.PostID, poll.ID)

// Update the content with the results
content := poll.Content.GetCachedValue().(*types.Poll)
content.FinalTallyResults = results

contentAny, err := codectypes.NewAnyWithValue(content)
if err != nil {
panic(err)
}
poll.Content = contentAny

k.SaveAttachment(ctx, poll)
k.RemoveFromActivePollQueue(ctx, poll)

k.AfterPollVotingPeriodEnded(ctx, poll.SubspaceID, poll.PostID, poll.ID)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To allow to test AfterPollVotingPeriodEnded inside the keeper, it is moved here from abci.

Comment on lines 346 to 347
suite.Require().True(hooks.CalledMap["AfterPollVotingPeriodEnded"])
suite.Require().False(hooks.CalledMap["AfterPollAnswerDeleted"])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AfterPollVotingPeriodEnded should not call AfterPollAnswerDeleted.

}
}

k.AfterAttachmentDeleted(ctx, subspaceID, postID, attachmentID)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added since it was missed.

Comment on lines -59 to +47
sk := subspaceskeeper.NewKeeper(cdc, keys[subspacestypes.StoreKey], nil, nil)
rk := relationshipskeeper.NewKeeper(cdc, keys[relationshipstypes.StoreKey], sk)
authKeeper := authkeeper.NewAccountKeeper(cdc, keys[authtypes.StoreKey], pk.Subspace(authtypes.ModuleName), authtypes.ProtoBaseAccount, app.GetMaccPerms())
profilesKeeper := profileskeeper.NewKeeper(cdc, legacyAmino, keys[profilestypes.StoreKey], pk.Subspace(profilestypes.DefaultParamsSpace), authKeeper, rk, nil, nil, nil)
keeper := postskeeper.NewKeeper(cdc, keys[poststypes.StoreKey], pk.Subspace(types.DefaultParamsSpace), profilesKeeper, sk, rk)

keeper := postskeeper.NewKeeper(cdc, keys[poststypes.StoreKey], pk.Subspace(types.DefaultParamsSpace), nil, nil, nil)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed since abci test does not depend on these module.

@dadamu dadamu force-pushed the paul/improve-reactions-tests branch from 9752f01 to a08d195 Compare March 10, 2023 16:07
@@ -172,7 +172,7 @@ func (k Keeper) IteratePostReactions(ctx sdk.Context, subspaceID uint64, postID
func (k Keeper) HasReacted(ctx sdk.Context, subspaceID uint64, postID uint64, user string, value types.ReactionValue) bool {
found := false
k.IteratePostReactions(ctx, subspaceID, postID, func(reaction types.Reaction) (stop bool) {
if reaction.Author == user && reaction.Value.GetCachedValue().(types.ReactionValue) == value {
if reaction.Author == user && reaction.Value.GetCachedValue().(types.ReactionValue).Equal(value) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using "==" always returns false here since types.ReactionValue is a interface

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this fix mean we might have double reactions stored on chain? Should be create a migration to make sure those are deleted if that's the case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is, added the migration scripts and its test.

@@ -116,7 +116,24 @@ func (suite *KeeperTestSuite) TestKeeper_HasReacted() {
postID: 1,
user: "cosmos1efa8l9h4p6hmkps6vk8lu7nxydr46npr8qtg5f",
value: types.NewRegisteredReactionValue(1),
expResult: false,
expResult: true,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix to true

@dadamu dadamu force-pushed the paul/improve-reactions-tests branch from 6809244 to bd05a7c Compare March 13, 2023 11:17
@dadamu dadamu requested a review from RiccardoM March 13, 2023 11:17
Copy link

@manu0466 manu0466 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@RiccardoM
Copy link
Contributor

@dadamu Would you mind fixing the conflicts that are now present please?

@RiccardoM RiccardoM added the automerge Automatically merge PR once all prerequisites pass label Mar 13, 2023
@dadamu
Copy link
Contributor Author

dadamu commented Mar 14, 2023

@RiccardoM Fixed

Comment on lines 28 to 32
reactions = append(reactions, reaction)

if containsDuplicatedReaction(reactions, reaction) {
duplicatedReactions = append(duplicatedReactions, reaction)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this can be done in another way that might make the code more readable:

if contains(reactions, reaction) {
  duplicatedReactions = append(duplicatedReactions, reaction)
}

reactions = append(reactions, reacion)

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with it, improved

@dadamu dadamu requested a review from RiccardoM March 15, 2023 09:02
@dadamu dadamu force-pushed the paul/improve-reactions-tests branch from c757146 to 221b247 Compare March 22, 2023 15:11
@mergify mergify bot merged commit 1b17122 into master Mar 22, 2023
@mergify mergify bot deleted the paul/improve-reactions-tests branch March 22, 2023 16:21
dadamu added a commit that referenced this pull request Mar 30, 2023
Closes: #XXXX
This PR improves the x/reactions tests using gomock.

---

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://docs.cosmos.network/v0.44/building-modules/intro.html)
- [ ] included the necessary unit and integration [tests](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge Automatically merge PR once all prerequisites pass
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants