Skip to content

Commit

Permalink
Parse new "start_date", "end_date", "event_timezone" properties into …
Browse files Browse the repository at this point in the history
…Shift.

+ Deprecate "start", "end", "timezone" properties in favor of the new ones.
+ All new properties are mandatory in the JSON shift object which makes
  this change a breaking change.
  • Loading branch information
johnjohndoe committed Dec 10, 2021
1 parent 510250d commit 4d5b1e2
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 2 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Engelsystem changelog

## NEXT

* Not published yet.

### Changes

* **Breaking change:** Parse new mandatory `start_date`, `end_date`, `event_timezone` properties into `Shift`.
* Deprecate `start`, `end`, `timezone` properties in favor of the new ones.
* Related: https://github.com/engelsystem/engelsystem/issues/695


## [v.5.3.0](https://github.com/johnjohndoe/engelsystem/releases/tag/v.5.3.0)

* Published: 2021-11-14
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package info.metadude.kotlin.library.engelsystem
import com.squareup.moshi.Moshi
import info.metadude.kotlin.library.engelsystem.adapters.InstantJsonAdapter
import info.metadude.kotlin.library.engelsystem.adapters.ZoneOffsetJsonAdapter
import info.metadude.kotlin.library.engelsystem.adapters.ZonedDateTimeJsonAdapter
import okhttp3.OkHttpClient
import org.threeten.bp.Instant
import org.threeten.bp.ZoneOffset
import org.threeten.bp.ZonedDateTime
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory

