Fix a NPE when only a valid-timespan to is given - closes #122
Also add tests to cover this path
This commit is contained in:
parent
deaff19be7
commit
2a37166d4c
2 changed files with 176 additions and 3 deletions
|
@ -0,0 +1,164 @@
|
|||
package org.ligi.passandroid
|
||||
|
||||
import android.app.Activity.RESULT_CANCELED
|
||||
import android.app.Instrumentation
|
||||
import android.provider.CalendarContract
|
||||
import android.support.test.espresso.Espresso.onView
|
||||
import android.support.test.espresso.action.ViewActions.click
|
||||
import android.support.test.espresso.assertion.ViewAssertions.matches
|
||||
import android.support.test.espresso.intent.Intents.intended
|
||||
import android.support.test.espresso.intent.Intents.intending
|
||||
import android.support.test.espresso.intent.matcher.IntentMatchers.hasExtra
|
||||
import android.support.test.espresso.intent.matcher.IntentMatchers.hasType
|
||||
import android.support.test.espresso.matcher.ViewMatchers.*
|
||||
import org.hamcrest.CoreMatchers.not
|
||||
import org.hamcrest.Matchers.allOf
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.ligi.passandroid.functions.DEFAULT_EVENT_LENGTH_IN_HOURS
|
||||
import org.ligi.passandroid.model.pass.PassImpl
|
||||
import org.ligi.passandroid.ui.PassListActivity
|
||||
import org.ligi.trulesk.TruleskIntentRule
|
||||
import org.threeten.bp.ZonedDateTime
|
||||
|
||||
class TheAddToCalendar {
|
||||
|
||||
val time = ZonedDateTime.now()
|
||||
val time2 = ZonedDateTime.now().plusHours(3)
|
||||
|
||||
@get:Rule
|
||||
var rule = TruleskIntentRule(PassListActivity::class.java, false)
|
||||
|
||||
@Test
|
||||
fun testIfWeOnlyHaveCalendarStartDate() {
|
||||
TestApp.reset()
|
||||
|
||||
TestApp.getPassStore().currentPass!!.calendarTimespan = PassImpl.TimeSpan(time)
|
||||
rule.launchActivity()
|
||||
|
||||
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
||||
|
||||
onView(withId(R.id.timeButton)).perform(click())
|
||||
|
||||
intended(allOf(
|
||||
hasType("vnd.android.cursor.item/event"),
|
||||
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.toEpochSecond() * 1000),
|
||||
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time.plusHours(DEFAULT_EVENT_LENGTH_IN_HOURS).toEpochSecond() * 1000),
|
||||
hasExtra("title", TestApp.getPassStore().currentPass!!.description)
|
||||
))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIfWeOnlyHaveCalendarEndDate() {
|
||||
TestApp.reset()
|
||||
|
||||
TestApp.getPassStore().currentPass!!.calendarTimespan = PassImpl.TimeSpan(to = time)
|
||||
rule.launchActivity()
|
||||
|
||||
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
||||
|
||||
onView(withId(R.id.timeButton)).perform(click())
|
||||
|
||||
intended(allOf(
|
||||
hasType("vnd.android.cursor.item/event"),
|
||||
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.minusHours(DEFAULT_EVENT_LENGTH_IN_HOURS).toEpochSecond() * 1000),
|
||||
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time.toEpochSecond() * 1000),
|
||||
hasExtra("title", TestApp.getPassStore().currentPass!!.description)
|
||||
))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIfWeOnlyHaveCalendarStartAndEndDate() {
|
||||
TestApp.reset()
|
||||
|
||||
TestApp.getPassStore().currentPass!!.calendarTimespan = PassImpl.TimeSpan(time, time2)
|
||||
rule.launchActivity()
|
||||
|
||||
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
||||
|
||||
onView(withId(R.id.timeButton)).perform(click())
|
||||
|
||||
intended(allOf(
|
||||
hasType("vnd.android.cursor.item/event"),
|
||||
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.toEpochSecond() * 1000),
|
||||
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time2.toEpochSecond() * 1000),
|
||||
hasExtra("title", TestApp.getPassStore().currentPass!!.description)
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun testIfWeOnlyHaveExpirationDate() {
|
||||
TestApp.reset()
|
||||
|
||||
(TestApp.getPassStore().currentPass as PassImpl).validTimespans = listOf(PassImpl.TimeSpan(time))
|
||||
rule.launchActivity()
|
||||
|
||||
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
||||
|
||||
onView(withId(R.id.timeButton)).perform(click())
|
||||
|
||||
onView(withText(R.string.expiration_date_to_calendar_warning_title)).check(matches(isDisplayed()))
|
||||
onView(withText(android.R.string.ok)).perform(click())
|
||||
|
||||
intended(allOf(
|
||||
hasType("vnd.android.cursor.item/event"),
|
||||
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.toEpochSecond() * 1000),
|
||||
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time.plusHours(DEFAULT_EVENT_LENGTH_IN_HOURS).toEpochSecond() * 1000),
|
||||
hasExtra("title", TestApp.getPassStore().currentPass!!.description)
|
||||
))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIfWeOnlyHaveExpirationEndDate() {
|
||||
TestApp.reset()
|
||||
|
||||
(TestApp.getPassStore().currentPass as PassImpl).validTimespans = listOf(PassImpl.TimeSpan(to = time))
|
||||
rule.launchActivity()
|
||||
|
||||
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
||||
|
||||
onView(withId(R.id.timeButton)).perform(click())
|
||||
|
||||
onView(withText(R.string.expiration_date_to_calendar_warning_title)).check(matches(isDisplayed()))
|
||||
onView(withText(android.R.string.ok)).perform(click())
|
||||
|
||||
intended(allOf(
|
||||
hasType("vnd.android.cursor.item/event"),
|
||||
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.minusHours(DEFAULT_EVENT_LENGTH_IN_HOURS).toEpochSecond() * 1000),
|
||||
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time.toEpochSecond() * 1000),
|
||||
hasExtra("title", TestApp.getPassStore().currentPass!!.description)
|
||||
))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIfWeOnlyHaveExpirationStartAndEndDate() {
|
||||
TestApp.reset()
|
||||
|
||||
(TestApp.getPassStore().currentPass as PassImpl).validTimespans = listOf(PassImpl.TimeSpan(time, time2))
|
||||
rule.launchActivity()
|
||||
|
||||
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
||||
|
||||
onView(withId(R.id.timeButton)).perform(click())
|
||||
|
||||
onView(withText(R.string.expiration_date_to_calendar_warning_title)).check(matches(isDisplayed()))
|
||||
onView(withText(android.R.string.ok)).perform(click())
|
||||
|
||||
intended(allOf(
|
||||
hasType("vnd.android.cursor.item/event"),
|
||||
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.toEpochSecond() * 1000),
|
||||
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time2.toEpochSecond() * 1000),
|
||||
hasExtra("title", TestApp.getPassStore().currentPass!!.description)
|
||||
))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testThereIsNoButtonWithNoDate() {
|
||||
TestApp.reset()
|
||||
rule.launchActivity()
|
||||
onView(withId(R.id.timeButton)).check(matches(not(isDisplayed())))
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -10,6 +10,8 @@ import org.ligi.passandroid.R
|
|||
import org.ligi.passandroid.model.pass.Pass
|
||||
import org.ligi.passandroid.model.pass.PassImpl
|
||||
|
||||
val DEFAULT_EVENT_LENGTH_IN_HOURS = 8L
|
||||
|
||||
fun tryAddDateToCalendar(pass: Pass, contextView: View, timeSpan: PassImpl.TimeSpan) {
|
||||
if (pass.calendarTimespan == null) {
|
||||
AlertDialog.Builder(contextView.context).setMessage(R.string.expiration_date_to_calendar_warning_message)
|
||||
|
@ -22,11 +24,18 @@ fun tryAddDateToCalendar(pass: Pass, contextView: View, timeSpan: PassImpl.TimeS
|
|||
}
|
||||
}
|
||||
|
||||
private fun reallyAddToCalendar(pass: Pass, contextView: View, date: PassImpl.TimeSpan) = try {
|
||||
private fun reallyAddToCalendar(pass: Pass, contextView: View, timeSpan: PassImpl.TimeSpan) = try {
|
||||
if (timeSpan.from == null && timeSpan.to == null) {
|
||||
throw IllegalArgumentException("span must have either a to or a from")
|
||||
}
|
||||
|
||||
val intent = Intent(Intent.ACTION_EDIT)
|
||||
intent.type = "vnd.android.cursor.item/event"
|
||||
intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, date.from!!.toEpochSecond() * 1000)
|
||||
val to = date.to ?: date.from.plusHours(4)
|
||||
|
||||
val from = timeSpan.from ?: timeSpan.to!!.minusHours(DEFAULT_EVENT_LENGTH_IN_HOURS)
|
||||
intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, from.toEpochSecond() * 1000)
|
||||
|
||||
val to = timeSpan.to ?: timeSpan.from!!.plusHours(DEFAULT_EVENT_LENGTH_IN_HOURS)
|
||||
intent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, to.toEpochSecond() * 1000)
|
||||
intent.putExtra("title", pass.description)
|
||||
contextView.context.startActivity(intent)
|
||||
|
|
Loading…
Reference in a new issue