Commit 95080640 authored by Alex Baker's avatar Alex Baker

Merge branch 'master' into tasks

parents 4c1ff076 626c36d9
......@@ -10,7 +10,7 @@ cache:
test:
script:
- (cd /sdk/emulator; ./emulator @test -no-audio -no-window & wait-for-emulator.sh)
- adb install src/androidTest/resources/org.dmfs.tasks_6760.apk
- adb install src/androidTest/resources/org.dmfs.tasks_6880.apk
- ./gradlew check connectedCheck
artifacts:
paths:
......
......@@ -24,11 +24,14 @@ Generated KDoc: https://bitfireAT.gitlab.io/ical4android/dokka/ical4android/
```
bitfire web engineering – Stockmann, Hirner GesnbR
Liniengasse 6/3/28
Florastraße 27
2540 Bad Vöslau, AUSTRIA
```
Email: [play@bitfire.at](mailto:play@bitfire.at)
Email: [play@bitfire.at](mailto:play@bitfire.at) (do not use this)
For questions, suggestions etc. please use the DAVdroid forum:
https://www.davdroid.com/forums/
## License
......
buildscript {
ext.kotlin_version = '1.2.21'
ext.dokka_version = '0.9.15'
ext.kotlin_version = '1.2.50'
ext.dokka_version = '0.9.16'
repositories {
jcenter()
maven {
url "https://maven.google.com"
}
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.dokka:dokka-android-gradle-plugin:${dokka_version}"
}
......@@ -18,15 +17,17 @@ buildscript {
repositories {
jcenter()
maven {
url "https://maven.google.com"
}
google()
}
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'org.jetbrains.dokka-android'
ext {
ical4j_version = '2.2.0'
}
android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
......@@ -36,6 +37,8 @@ android {
targetSdkVersion 27
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
buildConfigField "String", "version_ical4j", "\"$ical4j_version\""
}
buildTypes {
release {
......@@ -58,39 +61,13 @@ android {
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
compile ('org.mnode.ical4j:ical4j:2.1.5') {
exclude group: 'org.threeten', module: 'threetenbp'
}
compile 'org.slf4j:slf4j-jdk14:1.7.25'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
androidTestCompile 'com.android.support.test:runner:1.0.1'
androidTestCompile 'com.android.support.test:rules:1.0.1'
api "org.mnode.ical4j:ical4j:$ical4j_version"
implementation 'org.slf4j:slf4j-jdk14:1.7.25'
testCompile 'junit:junit:4.12'
testCompileOnly 'org.projectlombok:lombok:1.16.20'
}
// grant permissions for unit tests
task grantPermissions(dependsOn: 'installDebugAndroidTest') {
doFirst {
def adb = android.getAdbExe().toString()
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
// grant permissions
[
'android.permission.READ_CALENDAR',
'android.permission.WRITE_CALENDAR',
'org.dmfs.permission.READ_TASKS',
'org.dmfs.permission.WRITE_TASKS'
].each {
"${adb} shell pm grant at.bitfire.ical4android.test ${it}".execute()
}
}
}
tasks.whenTaskAdded { task ->
if (task.name.startsWith('connectedDebugAndroidTest')) {
task.dependsOn grantPermissions
}
testImplementation 'junit:junit:4.12'
}
......@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip
lombok.addGeneratedAnnotation = false
......@@ -66,7 +66,7 @@ class AndroidCalendarTest {
assertNotNull(uri)
// query task list
val calendar = AndroidCalendar.findByID(testAccount, provider, TestCalendar.Factory.INSTANCE, ContentUris.parseId(uri))
val calendar = AndroidCalendar.findByID(testAccount, provider, TestCalendar.Factory, ContentUris.parseId(uri))
assertNotNull(calendar)
// delete task list
......
......@@ -118,7 +118,7 @@ class AndroidEventTest {
val uri = TestEvent(calendar, event).add()
assertNotNull(uri)
val testEvent = TestEvent(calendar, ContentUris.parseId(uri))
val testEvent = calendar.findById(ContentUris.parseId(uri))
try {
// read and parse event from calendar provider
......@@ -189,7 +189,7 @@ class AndroidEventTest {
val uri = TestEvent(calendar, event).add()
// update test event in calendar
val testEvent = TestEvent(calendar, ContentUris.parseId(uri))
val testEvent = calendar.findById(ContentUris.parseId(uri))
val event2 = testEvent.event!!
event2.summary = "Updated event"
// add data rows
......@@ -198,7 +198,7 @@ class AndroidEventTest {
val uri2 = testEvent.update(event2)
// read again and verify result
val updatedEvent = TestEvent(calendar, ContentUris.parseId(uri2))
val updatedEvent = calendar.findById(ContentUris.parseId(uri2))
try {
val event3 = updatedEvent.event!!
assertEquals(event2.summary, event3.summary)
......@@ -221,7 +221,7 @@ class AndroidEventTest {
event.attendees += Attendee(URI("mailto:att$i@example.com"))
val uri = TestEvent(calendar, event).add()
val testEvent = TestEvent(calendar, ContentUris.parseId(uri))
val testEvent = calendar.findById(ContentUris.parseId(uri))
try {
assertEquals(4000, testEvent.event!!.attendees.size)
} finally {
......@@ -259,7 +259,7 @@ class AndroidEventTest {
val uri = TestEvent(calendar, event).add()
assertNotNull(uri)
val testEvent = TestEvent(calendar, ContentUris.parseId(uri))
val testEvent = calendar.findById(ContentUris.parseId(uri))
try {
// read again and verify result
val event2 = testEvent.event!!
......@@ -285,7 +285,7 @@ class AndroidEventTest {
val uri = TestEvent(calendar, event).add()
assertNotNull(uri)
val testEvent = TestEvent(calendar, ContentUris.parseId(uri))
val testEvent = calendar.findById(ContentUris.parseId(uri))
try {
// read again and verify result
val event2 = testEvent.event!!
......@@ -309,7 +309,7 @@ class AndroidEventTest {
val uri = TestEvent(calendar, event).add()
assertNotNull(uri)
val testEvent = TestEvent(calendar, ContentUris.parseId(uri))
val testEvent = calendar.findById(ContentUris.parseId(uri))
try {
// read again and verify result
val event2 = testEvent.event!!
......@@ -340,7 +340,7 @@ class AndroidEventTest {
calendar.provider.update(calendar.syncAdapterURI(ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id)),
values, null, null)
val testEvent = TestEvent(calendar, id)
val testEvent = calendar.findById(id)
try {
// read again and verify result
val event2 = testEvent.event!!
......@@ -355,7 +355,7 @@ class AndroidEventTest {
values, null, null)
// read again and verify result
val testEventPrivate = TestEvent(calendar, id)
val testEventPrivate = calendar.findById(id)
val eventPrivate = testEventPrivate.event!!
// should be PRIVATE
assertEquals(Clazz.PRIVATE, eventPrivate.classification)
......@@ -378,7 +378,7 @@ class AndroidEventTest {
assertNotNull(uri)
val id = ContentUris.parseId(uri)
val testEvent = TestEvent(calendar, id)
val testEvent = calendar.findById(id)
try {
// read again and verify result
val event2 = testEvent.event!!
......@@ -412,7 +412,7 @@ class AndroidEventTest {
val uri = TestEvent(calendar, event).add()
assertNotNull(uri)
val testEvent = TestEvent(calendar, ContentUris.parseId(uri))
val testEvent = calendar.findById(ContentUris.parseId(uri))
try {
// read again and verify result
val event2 = testEvent.event!!
......@@ -434,7 +434,7 @@ class AndroidEventTest {
values.put(CalendarContract.Events.TITLE, "Without dtend/duration")
val uri = provider.insert(syncAdapterURI(CalendarContract.Events.CONTENT_URI, testAccount), values)
val testEvent = TestEvent(calendar, ContentUris.parseId(uri))
val testEvent = calendar.findById(ContentUris.parseId(uri))
try {
assertNull(testEvent.event!!.dtEnd)
} finally {
......@@ -453,7 +453,7 @@ class AndroidEventTest {
val uri = TestEvent(calendar, event).add()
assertNotNull(uri)
val testEvent = TestEvent(calendar, ContentUris.parseId(uri))
val testEvent = calendar.findById(ContentUris.parseId(uri))
try {
// read again and verify result
val event2 = testEvent.event!!
......
......@@ -58,9 +58,18 @@ class AndroidTaskListTest {
assertNotNull(uri)
// query task list
val taskList = AndroidTaskList.findByID(testAccount, provider!!, TestTaskList.Factory.FACTORY, ContentUris.parseId(uri))
val taskList = AndroidTaskList.findByID(testAccount, provider!!, TestTaskList.Factory, ContentUris.parseId(uri))
assertNotNull(taskList)
// sync URIs
assertEquals("true", taskList.taskListSyncUri().getQueryParameter(TaskContract.CALLER_IS_SYNCADAPTER))
assertEquals(testAccount.type, taskList.taskListSyncUri().getQueryParameter(TaskContract.ACCOUNT_TYPE))
assertEquals(testAccount.name, taskList.taskListSyncUri().getQueryParameter(TaskContract.ACCOUNT_NAME))
assertEquals("true", taskList.tasksSyncUri().getQueryParameter(TaskContract.CALLER_IS_SYNCADAPTER))
assertEquals(testAccount.type, taskList.tasksSyncUri().getQueryParameter(TaskContract.ACCOUNT_TYPE))
assertEquals(testAccount.name, taskList.tasksSyncUri().getQueryParameter(TaskContract.ACCOUNT_NAME))
// delete task list
assertEquals(1, taskList.delete())
}
......
......@@ -48,7 +48,7 @@ class AndroidTaskTest {
assumeNotNull(providerOrNull)
provider = providerOrNull!!
taskList = TestTaskList.findOrCreate(testAccount, provider)
taskList = TestTaskList.create(testAccount, providerOrNull)
assertNotNull("Couldn't find/create test task list", taskList)
taskListUri = ContentUris.withAppendedId(provider!!.taskListsUri(), taskList!!.id)
......@@ -78,11 +78,11 @@ class AndroidTaskTest {
assertFalse(task.isAllDay())
// add to task list
val uri = TestTask(taskList, task).add()
val uri = TestTask(taskList!!, task).add()
assertNotNull("Couldn't add task", uri)
// read and parse event from calendar provider
val testTask = TestTask(taskList, ContentUris.parseId(uri))
val testTask = taskList!!.findById(ContentUris.parseId(uri))
try {
assertNotNull("Inserted task is not here", testTask)
val task2 = testTask.task
......@@ -107,7 +107,7 @@ class AndroidTaskTest {
task.dtStart = DtStart(Date("20150102"))
task.due = Due(Date("20150101"))
TestTask(taskList, task).add()
TestTask(taskList!!, task).add()
}
@MediumTest
......@@ -121,10 +121,10 @@ class AndroidTaskTest {
task.location = "Sample location"
task.dtStart = DtStart("20150501T120000", tzVienna)
assertFalse(task.isAllDay())
val uri = TestTask(taskList, task).add()
val uri = TestTask(taskList!!, task).add()
assertNotNull(uri)
val testTask = TestTask(taskList, ContentUris.parseId(uri))
val testTask = taskList!!.findById(ContentUris.parseId(uri))
try {
// update test event in calendar
val task2 = testTask.task!!
......@@ -134,7 +134,7 @@ class AndroidTaskTest {
testTask.update(task)
// read again and verify result
val updatedTask = TestTask(taskList, ContentUris.parseId(uri)).task!!
val updatedTask = taskList!!.findById(ContentUris.parseId(uri)).task!!
assertEquals(task.summary, updatedTask.summary)
assertEquals(task.dtStart, updatedTask.dtStart)
assertEquals(task.due, updatedTask.due)
......@@ -154,10 +154,10 @@ class AndroidTaskTest {
task.dtStart = DtStart(Date("20150501"))
task.due = Due(Date("20150502"))
assertTrue(task.isAllDay())
val uri = TestTask(taskList, task).add()
val uri = TestTask(taskList!!, task).add()
assertNotNull(uri)
val testTask = TestTask(taskList, ContentUris.parseId(uri))
val testTask = taskList!!.findById(ContentUris.parseId(uri))
try {
// read again and verify result
val task2 = testTask.task!!
......@@ -176,16 +176,16 @@ class AndroidTaskTest {
@Test
fun testGetTimeZone() {
// no date/time
var t = TestTask(taskList, Task())
var t = TestTask(taskList!!, Task())
assertEquals(TimeZone.getDefault(), t.getTimeZone())
// dtstart with date (no time)
t = TestTask(taskList, Task())
t = TestTask(taskList!!, Task())
t.task!!.dtStart = DtStart("20150101")
assertEquals(TimeZone.getDefault(), t.getTimeZone())
// dtstart with time
t = TestTask(taskList, Task())
t = TestTask(taskList!!, Task())
t.task!!.dtStart = (DtStart("20150101", tzVienna))
assertEquals(tzVienna, t.getTimeZone())
}
......
......@@ -72,7 +72,7 @@ class MiscUtilsTest {
assertEquals(TimeZones.UTC_ID, MiscUtils.getTzId(DtStart(DateTime(1438607288000L))))
// DATE-TIME with time zone
assertEquals(tzVienna.getID(), MiscUtils.getTzId(DtStart(DateTime("20150101T000000", tzVienna))))
assertEquals(tzVienna.id, MiscUtils.getTzId(DtStart(DateTime("20150101T000000", tzVienna))))
}
@Test
......
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.ical4android.impl;
import android.accounts.Account;
import android.content.ContentProviderClient;
import android.content.ContentUris;
import android.content.ContentValues;
import android.net.Uri;
import android.provider.CalendarContract;
import android.util.Log;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import at.bitfire.ical4android.AndroidCalendar;
import at.bitfire.ical4android.AndroidCalendarFactory;
import at.bitfire.ical4android.CalendarStorageException;
public class TestCalendar extends AndroidCalendar<TestEvent> {
private static final String TAG = "ical4android.TestCal";
public TestCalendar(Account account, ContentProviderClient provider, long id) {
super(account, provider, TestEvent.Factory.INSTANCE, id);
}
static public TestCalendar findOrCreate(Account account, ContentProviderClient provider) throws CalendarStorageException {
List<TestCalendar> calendars = AndroidCalendar.find(account, provider, Factory.INSTANCE, null, null);
if (calendars.size() == 0) {
Log.i(TAG, "Test calendar not found, creating");
ContentValues values = new ContentValues();
values.put(CalendarContract.Calendars.NAME, "TestCalendar");
values.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "ical4android Test Calendar");
values.put(CalendarContract.Calendars.ALLOWED_REMINDERS,
CalendarContract.Reminders.METHOD_DEFAULT);
Uri uri = AndroidCalendar.create(account, provider, values);
return new TestCalendar(account, provider, ContentUris.parseId(uri));
} else
return calendars.get(0);
}
public static class Factory implements AndroidCalendarFactory<TestCalendar> {
public static final Factory INSTANCE = new Factory();
@NotNull
@Override
public TestCalendar newInstance(@NotNull Account account, @NotNull ContentProviderClient provider, long id) {
return new TestCalendar(account, provider, id);
}
}
}
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.ical4android.impl
import android.accounts.Account
import android.content.ContentProviderClient
import android.content.ContentUris
import android.content.ContentValues
import android.provider.CalendarContract
import at.bitfire.ical4android.AndroidCalendar
import at.bitfire.ical4android.AndroidCalendarFactory
class TestCalendar(
account: Account,
providerClient: ContentProviderClient,
id: Long
): AndroidCalendar<TestEvent>(account, providerClient, TestEvent.Factory, id) {
companion object {
fun findOrCreate(account: Account, provider: ContentProviderClient): TestCalendar {
val calendars = AndroidCalendar.find(account, provider, Factory, null, null)
return if (calendars.isEmpty()) {
val values = ContentValues(3)
values.put(CalendarContract.Calendars.NAME, "TestCalendar")
values.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "ical4android Test Calendar")
values.put(CalendarContract.Calendars.ALLOWED_REMINDERS,
CalendarContract.Reminders.METHOD_DEFAULT)
val uri = AndroidCalendar.create(account, provider, values)
TestCalendar(account, provider, ContentUris.parseId(uri))
} else
calendars.first()
}
}
object Factory: AndroidCalendarFactory<TestCalendar> {
override fun newInstance(account: Account, provider: ContentProviderClient, id: Long) =
TestCalendar(account, provider, id)
}
}
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.ical4android.impl;
import android.content.ContentValues;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import at.bitfire.ical4android.AndroidCalendar;
import at.bitfire.ical4android.AndroidEvent;
import at.bitfire.ical4android.AndroidEventFactory;
import at.bitfire.ical4android.Event;
public class TestEvent extends AndroidEvent {
public TestEvent(AndroidCalendar calendar, long id) {
super(calendar, id, null);
}
public TestEvent(AndroidCalendar calendar, Event event) {
super(calendar, event);
}
public static class Factory implements AndroidEventFactory<TestEvent> {
public static final Factory INSTANCE = new Factory();
@NotNull
@Override
public TestEvent newInstance(@NotNull AndroidCalendar calendar, long id, @Nullable ContentValues baseInfo) {
return new TestEvent(calendar, id);
}
@NotNull
@Override
public TestEvent newInstance(@NotNull AndroidCalendar calendar, @NotNull Event event) {
return new TestEvent(calendar, event);
}
}
}
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.ical4android.impl
import android.content.ContentValues
import at.bitfire.ical4android.AndroidCalendar
import at.bitfire.ical4android.AndroidEvent
import at.bitfire.ical4android.AndroidEventFactory
import at.bitfire.ical4android.Event
class TestEvent: AndroidEvent {
constructor(calendar: AndroidCalendar<AndroidEvent>, values: ContentValues)
: super(calendar, values)
constructor(calendar: TestCalendar, event: Event)
: super(calendar, event)
object Factory: AndroidEventFactory<TestEvent> {
override fun fromProvider(calendar: AndroidCalendar<AndroidEvent>, values: ContentValues) =
TestEvent(calendar, values)
}
}
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.ical4android.impl;
import android.content.ContentValues;
import at.bitfire.ical4android.AndroidTask;
import at.bitfire.ical4android.AndroidTaskFactory;
import at.bitfire.ical4android.AndroidTaskList;
import at.bitfire.ical4android.Task;
public class TestTask extends AndroidTask {
public TestTask(AndroidTaskList calendar, long id) {
super(calendar, id);
}
public TestTask(AndroidTaskList calendar, Task task) {
super(calendar, task);
}
public static class Factory implements AndroidTaskFactory<TestTask> {
public static final Factory FACTORY = new Factory();
@Override
public TestTask newInstance(AndroidTaskList taskList, long id, ContentValues baseInfo) {
return new TestTask(taskList, id);
}
@Override
public TestTask newInstance(AndroidTaskList taskList, Task task) {
return new TestTask(taskList, task);
}
}
}
......@@ -6,20 +6,26 @@
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.ical4android;
package at.bitfire.ical4android.impl
import org.junit.Test;
import android.content.ContentValues
import static org.junit.Assert.assertNotNull;
import at.bitfire.ical4android.AndroidTask
import at.bitfire.ical4android.AndroidTaskFactory
import at.bitfire.ical4android.AndroidTaskList
import at.bitfire.ical4android.Task
public class TestDateUtils {
class TestTask: AndroidTask {
@Test
public void testTimeZoneRegistry() {
assertNotNull(DateUtils.tzRegistry.getTimeZone("Europe/Vienna"));
constructor(taskList: AndroidTaskList<AndroidTask>, values: ContentValues)
: super(taskList, values)
// https://github.com/ical4j/ical4j/issues/207
// assertNotNull(DateUtils.tzRegistry.getTimeZone("EST"));
constructor(taskList: TestTaskList, task: Task)
: super(taskList, task)
object Factory: AndroidTaskFactory<TestTask> {
override fun fromProvider(taskList: AndroidTaskList<AndroidTask>, values: ContentValues) =
TestTask(taskList, values)
}
}
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.ical4android.impl;
import android.accounts.Account;
import android.content.ContentUris;
import android.content.ContentValues;
import android.net.Uri;
import android.util.Log;
import org.dmfs.tasks.contract.TaskContract;
import at.bitfire.ical4android.AndroidTaskList;
import at.bitfire.ical4android.AndroidTaskListFactory;
import at.bitfire.ical4android.CalendarStorageException;
import at.bitfire.ical4android.TaskProvider;
public class TestTaskList extends AndroidTaskList<TestTask> {
private static final String TAG = "ical4android.TestCal";
protected TestTaskList(Account account, TaskProvider provider, long id) {
super(account, provider, TestTask.Factory.FACTORY, id);
}
public static TestTaskList findOrCreate(Account account, TaskProvider provider) throws CalendarStorageException {
TestTaskList[] taskLists = new TestTaskList[0]; /*findAll()*/
if (taskLists.length == 0) {
Log.i(TAG, "Test calendar not found, creating");
ContentValues values = new ContentValues();