Expand All @@ -22,6 +24,7 @@ object ApiModule {
private fun provideMoshiBuilder(): Moshi {
return Moshi.Builder()
.add(Instant::class.java, InstantJsonAdapter())
.add(ZonedDateTime::class.java, ZonedDateTimeJsonAdapter())
.add(ZoneOffset::class.java, ZoneOffsetJsonAdapter())
.build()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package info.metadude.kotlin.library.engelsystem.adapters

import com.squareup.moshi.FromJson
import org.threeten.bp.DateTimeException
import org.threeten.bp.ZonedDateTime

class ZonedDateTimeAdapter {

@FromJson
fun fromJson(jsonValue: String?) = jsonValue?.let {
try {
ZonedDateTime.parse(jsonValue)
} catch (e: DateTimeException) {
println(e.message)
null
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package info.metadude.kotlin.library.engelsystem.adapters

import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import org.threeten.bp.ZonedDateTime

class ZonedDateTimeJsonAdapter : JsonAdapter<ZonedDateTime>() {

private val delegate = ZonedDateTimeAdapter()

override fun fromJson(reader: JsonReader): ZonedDateTime? {
val jsonValue = reader.nextString()
return delegate.fromJson(jsonValue)
}

override fun toJson(writer: JsonWriter, value: ZonedDateTime?) {
throw NotImplementedError()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,20 @@ data class Shift internal constructor(
/**
* Unix timestamp of when the shift ends.
*/
@Deprecated(
message = "Use endsAtDate instead." +
" See https://github.com/engelsystem/engelsystem/issues/695",
ReplaceWith("endsAtDate")
)
@Json(name = "end")
internal val endsAtInstant: Instant = DEFAULT_INSTANT,

/**
* Date and time with time zone offset of when the shift ends, RFC3339 compliant (Y-m-d\TH:i:sP).
*/
@Json(name = "end_date")
val endsAtDate: ZonedDateTime,

/**
* Description of the shift location.
*/
Expand Down Expand Up @@ -58,9 +69,20 @@ data class Shift internal constructor(
/**
* Unix timestamp of when the shift starts.
*/
@Deprecated(
message = "Use startsAtDate instead." +
" See https://github.com/engelsystem/engelsystem/issues/695",
ReplaceWith("startsAtDate")
)
@Json(name = "start")
internal val startsAtInstant: Instant = DEFAULT_INSTANT,

/**
* Date and time with time zone offset of when the shift starts, RFC3339 compliant (Y-m-d\TH:i:sP).
*/
@Json(name = "start_date")
val startsAtDate: ZonedDateTime,

/**
* Title of the associated talk in case the shift happens at a talk.
*/
Expand All @@ -76,9 +98,19 @@ data class Shift internal constructor(
/**
* Time zone offset associated with the time stamps in this class. Example: "+01:00"
*/
@Deprecated(
message = "Retrieve the time zone offset from either startsAtDate or endsAtDate. " +
"See https://github.com/engelsystem/engelsystem/issues/695"
)
@Json(name = "timezone")
val timeZoneOffset: ZoneOffset = DEFAULT_ZONE_OFFSET,

/**
* Time zone name associated with the physical location of the event, e.g. "Europe/Berlin".
*/
@Json(name = "event_timezone")
val timeZoneName: String,

/**
* Shift types ids are not fixed. They can be assigned whenever an instance of the Engelsystem is launched.
*/
Expand All @@ -90,27 +122,33 @@ data class Shift internal constructor(
constructor(
userComment: String = "",
endsAt: ZonedDateTime = DEFAULT_ZONED_DATE_TIME,
endsAtDate: ZonedDateTime = DEFAULT_ZONED_DATE_TIME,
locationDescription: String = "",
locationName: String = "",
locationUrl: String = "",
name: String = "",
sID: Int = 0,
startsAt: ZonedDateTime = DEFAULT_ZONED_DATE_TIME,
startsAtDate: ZonedDateTime = DEFAULT_ZONED_DATE_TIME,
talkTitle: String = "",
talkUrl: String = "",
timeZoneName: String = "",
timeZoneOffset: ZoneOffset = DEFAULT_ZONE_OFFSET,
typeId: Int = 0
) : this(
userComment = userComment,
endsAtDate = endsAtDate,
endsAtInstant = endsAt.toInstant(),
locationDescriptionString = locationDescription,
locationName = locationName,
locationUrlString = locationUrl,
name = name,
sID = sID,
startsAtDate = startsAtDate,
startsAtInstant = startsAt.toInstant(),
talkTitle = talkTitle,
talkUrlString = talkUrl,
timeZoneName = timeZoneName,
timeZoneOffset = timeZoneOffset,
typeId = typeId
)
Expand All @@ -125,6 +163,11 @@ data class Shift internal constructor(
/**
* Date and time with time zone offset of when the shift ends.
*/
@Deprecated(
message = "Use endsAtDate instead." +
" See https://github.com/engelsystem/engelsystem/issues/695",
ReplaceWith("endsAtDate")
)
val endsAt: ZonedDateTime
get() = ZonedDateTime.ofInstant(endsAtInstant, timeZoneOffset)

Expand All @@ -143,6 +186,11 @@ data class Shift internal constructor(
/**
* Date and time with time zone offset of when the shift starts.
*/
@Deprecated(
message = "Use startsAtDate instead." +
" See https://github.com/engelsystem/engelsystem/issues/695",
ReplaceWith("startsAtDate")
)
val startsAt: ZonedDateTime
get() = ZonedDateTime.ofInstant(startsAtInstant, timeZoneOffset)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ class ProductionApiTest {
assertThat(shift.startsAtInstant).isNotEqualTo(Shift.DEFAULT_INSTANT)
assertThat(shift.endsAtInstant).isNotEqualTo(Shift.DEFAULT_INSTANT)
assertThat(shift.startsAt).isNotEqualTo(DEFAULT_DATE_TIME)
assertThat(shift.startsAtDate).isNotEqualTo(DEFAULT_DATE_TIME)
assertThat(shift.endsAt).isNotEqualTo(DEFAULT_DATE_TIME)
assertThat(shift.endsAtDate).isNotEqualTo(DEFAULT_DATE_TIME)
assertThat(shift.timeZoneName).isNotEmpty()
assertThat(shift.timeZoneOffset).isNotNull()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package info.metadude.kotlin.library.engelsystem.adapters

import com.google.common.truth.Truth.assertThat
import org.junit.jupiter.api.Test
import org.threeten.bp.ZoneOffset
import org.threeten.bp.ZonedDateTime

class ZonedDateTimeAdapterTest {

private val adapter = ZonedDateTimeAdapter()

@Test
fun `Converts RFC3339 date to its ZonedDateTime representation`() {
val actual = adapter.fromJson("2019-08-21T00:00:00+02:00")
val expected = ZonedDateTime.of(2019, 8, 21, 0, 0, 0, 0, ZoneOffset.ofHours(2))
assertThat(actual).isEqualTo(expected)
}

@Test
fun `Converts date without zone offset to null`() {
val actual = adapter.fromJson("2019-08-21T00:00:00")
assertThat(actual).isEqualTo(null)
}

@Test
fun `Converts 0 to null`() {
val actual = adapter.fromJson("")
assertThat(actual).isEqualTo(null)
}

@Test
fun `Converts null to null`() {
val actual = adapter.fromJson(null)
assertThat(actual).isEqualTo(null)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ import org.threeten.bp.ZonedDateTime
class ShiftTest {

@Test
fun `Assert a shift can be constructed`() {
fun `Assert a shift with minimal parameters can be constructed`() {
val startsAt = ZonedDateTime.now()
val endsAt = ZonedDateTime.now().plusHours(1)
assertThat(
Shift(
userComment = "comment",
endsAt = ZonedDateTime.now(),
endsAtDate = endsAt,
locationDescription = "",
locationUrl = "https://example1.com",
startsAtDate = startsAt,
talkUrl = "https://example2.com",
timeZoneName = "Europe/Berlin",
timeZoneOffset = ZoneOffset.UTC
)
).isNotNull()
Expand Down

0 comments on commit 4d5b1e2

Please sign in to comment.