Repository: wordpress-mobile/WordPress-Android (language: kotlin)

Issue:
NullPointerException: Attempt to invoke virtual method 'long java.util.Date.getTime()' on a null object reference
Sentry Issue: [JETPACK-ANDROID-7TE](https://a8c.sentry.io/issues/4259423167/?referrer=github_integration)

```
NullPointerException: Attempt to invoke virtual method 'long java.util.Date.getTime()' on a null object reference
    at java.util.Calendar.setTime(Calendar.java:1749)
    at org.wordpress.android.ui.posts.PublishSettingsViewModel.getCurrentPublishDateAsCalendar(PublishSettingsViewModel.kt:208)
    at org.wordpress.android.ui.posts.PublishSettingsViewModel.start(PublishSettingsViewModel.kt:70)
    at org.wordpress.android.ui.posts.EditPostPublishSettingsViewModel.start(EditPostPublishSettingsViewModel.kt:40)
    at org.wordpress.android.ui.posts.EditPostSettingsFragment.refreshViews(EditPostSettingsFragment.java:508)
...
(66 additional frame(s) were not displayed)
```


Discussion hints:
This looks like it is coming from [an unannotated nullable in the Java utility code](https://github.com/wordpress-mobile/WordPress-Utils-Android/blob/20c490bdf3def25600c76b8cb9796eeccb14edc6/WordPressUtils/src/main/java/org/wordpress/android/util/DateTimeUtils.java#L63). If content loss is possible from this, it may be worth bumping to high priority.

Pull request: Fix: PublishSettingsViewModel NPE on create date
Fixes #18615 

This PR adjusts `onAddToCalendar()` to handle scenarios where the `EditPostRepository.dateCreated` may be empty. Previously, the method would attempt to process the calendar event without considering the possibility of an empty dateCreated. This could potentially lead to null return from `DateTimeUtils.dateFromIso8601()`, then a subsequent attempt to access `time` on a null object would throw an NPE.

In this PR, I've introduced a null check using ?.let { } to ensure that the time is only accessed when `dateFromIso8601` returns a value that is not null. A toast message is shown if  we are unable to get the time properly.

It's important to note that while val dateCreated: String get() = post!!.dateCreated cannot be null due to its definition, it's possible for it to be empty. 

-----

## To Test:
I was unable to create this scenario using the app.
Please ensure the code looks good and the unit tests pass.
If you are feeling extra adventurous, you can download the branch and modify the `onAddToCalendar()` to pass an empty string to `DateTimeUtils.dateFromIso8601` and then run the app.

-----

## Regression Notes

1. Potential unintended areas of impact
The app still crashes when dateCreated is empty

2. What I did to test those areas of impact (or what existing automated tests I relied on)
New unit test in `EditPostPublishSettingsViewModelTest`

3. What automated tests I added (or what prevented me from doing so)
N/A

-----

## PR Submission Checklist:
- [X] I have completed the Regression Notes.
- [X] I have considered adding accessibility improvements for my changes.
- [X] I have considered if this change warrants user-facing release notes and have added them to `RELEASE-NOTES.txt` if necessary.

-----

## Testing Checklist (strike-out the not-applying and unnecessary ones): N/A



Test command: ./gradlew :WordPress:testWordpressVanillaDebugUnitTest --tests "org.wordpress.android.ui.posts.EditPostPublishSettingsViewModelTest"

Fix patch:
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/PublishSettingsViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/PublishSettingsViewModel.kt
index 0c3a87edcbef..d8672ec395f5 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/posts/PublishSettingsViewModel.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/PublishSettingsViewModel.kt
@@ -188,21 +188,23 @@ constructor(
     }
 
     fun onAddToCalendar(postRepository: EditPostRepository) {
-        val startTime = DateTimeUtils.dateFromIso8601(postRepository.dateCreated).time
-        val site = siteStore.getSiteByLocalId(postRepository.localSiteId)
-        val title = resourceProvider.getString(
-            R.string.calendar_scheduled_post_title,
-            postRepository.title
-        )
-        val appName = resourceProvider.getString(R.string.app_name)
-        val description = resourceProvider.getString(
-            R.string.calendar_scheduled_post_description,
-            postRepository.title,
-            site?.name ?: site?.url ?: "",
-            appName,
-            postRepository.link
-        )
-        _onAddToCalendar.value = Event(CalendarEvent(title, description, startTime))
+        DateTimeUtils.dateFromIso8601(postRepository.dateCreated)?.let {
+            val startTime = it.time
+            val site = siteStore.getSiteByLocalId(postRepository.localSiteId)
+            val title = resourceProvider.getString(
+                R.string.calendar_scheduled_post_title,
+                postRepository.title
+            )
+            val appName = resourceProvider.getString(R.string.app_name)
+            val description = resourceProvider.getString(
+                R.string.calendar_scheduled_post_description,
+                postRepository.title,
+                site?.name ?: site?.url ?: "",
+                appName,
+                postRepository.link
+            )
+            _onAddToCalendar.value = Event(CalendarEvent(title, description, startTime))
+        } ?: _onToast.postValue(Event(resourceProvider.getString(R.string.post_settings_add_to_calendar_error)))
     }
 
     private fun getCurrentPublishDateAsCalendar(postRepository: EditPostRepository): Calendar {
diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml
index f0f385ac490a..27a2cb7163a6 100644
--- a/WordPress/src/main/res/values/strings.xml
+++ b/WordPress/src/main/res/values/strings.xml
@@ -1796,6 +1796,7 @@
     <string name="post_settings_notification">Notification</string>
     <string name="post_settings_add_to_calendar">Add to calendar</string>
     <string name="post_settings_no_calendar_app_exists">No app found to handle the request to add to calendar</string>
+    <string name="post_settings_add_to_calendar_error">Unable to add to calendar</string>
     <string name="post_settings_jetpack_social_header">Social Sharing</string>
     <string name="post_settings_jetpack_social_connect_social_profiles_message">Increase your traffic by auto-sharing your posts with your friends on social media.</string>
     <string name="post_settings_jetpack_social_connect_social_profiles_button">Connect accounts</string>


Test patch:
diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/EditPostPublishSettingsViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/EditPostPublishSettingsViewModelTest.kt
index ecd6b449465b..3e6582489b32 100644
--- a/WordPress/src/test/java/org/wordpress/android/ui/posts/EditPostPublishSettingsViewModelTest.kt
+++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/EditPostPublishSettingsViewModelTest.kt
@@ -472,4 +472,22 @@ class EditPostPublishSettingsViewModelTest : BaseUnitTest() {
 
         assertThat(uiModel!!.publishDateLabel).isEqualTo("Immediately")
     }
+
+    @Test
+    fun `given dateCreated is empty, when onAddToCalendar, then a toast is shown`() {
+        whenever(editPostRepository.dateCreated).thenReturn("")
+        val expectedToastMessage = ""
+        whenever(resourceProvider.getString(R.string.post_settings_add_to_calendar_error)).thenReturn(
+            expectedToastMessage
+        )
+
+        var toastMessage: String? = null
+        viewModel.onToast.observeForever {
+            toastMessage = it?.getContentIfNotHandled()
+        }
+
+        viewModel.onAddToCalendar(editPostRepository)
+
+        assertThat(toastMessage).isEqualTo(expectedToastMessage)
+    }
 }