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

Quick fix to bug with push token request equality operator #117

Merged
merged 2 commits into from
Jan 18, 2024

Conversation

evan-masseau
Copy link
Contributor

@evan-masseau evan-masseau commented Jan 17, 2024

Description

Fixes #116 by removing the lateinit property. Instead, keep body itself as the initial value, and use requestBody to append metadata at send time. This way the equality operator will work (and not crash) the same after decoding from json.

Check List

  • Are you changing anything with the public API? - NO
  • Are your changes backwards compatible with previous SDK Versions? - YES
  • Have you tested this change on real device? - YES
  • Have you added unit test coverage for your changes? - YES
  • Have you verified that your changes are compatible with all Android versions the SDK currently supports? - YES

Changelog / Code Overview

  • remove lateinit property initialBody
  • move metadata insertion to the requestBody method that is invoked only at send time.

Test Plan

  • Added a failing test to repro the initial issue: json decoded PushTokenApiRequest doesn't set initialBody and crashes when equality operator is invoked.
  • Fixed code to pass the repro test conditions, see above

Related Issues/Tickets

#116

kennyklaviyo
kennyklaviyo previously approved these changes Jan 17, 2024
@evan-masseau evan-masseau added the patch-release For issues or code that should be included in a patch release per semantic versioning guidelines label Jan 18, 2024
@evan-masseau evan-masseau marked this pull request as ready for review January 18, 2024 16:17
@evan-masseau evan-masseau requested a review from a team as a code owner January 18, 2024 16:17
// At this time, decoding from JSON does not preserve equality check for push token requests
// But at least it should not crash to compare them
val bRequestDecoded = KlaviyoApiRequestDecoder.fromJson(bRequest.toJson())
assertNotEquals(aRequest, bRequestDecoded)
Copy link
Contributor

Choose a reason for hiding this comment

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

What's different between these?

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 cause of the bug was that we use a different constructor when decoding this class from JSON. So the first is just create 2 objects, test their equality. The second is encode and decode it, and re-test equality

Copy link
Contributor

Choose a reason for hiding this comment

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

So previously this test would have reproduced the crash?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Previously, testing equality failed on a decoded json object because the lateinit var was not initialized. With this patch, equality check should not crash, though expected behavior is that it will not be equal anymore, because the payload body has been mutated

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Exactly, this was my failing-test repro.

…it keeps the idea of having up to date metadata at send time.
}

// Update body to include Device metadata whenever the body is retrieved (typically during sending) so the latest data is included
override val requestBody: String?
Copy link
Contributor Author

Choose a reason for hiding this comment

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

requestBody is invoked at send time to format the body JSON for the network request. but it is not invoked when json encoding. This way, decoding from json will expect the same initial body payload.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nice!

@@ -11,7 +11,7 @@ import com.klaviyo.core.Registry
import com.klaviyo.core.networking.NetworkMonitor

/**
* Exception that is thrown when the the Klaviyo API token is missing from the config
* Exception that is thrown when the Klaviyo API token is missing from the config
Copy link
Contributor Author

Choose a reason for hiding this comment

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

can't help fixing grammar things when i see them

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 linter that helps with 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.

Good Q, grammar problems are highlighted in a shade of red in my IDE color theme, so it always catches my eye.

Copy link
Contributor

Choose a reason for hiding this comment

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

we should find a way to share some IDE configs

override fun equals(other: Any?): Boolean {
return when (other) {
is PushTokenApiRequest -> initialBody == other.initialBody
is PushTokenApiRequest -> body.toString() == other.body.toString()
Copy link
Contributor

@ndurell ndurell Jan 18, 2024

Choose a reason for hiding this comment

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

Sorry if I missed it, what's the reasoning behind using toString() vs comparing body to other.body?

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 didn't actually try that, let me see. My assumption was separate object instances won't appear equal

Copy link
Contributor

Choose a reason for hiding this comment

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

Ahh might compare references?

Copy link
Contributor

@kennyklaviyo kennyklaviyo Jan 18, 2024

Choose a reason for hiding this comment

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

one difficult thing is order:

JSONObject("{'keyA': 'value', 'keyB': 1}").toString() == JSONObject("{'keyB': 1, 'keyA': 'value'}").toString()
// false

Copy link
Contributor

Choose a reason for hiding this comment

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

but yeah, without to string, its a reference check:

JSONObject("{'keyA': 'value'}") == JSONObject("{'keyA': 'value'}")
// false
JSONObject("{'keyA': 'value'}").toString() == JSONObject("{'keyA': 'value'}").toString()
// 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.

Thanks for the check kenny. Yeah I was surprised the order thing didn't cause my test to fail actually. Unless its just coincidentally passing. I had to add a json compare function to the unit tests for that same reason.

@evan-masseau evan-masseau merged commit 8c6298d into master Jan 18, 2024
2 checks passed
@evan-masseau evan-masseau deleted the ecm/pushtoken-bug branch January 18, 2024 18:51
evan-masseau pushed a commit that referenced this pull request Jan 18, 2024
* master:
  Release 1.4.1 (#118)
  Replace lateinit property in PushTokenApiRequest (#117)

# Conflicts:
#	README.md
#	versions.gradle
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
patch-release For issues or code that should be included in a patch release per semantic versioning guidelines
Projects
None yet
Development

Successfully merging this pull request may close these issues.

UninitializedPropertyAccessException on setPushToken
3 participants