@@ -8,41 +8,29 @@ package at.bitfire.synctools.mapping.calendar
88
99import android.accounts.Account
1010import android.content.ContentProviderClient
11- import android.content.Entity
1211import android.provider.CalendarContract.ACCOUNT_TYPE_LOCAL
1312import android.provider.CalendarContract.AUTHORITY
1413import android.provider.CalendarContract.Events
15- import android.provider.CalendarContract.ExtendedProperties
1614import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
1715import at.bitfire.ical4android.Event
18- import at.bitfire.ical4android.UnknownProperty
1916import at.bitfire.ical4android.impl.TestCalendar
2017import at.bitfire.ical4android.util.AndroidTimeUtils
2118import at.bitfire.ical4android.util.MiscUtils.closeCompat
22- import at.bitfire.synctools.icalendar.Css3Color
2319import at.bitfire.synctools.storage.calendar.AndroidCalendar
24- import at.bitfire.synctools.storage.calendar.AndroidCalendarProvider
2520import at.bitfire.synctools.storage.calendar.EventAndExceptions
2621import at.bitfire.synctools.test.InitCalendarProviderRule
2722import net.fortuna.ical4j.model.Date
2823import net.fortuna.ical4j.model.DateList
2924import net.fortuna.ical4j.model.DateTime
30- import net.fortuna.ical4j.model.Property
3125import net.fortuna.ical4j.model.Recur
3226import net.fortuna.ical4j.model.TimeZoneRegistryFactory
33- import net.fortuna.ical4j.model.parameter.Email
3427import net.fortuna.ical4j.model.parameter.Value
35- import net.fortuna.ical4j.model.property.Attendee
36- import net.fortuna.ical4j.model.property.Clazz
3728import net.fortuna.ical4j.model.property.DtEnd
3829import net.fortuna.ical4j.model.property.DtStart
3930import net.fortuna.ical4j.model.property.Duration
4031import net.fortuna.ical4j.model.property.ExDate
41- import net.fortuna.ical4j.model.property.Organizer
4232import net.fortuna.ical4j.model.property.RDate
4333import net.fortuna.ical4j.model.property.RRule
44- import net.fortuna.ical4j.model.property.RecurrenceId
45- import net.fortuna.ical4j.model.property.Status
4634import net.fortuna.ical4j.util.TimeZones
4735import org.junit.After
4836import org.junit.Assert.assertEquals
@@ -119,7 +107,6 @@ class LegacyAndroidEventBuilder2Test {
119107 return LegacyAndroidEventBuilder2 (
120108 calendar = calendar,
121109 event = event,
122- id = null ,
123110 syncId = " some sync ID" ,
124111 eTag = null ,
125112 scheduleTag = null ,
@@ -130,17 +117,6 @@ class LegacyAndroidEventBuilder2Test {
130117 private fun buildEvent (automaticDates : Boolean , eventBuilder : Event .() -> Unit ) =
131118 buildEventAndExceptions(automaticDates, eventBuilder).main
132119
133- private fun firstExtendedProperty (entity : Entity ) =
134- entity.subValues.firstOrNull { it.uri == ExtendedProperties .CONTENT_URI }?.values?.getAsString(ExtendedProperties .VALUE )
135-
136- private fun firstUnknownProperty (entity : Entity ): Property ? {
137- val rawValue = firstExtendedProperty(entity)
138- return if (rawValue != null )
139- UnknownProperty .fromJsonString(rawValue)
140- else
141- null
142- }
143-
144120 @Test
145121 fun testBuildEvent_NonAllDay_NoDtEnd_NoDuration_NonRecurring () {
146122 val entity = buildEvent(false ) {
@@ -508,301 +484,4 @@ class LegacyAndroidEventBuilder2Test {
508484 assertEquals(TimeZones .UTC_ID , entity.entityValues.get(Events .EVENT_END_TIMEZONE ))
509485 }
510486
511- @Test
512- fun testBuildEvent_Color_WhenNotAvailable () {
513- buildEvent(true ) {
514- color = Css3Color .darkseagreen
515- }.let { result ->
516- assertNull(result.entityValues.getAsString(Events .CALENDAR_COLOR_KEY ))
517- }
518- }
519-
520- @Test
521- fun testBuildEvent_Color_WhenAvailable () {
522- val provider = AndroidCalendarProvider (testAccount, client)
523- provider.provideCss3ColorIndices()
524- buildEvent(true ) {
525- color = Css3Color .darkseagreen
526- }.let { result ->
527- assertEquals(Css3Color .darkseagreen.name, result.entityValues.getAsString(Events .EVENT_COLOR_KEY ))
528- }
529- }
530-
531- @Test
532- fun testBuildEvent_Organizer_NotGroupScheduled () {
533- buildEvent(true ) {
534- organizer = Organizer (" mailto:organizer@example.com" )
535- }.let { result ->
536- assertNull(result.entityValues.getAsString(Events .ORGANIZER ))
537- }
538- }
539-
540- @Test
541- fun testBuildEvent_Organizer_MailTo () {
542- buildEvent(true ) {
543- organizer = Organizer (" mailto:organizer@example.com" )
544- attendees + = Attendee (" mailto:attendee@example.com" )
545- }.let { result ->
546- assertEquals(" organizer@example.com" , result.entityValues.getAsString(Events .ORGANIZER ))
547- }
548- }
549-
550- @Test
551- fun testBuildEvent_Organizer_EmailParameter () {
552- buildEvent(true ) {
553- organizer = Organizer (" local-id:user" ).apply {
554- parameters.add(Email (" organizer@example.com" ))
555- }
556- attendees + = Attendee (" mailto:attendee@example.com" )
557- }.let { result ->
558- assertEquals(" organizer@example.com" , result.entityValues.getAsString(Events .ORGANIZER ))
559- }
560- }
561-
562- @Test
563- fun testBuildEvent_Organizer_NotEmail () {
564- buildEvent(true ) {
565- organizer = Organizer (" local-id:user" )
566- attendees + = Attendee (" mailto:attendee@example.com" )
567- }.let { result ->
568- assertNull(result.entityValues.getAsString(Events .ORGANIZER ))
569- }
570- }
571-
572- @Test
573- fun testBuildEvent_Status_Confirmed () {
574- buildEvent(true ) {
575- status = Status .VEVENT_CONFIRMED
576- }.let { result ->
577- assertEquals(Events .STATUS_CONFIRMED , result.entityValues.getAsInteger(Events .STATUS ))
578- }
579- }
580-
581- @Test
582- fun testBuildEvent_Status_Cancelled () {
583- buildEvent(true ) {
584- status = Status .VEVENT_CANCELLED
585- }.let { result ->
586- assertEquals(Events .STATUS_CANCELED , result.entityValues.getAsInteger(Events .STATUS ))
587- }
588- }
589-
590- @Test
591- fun testBuildEvent_Status_Tentative () {
592- buildEvent(true ) {
593- status = Status .VEVENT_TENTATIVE
594- }.let { result ->
595- assertEquals(Events .STATUS_TENTATIVE , result.entityValues.getAsInteger(Events .STATUS ))
596- }
597- }
598-
599- @Test
600- fun testBuildEvent_Status_Invalid () {
601- buildEvent(true ) {
602- status = Status .VTODO_IN_PROCESS
603- }.let { result ->
604- assertEquals(Events .STATUS_TENTATIVE , result.entityValues.getAsInteger(Events .STATUS ))
605- }
606- }
607-
608- @Test
609- fun testBuildEvent_Status_None () {
610- buildEvent(true ) {
611- }.let { result ->
612- assertNull(result.entityValues.getAsInteger(Events .STATUS ))
613- }
614- }
615-
616- @Test
617- fun testBuildEvent_Opaque_True () {
618- buildEvent(true ) {
619- opaque = true
620- }.let { result ->
621- assertEquals(Events .AVAILABILITY_BUSY , result.entityValues.getAsInteger(Events .AVAILABILITY ))
622- }
623- }
624-
625- @Test
626- fun testBuildEvent_Opaque_False () {
627- buildEvent(true ) {
628- opaque = false
629- }.let { result ->
630- assertEquals(Events .AVAILABILITY_FREE , result.entityValues.getAsInteger(Events .AVAILABILITY ))
631- }
632- }
633-
634- @Test
635- fun testBuildEvent_Classification_Public () {
636- buildEvent(true ) {
637- classification = Clazz .PUBLIC
638- }.let { result ->
639- assertEquals(Events .ACCESS_PUBLIC , result.entityValues.getAsInteger(Events .ACCESS_LEVEL ))
640- assertNull(firstUnknownProperty(result))
641- }
642- }
643-
644- @Test
645- fun testBuildEvent_Classification_Private () {
646- buildEvent(true ) {
647- classification = Clazz .PRIVATE
648- }.let { result ->
649- assertEquals(Events .ACCESS_PRIVATE , result.entityValues.getAsInteger(Events .ACCESS_LEVEL ))
650- assertNull(firstUnknownProperty(result))
651- }
652- }
653-
654- @Test
655- fun testBuildEvent_Classification_Confidential () {
656- buildEvent(true ) {
657- classification = Clazz .CONFIDENTIAL
658- }.let { result ->
659- assertEquals(Events .ACCESS_CONFIDENTIAL , result.entityValues.getAsInteger(Events .ACCESS_LEVEL ))
660- assertEquals(Clazz .CONFIDENTIAL , firstUnknownProperty(result))
661- }
662- }
663-
664- @Test
665- fun testBuildEvent_Classification_Custom () {
666- buildEvent(true ) {
667- classification = Clazz (" TOP-SECRET" )
668- }.let { result ->
669- assertEquals(Events .ACCESS_PRIVATE , result.entityValues.getAsInteger(Events .ACCESS_LEVEL ))
670- assertEquals(Clazz (" TOP-SECRET" ), firstUnknownProperty(result))
671- }
672- }
673-
674- @Test
675- fun testBuildEvent_Classification_None () {
676- buildEvent(true ) {
677- }.let { result ->
678- assertEquals(Events .ACCESS_DEFAULT , result.entityValues.getAsInteger(Events .ACCESS_LEVEL ))
679- assertNull(firstUnknownProperty(result))
680- }
681- }
682-
683- @Test
684- fun testBuildEvent_UID2445 () {
685- buildEvent(true ) {
686- uid = " event1@example.com"
687- }.let { result ->
688- assertEquals(" event1@example.com" , result.entityValues.getAsString(Events .UID_2445 ))
689- }
690- }
691-
692-
693- // exceptions → test with EventAndException
694-
695- private fun firstException (eventAndExceptions : EventAndExceptions ) =
696- eventAndExceptions.exceptions.first()
697-
698- @Test
699- fun testBuildException_NonAllDay () {
700- buildEventAndExceptions(false ) {
701- dtStart = DtStart (" 20200706T193000" , tzVienna)
702- rRules + = RRule (" FREQ=DAILY;COUNT=10" )
703- exceptions + = Event ().apply {
704- recurrenceId = RecurrenceId (" 20200707T193000" , tzVienna)
705- dtStart = DtStart (" 20200706T203000" , tzShanghai)
706- summary = " Event moved to one hour later"
707- }
708- }.let { result ->
709- val values = result.main.entityValues
710- assertEquals(1594056600000L , values.getAsLong(Events .DTSTART ))
711- assertEquals(tzVienna.id, values.getAsString(Events .EVENT_TIMEZONE ))
712- assertEquals(0 , values.getAsInteger(Events .ALL_DAY ))
713- assertEquals(" FREQ=DAILY;COUNT=10" , values.getAsString(Events .RRULE ))
714- firstException(result).let { exceptionEntity ->
715- val exception = exceptionEntity.entityValues
716- assertEquals(1594143000000L , exception.getAsLong(Events .ORIGINAL_INSTANCE_TIME ))
717- assertEquals(0 , exception.getAsInteger(Events .ORIGINAL_ALL_DAY ))
718- assertEquals(1594038600000L , exception.getAsLong(Events .DTSTART ))
719- assertEquals(tzShanghai.id, exception.getAsString(Events .EVENT_TIMEZONE ))
720- assertEquals(0 , exception.getAsInteger(Events .ALL_DAY ))
721- assertEquals(" Event moved to one hour later" , exception.getAsString(Events .TITLE ))
722- }
723- }
724- }
725-
726- @Test
727- fun testBuildException_NonAllDay_RecurrenceIdAllDay () {
728- buildEventAndExceptions(false ) {
729- dtStart = DtStart (" 20200706T193000" , tzVienna)
730- rRules + = RRule (" FREQ=DAILY;COUNT=10" )
731- exceptions + = Event ().apply {
732- recurrenceId = RecurrenceId (Date (" 20200707" )) // illegal! should be rewritten to DateTime("20200707T193000", tzVienna)
733- dtStart = DtStart (" 20200706T203000" , tzShanghai)
734- summary = " Event moved to one hour later"
735- }
736- }.let { result ->
737- val values = result.main.entityValues
738- assertEquals(1594056600000L , values.getAsLong(Events .DTSTART ))
739- assertEquals(tzVienna.id, values.getAsString(Events .EVENT_TIMEZONE ))
740- assertEquals(0 , values.getAsInteger(Events .ALL_DAY ))
741- assertEquals(" FREQ=DAILY;COUNT=10" , values.getAsString(Events .RRULE ))
742- firstException(result).let { exceptionEntity ->
743- val exception = exceptionEntity.entityValues
744- assertEquals(1594143000000L , exception.getAsLong(Events .ORIGINAL_INSTANCE_TIME ))
745- assertEquals(0 , exception.getAsInteger(Events .ORIGINAL_ALL_DAY ))
746- assertEquals(1594038600000L , exception.getAsLong(Events .DTSTART ))
747- assertEquals(tzShanghai.id, exception.getAsString(Events .EVENT_TIMEZONE ))
748- assertEquals(0 , exception.getAsInteger(Events .ALL_DAY ))
749- assertEquals(" Event moved to one hour later" , exception.getAsString(Events .TITLE ))
750- }
751- }
752- }
753-
754- @Test
755- fun testBuildException_AllDay () {
756- buildEventAndExceptions(false ) {
757- dtStart = DtStart (Date (" 20200706" ))
758- rRules + = RRule (" FREQ=WEEKLY;COUNT=3" )
759- exceptions + = Event ().apply {
760- recurrenceId = RecurrenceId (Date (" 20200707" ))
761- dtStart = DtStart (" 20200706T123000" , tzVienna)
762- summary = " Today not an all-day event"
763- }
764- }.let { result ->
765- val values = result.main.entityValues
766- assertEquals(1593993600000L , values.getAsLong(Events .DTSTART ))
767- assertEquals(AndroidTimeUtils .TZID_ALLDAY , values.getAsString(Events .EVENT_TIMEZONE ))
768- assertEquals(1 , values.getAsInteger(Events .ALL_DAY ))
769- assertEquals(" FREQ=WEEKLY;COUNT=3" , values.getAsString(Events .RRULE ))
770- firstException(result).let { exceptionEntity ->
771- val exception = exceptionEntity.entityValues
772- assertEquals(1594080000000L , exception.getAsLong(Events .ORIGINAL_INSTANCE_TIME ))
773- assertEquals(1 , exception.getAsInteger(Events .ORIGINAL_ALL_DAY ))
774- assertEquals(1594031400000L , exception.getAsLong(Events .DTSTART ))
775- assertEquals(0 , exception.getAsInteger(Events .ALL_DAY ))
776- assertEquals(" Today not an all-day event" , exception.getAsString(Events .TITLE ))
777- }
778- }
779- }
780-
781- @Test
782- fun testBuildException_AllDay_RecurrenceIdNonAllDay () {
783- buildEventAndExceptions(false ) {
784- dtStart = DtStart (Date (" 20200706" ))
785- rRules + = RRule (" FREQ=WEEKLY;COUNT=3" )
786- exceptions + = Event ().apply {
787- recurrenceId = RecurrenceId (" 20200707T000000" , tzVienna) // illegal! should be rewritten to Date("20200707")
788- dtStart = DtStart (" 20200706T123000" , tzVienna)
789- summary = " Today not an all-day event"
790- }
791- }.let { result ->
792- val values = result.main.entityValues
793- assertEquals(1593993600000L , values.getAsLong(Events .DTSTART ))
794- assertEquals(AndroidTimeUtils .TZID_ALLDAY , values.getAsString(Events .EVENT_TIMEZONE ))
795- assertEquals(1 , values.getAsInteger(Events .ALL_DAY ))
796- assertEquals(" FREQ=WEEKLY;COUNT=3" , values.getAsString(Events .RRULE ))
797- firstException(result).let { exceptionEntity ->
798- val exception = exceptionEntity.entityValues
799- assertEquals(1594080000000L , exception.getAsLong(Events .ORIGINAL_INSTANCE_TIME ))
800- assertEquals(1 , exception.getAsInteger(Events .ORIGINAL_ALL_DAY ))
801- assertEquals(1594031400000L , exception.getAsLong(Events .DTSTART ))
802- assertEquals(0 , exception.getAsInteger(Events .ALL_DAY ))
803- assertEquals(" Today not an all-day event" , exception.getAsString(Events .TITLE ))
804- }
805- }
806- }
807-
808487}
0 commit comments