Convert test classes to Kotlin

pull/996/head
Alex Baker 4 years ago
parent b193f7b75f
commit 4042dd4ebd

@ -1,261 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.test;
import static androidx.test.InstrumentationRegistry.getTargetContext;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import android.content.res.Configuration;
import android.content.res.Resources;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.R;
/**
* Tests translations for consistency with the default values. You must extend this class and create
* it with your own values for strings and arrays.
*
* @author Tim Su <tim@todoroo.com>
*/
@RunWith(AndroidJUnit4.class)
public class TranslationTests {
/** Loop through each locale and call runnable */
private void forEachLocale(Callback<Resources> callback) {
Locale[] locales = Locale.getAvailableLocales();
for (Locale locale : locales) {
callback.apply(getResourcesForLocale(locale));
}
}
private Resources getResourcesForLocale(Locale locale) {
Resources resources = getTargetContext().getResources();
Configuration configuration = new Configuration(resources.getConfiguration());
configuration.locale = locale;
return new Resources(resources.getAssets(), resources.getDisplayMetrics(), configuration);
}
/** Internal test of format string parser */
@Test
public void testFormatStringParser() {
String s = "abc";
FormatStringData data = new FormatStringData(s);
assertEquals(s, data.string);
assertEquals(0, data.characters.length);
s = "abc %s def";
data = new FormatStringData(s);
assertEquals(1, data.characters.length);
assertEquals('s', data.characters[0]);
s = "abc %%s def %d";
data = new FormatStringData(s);
assertEquals(2, data.characters.length);
assertEquals('%', data.characters[0]);
assertEquals('d', data.characters[1]);
assertTrue(data.toString(), data.toString().contains("[%"));
assertTrue(data.toString(), data.toString().contains("d]"));
assertTrue(data.toString(), data.toString().contains(s));
assertTrue(data.matches(new FormatStringData("espanol %% und %d si")));
assertFalse(data.matches(new FormatStringData("ingles %d ja %% pon")));
s = "% abc %";
data = new FormatStringData(s);
assertEquals(2, data.characters.length);
assertEquals(' ', data.characters[0]);
assertEquals('\0', data.characters[1]);
}
/**
* Test that the format specifiers in translations match exactly the translations in the default
* text
*/
@Test
public void testFormatStringsMatch() {
final Resources resources = getTargetContext().getResources();
final int[] strings = getResourceIds(R.string.class);
final FormatStringData[] formatStrings = new FormatStringData[strings.length];
final StringBuilder failures = new StringBuilder();
for (int i = 0; i < strings.length; i++) {
try {
String string = resources.getString(strings[i]);
formatStrings[i] = new FormatStringData(string);
} catch (Exception e) {
String name = resources.getResourceName(strings[i]);
failures.append(String.format("error opening %s: %s\n", name, e.getMessage()));
}
}
forEachLocale(
r -> {
Locale locale = r.getConfiguration().locale;
for (int i = 0; i < strings.length; i++) {
try {
switch (strings[i]) {
case R.string.abc_shareactionprovider_share_with_application:
continue;
}
String string = r.getString(strings[i]);
FormatStringData newFS = new FormatStringData(string);
if (!newFS.matches(formatStrings[i])) {
String name = r.getResourceName(strings[i]);
failures.append(
String.format(
"%s (%s): %s != %s\n", name, locale.toString(), newFS, formatStrings[i]));
}
} catch (Exception e) {
String name = r.getResourceName(strings[i]);
failures.append(
String.format(
"%s: error opening %s: %s\n", locale.toString(), name, e.getMessage()));
}
}
});
assertEquals(failures.toString(), 0, errorCount(failures));
}
/** check if string contains contains substrings */
private void contains(Resources r, int resource, StringBuilder failures, String expected) {
String translation = r.getString(resource);
if (!translation.contains(expected)) {
Locale locale = r.getConfiguration().locale;
String name = r.getResourceName(resource);
failures.append(
String.format("%s: %s did not contain: %s\n", locale.toString(), name, expected));
}
}
/** Test dollar sign resources */
@Test
public void testSpecialStringsMatch() {
final StringBuilder failures = new StringBuilder();
forEachLocale(
r -> {
contains(r, R.string.CFC_tag_text, failures, "?");
contains(r, R.string.CFC_title_contains_text, failures, "?");
contains(r, R.string.CFC_dueBefore_text, failures, "?");
contains(r, R.string.CFC_tag_contains_text, failures, "?");
contains(r, R.string.CFC_gtasks_list_text, failures, "?");
});
assertEquals(failures.toString(), 0, failures.toString().replaceAll("[^\n]", "").length());
}
/** Count newlines */
private int errorCount(StringBuilder failures) {
int count = 0;
int pos = -1;
while (true) {
pos = failures.indexOf("\n", pos + 1);
if (pos == -1) {
return count;
}
count++;
}
}
/** @return an array of all string resource id's */
private int[] getResourceIds(Class<?> resources) {
Field[] fields = resources.getDeclaredFields();
List<Integer> ids = new ArrayList<>(fields.length);
for (Field field : fields) {
try {
ids.add(field.getInt(null));
} catch (Exception e) {
// not a field we care about
}
}
int[] idsAsIntArray = new int[ids.size()];
for (int i = 0; i < ids.size(); i++) {
idsAsIntArray[i] = ids.get(i);
}
return idsAsIntArray;
}
public interface Callback<T> {
void apply(T entry);
}
private static final class FormatStringData {
private static final char[] scratch = new char[10];
/** format characters */
final char[] characters;
/** the original string */
final String string;
FormatStringData(String string) {
this.string = string;
int pos = -1;
int count = 0;
while (true) {
pos = string.indexOf('%', ++pos);
if (pos++ == -1) {
break;
}
if (pos >= string.length()) {
scratch[count++] = '\0';
} else {
scratch[count++] = string.charAt(pos);
}
}
characters = new char[count];
for (int i = 0; i < count; i++) {
characters[i] = scratch[i];
}
}
/** test that the characters match */
boolean matches(FormatStringData other) {
if (characters.length != other.characters.length) {
return false;
}
outer:
for (int i = 0; i < characters.length; i++) {
if (Character.isDigit(characters[i])) {
for (int j = 0; j < other.characters.length; j++) {
if (characters[i] == other.characters[j]) {
break outer;
}
}
return false;
} else if (characters[i] != other.characters[i]) {
return false;
}
}
return true;
}
@Override
public String toString() {
StringBuilder value = new StringBuilder("[");
for (int i = 0; i < characters.length; i++) {
value.append(characters[i]);
if (i < characters.length - 1) {
value.append(',');
}
}
value.append("]: '").append(string).append('\'');
return value.toString();
}
}
}

@ -0,0 +1,233 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.test
import android.content.res.Configuration
import android.content.res.Resources
import androidx.test.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Assert.*
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.Callback
import org.tasks.R.string
import java.util.*
/**
* Tests translations for consistency with the default values. You must extend this class and create
* it with your own values for strings and arrays.
*
* @author Tim Su <tim></tim>@todoroo.com>
*/
@RunWith(AndroidJUnit4::class)
class TranslationTests {
/** Loop through each locale and call runnable */
private fun forEachLocale(callback: Callback<Resources>) {
val locales = Locale.getAvailableLocales()
for (locale in locales) {
callback.call(getResourcesForLocale(locale))
}
}
private fun getResourcesForLocale(locale: Locale): Resources {
val resources = InstrumentationRegistry.getTargetContext().resources
val configuration = Configuration(resources.configuration)
configuration.locale = locale
return Resources(resources.assets, resources.displayMetrics, configuration)
}
/** Internal test of format string parser */
@Test
fun testFormatStringParser() {
var s = "abc"
var data = FormatStringData(s)
assertEquals(s, data.string)
assertEquals(0, data.characters.size)
s = "abc %s def"
data = FormatStringData(s)
assertEquals(1, data.characters.size)
assertEquals('s', data.characters[0])
s = "abc %%s def %d"
data = FormatStringData(s)
assertEquals(2, data.characters.size)
assertEquals('%', data.characters[0])
assertEquals('d', data.characters[1])
assertTrue(data.toString(), data.toString().contains("[%"))
assertTrue(data.toString(), data.toString().contains("d]"))
assertTrue(data.toString(), data.toString().contains(s))
assertTrue(data.matches(FormatStringData("espanol %% und %d si")))
assertFalse(data.matches(FormatStringData("ingles %d ja %% pon")))
s = "% abc %"
data = FormatStringData(s)
assertEquals(2, data.characters.size)
assertEquals(' ', data.characters[0])
assertEquals('\u0000', data.characters[1])
}
/**
* Test that the format specifiers in translations match exactly the translations in the default
* text
*/
@Test
fun testFormatStringsMatch() {
val resources = InstrumentationRegistry.getTargetContext().resources
val strings = getResourceIds(string::class.java)
val formatStrings = arrayOfNulls<FormatStringData>(strings.size)
val failures = StringBuilder()
for (i in strings.indices) {
try {
val string = resources.getString(strings[i])
formatStrings[i] = FormatStringData(string)
} catch (e: Exception) {
val name = resources.getResourceName(strings[i])
failures.append(String.format("error opening %s: %s\n", name, e.message))
}
}
forEachLocale(
Callback<Resources> { r: Resources ->
val locale = r.configuration.locale
for (i in strings.indices) {
try {
if (strings[i] == string.abc_shareactionprovider_share_with_application) {
continue
}
val string = r.getString(strings[i])
val newFS = FormatStringData(string)
if (!newFS.matches(formatStrings[i])) {
val name = r.getResourceName(strings[i])
failures.append(String.format(
"%s (%s): %s != %s\n", name, locale.toString(), newFS, formatStrings[i]))
}
} catch (e: Exception) {
val name = r.getResourceName(strings[i])
failures.append(String.format(
"%s: error opening %s: %s\n", locale.toString(), name, e.message))
}
}
})
assertEquals(failures.toString(), 0, errorCount(failures))
}
/** check if string contains contains substrings */
private fun contains(r: Resources, resource: Int, failures: StringBuilder, expected: String) {
val translation = r.getString(resource)
if (!translation.contains(expected)) {
val locale = r.configuration.locale
val name = r.getResourceName(resource)
failures.append(String.format("%s: %s did not contain: %s\n", locale.toString(), name, expected))
}
}
/** Test dollar sign resources */
@Test
fun testSpecialStringsMatch() {
val failures = StringBuilder()
forEachLocale(
Callback<Resources> { r: Resources ->
contains(r, string.CFC_tag_text, failures, "?")
contains(r, string.CFC_title_contains_text, failures, "?")
contains(r, string.CFC_dueBefore_text, failures, "?")
contains(r, string.CFC_tag_contains_text, failures, "?")
contains(r, string.CFC_gtasks_list_text, failures, "?")
})
assertEquals(failures.toString(), 0, failures.toString().replace("[^\n]".toRegex(), "").length)
}
/** Count newlines */
private fun errorCount(failures: StringBuilder): Int {
var count = 0
var pos = -1
while (true) {
pos = failures.indexOf("\n", pos + 1)
if (pos == -1) {
return count
}
count++
}
}
/** @return an array of all string resource id's
*/
private fun getResourceIds(resources: Class<*>): IntArray {
val fields = resources.declaredFields
val ids: MutableList<Int> = ArrayList(fields.size)
for (field in fields) {
try {
ids.add(field.getInt(null))
} catch (e: Exception) {
// not a field we care about
}
}
val idsAsIntArray = IntArray(ids.size)
for (i in ids.indices) {
idsAsIntArray[i] = ids[i]
}
return idsAsIntArray
}
private class FormatStringData internal constructor(
/** the original string */
val string: String) {
/** format characters */
val characters: CharArray
/** test that the characters match */
fun matches(other: FormatStringData?): Boolean {
if (characters.size != other!!.characters.size) {
return false
}
outer@ for (i in characters.indices) {
if (Character.isDigit(characters[i])) {
for (j in other.characters.indices) {
if (characters[i] == other.characters[j]) {
break@outer
}
}
return false
} else if (characters[i] != other.characters[i]) {
return false
}
}
return true
}
override fun toString(): String {
val value = StringBuilder("[")
for (i in characters.indices) {
value.append(characters[i])
if (i < characters.size - 1) {
value.append(',')
}
}
value.append("]: '").append(string).append('\'')
return value.toString()
}
companion object {
private val scratch = CharArray(10)
}
init {
var pos = -1
var count = 0
while (true) {
pos = string.indexOf('%', ++pos)
if (pos++ == -1) {
break
}
if (pos >= string.length) {
scratch[count++] = '\u0000'
} else {
scratch[count++] = string[pos]
}
}
characters = CharArray(count)
for (i in 0 until count) {
characters[i] = scratch[i]
}
}
}
}

@ -1,440 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.utility;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.todoroo.andlib.utility.DateUtilities.getDateString;
import static com.todoroo.andlib.utility.DateUtilities.getTimeString;
import static com.todoroo.andlib.utility.DateUtilities.getWeekday;
import static com.todoroo.andlib.utility.DateUtilities.getWeekdayShort;
import static junit.framework.Assert.assertEquals;
import static org.tasks.Freeze.freezeAt;
import static org.tasks.date.DateTimeUtils.newDate;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Locale;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.Snippet;
import org.tasks.time.DateTime;
import org.threeten.bp.format.FormatStyle;
@RunWith(AndroidJUnit4.class)
public class DateUtilitiesTest {
@After
public void after() {
DateUtilities.is24HourOverride = null;
}
@Test
public void testGet24HourTime() {
DateUtilities.is24HourOverride = true;
assertEquals("09:05", getTimeString(null, new DateTime(2014, 1, 4, 9, 5, 36)));
assertEquals("13:00", getTimeString(null, new DateTime(2014, 1, 4, 13, 0, 1)));
}
@Test
public void testGetTime() {
DateUtilities.is24HourOverride = false;
assertEquals("9:05 AM", getTimeString(null, new DateTime(2014, 1, 4, 9, 5, 36)));
assertEquals("1:05 PM", getTimeString(null, new DateTime(2014, 1, 4, 13, 5, 36)));
}
@Test
public void testGetTimeWithNoMinutes() {
DateUtilities.is24HourOverride = false;
assertEquals("1 PM", getTimeString(null, new DateTime(2014, 1, 4, 13, 0, 59))); // derp?
}
@Test
public void testGetDateStringWithYear() {
assertEquals("Jan 4, 2014", getDateString(getApplicationContext(), new DateTime(2014, 1, 4, 0, 0, 0)));
}
@Test
public void testGetDateStringHidingYear() {
freezeAt(newDate(2014, 2, 1))
.thawAfter(
new Snippet() {
{
assertEquals("Jan 1", getDateString(getApplicationContext(), new DateTime(2014, 1, 1)));
}
});
}
@Test
public void testGetDateStringWithDifferentYear() {
freezeAt(newDate(2013, 12, 1))
.thawAfter(
new Snippet() {
{
assertEquals("Jan 1, 2014", getDateString(getApplicationContext(),new DateTime(2014, 1, 1, 0, 0, 0)));
}
});
}
@Test
public void testGetWeekdayLongString() {
assertEquals("Sunday", getWeekday(newDate(2013, 12, 29), Locale.US));
assertEquals("Monday", getWeekday(newDate(2013, 12, 30), Locale.US));
assertEquals("Tuesday", getWeekday(newDate(2013, 12, 31), Locale.US));
assertEquals("Wednesday", getWeekday(newDate(2014, 1, 1), Locale.US));
assertEquals("Thursday", getWeekday(newDate(2014, 1, 2), Locale.US));
assertEquals("Friday", getWeekday(newDate(2014, 1, 3), Locale.US));
assertEquals("Saturday", getWeekday(newDate(2014, 1, 4), Locale.US));
}
@Test
public void testGetWeekdayShortString() {
assertEquals("Sun", getWeekdayShort(newDate(2013, 12, 29), Locale.US));
assertEquals("Mon", getWeekdayShort(newDate(2013, 12, 30), Locale.US));
assertEquals("Tue", getWeekdayShort(newDate(2013, 12, 31), Locale.US));
assertEquals("Wed", getWeekdayShort(newDate(2014, 1, 1), Locale.US));
assertEquals("Thu", getWeekdayShort(newDate(2014, 1, 2), Locale.US));
assertEquals("Fri", getWeekdayShort(newDate(2014, 1, 3), Locale.US));
assertEquals("Sat", getWeekdayShort(newDate(2014, 1, 4), Locale.US));
}
@Test
public void getRelativeFullDate() {
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
assertEquals(
"Sunday, January 14",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.US,
FormatStyle.FULL)));
}
@Test
public void getRelativeFullDateWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
assertEquals(
"Sunday, January 14, 2018",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.US,
FormatStyle.FULL)));
}
@Test
public void getRelativeFullDateTime() {
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
assertEquals(
"Sunday, January 14 1:43 PM",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 43, 1).getMillis(),
Locale.US,
FormatStyle.FULL)));
}
@Test
public void getRelativeFullDateTimeWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
assertEquals(
"Sunday, January 14, 2018 11:50 AM",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 11, 50, 1).getMillis(),
Locale.US,
FormatStyle.FULL)));
}
@Test
public void germanDateNoYear() {
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
Assert.assertEquals(
"Sonntag, 14. Januar",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.GERMAN,
FormatStyle.FULL)));
}
@Test
public void germanDateWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"Sonntag, 14. Januar 2018",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.GERMAN,
FormatStyle.FULL)));
}
@Test
public void koreanDateNoYear() {
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
Assert.assertEquals(
"1월 14일 일요일",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.KOREAN,
FormatStyle.FULL)));
}
@Test
public void koreanDateWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"2018년 1월 14일 일요일",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.KOREAN,
FormatStyle.FULL)));
}
@Test
public void japaneseDateNoYear() {
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
Assert.assertEquals(
"1月14日日曜日",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.JAPANESE,
FormatStyle.FULL)));
}
@Test
public void japaneseDateWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"2018年1月14日日曜日",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.JAPANESE,
FormatStyle.FULL)));
}
@Test
public void chineseDateNoYear() {
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
Assert.assertEquals(
"1月14日星期日",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.CHINESE,
FormatStyle.FULL)));
}
@Test
public void chineseDateWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"2018年1月14日星期日",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.CHINESE,
FormatStyle.FULL)));
}
@Test
public void chineseDateTimeNoYear() {
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
Assert.assertEquals(
"1月14日星期日 上午11:53",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 11, 53, 1).getMillis(),
Locale.CHINESE,
FormatStyle.FULL)));
}
@Test
public void chineseDateTimeWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"2018年1月14日星期日 下午1:45",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 45, 1).getMillis(),
Locale.CHINESE,
FormatStyle.FULL)));
}
@Test
public void frenchDateTimeWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"dimanche 14 janvier 2018 13:45",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 45, 1).getMillis(),
Locale.FRENCH,
FormatStyle.FULL)));
}
@Test
public void indiaDateTimeWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"रविवार, 14 जनवरी 2018 1:45 pm",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 45, 1).getMillis(),
Locale.forLanguageTag("hi-IN"),
FormatStyle.FULL)));
}
@Test
public void russiaDateTimeNoYear() {
freezeAt(new DateTime(2018, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"воскресенье, 14 января 13:45",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 45, 1).getMillis(),
Locale.forLanguageTag("ru"),
FormatStyle.FULL)));
}
@Test
public void russiaDateTimeWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"воскресенье, 14 января 2018 г. 13:45",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 45, 1).getMillis(),
Locale.forLanguageTag("ru"),
FormatStyle.FULL)));
}
@Test
public void brazilDateTimeNoYear() {
freezeAt(new DateTime(2018, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"domingo, 14 de janeiro 13:45",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 45, 1).getMillis(),
Locale.forLanguageTag("pt-br"),
FormatStyle.FULL)));
}
@Test
public void brazilDateTimeWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"domingo, 14 de janeiro de 2018 13:45",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 45, 1).getMillis(),
Locale.forLanguageTag("pt-br"),
FormatStyle.FULL)));
}
@Test
public void spainDateTimeNoYear() {
freezeAt(new DateTime(2018, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"domingo, 14 de enero 13:45",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 45, 1).getMillis(),
Locale.forLanguageTag("es"),
FormatStyle.FULL)));
}
@Test
public void spainDateTimeWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"domingo, 14 de enero de 2018 13:45",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 45, 1).getMillis(),
Locale.forLanguageTag("es"),
FormatStyle.FULL)));
}
@Test
public void hebrewDateTimeNoYear() {
freezeAt(new DateTime(2018, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"יום ראשון, 14 בינואר 13:45",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 45, 1).getMillis(),
Locale.forLanguageTag("iw"),
FormatStyle.FULL)));
}
@Test
public void hebrewDateTimeWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"יום ראשון, 14 בינואר 2018 13:45",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 45, 1).getMillis(),
Locale.forLanguageTag("iw"),
FormatStyle.FULL)));
}
}

@ -0,0 +1,399 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.utility
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.Freeze.Companion.freezeAt
import org.tasks.date.DateTimeUtils
import org.tasks.time.DateTime
import org.threeten.bp.format.FormatStyle
import java.util.*
@RunWith(AndroidJUnit4::class)
class DateUtilitiesTest {
@After
fun after() {
DateUtilities.is24HourOverride = null
}
@Test
fun testGet24HourTime() {
DateUtilities.is24HourOverride = true
assertEquals("09:05", DateUtilities.getTimeString(null, DateTime(2014, 1, 4, 9, 5, 36)))
assertEquals("13:00", DateUtilities.getTimeString(null, DateTime(2014, 1, 4, 13, 0, 1)))
}
@Test
fun testGetTime() {
DateUtilities.is24HourOverride = false
assertEquals("9:05 AM", DateUtilities.getTimeString(null, DateTime(2014, 1, 4, 9, 5, 36)))
assertEquals("1:05 PM", DateUtilities.getTimeString(null, DateTime(2014, 1, 4, 13, 5, 36)))
}
@Test
fun testGetTimeWithNoMinutes() {
DateUtilities.is24HourOverride = false
assertEquals("1 PM", DateUtilities.getTimeString(null, DateTime(2014, 1, 4, 13, 0, 59))) // derp?
}
@Test
fun testGetDateStringWithYear() {
assertEquals("Jan 4, 2014", DateUtilities.getDateString(ApplicationProvider.getApplicationContext(), DateTime(2014, 1, 4, 0, 0, 0)))
}
@Test
fun testGetDateStringHidingYear() {
freezeAt(DateTimeUtils.newDate(2014, 2, 1)) {
assertEquals("Jan 1", DateUtilities.getDateString(ApplicationProvider.getApplicationContext(), DateTime(2014, 1, 1)))
}
}
@Test
fun testGetDateStringWithDifferentYear() {
freezeAt(DateTimeUtils.newDate(2013, 12, 1)) {
assertEquals("Jan 1, 2014", DateUtilities.getDateString(ApplicationProvider.getApplicationContext(), DateTime(2014, 1, 1, 0, 0, 0)))
}
}
@Test
fun testGetWeekdayLongString() {
assertEquals("Sunday", DateUtilities.getWeekday(DateTimeUtils.newDate(2013, 12, 29), Locale.US))
assertEquals("Monday", DateUtilities.getWeekday(DateTimeUtils.newDate(2013, 12, 30), Locale.US))
assertEquals("Tuesday", DateUtilities.getWeekday(DateTimeUtils.newDate(2013, 12, 31), Locale.US))
assertEquals("Wednesday", DateUtilities.getWeekday(DateTimeUtils.newDate(2014, 1, 1), Locale.US))
assertEquals("Thursday", DateUtilities.getWeekday(DateTimeUtils.newDate(2014, 1, 2), Locale.US))
assertEquals("Friday", DateUtilities.getWeekday(DateTimeUtils.newDate(2014, 1, 3), Locale.US))
assertEquals("Saturday", DateUtilities.getWeekday(DateTimeUtils.newDate(2014, 1, 4), Locale.US))
}
@Test
fun testGetWeekdayShortString() {
assertEquals("Sun", DateUtilities.getWeekdayShort(DateTimeUtils.newDate(2013, 12, 29), Locale.US))
assertEquals("Mon", DateUtilities.getWeekdayShort(DateTimeUtils.newDate(2013, 12, 30), Locale.US))
assertEquals("Tue", DateUtilities.getWeekdayShort(DateTimeUtils.newDate(2013, 12, 31), Locale.US))
assertEquals("Wed", DateUtilities.getWeekdayShort(DateTimeUtils.newDate(2014, 1, 1), Locale.US))
assertEquals("Thu", DateUtilities.getWeekdayShort(DateTimeUtils.newDate(2014, 1, 2), Locale.US))
assertEquals("Fri", DateUtilities.getWeekdayShort(DateTimeUtils.newDate(2014, 1, 3), Locale.US))
assertEquals("Sat", DateUtilities.getWeekdayShort(DateTimeUtils.newDate(2014, 1, 4), Locale.US))
}
@Test
fun getRelativeFullDate() {
freezeAt(DateTime(2018, 1, 1)) {
assertEquals(
"Sunday, January 14",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14).millis,
Locale.US,
FormatStyle.FULL))
}
}
@Test
fun getRelativeFullDateWithYear() {
freezeAt(DateTime(2017, 12, 12)) {
assertEquals(
"Sunday, January 14, 2018",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14).millis,
Locale.US,
FormatStyle.FULL))
}
}
@Test
fun getRelativeFullDateTime() {
freezeAt(DateTime(2018, 1, 1)) {
assertEquals(
"Sunday, January 14 1:43 PM",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 13, 43, 1).millis,
Locale.US,
FormatStyle.FULL))
}
}
@Test
fun getRelativeFullDateTimeWithYear() {
freezeAt(DateTime(2017, 12, 12)) {
assertEquals(
"Sunday, January 14, 2018 11:50 AM",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 11, 50, 1).millis,
Locale.US,
FormatStyle.FULL))
}
}
@Test
fun germanDateNoYear() {
freezeAt(DateTime(2018, 1, 1)) {
assertEquals(
"Sonntag, 14. Januar",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14).millis,
Locale.GERMAN,
FormatStyle.FULL))
}
}
@Test
fun germanDateWithYear() {
freezeAt(DateTime(2017, 12, 12)) {
assertEquals(
"Sonntag, 14. Januar 2018",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14).millis,
Locale.GERMAN,
FormatStyle.FULL))
}
}
@Test
fun koreanDateNoYear() {
freezeAt(DateTime(2018, 1, 1)) {
assertEquals(
"1월 14일 일요일",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14).millis,
Locale.KOREAN,
FormatStyle.FULL))
}
}
@Test
fun koreanDateWithYear() {
freezeAt(DateTime(2017, 12, 12)) {
assertEquals(
"2018년 1월 14일 일요일",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14).millis,
Locale.KOREAN,
FormatStyle.FULL))
}
}
@Test
fun japaneseDateNoYear() {
freezeAt(DateTime(2018, 1, 1)) {
assertEquals(
"1月14日日曜日",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14).millis,
Locale.JAPANESE,
FormatStyle.FULL))
}
}
@Test
fun japaneseDateWithYear() {
freezeAt(DateTime(2017, 12, 12)) {
assertEquals(
"2018年1月14日日曜日",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14).millis,
Locale.JAPANESE,
FormatStyle.FULL))
}
}
@Test
fun chineseDateNoYear() {
freezeAt(DateTime(2018, 1, 1)) {
assertEquals(
"1月14日星期日",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14).millis,
Locale.CHINESE,
FormatStyle.FULL))
}
}
@Test
fun chineseDateWithYear() {
freezeAt(DateTime(2017, 12, 12)) {
assertEquals(
"2018年1月14日星期日",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14).millis,
Locale.CHINESE,
FormatStyle.FULL))
}
}
@Test
fun chineseDateTimeNoYear() {
freezeAt(DateTime(2018, 1, 1)) {
assertEquals(
"1月14日星期日 上午11:53",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 11, 53, 1).millis,
Locale.CHINESE,
FormatStyle.FULL))
}
}
@Test
fun chineseDateTimeWithYear() {
freezeAt(DateTime(2017, 12, 12)) {
assertEquals(
"2018年1月14日星期日 下午1:45",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 13, 45, 1).millis,
Locale.CHINESE,
FormatStyle.FULL))
}
}
@Test
fun frenchDateTimeWithYear() {
freezeAt(DateTime(2017, 12, 12)) {
assertEquals(
"dimanche 14 janvier 2018 13:45",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 13, 45, 1).millis,
Locale.FRENCH,
FormatStyle.FULL))
}
}
@Test
fun indiaDateTimeWithYear() {
freezeAt(DateTime(2017, 12, 12)) {
assertEquals(
"रविवार, 14 जनवरी 2018 1:45 pm",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 13, 45, 1).millis,
Locale.forLanguageTag("hi-IN"),
FormatStyle.FULL))
}
}
@Test
fun russiaDateTimeNoYear() {
freezeAt(DateTime(2018, 12, 12)) {
assertEquals(
"воскресенье, 14 января 13:45",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 13, 45, 1).millis,
Locale.forLanguageTag("ru"),
FormatStyle.FULL))
}
}
@Test
fun russiaDateTimeWithYear() {
freezeAt(DateTime(2017, 12, 12)) {
assertEquals(
"воскресенье, 14 января 2018 г. 13:45",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 13, 45, 1).millis,
Locale.forLanguageTag("ru"),
FormatStyle.FULL))
}
}
@Test
fun brazilDateTimeNoYear() {
freezeAt(DateTime(2018, 12, 12)) {
assertEquals(
"domingo, 14 de janeiro 13:45",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 13, 45, 1).millis,
Locale.forLanguageTag("pt-br"),
FormatStyle.FULL))
}
}
@Test
fun brazilDateTimeWithYear() {
freezeAt(DateTime(2017, 12, 12)) {
assertEquals(
"domingo, 14 de janeiro de 2018 13:45",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 13, 45, 1).millis,
Locale.forLanguageTag("pt-br"),
FormatStyle.FULL))
}
}
@Test
fun spainDateTimeNoYear() {
freezeAt(DateTime(2018, 12, 12)) {
assertEquals(
"domingo, 14 de enero 13:45",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 13, 45, 1).millis,
Locale.forLanguageTag("es"),
FormatStyle.FULL))
}
}
@Test
fun spainDateTimeWithYear() {
freezeAt(DateTime(2017, 12, 12)) {
assertEquals(
"domingo, 14 de enero de 2018 13:45",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 13, 45, 1).millis,
Locale.forLanguageTag("es"),
FormatStyle.FULL))
}
}
@Test
fun hebrewDateTimeNoYear() {
freezeAt(DateTime(2018, 12, 12)) {
assertEquals(
"יום ראשון, 14 בינואר 13:45",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 13, 45, 1).millis,
Locale.forLanguageTag("iw"),
FormatStyle.FULL))
}
}
@Test
fun hebrewDateTimeWithYear() {
freezeAt(DateTime(2017, 12, 12)) {
assertEquals(
"יום ראשון, 14 בינואר 2018 13:45",
DateUtilities.getRelativeDateTime(
ApplicationProvider.getApplicationContext(),
DateTime(2018, 1, 14, 13, 45, 1).millis,
Locale.forLanguageTag("iw"),
FormatStyle.FULL))
}
}
}

@ -1,82 +0,0 @@
package com.todoroo.andlib.utility;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.todoroo.andlib.utility.DateUtilities.getRelativeDay;
import static junit.framework.Assert.assertEquals;
import static org.tasks.Freeze.freezeAt;
import static org.tasks.Freeze.thaw;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Locale;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.time.DateTime;
import org.threeten.bp.format.FormatStyle;
@RunWith(AndroidJUnit4.class)
public class RelativeDayTest {
private static final DateTime now = new DateTime(2013, 12, 31, 11, 9, 42, 357);
private static Locale defaultLocale;
@Before
public void setUp() {
defaultLocale = Locale.getDefault();
Locale.setDefault(Locale.US);
freezeAt(now);
}
@After
public void tearDown() {
Locale.setDefault(defaultLocale);
thaw();
}
@Test
public void testRelativeDayIsToday() {
checkRelativeDay(new DateTime(), "Today", "Today");
}
@Test
public void testRelativeDayIsTomorrow() {
checkRelativeDay(new DateTime().plusDays(1), "Tomorrow", "Tmrw");
}
@Test
public void testRelativeDayIsYesterday() {
checkRelativeDay(new DateTime().minusDays(1), "Yesterday", "Yest");
}
@Test
public void testRelativeDayTwo() {
checkRelativeDay(new DateTime().minusDays(2), "Sunday", "Sun");
checkRelativeDay(new DateTime().plusDays(2), "Thursday", "Thu");
}
@Test
public void testRelativeDaySix() {
checkRelativeDay(new DateTime().minusDays(6), "Wednesday", "Wed");
checkRelativeDay(new DateTime().plusDays(6), "Monday", "Mon");
}
@Test
public void testRelativeDayOneWeek() {
checkRelativeDay(new DateTime().minusDays(7), "December 24", "Dec 24");
}
@Test
public void testRelativeDayOneWeekNextYear() {
checkRelativeDay(new DateTime().plusDays(7), "January 7, 2014", "Jan 7, 2014");
}
private void checkRelativeDay(DateTime now, String full, String abbreviated) {
assertEquals(
full,
getRelativeDay(getApplicationContext(), now.getMillis(), Locale.US, FormatStyle.LONG));
assertEquals(
abbreviated,
getRelativeDay(getApplicationContext(), now.getMillis(), Locale.US, FormatStyle.MEDIUM));
}
}

@ -0,0 +1,78 @@
package com.todoroo.andlib.utility
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.Freeze
import org.tasks.time.DateTime
import org.threeten.bp.format.FormatStyle
import java.util.*
@RunWith(AndroidJUnit4::class)
class RelativeDayTest {
private lateinit var defaultLocale: Locale
private val now = DateTime(2013, 12, 31, 11, 9, 42, 357)
@Before
fun setUp() {
defaultLocale = Locale.getDefault()
Locale.setDefault(Locale.US)
Freeze.freezeAt(now)
}
@After
fun tearDown() {
Locale.setDefault(defaultLocale)
Freeze.thaw()
}
@Test
fun testRelativeDayIsToday() {
checkRelativeDay(DateTime(), "Today", "Today")
}
@Test
fun testRelativeDayIsTomorrow() {
checkRelativeDay(DateTime().plusDays(1), "Tomorrow", "Tmrw")
}
@Test
fun testRelativeDayIsYesterday() {
checkRelativeDay(DateTime().minusDays(1), "Yesterday", "Yest")
}
@Test
fun testRelativeDayTwo() {
checkRelativeDay(DateTime().minusDays(2), "Sunday", "Sun")
checkRelativeDay(DateTime().plusDays(2), "Thursday", "Thu")
}
@Test
fun testRelativeDaySix() {
checkRelativeDay(DateTime().minusDays(6), "Wednesday", "Wed")
checkRelativeDay(DateTime().plusDays(6), "Monday", "Mon")
}
@Test
fun testRelativeDayOneWeek() {
checkRelativeDay(DateTime().minusDays(7), "December 24", "Dec 24")
}
@Test
fun testRelativeDayOneWeekNextYear() {
checkRelativeDay(DateTime().plusDays(7), "January 7, 2014", "Jan 7, 2014")
}
private fun checkRelativeDay(now: DateTime, full: String, abbreviated: String) {
assertEquals(
full,
DateUtilities.getRelativeDay(ApplicationProvider.getApplicationContext(), now.millis, Locale.US, FormatStyle.LONG))
assertEquals(
abbreviated,
DateUtilities.getRelativeDay(ApplicationProvider.getApplicationContext(), now.millis, Locale.US, FormatStyle.MEDIUM))
}
}

@ -1,82 +0,0 @@
package com.todoroo.astrid.alarms;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.tasks.makers.TaskMaker.REMINDER_LAST;
import static org.tasks.makers.TaskMaker.newTask;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import javax.inject.Inject;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.tasks.data.Alarm;
import org.tasks.data.AlarmDao;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
import org.tasks.jobs.AlarmEntry;
import org.tasks.jobs.NotificationQueue;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class AlarmJobServiceTest extends InjectingTestCase {
@Inject AlarmDao alarmDao;
@Inject TaskDao taskDao;
private AlarmService alarmService;
private NotificationQueue jobs;
@Before
public void before() {
jobs = mock(NotificationQueue.class);
alarmService = new AlarmService(alarmDao, jobs);
}
@After
public void after() {
verifyNoMoreInteractions(jobs);
}
@Test
public void scheduleAlarm() {
Task task = newTask();
taskDao.createNew(task);
DateTime alarmTime = new DateTime(2017, 9, 24, 19, 57);
Alarm alarm = new Alarm(task.getId(), alarmTime.getMillis());
alarm.setId(alarmDao.insert(alarm));
alarmService.scheduleAllAlarms();
InOrder order = inOrder(jobs);
order.verify(jobs).add(new AlarmEntry(alarm));
}
@Test
public void ignoreStaleAlarm() {
DateTime alarmTime = new DateTime(2017, 9, 24, 19, 57);
Task task = newTask(with(REMINDER_LAST, alarmTime.endOfMinute()));
taskDao.createNew(task);
alarmDao.insert(new Alarm(task.getId(), alarmTime.getMillis()));
alarmService.scheduleAllAlarms();
verifyNoMoreInteractions(jobs);
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
}

@ -0,0 +1,62 @@
package com.todoroo.astrid.alarms
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.natpryce.makeiteasy.MakeItEasy.with
import com.todoroo.astrid.dao.TaskDao
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
import org.tasks.data.Alarm
import org.tasks.data.AlarmDao
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.jobs.AlarmEntry
import org.tasks.jobs.NotificationQueue
import org.tasks.makers.TaskMaker.REMINDER_LAST
import org.tasks.makers.TaskMaker.newTask
import org.tasks.time.DateTime
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class AlarmJobServiceTest : InjectingTestCase() {
@Inject lateinit var alarmDao: AlarmDao
@Inject lateinit var taskDao: TaskDao
lateinit var alarmService: AlarmService
lateinit var jobs: NotificationQueue
@Before
fun before() {
jobs = Mockito.mock(NotificationQueue::class.java)
alarmService = AlarmService(alarmDao, jobs)
}
@After
fun after() {
Mockito.verifyNoMoreInteractions(jobs)
}
@Test
fun scheduleAlarm() {
val task = newTask()
taskDao.createNew(task)
val alarmTime = DateTime(2017, 9, 24, 19, 57)
val alarm = Alarm(task.getId(), alarmTime.millis)
alarm.id = alarmDao.insert(alarm)
alarmService.scheduleAllAlarms()
Mockito.verify(jobs).add(AlarmEntry(alarm))
}
@Test
fun ignoreStaleAlarm() {
val alarmTime = DateTime(2017, 9, 24, 19, 57)
val task = newTask(with(REMINDER_LAST, alarmTime.endOfMinute()))
taskDao.createNew(task)
alarmDao.insert(Alarm(task.getId(), alarmTime.millis))
alarmService.scheduleAllAlarms()
}
override fun inject(component: TestComponent) = component.inject(this)
}

@ -1,192 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.dao;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotSame;
import static junit.framework.Assert.assertNull;
import static org.tasks.makers.TaskMaker.ID;
import static org.tasks.makers.TaskMaker.PARENT;
import static org.tasks.makers.TaskMaker.newTask;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SdkSuppress;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Longs;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.TaskDeleter;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
@RunWith(AndroidJUnit4.class)
public class TaskDaoTests extends InjectingTestCase {
@Inject TaskDao taskDao;
@Inject TaskDeleter taskDeleter;
/** Test basic task creation, fetch, and save */
@Test
public void testTaskCreation() {
assertEquals(0, taskDao.getAll().size());
// create task "happy"
Task task = new Task();
task.setTitle("happy");
taskDao.createNew(task);
assertEquals(1, taskDao.getAll().size());
long happyId = task.getId();
assertNotSame(Task.NO_ID, happyId);
task = taskDao.fetch(happyId);
assertEquals("happy", task.getTitle());
// create task "sad"
task = new Task();
task.setTitle("sad");
taskDao.createNew(task);
assertEquals(2, taskDao.getAll().size());
// rename sad to melancholy
long sadId = task.getId();
assertNotSame(Task.NO_ID, sadId);
task.setTitle("melancholy");
taskDao.save(task);
assertEquals(2, taskDao.getAll().size());
// check state
task = taskDao.fetch(happyId);
assertEquals("happy", task.getTitle());
task = taskDao.fetch(sadId);
assertEquals("melancholy", task.getTitle());
}
/** Test various task fetch conditions */
@Test
public void testTaskConditions() {
// create normal task
Task task = new Task();
task.setTitle("normal");
taskDao.createNew(task);
// create blank task
task = new Task();
task.setTitle("");
taskDao.createNew(task);
// create hidden task
task = new Task();
task.setTitle("hidden");
task.setHideUntil(DateUtilities.now() + 10000);
taskDao.createNew(task);
// create task with deadlines
task = new Task();
task.setTitle("deadlineInFuture");
task.setDueDate(DateUtilities.now() + 10000);
taskDao.createNew(task);
task = new Task();
task.setTitle("deadlineInPast");
task.setDueDate(DateUtilities.now() - 10000);
taskDao.createNew(task);
// create completed task
task = new Task();
task.setTitle("completed");
task.setCompletionDate(DateUtilities.now() - 10000);
taskDao.createNew(task);
// check is active
assertEquals(5, taskDao.getActiveTasks().size());
// check is visible
assertEquals(5, taskDao.getVisibleTasks().size());
}
/** Test task deletion */
@Test
public void testTDeletion() {
assertEquals(0, taskDao.getAll().size());
// create task "happy"
Task task = new Task();
task.setTitle("happy");
taskDao.createNew(task);
assertEquals(1, taskDao.getAll().size());
// delete
taskDeleter.delete(task);
assertEquals(0, taskDao.getAll().size());
}
/** Test save without prior create doesn't work */
@Test
public void testSaveWithoutCreate() {
// try to save task "happy"
Task task = new Task();
task.setTitle("happy");
task.setId(1L);
taskDao.save(task);
assertEquals(0, taskDao.getAll().size());
}
/** Test passing invalid task indices to various things */
@Test
public void testInvalidIndex() {
assertEquals(0, taskDao.getAll().size());
assertNull(taskDao.fetch(1));
taskDeleter.delete(ImmutableList.of(1L));
// make sure db still works
assertEquals(0, taskDao.getAll().size());
}
@Test
@SdkSuppress(minSdkVersion = 21)
public void findChildrenInList() {
taskDao.createNew(newTask(with(ID, 1L)));
taskDao.createNew(newTask(with(ID, 2L), with(PARENT, 1L)));
assertEquals(singletonList(2L), taskDao.findChildrenInList(Longs.asList(1, 2)));
}
@Test
@SdkSuppress(minSdkVersion = 21)
public void findRecursiveChildrenInList() {
taskDao.createNew(newTask(with(ID, 1L)));
taskDao.createNew(newTask(with(ID, 2L), with(PARENT, 1L)));
taskDao.createNew(newTask(with(ID, 3L), with(PARENT, 2L)));
assertEquals(asList(2L, 3L), taskDao.findChildrenInList(Longs.asList(1, 2, 3)));
}
@Test
@SdkSuppress(minSdkVersion = 21)
public void findRecursiveChildrenInListAfterSkippingParent() {
taskDao.createNew(newTask(with(ID, 1L)));
taskDao.createNew(newTask(with(ID, 2L), with(PARENT, 1L)));
taskDao.createNew(newTask(with(ID, 3L), with(PARENT, 2L)));
assertEquals(singletonList(3L), taskDao.findChildrenInList(Longs.asList(1, 3)));
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
// TODO check eventing
}

@ -0,0 +1,167 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.dao
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.natpryce.makeiteasy.MakeItEasy.with
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.service.TaskDeleter
import org.junit.Assert.*
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.makers.TaskMaker.ID
import org.tasks.makers.TaskMaker.PARENT
import org.tasks.makers.TaskMaker.newTask
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class TaskDaoTests : InjectingTestCase() {
@Inject lateinit var taskDao: TaskDao
@Inject lateinit var taskDeleter: TaskDeleter
/** Test basic task creation, fetch, and save */
@Test
fun testTaskCreation() {
assertEquals(0, taskDao.all.size)
// create task "happy"
var task = Task()
task.setTitle("happy")
taskDao.createNew(task)
assertEquals(1, taskDao.all.size)
val happyId = task.getId()
assertNotSame(Task.NO_ID, happyId)
task = taskDao.fetch(happyId)
assertEquals("happy", task.getTitle())
// create task "sad"
task = Task()
task.setTitle("sad")
taskDao.createNew(task)
assertEquals(2, taskDao.all.size)
// rename sad to melancholy
val sadId = task.getId()
assertNotSame(Task.NO_ID, sadId)
task.setTitle("melancholy")
taskDao.save(task)
assertEquals(2, taskDao.all.size)
// check state
task = taskDao.fetch(happyId)
assertEquals("happy", task.getTitle())
task = taskDao.fetch(sadId)
assertEquals("melancholy", task.getTitle())
}
/** Test various task fetch conditions */
@Test
fun testTaskConditions() {
// create normal task
var task = Task()
task.setTitle("normal")
taskDao.createNew(task)
// create blank task
task = Task()
task.setTitle("")
taskDao.createNew(task)
// create hidden task
task = Task()
task.setTitle("hidden")
task.setHideUntil(DateUtilities.now() + 10000)
taskDao.createNew(task)
// create task with deadlines
task = Task()
task.setTitle("deadlineInFuture")
task.setDueDate(DateUtilities.now() + 10000)
taskDao.createNew(task)
task = Task()
task.setTitle("deadlineInPast")
task.setDueDate(DateUtilities.now() - 10000)
taskDao.createNew(task)
// create completed task
task = Task()
task.setTitle("completed")
task.completionDate = DateUtilities.now() - 10000
taskDao.createNew(task)
// check is active
assertEquals(5, taskDao.activeTasks.size)
// check is visible
assertEquals(5, taskDao.visibleTasks.size)
}
/** Test task deletion */
@Test
fun testTDeletion() {
assertEquals(0, taskDao.all.size)
// create task "happy"
val task = Task()
task.setTitle("happy")
taskDao.createNew(task)
assertEquals(1, taskDao.all.size)
// delete
taskDeleter.delete(task)
assertEquals(0, taskDao.all.size)
}
/** Test save without prior create doesn't work */
@Test
fun testSaveWithoutCreate() {
// try to save task "happy"
val task = Task()
task.setTitle("happy")
task.setId(1L)
taskDao.save(task)
assertEquals(0, taskDao.all.size)
}
/** Test passing invalid task indices to various things */
@Test
fun testInvalidIndex() {
assertEquals(0, taskDao.all.size)
assertNull(taskDao.fetch(1))
taskDeleter.delete(listOf(1L))
// make sure db still works
assertEquals(0, taskDao.all.size)
}
@Test
fun findChildrenInList() {
taskDao.createNew(newTask(with(ID, 1L)))
taskDao.createNew(newTask(with(ID, 2L), with(PARENT, 1L)))
assertEquals(listOf(2L), taskDao.findChildrenInList(listOf(1, 2)))
}
@Test
fun findRecursiveChildrenInList() {
taskDao.createNew(newTask(with(ID, 1L)))
taskDao.createNew(newTask(with(ID, 2L), with(PARENT, 1L)))
taskDao.createNew(newTask(with(ID, 3L), with(PARENT, 2L)))
assertEquals(listOf(2L, 3L), taskDao.findChildrenInList(listOf(1, 2, 3)))
}
@Test
fun findRecursiveChildrenInListAfterSkippingParent() {
taskDao.createNew(newTask(with(ID, 1L)))
taskDao.createNew(newTask(with(ID, 2L), with(PARENT, 1L)))
taskDao.createNew(newTask(with(ID, 3L), with(PARENT, 2L)))
assertEquals(listOf(3L), taskDao.findChildrenInList(listOf(1, 3)))
}
override fun inject(component: TestComponent) = component.inject(this)
}

@ -1,296 +0,0 @@
package com.todoroo.astrid.data;
import static com.todoroo.astrid.data.Task.URGENCY_DAY_AFTER;
import static com.todoroo.astrid.data.Task.URGENCY_IN_TWO_WEEKS;
import static com.todoroo.astrid.data.Task.URGENCY_NEXT_WEEK;
import static com.todoroo.astrid.data.Task.URGENCY_NONE;
import static com.todoroo.astrid.data.Task.URGENCY_SPECIFIC_DAY;
import static com.todoroo.astrid.data.Task.URGENCY_SPECIFIC_DAY_TIME;
import static com.todoroo.astrid.data.Task.URGENCY_TODAY;
import static com.todoroo.astrid.data.Task.URGENCY_TOMORROW;
import static com.todoroo.astrid.data.Task.createDueDate;
import static com.todoroo.astrid.data.Task.hasDueTime;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.tasks.Freeze.freezeAt;
import static org.tasks.Freeze.thaw;
import static org.tasks.date.DateTimeUtils.newDateTime;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.data.Task.Priority;
import java.util.ArrayList;
import java.util.TreeSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.Snippet;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class TaskTest {
private static final DateTime now = new DateTime(2013, 12, 31, 16, 10, 53, 452);
private static final DateTime specificDueDate = new DateTime(2014, 3, 17, 9, 54, 27, 959);
@Before
public void setUp() {
freezeAt(now);
}
@After
public void tearDown() {
thaw();
}
@Test
public void testCreateDueDateNoUrgency() {
assertEquals(0, createDueDate(URGENCY_NONE, 1L));
}
@Test
public void testCreateDueDateToday() {
long expected = new DateTime(2013, 12, 31, 12, 0, 0, 0).getMillis();
assertEquals(expected, createDueDate(URGENCY_TODAY, -1L));
}
@Test
public void testCreateDueDateTomorrow() {
long expected = new DateTime(2014, 1, 1, 12, 0, 0, 0).getMillis();
assertEquals(expected, createDueDate(URGENCY_TOMORROW, -1L));
}
@Test
public void testCreateDueDateDayAfter() {
long expected = new DateTime(2014, 1, 2, 12, 0, 0, 0).getMillis();
assertEquals(expected, createDueDate(URGENCY_DAY_AFTER, -1L));
}
@Test
public void testCreateDueDateNextWeek() {
long expected = new DateTime(2014, 1, 7, 12, 0, 0, 0).getMillis();
assertEquals(expected, createDueDate(URGENCY_NEXT_WEEK, -1L));
}
@Test
public void testCreateDueDateInTwoWeeks() {
long expected = new DateTime(2014, 1, 14, 12, 0, 0, 0).getMillis();
assertEquals(expected, createDueDate(URGENCY_IN_TWO_WEEKS, -1L));
}
@Test
public void testRemoveTimeForSpecificDay() {
long expected =
specificDueDate
.withHourOfDay(12)
.withMinuteOfHour(0)
.withSecondOfMinute(0)
.withMillisOfSecond(0)
.getMillis();
assertEquals(expected, createDueDate(URGENCY_SPECIFIC_DAY, specificDueDate.getMillis()));
}
@Test
public void testRemoveSecondsForSpecificTime() {
long expected = specificDueDate.withSecondOfMinute(1).withMillisOfSecond(0).getMillis();
assertEquals(expected, createDueDate(URGENCY_SPECIFIC_DAY_TIME, specificDueDate.getMillis()));
}
@Test
public void testTaskHasDueTime() {
Task task = new Task();
task.setDueDate(1388516076000L);
assertTrue(task.hasDueTime());
assertTrue(task.hasDueDate());
}
@Test
public void testTaskHasDueDate() {
Task task = new Task();
task.setDueDate(1388469600000L);
assertFalse(task.hasDueTime());
assertTrue(task.hasDueDate());
}
@Test
public void testDoesHaveDueTime() {
assertTrue(hasDueTime(1388516076000L));
}
@Test
public void testNoDueTime() {
assertFalse(hasDueTime(newDateTime().startOfDay().getMillis()));
assertFalse(hasDueTime(newDateTime().withMillisOfDay(60000).getMillis()));
}
@Test
public void testHasDueTime() {
assertTrue(hasDueTime(newDateTime().withMillisOfDay(1).getMillis()));
assertTrue(hasDueTime(newDateTime().withMillisOfDay(1000).getMillis()));
assertTrue(hasDueTime(newDateTime().withMillisOfDay(59999).getMillis()));
}
@Test
public void testDoesNotHaveDueTime() {
assertFalse(hasDueTime(1388469600000L));
}
@Test
public void testNewTaskIsNotCompleted() {
assertFalse(new Task().isCompleted());
}
@Test
public void testNewTaskNotDeleted() {
assertFalse(new Task().isDeleted());
}
@Test
public void testNewTaskNotHidden() {
assertFalse(new Task().isHidden());
}
@Test
public void testNewTaskDoesNotHaveDueDateOrTime() {
assertFalse(new Task().hasDueDate());
assertFalse(new Task().hasDueTime());
}
@Test
public void testTaskIsCompleted() {
Task task = new Task();
task.setCompletionDate(1L);
assertTrue(task.isCompleted());
}
@Test
public void testTaskIsNotHiddenAtHideUntilTime() {
final long now = currentTimeMillis();
freezeAt(now)
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setHideUntil(now);
assertFalse(task.isHidden());
}
});
}
@Test
public void testTaskIsHiddenBeforeHideUntilTime() {
final long now = currentTimeMillis();
freezeAt(now)
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setHideUntil(now + 1);
assertTrue(task.isHidden());
}
});
}
@Test
public void testTaskIsDeleted() {
Task task = new Task();
task.setDeletionDate(1L);
assertTrue(task.isDeleted());
}
@Test
public void testTaskWithNoDueDateIsOverdue() {
assertTrue(new Task().isOverdue());
}
@Test
public void testTaskNotOverdueAtDueTime() {
final long now = currentTimeMillis();
freezeAt(now)
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setDueDate(now);
assertFalse(task.isOverdue());
}
});
}
@Test
public void testTaskIsOverduePastDueTime() {
final long dueDate = currentTimeMillis();
freezeAt(dueDate + 1)
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setDueDate(dueDate);
assertTrue(task.isOverdue());
}
});
}
@Test
public void testTaskNotOverdueBeforeNoonOnDueDate() {
final DateTime dueDate = new DateTime().startOfDay();
freezeAt(dueDate.plusHours(12).minusMillis(1))
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setDueDate(dueDate.getMillis());
assertFalse(task.hasDueTime());
assertFalse(task.isOverdue());
}
});
}
@Test
public void testTaskOverdueAtNoonOnDueDate() {
final DateTime dueDate = new DateTime().startOfDay();
freezeAt(dueDate.plusHours(12))
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setDueDate(dueDate.getMillis());
assertFalse(task.hasDueTime());
assertFalse(task.isOverdue());
}
});
}
@Test
public void testTaskWithNoDueTimeIsOverdue() {
final DateTime dueDate = new DateTime().startOfDay();
freezeAt(dueDate.plusDays(1))
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setDueDate(dueDate.getMillis());
assertFalse(task.hasDueTime());
assertTrue(task.isOverdue());
}
});
}
@Test
@SuppressWarnings("ConstantConditions")
public void testSanity() {
assertTrue(Priority.HIGH < Priority.MEDIUM);
assertTrue(Priority.MEDIUM < Priority.LOW);
assertTrue(Priority.LOW < Priority.NONE);
ArrayList<Integer> reminderFlags = new ArrayList<>();
reminderFlags.add(Task.NOTIFY_AFTER_DEADLINE);
reminderFlags.add(Task.NOTIFY_AT_DEADLINE);
reminderFlags.add(Task.NOTIFY_MODE_NONSTOP);
// assert no duplicates
assertEquals(new TreeSet<>(reminderFlags).size(), reminderFlags.size());
}
}

@ -0,0 +1,249 @@
package com.todoroo.astrid.data
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.After
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.Freeze
import org.tasks.Freeze.Companion.freezeAt
import org.tasks.date.DateTimeUtils
import org.tasks.time.DateTime
import java.util.*
@RunWith(AndroidJUnit4::class)
class TaskTest {
@Before
fun setUp() {
freezeAt(now)
}
@After
fun tearDown() {
Freeze.thaw()
}
@Test
fun testCreateDueDateNoUrgency() {
assertEquals(0, Task.createDueDate(Task.URGENCY_NONE, 1L))
}
@Test
fun testCreateDueDateToday() {
val expected = DateTime(2013, 12, 31, 12, 0, 0, 0).millis
assertEquals(expected, Task.createDueDate(Task.URGENCY_TODAY, -1L))
}
@Test
fun testCreateDueDateTomorrow() {
val expected = DateTime(2014, 1, 1, 12, 0, 0, 0).millis
assertEquals(expected, Task.createDueDate(Task.URGENCY_TOMORROW, -1L))
}
@Test
fun testCreateDueDateDayAfter() {
val expected = DateTime(2014, 1, 2, 12, 0, 0, 0).millis
assertEquals(expected, Task.createDueDate(Task.URGENCY_DAY_AFTER, -1L))
}
@Test
fun testCreateDueDateNextWeek() {
val expected = DateTime(2014, 1, 7, 12, 0, 0, 0).millis
assertEquals(expected, Task.createDueDate(Task.URGENCY_NEXT_WEEK, -1L))
}
@Test
fun testCreateDueDateInTwoWeeks() {
val expected = DateTime(2014, 1, 14, 12, 0, 0, 0).millis
assertEquals(expected, Task.createDueDate(Task.URGENCY_IN_TWO_WEEKS, -1L))
}
@Test
fun testRemoveTimeForSpecificDay() {
val expected = specificDueDate
.withHourOfDay(12)
.withMinuteOfHour(0)
.withSecondOfMinute(0)
.withMillisOfSecond(0)
.millis
assertEquals(expected, Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, specificDueDate.millis))
}
@Test
fun testRemoveSecondsForSpecificTime() {
val expected = specificDueDate.withSecondOfMinute(1).withMillisOfSecond(0).millis
assertEquals(expected, Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, specificDueDate.millis))
}
@Test
fun testTaskHasDueTime() {
val task = Task()
task.setDueDate(1388516076000L)
assertTrue(task.hasDueTime())
assertTrue(task.hasDueDate())
}
@Test
fun testTaskHasDueDate() {
val task = Task()
task.setDueDate(1388469600000L)
assertFalse(task.hasDueTime())
assertTrue(task.hasDueDate())
}
@Test
fun testDoesHaveDueTime() {
assertTrue(Task.hasDueTime(1388516076000L))
}
@Test
fun testNoDueTime() {
assertFalse(Task.hasDueTime(DateTimeUtils.newDateTime().startOfDay().millis))
assertFalse(Task.hasDueTime(DateTimeUtils.newDateTime().withMillisOfDay(60000).millis))
}
@Test
fun testHasDueTime() {
assertTrue(Task.hasDueTime(DateTimeUtils.newDateTime().withMillisOfDay(1).millis))
assertTrue(Task.hasDueTime(DateTimeUtils.newDateTime().withMillisOfDay(1000).millis))
assertTrue(Task.hasDueTime(DateTimeUtils.newDateTime().withMillisOfDay(59999).millis))
}
@Test
fun testDoesNotHaveDueTime() {
assertFalse(Task.hasDueTime(1388469600000L))
}
@Test
fun testNewTaskIsNotCompleted() {
assertFalse(Task().isCompleted)
}
@Test
fun testNewTaskNotDeleted() {
assertFalse(Task().isDeleted)
}
@Test
fun testNewTaskNotHidden() {
assertFalse(Task().isHidden)
}
@Test
fun testNewTaskDoesNotHaveDueDateOrTime() {
assertFalse(Task().hasDueDate())
assertFalse(Task().hasDueTime())
}
@Test
fun testTaskIsCompleted() {
val task = Task()
task.completionDate = 1L
assertTrue(task.isCompleted)
}
@Test
fun testTaskIsNotHiddenAtHideUntilTime() {
val now = org.tasks.time.DateTimeUtils.currentTimeMillis()
freezeAt(now) {
val task = Task()
task.setHideUntil(now)
assertFalse(task.isHidden)
}
}
@Test
fun testTaskIsHiddenBeforeHideUntilTime() {
val now = org.tasks.time.DateTimeUtils.currentTimeMillis()
freezeAt(now) {
val task = Task()
task.setHideUntil(now + 1)
assertTrue(task.isHidden)
}
}
@Test
fun testTaskIsDeleted() {
val task = Task()
task.deletionDate = 1L
assertTrue(task.isDeleted)
}
@Test
fun testTaskWithNoDueDateIsOverdue() {
assertTrue(Task().isOverdue)
}
@Test
fun testTaskNotOverdueAtDueTime() {
val now = org.tasks.time.DateTimeUtils.currentTimeMillis()
freezeAt(now) {
val task = Task()
task.setDueDate(now)
assertFalse(task.isOverdue)
}
}
@Test
fun testTaskIsOverduePastDueTime() {
val dueDate = org.tasks.time.DateTimeUtils.currentTimeMillis()
freezeAt(dueDate + 1) {
val task = Task()
task.setDueDate(dueDate)
assertTrue(task.isOverdue)
}
}
@Test
fun testTaskNotOverdueBeforeNoonOnDueDate() {
val dueDate = DateTime().startOfDay()
freezeAt(dueDate.plusHours(12).minusMillis(1)) {
val task = Task()
task.setDueDate(dueDate.millis)
assertFalse(task.hasDueTime())
assertFalse(task.isOverdue)
}
}
@Test
fun testTaskOverdueAtNoonOnDueDate() {
val dueDate = DateTime().startOfDay()
freezeAt(dueDate.plusHours(12)) {
val task = Task()
task.setDueDate(dueDate.millis)
assertFalse(task.hasDueTime())
assertFalse(task.isOverdue)
}
}
@Test
fun testTaskWithNoDueTimeIsOverdue() {
val dueDate = DateTime().startOfDay()
freezeAt(dueDate.plusDays(1)) {
val task = Task()
task.setDueDate(dueDate.millis)
assertFalse(task.hasDueTime())
assertTrue(task.isOverdue)
}
}
@Test
fun testSanity() {
assertTrue(Task.Priority.HIGH < Task.Priority.MEDIUM)
assertTrue(Task.Priority.MEDIUM < Task.Priority.LOW)
assertTrue(Task.Priority.LOW < Task.Priority.NONE)
val reminderFlags = ArrayList<Int>()
reminderFlags.add(Task.NOTIFY_AFTER_DEADLINE)
reminderFlags.add(Task.NOTIFY_AT_DEADLINE)
reminderFlags.add(Task.NOTIFY_MODE_NONSTOP)
// assert no duplicates
assertEquals(TreeSet(reminderFlags).size, reminderFlags.size)
}
companion object {
private val now = DateTime(2013, 12, 31, 16, 10, 53, 452)
private val specificDueDate = DateTime(2014, 3, 17, 9, 54, 27, 959)
}
}

@ -1,110 +0,0 @@
package com.todoroo.astrid.gtasks;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static org.tasks.makers.GtaskListMaker.ID;
import static org.tasks.makers.GtaskListMaker.NAME;
import static org.tasks.makers.GtaskListMaker.REMOTE_ID;
import static org.tasks.makers.GtaskListMaker.newGtaskList;
import static org.tasks.makers.RemoteGtaskListMaker.newRemoteList;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.api.services.tasks.model.TaskList;
import com.todoroo.astrid.service.TaskDeleter;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.LocalBroadcastManager;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
import org.tasks.makers.RemoteGtaskListMaker;
@RunWith(AndroidJUnit4.class)
public class GtasksListServiceTest extends InjectingTestCase {
@Inject TaskDeleter taskDeleter;
@Inject LocalBroadcastManager localBroadcastManager;
@Inject GoogleTaskListDao googleTaskListDao;
private GtasksListService gtasksListService;
@Override
public void setUp() {
super.setUp();
gtasksListService =
new GtasksListService(googleTaskListDao, taskDeleter, localBroadcastManager);
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
@Test
public void testCreateNewList() {
setLists(
newRemoteList(
with(RemoteGtaskListMaker.REMOTE_ID, "1"), with(RemoteGtaskListMaker.NAME, "Default")));
assertEquals(
newGtaskList(with(ID, 1L), with(REMOTE_ID, "1"), with(NAME, "Default")),
googleTaskListDao.getById(1L));
}
@Test
public void testGetListByRemoteId() {
GoogleTaskList list = newGtaskList(with(REMOTE_ID, "1"));
list.setId(googleTaskListDao.insertOrReplace(list));
assertEquals(list, gtasksListService.getList("1"));
}
@Test
public void testGetListReturnsNullWhenNotFound() {
assertNull(gtasksListService.getList("1"));
}
@Test
public void testDeleteMissingList() {
googleTaskListDao.insertOrReplace(newGtaskList(with(ID, 1L), with(REMOTE_ID, "1")));
TaskList taskList = newRemoteList(with(RemoteGtaskListMaker.REMOTE_ID, "2"));
setLists(taskList);
assertEquals(
singletonList(newGtaskList(with(ID, 2L), with(REMOTE_ID, "2"))),
googleTaskListDao.getLists("account"));
}
@Test
public void testUpdateListName() {
googleTaskListDao.insertOrReplace(
newGtaskList(with(ID, 1L), with(REMOTE_ID, "1"), with(NAME, "oldName")));
setLists(
newRemoteList(
with(RemoteGtaskListMaker.REMOTE_ID, "1"), with(RemoteGtaskListMaker.NAME, "newName")));
assertEquals("newName", googleTaskListDao.getById(1).getTitle());
}
@Test
public void testNewListLastSyncIsZero() {
setLists(new TaskList().setId("1"));
assertEquals(0L, gtasksListService.getList("1").getLastSync());
}
private void setLists(TaskList... list) {
GoogleTaskAccount account = new GoogleTaskAccount("account");
googleTaskListDao.insert(account);
gtasksListService.updateLists(account, asList(list));
}
}

@ -0,0 +1,92 @@
package com.todoroo.astrid.gtasks
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.api.services.tasks.model.TaskList
import com.natpryce.makeiteasy.MakeItEasy.with
import com.todoroo.astrid.service.TaskDeleter
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.LocalBroadcastManager
import org.tasks.data.GoogleTaskAccount
import org.tasks.data.GoogleTaskListDao
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.makers.GtaskListMaker.ID
import org.tasks.makers.GtaskListMaker.NAME
import org.tasks.makers.GtaskListMaker.REMOTE_ID
import org.tasks.makers.GtaskListMaker.newGtaskList
import org.tasks.makers.RemoteGtaskListMaker
import org.tasks.makers.RemoteGtaskListMaker.newRemoteList
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class GtasksListServiceTest : InjectingTestCase() {
@Inject lateinit var taskDeleter: TaskDeleter
@Inject lateinit var localBroadcastManager: LocalBroadcastManager
@Inject lateinit var googleTaskListDao: GoogleTaskListDao
private lateinit var gtasksListService: GtasksListService
override fun setUp() {
super.setUp()
gtasksListService = GtasksListService(googleTaskListDao, taskDeleter, localBroadcastManager)
}
override fun inject(component: TestComponent) = component.inject(this)
@Test
fun testCreateNewList() {
setLists(
newRemoteList(
with(RemoteGtaskListMaker.REMOTE_ID, "1"), with(RemoteGtaskListMaker.NAME, "Default")))
assertEquals(
newGtaskList(with(ID, 1L), with(REMOTE_ID, "1"), with(NAME, "Default")),
googleTaskListDao.getById(1L))
}
@Test
fun testGetListByRemoteId() {
val list = newGtaskList(with(REMOTE_ID, "1"))
list.id = googleTaskListDao.insertOrReplace(list)
assertEquals(list, gtasksListService.getList("1"))
}
@Test
fun testGetListReturnsNullWhenNotFound() {
assertNull(gtasksListService.getList("1"))
}
@Test
fun testDeleteMissingList() {
googleTaskListDao.insertOrReplace(newGtaskList(with(ID, 1L), with(REMOTE_ID, "1")))
val taskList = newRemoteList(with(RemoteGtaskListMaker.REMOTE_ID, "2"))
setLists(taskList)
assertEquals(
listOf(newGtaskList(with(ID, 2L), with(REMOTE_ID, "2"))),
googleTaskListDao.getLists("account"))
}
@Test
fun testUpdateListName() {
googleTaskListDao.insertOrReplace(
newGtaskList(with(ID, 1L), with(REMOTE_ID, "1"), with(NAME, "oldName")))
setLists(
newRemoteList(
with(RemoteGtaskListMaker.REMOTE_ID, "1"), with(RemoteGtaskListMaker.NAME, "newName")))
assertEquals("newName", googleTaskListDao.getById(1)!!.title)
}
@Test
fun testNewListLastSyncIsZero() {
setLists(TaskList().setId("1"))
assertEquals(0L, gtasksListService.getList("1").lastSync)
}
private fun setLists(vararg list: TaskList) {
val account = GoogleTaskAccount("account")
googleTaskListDao.insert(account)
gtasksListService.updateLists(account, listOf(*list))
}
}

@ -1,92 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.gtasks;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.data.GoogleTask;
import org.tasks.data.GoogleTaskDao;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
@SuppressWarnings("nls")
@RunWith(AndroidJUnit4.class)
public class GtasksMetadataServiceTest extends InjectingTestCase {
@Inject TaskDao taskDao;
@Inject GoogleTaskDao googleTaskDao;
private Task task;
private GoogleTask metadata;
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
@Test
public void testMetadataFound() {
givenTask(taskWithMetadata(null));
whenSearchForMetadata();
thenExpectMetadataFound();
}
@Test
public void testMetadataDoesntExist() {
givenTask(taskWithoutMetadata());
whenSearchForMetadata();
thenExpectNoMetadataFound();
}
private void thenExpectNoMetadataFound() {
assertNull(metadata);
}
private void thenExpectMetadataFound() {
assertNotNull(metadata);
}
// --- helpers
private void whenSearchForMetadata() {
metadata = googleTaskDao.getByTaskId(task.getId());
}
private Task taskWithMetadata(String id) {
Task task = new Task();
task.setTitle("cats");
taskDao.createNew(task);
GoogleTask metadata = new GoogleTask(task.getId(), "");
if (id != null) {
metadata.setRemoteId(id);
}
metadata.setTask(task.getId());
googleTaskDao.insert(metadata);
return task;
}
private void givenTask(Task taskToTest) {
task = taskToTest;
}
private Task taskWithoutMetadata() {
Task task = new Task();
task.setTitle("dogs");
taskDao.createNew(task);
return task;
}
}

@ -0,0 +1,81 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.gtasks
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.data.GoogleTask
import org.tasks.data.GoogleTaskDao
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class GtasksMetadataServiceTest : InjectingTestCase() {
@Inject lateinit var taskDao: TaskDao
@Inject lateinit var googleTaskDao: GoogleTaskDao
private var task: Task? = null
private var metadata: GoogleTask? = null
override fun inject(component: TestComponent) = component.inject(this)
@Test
fun testMetadataFound() {
givenTask(taskWithMetadata(null))
whenSearchForMetadata()
thenExpectMetadataFound()
}
@Test
fun testMetadataDoesntExist() {
givenTask(taskWithoutMetadata())
whenSearchForMetadata()
thenExpectNoMetadataFound()
}
private fun thenExpectNoMetadataFound() {
assertNull(metadata)
}
private fun thenExpectMetadataFound() {
assertNotNull(metadata)
}
// --- helpers
private fun whenSearchForMetadata() {
metadata = googleTaskDao.getByTaskId(task!!.getId())
}
private fun taskWithMetadata(id: String?): Task {
val task = Task()
task.setTitle("cats")
taskDao.createNew(task)
val metadata = GoogleTask(task.getId(), "")
if (id != null) {
metadata.remoteId = id
}
metadata.task = task.getId()
googleTaskDao.insert(metadata)
return task
}
private fun givenTask(taskToTest: Task) {
task = taskToTest
}
private fun taskWithoutMetadata(): Task {
val task = Task()
task.setTitle("dogs")
taskDao.createNew(task)
return task
}
}

@ -1,82 +0,0 @@
package com.todoroo.astrid.gtasks.api;
import static com.todoroo.astrid.gtasks.api.GtasksApiUtilities.gtasksCompletedTimeToUnixTime;
import static com.todoroo.astrid.gtasks.api.GtasksApiUtilities.gtasksDueTimeToUnixTime;
import static com.todoroo.astrid.gtasks.api.GtasksApiUtilities.unixTimeToGtasksCompletionTime;
import static com.todoroo.astrid.gtasks.api.GtasksApiUtilities.unixTimeToGtasksDueDate;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class GtasksApiUtilitiesTest {
private static final Locale defaultLocale = Locale.getDefault();
private static final TimeZone defaultDateTimeZone = TimeZone.getDefault();
@Before
public void setUp() {
Locale.setDefault(Locale.US);
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
}
@After
public void tearDown() {
Locale.setDefault(defaultLocale);
TimeZone.setDefault(defaultDateTimeZone);
}
@Test
public void testConvertUnixToGoogleCompletionTime() {
long now = new DateTime(2014, 1, 8, 8, 53, 20, 109).getMillis();
assertEquals(now, unixTimeToGtasksCompletionTime(now).getValue());
}
@Test
public void testConvertGoogleCompletedTimeToUnixTime() {
long now = new DateTime(2014, 1, 8, 8, 53, 20, 109).getMillis();
com.google.api.client.util.DateTime gtime = new com.google.api.client.util.DateTime(now);
assertEquals(now, gtasksCompletedTimeToUnixTime(gtime));
}
@Test
public void testConvertDueDateTimeToGoogleDueDate() {
DateTime now = new DateTime(2014, 1, 8, 8, 53, 20, 109);
assertEquals(
new DateTime(2014, 1, 8, 0, 0, 0, 0, TimeZone.getTimeZone("GMT")).getMillis(),
unixTimeToGtasksDueDate(now.getMillis()).getValue());
}
@Test
public void testConvertGoogleDueDateToUnixTime() {
com.google.api.client.util.DateTime googleDueDate =
new com.google.api.client.util.DateTime(
new Date(new DateTime(2014, 1, 8, 0, 0, 0, 0).getMillis()),
TimeZone.getTimeZone("GMT"));
assertEquals(
new DateTime(2014, 1, 8, 6, 0, 0, 0).getMillis(), gtasksDueTimeToUnixTime(googleDueDate));
}
@Test
public void testConvertToInvalidGtaskTimes() {
assertNull(unixTimeToGtasksCompletionTime(-1));
assertNull(unixTimeToGtasksDueDate(-1));
}
@Test
public void testConvertFromInvalidGtaskTimes() {
assertEquals(0, gtasksCompletedTimeToUnixTime(null));
assertEquals(0, gtasksDueTimeToUnixTime(null));
}
}

@ -0,0 +1,73 @@
package com.todoroo.astrid.gtasks.api
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.api.client.util.DateTime
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.util.*
@RunWith(AndroidJUnit4::class)
class GtasksApiUtilitiesTest {
@Before
fun setUp() {
Locale.setDefault(Locale.US)
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"))
}
@After
fun tearDown() {
Locale.setDefault(defaultLocale)
TimeZone.setDefault(defaultDateTimeZone)
}
@Test
fun testConvertUnixToGoogleCompletionTime() {
val now = org.tasks.time.DateTime(2014, 1, 8, 8, 53, 20, 109).millis
assertEquals(now, GtasksApiUtilities.unixTimeToGtasksCompletionTime(now).value)
}
@Test
fun testConvertGoogleCompletedTimeToUnixTime() {
val now = org.tasks.time.DateTime(2014, 1, 8, 8, 53, 20, 109).millis
val gtime = DateTime(now)
assertEquals(now, GtasksApiUtilities.gtasksCompletedTimeToUnixTime(gtime))
}
@Test
fun testConvertDueDateTimeToGoogleDueDate() {
val now = org.tasks.time.DateTime(2014, 1, 8, 8, 53, 20, 109)
assertEquals(
org.tasks.time.DateTime(2014, 1, 8, 0, 0, 0, 0, TimeZone.getTimeZone("GMT")).millis,
GtasksApiUtilities.unixTimeToGtasksDueDate(now.millis).value)
}
@Test
fun testConvertGoogleDueDateToUnixTime() {
val googleDueDate = DateTime(
Date(org.tasks.time.DateTime(2014, 1, 8, 0, 0, 0, 0).millis),
TimeZone.getTimeZone("GMT"))
assertEquals(
org.tasks.time.DateTime(2014, 1, 8, 6, 0, 0, 0).millis, GtasksApiUtilities.gtasksDueTimeToUnixTime(googleDueDate))
}
@Test
fun testConvertToInvalidGtaskTimes() {
assertNull(GtasksApiUtilities.unixTimeToGtasksCompletionTime(-1))
assertNull(GtasksApiUtilities.unixTimeToGtasksDueDate(-1))
}
@Test
fun testConvertFromInvalidGtaskTimes() {
assertEquals(0, GtasksApiUtilities.gtasksCompletedTimeToUnixTime(null))
assertEquals(0, GtasksApiUtilities.gtasksDueTimeToUnixTime(null))
}
companion object {
private val defaultLocale = Locale.getDefault()
private val defaultDateTimeZone = TimeZone.getDefault()
}
}

@ -1,47 +0,0 @@
package com.todoroo.astrid.model;
import static junit.framework.Assert.assertEquals;
import static org.tasks.Freeze.freezeClock;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.Snippet;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
@RunWith(AndroidJUnit4.class)
public class TaskTest extends InjectingTestCase {
@Inject TaskDao taskDao;
@Test
public void testSavedTaskHasCreationDate() {
freezeClock()
.thawAfter(
new Snippet() {
{
Task task = new Task();
taskDao.createNew(task);
assertEquals(currentTimeMillis(), (long) task.getCreationDate());
}
});
}
@Test
public void testReadTaskFromDb() {
Task task = new Task();
taskDao.createNew(task);
final Task fromDb = taskDao.fetch(task.getId());
assertEquals(task, fromDb);
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
}

@ -0,0 +1,37 @@
package com.todoroo.astrid.model
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.Freeze
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.time.DateTimeUtils
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class TaskTest : InjectingTestCase() {
@Inject lateinit var taskDao: TaskDao
@Test
fun testSavedTaskHasCreationDate() {
Freeze.freezeClock {
val task = Task()
taskDao.createNew(task)
assertEquals(DateTimeUtils.currentTimeMillis(), task.creationDate as Long)
}
}
@Test
fun testReadTaskFromDb() {
val task = Task()
taskDao.createNew(task)
val fromDb = taskDao.fetch(task.getId())
assertEquals(task, fromDb)
}
override fun inject(component: TestComponent) = component.inject(this)
}

@ -1,452 +0,0 @@
package com.todoroo.astrid.reminders;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static com.todoroo.andlib.utility.DateUtilities.ONE_HOUR;
import static com.todoroo.andlib.utility.DateUtilities.ONE_WEEK;
import static com.todoroo.astrid.data.Task.NOTIFY_AFTER_DEADLINE;
import static com.todoroo.astrid.data.Task.NOTIFY_AT_DEADLINE;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.tasks.Freeze.freezeClock;
import static org.tasks.date.DateTimeUtils.newDateTime;
import static org.tasks.makers.TaskMaker.COMPLETION_TIME;
import static org.tasks.makers.TaskMaker.CREATION_TIME;
import static org.tasks.makers.TaskMaker.DELETION_TIME;
import static org.tasks.makers.TaskMaker.DUE_DATE;
import static org.tasks.makers.TaskMaker.DUE_TIME;
import static org.tasks.makers.TaskMaker.ID;
import static org.tasks.makers.TaskMaker.RANDOM_REMINDER_PERIOD;
import static org.tasks.makers.TaskMaker.REMINDERS;
import static org.tasks.makers.TaskMaker.REMINDER_LAST;
import static org.tasks.makers.TaskMaker.SNOOZE_TIME;
import static org.tasks.makers.TaskMaker.newTask;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.tasks.R;
import org.tasks.Snippet;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
import org.tasks.jobs.NotificationQueue;
import org.tasks.jobs.ReminderEntry;
import org.tasks.preferences.Preferences;
import org.tasks.reminders.Random;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class ReminderServiceTest extends InjectingTestCase {
@Inject Preferences preferences;
@Inject TaskDao taskDao;
private ReminderService service;
private Random random;
private NotificationQueue jobs;
@Override
public void setUp() {
super.setUp();
jobs = mock(NotificationQueue.class);
random = mock(Random.class);
when(random.nextFloat()).thenReturn(1.0f);
preferences.clear();
service = new ReminderService(preferences, jobs, random, taskDao);
}
@After
public void after() {
verifyNoMoreInteractions(jobs);
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
@Test
public void dontScheduleDueDateReminderWhenFlagNotSet() {
service.scheduleAlarm(newTask(with(ID, 1L), with(DUE_TIME, newDateTime())));
verify(jobs).cancelReminder(1);
}
@Test
public void dontScheduleDueDateReminderWhenTimeNotSet() {
service.scheduleAlarm(newTask(with(ID, 1L), with(REMINDERS, NOTIFY_AT_DEADLINE)));
verify(jobs).cancelReminder(1);
}
@Test
public void schedulePastDueDate() {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime().minusDays(1)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs).add(new ReminderEntry(1, task.getDueDate(), ReminderService.TYPE_DUE));
}
@Test
public void scheduleFutureDueDate() {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime().plusDays(1)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs).add(new ReminderEntry(1, task.getDueDate(), ReminderService.TYPE_DUE));
}
@Test
public void scheduleReminderAtDefaultDueTime() {
DateTime now = newDateTime();
Task task = newTask(with(ID, 1L), with(DUE_DATE, now), with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(
new ReminderEntry(
1, now.startOfDay().withHourOfDay(18).getMillis(), ReminderService.TYPE_DUE));
}
@Test
public void dontScheduleReminderForCompletedTask() {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime().plusDays(1)),
with(COMPLETION_TIME, newDateTime()),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
verify(jobs).cancelReminder(1);
}
@Test
public void dontScheduleReminderForDeletedTask() {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime().plusDays(1)),
with(DELETION_TIME, newDateTime()),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
verify(jobs).cancelReminder(1);
}
@Test
public void dontScheduleDueDateReminderWhenAlreadyReminded() {
DateTime now = newDateTime();
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, now),
with(REMINDER_LAST, now.plusSeconds(1)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
verify(jobs).cancelReminder(1);
}
@Test
public void ignoreStaleSnoozeTime() {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime()),
with(SNOOZE_TIME, newDateTime().minusMinutes(5)),
with(REMINDER_LAST, newDateTime().minusMinutes(4)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs).add(new ReminderEntry(1, task.getDueDate(), ReminderService.TYPE_DUE));
}
@Test
public void dontIgnoreMissedSnoozeTime() {
DateTime dueDate = newDateTime();
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, dueDate),
with(SNOOZE_TIME, dueDate.minusMinutes(4)),
with(REMINDER_LAST, dueDate.minusMinutes(5)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(new ReminderEntry(1, task.getReminderSnooze(), ReminderService.TYPE_SNOOZE));
}
@Test
public void scheduleInitialRandomReminder() {
freezeClock()
.thawAfter(
new Snippet() {
{
DateTime now = newDateTime();
when(random.nextFloat()).thenReturn(0.3865f);
Task task =
newTask(
with(ID, 1L),
with(REMINDER_LAST, (DateTime) null),
with(CREATION_TIME, now.minusDays(1)),
with(RANDOM_REMINDER_PERIOD, ONE_WEEK));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
now.minusDays(1).getMillis() + 584206592,
ReminderService.TYPE_RANDOM));
}
});
}
@Test
public void scheduleNextRandomReminder() {
freezeClock()
.thawAfter(
new Snippet() {
{
DateTime now = newDateTime();
when(random.nextFloat()).thenReturn(0.3865f);
Task task =
newTask(
with(ID, 1L),
with(REMINDER_LAST, now.minusDays(1)),
with(CREATION_TIME, now.minusDays(30)),
with(RANDOM_REMINDER_PERIOD, ONE_WEEK));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
now.minusDays(1).getMillis() + 584206592,
ReminderService.TYPE_RANDOM));
}
});
}
@Test
public void scheduleOverdueRandomReminder() {
freezeClock()
.thawAfter(
new Snippet() {
{
DateTime now = newDateTime();
when(random.nextFloat()).thenReturn(0.3865f);
Task task =
newTask(
with(ID, 1L),
with(REMINDER_LAST, now.minusDays(14)),
with(CREATION_TIME, now.minusDays(30)),
with(RANDOM_REMINDER_PERIOD, ONE_WEEK));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(
new ReminderEntry(
1L, now.getMillis() + 10148400, ReminderService.TYPE_RANDOM));
}
});
}
@Test
public void scheduleOverdueNoLastReminder() {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, (DateTime) null),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
new DateTime(2017, 9, 23, 15, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
}
@Test
public void scheduleOverduePastLastReminder() {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, new DateTime(2017, 9, 24, 12, 0)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
new DateTime(2017, 9, 24, 15, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
}
@Test
public void scheduleOverdueBeforeLastReminder() {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 12, 30)),
with(REMINDER_LAST, new DateTime(2017, 9, 24, 15, 0)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
new DateTime(2017, 9, 25, 12, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
}
@Test
public void scheduleOverdueWithNoDueTime() {
preferences.setInt(R.string.p_rmd_time, (int) TimeUnit.HOURS.toMillis(15));
Task task =
newTask(
with(ID, 1L),
with(DUE_DATE, new DateTime(2017, 9, 22)),
with(REMINDER_LAST, new DateTime(2017, 9, 23, 12, 17, 59, 999)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
new DateTime(2017, 9, 23, 15, 0, 0, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
}
@Test
public void scheduleSubsequentOverdueReminder() {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, new DateTime(2017, 9, 23, 15, 30, 59, 999)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
new DateTime(2017, 9, 24, 15, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
}
@Test
public void scheduleOverdueAfterLastReminder() {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, new DateTime(2017, 9, 23, 12, 17, 59, 999)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
new DateTime(2017, 9, 23, 15, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
}
@Test
public void snoozeOverridesAll() {
DateTime now = newDateTime();
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, now),
with(SNOOZE_TIME, now.plusMonths(12)),
with(REMINDERS, NOTIFY_AT_DEADLINE | NOTIFY_AFTER_DEADLINE),
with(RANDOM_REMINDER_PERIOD, ONE_HOUR));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(new ReminderEntry(1, now.plusMonths(12).getMillis(), ReminderService.TYPE_SNOOZE));
}
}

@ -0,0 +1,375 @@
package com.todoroo.astrid.reminders
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.natpryce.makeiteasy.MakeItEasy.with
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import org.junit.After
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
import org.tasks.Freeze
import org.tasks.R
import org.tasks.date.DateTimeUtils
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.jobs.NotificationQueue
import org.tasks.jobs.ReminderEntry
import org.tasks.makers.TaskMaker.COMPLETION_TIME
import org.tasks.makers.TaskMaker.CREATION_TIME
import org.tasks.makers.TaskMaker.DELETION_TIME
import org.tasks.makers.TaskMaker.DUE_DATE
import org.tasks.makers.TaskMaker.DUE_TIME
import org.tasks.makers.TaskMaker.ID
import org.tasks.makers.TaskMaker.RANDOM_REMINDER_PERIOD
import org.tasks.makers.TaskMaker.REMINDERS
import org.tasks.makers.TaskMaker.REMINDER_LAST
import org.tasks.makers.TaskMaker.SNOOZE_TIME
import org.tasks.makers.TaskMaker.newTask
import org.tasks.preferences.Preferences
import org.tasks.reminders.Random
import org.tasks.time.DateTime
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class ReminderServiceTest : InjectingTestCase() {
@Inject
lateinit var preferences: Preferences
@Inject
lateinit var taskDao: TaskDao
private lateinit var service: ReminderService
private lateinit var random: Random
private lateinit var jobs: NotificationQueue
override fun setUp() {
super.setUp()
jobs = Mockito.mock(NotificationQueue::class.java)
random = Mockito.mock(Random::class.java)
Mockito.`when`(random.nextFloat()).thenReturn(1.0f)
preferences.clear()
service = ReminderService(preferences, jobs, random, taskDao)
}
@After
fun after() {
Mockito.verifyNoMoreInteractions(jobs)
}
override fun inject(component: TestComponent) = component.inject(this)
@Test
fun dontScheduleDueDateReminderWhenFlagNotSet() {
service.scheduleAlarm(newTask(with(ID, 1L), with(DUE_TIME, DateTimeUtils.newDateTime())))
Mockito.verify(jobs).cancelReminder(1)
}
@Test
fun dontScheduleDueDateReminderWhenTimeNotSet() {
service.scheduleAlarm(newTask(with(ID, 1L), with(REMINDERS, Task.NOTIFY_AT_DEADLINE)))
Mockito.verify(jobs).cancelReminder(1)
}
@Test
fun schedulePastDueDate() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTimeUtils.newDateTime().minusDays(1)),
with(REMINDERS, Task.NOTIFY_AT_DEADLINE))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order.verify(jobs).add(ReminderEntry(1, task.getDueDate(), ReminderService.TYPE_DUE))
}
@Test
fun scheduleFutureDueDate() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTimeUtils.newDateTime().plusDays(1)),
with(REMINDERS, Task.NOTIFY_AT_DEADLINE))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order.verify(jobs).add(ReminderEntry(1, task.getDueDate(), ReminderService.TYPE_DUE))
}
@Test
fun scheduleReminderAtDefaultDueTime() {
val now = DateTimeUtils.newDateTime()
val task = newTask(with(ID, 1L), with(DUE_DATE, now), with(REMINDERS, Task.NOTIFY_AT_DEADLINE))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order
.verify(jobs)
.add(
ReminderEntry(
1, now.startOfDay().withHourOfDay(18).millis, ReminderService.TYPE_DUE))
}
@Test
fun dontScheduleReminderForCompletedTask() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTimeUtils.newDateTime().plusDays(1)),
with(COMPLETION_TIME, DateTimeUtils.newDateTime()),
with(REMINDERS, Task.NOTIFY_AT_DEADLINE))
service.scheduleAlarm(task)
Mockito.verify(jobs).cancelReminder(1)
}
@Test
fun dontScheduleReminderForDeletedTask() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTimeUtils.newDateTime().plusDays(1)),
with(DELETION_TIME, DateTimeUtils.newDateTime()),
with(REMINDERS, Task.NOTIFY_AT_DEADLINE))
service.scheduleAlarm(task)
Mockito.verify(jobs).cancelReminder(1)
}
@Test
fun dontScheduleDueDateReminderWhenAlreadyReminded() {
val now = DateTimeUtils.newDateTime()
val task = newTask(
with(ID, 1L),
with(DUE_TIME, now),
with(REMINDER_LAST, now.plusSeconds(1)),
with(REMINDERS, Task.NOTIFY_AT_DEADLINE))
service.scheduleAlarm(task)
Mockito.verify(jobs).cancelReminder(1)
}
@Test
fun ignoreStaleSnoozeTime() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTimeUtils.newDateTime()),
with(SNOOZE_TIME, DateTimeUtils.newDateTime().minusMinutes(5)),
with(REMINDER_LAST, DateTimeUtils.newDateTime().minusMinutes(4)),
with(REMINDERS, Task.NOTIFY_AT_DEADLINE))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order.verify(jobs).add(ReminderEntry(1, task.getDueDate(), ReminderService.TYPE_DUE))
}
@Test
fun dontIgnoreMissedSnoozeTime() {
val dueDate = DateTimeUtils.newDateTime()
val task = newTask(
with(ID, 1L),
with(DUE_TIME, dueDate),
with(SNOOZE_TIME, dueDate.minusMinutes(4)),
with(REMINDER_LAST, dueDate.minusMinutes(5)),
with(REMINDERS, Task.NOTIFY_AT_DEADLINE))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order
.verify(jobs)
.add(ReminderEntry(1, task.reminderSnooze, ReminderService.TYPE_SNOOZE))
}
@Test
fun scheduleInitialRandomReminder() {
Freeze.freezeClock {
val now = DateTimeUtils.newDateTime()
Mockito.`when`(random.nextFloat()).thenReturn(0.3865f)
val task = newTask(
with(ID, 1L),
with(REMINDER_LAST, null as DateTime?),
with(CREATION_TIME, now.minusDays(1)),
with(RANDOM_REMINDER_PERIOD, DateUtilities.ONE_WEEK))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order
.verify(jobs)
.add(
ReminderEntry(
1L,
now.minusDays(1).millis + 584206592,
ReminderService.TYPE_RANDOM))
}
}
@Test
fun scheduleNextRandomReminder() {
Freeze.freezeClock {
val now = DateTimeUtils.newDateTime()
Mockito.`when`(random.nextFloat()).thenReturn(0.3865f)
val task = newTask(
with(ID, 1L),
with(REMINDER_LAST, now.minusDays(1)),
with(CREATION_TIME, now.minusDays(30)),
with(RANDOM_REMINDER_PERIOD, DateUtilities.ONE_WEEK))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order
.verify(jobs)
.add(
ReminderEntry(
1L,
now.minusDays(1).millis + 584206592,
ReminderService.TYPE_RANDOM))
}
}
@Test
fun scheduleOverdueRandomReminder() {
Freeze.freezeClock {
val now = DateTimeUtils.newDateTime()
Mockito.`when`(random.nextFloat()).thenReturn(0.3865f)
val task = newTask(
with(ID, 1L),
with(REMINDER_LAST, now.minusDays(14)),
with(CREATION_TIME, now.minusDays(30)),
with(RANDOM_REMINDER_PERIOD, DateUtilities.ONE_WEEK))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order
.verify(jobs)
.add(
ReminderEntry(
1L, now.millis + 10148400, ReminderService.TYPE_RANDOM))
}
}
@Test
fun scheduleOverdueNoLastReminder() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, null as DateTime?),
with(REMINDERS, Task.NOTIFY_AFTER_DEADLINE))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order
.verify(jobs)
.add(
ReminderEntry(
1L,
DateTime(2017, 9, 23, 15, 30, 1, 0).millis,
ReminderService.TYPE_OVERDUE))
}
@Test
fun scheduleOverduePastLastReminder() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, DateTime(2017, 9, 24, 12, 0)),
with(REMINDERS, Task.NOTIFY_AFTER_DEADLINE))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order
.verify(jobs)
.add(
ReminderEntry(
1L,
DateTime(2017, 9, 24, 15, 30, 1, 0).millis,
ReminderService.TYPE_OVERDUE))
}
@Test
fun scheduleOverdueBeforeLastReminder() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 9, 22, 12, 30)),
with(REMINDER_LAST, DateTime(2017, 9, 24, 15, 0)),
with(REMINDERS, Task.NOTIFY_AFTER_DEADLINE))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order
.verify(jobs)
.add(
ReminderEntry(
1L,
DateTime(2017, 9, 25, 12, 30, 1, 0).millis,
ReminderService.TYPE_OVERDUE))
}
@Test
fun scheduleOverdueWithNoDueTime() {
preferences.setInt(R.string.p_rmd_time, TimeUnit.HOURS.toMillis(15).toInt())
val task = newTask(
with(ID, 1L),
with(DUE_DATE, DateTime(2017, 9, 22)),
with(REMINDER_LAST, DateTime(2017, 9, 23, 12, 17, 59, 999)),
with(REMINDERS, Task.NOTIFY_AFTER_DEADLINE))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order
.verify(jobs)
.add(
ReminderEntry(
1L,
DateTime(2017, 9, 23, 15, 0, 0, 0).millis,
ReminderService.TYPE_OVERDUE))
}
@Test
fun scheduleSubsequentOverdueReminder() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, DateTime(2017, 9, 23, 15, 30, 59, 999)),
with(REMINDERS, Task.NOTIFY_AFTER_DEADLINE))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order
.verify(jobs)
.add(
ReminderEntry(
1L,
DateTime(2017, 9, 24, 15, 30, 1, 0).millis,
ReminderService.TYPE_OVERDUE))
}
@Test
fun scheduleOverdueAfterLastReminder() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, DateTime(2017, 9, 23, 12, 17, 59, 999)),
with(REMINDERS, Task.NOTIFY_AFTER_DEADLINE))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order
.verify(jobs)
.add(
ReminderEntry(
1L,
DateTime(2017, 9, 23, 15, 30, 1, 0).millis,
ReminderService.TYPE_OVERDUE))
}
@Test
fun snoozeOverridesAll() {
val now = DateTimeUtils.newDateTime()
val task = newTask(
with(ID, 1L),
with(DUE_TIME, now),
with(SNOOZE_TIME, now.plusMonths(12)),
with(REMINDERS, Task.NOTIFY_AT_DEADLINE or Task.NOTIFY_AFTER_DEADLINE),
with(RANDOM_REMINDER_PERIOD, DateUtilities.ONE_HOUR))
service.scheduleAlarm(task)
val order = Mockito.inOrder(jobs)
order.verify(jobs).cancelReminder(1)
order
.verify(jobs)
.add(ReminderEntry(1, now.plusMonths(12).millis, ReminderService.TYPE_SNOOZE))
}
}

@ -1,272 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.repeats;
import static junit.framework.Assert.assertEquals;
import static org.tasks.date.DateTimeUtils.newDateTime;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.ical.values.Frequency;
import com.google.ical.values.RRule;
import com.google.ical.values.Weekday;
import com.google.ical.values.WeekdayNum;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.data.Task;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class AdvancedRepeatTest {
private static final int PREV_PREV = -2;
private static final int PREV = -1;
private static final int THIS = 1;
private static final int NEXT = 2;
private Task task;
private long nextDueDate;
private RRule rrule;
public static void assertDateTimeEquals(long date, long other) {
assertEquals("Expected: " + newDateTime(date) + ", Actual: " + newDateTime(other), date, other);
}
// --- date with time tests
@Before
public void setUp() {
task = new Task();
task.setCompletionDate(DateUtilities.now());
rrule = new RRule();
}
@Test
public void testDueDateSpecificTime() throws ParseException {
buildRRule(1, Frequency.DAILY);
// test specific day & time
long dayWithTime =
Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY_TIME, new DateTime(2010, 8, 1, 10, 4, 0).getMillis());
task.setDueDate(dayWithTime);
long nextDayWithTime = dayWithTime + DateUtilities.ONE_DAY;
nextDueDate = RepeatTaskHelper.computeNextDueDate(task, rrule.toIcal(), false);
assertDateTimeEquals(nextDayWithTime, nextDueDate);
}
// --- due date tests
@Test
public void testCompletionDateSpecificTime() throws ParseException {
buildRRule(1, Frequency.DAILY);
// test specific day & time
long dayWithTime =
Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY_TIME, new DateTime(2010, 8, 1, 10, 4, 0).getMillis());
task.setDueDate(dayWithTime);
DateTime todayWithTime =
newDateTime().withHourOfDay(10).withMinuteOfHour(4).withSecondOfMinute(1);
long nextDayWithTimeLong = todayWithTime.getMillis();
nextDayWithTimeLong += DateUtilities.ONE_DAY;
nextDayWithTimeLong = nextDayWithTimeLong / 1000L * 1000;
nextDueDate = RepeatTaskHelper.computeNextDueDate(task, rrule.toIcal(), true);
assertDateTimeEquals(nextDayWithTimeLong, nextDueDate);
}
/** test multiple days per week - DUE DATE */
@Test
public void testDueDateInPastSingleWeekMultiDay() throws Exception {
buildRRule(1, Frequency.WEEKLY, Weekday.MO, Weekday.WE, Weekday.FR);
setTaskDueDate(THIS, Calendar.SUNDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, THIS, Calendar.MONDAY);
setTaskDueDate(THIS, Calendar.MONDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, THIS, Calendar.WEDNESDAY);
setTaskDueDate(THIS, Calendar.FRIDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, THIS, Calendar.MONDAY);
}
/** test single day repeats - DUE DATE */
@Test
public void testDueDateSingleDay() throws Exception {
buildRRule(1, Frequency.WEEKLY, Weekday.MO);
setTaskDueDate(PREV_PREV, Calendar.MONDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY);
setTaskDueDate(PREV_PREV, Calendar.FRIDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, THIS, Calendar.MONDAY);
setTaskDueDate(PREV, Calendar.MONDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY);
setTaskDueDate(PREV, Calendar.FRIDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, THIS, Calendar.MONDAY);
setTaskDueDate(THIS, Calendar.SUNDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, THIS, Calendar.MONDAY);
setTaskDueDate(THIS, Calendar.MONDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY);
}
/** test multiple days per week - DUE DATE */
@Test
public void testDueDateSingleWeekMultiDay() throws Exception {
buildRRule(1, Frequency.WEEKLY, Weekday.MO, Weekday.WE, Weekday.FR);
setTaskDueDate(THIS, Calendar.SUNDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, THIS, Calendar.MONDAY);
setTaskDueDate(THIS, Calendar.MONDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, THIS, Calendar.WEDNESDAY);
setTaskDueDate(THIS, Calendar.FRIDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, THIS, Calendar.MONDAY);
}
// --- completion tests
/** test multiple days per week, multiple intervals - DUE DATE */
@Test
public void testDueDateMultiWeekMultiDay() throws Exception {
buildRRule(2, Frequency.WEEKLY, Weekday.MO, Weekday.WE, Weekday.FR);
setTaskDueDate(THIS, Calendar.SUNDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY);
setTaskDueDate(THIS, Calendar.MONDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, THIS, Calendar.WEDNESDAY);
setTaskDueDate(THIS, Calendar.FRIDAY);
computeNextDueDate(false);
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY);
}
/** test multiple days per week - COMPLETE DATE */
@Test
public void testCompleteDateSingleWeek() throws Exception {
for (Weekday wday : Weekday.values()) {
buildRRule(1, Frequency.WEEKLY, wday);
computeNextDueDate(true);
long expected = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, wday.javaDayNum);
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate);
assertEquals(expected, nextDueDate);
}
for (Weekday wday1 : Weekday.values()) {
for (Weekday wday2 : Weekday.values()) {
if (wday1 == wday2) {
continue;
}
buildRRule(1, Frequency.WEEKLY, wday1, wday2);
long nextOne = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, wday1.javaDayNum);
long nextTwo = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, wday2.javaDayNum);
computeNextDueDate(true);
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate);
assertEquals(Math.min(nextOne, nextTwo), nextDueDate);
}
}
}
// --- helpers
/** test multiple days per week, multiple intervals - COMPLETE DATE */
@Test
public void testCompleteDateMultiWeek() throws Exception {
for (Weekday wday : Weekday.values()) {
buildRRule(2, Frequency.WEEKLY, wday);
computeNextDueDate(true);
long expected = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, wday.javaDayNum);
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate);
assertEquals(expected, nextDueDate);
}
for (Weekday wday1 : Weekday.values()) {
for (Weekday wday2 : Weekday.values()) {
if (wday1 == wday2) {
continue;
}
buildRRule(2, Frequency.WEEKLY, wday1, wday2);
long nextOne = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, wday1.javaDayNum);
long nextTwo = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, wday2.javaDayNum);
computeNextDueDate(true);
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate);
assertEquals(Math.min(nextOne, nextTwo), nextDueDate);
}
}
}
private void computeNextDueDate(boolean fromComplete) throws ParseException {
nextDueDate = RepeatTaskHelper.computeNextDueDate(task, rrule.toIcal(), fromComplete);
}
private void buildRRule(int interval, Frequency freq, Weekday... weekdays) {
rrule.setInterval(interval);
rrule.setFreq(freq);
setRRuleDays(rrule, weekdays);
}
private void assertDueDate(long actual, int expectedWhich, int expectedDayOfWeek) {
long expected = getDate(task.getDueDate(), expectedWhich, expectedDayOfWeek);
assertEquals(expected, actual);
}
private void setRRuleDays(RRule rrule, Weekday... weekdays) {
ArrayList<WeekdayNum> days = new ArrayList<>();
for (Weekday wd : weekdays) {
days.add(new WeekdayNum(0, wd));
}
rrule.setByDay(days);
}
private void setTaskDueDate(int which, int day) {
long time = getDate(DateUtilities.now(), which, day);
task.setDueDate(time);
}
private long getDate(long start, int which, int dayOfWeek) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(start);
int direction = which > 0 ? 1 : -1;
while (c.get(Calendar.DAY_OF_WEEK) != dayOfWeek) {
c.add(Calendar.DAY_OF_MONTH, direction);
}
c.add(Calendar.DAY_OF_MONTH, (Math.abs(which) - 1) * direction * 7);
return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, c.getTimeInMillis());
}
}

@ -0,0 +1,246 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.repeats
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.ical.values.Frequency
import com.google.ical.values.RRule
import com.google.ical.values.Weekday
import com.google.ical.values.WeekdayNum
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.data.Task
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.date.DateTimeUtils
import org.tasks.time.DateTime
import java.text.ParseException
import java.util.*
import kotlin.math.abs
import kotlin.math.min
@RunWith(AndroidJUnit4::class)
class AdvancedRepeatTest {
private var task: Task? = null
private var nextDueDate: Long = 0
private var rrule: RRule? = null
// --- date with time tests
@Before
fun setUp() {
task = Task()
task!!.completionDate = DateUtilities.now()
rrule = RRule()
}
@Test
@Throws(ParseException::class)
fun testDueDateSpecificTime() {
buildRRule(1, Frequency.DAILY)
// test specific day & time
val dayWithTime = Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY_TIME, DateTime(2010, 8, 1, 10, 4, 0).millis)
task!!.setDueDate(dayWithTime)
val nextDayWithTime = dayWithTime + DateUtilities.ONE_DAY
nextDueDate = RepeatTaskHelper.computeNextDueDate(task, rrule!!.toIcal(), false)
assertDateTimeEquals(nextDayWithTime, nextDueDate)
}
// --- due date tests
@Test
@Throws(ParseException::class)
fun testCompletionDateSpecificTime() {
buildRRule(1, Frequency.DAILY)
// test specific day & time
val dayWithTime = Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY_TIME, DateTime(2010, 8, 1, 10, 4, 0).millis)
task!!.setDueDate(dayWithTime)
val todayWithTime = DateTimeUtils.newDateTime().withHourOfDay(10).withMinuteOfHour(4).withSecondOfMinute(1)
var nextDayWithTimeLong = todayWithTime.millis
nextDayWithTimeLong += DateUtilities.ONE_DAY
nextDayWithTimeLong = nextDayWithTimeLong / 1000L * 1000
nextDueDate = RepeatTaskHelper.computeNextDueDate(task, rrule!!.toIcal(), true)
assertDateTimeEquals(nextDayWithTimeLong, nextDueDate)
}
/** test multiple days per week - DUE DATE */
@Test
@Throws(Exception::class)
fun testDueDateInPastSingleWeekMultiDay() {
buildRRule(1, Frequency.WEEKLY, Weekday.MO, Weekday.WE, Weekday.FR)
setTaskDueDate(THIS, Calendar.SUNDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
setTaskDueDate(THIS, Calendar.MONDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.WEDNESDAY)
setTaskDueDate(THIS, Calendar.FRIDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
}
/** test single day repeats - DUE DATE */
@Test
@Throws(Exception::class)
fun testDueDateSingleDay() {
buildRRule(1, Frequency.WEEKLY, Weekday.MO)
setTaskDueDate(PREV_PREV, Calendar.MONDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY)
setTaskDueDate(PREV_PREV, Calendar.FRIDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
setTaskDueDate(PREV, Calendar.MONDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY)
setTaskDueDate(PREV, Calendar.FRIDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
setTaskDueDate(THIS, Calendar.SUNDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
setTaskDueDate(THIS, Calendar.MONDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY)
}
/** test multiple days per week - DUE DATE */
@Test
@Throws(Exception::class)
fun testDueDateSingleWeekMultiDay() {
buildRRule(1, Frequency.WEEKLY, Weekday.MO, Weekday.WE, Weekday.FR)
setTaskDueDate(THIS, Calendar.SUNDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
setTaskDueDate(THIS, Calendar.MONDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.WEDNESDAY)
setTaskDueDate(THIS, Calendar.FRIDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
}
// --- completion tests
/** test multiple days per week, multiple intervals - DUE DATE */
@Test
@Throws(Exception::class)
fun testDueDateMultiWeekMultiDay() {
buildRRule(2, Frequency.WEEKLY, Weekday.MO, Weekday.WE, Weekday.FR)
setTaskDueDate(THIS, Calendar.SUNDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY)
setTaskDueDate(THIS, Calendar.MONDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.WEDNESDAY)
setTaskDueDate(THIS, Calendar.FRIDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY)
}
/** test multiple days per week - COMPLETE DATE */
@Test
@Throws(Exception::class)
fun testCompleteDateSingleWeek() {
for (wday in Weekday.values()) {
buildRRule(1, Frequency.WEEKLY, wday)
computeNextDueDate(true)
val expected = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, wday.javaDayNum)
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate)
assertEquals(expected, nextDueDate)
}
for (wday1 in Weekday.values()) {
for (wday2 in Weekday.values()) {
if (wday1 == wday2) {
continue
}
buildRRule(1, Frequency.WEEKLY, wday1, wday2)
val nextOne = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, wday1.javaDayNum)
val nextTwo = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, wday2.javaDayNum)
computeNextDueDate(true)
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate)
assertEquals(min(nextOne, nextTwo), nextDueDate)
}
}
}
// --- helpers
/** test multiple days per week, multiple intervals - COMPLETE DATE */
@Test
@Throws(Exception::class)
fun testCompleteDateMultiWeek() {
for (wday in Weekday.values()) {
buildRRule(2, Frequency.WEEKLY, wday)
computeNextDueDate(true)
val expected = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, wday.javaDayNum)
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate)
assertEquals(expected, nextDueDate)
}
for (wday1 in Weekday.values()) {
for (wday2 in Weekday.values()) {
if (wday1 == wday2) {
continue
}
buildRRule(2, Frequency.WEEKLY, wday1, wday2)
val nextOne = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, wday1.javaDayNum)
val nextTwo = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, wday2.javaDayNum)
computeNextDueDate(true)
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate)
assertEquals(min(nextOne, nextTwo), nextDueDate)
}
}
}
@Throws(ParseException::class)
private fun computeNextDueDate(fromComplete: Boolean) {
nextDueDate = RepeatTaskHelper.computeNextDueDate(task, rrule!!.toIcal(), fromComplete)
}
private fun buildRRule(interval: Int, freq: Frequency, vararg weekdays: Weekday) {
rrule!!.interval = interval
rrule!!.freq = freq
setRRuleDays(rrule, *weekdays)
}
private fun assertDueDate(actual: Long, expectedWhich: Int, expectedDayOfWeek: Int) {
val expected = getDate(task!!.getDueDate(), expectedWhich, expectedDayOfWeek)
assertEquals(expected, actual)
}
private fun setRRuleDays(rrule: RRule?, vararg weekdays: Weekday) {
val days = ArrayList<WeekdayNum>()
for (wd in weekdays) {
days.add(WeekdayNum(0, wd))
}
rrule!!.byDay = days
}
private fun setTaskDueDate(which: Int, day: Int) {
val time = getDate(DateUtilities.now(), which, day)
task!!.setDueDate(time)
}
private fun getDate(start: Long, which: Int, dayOfWeek: Int): Long {
val c = Calendar.getInstance()
c.timeInMillis = start
val direction = if (which > 0) 1 else -1
while (c[Calendar.DAY_OF_WEEK] != dayOfWeek) {
c.add(Calendar.DAY_OF_MONTH, direction)
}
c.add(Calendar.DAY_OF_MONTH, (abs(which) - 1) * direction * 7)
return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, c.timeInMillis)
}
companion object {
private const val PREV_PREV = -2
private const val PREV = -1
private const val THIS = 1
private const val NEXT = 2
fun assertDateTimeEquals(date: Long, other: Long) {
assertEquals("Expected: " + DateTimeUtils.newDateTime(date) + ", Actual: " + DateTimeUtils.newDateTime(other), date, other)
}
}
}

@ -1,284 +0,0 @@
package com.todoroo.astrid.repeats;
import static com.todoroo.astrid.repeats.RepeatTaskHelper.computeNextDueDate;
import static java.util.Arrays.asList;
import static junit.framework.Assert.assertEquals;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.ical.values.Frequency;
import com.google.ical.values.RRule;
import com.google.ical.values.Weekday;
import com.google.ical.values.WeekdayNum;
import com.todoroo.astrid.data.Task;
import java.text.ParseException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class NewRepeatTests {
@Test
public void testRepeatMinutelyFromDueDate() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 26, 12, 30);
Task task = newFromDue(Frequency.MINUTELY, 1, dueDateTime);
assertEquals(newDayTime(2016, 8, 26, 12, 31), calculateNextDueDate(task));
}
@Test
public void testRepeatHourlyFromDueDate() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 26, 12, 30);
Task task = newFromDue(Frequency.HOURLY, 1, dueDateTime);
assertEquals(newDayTime(2016, 8, 26, 13, 30), calculateNextDueDate(task));
}
@Test
public void testRepeatDailyFromDueDate() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 26, 12, 30);
Task task = newFromDue(Frequency.DAILY, 1, dueDateTime);
assertEquals(newDayTime(2016, 8, 27, 12, 30), calculateNextDueDate(task));
}
@Test
public void testRepeatWeeklyFromDueDate() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 28, 1, 34);
Task task = newFromDue(Frequency.WEEKLY, 1, dueDateTime);
assertEquals(newDayTime(2016, 9, 4, 1, 34), calculateNextDueDate(task));
}
@Test
public void testRepeatMonthlyFromDueDate() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 28, 1, 44);
Task task = newFromDue(Frequency.MONTHLY, 1, dueDateTime);
assertEquals(newDayTime(2016, 9, 28, 1, 44), calculateNextDueDate(task));
}
@Test
public void testRepeatYearlyFromDueDate() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 28, 1, 44);
Task task = newFromDue(Frequency.YEARLY, 1, dueDateTime);
assertEquals(newDayTime(2017, 8, 28, 1, 44), calculateNextDueDate(task));
}
/** Tests for repeating from completionDate */
@Test
public void testRepeatMinutelyFromCompleteDateCompleteBefore() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 30, 0, 25);
DateTime completionDateTime = newDayTime(2016, 8, 29, 0, 14);
Task task = newFromCompleted(Frequency.MINUTELY, 1, dueDateTime, completionDateTime);
assertEquals(newDayTime(2016, 8, 29, 0, 15), calculateNextDueDate(task));
}
@Test
public void testRepeatMinutelyFromCompleteDateCompleteAfter() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 28, 0, 4);
DateTime completionDateTime = newDayTime(2016, 8, 29, 0, 14);
Task task = newFromCompleted(Frequency.MINUTELY, 1, dueDateTime, completionDateTime);
assertEquals(newDayTime(2016, 8, 29, 0, 15), calculateNextDueDate(task));
}
@Test
public void testRepeatHourlyFromCompleteDateCompleteBefore() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 30, 0, 25);
DateTime completionDateTime = newDayTime(2016, 8, 29, 0, 14);
Task task = newFromCompleted(Frequency.HOURLY, 1, dueDateTime, completionDateTime);
assertEquals(newDayTime(2016, 8, 29, 1, 14), calculateNextDueDate(task));
}
@Test
public void testRepeatHourlyFromCompleteDateCompleteAfter() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 28, 0, 4);
DateTime completionDateTime = newDayTime(2016, 8, 29, 0, 14);
Task task = newFromCompleted(Frequency.HOURLY, 1, dueDateTime, completionDateTime);
assertEquals(newDayTime(2016, 8, 29, 1, 14), calculateNextDueDate(task));
}
@Test
public void testRepeatDailyFromCompleteDateCompleteBefore() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 30, 0, 25);
DateTime completionDateTime = newDayTime(2016, 8, 29, 0, 14);
Task task = newFromCompleted(Frequency.DAILY, 1, dueDateTime, completionDateTime);
assertEquals(newDayTime(2016, 8, 30, 0, 25), calculateNextDueDate(task));
}
@Test
public void testRepeatDailyFromCompleteDateCompleteAfter() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 28, 0, 4);
DateTime completionDateTime = newDayTime(2016, 8, 29, 0, 14);
Task task = newFromCompleted(Frequency.DAILY, 1, dueDateTime, completionDateTime);
assertEquals(newDayTime(2016, 8, 30, 0, 4), calculateNextDueDate(task));
}
@Test
public void testRepeatWeeklyFromCompleteDateCompleteBefore() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 30, 0, 25);
DateTime completionDateTime = newDayTime(2016, 8, 29, 0, 14);
Task task = newFromCompleted(Frequency.WEEKLY, 1, dueDateTime, completionDateTime);
assertEquals(newDayTime(2016, 9, 5, 0, 25), calculateNextDueDate(task));
}
@Test
public void testRepeatWeeklyFromCompleteDateCompleteAfter() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 28, 0, 4);
DateTime completionDateTime = newDayTime(2016, 8, 29, 0, 14);
Task task = newFromCompleted(Frequency.WEEKLY, 1, dueDateTime, completionDateTime);
assertEquals(newDayTime(2016, 9, 5, 0, 4), calculateNextDueDate(task));
}
@Test
public void testRepeatMonthlyFromCompleteDateCompleteBefore() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 30, 0, 25);
DateTime completionDateTime = newDayTime(2016, 8, 29, 0, 14);
Task task = newFromCompleted(Frequency.MONTHLY, 1, dueDateTime, completionDateTime);
assertEquals(newDayTime(2016, 9, 29, 0, 25), calculateNextDueDate(task));
}
@Test
public void testRepeatMonthlyFromCompleteDateCompleteAfter() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 28, 0, 4);
DateTime completionDateTime = newDayTime(2016, 8, 29, 0, 14);
Task task = newFromCompleted(Frequency.MONTHLY, 1, dueDateTime, completionDateTime);
assertEquals(newDayTime(2016, 9, 29, 0, 4), calculateNextDueDate(task));
}
@Test
public void testRepeatYearlyFromCompleteDateCompleteBefore() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 30, 0, 25);
DateTime completionDateTime = newDayTime(2016, 8, 29, 0, 14);
Task task = newFromCompleted(Frequency.YEARLY, 1, dueDateTime, completionDateTime);
assertEquals(newDayTime(2017, 8, 29, 0, 25), calculateNextDueDate(task));
}
@Test
public void testRepeatYearlyFromCompleteDateCompleteAfter() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 28, 0, 4);
DateTime completionDateTime = newDayTime(2016, 8, 29, 0, 14);
Task task = newFromCompleted(Frequency.YEARLY, 1, dueDateTime, completionDateTime);
assertEquals(newDayTime(2017, 8, 29, 0, 4), calculateNextDueDate(task));
}
@Test
public void testAdvancedRepeatWeeklyFromDueDate() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 29, 0, 25);
Task task =
newWeeklyFromDue(
1, dueDateTime, new WeekdayNum(0, Weekday.MO), new WeekdayNum(0, Weekday.WE));
assertEquals(newDayTime(2016, 8, 31, 0, 25), calculateNextDueDate(task));
}
@Test
public void testAdvancedRepeatWeeklyFromCompleteDateCompleteBefore() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 29, 0, 25);
DateTime completionDateTime = newDayTime(2016, 8, 28, 1, 9);
Task task =
newWeeklyFromCompleted(
1,
dueDateTime,
completionDateTime,
new WeekdayNum(0, Weekday.MO),
new WeekdayNum(0, Weekday.WE));
assertEquals(newDayTime(2016, 8, 29, 0, 25), calculateNextDueDate(task));
}
@Test
public void testAdvancedRepeatWeeklyFromCompleteDateCompleteAfter() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 29, 0, 25);
DateTime completionDateTime = newDayTime(2016, 9, 1, 1, 9);
Task task =
newWeeklyFromCompleted(
1,
dueDateTime,
completionDateTime,
new WeekdayNum(0, Weekday.MO),
new WeekdayNum(0, Weekday.WE));
assertEquals(newDayTime(2016, 9, 5, 0, 25), calculateNextDueDate(task));
}
private DateTime newDayTime(int year, int month, int day, int hour, int minute) {
return new DateTime(
Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY_TIME,
new DateTime(year, month, day, hour, minute).getMillis()));
}
private DateTime calculateNextDueDate(Task task) throws ParseException {
return new DateTime(
computeNextDueDate(task, task.sanitizedRecurrence(), task.repeatAfterCompletion()));
}
private Task newFromDue(Frequency frequency, int interval, DateTime dueDateTime) {
return new Task() {
{
setRecurrence(getRecurrenceRule(frequency, interval, false));
setDueDate(dueDateTime.getMillis());
}
};
}
private Task newWeeklyFromDue(int interval, DateTime dueDateTime, WeekdayNum... weekdays) {
return new Task() {
{
setRecurrence(getRecurrenceRule(Frequency.WEEKLY, interval, false, weekdays));
setDueDate(dueDateTime.getMillis());
}
};
}
private Task newFromCompleted(
Frequency frequency, int interval, DateTime dueDateTime, DateTime completionDate) {
return new Task() {
{
setRecurrence(getRecurrenceRule(frequency, interval, true));
setDueDate(dueDateTime.getMillis());
setCompletionDate(completionDate.getMillis());
}
};
}
private Task newWeeklyFromCompleted(
int interval, DateTime dueDateTime, DateTime completionDate, WeekdayNum... weekdays) {
return new Task() {
{
setRecurrence(getRecurrenceRule(Frequency.WEEKLY, interval, true, weekdays));
setDueDate(dueDateTime.getMillis());
setCompletionDate(completionDate.getMillis());
}
};
}
private String getRecurrenceRule(
Frequency frequency, int interval, boolean fromCompletion, WeekdayNum... weekdays) {
RRule rrule = new RRule();
rrule.setFreq(frequency);
rrule.setInterval(interval);
if (weekdays != null) {
rrule.setByDay(asList(weekdays));
}
String result = rrule.toIcal();
if (fromCompletion) {
result += ";FROM=COMPLETION";
}
return result;
}
}

@ -0,0 +1,278 @@
package com.todoroo.astrid.repeats
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.ical.values.Frequency
import com.google.ical.values.RRule
import com.google.ical.values.Weekday
import com.google.ical.values.WeekdayNum
import com.todoroo.astrid.data.Task
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.time.DateTime
import java.text.ParseException
@RunWith(AndroidJUnit4::class)
class NewRepeatTests {
@Test
@Throws(ParseException::class)
fun testRepeatMinutelyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 26, 12, 30)
val task = newFromDue(Frequency.MINUTELY, 1, dueDateTime)
assertEquals(newDayTime(2016, 8, 26, 12, 31), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatHourlyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 26, 12, 30)
val task = newFromDue(Frequency.HOURLY, 1, dueDateTime)
assertEquals(newDayTime(2016, 8, 26, 13, 30), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatDailyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 26, 12, 30)
val task = newFromDue(Frequency.DAILY, 1, dueDateTime)
assertEquals(newDayTime(2016, 8, 27, 12, 30), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatWeeklyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 28, 1, 34)
val task = newFromDue(Frequency.WEEKLY, 1, dueDateTime)
assertEquals(newDayTime(2016, 9, 4, 1, 34), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatMonthlyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 28, 1, 44)
val task = newFromDue(Frequency.MONTHLY, 1, dueDateTime)
assertEquals(newDayTime(2016, 9, 28, 1, 44), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatYearlyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 28, 1, 44)
val task = newFromDue(Frequency.YEARLY, 1, dueDateTime)
assertEquals(newDayTime(2017, 8, 28, 1, 44), calculateNextDueDate(task))
}
/** Tests for repeating from completionDate */
@Test
@Throws(ParseException::class)
fun testRepeatMinutelyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 30, 0, 25)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.MINUTELY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 8, 29, 0, 15), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatMinutelyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 28, 0, 4)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.MINUTELY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 8, 29, 0, 15), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatHourlyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 30, 0, 25)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.HOURLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 8, 29, 1, 14), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatHourlyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 28, 0, 4)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.HOURLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 8, 29, 1, 14), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatDailyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 30, 0, 25)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.DAILY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 8, 30, 0, 25), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatDailyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 28, 0, 4)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.DAILY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 8, 30, 0, 4), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatWeeklyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 30, 0, 25)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.WEEKLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 9, 5, 0, 25), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatWeeklyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 28, 0, 4)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.WEEKLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 9, 5, 0, 4), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatMonthlyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 30, 0, 25)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.MONTHLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 9, 29, 0, 25), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatMonthlyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 28, 0, 4)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.MONTHLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 9, 29, 0, 4), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatYearlyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 30, 0, 25)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.YEARLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2017, 8, 29, 0, 25), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatYearlyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 28, 0, 4)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.YEARLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2017, 8, 29, 0, 4), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testAdvancedRepeatWeeklyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 29, 0, 25)
val task = newWeeklyFromDue(
1, dueDateTime, WeekdayNum(0, Weekday.MO), WeekdayNum(0, Weekday.WE))
assertEquals(newDayTime(2016, 8, 31, 0, 25), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testAdvancedRepeatWeeklyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 29, 0, 25)
val completionDateTime = newDayTime(2016, 8, 28, 1, 9)
val task = newWeeklyFromCompleted(
1,
dueDateTime,
completionDateTime,
WeekdayNum(0, Weekday.MO),
WeekdayNum(0, Weekday.WE))
assertEquals(newDayTime(2016, 8, 29, 0, 25), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testAdvancedRepeatWeeklyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 29, 0, 25)
val completionDateTime = newDayTime(2016, 9, 1, 1, 9)
val task = newWeeklyFromCompleted(
1,
dueDateTime,
completionDateTime,
WeekdayNum(0, Weekday.MO),
WeekdayNum(0, Weekday.WE))
assertEquals(newDayTime(2016, 9, 5, 0, 25), calculateNextDueDate(task))
}
private fun newDayTime(year: Int, month: Int, day: Int, hour: Int, minute: Int): DateTime {
return DateTime(
Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY_TIME,
DateTime(year, month, day, hour, minute).millis))
}
@Throws(ParseException::class)
private fun calculateNextDueDate(task: Task): DateTime {
return DateTime(
RepeatTaskHelper.computeNextDueDate(task, task.sanitizedRecurrence(), task.repeatAfterCompletion()))
}
private fun newFromDue(frequency: Frequency, interval: Int, dueDateTime: DateTime): Task {
return object : Task() {
init {
setRecurrence(getRecurrenceRule(frequency, interval, false))
setDueDate(dueDateTime.millis)
}
}
}
private fun newWeeklyFromDue(interval: Int, dueDateTime: DateTime, vararg weekdays: WeekdayNum): Task {
return object : Task() {
init {
setRecurrence(getRecurrenceRule(Frequency.WEEKLY, interval, false, *weekdays))
setDueDate(dueDateTime.millis)
}
}
}
private fun newFromCompleted(
frequency: Frequency, interval: Int, dueDateTime: DateTime, completionDate: DateTime): Task {
return object : Task() {
init {
setRecurrence(getRecurrenceRule(frequency, interval, true))
setDueDate(dueDateTime.millis)
setCompletionDate(completionDate.millis)
}
}
}
private fun newWeeklyFromCompleted(
interval: Int, dueDateTime: DateTime, completionDate: DateTime, vararg weekdays: WeekdayNum): Task {
return object : Task() {
init {
setRecurrence(getRecurrenceRule(Frequency.WEEKLY, interval, true, *weekdays))
setDueDate(dueDateTime.millis)
setCompletionDate(completionDate.millis)
}
}
}
private fun getRecurrenceRule(
frequency: Frequency, interval: Int, fromCompletion: Boolean, vararg weekdays: WeekdayNum): String {
val rrule = RRule()
rrule.freq = frequency
rrule.interval = interval
if (weekdays.isNotEmpty()) {
rrule.byDay = listOf(*weekdays)
}
var result = rrule.toIcal()
if (fromCompletion) {
result += ";FROM=COMPLETION"
}
return result
}
}

@ -1,216 +0,0 @@
package com.todoroo.astrid.repeats;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.tasks.makers.TaskMaker.AFTER_COMPLETE;
import static org.tasks.makers.TaskMaker.COMPLETION_TIME;
import static org.tasks.makers.TaskMaker.DUE_TIME;
import static org.tasks.makers.TaskMaker.ID;
import static org.tasks.makers.TaskMaker.RRULE;
import static org.tasks.makers.TaskMaker.newTask;
import android.annotation.SuppressLint;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.ical.values.RRule;
import com.todoroo.astrid.alarms.AlarmService;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gcal.GCalHelper;
import java.text.ParseException;
import javax.inject.Inject;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.tasks.LocalBroadcastManager;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
import org.tasks.time.DateTime;
@SuppressLint("NewApi")
@RunWith(AndroidJUnit4.class)
public class RepeatTaskHelperTest extends InjectingTestCase {
@Inject TaskDao taskDao;
private LocalBroadcastManager localBroadcastManager;
private AlarmService alarmService;
private GCalHelper gCalHelper;
private RepeatTaskHelper helper;
private InOrder mocks;
@Before
public void before() {
alarmService = mock(AlarmService.class);
gCalHelper = mock(GCalHelper.class);
localBroadcastManager = mock(LocalBroadcastManager.class);
mocks = inOrder(alarmService, gCalHelper, localBroadcastManager);
helper = new RepeatTaskHelper(gCalHelper, alarmService, taskDao, localBroadcastManager);
}
@After
public void after() {
verifyNoMoreInteractions(localBroadcastManager, gCalHelper, alarmService);
}
@Test
public void noRepeat() {
helper.handleRepeat(newTask(with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30))));
}
@Test
public void testMinutelyRepeat() throws ParseException {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MINUTELY;INTERVAL=30")));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 4, 14, 0, 1));
}
@Test
public void testMinutelyRepeatAfterCompletion() throws ParseException {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(COMPLETION_TIME, new DateTime(2017, 10, 4, 13, 17, 45, 340)),
with(RRULE, new RRule("RRULE:FREQ=MINUTELY;INTERVAL=30")),
with(AFTER_COMPLETE, true));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 4, 13, 47, 1));
}
@Test
public void testMinutelyDecrementCount() throws ParseException {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MINUTELY;COUNT=2;INTERVAL=30")));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 4, 14, 0, 1));
assertEquals(1, new RRule(task.getRecurrenceWithoutFrom()).getCount());
}
@Test
public void testMinutelyLastOccurrence() throws ParseException {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MINUTELY;COUNT=1;INTERVAL=30")));
helper.handleRepeat(task);
}
@Test
public void testHourlyRepeat() throws ParseException {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=HOURLY;INTERVAL=6")));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 4, 19, 30, 1));
}
@Test
public void testHourlyRepeatAfterCompletion() throws ParseException {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(COMPLETION_TIME, new DateTime(2017, 10, 4, 13, 17, 45, 340)),
with(RRULE, new RRule("RRULE:FREQ=HOURLY;INTERVAL=6")),
with(AFTER_COMPLETE, true));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 4, 19, 17, 1));
}
@Test
public void testDailyRepeat() throws ParseException {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=DAILY;INTERVAL=6")));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 10, 13, 30, 1));
}
@Test
public void testRepeatWeeklyNoDays() throws ParseException {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=WEEKLY;INTERVAL=2")));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 18, 13, 30, 1));
}
@Test
public void testYearly() throws ParseException {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=YEARLY;INTERVAL=3")));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2020, 10, 4, 13, 30, 1));
}
@Test
public void testMonthlyRepeat() throws ParseException {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MONTHLY;INTERVAL=3")));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2018, 1, 4, 13, 30, 1));
}
@Test
public void testMonthlyRepeatAtEndOfMonth() throws ParseException {
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 1, 31, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MONTHLY;INTERVAL=1")));
repeatAndVerify(
task, new DateTime(2017, 1, 31, 13, 30, 1), new DateTime(2017, 2, 28, 13, 30, 1));
}
private void repeatAndVerify(Task task, DateTime oldDueDate, DateTime newDueDate) {
helper.handleRepeat(task);
mocks.verify(gCalHelper).rescheduleRepeatingTask(task);
mocks.verify(alarmService).rescheduleAlarms(1, oldDueDate.getMillis(), newDueDate.getMillis());
mocks
.verify(localBroadcastManager)
.broadcastRepeat(1, oldDueDate.getMillis(), newDueDate.getMillis());
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
}

@ -0,0 +1,193 @@
package com.todoroo.astrid.repeats
import android.annotation.SuppressLint
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.ical.values.RRule
import com.natpryce.makeiteasy.MakeItEasy.with
import com.todoroo.astrid.alarms.AlarmService
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.gcal.GCalHelper
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.InOrder
import org.mockito.Mockito
import org.tasks.LocalBroadcastManager
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.makers.TaskMaker.AFTER_COMPLETE
import org.tasks.makers.TaskMaker.COMPLETION_TIME
import org.tasks.makers.TaskMaker.DUE_TIME
import org.tasks.makers.TaskMaker.ID
import org.tasks.makers.TaskMaker.RRULE
import org.tasks.makers.TaskMaker.newTask
import org.tasks.time.DateTime
import java.text.ParseException
import javax.inject.Inject
@SuppressLint("NewApi")
@RunWith(AndroidJUnit4::class)
class RepeatTaskHelperTest : InjectingTestCase() {
@Inject lateinit var taskDao: TaskDao
private lateinit var localBroadcastManager: LocalBroadcastManager
private lateinit var alarmService: AlarmService
private lateinit var gCalHelper: GCalHelper
private lateinit var helper: RepeatTaskHelper
private lateinit var mocks: InOrder
@Before
fun before() {
alarmService = Mockito.mock(AlarmService::class.java)
gCalHelper = Mockito.mock(GCalHelper::class.java)
localBroadcastManager = Mockito.mock(LocalBroadcastManager::class.java)
mocks = Mockito.inOrder(alarmService, gCalHelper, localBroadcastManager)
helper = RepeatTaskHelper(gCalHelper, alarmService, taskDao, localBroadcastManager)
}
@After
fun after() {
Mockito.verifyNoMoreInteractions(localBroadcastManager, gCalHelper, alarmService)
}
@Test
fun noRepeat() {
helper.handleRepeat(newTask(with(DUE_TIME, DateTime(2017, 10, 4, 13, 30))))
}
@Test
@Throws(ParseException::class)
fun testMinutelyRepeat() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RRULE, RRule("RRULE:FREQ=MINUTELY;INTERVAL=30")))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 14, 0, 1))
}
@Test
@Throws(ParseException::class)
fun testMinutelyRepeatAfterCompletion() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(COMPLETION_TIME, DateTime(2017, 10, 4, 13, 17, 45, 340)),
with(RRULE, RRule("RRULE:FREQ=MINUTELY;INTERVAL=30")),
with(AFTER_COMPLETE, true))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 13, 47, 1))
}
@Test
@Throws(ParseException::class)
fun testMinutelyDecrementCount() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RRULE, RRule("RRULE:FREQ=MINUTELY;COUNT=2;INTERVAL=30")))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 14, 0, 1))
assertEquals(1, RRule(task.recurrenceWithoutFrom).count)
}
@Test
@Throws(ParseException::class)
fun testMinutelyLastOccurrence() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RRULE, RRule("RRULE:FREQ=MINUTELY;COUNT=1;INTERVAL=30")))
helper.handleRepeat(task)
}
@Test
@Throws(ParseException::class)
fun testHourlyRepeat() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RRULE, RRule("RRULE:FREQ=HOURLY;INTERVAL=6")))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 19, 30, 1))
}
@Test
@Throws(ParseException::class)
fun testHourlyRepeatAfterCompletion() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(COMPLETION_TIME, DateTime(2017, 10, 4, 13, 17, 45, 340)),
with(RRULE, RRule("RRULE:FREQ=HOURLY;INTERVAL=6")),
with(AFTER_COMPLETE, true))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 19, 17, 1))
}
@Test
@Throws(ParseException::class)
fun testDailyRepeat() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RRULE, RRule("RRULE:FREQ=DAILY;INTERVAL=6")))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 10, 13, 30, 1))
}
@Test
@Throws(ParseException::class)
fun testRepeatWeeklyNoDays() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RRULE, RRule("RRULE:FREQ=WEEKLY;INTERVAL=2")))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 18, 13, 30, 1))
}
@Test
@Throws(ParseException::class)
fun testYearly() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RRULE, RRule("RRULE:FREQ=YEARLY;INTERVAL=3")))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2020, 10, 4, 13, 30, 1))
}
@Test
@Throws(ParseException::class)
fun testMonthlyRepeat() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RRULE, RRule("RRULE:FREQ=MONTHLY;INTERVAL=3")))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2018, 1, 4, 13, 30, 1))
}
@Test
@Throws(ParseException::class)
fun testMonthlyRepeatAtEndOfMonth() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 1, 31, 13, 30)),
with(RRULE, RRule("RRULE:FREQ=MONTHLY;INTERVAL=1")))
repeatAndVerify(
task, DateTime(2017, 1, 31, 13, 30, 1), DateTime(2017, 2, 28, 13, 30, 1))
}
private fun repeatAndVerify(task: Task, oldDueDate: DateTime, newDueDate: DateTime) {
helper.handleRepeat(task)
mocks.verify(gCalHelper).rescheduleRepeatingTask(task)
mocks.verify(alarmService).rescheduleAlarms(1, oldDueDate.millis, newDueDate.millis)
mocks.verify(localBroadcastManager).broadcastRepeat(1, oldDueDate.millis, newDueDate.millis)
}
override fun inject(component: TestComponent) = component.inject(this)
}

@ -1,110 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.service;
import static junit.framework.Assert.assertEquals;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.Task.Priority;
import com.todoroo.astrid.utility.TitleParser;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.data.TagDataDao;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
@RunWith(AndroidJUnit4.class)
public class QuickAddMarkupTest extends InjectingTestCase {
private final ArrayList<String> tags = new ArrayList<>();
@Inject TagDataDao tagDataDao;
private Task task;
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
@Test
public void testTags() {
whenTitleIs("this #cool");
assertTitleBecomes("this");
assertTagsAre("cool");
whenTitleIs("#cool task");
assertTitleBecomes("task");
assertTagsAre("cool");
whenTitleIs("doggie #nice #cute");
assertTitleBecomes("doggie");
assertTagsAre("nice", "cute");
}
@Test
public void testContexts() {
whenTitleIs("eat @home");
assertTitleBecomes("eat");
assertTagsAre("home");
whenTitleIs("buy oatmeal @store @morning");
assertTitleBecomes("buy oatmeal");
assertTagsAre("store", "morning");
whenTitleIs("look @ me");
assertTitleBecomes("look @ me");
assertTagsAre();
}
// --- helpers
@Test
public void testPriorities() {
whenTitleIs("eat !1");
assertTitleBecomes("eat");
assertPriority(Priority.LOW);
whenTitleIs("super cool!");
assertTitleBecomes("super cool!");
whenTitleIs("stay alive !4");
assertTitleBecomes("stay alive");
assertPriority(Priority.HIGH);
}
@Test
public void testMixed() {
whenTitleIs("eat #food !2");
assertTitleBecomes("eat");
assertTagsAre("food");
assertPriority(Priority.MEDIUM);
}
private void assertTagsAre(String... expectedTags) {
List<String> expected = Arrays.asList(expectedTags);
assertEquals(expected.toString(), tags.toString());
}
private void assertTitleBecomes(String title) {
assertEquals(title, task.getTitle());
}
private void whenTitleIs(String title) {
task = new Task();
task.setTitle(title);
tags.clear();
TitleParser.parse(tagDataDao, task, tags);
}
private void assertPriority(int priority) {
assertEquals(priority, (int) task.getPriority());
}
}

@ -0,0 +1,95 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.service
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.utility.TitleParser
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.data.TagDataDao
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import java.util.*
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class QuickAddMarkupTest : InjectingTestCase() {
private val tags = ArrayList<String>()
@Inject lateinit var tagDataDao: TagDataDao
private var task: Task? = null
override fun inject(component: TestComponent) = component.inject(this)
@Test
fun testTags() {
whenTitleIs("this #cool")
assertTitleBecomes("this")
assertTagsAre("cool")
whenTitleIs("#cool task")
assertTitleBecomes("task")
assertTagsAre("cool")
whenTitleIs("doggie #nice #cute")
assertTitleBecomes("doggie")
assertTagsAre("nice", "cute")
}
@Test
fun testContexts() {
whenTitleIs("eat @home")
assertTitleBecomes("eat")
assertTagsAre("home")
whenTitleIs("buy oatmeal @store @morning")
assertTitleBecomes("buy oatmeal")
assertTagsAre("store", "morning")
whenTitleIs("look @ me")
assertTitleBecomes("look @ me")
assertTagsAre()
}
// --- helpers
@Test
fun testPriorities() {
whenTitleIs("eat !1")
assertTitleBecomes("eat")
assertPriority(Task.Priority.LOW)
whenTitleIs("super cool!")
assertTitleBecomes("super cool!")
whenTitleIs("stay alive !4")
assertTitleBecomes("stay alive")
assertPriority(Task.Priority.HIGH)
}
@Test
fun testMixed() {
whenTitleIs("eat #food !2")
assertTitleBecomes("eat")
assertTagsAre("food")
assertPriority(Task.Priority.MEDIUM)
}
private fun assertTagsAre(vararg expectedTags: String) {
val expected = listOf(*expectedTags)
assertEquals(expected.toString(), tags.toString())
}
private fun assertTitleBecomes(title: String) {
assertEquals(title, task!!.getTitle())
}
private fun whenTitleIs(title: String) {
task = Task()
task!!.setTitle(title)
tags.clear()
TitleParser.parse(tagDataDao, task, tags)
}
private fun assertPriority(priority: Int) {
assertEquals(priority, task!!.getPriority() as Int)
}
}

@ -1,434 +0,0 @@
package com.todoroo.astrid.service;
import static com.google.common.collect.FluentIterable.from;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.tasks.makers.CaldavTaskMaker.CALENDAR;
import static org.tasks.makers.CaldavTaskMaker.REMOTE_ID;
import static org.tasks.makers.CaldavTaskMaker.REMOTE_PARENT;
import static org.tasks.makers.CaldavTaskMaker.newCaldavTask;
import static org.tasks.makers.GoogleTaskMaker.LIST;
import static org.tasks.makers.GoogleTaskMaker.PARENT;
import static org.tasks.makers.GoogleTaskMaker.TASK;
import static org.tasks.makers.GoogleTaskMaker.newGoogleTask;
import static org.tasks.makers.GtaskListMaker.newGtaskList;
import static org.tasks.makers.TaskMaker.ID;
import static org.tasks.makers.TaskMaker.newTask;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SdkSuppress;
import com.google.common.primitives.Longs;
import com.todoroo.astrid.api.CaldavFilter;
import com.todoroo.astrid.api.GtasksFilter;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import java.util.List;
import javax.inject.Inject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.data.CaldavCalendar;
import org.tasks.data.CaldavDao;
import org.tasks.data.CaldavTask;
import org.tasks.data.GoogleTask;
import org.tasks.data.GoogleTaskDao;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
import org.tasks.jobs.WorkManager;
import org.tasks.makers.CaldavTaskMaker;
import org.tasks.makers.GtaskListMaker;
import org.tasks.makers.TaskMaker;
@RunWith(AndroidJUnit4.class)
public class TaskMoverTest extends InjectingTestCase {
@Inject TaskDao taskDao;
@Inject GoogleTaskDao googleTaskDao;
@Inject WorkManager workManager;
@Inject CaldavDao caldavDao;
@Inject TaskMover taskMover;
@Before
public void setUp() {
super.setUp();
taskDao.initialize(workManager);
}
@Test
public void moveBetweenGoogleTaskLists() {
createTasks(1);
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")));
moveToGoogleTasks("2", 1);
assertEquals("2", googleTaskDao.getByTaskId(1).getListId());
}
@Test
public void deleteGoogleTaskAfterMove() {
createTasks(1);
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")));
moveToGoogleTasks("2", 1);
List<GoogleTask> deleted = googleTaskDao.getDeletedByTaskId(1);
assertEquals(1, deleted.size());
assertEquals(1, deleted.get(0).getTask());
assertTrue(deleted.get(0).getDeleted() > 0);
}
@Test
public void moveChildrenBetweenGoogleTaskLists() {
createTasks(1, 2);
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")));
googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(PARENT, 1L)));
moveToGoogleTasks("2", 1);
List<GoogleTask> deleted = googleTaskDao.getDeletedByTaskId(2);
assertEquals(1, deleted.size());
assertEquals(2, deleted.get(0).getTask());
assertTrue(deleted.get(0).getDeleted() > 0);
GoogleTask task = googleTaskDao.getByTaskId(2);
assertEquals(1, task.getParent());
assertEquals("2", task.getListId());
}
@Test
public void moveBetweenCaldavList() {
createTasks(1);
caldavDao.insert(newCaldavTask(with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1")));
moveToCaldavList("2", 1);
assertEquals("2", caldavDao.getTask(1).getCalendar());
}
@Test
public void deleteCaldavTaskAfterMove() {
createTasks(1);
caldavDao.insert(newCaldavTask(with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1")));
moveToCaldavList("2", 1);
List<CaldavTask> deleted = caldavDao.getDeleted("1");
assertEquals(1, deleted.size());
assertEquals(1, deleted.get(0).getTask());
assertTrue(deleted.get(0).getDeleted() > 0);
}
@Test
@SdkSuppress(minSdkVersion = 21)
public void moveRecursiveCaldavChildren() {
createTasks(1);
createSubtask(2, 1);
createSubtask(3, 2);
caldavDao.insert(
asList(
newCaldavTask(
with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"), with(REMOTE_ID, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 2L),
with(CALENDAR, "1"),
with(REMOTE_ID, "b"),
with(REMOTE_PARENT, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 3L),
with(CALENDAR, "1"),
with(REMOTE_PARENT, "b"))));
moveToCaldavList("2", 1);
List<CaldavTask> deleted = caldavDao.getDeleted("1");
assertEquals(3, deleted.size());
CaldavTask task = caldavDao.getTask(3);
assertEquals("2", task.getCalendar());
assertEquals(2, taskDao.fetch(3).getParent());
}
@Test
public void moveGoogleTaskChildrenToCaldav() {
createTasks(1, 2);
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")));
googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(PARENT, 1L)));
moveToCaldavList("1", 1);
CaldavTask task = caldavDao.getTask(2);
assertEquals("1", task.getCalendar());
assertEquals(1, taskDao.fetch(2).getParent());
}
@Test
@SdkSuppress(minSdkVersion = 21)
public void flattenLocalSubtasksWhenMovingToGoogleTasks() {
createTasks(1);
createSubtask(2, 1);
createSubtask(3, 2);
moveToGoogleTasks("1", 1);
assertEquals(1, googleTaskDao.getByTaskId(3).getParent());
assertEquals(0, taskDao.fetch(3).getParent());
}
@Test
public void moveLocalChildToGoogleTasks() {
createTasks(1);
createSubtask(2, 1);
moveToGoogleTasks("1", 2);
assertEquals(0, taskDao.fetch(2).getParent());
}
@Test
public void moveLocalChildToCaldav() {
createTasks(1);
createSubtask(2, 1);
moveToCaldavList("1", 2);
assertEquals(0, taskDao.fetch(2).getParent());
}
@Test
@SdkSuppress(minSdkVersion = 21)
public void flattenCaldavSubtasksWhenMovingToGoogleTasks() {
createTasks(1);
createSubtask(2, 1);
createSubtask(3, 2);
caldavDao.insert(
asList(
newCaldavTask(
with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"), with(REMOTE_ID, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 2L),
with(CALENDAR, "1"),
with(REMOTE_ID, "b"),
with(REMOTE_PARENT, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 3L),
with(CALENDAR, "1"),
with(REMOTE_PARENT, "b"))));
moveToGoogleTasks("1", 1);
GoogleTask task = googleTaskDao.getByTaskId(3L);
assertEquals(1, task.getParent());
}
@Test
public void moveGoogleTaskChildWithoutParent() {
createTasks(1, 2);
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")));
googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(PARENT, 1L)));
moveToGoogleTasks("2", 2);
GoogleTask task = googleTaskDao.getByTaskId(2);
assertEquals(0L, task.getParent());
assertEquals("2", task.getListId());
}
@Test
public void moveCaldavChildWithoutParent() {
createTasks(1);
createSubtask(2, 1);
caldavDao.insert(
asList(
newCaldavTask(
with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"), with(REMOTE_ID, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 2L),
with(CALENDAR, "1"),
with(REMOTE_PARENT, "a"))));
moveToCaldavList("2", 2);
assertEquals("2", caldavDao.getTask(2).getCalendar());
assertEquals(0, taskDao.fetch(2).getParent());
}
@Test
public void moveGoogleTaskToCaldav() {
createTasks(1);
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")));
moveToCaldavList("2", 1);
assertEquals("2", caldavDao.getTask(1).getCalendar());
}
@Test
public void moveCaldavToGoogleTask() {
createTasks(1);
caldavDao.insert(newCaldavTask(with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1")));
moveToGoogleTasks("2", 1);
assertEquals("2", googleTaskDao.getByTaskId(1L).getListId());
}
@Test
public void moveLocalToCaldav() {
createTasks(1);
createSubtask(2, 1);
createSubtask(3, 2);
moveToCaldavList("1", 1);
assertEquals("1", caldavDao.getTask(3).getCalendar());
assertEquals(2, taskDao.fetch(3).getParent());
}
@Test
public void dontSyncGoogleTask() {
createTasks(1);
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")));
dontSync(1);
assertNull(googleTaskDao.getByTaskId(1));
assertFalse(taskDao.fetch(1).isDeleted());
}
@Test
public void dontSyncCaldavTask() {
createTasks(1);
caldavDao.insert(newCaldavTask(with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1")));
dontSync(1);
assertNull(caldavDao.getTask(1));
assertFalse(taskDao.fetch(1).isDeleted());
}
@Test
public void dontSyncGoogleTaskWithSubtasks() {
createTasks(1, 2);
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")));
googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(PARENT, 1L)));
dontSync(1);
assertNull(googleTaskDao.getByTaskId(2));
Task task = taskDao.fetch(2);
assertFalse(task.isDeleted());
assertEquals(1, task.getParent());
assertEquals(taskDao.fetch(1).getUuid(), task.getParentUuid());
}
@Test
public void dontSyncCaldavWithSubtasks() {
createTasks(1);
createSubtask(2, 1);
createSubtask(3, 2);
caldavDao.insert(
asList(
newCaldavTask(
with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"), with(REMOTE_ID, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 2L),
with(CALENDAR, "1"),
with(REMOTE_ID, "b"),
with(REMOTE_PARENT, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 3L),
with(CALENDAR, "1"),
with(REMOTE_PARENT, "b"))));
dontSync(1);
assertNull(caldavDao.getTask(3));
Task task = taskDao.fetch(3);
assertFalse(task.isDeleted());
assertEquals(2, task.getParent());
assertEquals(taskDao.fetch(2).getUuid(), task.getParentUuid());
}
@Test
public void moveToSameGoogleTaskListIsNoop() {
createTasks(1);
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")));
moveToGoogleTasks("1", 1);
assertTrue(googleTaskDao.getDeletedByTaskId(1).isEmpty());
assertEquals(1, googleTaskDao.getAllByTaskId(1).size());
}
@Test
public void moveToSameCaldavListIsNoop() {
createTasks(1);
caldavDao.insert(newCaldavTask(with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1")));
moveToCaldavList("1", 1);
assertTrue(caldavDao.getDeleted("1").isEmpty());
assertEquals(1, caldavDao.getTasks(1).size());
}
@Test
public void dontDuplicateWhenParentAndChildGoogleTaskMoved() {
createTasks(1, 2);
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")));
googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(PARENT, 1L)));
moveToGoogleTasks("2", 1, 2);
assertEquals(1, from(googleTaskDao.getAllByTaskId(2)).filter(t -> t.getDeleted() == 0).size());
}
@Test
public void dontDuplicateWhenParentAndChildCaldavMoved() {
createTasks(1);
createSubtask(2, 1);
caldavDao.insert(
asList(
newCaldavTask(
with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"), with(REMOTE_ID, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 2L),
with(CALENDAR, "1"),
with(REMOTE_PARENT, "a"))));
moveToCaldavList("2", 1, 2);
assertEquals(1, from(caldavDao.getTasks(2)).filter(t -> t.getDeleted() == 0).size());
}
private void createTasks(long... ids) {
for (long id : ids) {
taskDao.createNew(newTask(with(ID, id)));
}
}
private void createSubtask(long id, long parent) {
taskDao.createNew(newTask(with(ID, id), with(TaskMaker.PARENT, parent)));
}
private void moveToGoogleTasks(String list, long... tasks) {
taskMover.move(
Longs.asList(tasks), new GtasksFilter(newGtaskList(with(GtaskListMaker.REMOTE_ID, list))));
}
private void moveToCaldavList(String calendar, long... tasks) {
taskMover.move(Longs.asList(tasks), new CaldavFilter(new CaldavCalendar("", calendar)));
}
private void dontSync(long task) {
taskMover.move(singletonList(task), null);
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
}

@ -0,0 +1,364 @@
package com.todoroo.astrid.service
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.natpryce.makeiteasy.MakeItEasy.with
import com.todoroo.astrid.api.CaldavFilter
import com.todoroo.astrid.api.GtasksFilter
import com.todoroo.astrid.dao.TaskDao
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.data.CaldavCalendar
import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskDao
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.jobs.WorkManager
import org.tasks.makers.CaldavTaskMaker
import org.tasks.makers.CaldavTaskMaker.CALENDAR
import org.tasks.makers.CaldavTaskMaker.REMOTE_ID
import org.tasks.makers.CaldavTaskMaker.REMOTE_PARENT
import org.tasks.makers.CaldavTaskMaker.newCaldavTask
import org.tasks.makers.GoogleTaskMaker.LIST
import org.tasks.makers.GoogleTaskMaker.PARENT
import org.tasks.makers.GoogleTaskMaker.TASK
import org.tasks.makers.GoogleTaskMaker.newGoogleTask
import org.tasks.makers.GtaskListMaker
import org.tasks.makers.GtaskListMaker.newGtaskList
import org.tasks.makers.TaskMaker
import org.tasks.makers.TaskMaker.ID
import org.tasks.makers.TaskMaker.newTask
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class TaskMoverTest : InjectingTestCase() {
@Inject lateinit var taskDao: TaskDao
@Inject lateinit var googleTaskDao: GoogleTaskDao
@Inject lateinit var workManager: WorkManager
@Inject lateinit var caldavDao: CaldavDao
@Inject lateinit var taskMover: TaskMover
@Before
override fun setUp() {
super.setUp()
taskDao.initialize(workManager)
}
@Test
fun moveBetweenGoogleTaskLists() {
createTasks(1)
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")))
moveToGoogleTasks("2", 1)
assertEquals("2", googleTaskDao.getByTaskId(1).listId)
}
@Test
fun deleteGoogleTaskAfterMove() {
createTasks(1)
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")))
moveToGoogleTasks("2", 1)
val deleted = googleTaskDao.getDeletedByTaskId(1)
assertEquals(1, deleted.size.toLong())
assertEquals(1, deleted[0].task)
assertTrue(deleted[0].deleted > 0)
}
@Test
fun moveChildrenBetweenGoogleTaskLists() {
createTasks(1, 2)
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")))
googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(PARENT, 1L)))
moveToGoogleTasks("2", 1)
val deleted = googleTaskDao.getDeletedByTaskId(2)
assertEquals(1, deleted.size.toLong())
assertEquals(2, deleted[0].task)
assertTrue(deleted[0].deleted > 0)
val task = googleTaskDao.getByTaskId(2)
assertEquals(1, task.parent)
assertEquals("2", task.listId)
}
@Test
fun moveBetweenCaldavList() {
createTasks(1)
caldavDao.insert(newCaldavTask(with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1")))
moveToCaldavList("2", 1)
assertEquals("2", caldavDao.getTask(1)!!.calendar)
}
@Test
fun deleteCaldavTaskAfterMove() {
createTasks(1)
caldavDao.insert(newCaldavTask(with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1")))
moveToCaldavList("2", 1)
val deleted = caldavDao.getDeleted("1")
assertEquals(1, deleted.size.toLong())
assertEquals(1, deleted[0].task)
assertTrue(deleted[0].deleted > 0)
}
@Test
fun moveRecursiveCaldavChildren() {
createTasks(1)
createSubtask(2, 1)
createSubtask(3, 2)
caldavDao.insert(
listOf(
newCaldavTask(
with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"), with(REMOTE_ID, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 2L),
with(CALENDAR, "1"),
with(REMOTE_ID, "b"),
with(REMOTE_PARENT, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 3L),
with(CALENDAR, "1"),
with(REMOTE_PARENT, "b"))))
moveToCaldavList("2", 1)
val deleted = caldavDao.getDeleted("1")
assertEquals(3, deleted.size.toLong())
val task = caldavDao.getTask(3)
assertEquals("2", task!!.calendar)
assertEquals(2, taskDao.fetch(3).getParent())
}
@Test
fun moveGoogleTaskChildrenToCaldav() {
createTasks(1, 2)
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")))
googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(PARENT, 1L)))
moveToCaldavList("1", 1)
val task = caldavDao.getTask(2)
assertEquals("1", task!!.calendar)
assertEquals(1, taskDao.fetch(2).getParent())
}
@Test
fun flattenLocalSubtasksWhenMovingToGoogleTasks() {
createTasks(1)
createSubtask(2, 1)
createSubtask(3, 2)
moveToGoogleTasks("1", 1)
assertEquals(1, googleTaskDao.getByTaskId(3).parent)
assertEquals(0, taskDao.fetch(3).getParent())
}
@Test
fun moveLocalChildToGoogleTasks() {
createTasks(1)
createSubtask(2, 1)
moveToGoogleTasks("1", 2)
assertEquals(0, taskDao.fetch(2).getParent())
}
@Test
fun moveLocalChildToCaldav() {
createTasks(1)
createSubtask(2, 1)
moveToCaldavList("1", 2)
assertEquals(0, taskDao.fetch(2).getParent())
}
@Test
fun flattenCaldavSubtasksWhenMovingToGoogleTasks() {
createTasks(1)
createSubtask(2, 1)
createSubtask(3, 2)
caldavDao.insert(
listOf(
newCaldavTask(
with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"), with(REMOTE_ID, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 2L),
with(CALENDAR, "1"),
with(REMOTE_ID, "b"),
with(REMOTE_PARENT, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 3L),
with(CALENDAR, "1"),
with(REMOTE_PARENT, "b"))))
moveToGoogleTasks("1", 1)
val task = googleTaskDao.getByTaskId(3L)
assertEquals(1, task.parent)
}
@Test
fun moveGoogleTaskChildWithoutParent() {
createTasks(1, 2)
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")))
googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(PARENT, 1L)))
moveToGoogleTasks("2", 2)
val task = googleTaskDao.getByTaskId(2)
assertEquals(0L, task.parent)
assertEquals("2", task.listId)
}
@Test
fun moveCaldavChildWithoutParent() {
createTasks(1)
createSubtask(2, 1)
caldavDao.insert(
listOf(
newCaldavTask(
with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"), with(REMOTE_ID, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 2L),
with(CALENDAR, "1"),
with(REMOTE_PARENT, "a"))))
moveToCaldavList("2", 2)
assertEquals("2", caldavDao.getTask(2)!!.calendar)
assertEquals(0, taskDao.fetch(2).getParent())
}
@Test
fun moveGoogleTaskToCaldav() {
createTasks(1)
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")))
moveToCaldavList("2", 1)
assertEquals("2", caldavDao.getTask(1)!!.calendar)
}
@Test
fun moveCaldavToGoogleTask() {
createTasks(1)
caldavDao.insert(newCaldavTask(with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1")))
moveToGoogleTasks("2", 1)
assertEquals("2", googleTaskDao.getByTaskId(1L).listId)
}
@Test
fun moveLocalToCaldav() {
createTasks(1)
createSubtask(2, 1)
createSubtask(3, 2)
moveToCaldavList("1", 1)
assertEquals("1", caldavDao.getTask(3)!!.calendar)
assertEquals(2, taskDao.fetch(3).getParent())
}
@Test
fun dontSyncGoogleTask() {
createTasks(1)
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")))
dontSync(1)
assertNull(googleTaskDao.getByTaskId(1))
assertFalse(taskDao.fetch(1).isDeleted)
}
@Test
fun dontSyncCaldavTask() {
createTasks(1)
caldavDao.insert(newCaldavTask(with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1")))
dontSync(1)
assertNull(caldavDao.getTask(1))
assertFalse(taskDao.fetch(1).isDeleted)
}
@Test
fun dontSyncGoogleTaskWithSubtasks() {
createTasks(1, 2)
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")))
googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(PARENT, 1L)))
dontSync(1)
assertNull(googleTaskDao.getByTaskId(2))
val task = taskDao.fetch(2)
assertFalse(task.isDeleted)
assertEquals(1, task.getParent())
assertEquals(taskDao.fetch(1).uuid, task.getParentUuid())
}
@Test
fun dontSyncCaldavWithSubtasks() {
createTasks(1)
createSubtask(2, 1)
createSubtask(3, 2)
caldavDao.insert(
listOf(
newCaldavTask(
with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"), with(REMOTE_ID, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 2L),
with(CALENDAR, "1"),
with(REMOTE_ID, "b"),
with(REMOTE_PARENT, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 3L),
with(CALENDAR, "1"),
with(REMOTE_PARENT, "b"))))
dontSync(1)
assertNull(caldavDao.getTask(3))
val task = taskDao.fetch(3)
assertFalse(task.isDeleted)
assertEquals(2, task.getParent())
assertEquals(taskDao.fetch(2).uuid, task.getParentUuid())
}
@Test
fun moveToSameGoogleTaskListIsNoop() {
createTasks(1)
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")))
moveToGoogleTasks("1", 1)
assertTrue(googleTaskDao.getDeletedByTaskId(1).isEmpty())
assertEquals(1, googleTaskDao.getAllByTaskId(1).size.toLong())
}
@Test
fun moveToSameCaldavListIsNoop() {
createTasks(1)
caldavDao.insert(newCaldavTask(with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1")))
moveToCaldavList("1", 1)
assertTrue(caldavDao.getDeleted("1").isEmpty())
assertEquals(1, caldavDao.getTasks(1).size.toLong())
}
@Test
fun dontDuplicateWhenParentAndChildGoogleTaskMoved() {
createTasks(1, 2)
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")))
googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(PARENT, 1L)))
moveToGoogleTasks("2", 1, 2)
assertEquals(1, googleTaskDao.getAllByTaskId(2).filter { it.deleted == 0L }.size)
}
@Test
fun dontDuplicateWhenParentAndChildCaldavMoved() {
createTasks(1)
createSubtask(2, 1)
caldavDao.insert(
listOf(
newCaldavTask(
with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"), with(REMOTE_ID, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 2L),
with(CALENDAR, "1"),
with(REMOTE_PARENT, "a"))))
moveToCaldavList("2", 1, 2)
assertEquals(1, caldavDao.getTasks(2).filter { it.deleted == 0L }.size)
}
private fun createTasks(vararg ids: Long) {
for (id in ids) {
taskDao.createNew(newTask(with(ID, id)))
}
}
private fun createSubtask(id: Long, parent: Long) {
taskDao.createNew(newTask(with(ID, id), with(TaskMaker.PARENT, parent)))
}
private fun moveToGoogleTasks(list: String, vararg tasks: Long) {
taskMover.move(tasks.toList(), GtasksFilter(newGtaskList(with(GtaskListMaker.REMOTE_ID, list))))
}
private fun moveToCaldavList(calendar: String, vararg tasks: Long) {
taskMover.move(tasks.toList(), CaldavFilter(CaldavCalendar("", calendar)))
}
private fun dontSync(task: Long) {
taskMover.move(listOf(task), null)
}
override fun inject(component: TestComponent) = component.inject(this)
}

@ -1,478 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.service;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotSame;
import static junit.framework.Assert.assertTrue;
import static org.tasks.date.DateTimeUtils.newDateTime;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.ical.values.Frequency;
import com.google.ical.values.RRule;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.Task.Priority;
import com.todoroo.astrid.utility.TitleParser;
import java.util.ArrayList;
import java.util.Calendar;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.R;
import org.tasks.data.TagDataDao;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
import org.tasks.preferences.Preferences;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class TitleParserTest extends InjectingTestCase {
@Inject TagDataDao tagDataDao;
@Inject Preferences preferences;
@Inject TaskCreator taskCreator;
@Override
public void setUp() {
super.setUp();
preferences.setStringFromInteger(R.string.p_default_urgency_key, 0);
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
/**
* test that completing a task w/ no regular expressions creates a simple task with no date, no
* repeat, no lists
*/
@Test
public void testNoRegexes() {
Task task = taskCreator.basicQuickAddTask("Jog");
Task nothing = new Task();
assertFalse(task.hasDueTime());
assertFalse(task.hasDueDate());
assertEquals(task.getRecurrence(), nothing.getRecurrence());
}
/** Tests correct date is parsed */
@Test
public void testMonthDate() {
String[] titleMonthStrings = {
"Jan.", "January",
"Feb.", "February",
"Mar.", "March",
"Apr.", "April",
"May", "May",
"Jun.", "June",
"Jul.", "July",
"Aug.", "August",
"Sep.", "September",
"Oct.", "October",
"Nov.", "November",
"Dec.", "December"
};
for (int i = 0; i < 23; i++) {
String testTitle = "Jog on " + titleMonthStrings[i] + " 12.";
Task task = insertTitleAddTask(testTitle);
DateTime date = newDateTime(task.getDueDate());
assertEquals(date.getMonthOfYear(), i / 2 + 1);
assertEquals(date.getDayOfMonth(), 12);
}
}
@Test
public void testMonthSlashDay() {
for (int i = 1; i < 13; i++) {
String testTitle = "Jog on " + i + "/12/13";
Task task = insertTitleAddTask(testTitle);
DateTime date = newDateTime(task.getDueDate());
assertEquals(date.getMonthOfYear(), i);
assertEquals(date.getDayOfMonth(), 12);
assertEquals(date.getYear(), 2013);
}
}
@Test
public void testArmyTime() {
String testTitle = "Jog on 23:21.";
Task task = insertTitleAddTask(testTitle);
DateTime date = newDateTime(task.getDueDate());
assertEquals(date.getHourOfDay(), 23);
assertEquals(date.getMinuteOfHour(), 21);
}
@Test
public void test_AM_PM() {
String testTitle = "Jog at 8:33 PM.";
Task task = insertTitleAddTask(testTitle);
DateTime date = newDateTime(task.getDueDate());
assertEquals(date.getHourOfDay(), 20);
assertEquals(date.getMinuteOfHour(), 33);
}
@Test
public void test_at_hour() {
String testTitle = "Jog at 8 PM.";
Task task = insertTitleAddTask(testTitle);
DateTime date = newDateTime(task.getDueDate());
assertEquals(date.getHourOfDay(), 20);
assertEquals(date.getMinuteOfHour(), 0);
}
@Test
public void test_oclock_AM() {
String testTitle = "Jog at 8 o'clock AM.";
Task task = insertTitleAddTask(testTitle);
DateTime date = newDateTime(task.getDueDate());
assertEquals(date.getHourOfDay(), 8);
assertEquals(date.getMinuteOfHour(), 0);
}
@Test
public void test_several_forms_of_eight() {
String[] testTitles = {"Jog 8 AM", "Jog 8 o'clock AM", "at 8:00 AM"};
for (String testTitle : testTitles) {
Task task = insertTitleAddTask(testTitle);
DateTime date = newDateTime(task.getDueDate());
assertEquals(date.getHourOfDay(), 8);
assertEquals(date.getMinuteOfHour(), 0);
}
}
@Test
public void test_several_forms_of_1230PM() {
String[] testTitles = {
"Jog 12:30 PM", "at 12:30 PM", "Do something on 12:30 PM", "Jog at 12:30 PM Friday"
};
for (String testTitle : testTitles) {
Task task = insertTitleAddTask(testTitle);
DateTime date = newDateTime(task.getDueDate());
assertEquals(date.getHourOfDay(), 12);
assertEquals(date.getMinuteOfHour(), 30);
}
}
private Task insertTitleAddTask(String title) {
return taskCreator.createWithValues(title);
}
// ----------------Days begin----------------//
@Test
public void testDays() {
Calendar today = Calendar.getInstance();
String title = "Jog today";
Task task = taskCreator.createWithValues(title);
DateTime date = newDateTime(task.getDueDate());
assertEquals(date.getDayOfWeek(), today.get(Calendar.DAY_OF_WEEK));
// Calendar starts 1-6, date.getDay() starts at 0
title = "Jog tomorrow";
task = taskCreator.createWithValues(title);
date = newDateTime(task.getDueDate());
assertEquals((date.getDayOfWeek()) % 7, (today.get(Calendar.DAY_OF_WEEK) + 1) % 7);
String[] days = {
"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday",
};
String[] abrevDays = {"sun.", "mon.", "tue.", "wed.", "thu.", "fri.", "sat."};
for (int i = 1; i <= 6; i++) {
title = "Jog " + days[i];
task = taskCreator.createWithValues(title);
date = newDateTime(task.getDueDate());
assertEquals(date.getDayOfWeek(), i + 1);
title = "Jog " + abrevDays[i];
task = taskCreator.createWithValues(title);
date = newDateTime(task.getDueDate());
assertEquals(date.getDayOfWeek(), i + 1);
}
}
// ----------------Days end----------------//
// ----------------Priority begin----------------//
/** tests all words using priority 0 */
@Test
public void testPriority0() {
String[] acceptedStrings = {"priority 0", "least priority", "lowest priority", "bang 0"};
for (String acceptedString : acceptedStrings) {
String title = "Jog " + acceptedString;
Task task = taskCreator.createWithValues(title);
assertEquals((int) task.getPriority(), Priority.NONE);
}
for (String acceptedString : acceptedStrings) {
String title = acceptedString + " jog";
Task task = taskCreator.createWithValues(title);
assertNotSame(task.getPriority(), Priority.NONE);
}
}
@Test
public void testPriority1() {
String[] acceptedStringsAtEnd = {"priority 1", "low priority", "bang", "bang 1"};
String[] acceptedStringsAnywhere = {"!1", "!"};
Task task;
for (String acceptedStringAtEnd : acceptedStringsAtEnd) {
task =
taskCreator.basicQuickAddTask(
"Jog " + acceptedStringAtEnd); // test at end of task. should set importance.
assertEquals((int) task.getPriority(), Priority.LOW);
}
for (String acceptedStringAtEnd : acceptedStringsAtEnd) {
task =
taskCreator.basicQuickAddTask(
acceptedStringAtEnd
+ " jog"); // test at beginning of task. should not set importance.
assertEquals((int) task.getPriority(), Priority.LOW);
}
for (String acceptedStringAnywhere : acceptedStringsAnywhere) {
task =
taskCreator.basicQuickAddTask(
"Jog " + acceptedStringAnywhere); // test at end of task. should set importance.
assertEquals((int) task.getPriority(), Priority.LOW);
task =
taskCreator.basicQuickAddTask(
acceptedStringAnywhere + " jog"); // test at beginning of task. should set importance.
assertEquals((int) task.getPriority(), Priority.LOW);
}
}
@Test
public void testPriority2() {
String[] acceptedStringsAtEnd = {"priority 2", "high priority", "bang bang", "bang 2"};
String[] acceptedStringsAnywhere = {"!2", "!!"};
for (String acceptedStringAtEnd : acceptedStringsAtEnd) {
String title = "Jog " + acceptedStringAtEnd;
Task task = taskCreator.createWithValues(title);
assertEquals((int) task.getPriority(), Priority.MEDIUM);
title = acceptedStringAtEnd + " jog";
task = taskCreator.createWithValues(title);
assertNotSame(task.getPriority(), Priority.MEDIUM);
}
for (String acceptedStringAnywhere : acceptedStringsAnywhere) {
String title = "Jog " + acceptedStringAnywhere;
Task task = taskCreator.createWithValues(title);
assertEquals((int) task.getPriority(), Priority.MEDIUM);
title = acceptedStringAnywhere + " jog";
task = taskCreator.createWithValues(title);
assertEquals((int) task.getPriority(), Priority.MEDIUM);
}
}
@Test
public void testPriority3() {
String[] acceptedStringsAtEnd = {
"priority 3",
"highest priority",
"bang bang bang",
"bang 3",
"bang bang bang bang bang bang bang"
};
String[] acceptedStringsAnywhere = {"!3", "!!!", "!6", "!!!!!!!!!!!!!"};
for (String acceptedStringAtEnd : acceptedStringsAtEnd) {
String title = "Jog " + acceptedStringAtEnd;
Task task = taskCreator.createWithValues(title);
assertEquals((int) task.getPriority(), Priority.HIGH);
title = acceptedStringAtEnd + " jog";
task = taskCreator.createWithValues(title);
assertNotSame(task.getPriority(), Priority.HIGH);
}
for (String acceptedStringAnywhere : acceptedStringsAnywhere) {
String title = "Jog " + acceptedStringAnywhere;
Task task = taskCreator.createWithValues(title);
assertEquals((int) task.getPriority(), Priority.HIGH);
title = acceptedStringAnywhere + " jog";
task = taskCreator.createWithValues(title);
assertEquals((int) task.getPriority(), Priority.HIGH);
}
}
// ----------------Priority end----------------//
// ----------------Repeats begin----------------//
/** test daily repeat from due date, but with no due date set */
@Test
public void testDailyWithNoDueDate() {
String title = "Jog daily";
Task task = taskCreator.createWithValues(title);
RRule rrule = new RRule();
rrule.setFreq(Frequency.DAILY);
rrule.setInterval(1);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertFalse(task.hasDueTime());
assertFalse(task.hasDueDate());
title = "Jog every day";
task = taskCreator.createWithValues(title);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertFalse(task.hasDueTime());
assertFalse(task.hasDueDate());
for (int i = 1; i <= 12; i++) {
title = "Jog every " + i + " days.";
rrule.setInterval(i);
task = taskCreator.createWithValues(title);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertFalse(task.hasDueTime());
assertFalse(task.hasDueDate());
}
}
/** test weekly repeat from due date, with no due date & time set */
@Test
public void testWeeklyWithNoDueDate() {
String title = "Jog weekly";
Task task = taskCreator.createWithValues(title);
RRule rrule = new RRule();
rrule.setFreq(Frequency.WEEKLY);
rrule.setInterval(1);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertFalse(task.hasDueTime());
assertFalse(task.hasDueDate());
title = "Jog every week";
task = taskCreator.createWithValues(title);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertFalse(task.hasDueTime());
assertFalse(task.hasDueDate());
for (int i = 1; i <= 12; i++) {
title = "Jog every " + i + " weeks";
rrule.setInterval(i);
task = taskCreator.createWithValues(title);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertFalse(task.hasDueTime());
assertFalse(task.hasDueDate());
}
}
/** test hourly repeat from due date, with no due date but no time */
@Test
public void testMonthlyFromNoDueDate() {
String title = "Jog monthly";
Task task = taskCreator.createWithValues(title);
RRule rrule = new RRule();
rrule.setFreq(Frequency.MONTHLY);
rrule.setInterval(1);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertFalse(task.hasDueTime());
assertFalse(task.hasDueDate());
title = "Jog every month";
task = taskCreator.createWithValues(title);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertFalse(task.hasDueTime());
assertFalse(task.hasDueDate());
for (int i = 1; i <= 12; i++) {
title = "Jog every " + i + " months";
rrule.setInterval(i);
task = taskCreator.createWithValues(title);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertFalse(task.hasDueTime());
assertFalse(task.hasDueDate());
}
}
@Test
public void testDailyFromDueDate() {
String title = "Jog daily starting from today";
Task task = taskCreator.createWithValues(title);
RRule rrule = new RRule();
rrule.setFreq(Frequency.DAILY);
rrule.setInterval(1);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertTrue(task.hasDueDate());
title = "Jog every day starting from today";
task = taskCreator.createWithValues(title);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertTrue(task.hasDueDate());
for (int i = 1; i <= 12; i++) {
title = "Jog every " + i + " days starting from today";
rrule.setInterval(i);
task = taskCreator.createWithValues(title);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertTrue(task.hasDueDate());
}
}
@Test
public void testWeeklyFromDueDate() {
String title = "Jog weekly starting from today";
Task task = taskCreator.createWithValues(title);
RRule rrule = new RRule();
rrule.setFreq(Frequency.WEEKLY);
rrule.setInterval(1);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertTrue(task.hasDueDate());
title = "Jog every week starting from today";
task = taskCreator.createWithValues(title);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertTrue(task.hasDueDate());
for (int i = 1; i <= 12; i++) {
title = "Jog every " + i + " weeks starting from today";
rrule.setInterval(i);
task = taskCreator.createWithValues(title);
assertEquals(task.getRecurrence(), rrule.toIcal());
assertTrue(task.hasDueDate());
}
}
// ----------------Repeats end----------------//
// ----------------Tags begin----------------//
/** tests all words using priority 0 */
@Test
public void testTagsPound() {
String[] acceptedStrings = {"#tag", "#a", "#(a cool tag)", "#(cool)"};
Task task;
for (String acceptedString : acceptedStrings) {
task = new Task();
task.setTitle("Jog " + acceptedString); // test at end of task. should set importance.
ArrayList<String> tags = new ArrayList<>();
TitleParser.listHelper(tagDataDao, task, tags);
String tag = TitleParser.trimParenthesis(acceptedString);
assertTrue(
"test pound at failed for string: " + acceptedString + " for tags: " + tags.toString(),
tags.contains(tag));
}
}
/** tests all words using priority 0 */
@Test
public void testTagsAt() {
String[] acceptedStrings = {"@tag", "@a", "@(a cool tag)", "@(cool)"};
Task task;
for (String acceptedString : acceptedStrings) {
task = new Task();
task.setTitle("Jog " + acceptedString); // test at end of task. should set importance.
ArrayList<String> tags = new ArrayList<>();
TitleParser.listHelper(tagDataDao, task, tags);
String tag = TitleParser.trimParenthesis(acceptedString);
assertTrue(
"testTagsAt failed for string: " + acceptedString + " for tags: " + tags.toString(),
tags.contains(tag));
}
}
}

@ -0,0 +1,430 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.service
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.ical.values.Frequency
import com.google.ical.values.RRule
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.utility.TitleParser
import org.junit.Assert.*
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.R
import org.tasks.data.TagDataDao
import org.tasks.date.DateTimeUtils
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.preferences.Preferences
import java.util.*
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class TitleParserTest : InjectingTestCase() {
@Inject lateinit var tagDataDao: TagDataDao
@Inject lateinit var preferences: Preferences
@Inject lateinit var taskCreator: TaskCreator
override fun setUp() {
super.setUp()
preferences.setStringFromInteger(R.string.p_default_urgency_key, 0)
}
override fun inject(component: TestComponent) = component.inject(this)
/**
* test that completing a task w/ no regular expressions creates a simple task with no date, no
* repeat, no lists
*/
@Test
fun testNoRegexes() {
val task = taskCreator.basicQuickAddTask("Jog")
val nothing = Task()
assertFalse(task.hasDueTime())
assertFalse(task.hasDueDate())
assertEquals(task.getRecurrence(), nothing.getRecurrence())
}
/** Tests correct date is parsed */
@Test
fun testMonthDate() {
val titleMonthStrings = arrayOf(
"Jan.", "January",
"Feb.", "February",
"Mar.", "March",
"Apr.", "April",
"May", "May",
"Jun.", "June",
"Jul.", "July",
"Aug.", "August",
"Sep.", "September",
"Oct.", "October",
"Nov.", "November",
"Dec.", "December"
)
for (i in 0..22) {
val testTitle = "Jog on " + titleMonthStrings[i] + " 12."
val task = insertTitleAddTask(testTitle)
val date = DateTimeUtils.newDateTime(task.getDueDate())
assertEquals(date.monthOfYear, i / 2 + 1)
assertEquals(date.dayOfMonth, 12)
}
}
@Test
fun testMonthSlashDay() {
for (i in 1..12) {
val testTitle = "Jog on $i/12/13"
val task = insertTitleAddTask(testTitle)
val date = DateTimeUtils.newDateTime(task.getDueDate())
assertEquals(date.monthOfYear, i)
assertEquals(date.dayOfMonth, 12)
assertEquals(date.year, 2013)
}
}
@Test
fun testArmyTime() {
val testTitle = "Jog on 23:21."
val task = insertTitleAddTask(testTitle)
val date = DateTimeUtils.newDateTime(task.getDueDate())
assertEquals(date.hourOfDay, 23)
assertEquals(date.minuteOfHour, 21)
}
@Test
fun test_AM_PM() {
val testTitle = "Jog at 8:33 PM."
val task = insertTitleAddTask(testTitle)
val date = DateTimeUtils.newDateTime(task.getDueDate())
assertEquals(date.hourOfDay, 20)
assertEquals(date.minuteOfHour, 33)
}
@Test
fun test_at_hour() {
val testTitle = "Jog at 8 PM."
val task = insertTitleAddTask(testTitle)
val date = DateTimeUtils.newDateTime(task.getDueDate())
assertEquals(date.hourOfDay, 20)
assertEquals(date.minuteOfHour, 0)
}
@Test
fun test_oclock_AM() {
val testTitle = "Jog at 8 o'clock AM."
val task = insertTitleAddTask(testTitle)
val date = DateTimeUtils.newDateTime(task.getDueDate())
assertEquals(date.hourOfDay, 8)
assertEquals(date.minuteOfHour, 0)
}
@Test
fun test_several_forms_of_eight() {
val testTitles = arrayOf("Jog 8 AM", "Jog 8 o'clock AM", "at 8:00 AM")
for (testTitle in testTitles) {
val task = insertTitleAddTask(testTitle)
val date = DateTimeUtils.newDateTime(task.getDueDate())
assertEquals(date.hourOfDay, 8)
assertEquals(date.minuteOfHour, 0)
}
}
@Test
fun test_several_forms_of_1230PM() {
val testTitles = arrayOf(
"Jog 12:30 PM", "at 12:30 PM", "Do something on 12:30 PM", "Jog at 12:30 PM Friday"
)
for (testTitle in testTitles) {
val task = insertTitleAddTask(testTitle)
val date = DateTimeUtils.newDateTime(task.getDueDate())
assertEquals(date.hourOfDay, 12)
assertEquals(date.minuteOfHour, 30)
}
}
private fun insertTitleAddTask(title: String): Task {
return taskCreator.createWithValues(title)
}
// ----------------Days begin----------------//
@Test
fun testDays() {
val today = Calendar.getInstance()
var title = "Jog today"
var task = taskCreator.createWithValues(title)
var date = DateTimeUtils.newDateTime(task.getDueDate())
assertEquals(date.dayOfWeek, today[Calendar.DAY_OF_WEEK])
// Calendar starts 1-6, date.getDay() starts at 0
title = "Jog tomorrow"
task = taskCreator.createWithValues(title)
date = DateTimeUtils.newDateTime(task.getDueDate())
assertEquals(date.dayOfWeek % 7, (today[Calendar.DAY_OF_WEEK] + 1) % 7)
val days = arrayOf(
"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday")
val abrevDays = arrayOf("sun.", "mon.", "tue.", "wed.", "thu.", "fri.", "sat.")
for (i in 1..6) {
title = "Jog " + days[i]
task = taskCreator.createWithValues(title)
date = DateTimeUtils.newDateTime(task.getDueDate())
assertEquals(date.dayOfWeek, i + 1)
title = "Jog " + abrevDays[i]
task = taskCreator.createWithValues(title)
date = DateTimeUtils.newDateTime(task.getDueDate())
assertEquals(date.dayOfWeek, i + 1)
}
}
// ----------------Days end----------------//
// ----------------Priority begin----------------//
/** tests all words using priority 0 */
@Test
fun testPriority0() {
val acceptedStrings = arrayOf("priority 0", "least priority", "lowest priority", "bang 0")
for (acceptedString in acceptedStrings) {
val title = "Jog $acceptedString"
val task = taskCreator.createWithValues(title)
assertEquals(task.getPriority() as Int, Task.Priority.NONE)
}
for (acceptedString in acceptedStrings) {
val title = "$acceptedString jog"
val task = taskCreator.createWithValues(title)
assertNotSame(task.getPriority(), Task.Priority.NONE)
}
}
@Test
fun testPriority1() {
val acceptedStringsAtEnd = arrayOf("priority 1", "low priority", "bang", "bang 1")
val acceptedStringsAnywhere = arrayOf("!1", "!")
var task: Task
for (acceptedStringAtEnd in acceptedStringsAtEnd) {
task = taskCreator.basicQuickAddTask(
"Jog $acceptedStringAtEnd") // test at end of task. should set importance.
assertEquals(task.getPriority() as Int, Task.Priority.LOW)
}
for (acceptedStringAtEnd in acceptedStringsAtEnd) {
task = taskCreator.basicQuickAddTask(acceptedStringAtEnd
+ " jog") // test at beginning of task. should not set importance.
assertEquals(task.getPriority() as Int, Task.Priority.LOW)
}
for (acceptedStringAnywhere in acceptedStringsAnywhere) {
task = taskCreator.basicQuickAddTask(
"Jog $acceptedStringAnywhere") // test at end of task. should set importance.
assertEquals(task.getPriority() as Int, Task.Priority.LOW)
task = taskCreator.basicQuickAddTask(
"$acceptedStringAnywhere jog") // test at beginning of task. should set importance.
assertEquals(task.getPriority() as Int, Task.Priority.LOW)
}
}
@Test
fun testPriority2() {
val acceptedStringsAtEnd = arrayOf("priority 2", "high priority", "bang bang", "bang 2")
val acceptedStringsAnywhere = arrayOf("!2", "!!")
for (acceptedStringAtEnd in acceptedStringsAtEnd) {
var title = "Jog $acceptedStringAtEnd"
var task = taskCreator.createWithValues(title)
assertEquals(task.getPriority() as Int, Task.Priority.MEDIUM)
title = "$acceptedStringAtEnd jog"
task = taskCreator.createWithValues(title)
assertNotSame(task.getPriority(), Task.Priority.MEDIUM)
}
for (acceptedStringAnywhere in acceptedStringsAnywhere) {
var title = "Jog $acceptedStringAnywhere"
var task = taskCreator.createWithValues(title)
assertEquals(task.getPriority() as Int, Task.Priority.MEDIUM)
title = "$acceptedStringAnywhere jog"
task = taskCreator.createWithValues(title)
assertEquals(task.getPriority() as Int, Task.Priority.MEDIUM)
}
}
@Test
fun testPriority3() {
val acceptedStringsAtEnd = arrayOf(
"priority 3",
"highest priority",
"bang bang bang",
"bang 3",
"bang bang bang bang bang bang bang"
)
val acceptedStringsAnywhere = arrayOf("!3", "!!!", "!6", "!!!!!!!!!!!!!")
for (acceptedStringAtEnd in acceptedStringsAtEnd) {
var title = "Jog $acceptedStringAtEnd"
var task = taskCreator.createWithValues(title)
assertEquals(task.getPriority() as Int, Task.Priority.HIGH)
title = "$acceptedStringAtEnd jog"
task = taskCreator.createWithValues(title)
assertNotSame(task.getPriority(), Task.Priority.HIGH)
}
for (acceptedStringAnywhere in acceptedStringsAnywhere) {
var title = "Jog $acceptedStringAnywhere"
var task = taskCreator.createWithValues(title)
assertEquals(task.getPriority() as Int, Task.Priority.HIGH)
title = "$acceptedStringAnywhere jog"
task = taskCreator.createWithValues(title)
assertEquals(task.getPriority() as Int, Task.Priority.HIGH)
}
}
// ----------------Priority end----------------//
// ----------------Repeats begin----------------//
/** test daily repeat from due date, but with no due date set */
@Test
fun testDailyWithNoDueDate() {
var title = "Jog daily"
var task = taskCreator.createWithValues(title)
val rrule = RRule()
rrule.freq = Frequency.DAILY
rrule.interval = 1
assertEquals(task.getRecurrence(), rrule.toIcal())
assertFalse(task.hasDueTime())
assertFalse(task.hasDueDate())
title = "Jog every day"
task = taskCreator.createWithValues(title)
assertEquals(task.getRecurrence(), rrule.toIcal())
assertFalse(task.hasDueTime())
assertFalse(task.hasDueDate())
for (i in 1..12) {
title = "Jog every $i days."
rrule.interval = i
task = taskCreator.createWithValues(title)
assertEquals(task.getRecurrence(), rrule.toIcal())
assertFalse(task.hasDueTime())
assertFalse(task.hasDueDate())
}
}
/** test weekly repeat from due date, with no due date & time set */
@Test
fun testWeeklyWithNoDueDate() {
var title = "Jog weekly"
var task = taskCreator.createWithValues(title)
val rrule = RRule()
rrule.freq = Frequency.WEEKLY
rrule.interval = 1
assertEquals(task.getRecurrence(), rrule.toIcal())
assertFalse(task.hasDueTime())
assertFalse(task.hasDueDate())
title = "Jog every week"
task = taskCreator.createWithValues(title)
assertEquals(task.getRecurrence(), rrule.toIcal())
assertFalse(task.hasDueTime())
assertFalse(task.hasDueDate())
for (i in 1..12) {
title = "Jog every $i weeks"
rrule.interval = i
task = taskCreator.createWithValues(title)
assertEquals(task.getRecurrence(), rrule.toIcal())
assertFalse(task.hasDueTime())
assertFalse(task.hasDueDate())
}
}
/** test hourly repeat from due date, with no due date but no time */
@Test
fun testMonthlyFromNoDueDate() {
var title = "Jog monthly"
var task = taskCreator.createWithValues(title)
val rrule = RRule()
rrule.freq = Frequency.MONTHLY
rrule.interval = 1
assertEquals(task.getRecurrence(), rrule.toIcal())
assertFalse(task.hasDueTime())
assertFalse(task.hasDueDate())
title = "Jog every month"
task = taskCreator.createWithValues(title)
assertEquals(task.getRecurrence(), rrule.toIcal())
assertFalse(task.hasDueTime())
assertFalse(task.hasDueDate())
for (i in 1..12) {
title = "Jog every $i months"
rrule.interval = i
task = taskCreator.createWithValues(title)
assertEquals(task.getRecurrence(), rrule.toIcal())
assertFalse(task.hasDueTime())
assertFalse(task.hasDueDate())
}
}
@Test
fun testDailyFromDueDate() {
var title = "Jog daily starting from today"
var task = taskCreator.createWithValues(title)
val rrule = RRule()
rrule.freq = Frequency.DAILY
rrule.interval = 1
assertEquals(task.getRecurrence(), rrule.toIcal())
assertTrue(task.hasDueDate())
title = "Jog every day starting from today"
task = taskCreator.createWithValues(title)
assertEquals(task.getRecurrence(), rrule.toIcal())
assertTrue(task.hasDueDate())
for (i in 1..12) {
title = "Jog every $i days starting from today"
rrule.interval = i
task = taskCreator.createWithValues(title)
assertEquals(task.getRecurrence(), rrule.toIcal())
assertTrue(task.hasDueDate())
}
}
@Test
fun testWeeklyFromDueDate() {
var title = "Jog weekly starting from today"
var task = taskCreator.createWithValues(title)
val rrule = RRule()
rrule.freq = Frequency.WEEKLY
rrule.interval = 1
assertEquals(task.getRecurrence(), rrule.toIcal())
assertTrue(task.hasDueDate())
title = "Jog every week starting from today"
task = taskCreator.createWithValues(title)
assertEquals(task.getRecurrence(), rrule.toIcal())
assertTrue(task.hasDueDate())
for (i in 1..12) {
title = "Jog every $i weeks starting from today"
rrule.interval = i
task = taskCreator.createWithValues(title)
assertEquals(task.getRecurrence(), rrule.toIcal())
assertTrue(task.hasDueDate())
}
}
// ----------------Repeats end----------------//
// ----------------Tags begin----------------//
/** tests all words using priority 0 */
@Test
fun testTagsPound() {
val acceptedStrings = arrayOf("#tag", "#a", "#(a cool tag)", "#(cool)")
var task: Task
for (acceptedString in acceptedStrings) {
task = Task()
task.setTitle("Jog $acceptedString") // test at end of task. should set importance.
val tags = ArrayList<String>()
TitleParser.listHelper(tagDataDao, task, tags)
val tag = TitleParser.trimParenthesis(acceptedString)
assertTrue(
"test pound at failed for string: $acceptedString for tags: $tags",
tags.contains(tag))
}
}
/** tests all words using priority 0 */
@Test
fun testTagsAt() {
val acceptedStrings = arrayOf("@tag", "@a", "@(a cool tag)", "@(cool)")
var task: Task
for (acceptedString in acceptedStrings) {
task = Task()
task.setTitle("Jog $acceptedString") // test at end of task. should set importance.
val tags = ArrayList<String>()
TitleParser.listHelper(tagDataDao, task, tags)
val tag = TitleParser.trimParenthesis(acceptedString)
assertTrue(
"testTagsAt failed for string: $acceptedString for tags: $tags",
tags.contains(tag))
}
}
}

@ -1,71 +0,0 @@
package com.todoroo.astrid.subtasks;
import static junit.framework.Assert.assertEquals;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.data.TaskListMetadata;
import org.tasks.injection.TestComponent;
@RunWith(AndroidJUnit4.class)
public class SubtasksHelperTest extends SubtasksTestCase {
private static final String[] EXPECTED_ORDER = {"-1", "1", "2", "3", "4", "5", "6"};
private static final String EXPECTED_REMOTE =
"[\"-1\", [\"6\", \"4\", [\"3\", \"1\"]], \"2\", \"5\"]".replaceAll("\\s", "");
@Inject TaskDao taskDao;
@Override
public void setUp() {
super.setUp();
createTasks();
TaskListMetadata m = new TaskListMetadata();
m.setFilter(TaskListMetadata.FILTER_ID_ALL);
updater.initializeFromSerializedTree(
m, filter, SubtasksHelper.convertTreeToRemoteIds(taskDao, DEFAULT_SERIALIZED_TREE));
}
private void createTask(String title, String uuid) {
Task t = new Task();
t.setTitle(title);
t.setUuid(uuid);
taskDao.createNew(t);
}
private void createTasks() {
createTask("A", "6"); // Local id 1
createTask("B", "4"); // Local id 2
createTask("C", "3"); // Local id 3
createTask("D", "1"); // Local id 4
createTask("E", "2"); // Local id 5
createTask("F", "5"); // Local id 6
}
// Default order: "[-1, [1, 2, [3, 4]], 5, 6]"
@Test
public void testOrderedIdArray() {
String[] ids = SubtasksHelper.getStringIdArray(DEFAULT_SERIALIZED_TREE);
assertEquals(EXPECTED_ORDER.length, ids.length);
for (int i = 0; i < EXPECTED_ORDER.length; i++) {
assertEquals(EXPECTED_ORDER[i], ids[i]);
}
}
@Test
public void testLocalToRemoteIdMapping() {
String mapped =
SubtasksHelper.convertTreeToRemoteIds(taskDao, DEFAULT_SERIALIZED_TREE)
.replaceAll("\\s", "");
assertEquals(EXPECTED_REMOTE, mapped);
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
}

@ -0,0 +1,62 @@
package com.todoroo.astrid.subtasks
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.todoroo.astrid.data.Task
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.data.TaskListMetadata
import org.tasks.injection.TestComponent
@RunWith(AndroidJUnit4::class)
class SubtasksHelperTest : SubtasksTestCase() {
override fun setUp() {
super.setUp()
createTasks()
val m = TaskListMetadata()
m.filter = TaskListMetadata.FILTER_ID_ALL
updater.initializeFromSerializedTree(
m, filter, SubtasksHelper.convertTreeToRemoteIds(taskDao, DEFAULT_SERIALIZED_TREE))
}
private fun createTask(title: String, uuid: String) {
val t = Task()
t.setTitle(title)
t.uuid = uuid
taskDao.createNew(t)
}
private fun createTasks() {
createTask("A", "6") // Local id 1
createTask("B", "4") // Local id 2
createTask("C", "3") // Local id 3
createTask("D", "1") // Local id 4
createTask("E", "2") // Local id 5
createTask("F", "5") // Local id 6
}
// Default order: "[-1, [1, 2, [3, 4]], 5, 6]"
@Test
fun testOrderedIdArray() {
val ids = SubtasksHelper.getStringIdArray(DEFAULT_SERIALIZED_TREE)
assertEquals(EXPECTED_ORDER.size, ids.size)
for (i in EXPECTED_ORDER.indices) {
assertEquals(EXPECTED_ORDER[i], ids[i])
}
}
@Test
fun testLocalToRemoteIdMapping() {
val mapped = SubtasksHelper.convertTreeToRemoteIds(taskDao, DEFAULT_SERIALIZED_TREE)
.replace("\\s".toRegex(), "")
assertEquals(EXPECTED_REMOTE, mapped)
}
override fun inject(component: TestComponent) = component.inject(this)
companion object {
private val EXPECTED_ORDER = arrayOf("-1", "1", "2", "3", "4", "5", "6")
private val EXPECTED_REMOTE = "[\"-1\", [\"6\", \"4\", [\"3\", \"1\"]], \"2\", \"5\"]".replace("\\s".toRegex(), "")
}
}

@ -1,132 +0,0 @@
package com.todoroo.astrid.subtasks;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.data.TaskListMetadata;
import org.tasks.injection.TestComponent;
@RunWith(AndroidJUnit4.class)
public class SubtasksMovingTest extends SubtasksTestCase {
@Inject TaskDao taskDao;
private Task A, B, C, D, E, F;
@Override
public void setUp() {
super.setUp();
createTasks();
TaskListMetadata m = new TaskListMetadata();
m.setFilter(TaskListMetadata.FILTER_ID_ALL);
updater.initializeFromSerializedTree(
m, filter, SubtasksHelper.convertTreeToRemoteIds(taskDao, DEFAULT_SERIALIZED_TREE));
// Assert initial state is correct
expectParentAndPosition(A, null, 0);
expectParentAndPosition(B, A, 0);
expectParentAndPosition(C, A, 1);
expectParentAndPosition(D, C, 0);
expectParentAndPosition(E, null, 1);
expectParentAndPosition(F, null, 2);
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
private void createTasks() {
A = createTask("A");
B = createTask("B");
C = createTask("C");
D = createTask("D");
E = createTask("E");
F = createTask("F");
}
private Task createTask(String title) {
Task task = new Task();
task.setTitle(title);
taskDao.createNew(task);
return task;
}
private void whenTriggerMoveBefore(Task target, Task before) {
String beforeId = (before == null ? "-1" : before.getUuid());
updater.moveTo(null, filter, target.getUuid(), beforeId);
}
/* Starting State (see SubtasksTestCase):
*
* A
* B
* C
* D
* E
* F
*/
@Test
public void testMoveBeforeIntoSelf() { // Should have no effect
whenTriggerMoveBefore(A, B);
expectParentAndPosition(A, null, 0);
expectParentAndPosition(B, A, 0);
expectParentAndPosition(C, A, 1);
expectParentAndPosition(D, C, 0);
expectParentAndPosition(E, null, 1);
expectParentAndPosition(F, null, 2);
}
@Test
public void testMoveIntoDescendant() { // Should have no effect
whenTriggerMoveBefore(A, C);
expectParentAndPosition(A, null, 0);
expectParentAndPosition(B, A, 0);
expectParentAndPosition(C, A, 1);
expectParentAndPosition(D, C, 0);
expectParentAndPosition(E, null, 1);
expectParentAndPosition(F, null, 2);
}
@Test
public void testMoveToEndOfChildren() { // Should have no effect
whenTriggerMoveBefore(A, E);
expectParentAndPosition(A, null, 0);
expectParentAndPosition(B, A, 0);
expectParentAndPosition(C, A, 1);
expectParentAndPosition(D, C, 0);
expectParentAndPosition(E, null, 1);
expectParentAndPosition(F, null, 2);
}
@Test
public void testStandardMove() {
whenTriggerMoveBefore(A, F);
expectParentAndPosition(A, null, 1);
expectParentAndPosition(B, A, 0);
expectParentAndPosition(C, A, 1);
expectParentAndPosition(D, C, 0);
expectParentAndPosition(E, null, 0);
expectParentAndPosition(F, null, 2);
}
@Test
public void testMoveToEndOfList() {
whenTriggerMoveBefore(A, null);
expectParentAndPosition(A, null, 2);
expectParentAndPosition(B, A, 0);
expectParentAndPosition(C, A, 1);
expectParentAndPosition(D, C, 0);
expectParentAndPosition(E, null, 0);
expectParentAndPosition(F, null, 1);
}
}

@ -0,0 +1,122 @@
package com.todoroo.astrid.subtasks
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.todoroo.astrid.data.Task
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.data.TaskListMetadata
import org.tasks.injection.TestComponent
@RunWith(AndroidJUnit4::class)
class SubtasksMovingTest : SubtasksTestCase() {
private lateinit var A: Task
private lateinit var B: Task
private lateinit var C: Task
private lateinit var D: Task
private lateinit var E: Task
private lateinit var F: Task
override fun setUp() {
super.setUp()
createTasks()
val m = TaskListMetadata()
m.filter = TaskListMetadata.FILTER_ID_ALL
updater.initializeFromSerializedTree(
m, filter, SubtasksHelper.convertTreeToRemoteIds(taskDao, DEFAULT_SERIALIZED_TREE))
// Assert initial state is correct
expectParentAndPosition(A, null, 0)
expectParentAndPosition(B, A, 0)
expectParentAndPosition(C, A, 1)
expectParentAndPosition(D, C, 0)
expectParentAndPosition(E, null, 1)
expectParentAndPosition(F, null, 2)
}
override fun inject(component: TestComponent) = component.inject(this)
private fun createTasks() {
A = createTask("A")
B = createTask("B")
C = createTask("C")
D = createTask("D")
E = createTask("E")
F = createTask("F")
}
private fun createTask(title: String): Task {
val task = Task()
task.setTitle(title)
taskDao.createNew(task)
return task
}
private fun whenTriggerMoveBefore(target: Task?, before: Task?) {
val beforeId = if (before == null) "-1" else before.uuid
updater.moveTo(null, filter, target!!.uuid, beforeId)
}
/* Starting State (see SubtasksTestCase):
*
* A
* B
* C
* D
* E
* F
*/
@Test
fun testMoveBeforeIntoSelf() { // Should have no effect
whenTriggerMoveBefore(A, B)
expectParentAndPosition(A, null, 0)
expectParentAndPosition(B, A, 0)
expectParentAndPosition(C, A, 1)
expectParentAndPosition(D, C, 0)
expectParentAndPosition(E, null, 1)
expectParentAndPosition(F, null, 2)
}
@Test
fun testMoveIntoDescendant() { // Should have no effect
whenTriggerMoveBefore(A, C)
expectParentAndPosition(A, null, 0)
expectParentAndPosition(B, A, 0)
expectParentAndPosition(C, A, 1)
expectParentAndPosition(D, C, 0)
expectParentAndPosition(E, null, 1)
expectParentAndPosition(F, null, 2)
}
@Test
fun testMoveToEndOfChildren() { // Should have no effect
whenTriggerMoveBefore(A, E)
expectParentAndPosition(A, null, 0)
expectParentAndPosition(B, A, 0)
expectParentAndPosition(C, A, 1)
expectParentAndPosition(D, C, 0)
expectParentAndPosition(E, null, 1)
expectParentAndPosition(F, null, 2)
}
@Test
fun testStandardMove() {
whenTriggerMoveBefore(A, F)
expectParentAndPosition(A, null, 1)
expectParentAndPosition(B, A, 0)
expectParentAndPosition(C, A, 1)
expectParentAndPosition(D, C, 0)
expectParentAndPosition(E, null, 0)
expectParentAndPosition(F, null, 2)
}
@Test
fun testMoveToEndOfList() {
whenTriggerMoveBefore(A, null)
expectParentAndPosition(A, null, 2)
expectParentAndPosition(B, A, 0)
expectParentAndPosition(C, A, 1)
expectParentAndPosition(D, C, 0)
expectParentAndPosition(E, null, 0)
expectParentAndPosition(F, null, 1)
}
}

@ -1,55 +0,0 @@
package com.todoroo.astrid.subtasks;
import static androidx.test.InstrumentationRegistry.getTargetContext;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.core.BuiltInFilterExposer;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.subtasks.SubtasksFilterUpdater.Node;
import javax.inject.Inject;
import org.tasks.data.TaskListMetadataDao;
import org.tasks.injection.InjectingTestCase;
import org.tasks.preferences.Preferences;
/**
* Contains useful methods common to all subtasks tests
*
* @author Sam
*/
public abstract class SubtasksTestCase extends InjectingTestCase {
/* Starting State:
*
* A
* B
* C
* D
* E
* F
*/
static final String DEFAULT_SERIALIZED_TREE = "[-1, [1, 2, [3, 4]], 5, 6]".replaceAll("\\s", "");
SubtasksFilterUpdater updater;
Filter filter;
@Inject TaskListMetadataDao taskListMetadataDao;
@Inject TaskDao taskDao;
@Inject Preferences preferences;
@Override
public void setUp() {
super.setUp();
filter = BuiltInFilterExposer.getMyTasksFilter(getTargetContext().getResources());
preferences.clear(SubtasksFilterUpdater.ACTIVE_TASKS_ORDER);
updater = new SubtasksFilterUpdater(taskListMetadataDao, taskDao);
}
void expectParentAndPosition(Task task, Task parent, int positionInParent) {
String parentId = (parent == null ? "-1" : parent.getUuid());
Node n = updater.findNodeForTask(task.getUuid());
assertNotNull("No node found for task " + task.getTitle(), n);
assertEquals("Parent mismatch", parentId, n.parent.uuid);
assertEquals("Position mismatch", positionInParent, n.parent.children.indexOf(n));
}
}

@ -0,0 +1,50 @@
package com.todoroo.astrid.subtasks
import androidx.test.InstrumentationRegistry
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.core.BuiltInFilterExposer
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.tasks.data.TaskListMetadataDao
import org.tasks.injection.InjectingTestCase
import org.tasks.preferences.Preferences
import javax.inject.Inject
abstract class SubtasksTestCase : InjectingTestCase() {
lateinit var updater: SubtasksFilterUpdater
lateinit var filter: Filter
@Inject lateinit var taskListMetadataDao: TaskListMetadataDao
@Inject lateinit var taskDao: TaskDao
@Inject lateinit var preferences: Preferences
override fun setUp() {
super.setUp()
filter = BuiltInFilterExposer.getMyTasksFilter(InstrumentationRegistry.getTargetContext().resources)
preferences.clear(SubtasksFilterUpdater.ACTIVE_TASKS_ORDER)
updater = SubtasksFilterUpdater(taskListMetadataDao, taskDao)
}
fun expectParentAndPosition(task: Task, parent: Task?, positionInParent: Int) {
val parentId = if (parent == null) "-1" else parent.uuid
val n = updater.findNodeForTask(task.uuid)
assertNotNull("No node found for task " + task.getTitle(), n)
assertEquals("Parent mismatch", parentId, n.parent.uuid)
assertEquals("Position mismatch", positionInParent, n.parent.children.indexOf(n))
}
companion object {
/* Starting State:
*
* A
* B
* C
* D
* E
* F
*/
@JvmField
val DEFAULT_SERIALIZED_TREE = "[-1, [1, 2, [3, 4]], 5, 6]".replace("\\s".toRegex(), "")
}
}

@ -1,48 +0,0 @@
package com.todoroo.astrid.sync;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.Task.Priority;
import javax.inject.Inject;
import org.tasks.data.TagData;
import org.tasks.data.TagDataDao;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
public class NewSyncTestCase extends InjectingTestCase {
private static final String SYNC_TASK_TITLE = "new title";
private static final int SYNC_TASK_IMPORTANCE = Priority.MEDIUM;
@Inject TaskDao taskDao;
@Inject TagDataDao tagDataDao;
private Task createTask(String title) {
Task task = new Task();
task.setTitle(title);
task.setPriority(SYNC_TASK_IMPORTANCE);
taskDao.createNew(task);
return task;
}
Task createTask() {
return createTask(SYNC_TASK_TITLE);
}
private TagData createTagData(String name) {
TagData tag = new TagData();
tag.setName(name);
tagDataDao.createNew(tag);
return tag;
}
TagData createTagData() {
return createTagData("new tag");
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
}

@ -0,0 +1,36 @@
package com.todoroo.astrid.sync
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import org.tasks.data.TagData
import org.tasks.data.TagDataDao
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import javax.inject.Inject
open class NewSyncTestCase : InjectingTestCase() {
@Inject lateinit var taskDao: TaskDao
@Inject lateinit var tagDataDao: TagDataDao
fun createTask(): Task {
val task = Task()
task.setTitle(SYNC_TASK_TITLE)
task.setPriority(SYNC_TASK_IMPORTANCE)
taskDao.createNew(task)
return task
}
fun createTagData(): TagData {
val tag = TagData()
tag.name = "new tag"
tagDataDao.createNew(tag)
return tag
}
override fun inject(component: TestComponent) = component.inject(this)
companion object {
private const val SYNC_TASK_TITLE = "new title"
private const val SYNC_TASK_IMPORTANCE = Task.Priority.MEDIUM
}
}

@ -1,25 +0,0 @@
package com.todoroo.astrid.sync;
import static org.junit.Assert.assertNotEquals;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.data.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.data.TagData;
@RunWith(AndroidJUnit4.class)
public class SyncModelTest extends NewSyncTestCase {
@Test
public void testCreateTaskMakesUuid() {
Task task = createTask();
assertNotEquals(Task.NO_UUID, task.getUuid());
}
@Test
public void testCreateTagMakesUuid() {
TagData tag = createTagData();
assertNotEquals(Task.NO_UUID, tag.getRemoteId());
}
}

@ -0,0 +1,22 @@
package com.todoroo.astrid.sync
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.todoroo.astrid.data.Task
import org.junit.Assert.assertNotEquals
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class SyncModelTest : NewSyncTestCase() {
@Test
fun testCreateTaskMakesUuid() {
val task = createTask()
assertNotEquals(Task.NO_UUID, task.uuid)
}
@Test
fun testCreateTagMakesUuid() {
val tag = createTagData()
assertNotEquals(Task.NO_UUID, tag.remoteId)
}
}

@ -1,39 +0,0 @@
package org.tasks;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import org.tasks.time.DateTime;
import org.tasks.time.DateTimeUtils;
public class Freeze {
public static Freeze freezeClock() {
return freezeAt(currentTimeMillis());
}
public static Freeze freezeAt(DateTime dateTime) {
return freezeAt(dateTime.getMillis());
}
public static Freeze freezeAt(long millis) {
DateTimeUtils.setCurrentMillisFixed(millis);
return new Freeze();
}
public static void thaw() {
DateTimeUtils.setCurrentMillisSystem();
}
@SuppressWarnings("UnusedParameters")
public void thawAfter(Snippet snippet) {
thaw();
}
public void thawAfter(Runnable run) {
try {
run.run();
} finally {
thaw();
}
}
}

@ -0,0 +1,42 @@
package org.tasks
import org.tasks.time.DateTime
import org.tasks.time.DateTimeUtils
class Freeze {
fun thawAfter(run: () -> Unit) {
try {
run.invoke()
} finally {
thaw()
}
}
companion object {
fun freezeClock(run: () -> Unit) {
freezeAt(DateTimeUtils.currentTimeMillis()).thawAfter(run)
}
fun freezeAt(dateTime: DateTime, run: () -> Unit) {
freezeAt(dateTime.millis, run)
}
fun freezeAt(timestamp: Long, run: () -> Unit) {
freezeAt(timestamp).thawAfter(run)
}
fun freezeAt(dateTime: DateTime): Freeze {
return freezeAt(dateTime.millis)
}
fun freezeAt(millis: Long): Freeze {
DateTimeUtils.setCurrentMillisFixed(millis)
return Freeze()
}
fun thaw() {
DateTimeUtils.setCurrentMillisSystem()
}
}
}

@ -1,3 +0,0 @@
package org.tasks;
public class Snippet {}

@ -1,72 +0,0 @@
package org.tasks;
import android.content.Context;
import androidx.test.InstrumentationRegistry;
import com.google.common.base.Charsets;
import com.google.common.io.CharStreams;
import com.todoroo.astrid.data.Task;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import org.tasks.caldav.CaldavConverter;
import org.tasks.preferences.Preferences;
public class TestUtilities {
private static boolean mockitoInitialized;
public static void initializeMockito(Context context) {
if (!mockitoInitialized) {
// for mockito: https://code.google.com/p/dexmaker/issues/detail?id=2
System.setProperty("dexmaker.dexcache", context.getCacheDir().toString());
mockitoInitialized = true;
}
}
public static Preferences newPreferences(Context context) {
return new Preferences(context, "test_preferences");
}
public static Task vtodo(String path) {
Task task = new Task();
CaldavConverter.apply(task, fromResource(path));
return task;
}
private static at.bitfire.ical4android.Task fromResource(String path) {
Context context = InstrumentationRegistry.getInstrumentation().getContext();
InputStream is = null;
InputStreamReader reader = null;
try {
is = context.getAssets().open(path);
reader = new InputStreamReader(is, Charsets.UTF_8);
return fromString(CharStreams.toString(reader));
} catch (IOException e) {
throw new IllegalArgumentException(e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ignored) {
}
}
if (is != null) {
try {
is.close();
} catch (IOException ignored) {
}
}
}
}
private static at.bitfire.ical4android.Task fromString(String task) {
try {
return at.bitfire.ical4android.Task.Companion.tasksFromReader(new StringReader(task)).get(0);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
}

@ -0,0 +1,68 @@
package org.tasks
import android.content.Context
import androidx.test.InstrumentationRegistry
import at.bitfire.ical4android.Task.Companion.tasksFromReader
import com.todoroo.astrid.data.Task
import org.tasks.caldav.CaldavConverter
import org.tasks.preferences.Preferences
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.io.StringReader
object TestUtilities {
private var mockitoInitialized = false
@JvmStatic
fun initializeMockito(context: Context) {
if (!mockitoInitialized) {
// for mockito: https://code.google.com/p/dexmaker/issues/detail?id=2
System.setProperty("dexmaker.dexcache", context.cacheDir.toString())
mockitoInitialized = true
}
}
@JvmStatic
fun newPreferences(context: Context?): Preferences {
return Preferences(context, "test_preferences")
}
@JvmStatic
fun vtodo(path: String): Task {
val task = Task()
CaldavConverter.apply(task, fromResource(path))
return task
}
private fun fromResource(path: String): at.bitfire.ical4android.Task {
val context = InstrumentationRegistry.getInstrumentation().context
var `is`: InputStream? = null
var reader: InputStreamReader? = null
return try {
`is` = context.assets.open(path)
reader = InputStreamReader(`is`, Charsets.UTF_8)
fromString(reader.readText())
} catch (e: IOException) {
throw IllegalArgumentException(e)
} finally {
if (reader != null) {
try {
reader.close()
} catch (ignored: IOException) {
}
}
if (`is` != null) {
try {
`is`.close()
} catch (ignored: IOException) {
}
}
}
}
private fun fromString(task: String) = try {
tasksFromReader(StringReader(task))[0]
} catch (e: Exception) {
throw IllegalArgumentException(e)
}
}

@ -1,85 +0,0 @@
package org.tasks.caldav;
import static junit.framework.Assert.assertEquals;
import static org.tasks.TestUtilities.vtodo;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.data.Task.Priority;
import java.util.TimeZone;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class AppleRemindersTests {
private final TimeZone defaultTimeZone = TimeZone.getDefault();
@Before
public void before() {
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
}
@After
public void after() {
TimeZone.setDefault(defaultTimeZone);
}
@Test
public void readTitle() {
assertEquals("Test title", vtodo("apple/basic_no_due_date.txt").getTitle());
}
@Test
public void readDescription() {
assertEquals("Test description", vtodo("apple/basic_no_due_date.txt").getNotes());
}
@Test
public void readCreationDate() {
assertEquals(
new DateTime(2018, 4, 16, 17, 24, 10).getMillis(),
(long) vtodo("apple/basic_no_due_date.txt").getCreationDate());
}
@Test
public void readDueDate() {
assertEquals(
new DateTime(2018, 4, 16, 18, 0, 1, 0).getMillis(),
(long) vtodo("apple/basic_due_date.txt").getDueDate());
}
@Test
public void completed() {
assertEquals(
new DateTime(2018, 4, 17, 13, 43, 2).getMillis(),
(long) vtodo("apple/basic_completed.txt").getCompletionDate());
}
@Test
public void repeatDaily() {
assertEquals("RRULE:FREQ=DAILY;INTERVAL=1", vtodo("apple/repeat_daily.txt").getRecurrence());
}
@Test
public void noPriority() {
assertEquals(Priority.NONE, (int) vtodo("apple/priority_none.txt").getPriority());
}
@Test
public void lowPriority() {
assertEquals(Priority.LOW, (int) vtodo("apple/priority_low.txt").getPriority());
}
@Test
public void mediumPriority() {
assertEquals(Priority.MEDIUM, (int) vtodo("apple/priority_medium.txt").getPriority());
}
@Test
public void highPriority() {
assertEquals(Priority.HIGH, (int) vtodo("apple/priority_high.txt").getPriority());
}
}

@ -0,0 +1,83 @@
package org.tasks.caldav
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.todoroo.astrid.data.Task
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.TestUtilities.vtodo
import org.tasks.time.DateTime
import java.util.*
@RunWith(AndroidJUnit4::class)
class AppleRemindersTests {
private val defaultTimeZone = TimeZone.getDefault()
@Before
fun before() {
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"))
}
@After
fun after() {
TimeZone.setDefault(defaultTimeZone)
}
@Test
fun readTitle() {
assertEquals("Test title", vtodo("apple/basic_no_due_date.txt").getTitle())
}
@Test
fun readDescription() {
assertEquals("Test description", vtodo("apple/basic_no_due_date.txt").getNotes())
}
@Test
fun readCreationDate() {
assertEquals(
DateTime(2018, 4, 16, 17, 24, 10).millis,
vtodo("apple/basic_no_due_date.txt").creationDate as Long)
}
@Test
fun readDueDate() {
assertEquals(
DateTime(2018, 4, 16, 18, 0, 1, 0).millis,
vtodo("apple/basic_due_date.txt").getDueDate() as Long)
}
@Test
fun completed() {
assertEquals(
DateTime(2018, 4, 17, 13, 43, 2).millis,
vtodo("apple/basic_completed.txt").completionDate as Long)
}
@Test
fun repeatDaily() {
assertEquals("RRULE:FREQ=DAILY;INTERVAL=1", vtodo("apple/repeat_daily.txt").getRecurrence())
}
@Test
fun noPriority() {
assertEquals(Task.Priority.NONE, vtodo("apple/priority_none.txt").getPriority() as Int)
}
@Test
fun lowPriority() {
assertEquals(Task.Priority.LOW, vtodo("apple/priority_low.txt").getPriority() as Int)
}
@Test
fun mediumPriority() {
assertEquals(Task.Priority.MEDIUM, vtodo("apple/priority_medium.txt").getPriority() as Int)
}
@Test
fun highPriority() {
assertEquals(Task.Priority.HIGH, vtodo("apple/priority_high.txt").getPriority() as Int)
}
}

@ -1,22 +0,0 @@
package org.tasks.caldav;
import static org.tasks.TestUtilities.newPreferences;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class CaldavClientTest {
@Test
public void dontCrashOnSpaceInUrl() throws NoSuchAlgorithmException, KeyManagementException {
Context context = ApplicationProvider.getApplicationContext();
new CaldavClient(context, null, newPreferences(context), null)
.forUrl("https://example.com/remote.php/a space/", "username", "password");
}
}

@ -0,0 +1,21 @@
package org.tasks.caldav
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.TestUtilities.newPreferences
import java.security.KeyManagementException
import java.security.NoSuchAlgorithmException
@RunWith(AndroidJUnit4::class)
class CaldavClientTest {
@Test
@Throws(NoSuchAlgorithmException::class, KeyManagementException::class)
fun dontCrashOnSpaceInUrl() {
val context = ApplicationProvider.getApplicationContext<Context>()
CaldavClient(context, null, newPreferences(context), null)
.forUrl("https://example.com/remote.php/a space/", "username", "password")
}
}

@ -1,103 +0,0 @@
package org.tasks.caldav;
import static junit.framework.Assert.assertEquals;
import static org.tasks.TestUtilities.vtodo;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.data.Task.Priority;
import java.util.TimeZone;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class NextCloudTests {
private final TimeZone defaultTimeZone = TimeZone.getDefault();
@Before
public void before() {
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
}
@After
public void after() {
TimeZone.setDefault(defaultTimeZone);
}
@Test
public void readTitle() {
assertEquals("Test title", vtodo("nextcloud/basic_no_due_date.txt").getTitle());
}
@Test
public void readDescription() {
assertEquals("Test description", vtodo("nextcloud/basic_no_due_date.txt").getNotes());
}
@Test
public void readCreationDate() {
assertEquals(
new DateTime(2018, 4, 17, 11, 32, 3).getMillis(),
(long) vtodo("nextcloud/basic_no_due_date.txt").getCreationDate());
}
@Test
public void readDueDate() {
assertEquals(
new DateTime(2018, 4, 17, 17, 0, 1).getMillis(),
(long) vtodo("nextcloud/basic_due_date.txt").getDueDate());
}
@Test
public void priorityNoStars() {
assertEquals(Priority.NONE, (int) vtodo("nextcloud/priority_no_stars.txt").getPriority());
}
@Test
public void priorityOneStar() {
assertEquals(Priority.LOW, (int) vtodo("nextcloud/priority_1_star.txt").getPriority());
}
@Test
public void priorityTwoStars() {
assertEquals(Priority.LOW, (int) vtodo("nextcloud/priority_2_stars.txt").getPriority());
}
@Test
public void priorityThreeStars() {
assertEquals(Priority.LOW, (int) vtodo("nextcloud/priority_3_stars.txt").getPriority());
}
@Test
public void priorityFourStars() {
assertEquals(Priority.LOW, (int) vtodo("nextcloud/priority_4_stars.txt").getPriority());
}
@Test
public void priorityFiveStars() {
assertEquals(Priority.MEDIUM, (int) vtodo("nextcloud/priority_5_stars.txt").getPriority());
}
@Test
public void prioritySixStars() {
assertEquals(Priority.HIGH, (int) vtodo("nextcloud/priority_6_stars.txt").getPriority());
}
@Test
public void prioritySevenStars() {
assertEquals(Priority.HIGH, (int) vtodo("nextcloud/priority_7_stars.txt").getPriority());
}
@Test
public void priorityEightStars() {
assertEquals(Priority.HIGH, (int) vtodo("nextcloud/priority_8_stars.txt").getPriority());
}
@Test
public void priorityNineStars() {
assertEquals(Priority.HIGH, (int) vtodo("nextcloud/priority_9_stars.txt").getPriority());
}
}

@ -0,0 +1,101 @@
package org.tasks.caldav
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.todoroo.astrid.data.Task
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.TestUtilities.vtodo
import org.tasks.time.DateTime
import java.util.*
@RunWith(AndroidJUnit4::class)
class NextCloudTests {
private val defaultTimeZone = TimeZone.getDefault()
@Before
fun before() {
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"))
}
@After
fun after() {
TimeZone.setDefault(defaultTimeZone)
}
@Test
fun readTitle() {
assertEquals("Test title", vtodo("nextcloud/basic_no_due_date.txt").getTitle())
}
@Test
fun readDescription() {
assertEquals("Test description", vtodo("nextcloud/basic_no_due_date.txt").getNotes())
}
@Test
fun readCreationDate() {
assertEquals(
DateTime(2018, 4, 17, 11, 32, 3).millis,
vtodo("nextcloud/basic_no_due_date.txt").creationDate as Long)
}
@Test
fun readDueDate() {
assertEquals(
DateTime(2018, 4, 17, 17, 0, 1).millis,
vtodo("nextcloud/basic_due_date.txt").getDueDate() as Long)
}
@Test
fun priorityNoStars() {
assertEquals(Task.Priority.NONE, vtodo("nextcloud/priority_no_stars.txt").getPriority() as Int)
}
@Test
fun priorityOneStar() {
assertEquals(Task.Priority.LOW, vtodo("nextcloud/priority_1_star.txt").getPriority() as Int)
}
@Test
fun priorityTwoStars() {
assertEquals(Task.Priority.LOW, vtodo("nextcloud/priority_2_stars.txt").getPriority() as Int)
}
@Test
fun priorityThreeStars() {
assertEquals(Task.Priority.LOW, vtodo("nextcloud/priority_3_stars.txt").getPriority() as Int)
}
@Test
fun priorityFourStars() {
assertEquals(Task.Priority.LOW, vtodo("nextcloud/priority_4_stars.txt").getPriority() as Int)
}
@Test
fun priorityFiveStars() {
assertEquals(Task.Priority.MEDIUM, vtodo("nextcloud/priority_5_stars.txt").getPriority() as Int)
}
@Test
fun prioritySixStars() {
assertEquals(Task.Priority.HIGH, vtodo("nextcloud/priority_6_stars.txt").getPriority() as Int)
}
@Test
fun prioritySevenStars() {
assertEquals(Task.Priority.HIGH, vtodo("nextcloud/priority_7_stars.txt").getPriority() as Int)
}
@Test
fun priorityEightStars() {
assertEquals(Task.Priority.HIGH, vtodo("nextcloud/priority_8_stars.txt").getPriority() as Int)
}
@Test
fun priorityNineStars() {
assertEquals(Task.Priority.HIGH, vtodo("nextcloud/priority_9_stars.txt").getPriority() as Int)
}
}

@ -1,42 +0,0 @@
package org.tasks.caldav;
import static junit.framework.Assert.assertTrue;
import static org.tasks.TestUtilities.vtodo;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.TimeZone;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class SynologyTests {
private final TimeZone defaultTimeZone = TimeZone.getDefault();
@Before
public void before() {
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
}
@After
public void after() {
TimeZone.setDefault(defaultTimeZone);
}
@Test
public void completedWithoutDueDate() {
assertTrue(vtodo("synology/complete_no_due_date.txt").isCompleted());
}
@Test
public void completedWithDueDate() {
assertTrue(vtodo("synology/complete_with_date.txt").isCompleted());
}
@Test
public void completedWithDateTime() {
assertTrue(vtodo("synology/complete_with_date_time.txt").isCompleted());
}
}

@ -0,0 +1,40 @@
package org.tasks.caldav
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.After
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.TestUtilities.vtodo
import java.util.*
@RunWith(AndroidJUnit4::class)
class SynologyTests {
private val defaultTimeZone = TimeZone.getDefault()
@Before
fun before() {
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"))
}
@After
fun after() {
TimeZone.setDefault(defaultTimeZone)
}
@Test
fun completedWithoutDueDate() {
assertTrue(vtodo("synology/complete_no_due_date.txt").isCompleted)
}
@Test
fun completedWithDueDate() {
assertTrue(vtodo("synology/complete_with_date.txt").isCompleted)
}
@Test
fun completedWithDateTime() {
assertTrue(vtodo("synology/complete_with_date_time.txt").isCompleted)
}
}

@ -1,91 +0,0 @@
package org.tasks.caldav;
import static junit.framework.Assert.assertEquals;
import static org.tasks.TestUtilities.vtodo;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.data.Task.Priority;
import java.util.TimeZone;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class ThunderbirdTests {
private final TimeZone defaultTimeZone = TimeZone.getDefault();
@Before
public void before() {
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
}
@After
public void after() {
TimeZone.setDefault(defaultTimeZone);
}
@Test
public void readTitle() {
assertEquals("Test title", vtodo("thunderbird/basic_no_due_date.txt").getTitle());
}
@Test
public void readDescription() {
assertEquals("Test description", vtodo("thunderbird/basic_no_due_date.txt").getNotes());
}
@Test
public void readCreationDate() {
assertEquals(
new DateTime(2018, 4, 17, 11, 31, 52).getMillis(),
(long) vtodo("thunderbird/basic_no_due_date.txt").getCreationDate());
}
@Test
public void readDueDate() {
assertEquals(
new DateTime(2018, 4, 17, 14, 0, 1).getMillis(),
(long) vtodo("thunderbird/basic_due_date.txt").getDueDate());
}
@Test
public void completed() {
assertEquals(
new DateTime(2018, 4, 17, 16, 24, 29).getMillis(),
(long) vtodo("thunderbird/basic_completed.txt").getCompletionDate());
}
@Test
public void repeatDaily() {
assertEquals(
"RRULE:FREQ=DAILY;INTERVAL=1", vtodo("thunderbird/repeat_daily.txt").getRecurrence());
}
@Test
public void priorityNotSet() {
assertEquals(Priority.NONE, (int) vtodo("thunderbird/basic_no_due_date.txt").getPriority());
}
@Test
public void priorityNotSpecified() {
assertEquals(Priority.NONE, (int) vtodo("thunderbird/priority_unspecified.txt").getPriority());
}
@Test
public void lowPriority() {
assertEquals(Priority.LOW, (int) vtodo("thunderbird/priority_low.txt").getPriority());
}
@Test
public void normalPriority() {
assertEquals(Priority.MEDIUM, (int) vtodo("thunderbird/priority_normal.txt").getPriority());
}
@Test
public void highPriority() {
assertEquals(Priority.HIGH, (int) vtodo("thunderbird/priority_high.txt").getPriority());
}
}

@ -0,0 +1,89 @@
package org.tasks.caldav
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.todoroo.astrid.data.Task
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.TestUtilities.vtodo
import org.tasks.time.DateTime
import java.util.*
@RunWith(AndroidJUnit4::class)
class ThunderbirdTests {
private val defaultTimeZone = TimeZone.getDefault()
@Before
fun before() {
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"))
}
@After
fun after() {
TimeZone.setDefault(defaultTimeZone)
}
@Test
fun readTitle() {
assertEquals("Test title", vtodo("thunderbird/basic_no_due_date.txt").getTitle())
}
@Test
fun readDescription() {
assertEquals("Test description", vtodo("thunderbird/basic_no_due_date.txt").getNotes())
}
@Test
fun readCreationDate() {
assertEquals(
DateTime(2018, 4, 17, 11, 31, 52).millis,
vtodo("thunderbird/basic_no_due_date.txt").creationDate as Long)
}
@Test
fun readDueDate() {
assertEquals(
DateTime(2018, 4, 17, 14, 0, 1).millis,
vtodo("thunderbird/basic_due_date.txt").getDueDate() as Long)
}
@Test
fun completed() {
assertEquals(
DateTime(2018, 4, 17, 16, 24, 29).millis,
vtodo("thunderbird/basic_completed.txt").completionDate as Long)
}
@Test
fun repeatDaily() {
assertEquals(
"RRULE:FREQ=DAILY;INTERVAL=1", vtodo("thunderbird/repeat_daily.txt").getRecurrence())
}
@Test
fun priorityNotSet() {
assertEquals(Task.Priority.NONE, vtodo("thunderbird/basic_no_due_date.txt").getPriority() as Int)
}
@Test
fun priorityNotSpecified() {
assertEquals(Task.Priority.NONE, vtodo("thunderbird/priority_unspecified.txt").getPriority() as Int)
}
@Test
fun lowPriority() {
assertEquals(Task.Priority.LOW, vtodo("thunderbird/priority_low.txt").getPriority() as Int)
}
@Test
fun normalPriority() {
assertEquals(Task.Priority.MEDIUM, vtodo("thunderbird/priority_normal.txt").getPriority() as Int)
}
@Test
fun highPriority() {
assertEquals(Task.Priority.HIGH, vtodo("thunderbird/priority_high.txt").getPriority() as Int)
}
}

@ -1,81 +0,0 @@
package org.tasks.data;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static com.todoroo.andlib.utility.DateUtilities.now;
import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.tasks.makers.TagDataMaker.newTagData;
import static org.tasks.makers.TagMaker.TAGDATA;
import static org.tasks.makers.TagMaker.TASK;
import static org.tasks.makers.TagMaker.newTag;
import static org.tasks.makers.TaskMaker.ID;
import static org.tasks.makers.TaskMaker.newTask;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.helper.UUIDHelper;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
@RunWith(AndroidJUnit4.class)
public class CaldavDaoTests extends InjectingTestCase {
@Inject TaskDao taskDao;
@Inject TagDao tagDao;
@Inject TagDataDao tagDataDao;
@Inject CaldavDao caldavDao;
@Test
public void getCaldavTasksWithTags() {
Task task = newTask(with(ID, 1L));
taskDao.createNew(task);
TagData one = newTagData();
TagData two = newTagData();
tagDataDao.createNew(one);
tagDataDao.createNew(two);
tagDao.insert(newTag(with(TASK, task), with(TAGDATA, one)));
tagDao.insert(newTag(with(TASK, task), with(TAGDATA, two)));
caldavDao.insert(new CaldavTask(task.getId(), "calendar"));
assertEquals(singletonList(task.getId()), caldavDao.getTasksWithTags());
}
@Test
public void ignoreNonCaldavTaskWithTags() {
Task task = newTask(with(ID, 1L));
taskDao.createNew(task);
TagData tag = newTagData();
tagDataDao.createNew(tag);
tagDao.insert(newTag(with(TASK, task), with(TAGDATA, tag)));
assertTrue(caldavDao.getTasksWithTags().isEmpty());
}
@Test
public void ignoreCaldavTaskWithoutTags() {
Task task = newTask(with(ID, 1L));
taskDao.createNew(task);
tagDataDao.createNew(newTagData());
caldavDao.insert(new CaldavTask(task.getId(), "calendar"));
assertTrue(caldavDao.getTasksWithTags().isEmpty());
}
@Test
public void noResultsForEmptyAccounts() {
CaldavAccount caldavAccount = new CaldavAccount();
caldavAccount.setUuid(UUIDHelper.newUUID());
caldavDao.insert(caldavAccount);
assertTrue(caldavDao.getCaldavFilters(caldavAccount.getUuid(), now()).isEmpty());
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
}

@ -0,0 +1,71 @@
package org.tasks.data
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.natpryce.makeiteasy.MakeItEasy.with
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.helper.UUIDHelper
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.makers.TagDataMaker.newTagData
import org.tasks.makers.TagMaker.TAGDATA
import org.tasks.makers.TagMaker.TASK
import org.tasks.makers.TagMaker.newTag
import org.tasks.makers.TaskMaker.ID
import org.tasks.makers.TaskMaker.newTask
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class CaldavDaoTests : InjectingTestCase() {
@Inject lateinit var taskDao: TaskDao
@Inject lateinit var tagDao: TagDao
@Inject lateinit var tagDataDao: TagDataDao
@Inject lateinit var caldavDao: CaldavDao
@Test
fun getCaldavTasksWithTags() {
val task = newTask(with(ID, 1L))
taskDao.createNew(task)
val one = newTagData()
val two = newTagData()
tagDataDao.createNew(one)
tagDataDao.createNew(two)
tagDao.insert(newTag(with(TASK, task), with(TAGDATA, one)))
tagDao.insert(newTag(with(TASK, task), with(TAGDATA, two)))
caldavDao.insert(CaldavTask(task.getId(), "calendar"))
assertEquals(listOf(task.getId()), caldavDao.getTasksWithTags())
}
@Test
fun ignoreNonCaldavTaskWithTags() {
val task = newTask(with(ID, 1L))
taskDao.createNew(task)
val tag = newTagData()
tagDataDao.createNew(tag)
tagDao.insert(newTag(with(TASK, task), with(TAGDATA, tag)))
assertTrue(caldavDao.getTasksWithTags().isEmpty())
}
@Test
fun ignoreCaldavTaskWithoutTags() {
val task = newTask(with(ID, 1L))
taskDao.createNew(task)
tagDataDao.createNew(newTagData())
caldavDao.insert(CaldavTask(task.getId(), "calendar"))
assertTrue(caldavDao.getTasksWithTags().isEmpty())
}
@Test
fun noResultsForEmptyAccounts() {
val caldavAccount = CaldavAccount()
caldavAccount.uuid = UUIDHelper.newUUID()
caldavDao.insert(caldavAccount)
assertTrue(caldavDao.getCaldavFilters(caldavAccount.uuid, DateUtilities.now()).isEmpty())
}
override fun inject(component: TestComponent) = component.inject(this)
}

@ -1,66 +0,0 @@
package org.tasks.data;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static java.util.Collections.singletonList;
import static junit.framework.TestCase.assertTrue;
import static org.tasks.makers.TaskMaker.CREATION_TIME;
import static org.tasks.makers.TaskMaker.newTask;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ContiguousSet;
import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.Range;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import java.util.ArrayList;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class DeletionDaoTests extends InjectingTestCase {
@Inject TaskDao taskDao;
@Inject DeletionDao deletionDao;
@Test
public void deleting1000DoesntCrash() {
deletionDao.delete(
new ArrayList<>(ContiguousSet.create(Range.closed(1L, 1000L), DiscreteDomain.longs())));
}
@Test
public void marking998ForDeletionDoesntCrash() {
deletionDao.markDeleted(
new ArrayList<>(ContiguousSet.create(Range.closed(1L, 1000L), DiscreteDomain.longs())));
}
@Test
public void markDeletedUpdatesModificationTime() {
Task task = newTask(with(CREATION_TIME, new DateTime().minusMinutes(1)));
taskDao.createNew(task);
deletionDao.markDeleted(singletonList(task.getId()));
task = taskDao.fetch(task.getId());
assertTrue(task.getModificationDate() > task.getCreationDate());
assertTrue(task.getModificationDate() < currentTimeMillis());
}
@Test
public void markDeletedUpdatesDeletionTime() {
Task task = newTask(with(CREATION_TIME, new DateTime().minusMinutes(1)));
taskDao.createNew(task);
deletionDao.markDeleted(singletonList(task.getId()));
task = taskDao.fetch(task.getId());
assertTrue(task.getDeletionDate() > task.getCreationDate());
assertTrue(task.getDeletionDate() < currentTimeMillis());
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
}

@ -0,0 +1,53 @@
package org.tasks.data
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.natpryce.makeiteasy.MakeItEasy
import com.todoroo.astrid.dao.TaskDao
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.makers.TaskMaker.CREATION_TIME
import org.tasks.makers.TaskMaker.newTask
import org.tasks.time.DateTime
import org.tasks.time.DateTimeUtils
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class DeletionDaoTests : InjectingTestCase() {
@Inject lateinit var taskDao: TaskDao
@Inject lateinit var deletionDao: DeletionDao
@Test
fun deleting1000DoesntCrash() {
deletionDao.delete((1L..1000L).toList())
}
@Test
fun marking998ForDeletionDoesntCrash() {
deletionDao.markDeleted(1L..1000L)
}
@Test
fun markDeletedUpdatesModificationTime() {
var task = newTask(MakeItEasy.with(CREATION_TIME, DateTime().minusMinutes(1)))
taskDao.createNew(task)
deletionDao.markDeleted(listOf(task.getId()))
task = taskDao.fetch(task.getId())
assertTrue(task.modificationDate > task.creationDate)
assertTrue(task.modificationDate < DateTimeUtils.currentTimeMillis())
}
@Test
fun markDeletedUpdatesDeletionTime() {
var task = newTask(MakeItEasy.with(CREATION_TIME, DateTime().minusMinutes(1)))
taskDao.createNew(task)
deletionDao.markDeleted(listOf(task.getId()))
task = taskDao.fetch(task.getId())
assertTrue(task.deletionDate > task.creationDate)
assertTrue(task.deletionDate < DateTimeUtils.currentTimeMillis())
}
override fun inject(component: TestComponent) = component.inject(this)
}

@ -1,209 +0,0 @@
package org.tasks.data;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.tasks.makers.GoogleTaskMaker.LIST;
import static org.tasks.makers.GoogleTaskMaker.PARENT;
import static org.tasks.makers.GoogleTaskMaker.REMOTE_ID;
import static org.tasks.makers.GoogleTaskMaker.TASK;
import static org.tasks.makers.GoogleTaskMaker.newGoogleTask;
import static org.tasks.makers.GtaskListMaker.newGtaskList;
import static org.tasks.makers.TaskMaker.newTask;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.primitives.Longs;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import java.util.List;
import javax.inject.Inject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
@RunWith(AndroidJUnit4.class)
public class GoogleTaskDaoTests extends InjectingTestCase {
@Inject GoogleTaskListDao googleTaskListDao;
@Inject GoogleTaskDao googleTaskDao;
@Inject TaskDao taskDao;
@Override
@Before
public void setUp() {
super.setUp();
googleTaskListDao.insert(newGtaskList());
}
@Test
public void insertAtTopOfEmptyList() {
insertTop(newGoogleTask(with(REMOTE_ID, "1234")));
List<GoogleTask> tasks = googleTaskDao.getByLocalOrder("1");
assertEquals(1, tasks.size());
GoogleTask task = tasks.get(0);
assertEquals("1234", task.getRemoteId());
assertEquals(0, task.getOrder());
}
@Test
public void insertAtBottomOfEmptyList() {
insertBottom(newGoogleTask(with(REMOTE_ID, "1234")));
List<GoogleTask> tasks = googleTaskDao.getByLocalOrder("1");
assertEquals(1, tasks.size());
GoogleTask task = tasks.get(0);
assertEquals("1234", task.getRemoteId());
assertEquals(0, task.getOrder());
}
@Test
public void getPreviousIsNullForTopTask() {
googleTaskDao.insertAndShift(newGoogleTask(), true);
assertNull(googleTaskDao.getPrevious("1", 0, 0));
}
@Test
public void getPrevious() {
insertTop(newGoogleTask());
insertTop(newGoogleTask(with(REMOTE_ID, "1234")));
assertEquals("1234", googleTaskDao.getPrevious("1", 0, 1));
}
@Test
public void insertAtTopOfList() {
insertTop(newGoogleTask(with(REMOTE_ID, "1234")));
insertTop(newGoogleTask(with(REMOTE_ID, "5678")));
List<GoogleTask> tasks = googleTaskDao.getByLocalOrder("1");
assertEquals(2, tasks.size());
GoogleTask top = tasks.get(0);
assertEquals("5678", top.getRemoteId());
assertEquals(0, top.getOrder());
}
@Test
public void insertAtTopOfListShiftsExisting() {
insertTop(newGoogleTask(with(REMOTE_ID, "1234")));
insertTop(newGoogleTask(with(REMOTE_ID, "5678")));
List<GoogleTask> tasks = googleTaskDao.getByLocalOrder("1");
assertEquals(2, tasks.size());
GoogleTask bottom = tasks.get(1);
assertEquals("1234", bottom.getRemoteId());
assertEquals(1, bottom.getOrder());
}
@Test
public void getTaskFromRemoteId() {
googleTaskDao.insert(newGoogleTask(with(REMOTE_ID, "1234"), with(TASK, 4)));
assertEquals(4, googleTaskDao.getTask("1234"));
}
@Test
public void getRemoteIdForTask() {
googleTaskDao.insert(newGoogleTask(with(REMOTE_ID, "1234"), with(TASK, 4)));
assertEquals("1234", googleTaskDao.getRemoteId(4L));
}
@Test
public void moveDownInList() {
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "1")), false);
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "2")), false);
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "3")), false);
SubsetGoogleTask two = getByRemoteId("2");
googleTaskDao.move(two, 0, 0);
assertEquals(0, googleTaskDao.getByRemoteId("2").getOrder());
assertEquals(1, googleTaskDao.getByRemoteId("1").getOrder());
assertEquals(2, googleTaskDao.getByRemoteId("3").getOrder());
}
@Test
public void moveUpInList() {
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "1")), false);
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "2")), false);
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "3")), false);
SubsetGoogleTask one = getByRemoteId("1");
googleTaskDao.move(one, 0, 1);
assertEquals(0, googleTaskDao.getByRemoteId("2").getOrder());
assertEquals(1, googleTaskDao.getByRemoteId("1").getOrder());
assertEquals(2, googleTaskDao.getByRemoteId("3").getOrder());
}
@Test
public void moveToTop() {
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "1")), false);
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "2")), false);
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "3")), false);
SubsetGoogleTask three = getByRemoteId("3");
googleTaskDao.move(three, 0, 0);
assertEquals(0, googleTaskDao.getByRemoteId("3").getOrder());
assertEquals(1, googleTaskDao.getByRemoteId("1").getOrder());
assertEquals(2, googleTaskDao.getByRemoteId("2").getOrder());
}
@Test
public void moveToBottom() {
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "1")), false);
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "2")), false);
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "3")), false);
SubsetGoogleTask one = getByRemoteId("1");
googleTaskDao.move(one, 0, 2);
assertEquals(0, googleTaskDao.getByRemoteId("2").getOrder());
assertEquals(1, googleTaskDao.getByRemoteId("3").getOrder());
assertEquals(2, googleTaskDao.getByRemoteId("1").getOrder());
}
@Test
public void findChildrenInList() {
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")));
googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(PARENT, 1L)));
assertEquals(singletonList(2L), googleTaskDao.findChildrenInList(Longs.asList(1, 2)));
}
private void insertTop(GoogleTask googleTask) {
insert(googleTask, true);
}
private void insertBottom(GoogleTask googleTask) {
insert(googleTask, false);
}
private void insert(GoogleTask googleTask, boolean top) {
Task task = newTask();
taskDao.createNew(task);
googleTask.setTask(task.getId());
googleTaskDao.insertAndShift(googleTask, top);
}
private SubsetGoogleTask getByRemoteId(String remoteId) {
GoogleTask googleTask = googleTaskDao.getByRemoteId(remoteId);
SubsetGoogleTask result = new SubsetGoogleTask();
result.gt_id = googleTask.getId();
result.gt_list_id = googleTask.getListId();
result.gt_order = googleTask.getOrder();
result.gt_parent = googleTask.getParent();
return result;
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
}

@ -0,0 +1,182 @@
package org.tasks.data
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.natpryce.makeiteasy.MakeItEasy.with
import com.todoroo.astrid.dao.TaskDao
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.makers.GoogleTaskMaker.LIST
import org.tasks.makers.GoogleTaskMaker.PARENT
import org.tasks.makers.GoogleTaskMaker.REMOTE_ID
import org.tasks.makers.GoogleTaskMaker.TASK
import org.tasks.makers.GoogleTaskMaker.newGoogleTask
import org.tasks.makers.GtaskListMaker.newGtaskList
import org.tasks.makers.TaskMaker.newTask
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class GoogleTaskDaoTests : InjectingTestCase() {
@Inject lateinit var googleTaskListDao: GoogleTaskListDao
@Inject lateinit var googleTaskDao: GoogleTaskDao
@Inject lateinit var taskDao: TaskDao
@Before
override fun setUp() {
super.setUp()
googleTaskListDao.insert(newGtaskList())
}
@Test
fun insertAtTopOfEmptyList() {
insertTop(newGoogleTask(with(REMOTE_ID, "1234")))
val tasks = googleTaskDao.getByLocalOrder("1")
assertEquals(1, tasks.size.toLong())
val task = tasks[0]
assertEquals("1234", task.remoteId)
assertEquals(0, task.order)
}
@Test
fun insertAtBottomOfEmptyList() {
insertBottom(newGoogleTask(with(REMOTE_ID, "1234")))
val tasks = googleTaskDao.getByLocalOrder("1")
assertEquals(1, tasks.size.toLong())
val task = tasks[0]
assertEquals("1234", task.remoteId)
assertEquals(0, task.order)
}
@Test
fun getPreviousIsNullForTopTask() {
googleTaskDao.insertAndShift(newGoogleTask(), true)
assertNull(googleTaskDao.getPrevious("1", 0, 0))
}
@Test
fun getPrevious() {
insertTop(newGoogleTask())
insertTop(newGoogleTask(with(REMOTE_ID, "1234")))
assertEquals("1234", googleTaskDao.getPrevious("1", 0, 1))
}
@Test
fun insertAtTopOfList() {
insertTop(newGoogleTask(with(REMOTE_ID, "1234")))
insertTop(newGoogleTask(with(REMOTE_ID, "5678")))
val tasks = googleTaskDao.getByLocalOrder("1")
assertEquals(2, tasks.size.toLong())
val top = tasks[0]
assertEquals("5678", top.remoteId)
assertEquals(0, top.order)
}
@Test
fun insertAtTopOfListShiftsExisting() {
insertTop(newGoogleTask(with(REMOTE_ID, "1234")))
insertTop(newGoogleTask(with(REMOTE_ID, "5678")))
val tasks = googleTaskDao.getByLocalOrder("1")
assertEquals(2, tasks.size.toLong())
val bottom = tasks[1]
assertEquals("1234", bottom.remoteId)
assertEquals(1, bottom.order)
}
@Test
fun getTaskFromRemoteId() {
googleTaskDao.insert(newGoogleTask(with(REMOTE_ID, "1234"), with(TASK, 4)))
assertEquals(4, googleTaskDao.getTask("1234"))
}
@Test
fun getRemoteIdForTask() {
googleTaskDao.insert(newGoogleTask(with(REMOTE_ID, "1234"), with(TASK, 4)))
assertEquals("1234", googleTaskDao.getRemoteId(4L))
}
@Test
fun moveDownInList() {
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "1")), false)
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "2")), false)
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "3")), false)
val two = getByRemoteId("2")
googleTaskDao.move(two, 0, 0)
assertEquals(0, googleTaskDao.getByRemoteId("2").order)
assertEquals(1, googleTaskDao.getByRemoteId("1").order)
assertEquals(2, googleTaskDao.getByRemoteId("3").order)
}
@Test
fun moveUpInList() {
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "1")), false)
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "2")), false)
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "3")), false)
val one = getByRemoteId("1")
googleTaskDao.move(one, 0, 1)
assertEquals(0, googleTaskDao.getByRemoteId("2").order)
assertEquals(1, googleTaskDao.getByRemoteId("1").order)
assertEquals(2, googleTaskDao.getByRemoteId("3").order)
}
@Test
fun moveToTop() {
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "1")), false)
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "2")), false)
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "3")), false)
val three = getByRemoteId("3")
googleTaskDao.move(three, 0, 0)
assertEquals(0, googleTaskDao.getByRemoteId("3").order)
assertEquals(1, googleTaskDao.getByRemoteId("1").order)
assertEquals(2, googleTaskDao.getByRemoteId("2").order)
}
@Test
fun moveToBottom() {
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "1")), false)
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "2")), false)
googleTaskDao.insertAndShift(newGoogleTask(with(REMOTE_ID, "3")), false)
val one = getByRemoteId("1")
googleTaskDao.move(one, 0, 2)
assertEquals(0, googleTaskDao.getByRemoteId("2").order)
assertEquals(1, googleTaskDao.getByRemoteId("3").order)
assertEquals(2, googleTaskDao.getByRemoteId("1").order)
}
@Test
fun findChildrenInList() {
googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1")))
googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(PARENT, 1L)))
assertEquals(listOf(2L), googleTaskDao.findChildrenInList(listOf(1, 2)))
}
private fun insertTop(googleTask: GoogleTask) {
insert(googleTask, true)
}
private fun insertBottom(googleTask: GoogleTask) {
insert(googleTask, false)
}
private fun insert(googleTask: GoogleTask, top: Boolean) {
val task = newTask()
taskDao.createNew(task)
googleTask.task = task.getId()
googleTaskDao.insertAndShift(googleTask, top)
}
private fun getByRemoteId(remoteId: String): SubsetGoogleTask {
val googleTask = googleTaskDao.getByRemoteId(remoteId)
val result = SubsetGoogleTask()
result.gt_id = googleTask.id
result.gt_list_id = googleTask.listId
result.gt_order = googleTask.order
result.gt_parent = googleTask.parent
return result
}
override fun inject(component: TestComponent) = component.inject(this)
}

@ -21,7 +21,13 @@ import org.tasks.makers.GeofenceMaker.newGeofence
import org.tasks.makers.PlaceMaker.LATITUDE
import org.tasks.makers.PlaceMaker.LONGITUDE
import org.tasks.makers.PlaceMaker.newPlace
import org.tasks.makers.TaskMaker.*
import org.tasks.makers.TaskMaker.COMPLETION_TIME
import org.tasks.makers.TaskMaker.DELETION_TIME
import org.tasks.makers.TaskMaker.DUE_TIME
import org.tasks.makers.TaskMaker.HIDE_TYPE
import org.tasks.makers.TaskMaker.ID
import org.tasks.makers.TaskMaker.SNOOZE_TIME
import org.tasks.makers.TaskMaker.newTask
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)

@ -1,167 +0,0 @@
package org.tasks.data;
import static com.google.common.collect.Sets.newHashSet;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.tasks.makers.TagDataMaker.NAME;
import static org.tasks.makers.TagDataMaker.newTagData;
import static org.tasks.makers.TagMaker.TAGDATA;
import static org.tasks.makers.TagMaker.TAGUID;
import static org.tasks.makers.TagMaker.TASK;
import static org.tasks.makers.TaskMaker.ID;
import static org.tasks.makers.TaskMaker.newTask;
import androidx.core.util.Pair;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import java.util.Set;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
import org.tasks.makers.TagMaker;
@RunWith(AndroidJUnit4.class)
public class TagDataDaoTest extends InjectingTestCase {
@Inject TaskDao taskDao;
@Inject TagDao tagDao;
@Inject TagDataDao tagDataDao;
@Test
public void tagDataOrderedByNameIgnoresNullNames() {
tagDataDao.createNew(newTagData(with(NAME, (String) null)));
assertTrue(tagDataDao.tagDataOrderedByName().isEmpty());
}
@Test
public void tagDataOrderedByNameIgnoresEmptyNames() {
tagDataDao.createNew(newTagData(with(NAME, "")));
assertTrue(tagDataDao.tagDataOrderedByName().isEmpty());
}
@Test
public void getTagWithCaseForMissingTag() {
assertEquals("derp", tagDataDao.getTagWithCase("derp"));
}
@Test
public void getTagWithCaseFixesCase() {
tagDataDao.createNew(newTagData(with(NAME, "Derp")));
assertEquals("Derp", tagDataDao.getTagWithCase("derp"));
}
@Test
public void getTagsByName() {
TagData tagData = newTagData(with(NAME, "Derp"));
tagDataDao.createNew(tagData);
assertEquals(singletonList(tagData), tagDataDao.getTags(singletonList("Derp")));
}
@Test
public void getTagsByNameCaseSensitive() {
tagDataDao.createNew(newTagData(with(NAME, "Derp")));
assertTrue(tagDataDao.getTags(singletonList("derp")).isEmpty());
}
@Test
public void getTagDataForTask() {
Task taskOne = newTask();
Task taskTwo = newTask();
taskDao.createNew(taskOne);
taskDao.createNew(taskTwo);
TagData tagOne = newTagData(with(NAME, "one"));
TagData tagTwo = newTagData(with(NAME, "two"));
tagDataDao.createNew(tagOne);
tagDataDao.createNew(tagTwo);
tagDao.insert(TagMaker.newTag(with(TAGDATA, tagOne), with(TASK, taskOne)));
tagDao.insert(TagMaker.newTag(with(TAGDATA, tagTwo), with(TASK, taskTwo)));
assertEquals(singletonList(tagOne), tagDataDao.getTagDataForTask(taskOne.getId()));
}
@Test
public void getEmptyTagSelections() {
Pair<Set<String>, Set<String>> selections = tagDataDao.getTagSelections(ImmutableList.of(1L));
assertTrue(selections.first.isEmpty());
assertTrue(selections.second.isEmpty());
}
@Test
public void getPartialTagSelections() {
newTag(1, "tag1", "tag2");
newTag(2, "tag2", "tag3");
assertEquals(
newHashSet("tag1", "tag3"), tagDataDao.getTagSelections(ImmutableList.of(1L, 2L)).first);
}
@Test
public void getEmptyPartialSelections() {
newTag(1, "tag1");
newTag(2, "tag1");
assertTrue(tagDataDao.getTagSelections(ImmutableList.of(1L, 2L)).first.isEmpty());
}
@Test
public void getCommonTagSelections() {
newTag(1, "tag1", "tag2");
newTag(2, "tag2", "tag3");
assertEquals(newHashSet("tag2"), tagDataDao.getTagSelections(ImmutableList.of(1L, 2L)).second);
}
@Test
public void getEmptyCommonSelections() {
newTag(1, "tag1");
newTag(2, "tag2");
assertTrue(tagDataDao.getTagSelections(ImmutableList.of(1L, 2L)).second.isEmpty());
}
@Test
public void getSelectionsWithNoTags() {
newTag(1);
Pair<Set<String>, Set<String>> selections = tagDataDao.getTagSelections(ImmutableList.of(1L));
assertTrue(selections.first.isEmpty());
assertTrue(selections.second.isEmpty());
}
@Test
public void noCommonSelectionsWhenOneTaskHasNoTags() {
newTag(1, "tag1");
newTag(2);
Pair<Set<String>, Set<String>> selections =
tagDataDao.getTagSelections(ImmutableList.of(1L, 2L));
assertEquals(newHashSet("tag1"), selections.first);
assertTrue(selections.second.isEmpty());
}
private void newTag(long taskId, String... tags) {
Task task = newTask(with(ID, taskId));
taskDao.createNew(task);
for (String tag : tags) {
tagDao.insert(TagMaker.newTag(with(TASK, task), with(TAGUID, tag)));
}
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
}

@ -0,0 +1,141 @@
package org.tasks.data
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.natpryce.makeiteasy.MakeItEasy.with
import com.todoroo.astrid.dao.TaskDao
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.makers.TagDataMaker.NAME
import org.tasks.makers.TagDataMaker.newTagData
import org.tasks.makers.TagMaker.TAGDATA
import org.tasks.makers.TagMaker.TAGUID
import org.tasks.makers.TagMaker.TASK
import org.tasks.makers.TagMaker.newTag
import org.tasks.makers.TaskMaker.ID
import org.tasks.makers.TaskMaker.newTask
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class TagDataDaoTest : InjectingTestCase() {
@Inject lateinit var taskDao: TaskDao
@Inject lateinit var tagDao: TagDao
@Inject lateinit var tagDataDao: TagDataDao
@Test
fun tagDataOrderedByNameIgnoresNullNames() {
tagDataDao.createNew(newTagData(with(NAME, null as String?)))
assertTrue(tagDataDao.tagDataOrderedByName().isEmpty())
}
@Test
fun tagDataOrderedByNameIgnoresEmptyNames() {
tagDataDao.createNew(newTagData(with(NAME, "")))
assertTrue(tagDataDao.tagDataOrderedByName().isEmpty())
}
@Test
fun getTagWithCaseForMissingTag() {
assertEquals("derp", tagDataDao.getTagWithCase("derp"))
}
@Test
fun getTagWithCaseFixesCase() {
tagDataDao.createNew(newTagData(with(NAME, "Derp")))
assertEquals("Derp", tagDataDao.getTagWithCase("derp"))
}
@Test
fun getTagsByName() {
val tagData = newTagData(with(NAME, "Derp"))
tagDataDao.createNew(tagData)
assertEquals(listOf(tagData), tagDataDao.getTags(listOf("Derp")))
}
@Test
fun getTagsByNameCaseSensitive() {
tagDataDao.createNew(newTagData(with(NAME, "Derp")))
assertTrue(tagDataDao.getTags(listOf("derp")).isEmpty())
}
@Test
fun getTagDataForTask() {
val taskOne = newTask()
val taskTwo = newTask()
taskDao.createNew(taskOne)
taskDao.createNew(taskTwo)
val tagOne = newTagData(with(NAME, "one"))
val tagTwo = newTagData(with(NAME, "two"))
tagDataDao.createNew(tagOne)
tagDataDao.createNew(tagTwo)
tagDao.insert(newTag(with(TAGDATA, tagOne), with(TASK, taskOne)))
tagDao.insert(newTag(with(TAGDATA, tagTwo), with(TASK, taskTwo)))
assertEquals(listOf(tagOne), tagDataDao.getTagDataForTask(taskOne.getId()))
}
@Test
fun getEmptyTagSelections() {
val selections = tagDataDao.getTagSelections(listOf(1L))
assertTrue(selections.first!!.isEmpty())
assertTrue(selections.second!!.isEmpty())
}
@Test
fun getPartialTagSelections() {
newTag(1, "tag1", "tag2")
newTag(2, "tag2", "tag3")
assertEquals(
setOf("tag1", "tag3"), tagDataDao.getTagSelections(listOf(1L, 2L)).first)
}
@Test
fun getEmptyPartialSelections() {
newTag(1, "tag1")
newTag(2, "tag1")
assertTrue(tagDataDao.getTagSelections(listOf(1L, 2L)).first!!.isEmpty())
}
@Test
fun getCommonTagSelections() {
newTag(1, "tag1", "tag2")
newTag(2, "tag2", "tag3")
assertEquals(setOf("tag2"), tagDataDao.getTagSelections(listOf(1L, 2L)).second)
}
@Test
fun getEmptyCommonSelections() {
newTag(1, "tag1")
newTag(2, "tag2")
assertTrue(tagDataDao.getTagSelections(listOf(1L, 2L)).second!!.isEmpty())
}
@Test
fun getSelectionsWithNoTags() {
newTag(1)
val selections = tagDataDao.getTagSelections(listOf(1L))
assertTrue(selections.first!!.isEmpty())
assertTrue(selections.second!!.isEmpty())
}
@Test
fun noCommonSelectionsWhenOneTaskHasNoTags() {
newTag(1, "tag1")
newTag(2)
val selections = tagDataDao.getTagSelections(listOf(1L, 2L))
assertEquals(setOf("tag1"), selections.first)
assertTrue(selections.second!!.isEmpty())
}
private fun newTag(taskId: Long, vararg tags: String) {
val task = newTask(with(ID, taskId))
taskDao.createNew(task)
for (tag in tags) {
tagDao.insert(newTag(with(TASK, task), with(TAGUID, tag)))
}
}
override fun inject(component: TestComponent) = component.inject(this)
}

@ -1,51 +0,0 @@
package org.tasks.date;
import static junit.framework.Assert.assertEquals;
import static org.tasks.Freeze.freezeAt;
import static org.tasks.date.DateTimeUtils.newDateUtc;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.TimeZone;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.Snippet;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class DateTimeUtilsTest {
private final DateTime now = new DateTime(2014, 1, 1, 15, 17, 53, 0);
@Test
public void testGetCurrentTime() {
freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(now.getMillis(), currentTimeMillis());
}
});
}
@Test
public void testCreateNewUtcDate() {
DateTime utc = now.toUTC();
DateTime actual =
newDateUtc(
utc.getYear(),
utc.getMonthOfYear(),
utc.getDayOfMonth(),
utc.getHourOfDay(),
utc.getMinuteOfHour(),
utc.getSecondOfMinute());
assertEquals(utc.getMillis(), actual.getMillis());
}
@Test
public void testIllegalInstant() {
new DateTime(2015, 7, 24, 0, 0, 0, 0, TimeZone.getTimeZone("Africa/Cairo"));
new DateTime(2015, 10, 18, 0, 0, 0, 0, TimeZone.getTimeZone("America/Sao_Paulo"));
new DateTime(2015, 10, 4, 0, 0, 0, 0, TimeZone.getTimeZone("America/Asuncion"));
}
}

@ -0,0 +1,41 @@
package org.tasks.date
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.Freeze.Companion.freezeAt
import org.tasks.time.DateTime
import java.util.*
@RunWith(AndroidJUnit4::class)
class DateTimeUtilsTest {
private val now = DateTime(2014, 1, 1, 15, 17, 53, 0)
@Test
fun testGetCurrentTime() {
freezeAt(now) {
assertEquals(now.millis, org.tasks.time.DateTimeUtils.currentTimeMillis())
}
}
@Test
fun testCreateNewUtcDate() {
val utc = now.toUTC()
val actual = DateTimeUtils.newDateUtc(
utc.year,
utc.monthOfYear,
utc.dayOfMonth,
utc.hourOfDay,
utc.minuteOfHour,
utc.secondOfMinute)
assertEquals(utc.millis, actual.millis)
}
@Test
fun testIllegalInstant() {
DateTime(2015, 7, 24, 0, 0, 0, 0, TimeZone.getTimeZone("Africa/Cairo"))
DateTime(2015, 10, 18, 0, 0, 0, 0, TimeZone.getTimeZone("America/Sao_Paulo"))
DateTime(2015, 10, 4, 0, 0, 0, 0, TimeZone.getTimeZone("America/Asuncion"))
}
}

@ -1,42 +0,0 @@
package org.tasks.db;
import static org.junit.Assert.assertEquals;
import static org.tasks.db.QueryUtils.showCompleted;
import static org.tasks.db.QueryUtils.showHidden;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.andlib.sql.Functions;
import com.todoroo.astrid.data.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class QueryUtilsTest {
@Test
public void replaceHiddenLT() {
assertEquals(
"(1)",
showHidden(Task.HIDE_UNTIL.lt(Functions.now()).toString()));
}
@Test
public void replaceHiddenLTE() {
assertEquals(
"(1)",
showHidden(Task.HIDE_UNTIL.lte(Functions.now()).toString()));
}
@Test
public void replaceUncompletedEQ() {
assertEquals(
"(1)",
showCompleted(Task.COMPLETION_DATE.eq(0).toString()));
}
@Test
public void replaceUncompletedLTE() {
assertEquals(
"(1)",
showCompleted(Task.COMPLETION_DATE.lte(0).toString()));
}
}

@ -0,0 +1,31 @@
package org.tasks.db
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.todoroo.andlib.sql.Functions
import com.todoroo.astrid.data.Task
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class QueryUtilsTest {
@Test
fun replaceHiddenLT() {
assertEquals("(1)", QueryUtils.showHidden(Task.HIDE_UNTIL.lt(Functions.now()).toString()))
}
@Test
fun replaceHiddenLTE() {
assertEquals("(1)", QueryUtils.showHidden(Task.HIDE_UNTIL.lte(Functions.now()).toString()))
}
@Test
fun replaceUncompletedEQ() {
assertEquals("(1)", QueryUtils.showCompleted(Task.COMPLETION_DATE.eq(0).toString()))
}
@Test
fun replaceUncompletedLTE() {
assertEquals("(1)", QueryUtils.showCompleted(Task.COMPLETION_DATE.lte(0).toString()))
}
}

@ -1,150 +0,0 @@
package org.tasks.gtasks;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static com.todoroo.astrid.data.Task.HIDE_UNTIL_DUE;
import static com.todoroo.astrid.data.Task.HIDE_UNTIL_DUE_TIME;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static org.tasks.gtasks.GoogleTaskSynchronizer.getTruncatedValue;
import static org.tasks.gtasks.GoogleTaskSynchronizer.mergeDates;
import static org.tasks.gtasks.GoogleTaskSynchronizer.truncate;
import static org.tasks.makers.TaskMaker.DUE_DATE;
import static org.tasks.makers.TaskMaker.DUE_TIME;
import static org.tasks.makers.TaskMaker.HIDE_TYPE;
import static org.tasks.makers.TaskMaker.newTask;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.data.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class GoogleTaskSynchronizerTest {
@Test
public void testMergeDate() {
Task local = newTask(with(DUE_DATE, new DateTime(2016, 3, 12)));
mergeDates(newTask(with(DUE_DATE, new DateTime(2016, 3, 11))).getDueDate(), local);
assertEquals(new DateTime(2016, 3, 11, 12, 0).getMillis(), local.getDueDate().longValue());
}
@Test
public void testMergeTime() {
Task local = newTask(with(DUE_TIME, new DateTime(2016, 3, 11, 13, 30)));
mergeDates(newTask(with(DUE_DATE, new DateTime(2016, 3, 11))).getDueDate(), local);
assertEquals(new DateTime(2016, 3, 11, 13, 30, 1).getMillis(), local.getDueDate().longValue());
}
@Test
public void testDueDateAdjustHideBackwards() {
Task local =
newTask(with(DUE_DATE, new DateTime(2016, 3, 12)), with(HIDE_TYPE, HIDE_UNTIL_DUE));
mergeDates(newTask(with(DUE_DATE, new DateTime(2016, 3, 11))).getDueDate(), local);
assertEquals(new DateTime(2016, 3, 11).getMillis(), local.getHideUntil().longValue());
}
@Test
public void testDueDateAdjustHideForwards() {
Task local =
newTask(with(DUE_DATE, new DateTime(2016, 3, 12)), with(HIDE_TYPE, HIDE_UNTIL_DUE));
mergeDates(newTask(with(DUE_DATE, new DateTime(2016, 3, 14))).getDueDate(), local);
assertEquals(new DateTime(2016, 3, 14).getMillis(), local.getHideUntil().longValue());
}
@Test
public void testDueTimeAdjustHideBackwards() {
Task local =
newTask(
with(DUE_TIME, new DateTime(2016, 3, 12, 13, 30)),
with(HIDE_TYPE, HIDE_UNTIL_DUE_TIME));
mergeDates(newTask(with(DUE_DATE, new DateTime(2016, 3, 11))).getDueDate(), local);
assertEquals(
new DateTime(2016, 3, 11, 13, 30, 1).getMillis(), local.getHideUntil().longValue());
}
@Test
public void testDueTimeAdjustTimeForwards() {
Task local =
newTask(
with(DUE_TIME, new DateTime(2016, 3, 12, 13, 30)),
with(HIDE_TYPE, HIDE_UNTIL_DUE_TIME));
mergeDates(newTask(with(DUE_DATE, new DateTime(2016, 3, 14))).getDueDate(), local);
assertEquals(
new DateTime(2016, 3, 14, 13, 30, 1).getMillis(), local.getHideUntil().longValue());
}
@Test
public void testDueDateClearHide() {
Task local =
newTask(with(DUE_DATE, new DateTime(2016, 3, 12)), with(HIDE_TYPE, HIDE_UNTIL_DUE));
mergeDates(newTask().getDueDate(), local);
assertEquals(0, local.getHideUntil().longValue());
}
@Test
public void testDueTimeClearHide() {
Task local =
newTask(
with(DUE_TIME, new DateTime(2016, 3, 12, 13, 30)),
with(HIDE_TYPE, HIDE_UNTIL_DUE_TIME));
mergeDates(newTask().getDueDate(), local);
assertEquals(0, local.getHideUntil().longValue());
}
@Test
public void truncateValue() {
assertEquals("1234567", truncate("12345678", 7));
}
@Test
public void dontTruncateMax() {
assertEquals("1234567", truncate("1234567", 7));
}
@Test
public void dontTruncateShortValue() {
assertEquals("12345", truncate("12345", 7));
}
@Test
public void dontTruncateNull() {
assertNull(truncate(null, 7));
}
@Test
public void dontOverwriteTruncatedValue() {
assertEquals("123456789", getTruncatedValue("123456789", "1234567", 7));
}
@Test
public void overwriteTruncatedValueWithShortenedValue() {
assertEquals("12345", getTruncatedValue("123456789", "12345", 7));
}
@Test
public void overwriteTruncatedValueWithNullValue() {
assertNull(getTruncatedValue("123456789", null, 7));
}
@Test
public void overwriteNullValueWithTruncatedValue() {
assertEquals("1234567", getTruncatedValue(null, "1234567", 7));
}
}

@ -0,0 +1,121 @@
package org.tasks.gtasks
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.natpryce.makeiteasy.MakeItEasy.with
import com.todoroo.astrid.data.Task
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.makers.TaskMaker.DUE_DATE
import org.tasks.makers.TaskMaker.DUE_TIME
import org.tasks.makers.TaskMaker.HIDE_TYPE
import org.tasks.makers.TaskMaker.newTask
import org.tasks.time.DateTime
@RunWith(AndroidJUnit4::class)
class GoogleTaskSynchronizerTest {
@Test
fun testMergeDate() {
val local = newTask(with(DUE_DATE, DateTime(2016, 3, 12)))
GoogleTaskSynchronizer.mergeDates(newTask(with(DUE_DATE, DateTime(2016, 3, 11))).getDueDate(), local)
assertEquals(DateTime(2016, 3, 11, 12, 0).millis, local.getDueDate().toLong())
}
@Test
fun testMergeTime() {
val local = newTask(with(DUE_TIME, DateTime(2016, 3, 11, 13, 30)))
GoogleTaskSynchronizer.mergeDates(newTask(with(DUE_DATE, DateTime(2016, 3, 11))).getDueDate(), local)
assertEquals(DateTime(2016, 3, 11, 13, 30, 1).millis, local.getDueDate().toLong())
}
@Test
fun testDueDateAdjustHideBackwards() {
val local = newTask(with(DUE_DATE, DateTime(2016, 3, 12)), with(HIDE_TYPE, Task.HIDE_UNTIL_DUE))
GoogleTaskSynchronizer.mergeDates(newTask(with(DUE_DATE, DateTime(2016, 3, 11))).getDueDate(), local)
assertEquals(DateTime(2016, 3, 11).millis, local.getHideUntil().toLong())
}
@Test
fun testDueDateAdjustHideForwards() {
val local = newTask(with(DUE_DATE, DateTime(2016, 3, 12)), with(HIDE_TYPE, Task.HIDE_UNTIL_DUE))
GoogleTaskSynchronizer.mergeDates(newTask(with(DUE_DATE, DateTime(2016, 3, 14))).getDueDate(), local)
assertEquals(DateTime(2016, 3, 14).millis, local.getHideUntil().toLong())
}
@Test
fun testDueTimeAdjustHideBackwards() {
val local = newTask(
with(DUE_TIME, DateTime(2016, 3, 12, 13, 30)),
with(HIDE_TYPE, Task.HIDE_UNTIL_DUE_TIME))
GoogleTaskSynchronizer.mergeDates(newTask(with(DUE_DATE, DateTime(2016, 3, 11))).getDueDate(), local)
assertEquals(
DateTime(2016, 3, 11, 13, 30, 1).millis, local.getHideUntil().toLong())
}
@Test
fun testDueTimeAdjustTimeForwards() {
val local = newTask(
with(DUE_TIME, DateTime(2016, 3, 12, 13, 30)),
with(HIDE_TYPE, Task.HIDE_UNTIL_DUE_TIME))
GoogleTaskSynchronizer.mergeDates(newTask(with(DUE_DATE, DateTime(2016, 3, 14))).getDueDate(), local)
assertEquals(
DateTime(2016, 3, 14, 13, 30, 1).millis, local.getHideUntil().toLong())
}
@Test
fun testDueDateClearHide() {
val local = newTask(with(DUE_DATE, DateTime(2016, 3, 12)), with(HIDE_TYPE, Task.HIDE_UNTIL_DUE))
GoogleTaskSynchronizer.mergeDates(newTask().getDueDate(), local)
assertEquals(0, local.getHideUntil().toLong())
}
@Test
fun testDueTimeClearHide() {
val local = newTask(
with(DUE_TIME, DateTime(2016, 3, 12, 13, 30)),
with(HIDE_TYPE, Task.HIDE_UNTIL_DUE_TIME))
GoogleTaskSynchronizer.mergeDates(newTask().getDueDate(), local)
assertEquals(0, local.getHideUntil().toLong())
}
@Test
fun truncateValue() {
assertEquals("1234567", GoogleTaskSynchronizer.truncate("12345678", 7))
}
@Test
fun dontTruncateMax() {
assertEquals("1234567", GoogleTaskSynchronizer.truncate("1234567", 7))
}
@Test
fun dontTruncateShortValue() {
assertEquals("12345", GoogleTaskSynchronizer.truncate("12345", 7))
}
@Test
fun dontTruncateNull() {
assertNull(GoogleTaskSynchronizer.truncate(null, 7))
}
@Test
fun dontOverwriteTruncatedValue() {
assertEquals("123456789", GoogleTaskSynchronizer.getTruncatedValue("123456789", "1234567", 7))
}
@Test
fun overwriteTruncatedValueWithShortenedValue() {
assertEquals("12345", GoogleTaskSynchronizer.getTruncatedValue("123456789", "12345", 7))
}
@Test
fun overwriteTruncatedValueWithNullValue() {
assertNull(GoogleTaskSynchronizer.getTruncatedValue("123456789", null, 7))
}
@Test
fun overwriteNullValueWithTruncatedValue() {
assertEquals("1234567", GoogleTaskSynchronizer.getTruncatedValue(null, "1234567", 7))
}
}

@ -1,28 +0,0 @@
package org.tasks.injection;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static org.tasks.TestUtilities.initializeMockito;
import android.content.Context;
import org.junit.Before;
import timber.log.Timber;
public abstract class InjectingTestCase {
@Before
public void setUp() {
Thread.setDefaultUncaughtExceptionHandler((t, e) -> Timber.e(e));
Context context = getApplicationContext();
initializeMockito(context);
TestComponent component =
DaggerTestComponent.builder()
.applicationModule(new ApplicationModule(context))
.testModule(new TestModule()).build();
inject(component);
}
protected abstract void inject(TestComponent component);
}

@ -0,0 +1,22 @@
package org.tasks.injection
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import org.junit.Before
import org.tasks.TestUtilities.initializeMockito
import timber.log.Timber
abstract class InjectingTestCase {
@Before
open fun setUp() {
Thread.setDefaultUncaughtExceptionHandler { _, e: Throwable? -> Timber.e(e) }
val context = ApplicationProvider.getApplicationContext<Context>()
initializeMockito(context)
val component = DaggerTestComponent.builder()
.applicationModule(ApplicationModule(context))
.testModule(TestModule()).build()
inject(component)
}
protected abstract fun inject(component: TestComponent)
}

@ -1,68 +0,0 @@
package org.tasks.injection;
import com.todoroo.astrid.alarms.AlarmJobServiceTest;
import com.todoroo.astrid.dao.TaskDaoTests;
import com.todoroo.astrid.gtasks.GtasksListServiceTest;
import com.todoroo.astrid.gtasks.GtasksMetadataServiceTest;
import com.todoroo.astrid.model.TaskTest;
import com.todoroo.astrid.reminders.ReminderServiceTest;
import com.todoroo.astrid.repeats.RepeatTaskHelperTest;
import com.todoroo.astrid.service.QuickAddMarkupTest;
import com.todoroo.astrid.service.TaskMoverTest;
import com.todoroo.astrid.service.TitleParserTest;
import com.todoroo.astrid.subtasks.SubtasksHelperTest;
import com.todoroo.astrid.subtasks.SubtasksMovingTest;
import com.todoroo.astrid.sync.NewSyncTestCase;
import dagger.Component;
import org.tasks.data.CaldavDaoTests;
import org.tasks.data.DeletionDaoTests;
import org.tasks.data.GoogleTaskDaoTests;
import org.tasks.data.GoogleTaskListDaoTest;
import org.tasks.data.LocationDaoTest;
import org.tasks.data.TagDataDaoTest;
import org.tasks.jobs.BackupServiceTests;
@ApplicationScope
@Component(modules = TestModule.class)
public interface TestComponent extends ApplicationComponent {
void inject(GtasksListServiceTest gtasksListServiceTest);
void inject(ReminderServiceTest reminderServiceTest);
void inject(TaskTest taskTest);
void inject(TaskDaoTests taskDaoTests);
void inject(NewSyncTestCase newSyncTestCase);
void inject(SubtasksMovingTest subtasksTestCase);
void inject(SubtasksHelperTest subtasksHelperTest);
void inject(QuickAddMarkupTest quickAddMarkupTest);
void inject(TitleParserTest titleParserTest);
void inject(BackupServiceTests backupServiceTests);
void inject(AlarmJobServiceTest alarmServiceTest);
void inject(RepeatTaskHelperTest repeatTaskHelperTest);
void inject(GtasksMetadataServiceTest gtasksMetadataServiceTest);
void inject(DeletionDaoTests deletionDaoTests);
void inject(GoogleTaskDaoTests googleTaskDaoTests);
void inject(TagDataDaoTest tagDataDaoTest);
void inject(CaldavDaoTests caldavDaoTests);
void inject(TaskMoverTest taskMoverTest);
void inject(LocationDaoTest locationDaoTest);
void inject(GoogleTaskListDaoTest googleTaskListDaoTest);
}

@ -0,0 +1,43 @@
package org.tasks.injection
import com.todoroo.astrid.alarms.AlarmJobServiceTest
import com.todoroo.astrid.dao.TaskDaoTests
import com.todoroo.astrid.gtasks.GtasksListServiceTest
import com.todoroo.astrid.gtasks.GtasksMetadataServiceTest
import com.todoroo.astrid.model.TaskTest
import com.todoroo.astrid.reminders.ReminderServiceTest
import com.todoroo.astrid.repeats.RepeatTaskHelperTest
import com.todoroo.astrid.service.QuickAddMarkupTest
import com.todoroo.astrid.service.TaskMoverTest
import com.todoroo.astrid.service.TitleParserTest
import com.todoroo.astrid.subtasks.SubtasksHelperTest
import com.todoroo.astrid.subtasks.SubtasksMovingTest
import com.todoroo.astrid.sync.NewSyncTestCase
import dagger.Component
import org.tasks.data.*
import org.tasks.jobs.BackupServiceTests
@ApplicationScope
@Component(modules = [TestModule::class])
interface TestComponent : ApplicationComponent {
fun inject(gtasksListServiceTest: GtasksListServiceTest)
fun inject(reminderServiceTest: ReminderServiceTest)
fun inject(taskTest: TaskTest)
fun inject(taskDaoTests: TaskDaoTests)
fun inject(newSyncTestCase: NewSyncTestCase)
fun inject(subtasksTestCase: SubtasksMovingTest)
fun inject(subtasksHelperTest: SubtasksHelperTest)
fun inject(quickAddMarkupTest: QuickAddMarkupTest)
fun inject(titleParserTest: TitleParserTest)
fun inject(backupServiceTests: BackupServiceTests)
fun inject(alarmServiceTest: AlarmJobServiceTest)
fun inject(repeatTaskHelperTest: RepeatTaskHelperTest)
fun inject(gtasksMetadataServiceTest: GtasksMetadataServiceTest)
fun inject(deletionDaoTests: DeletionDaoTests)
fun inject(googleTaskDaoTests: GoogleTaskDaoTests)
fun inject(tagDataDaoTest: TagDataDaoTest)
fun inject(caldavDaoTests: CaldavDaoTests)
fun inject(taskMoverTest: TaskMoverTest)
fun inject(locationDaoTest: LocationDaoTest)
fun inject(googleTaskListDaoTest: GoogleTaskListDaoTest)
}

@ -1,34 +0,0 @@
package org.tasks.injection;
import static org.tasks.TestUtilities.newPreferences;
import android.content.Context;
import androidx.room.Room;
import com.todoroo.astrid.dao.Database;
import dagger.Module;
import dagger.Provides;
import org.tasks.preferences.PermissionChecker;
import org.tasks.preferences.PermissivePermissionChecker;
import org.tasks.preferences.Preferences;
@Module(includes = ApplicationModule.class)
class TestModule {
@Provides
@ApplicationScope
Database getDatabase(@ForApplication Context context) {
return Room.inMemoryDatabaseBuilder(context, Database.class)
.fallbackToDestructiveMigration()
.build();
}
@Provides
PermissionChecker getPermissionChecker(@ForApplication Context context) {
return new PermissivePermissionChecker(context);
}
@Provides
Preferences getPreferences(@ForApplication Context context) {
return newPreferences(context);
}
}

@ -0,0 +1,32 @@
package org.tasks.injection
import android.content.Context
import androidx.room.Room
import com.todoroo.astrid.dao.Database
import dagger.Module
import dagger.Provides
import org.tasks.TestUtilities
import org.tasks.preferences.PermissionChecker
import org.tasks.preferences.PermissivePermissionChecker
import org.tasks.preferences.Preferences
@Module(includes = [ApplicationModule::class])
class TestModule {
@Provides
@ApplicationScope
fun getDatabase(@ForApplication context: Context): Database {
return Room.inMemoryDatabaseBuilder(context, Database::class.java)
.fallbackToDestructiveMigration()
.build()
}
@Provides
fun getPermissionChecker(@ForApplication context: Context): PermissionChecker {
return PermissivePermissionChecker(context)
}
@Provides
fun getPreferences(@ForApplication context: Context): Preferences {
return TestUtilities.newPreferences(context)
}
}

@ -1,91 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package org.tasks.jobs;
import static androidx.test.InstrumentationRegistry.getTargetContext;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import android.net.Uri;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import java.io.File;
import java.io.IOException;
import javax.inject.Inject;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.R;
import org.tasks.backup.TasksJsonExporter;
import org.tasks.backup.TasksJsonExporter.ExportType;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
import org.tasks.preferences.Preferences;
@RunWith(AndroidJUnit4.class)
public class BackupServiceTests extends InjectingTestCase {
@Inject TasksJsonExporter jsonExporter;
@Inject TaskDao taskDao;
@Inject Preferences preferences;
private File temporaryDirectory = null;
@Override
public void setUp() {
super.setUp();
try {
temporaryDirectory = File.createTempFile("backup", Long.toString(System.nanoTime()));
} catch (IOException e) {
throw new RuntimeException(e);
}
if (!(temporaryDirectory.delete())) {
throw new RuntimeException(
"Could not delete temp file: " + temporaryDirectory.getAbsolutePath());
}
if (!(temporaryDirectory.mkdir())) {
throw new RuntimeException(
"Could not create temp directory: " + temporaryDirectory.getAbsolutePath());
}
preferences.setUri(R.string.p_backup_dir, Uri.fromFile(temporaryDirectory));
// make a temporary task
Task task = new Task();
task.setTitle("helicopter");
taskDao.createNew(task);
}
@Override
protected void inject(TestComponent component) {
component.inject(this);
}
@After
public void tearDown() {
if (temporaryDirectory != null) {
for (File file : temporaryDirectory.listFiles()) {
file.delete();
}
temporaryDirectory.delete();
}
}
@Test
public void testBackup() {
assertEquals(0, temporaryDirectory.list().length);
jsonExporter.exportTasks(getTargetContext(), ExportType.EXPORT_TYPE_SERVICE, null);
// assert file created
File[] files = temporaryDirectory.listFiles();
assertEquals(1, files.length);
assertTrue(files[0].getName().matches(BackupWork.BACKUP_FILE_NAME_REGEX));
}
}

@ -0,0 +1,78 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package org.tasks.jobs
import android.net.Uri
import androidx.test.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.R
import org.tasks.backup.TasksJsonExporter
import org.tasks.backup.TasksJsonExporter.ExportType
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.preferences.Preferences
import java.io.File
import java.io.IOException
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class BackupServiceTests : InjectingTestCase() {
@Inject lateinit var jsonExporter: TasksJsonExporter
@Inject lateinit var taskDao: TaskDao
@Inject lateinit var preferences: Preferences
private lateinit var temporaryDirectory: File
override fun setUp() {
super.setUp()
temporaryDirectory = try {
File.createTempFile("backup", System.nanoTime().toString())
} catch (e: IOException) {
throw RuntimeException(e)
}
if (!temporaryDirectory.delete()) {
throw RuntimeException(
"Could not delete temp file: " + temporaryDirectory.absolutePath)
}
if (!temporaryDirectory.mkdir()) {
throw RuntimeException(
"Could not create temp directory: " + temporaryDirectory.absolutePath)
}
preferences.setUri(R.string.p_backup_dir, Uri.fromFile(temporaryDirectory))
// make a temporary task
val task = Task()
task.setTitle("helicopter")
taskDao.createNew(task)
}
override fun inject(component: TestComponent) = component.inject(this)
@After
fun tearDown() {
for (file in temporaryDirectory.listFiles()!!) {
file.delete()
}
temporaryDirectory.delete()
}
@Test
fun testBackup() {
assertEquals(0, temporaryDirectory.list()!!.size)
jsonExporter.exportTasks(InstrumentationRegistry.getTargetContext(), ExportType.EXPORT_TYPE_SERVICE, null)
// assert file created
val files = temporaryDirectory.listFiles()
assertEquals(1, files!!.size)
assertTrue(files[0].name.matches(Regex(BackupWork.BACKUP_FILE_NAME_REGEX)))
}
}

@ -1,59 +0,0 @@
package org.tasks.jobs;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.stub;
import static org.tasks.date.DateTimeUtils.newDate;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class BackupWorkTest {
private static File newFile(DateTime lastModified) {
File result = mock(File.class);
stub(result.lastModified()).toReturn(lastModified.getMillis());
return result;
}
@Test
public void filterExcludesXmlFiles() {
assertFalse(BackupWork.FILE_FILTER.accept(new File("/a/b/c/d/auto.180329-0001.xml")));
}
@Test
public void filterIncludesJsonFiles() {
assertTrue(BackupWork.FILE_FILTER.accept(new File("/a/b/c/d/auto.180329-0001.json")));
}
@Test
public void getDeleteKeepAllFiles() {
File file1 = newFile(newDate(2018, 3, 27));
File file2 = newFile(newDate(2018, 3, 28));
File file3 = newFile(newDate(2018, 3, 29));
assertEquals(emptyList(), BackupWork.getDeleteList(new File[] {file2, file1, file3}, 7));
}
@Test
public void getDeleteFromNullFileList() {
assertEquals(emptyList(), BackupWork.getDeleteList(null, 2));
}
@Test
public void sortFiles() {
File file1 = newFile(newDate(2018, 3, 27));
File file2 = newFile(newDate(2018, 3, 28));
File file3 = newFile(newDate(2018, 3, 29));
assertEquals(
singletonList(file1), BackupWork.getDeleteList(new File[] {file2, file1, file3}, 2));
}
}

@ -0,0 +1,53 @@
package org.tasks.jobs
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Assert.*
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
import org.tasks.date.DateTimeUtils
import org.tasks.time.DateTime
import java.io.File
@RunWith(AndroidJUnit4::class)
class BackupWorkTest {
@Test
fun filterExcludesXmlFiles() {
assertFalse(BackupWork.FILE_FILTER.accept(File("/a/b/c/d/auto.180329-0001.xml")))
}
@Test
fun filterIncludesJsonFiles() {
assertTrue(BackupWork.FILE_FILTER.accept(File("/a/b/c/d/auto.180329-0001.json")))
}
@Test
fun getDeleteKeepAllFiles() {
val file1 = newFile(DateTimeUtils.newDate(2018, 3, 27))
val file2 = newFile(DateTimeUtils.newDate(2018, 3, 28))
val file3 = newFile(DateTimeUtils.newDate(2018, 3, 29))
assertEquals(emptyList<Any>(), BackupWork.getDeleteList(arrayOf(file2, file1, file3), 7))
}
@Test
fun getDeleteFromNullFileList() {
assertEquals(emptyList<Any>(), BackupWork.getDeleteList(null, 2))
}
@Test
fun sortFiles() {
val file1 = newFile(DateTimeUtils.newDate(2018, 3, 27))
val file2 = newFile(DateTimeUtils.newDate(2018, 3, 28))
val file3 = newFile(DateTimeUtils.newDate(2018, 3, 29))
assertEquals(
listOf(file1), BackupWork.getDeleteList(arrayOf(file2, file1, file3), 2))
}
companion object {
private fun newFile(lastModified: DateTime): File {
val result = Mockito.mock(File::class.java)
Mockito.stub(result.lastModified()).toReturn(lastModified.millis)
return result
}
}
}

@ -1,371 +0,0 @@
package org.tasks.jobs;
import static com.google.common.collect.Sets.newHashSet;
import static com.todoroo.astrid.reminders.ReminderService.TYPE_DUE;
import static com.todoroo.astrid.reminders.ReminderService.TYPE_SNOOZE;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static junit.framework.Assert.assertEquals;
import static org.mockito.AdditionalAnswers.returnsFirstArg;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.tasks.Freeze;
import org.tasks.Snippet;
import org.tasks.preferences.Preferences;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class NotificationQueueTest {
private static final long ONE_MINUTE = TimeUnit.MINUTES.toMillis(1);
private NotificationQueue queue;
private WorkManager workManager;
private Preferences preferences;
@Before
public void before() {
preferences = mock(Preferences.class);
when(preferences.adjustForQuietHours(anyLong())).then(returnsFirstArg());
workManager = mock(WorkManager.class);
queue = new NotificationQueue(preferences, workManager);
}
@After
public void after() {
verifyNoMoreInteractions(workManager);
}
@Test
public void alarmAndReminderSameTimeSameID() {
long now = currentTimeMillis();
queue.add(new ReminderEntry(1, now, TYPE_DUE));
queue.add(new AlarmEntry(1, 1, now));
verify(workManager).scheduleNotification(now);
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(
newHashSet(new AlarmEntry(1, 1, now), new ReminderEntry(1, now, TYPE_DUE)),
newHashSet(queue.getOverdueJobs()));
}
});
}
@Test
public void alarmAndReminderSameTimeDifferentId() {
long now = currentTimeMillis();
queue.add(new AlarmEntry(1, 2, now));
queue.add(new ReminderEntry(1, now + 1000, TYPE_DUE));
verify(workManager).scheduleNotification(now);
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(
newHashSet(new AlarmEntry(1, 2, now), new ReminderEntry(1, now + 1000, TYPE_DUE)),
newHashSet(queue.getOverdueJobs()));
}
});
}
@Test
public void removeAlarmLeaveReminder() {
long now = currentTimeMillis();
queue.add(new ReminderEntry(1, now, TYPE_DUE));
queue.add(new AlarmEntry(1, 1, now));
verify(workManager).scheduleNotification(now);
queue.remove(singletonList(new AlarmEntry(1, 1, now)));
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(
singletonList(new ReminderEntry(1, now, TYPE_DUE)), queue.getOverdueJobs());
}
});
}
@Test
public void removeReminderLeaveAlarm() {
long now = currentTimeMillis();
queue.add(new ReminderEntry(1, now, TYPE_DUE));
queue.add(new AlarmEntry(1, 1, now));
verify(workManager).scheduleNotification(now);
queue.remove(singletonList(new ReminderEntry(1, now, TYPE_DUE)));
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(singletonList(new AlarmEntry(1, 1, now)), queue.getOverdueJobs());
}
});
}
@Test
public void twoJobsAtSameTime() {
queue.add(new ReminderEntry(1, 1, 0));
queue.add(new ReminderEntry(2, 1, 0));
verify(workManager).scheduleNotification(1);
assertEquals(2, queue.size());
}
@Test
public void rescheduleForFirstJob() {
queue.add(new ReminderEntry(1, 1, 0));
verify(workManager).scheduleNotification(1);
}
@Test
public void dontRescheduleForLaterJobs() {
queue.add(new ReminderEntry(1, 1, 0));
queue.add(new ReminderEntry(2, 2, 0));
verify(workManager).scheduleNotification(1);
}
@Test
public void rescheduleForNewerJob() {
queue.add(new ReminderEntry(1, 2, 0));
queue.add(new ReminderEntry(1, 1, 0));
InOrder order = inOrder(workManager);
order.verify(workManager).scheduleNotification(2);
order.verify(workManager).scheduleNotification(1);
}
@Test
public void rescheduleWhenCancelingOnlyJob() {
queue.add(new ReminderEntry(1, 2, 0));
queue.cancelReminder(1);
InOrder order = inOrder(workManager);
order.verify(workManager).scheduleNotification(2);
order.verify(workManager).cancelNotifications();
}
@Test
public void rescheduleWhenCancelingFirstJob() {
queue.add(new ReminderEntry(1, 1, 0));
queue.add(new ReminderEntry(2, 2, 0));
queue.cancelReminder(1);
InOrder order = inOrder(workManager);
order.verify(workManager).scheduleNotification(1);
order.verify(workManager).scheduleNotification(2);
}
@Test
public void dontRescheduleWhenCancelingLaterJob() {
queue.add(new ReminderEntry(1, 1, 0));
queue.add(new ReminderEntry(2, 2, 0));
queue.cancelReminder(2);
verify(workManager).scheduleNotification(1);
}
@Test
public void nextScheduledTimeIsZeroWhenQueueIsEmpty() {
when(preferences.adjustForQuietHours(anyLong())).thenReturn(1234L);
assertEquals(0, queue.nextScheduledTime());
}
@Test
public void adjustNextScheduledTimeForQuietHours() {
when(preferences.adjustForQuietHours(anyLong())).thenReturn(1234L);
queue.add(new ReminderEntry(1, 1, 1));
verify(workManager).scheduleNotification(1234);
}
@Test
public void overdueJobsAreReturned() {
long now = currentTimeMillis();
queue.add(new ReminderEntry(1, now, TYPE_DUE));
queue.add(new ReminderEntry(2, now + ONE_MINUTE, TYPE_DUE));
verify(workManager).scheduleNotification(now);
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(
singletonList(new ReminderEntry(1, now, TYPE_DUE)), queue.getOverdueJobs());
}
});
}
@Test
public void twoOverdueJobsAtSameTimeReturned() {
long now = currentTimeMillis();
queue.add(new ReminderEntry(1, now, TYPE_DUE));
queue.add(new ReminderEntry(2, now, TYPE_DUE));
verify(workManager).scheduleNotification(now);
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(
asList(
new ReminderEntry(1, now, TYPE_DUE), new ReminderEntry(2, now, TYPE_DUE)),
queue.getOverdueJobs());
}
});
}
@Test
public void twoOverdueJobsAtDifferentTimes() {
long now = currentTimeMillis();
queue.add(new ReminderEntry(1, now, TYPE_DUE));
queue.add(new ReminderEntry(2, now + ONE_MINUTE, TYPE_DUE));
verify(workManager).scheduleNotification(now);
Freeze.freezeAt(now + 2 * ONE_MINUTE)
.thawAfter(
new Snippet() {
{
assertEquals(
asList(
new ReminderEntry(1, now, TYPE_DUE),
new ReminderEntry(2, now + ONE_MINUTE, TYPE_DUE)),
queue.getOverdueJobs());
}
});
}
@Test
public void overdueJobsAreRemoved() {
long now = currentTimeMillis();
queue.add(new ReminderEntry(1, now, TYPE_DUE));
queue.add(new ReminderEntry(2, now + ONE_MINUTE, TYPE_DUE));
verify(workManager).scheduleNotification(now);
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
queue.remove(queue.getOverdueJobs());
}
});
assertEquals(singletonList(new ReminderEntry(2, now + ONE_MINUTE, TYPE_DUE)), queue.getJobs());
}
@Test
public void multipleOverduePeriodsLapsed() {
long now = currentTimeMillis();
queue.add(new ReminderEntry(1, now, TYPE_DUE));
queue.add(new ReminderEntry(2, now + ONE_MINUTE, TYPE_DUE));
queue.add(new ReminderEntry(3, now + 2 * ONE_MINUTE, TYPE_DUE));
verify(workManager).scheduleNotification(now);
Freeze.freezeAt(now + ONE_MINUTE)
.thawAfter(
new Snippet() {
{
queue.remove(queue.getOverdueJobs());
}
});
assertEquals(
singletonList(new ReminderEntry(3, now + 2 * ONE_MINUTE, TYPE_DUE)), queue.getJobs());
}
@Test
public void clearShouldCancelExisting() {
queue.add(new ReminderEntry(1, 1, 0));
queue.clear();
InOrder order = inOrder(workManager);
order.verify(workManager).scheduleNotification(1);
order.verify(workManager).cancelNotifications();
assertEquals(0, queue.size());
}
@Test
public void ignoreInvalidCancel() {
long now = currentTimeMillis();
queue.add(new ReminderEntry(1, now, TYPE_DUE));
queue.cancelReminder(2);
verify(workManager).scheduleNotification(now);
}
@Test
public void allDuringSameMinuteAreOverdue() {
DateTime now = new DateTime(2017, 9, 3, 0, 14, 6, 455);
DateTime due = new DateTime(2017, 9, 3, 0, 14, 0, 0);
DateTime snooze = new DateTime(2017, 9, 3, 0, 14, 59, 999);
queue.add(new ReminderEntry(1, due.getMillis(), TYPE_DUE));
queue.add(new ReminderEntry(2, snooze.getMillis(), TYPE_SNOOZE));
queue.add(new ReminderEntry(3, due.plusMinutes(1).getMillis(), TYPE_DUE));
verify(workManager).scheduleNotification(due.getMillis());
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
List<? extends NotificationQueueEntry> overdueJobs = queue.getOverdueJobs();
assertEquals(
asList(
new ReminderEntry(1, due.getMillis(), TYPE_DUE),
new ReminderEntry(2, snooze.getMillis(), TYPE_SNOOZE)),
overdueJobs);
queue.remove(overdueJobs);
assertEquals(
singletonList(new ReminderEntry(3, due.plusMinutes(1).getMillis(), TYPE_DUE)),
queue.getJobs());
}
});
}
}

@ -0,0 +1,270 @@
package org.tasks.jobs
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.todoroo.astrid.reminders.ReminderService
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.AdditionalAnswers
import org.mockito.Matchers
import org.mockito.Mockito
import org.tasks.Freeze.Companion.freezeAt
import org.tasks.preferences.Preferences
import org.tasks.time.DateTime
import org.tasks.time.DateTimeUtils
import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
class NotificationQueueTest {
private lateinit var queue: NotificationQueue
private lateinit var workManager: WorkManager
private lateinit var preferences: Preferences
@Before
fun before() {
preferences = Mockito.mock(Preferences::class.java)
Mockito.`when`(preferences.adjustForQuietHours(Matchers.anyLong())).then(AdditionalAnswers.returnsFirstArg<Any>())
workManager = Mockito.mock(WorkManager::class.java)
queue = NotificationQueue(preferences, workManager)
}
@After
fun after() {
Mockito.verifyNoMoreInteractions(workManager)
}
@Test
fun alarmAndReminderSameTimeSameID() {
val now = DateTimeUtils.currentTimeMillis()
queue.add(ReminderEntry(1, now, ReminderService.TYPE_DUE))
queue.add(AlarmEntry(1, 1, now))
Mockito.verify(workManager).scheduleNotification(now)
freezeAt(now) {
assertEquals(
setOf(AlarmEntry(1, 1, now), ReminderEntry(1, now, ReminderService.TYPE_DUE)),
queue.overdueJobs.toSet())
}
}
@Test
fun alarmAndReminderSameTimeDifferentId() {
val now = DateTimeUtils.currentTimeMillis()
queue.add(AlarmEntry(1, 2, now))
queue.add(ReminderEntry(1, now + 1000, ReminderService.TYPE_DUE))
Mockito.verify(workManager).scheduleNotification(now)
freezeAt(now) {
assertEquals(
setOf(AlarmEntry(1, 2, now), ReminderEntry(1, now + 1000, ReminderService.TYPE_DUE)),
queue.overdueJobs.toSet())
}
}
@Test
fun removeAlarmLeaveReminder() {
val now = DateTimeUtils.currentTimeMillis()
queue.add(ReminderEntry(1, now, ReminderService.TYPE_DUE))
queue.add(AlarmEntry(1, 1, now))
Mockito.verify(workManager).scheduleNotification(now)
queue.remove(listOf(AlarmEntry(1, 1, now)))
freezeAt(now) {
assertEquals(
listOf(ReminderEntry(1, now, ReminderService.TYPE_DUE)), queue.overdueJobs)
}
}
@Test
fun removeReminderLeaveAlarm() {
val now = DateTimeUtils.currentTimeMillis()
queue.add(ReminderEntry(1, now, ReminderService.TYPE_DUE))
queue.add(AlarmEntry(1, 1, now))
Mockito.verify(workManager).scheduleNotification(now)
queue.remove(listOf(ReminderEntry(1, now, ReminderService.TYPE_DUE)))
freezeAt(now) {
assertEquals(listOf(AlarmEntry(1, 1, now)), queue.overdueJobs)
}
}
@Test
fun twoJobsAtSameTime() {
queue.add(ReminderEntry(1, 1, 0))
queue.add(ReminderEntry(2, 1, 0))
Mockito.verify(workManager).scheduleNotification(1)
assertEquals(2, queue.size())
}
@Test
fun rescheduleForFirstJob() {
queue.add(ReminderEntry(1, 1, 0))
Mockito.verify(workManager).scheduleNotification(1)
}
@Test
fun dontRescheduleForLaterJobs() {
queue.add(ReminderEntry(1, 1, 0))
queue.add(ReminderEntry(2, 2, 0))
Mockito.verify(workManager).scheduleNotification(1)
}
@Test
fun rescheduleForNewerJob() {
queue.add(ReminderEntry(1, 2, 0))
queue.add(ReminderEntry(1, 1, 0))
val order = Mockito.inOrder(workManager)
order.verify(workManager).scheduleNotification(2)
order.verify(workManager).scheduleNotification(1)
}
@Test
fun rescheduleWhenCancelingOnlyJob() {
queue.add(ReminderEntry(1, 2, 0))
queue.cancelReminder(1)
val order = Mockito.inOrder(workManager)
order.verify(workManager).scheduleNotification(2)
order.verify(workManager).cancelNotifications()
}
@Test
fun rescheduleWhenCancelingFirstJob() {
queue.add(ReminderEntry(1, 1, 0))
queue.add(ReminderEntry(2, 2, 0))
queue.cancelReminder(1)
val order = Mockito.inOrder(workManager)
order.verify(workManager).scheduleNotification(1)
order.verify(workManager).scheduleNotification(2)
}
@Test
fun dontRescheduleWhenCancelingLaterJob() {
queue.add(ReminderEntry(1, 1, 0))
queue.add(ReminderEntry(2, 2, 0))
queue.cancelReminder(2)
Mockito.verify(workManager).scheduleNotification(1)
}
@Test
fun nextScheduledTimeIsZeroWhenQueueIsEmpty() {
Mockito.`when`(preferences.adjustForQuietHours(Matchers.anyLong())).thenReturn(1234L)
assertEquals(0, queue.nextScheduledTime())
}
@Test
fun adjustNextScheduledTimeForQuietHours() {
Mockito.`when`(preferences.adjustForQuietHours(Matchers.anyLong())).thenReturn(1234L)
queue.add(ReminderEntry(1, 1, 1))
Mockito.verify(workManager).scheduleNotification(1234)
}
@Test
fun overdueJobsAreReturned() {
val now = DateTimeUtils.currentTimeMillis()
queue.add(ReminderEntry(1, now, ReminderService.TYPE_DUE))
queue.add(ReminderEntry(2, now + ONE_MINUTE, ReminderService.TYPE_DUE))
Mockito.verify(workManager).scheduleNotification(now)
freezeAt(now) {
assertEquals(
listOf(ReminderEntry(1, now, ReminderService.TYPE_DUE)), queue.overdueJobs)
}
}
@Test
fun twoOverdueJobsAtSameTimeReturned() {
val now = DateTimeUtils.currentTimeMillis()
queue.add(ReminderEntry(1, now, ReminderService.TYPE_DUE))
queue.add(ReminderEntry(2, now, ReminderService.TYPE_DUE))
Mockito.verify(workManager).scheduleNotification(now)
freezeAt(now) {
assertEquals(
listOf(
ReminderEntry(1, now, ReminderService.TYPE_DUE), ReminderEntry(2, now, ReminderService.TYPE_DUE)),
queue.overdueJobs)
}
}
@Test
fun twoOverdueJobsAtDifferentTimes() {
val now = DateTimeUtils.currentTimeMillis()
queue.add(ReminderEntry(1, now, ReminderService.TYPE_DUE))
queue.add(ReminderEntry(2, now + ONE_MINUTE, ReminderService.TYPE_DUE))
Mockito.verify(workManager).scheduleNotification(now)
freezeAt(now + 2 * ONE_MINUTE) {
assertEquals(
listOf(
ReminderEntry(1, now, ReminderService.TYPE_DUE),
ReminderEntry(2, now + ONE_MINUTE, ReminderService.TYPE_DUE)),
queue.overdueJobs)
}
}
@Test
fun overdueJobsAreRemoved() {
val now = DateTimeUtils.currentTimeMillis()
queue.add(ReminderEntry(1, now, ReminderService.TYPE_DUE))
queue.add(ReminderEntry(2, now + ONE_MINUTE, ReminderService.TYPE_DUE))
Mockito.verify(workManager).scheduleNotification(now)
freezeAt(now) {
queue.remove(queue.overdueJobs)
}
assertEquals(listOf(ReminderEntry(2, now + ONE_MINUTE, ReminderService.TYPE_DUE)), queue.jobs)
}
@Test
fun multipleOverduePeriodsLapsed() {
val now = DateTimeUtils.currentTimeMillis()
queue.add(ReminderEntry(1, now, ReminderService.TYPE_DUE))
queue.add(ReminderEntry(2, now + ONE_MINUTE, ReminderService.TYPE_DUE))
queue.add(ReminderEntry(3, now + 2 * ONE_MINUTE, ReminderService.TYPE_DUE))
Mockito.verify(workManager).scheduleNotification(now)
freezeAt(now + ONE_MINUTE) {
queue.remove(queue.overdueJobs)
}
assertEquals(
listOf(ReminderEntry(3, now + 2 * ONE_MINUTE, ReminderService.TYPE_DUE)), queue.jobs)
}
@Test
fun clearShouldCancelExisting() {
queue.add(ReminderEntry(1, 1, 0))
queue.clear()
val order = Mockito.inOrder(workManager)
order.verify(workManager).scheduleNotification(1)
order.verify(workManager).cancelNotifications()
assertEquals(0, queue.size())
}
@Test
fun ignoreInvalidCancel() {
val now = DateTimeUtils.currentTimeMillis()
queue.add(ReminderEntry(1, now, ReminderService.TYPE_DUE))
queue.cancelReminder(2)
Mockito.verify(workManager).scheduleNotification(now)
}
@Test
fun allDuringSameMinuteAreOverdue() {
val now = DateTime(2017, 9, 3, 0, 14, 6, 455)
val due = DateTime(2017, 9, 3, 0, 14, 0, 0)
val snooze = DateTime(2017, 9, 3, 0, 14, 59, 999)
queue.add(ReminderEntry(1, due.millis, ReminderService.TYPE_DUE))
queue.add(ReminderEntry(2, snooze.millis, ReminderService.TYPE_SNOOZE))
queue.add(ReminderEntry(3, due.plusMinutes(1).millis, ReminderService.TYPE_DUE))
Mockito.verify(workManager).scheduleNotification(due.millis)
freezeAt(now) {
val overdueJobs = queue.overdueJobs
assertEquals(
listOf(
ReminderEntry(1, due.millis, ReminderService.TYPE_DUE),
ReminderEntry(2, snooze.millis, ReminderService.TYPE_SNOOZE)),
overdueJobs)
queue.remove(overdueJobs)
assertEquals(
listOf(ReminderEntry(3, due.plusMinutes(1).millis, ReminderService.TYPE_DUE)),
queue.jobs)
}
}
companion object {
private val ONE_MINUTE = TimeUnit.MINUTES.toMillis(1)
}
}

@ -1,31 +0,0 @@
package org.tasks.makers;
import static com.natpryce.makeiteasy.Property.newProperty;
import static org.tasks.makers.Maker.make;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Property;
import com.natpryce.makeiteasy.PropertyValue;
import org.tasks.data.CaldavTask;
public class CaldavTaskMaker {
public static final Property<CaldavTask, String> CALENDAR = newProperty();
public static final Property<CaldavTask, Long> TASK = newProperty();
public static final Property<CaldavTask, String> REMOTE_ID = newProperty();
public static final Property<CaldavTask, String> REMOTE_PARENT = newProperty();
private static final Instantiator<CaldavTask> instantiator =
lookup -> {
CaldavTask task =
new CaldavTask(lookup.valueOf(TASK, 1L), lookup.valueOf(CALENDAR, "calendar"));
task.setRemoteId(lookup.valueOf(REMOTE_ID, task.getRemoteId()));
task.setRemoteParent(lookup.valueOf(REMOTE_PARENT, (String) null));
return task;
};
@SafeVarargs
public static CaldavTask newCaldavTask(PropertyValue<? super CaldavTask, ?>... properties) {
return make(instantiator, properties);
}
}

@ -0,0 +1,27 @@
package org.tasks.makers
import com.natpryce.makeiteasy.Instantiator
import com.natpryce.makeiteasy.Property
import com.natpryce.makeiteasy.Property.newProperty
import com.natpryce.makeiteasy.PropertyValue
import org.tasks.data.CaldavTask
import org.tasks.makers.Maker.make
object CaldavTaskMaker {
@JvmField val CALENDAR: Property<CaldavTask, String> = newProperty()
@JvmField val TASK: Property<CaldavTask, Long> = newProperty()
@JvmField val REMOTE_ID: Property<CaldavTask, String?> = newProperty()
@JvmField val REMOTE_PARENT: Property<CaldavTask, String?> = newProperty()
private val instantiator = Instantiator<CaldavTask> {
val task = CaldavTask(it.valueOf(TASK, 1L), it.valueOf(CALENDAR, "calendar"))
task.remoteId = it.valueOf(REMOTE_ID, task.remoteId)
task.remoteParent = it.valueOf(REMOTE_PARENT, null as String?)
task
}
@JvmStatic
fun newCaldavTask(vararg properties: PropertyValue<in CaldavTask?, *>): CaldavTask {
return make(instantiator, *properties)
}
}

@ -1,34 +0,0 @@
package org.tasks.makers;
import static com.natpryce.makeiteasy.Property.newProperty;
import static org.tasks.makers.Maker.make;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Property;
import com.natpryce.makeiteasy.PropertyValue;
import com.todoroo.astrid.helper.UUIDHelper;
import org.tasks.data.GoogleTask;
public class GoogleTaskMaker {
public static final Property<GoogleTask, String> LIST = newProperty();
public static final Property<GoogleTask, Integer> ORDER = newProperty();
public static final Property<GoogleTask, String> REMOTE_ID = newProperty();
public static final Property<GoogleTask, Integer> TASK = newProperty();
public static final Property<GoogleTask, Long> PARENT = newProperty();
private static final Instantiator<GoogleTask> instantiator = lookup -> {
GoogleTask task = new GoogleTask();
task.setListId(lookup.valueOf(LIST, "1"));
task.setOrder(lookup.valueOf(ORDER, 0));
task.setRemoteId(lookup.valueOf(REMOTE_ID, UUIDHelper.newUUID()));
task.setTask(lookup.valueOf(TASK, 1));
task.setParent(lookup.valueOf(PARENT, 0L));
return task;
};
@SafeVarargs
public static GoogleTask newGoogleTask(PropertyValue<? super GoogleTask, ?>... properties) {
return make(instantiator, properties);
}
}

@ -0,0 +1,32 @@
package org.tasks.makers
import com.natpryce.makeiteasy.Instantiator
import com.natpryce.makeiteasy.Property
import com.natpryce.makeiteasy.Property.newProperty
import com.natpryce.makeiteasy.PropertyValue
import com.todoroo.astrid.helper.UUIDHelper
import org.tasks.data.GoogleTask
import org.tasks.makers.Maker.make
object GoogleTaskMaker {
@JvmField val LIST: Property<GoogleTask, String> = newProperty()
val ORDER: Property<GoogleTask, Int> = newProperty()
@JvmField val REMOTE_ID: Property<GoogleTask, String> = newProperty()
@JvmField val TASK: Property<GoogleTask, Int> = newProperty()
@JvmField val PARENT: Property<GoogleTask, Long> = newProperty()
private val instantiator = Instantiator<GoogleTask> {
val task = GoogleTask()
task.listId = it.valueOf(LIST, "1")
task.order = it.valueOf(ORDER, 0).toLong()
task.remoteId = it.valueOf(REMOTE_ID, UUIDHelper.newUUID())
task.task = it.valueOf(TASK, 1).toLong()
task.parent = it.valueOf(PARENT, 0L)
task
}
@JvmStatic
fun newGoogleTask(vararg properties: PropertyValue<in GoogleTask?, *>): GoogleTask {
return make(instantiator, *properties)
}
}

@ -1,38 +0,0 @@
package org.tasks.makers;
import static com.natpryce.makeiteasy.Property.newProperty;
import static org.tasks.makers.Maker.make;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Property;
import com.natpryce.makeiteasy.PropertyValue;
import org.tasks.data.GoogleTaskList;
public class GtaskListMaker {
public static final Property<GoogleTaskList, Long> ID = newProperty();
public static final Property<GoogleTaskList, String> ACCOUNT = newProperty();
public static final Property<GoogleTaskList, String> REMOTE_ID = newProperty();
public static final Property<GoogleTaskList, Long> LAST_SYNC = newProperty();
public static final Property<GoogleTaskList, String> NAME = newProperty();
private static final Property<GoogleTaskList, Integer> ORDER = newProperty();
private static final Property<GoogleTaskList, Integer> COLOR = newProperty();
private static final Instantiator<GoogleTaskList> instantiator =
lookup -> {
GoogleTaskList list = new GoogleTaskList();
list.setId(lookup.valueOf(GtaskListMaker.ID, 0L));
list.setAccount(lookup.valueOf(ACCOUNT, "account"));
list.setRemoteId(lookup.valueOf(REMOTE_ID, "1"));
list.setTitle(lookup.valueOf(NAME, "Default"));
list.setRemoteOrder(lookup.valueOf(ORDER, 0));
list.setLastSync(lookup.valueOf(LAST_SYNC, 0L));
list.setColor(lookup.valueOf(COLOR, 0));
return list;
};
@SafeVarargs
public static GoogleTaskList newGtaskList(
PropertyValue<? super GoogleTaskList, ?>... properties) {
return make(instantiator, properties);
}
}

@ -0,0 +1,36 @@
package org.tasks.makers
import com.natpryce.makeiteasy.Instantiator
import com.natpryce.makeiteasy.Property
import com.natpryce.makeiteasy.Property.newProperty
import com.natpryce.makeiteasy.PropertyLookup
import com.natpryce.makeiteasy.PropertyValue
import org.tasks.data.GoogleTaskList
import org.tasks.makers.Maker.make
object GtaskListMaker {
@JvmField val ID: Property<GoogleTaskList, Long> = newProperty()
val ACCOUNT: Property<GoogleTaskList, String> = newProperty()
@JvmField val REMOTE_ID: Property<GoogleTaskList, String> = newProperty()
val LAST_SYNC: Property<GoogleTaskList, Long> = newProperty()
@JvmField val NAME: Property<GoogleTaskList, String> = newProperty()
private val ORDER: Property<GoogleTaskList, Int> = newProperty()
private val COLOR: Property<GoogleTaskList, Int> = newProperty()
private val instantiator = Instantiator { lookup: PropertyLookup<GoogleTaskList> ->
val list = GoogleTaskList()
list.id = lookup.valueOf(ID, 0L)
list.account = lookup.valueOf(ACCOUNT, "account")
list.remoteId = lookup.valueOf(REMOTE_ID, "1")
list.title = lookup.valueOf(NAME, "Default")
list.remoteOrder = lookup.valueOf(ORDER, 0)
list.lastSync = lookup.valueOf(LAST_SYNC, 0L)
list.color = lookup.valueOf(COLOR, 0)
list
}
@JvmStatic
fun newGtaskList(vararg properties: PropertyValue<in GoogleTaskList?, *>): GoogleTaskList {
return make(instantiator, *properties)
}
}

@ -1,15 +0,0 @@
package org.tasks.makers;
import static com.natpryce.makeiteasy.MakeItEasy.a;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.PropertyValue;
class Maker {
@SuppressWarnings("unchecked")
public static <T> T make(
Instantiator<T> instantiator, PropertyValue<? super T, ?>... properties) {
return com.natpryce.makeiteasy.MakeItEasy.make(a(instantiator, properties));
}
}

@ -0,0 +1,12 @@
package org.tasks.makers
import com.natpryce.makeiteasy.Instantiator
import com.natpryce.makeiteasy.MakeItEasy
import com.natpryce.makeiteasy.PropertyValue
internal object Maker {
@JvmStatic
fun <T> make(instantiator: Instantiator<T>, vararg properties: PropertyValue<in T, *>?): T {
return MakeItEasy.make(MakeItEasy.a(instantiator, *properties))
}
}

@ -1,27 +0,0 @@
package org.tasks.makers;
import static com.natpryce.makeiteasy.Property.newProperty;
import static org.tasks.makers.Maker.make;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import com.google.api.client.util.DateTime;
import com.google.api.services.tasks.model.TaskList;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Property;
import com.natpryce.makeiteasy.PropertyValue;
public class RemoteGtaskListMaker {
public static final Property<TaskList, String> REMOTE_ID = newProperty();
public static final Property<TaskList, String> NAME = newProperty();
private static final Instantiator<TaskList> instantiator =
lookup ->
new TaskList()
.setId(lookup.valueOf(REMOTE_ID, "1"))
.setTitle(lookup.valueOf(NAME, "Default"))
.setUpdated(new DateTime(currentTimeMillis()));
public static TaskList newRemoteList(PropertyValue<? super TaskList, ?>... properties) {
return make(instantiator, properties);
}
}

@ -0,0 +1,28 @@
package org.tasks.makers
import com.google.api.client.util.DateTime
import com.google.api.services.tasks.model.TaskList
import com.natpryce.makeiteasy.Instantiator
import com.natpryce.makeiteasy.Property
import com.natpryce.makeiteasy.Property.newProperty
import com.natpryce.makeiteasy.PropertyLookup
import com.natpryce.makeiteasy.PropertyValue
import org.tasks.makers.Maker.make
import org.tasks.time.DateTimeUtils
object RemoteGtaskListMaker {
@JvmField val REMOTE_ID: Property<TaskList, String> = newProperty()
@JvmField val NAME: Property<TaskList, String> = newProperty()
private val instantiator = Instantiator { lookup: PropertyLookup<TaskList> ->
TaskList()
.setId(lookup.valueOf(REMOTE_ID, "1"))
.setTitle(lookup.valueOf(NAME, "Default"))
.setUpdated(DateTime(DateTimeUtils.currentTimeMillis()))
}
@JvmStatic
fun newRemoteList(vararg properties: PropertyValue<in TaskList?, *>): TaskList {
return make(instantiator, *properties)
}
}

@ -1,27 +0,0 @@
package org.tasks.makers;
import static com.natpryce.makeiteasy.Property.newProperty;
import static org.tasks.makers.Maker.make;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Property;
import com.natpryce.makeiteasy.PropertyValue;
import org.tasks.data.TagData;
public class TagDataMaker {
public static final Property<TagData, String> NAME = newProperty();
public static final Property<TagData, String> UID = newProperty();
private static final Instantiator<TagData> instantiator = lookup -> {
TagData tagData = new TagData();
tagData.setName(lookup.valueOf(NAME, "tag"));
tagData.setRemoteId(lookup.valueOf(UID, (String) null));
return tagData;
};
@SafeVarargs
public static TagData newTagData(PropertyValue<? super TagData, ?>... properties) {
return make(instantiator, properties);
}
}

@ -0,0 +1,26 @@
package org.tasks.makers
import com.natpryce.makeiteasy.Instantiator
import com.natpryce.makeiteasy.Property
import com.natpryce.makeiteasy.Property.newProperty
import com.natpryce.makeiteasy.PropertyLookup
import com.natpryce.makeiteasy.PropertyValue
import org.tasks.data.TagData
import org.tasks.makers.Maker.make
object TagDataMaker {
@JvmField val NAME: Property<TagData, String> = newProperty()
val UID: Property<TagData, String?> = newProperty()
private val instantiator = Instantiator { lookup: PropertyLookup<TagData> ->
val tagData = TagData()
tagData.name = lookup.valueOf(NAME, "tag")
tagData.remoteId = lookup.valueOf(UID, null as String?)
tagData
}
@JvmStatic
fun newTagData(vararg properties: PropertyValue<in TagData?, *>): TagData {
return make(instantiator, *properties)
}
}

@ -1,39 +0,0 @@
package org.tasks.makers;
import static com.natpryce.makeiteasy.Property.newProperty;
import static org.tasks.makers.Maker.make;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Property;
import com.natpryce.makeiteasy.PropertyValue;
import com.todoroo.astrid.data.Task;
import org.tasks.data.Tag;
import org.tasks.data.TagData;
public class TagMaker {
public static final Property<Tag, TagData> TAGDATA = newProperty();
public static final Property<Tag, Task> TASK = newProperty();
public static final Property<Tag, String> TAGUID = newProperty();
private static final Instantiator<Tag> instantiator =
lookup -> {
Tag tag = new Tag();
Task task = lookup.valueOf(TASK, (Task) null);
assert (task != null);
tag.setTask(task.getId());
tag.setTaskUid(task.getUuid());
tag.setTagUid(lookup.valueOf(TAGUID, (String) null));
TagData tagData = lookup.valueOf(TAGDATA, (TagData) null);
if (tagData != null) {
tag.setTagUid(tagData.getRemoteId());
}
assert(tag.getTagUid() != null);
return tag;
};
@SafeVarargs
public static Tag newTag(PropertyValue<? super Tag, ?>... properties) {
return make(instantiator, properties);
}
}

@ -0,0 +1,36 @@
package org.tasks.makers
import com.natpryce.makeiteasy.Instantiator
import com.natpryce.makeiteasy.Property
import com.natpryce.makeiteasy.Property.newProperty
import com.natpryce.makeiteasy.PropertyLookup
import com.natpryce.makeiteasy.PropertyValue
import com.todoroo.astrid.data.Task
import org.tasks.data.Tag
import org.tasks.data.TagData
import org.tasks.makers.Maker.make
object TagMaker {
@JvmField val TAGDATA: Property<Tag, TagData?> = newProperty()
@JvmField val TASK: Property<Tag, Task?> = newProperty()
@JvmField val TAGUID: Property<Tag, String?> = newProperty()
private val instantiator = Instantiator { lookup: PropertyLookup<Tag> ->
val tag = Tag()
val task = lookup.valueOf(TASK, null as Task?)!!
tag.task = task.getId()
tag.taskUid = task.uuid
tag.tagUid = lookup.valueOf(TAGUID, null as String?)
val tagData = lookup.valueOf(TAGDATA, null as TagData?)
if (tagData != null) {
tag.tagUid = tagData.remoteId
}
assert(tag.tagUid != null)
tag
}
@JvmStatic
fun newTag(vararg properties: PropertyValue<in Tag?, *>): Tag {
return make(instantiator, *properties)
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save