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

Fixes ended poll voting #5473

Merged
merged 20 commits into from
Mar 24, 2022
Merged

Fixes ended poll voting #5473

merged 20 commits into from
Mar 24, 2022

Conversation

ericdecanini
Copy link
Contributor

@ericdecanini ericdecanini commented Mar 9, 2022

Type of change

  • Feature
  • Bugfix
  • Technical
  • Other :

Content

Fixes polls being votable after being ended

Motivation and context

Closes #5040

The cause of the issue is found in EventRelationsAggregationProcessor:388.

When voting, the SDK checks that the eventTimestamp is before the closed time and if it is, the vote response can go through, despite the poll having already been ended (determined by the non-null presence of a closed time).

The fix on the SDK was to simply remove that extra condition. I checked that this shouldn't have any side-effects. I tried to approach this differently, i.e. trying to fix the event timestamp (event.originServerTs) set during the poll ending so that it matches the poll closed time but to no avail.

Though I should be able to investigate this with a bit more time if that's the preferrable course of action

I also added an extra layer of protection on the client side to check that the poll is in an ended state.

Screenshots / GIFs

Tests

  • Set your device system time to 1 hour ahead of current time
  • In any timeline, create a new poll
  • Immediately end it
  • Try to vote on it and see that it cannot be voted

Tested devices

  • Physical
  • Emulator
  • OS version(s): Android 10

Checklist

@github-actions
Copy link

github-actions bot commented Mar 9, 2022

Unit Test Results

106 files  ±0  106 suites  ±0   1m 20s ⏱️ +6s
188 tests ±0  188 ✔️ ±0  0 💤 ±0  0 ±0 
622 runs  ±0  622 ✔️ ±0  0 💤 ±0  0 ±0 

Results for commit edfe81c. ± Comparison against base commit 84b34f7.

♻️ This comment has been updated with latest results.

@ericdecanini ericdecanini marked this pull request as ready for review March 10, 2022 20:27
@@ -385,7 +385,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
}

val closedTime = existingPollSummary?.closedTime
if (closedTime != null && eventTimestamp > closedTime) {
if (closedTime != null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

is there a case where the poll could have a closed timestamp but still be valid to casting votes? cc @onurays

Copy link
Contributor

@onurays onurays Mar 15, 2022

Choose a reason for hiding this comment

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

I think we should keep timestamp condition. Even if we prevent it previously, there is always a chance to trigger a poll response to an ended poll from another client or via rest api.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll investigate alternative solutions to this before merging

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reverted this change and pushed alternative solution. See below comment for details

Copy link
Member

@bmarty bmarty left a comment

Choose a reason for hiding this comment

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

}
}

private fun isPollActive(optionViewState: PollOptionViewState) = optionViewState !is PollOptionViewState.PollEnded
Copy link
Member

Choose a reason for hiding this comment

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

There is too much logic here. Better to move that to the controller.
Maybe replace var pollSent: Boolean = false which is unused by something like var canVote: Boolean = false

…-ended-poll

# Conflicts:
#	vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt
@ericdecanini
Copy link
Contributor Author

Update: refactored MessageItemFactory's buildPollItem method and a few other poll-related classes

…-ended-poll

# Conflicts:
#	vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
#	vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt
#	vector/src/main/java/im/vector/app/features/poll/create/CreatePollViewState.kt

package im.vector.app.features.poll

sealed class PollState {
Copy link
Contributor

Choose a reason for hiding this comment

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

tiny nit pick, if we're not using private base properties/functions in the base sealed class we can use sealed interface instead (which is more flexible and helps avoid duplicated properties!)

sealed interfaces are awesome, I struggle to find cases where a sealed classes would be better 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This has never crossed my mind, but I totally agree! Changes pushed

Copy link
Contributor

@ouchadam ouchadam left a comment

Choose a reason for hiding this comment

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

thanks for all the cleaning up 💯

would be good to double check with @onurays for the original timestamp condition in case there's a scenario we aren't aware of

is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, highlight, callback, attributes)
is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, highlight, callback, attributes)
is MessageFileContent -> buildFileMessageItem(messageContent, highlight, attributes)
is MessageAudioContent -> {
Copy link
Contributor

Choose a reason for hiding this comment

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

The arrows of when conditions should be at the same column. Could you please check your formatter? (We had this problem on a previous Android Studio).

Copy link
Contributor

Choose a reason for hiding this comment

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

@bmarty we need to discuss / revert this later.

Copy link
Contributor

@onurays onurays left a comment

Choose a reason for hiding this comment

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

Thanks. Statically reviewed, LGTM.

}

if (existingPollSummary.closedTime != null) {
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 source of the bug is here. A local echo being processed before the remote echo meant that the remote echo never reaches past this point. closedTime thus never gets set from the remote and always turns out to be the current time millis of the local device that ended the poll. If the device has time that's out of sync with unix current time, this bug can occur

cc @onurays

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, thanks for the clarification.

…-ended-poll

# Conflicts:
#	vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt
…-ended-poll

# Conflicts:
#	vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt
@ericdecanini ericdecanini merged commit 1097436 into develop Mar 24, 2022
@ericdecanini ericdecanini deleted the bugfix/eric/voting-ended-poll branch March 24, 2022 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Voting an ended poll sends a org.matrix.msc3381.poll.response event
4 participants