diff options
author | Niedermann IT-Dienstleistungen <stefan-niedermann@users.noreply.github.com> | 2021-01-03 22:20:10 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-03 22:20:10 +0300 |
commit | a6d553786c9666b6bcbdb534b121a261e3617cb1 (patch) | |
tree | b91248cb8c5370fec6cd7a9683b6b8bb157790a2 /app/src/test/java/it/niedermann/nextcloud/deck | |
parent | 73e5bcfabf65b4745b1e3473e46404ef14fe1a40 (diff) |
Migrate instrumented tests to robolectric tests (#784)
Diffstat (limited to 'app/src/test/java/it/niedermann/nextcloud/deck')
12 files changed, 953 insertions, 0 deletions
diff --git a/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DataBaseAdapterTest.java b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DataBaseAdapterTest.java new file mode 100644 index 000000000..9d41c06d1 --- /dev/null +++ b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DataBaseAdapterTest.java @@ -0,0 +1,88 @@ +package it.niedermann.nextcloud.deck.persistence.sync.adapters.db; + +import android.content.Context; +import android.os.Build; + +import androidx.room.Room; +import androidx.test.core.app.ApplicationProvider; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; + +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.Board; +import it.niedermann.nextcloud.deck.model.User; +import it.niedermann.nextcloud.deck.model.full.FullBoard; +import it.niedermann.nextcloud.deck.model.interfaces.AbstractRemoteEntity; + +import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabaseTestUtil.createAccount; +import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabaseTestUtil.createBoard; +import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabaseTestUtil.createUser; +import static org.junit.Assert.assertEquals; + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = {Build.VERSION_CODES.P}) +public class DataBaseAdapterTest { + + private DeckDatabase db; + private DataBaseAdapter adapter; + + @Before + public void createAdapter() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + final Constructor<DataBaseAdapter> constructor = DataBaseAdapter.class.getDeclaredConstructor(Context.class, DeckDatabase.class); + if (Modifier.isPrivate(constructor.getModifiers())) { + constructor.setAccessible(true); + db = Room + .inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), DeckDatabase.class) + .allowMainThreadQueries() + .build(); + adapter = constructor.newInstance(ApplicationProvider.getApplicationContext(), db); + } + } + + @After + public void closeDb() { + if (db != null) { + db.close(); + } + } + + @Test + public void testCreate() { + final Account account = createAccount(db.getAccountDao()); + final User user = createUser(db.getUserDao(), account); + final Board board = createBoard(db.getBoardDao(), account, user); + final FullBoard fetchedBoard = adapter.getFullBoardByLocalIdDirectly(account.getId(), board.getLocalId()); + + assertEquals(board.getTitle(), fetchedBoard.getBoard().getTitle()); + } + + @Test + public void testFillSqlWithListValues() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + // TODO understand what the method does and write a proper test. + final User user = createUser(db.getUserDao(), createAccount(db.getAccountDao())); + final StringBuilder builder = new StringBuilder(); + final List<Object> args = new ArrayList<>(1); + final List<? extends AbstractRemoteEntity> entities = new ArrayList<AbstractRemoteEntity>(1) {{ + add(user); + }}; + + final Method fillSqlWithListValues = DataBaseAdapter.class.getDeclaredMethod("fillSqlWithListValues", StringBuilder.class, List.class, List.class); + fillSqlWithListValues.setAccessible(true); + fillSqlWithListValues.invoke(adapter, builder, args, entities); + assertEquals("?", builder.toString()); + assertEquals(user.getLocalId(), args.get(0)); + } + +} diff --git a/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DeckDatabaseTestUtil.java b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DeckDatabaseTestUtil.java new file mode 100644 index 000000000..6583db0ff --- /dev/null +++ b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DeckDatabaseTestUtil.java @@ -0,0 +1,114 @@ +package it.niedermann.nextcloud.deck.persistence.sync.adapters.db; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.Observer; + +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.Board; +import it.niedermann.nextcloud.deck.model.Card; +import it.niedermann.nextcloud.deck.model.Stack; +import it.niedermann.nextcloud.deck.model.User; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.AccountDao; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.BoardDao; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.CardDao; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.StackDao; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.UserDao; + +public class DeckDatabaseTestUtil { + + private static long currentLong = 1; + + private DeckDatabaseTestUtil() { + // Util class + } + + /** + * @see <a href="https://gist.github.com/JoseAlcerreca/1e9ee05dcdd6a6a6fa1cbfc125559bba">Source</a> + */ + public static <T> T getOrAwaitValue(final LiveData<T> liveData) throws InterruptedException { + final Object[] data = new Object[1]; + final CountDownLatch latch = new CountDownLatch(1); + Observer<T> observer = new Observer<T>() { + @Override + public void onChanged(@Nullable T o) { + data[0] = o; + latch.countDown(); + liveData.removeObserver(this); + } + }; + liveData.observeForever(observer); + // Don't wait indefinitely if the LiveData is not set. + if (!latch.await(2, TimeUnit.SECONDS)) { + throw new RuntimeException("LiveData value was never set."); + } + //noinspection unchecked + return (T) data[0]; + } + + public static Account createAccount(@NonNull AccountDao dao) { + final Account accountToCreate = new Account(); + accountToCreate.setName(randomString(15) + " " + randomString(15)); + accountToCreate.setUserName(randomString(10)); + accountToCreate.setUrl("https://" + randomString(10) + ".example.com"); + final long id = dao.insert(accountToCreate); + return dao.getAccountByIdDirectly(id); + } + + public static User createUser(@NonNull UserDao dao, @NonNull Account account) { + final User userToCreate = new User(); + userToCreate.setDisplayname(randomString(15) + " " + randomString(15)); + userToCreate.setUid(randomString(10)); + userToCreate.setAccountId(account.getId()); + final long id = dao.insert(userToCreate); + return dao.getUserByLocalIdDirectly(id); + } + + public static Board createBoard(@NonNull BoardDao dao, @NonNull Account account, @NonNull User owner) { + final Board boardToCreate = new Board(); + boardToCreate.setAccountId(account.getId()); + boardToCreate.setTitle(randomString(10)); + boardToCreate.setOwnerId(owner.getLocalId()); + boardToCreate.setId(currentLong++); + long id = dao.insert(boardToCreate); + return dao.getBoardByIdDirectly(id); + } + + public static Stack createStack(@NonNull StackDao dao, @NonNull Account account, @NonNull Board board) { + final Stack stackToCreate = new Stack(); + stackToCreate.setTitle(randomString(5)); + stackToCreate.setAccountId(account.getId()); + stackToCreate.setBoardId(board.getLocalId()); + stackToCreate.setId(currentLong++); + long id = dao.insert(stackToCreate); + return dao.getStackByLocalIdDirectly(id); + } + + public static Card createCard(@NonNull CardDao dao, @NonNull Account account, @NonNull Stack stack) { + final Card cardToCreate = new Card(); + cardToCreate.setAccountId(account.getId()); + cardToCreate.setTitle(randomString(15)); + cardToCreate.setDescription(randomString(50)); + cardToCreate.setStackId(stack.getLocalId()); + cardToCreate.setId(currentLong++); + + long id = dao.insert(cardToCreate); + return dao.getCardByLocalIdDirectly(account.getId(), id); + } + + private static String randomString(int length) { + final int leftLimit = 48; // numeral '0' + final int rightLimit = 122; // letter 'z' + + return new Random().ints(leftLimit, rightLimit + 1) + .filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97)) + .limit(length) + .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) + .toString(); + } +} diff --git a/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/AbstractDaoTest.java b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/AbstractDaoTest.java new file mode 100644 index 000000000..566791669 --- /dev/null +++ b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/AbstractDaoTest.java @@ -0,0 +1,39 @@ +package it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao; + +import android.os.Build; + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule; +import androidx.room.Room; +import androidx.test.core.app.ApplicationProvider; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabase; + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = {Build.VERSION_CODES.P}) +public abstract class AbstractDaoTest { + + @Rule + public InstantTaskExecutorRule instantTaskExecutorRule = new InstantTaskExecutorRule(); + + protected DeckDatabase db; + + @Before + public void createDb() { + db = Room + .inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), DeckDatabase.class) + .allowMainThreadQueries() + .build(); + } + + @After + public void closeDb() { + db.close(); + } +} diff --git a/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/AccountDaoTest.java b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/AccountDaoTest.java new file mode 100644 index 000000000..889537c71 --- /dev/null +++ b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/AccountDaoTest.java @@ -0,0 +1,95 @@ +package it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao; + +import android.os.Build; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabaseTestUtil; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = {Build.VERSION_CODES.P}) +public class AccountDaoTest extends AbstractDaoTest { + + @Test + public void testCreate() { + final Account accountToCreate = new Account(); + accountToCreate.setName("test@example.com"); + accountToCreate.setUserName("test"); + accountToCreate.setUrl("https://example.com"); + + long id = db.getAccountDao().insert(accountToCreate); + final Account account = db.getAccountDao().getAccountByIdDirectly(id); + + assertEquals("test", account.getUserName()); + assertEquals("https://example.com", account.getUrl()); + assertEquals(Integer.valueOf(0), account.getColor()); + assertEquals(Integer.valueOf(0), account.getTextColor()); + assertEquals("0.6.4", account.getServerDeckVersion()); + assertEquals("https://example.com/index.php/avatar/test/1337", account.getAvatarUrl(1337)); + assertEquals(1, db.getAccountDao().countAccountsDirectly()); + assertNull(account.getEtag()); + assertFalse(account.isMaintenanceEnabled()); + } + + @Test + public void testGetAccountById() throws InterruptedException { + final Account account = DeckDatabaseTestUtil.createAccount(db.getAccountDao()); + assertEquals(account.getName(), DeckDatabaseTestUtil.getOrAwaitValue(db.getAccountDao().getAccountById(account.getId())).getName()); + } + + @Test + public void testGetAccountByName() throws InterruptedException { + final Account account = DeckDatabaseTestUtil.createAccount(db.getAccountDao()); + assertEquals(account.getUserName(), DeckDatabaseTestUtil.getOrAwaitValue(db.getAccountDao().getAccountByName(account.getName())).getUserName()); + } + + @Test + public void testGetAllAccounts() throws InterruptedException { + final int expectedCount = 13; + for (int i = 0; i < expectedCount; i++) { + DeckDatabaseTestUtil.createAccount(db.getAccountDao()); + } + assertEquals(expectedCount, DeckDatabaseTestUtil.getOrAwaitValue(db.getAccountDao().getAllAccounts()).size()); + } + + @Test + public void testCountAccountsDirectly() { + final int expectedCount = 12; + for (int i = 0; i < expectedCount; i++) { + DeckDatabaseTestUtil.createAccount(db.getAccountDao()); + } + assertEquals(expectedCount, db.getAccountDao().countAccountsDirectly()); + } + + @Test + public void testCountAccounts() throws InterruptedException { + final int expectedCount = 13; + for (int i = 0; i < expectedCount; i++) { + DeckDatabaseTestUtil.createAccount(db.getAccountDao()); + } + assertEquals(Integer.valueOf(expectedCount), DeckDatabaseTestUtil.getOrAwaitValue(db.getAccountDao().countAccounts())); + } + + @Test + public void testGetAllAccountsDirectly() { + final int expectedCount = 12; + for (int i = 0; i < expectedCount; i++) { + DeckDatabaseTestUtil.createAccount(db.getAccountDao()); + } + assertEquals(expectedCount, db.getAccountDao().getAllAccountsDirectly().size()); + } + + @Test + public void testGetAccountByNameDirectly() { + final Account account = DeckDatabaseTestUtil.createAccount(db.getAccountDao()); + assertEquals(account.getName(), db.getAccountDao().getAccountByNameDirectly(account.getName()).getName()); + } +} diff --git a/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/BoardDaoTest.java b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/BoardDaoTest.java new file mode 100644 index 000000000..6b5408668 --- /dev/null +++ b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/BoardDaoTest.java @@ -0,0 +1,178 @@ +package it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao; + +import android.os.Build; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import java.time.Instant; +import java.util.List; + +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.Board; +import it.niedermann.nextcloud.deck.model.Card; +import it.niedermann.nextcloud.deck.model.Stack; +import it.niedermann.nextcloud.deck.model.User; +import it.niedermann.nextcloud.deck.model.enums.DBStatus; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabaseTestUtil; + +import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabaseTestUtil.createAccount; +import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabaseTestUtil.createBoard; +import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabaseTestUtil.createCard; +import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabaseTestUtil.createStack; +import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabaseTestUtil.createUser; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = {Build.VERSION_CODES.P}) +public class BoardDaoTest extends AbstractDaoTest { + + @Test + public void writeAndReadBoard() { + final Account account = createAccount(db.getAccountDao()); + final User user = DeckDatabaseTestUtil.createUser(db.getUserDao(), account); + + final Board boardToCreate = new Board(); + boardToCreate.setAccountId(account.getId()); + boardToCreate.setTitle("Test-Board"); + boardToCreate.setOwnerId(user.getLocalId()); + boardToCreate.setId(1337L); + + long id = db.getBoardDao().insert(boardToCreate); + final Board board = db.getBoardDao().getBoardByIdDirectly(id); + + assertEquals("Test-Board", board.getTitle()); + assertEquals(board, db.getBoardDao().getBoardByRemoteIdDirectly(account.getId(), board.getId())); + assertEquals(board, db.getBoardDao().getBoardForAccountByNameDirectly(account.getId(), "Test-Board")); + assertEquals(board, db.getBoardDao().getFullBoardByLocalIdDirectly(account.getId(), board.getLocalId()).getBoard()); + assertEquals(board, db.getBoardDao().getFullBoardByRemoteIdDirectly(account.getId(), board.getId()).getBoard()); + } + + @Test + public void testGetBoardsForAccount() throws InterruptedException { + final Account account = createAccount(db.getAccountDao()); + final User owner = createUser(db.getUserDao(), account); + final Board boardVisible1 = createBoard(db.getBoardDao(), account, owner); + final Board boardVisible2 = createBoard(db.getBoardDao(), account, owner); + final Board boardVisible3 = createBoard(db.getBoardDao(), account, owner); + final Board boardInVisible1 = createBoard(db.getBoardDao(), account, owner); + boardInVisible1.setDeletedAt(Instant.now()); + final Board boardInVisible2 = createBoard(db.getBoardDao(), account, owner); + boardInVisible2.setStatus(3); + final Board boardInVisible3 = createBoard(db.getBoardDao(), account, owner); + boardInVisible3.setStatusEnum(DBStatus.LOCAL_DELETED); + final Board boardVisibleArchived = createBoard(db.getBoardDao(), account, owner); + boardVisibleArchived.setArchived(true); + db.getBoardDao().update(boardInVisible1, boardInVisible2, boardInVisible3, boardVisibleArchived); + + final List<Board> boards = DeckDatabaseTestUtil.getOrAwaitValue(db.getBoardDao().getBoardsForAccount(account.getId())); + assertEquals(4, boards.size()); + assertTrue(boards.stream().anyMatch((board -> boardVisible1.getLocalId().equals(board.getLocalId())))); + assertTrue(boards.stream().anyMatch((board -> boardVisible2.getLocalId().equals(board.getLocalId())))); + assertTrue(boards.stream().anyMatch((board -> boardVisible3.getLocalId().equals(board.getLocalId())))); + assertTrue(boards.stream().anyMatch((board -> boardVisibleArchived.getLocalId().equals(board.getLocalId())))); + assertFalse(boards.stream().anyMatch((board -> boardInVisible1.getLocalId().equals(board.getLocalId())))); + assertFalse(boards.stream().anyMatch((board -> boardInVisible2.getLocalId().equals(board.getLocalId())))); + assertFalse(boards.stream().anyMatch((board -> boardInVisible3.getLocalId().equals(board.getLocalId())))); + } + + @Test + public void testGetArchivedBoardsForAccount() throws InterruptedException { + final Account account = createAccount(db.getAccountDao()); + final User owner = createUser(db.getUserDao(), account); + final Board board1 = createBoard(db.getBoardDao(), account, owner); + final Board board2 = createBoard(db.getBoardDao(), account, owner); + final Board board3 = createBoard(db.getBoardDao(), account, owner); + final Board board5 = createBoard(db.getBoardDao(), account, owner); + board5.setDeletedAt(Instant.now()); + board5.setArchived(true); + final Board board6 = createBoard(db.getBoardDao(), account, owner); + board6.setStatus(3); + board6.setArchived(true); + final Board board7 = createBoard(db.getBoardDao(), account, owner); + board7.setStatusEnum(DBStatus.LOCAL_DELETED); + board7.setArchived(true); + final Board board4 = createBoard(db.getBoardDao(), account, owner); + board4.setArchived(true); + db.getBoardDao().update(board5, board6, board7, board4); + + final List<Board> boards = DeckDatabaseTestUtil.getOrAwaitValue(db.getBoardDao().getArchivedBoardsForAccount(account.getId())); + assertEquals(1, boards.size()); + assertFalse(boards.stream().anyMatch((board -> board1.getLocalId().equals(board.getLocalId())))); + assertFalse(boards.stream().anyMatch((board -> board2.getLocalId().equals(board.getLocalId())))); + assertFalse(boards.stream().anyMatch((board -> board3.getLocalId().equals(board.getLocalId())))); + assertTrue(boards.stream().anyMatch((board -> board4.getLocalId().equals(board.getLocalId())))); + assertFalse(boards.stream().anyMatch((board -> board5.getLocalId().equals(board.getLocalId())))); + assertFalse(boards.stream().anyMatch((board -> board6.getLocalId().equals(board.getLocalId())))); + assertFalse(boards.stream().anyMatch((board -> board7.getLocalId().equals(board.getLocalId())))); + } + + @Test + public void testGetNonArchivedBoardsForAccount() throws InterruptedException { + final Account account = createAccount(db.getAccountDao()); + final User owner = createUser(db.getUserDao(), account); + final Board board1 = createBoard(db.getBoardDao(), account, owner); + final Board board2 = createBoard(db.getBoardDao(), account, owner); + final Board board3 = createBoard(db.getBoardDao(), account, owner); + final Board board5 = createBoard(db.getBoardDao(), account, owner); + board5.setDeletedAt(Instant.now()); + board5.setArchived(true); + final Board board6 = createBoard(db.getBoardDao(), account, owner); + board6.setStatus(3); + board6.setArchived(true); + final Board board7 = createBoard(db.getBoardDao(), account, owner); + board7.setStatusEnum(DBStatus.LOCAL_DELETED); + board7.setArchived(true); + final Board board4 = createBoard(db.getBoardDao(), account, owner); + board4.setArchived(true); + db.getBoardDao().update(board5, board6, board7, board4); + + final List<Board> boards = DeckDatabaseTestUtil.getOrAwaitValue(db.getBoardDao().getNonArchivedBoardsForAccount(account.getId())); + assertEquals(3, boards.size()); + assertTrue(boards.stream().anyMatch((board -> board1.getLocalId().equals(board.getLocalId())))); + assertTrue(boards.stream().anyMatch((board -> board2.getLocalId().equals(board.getLocalId())))); + assertTrue(boards.stream().anyMatch((board -> board3.getLocalId().equals(board.getLocalId())))); + assertFalse(boards.stream().anyMatch((board -> board4.getLocalId().equals(board.getLocalId())))); + assertFalse(boards.stream().anyMatch((board -> board5.getLocalId().equals(board.getLocalId())))); + assertFalse(boards.stream().anyMatch((board -> board6.getLocalId().equals(board.getLocalId())))); + assertFalse(boards.stream().anyMatch((board -> board7.getLocalId().equals(board.getLocalId())))); + } + + @Test + public void testGetLocalBoardIdByCardRemoteIdAndAccountId() throws InterruptedException { + final Account account = createAccount(db.getAccountDao()); + final User owner = createUser(db.getUserDao(), account); + final Board board = createBoard(db.getBoardDao(), account, owner); + final Stack stack = createStack(db.getStackDao(), account, board); + final Card card = createCard(db.getCardDao(), account, stack); + + assertEquals(board.getLocalId(), DeckDatabaseTestUtil.getOrAwaitValue(db.getBoardDao().getLocalBoardIdByCardRemoteIdAndAccountId(card.getId(), account.getId()))); + } + + @Test + public void testCountArchivedBoards() throws InterruptedException { + final Account account = createAccount(db.getAccountDao()); + final User owner = createUser(db.getUserDao(), account); + final Board board1 = createBoard(db.getBoardDao(), account, owner); + final Board board2 = createBoard(db.getBoardDao(), account, owner); + final Board board3 = createBoard(db.getBoardDao(), account, owner); + final Board board5 = createBoard(db.getBoardDao(), account, owner); + board5.setDeletedAt(Instant.now()); + board5.setArchived(true); + final Board board6 = createBoard(db.getBoardDao(), account, owner); + board6.setStatus(3); + board6.setArchived(true); + final Board board7 = createBoard(db.getBoardDao(), account, owner); + board7.setStatusEnum(DBStatus.LOCAL_DELETED); + board7.setArchived(true); + final Board board4 = createBoard(db.getBoardDao(), account, owner); + board4.setArchived(true); + db.getBoardDao().update(board5, board6, board7, board4); + + assertEquals(Integer.valueOf(1), DeckDatabaseTestUtil.getOrAwaitValue(db.getBoardDao().countArchivedBoards(account.getId()))); + } +} diff --git a/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/CardDaoTest.java b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/CardDaoTest.java new file mode 100644 index 000000000..a3401de42 --- /dev/null +++ b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/CardDaoTest.java @@ -0,0 +1,157 @@ +package it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao; + +import android.os.Build; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import java.util.List; + +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.Board; +import it.niedermann.nextcloud.deck.model.Card; +import it.niedermann.nextcloud.deck.model.Stack; +import it.niedermann.nextcloud.deck.model.User; +import it.niedermann.nextcloud.deck.model.enums.DBStatus; +import it.niedermann.nextcloud.deck.model.full.FullCard; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabaseTestUtil; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = {Build.VERSION_CODES.P}) +public class CardDaoTest extends AbstractDaoTest { + + private Account account; + private User user; + private Board board; + + @Before + public void setupAccount() { + account = DeckDatabaseTestUtil.createAccount(db.getAccountDao()); + user = DeckDatabaseTestUtil.createUser(db.getUserDao(), account); + board = DeckDatabaseTestUtil.createBoard(db.getBoardDao(), account, user); + } + + @Test + public void writeAndReadCard() { + final Stack stack = DeckDatabaseTestUtil.createStack(db.getStackDao(), account, board); + + final Card cardToCreate = new Card(); + cardToCreate.setAccountId(account.getId()); + cardToCreate.setTitle("Test-Card"); + cardToCreate.setDescription("Holy Moly Description"); + cardToCreate.setStackId(stack.getLocalId()); + cardToCreate.setId(1234L); + + long id = db.getCardDao().insert(cardToCreate); + final Card card = db.getCardDao().getCardByLocalIdDirectly(account.getId(), id); + + assertEquals("Test-Card", card.getTitle()); + assertEquals(card, db.getCardDao().getCardByRemoteIdDirectly(account.getId(), card.getId())); + assertEquals(card, db.getCardDao().getFullCardByLocalIdDirectly(account.getId(), card.getLocalId()).getCard()); + assertEquals(card, db.getCardDao().getFullCardByRemoteIdDirectly(account.getId(), card.getId()).getCard()); + + card.setTitle("Changed Title"); + + db.getCardDao().update(card); + + assertEquals("Changed Title", db.getCardDao().getCardByLocalIdDirectly(account.getId(), id).getTitle()); + } + + @Test + public void testGetLocallyChangedCards() { + final Stack stack1 = DeckDatabaseTestUtil.createStack(db.getStackDao(), account, board); + final Stack stack2 = DeckDatabaseTestUtil.createStack(db.getStackDao(), account, board); + final Card card1 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack1); + final Card card2 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack1); + final Card card3 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack2); + final Card card4 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack2); + final Card card5 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack2); + + card1.setStatusEnum(DBStatus.LOCAL_EDITED); + card2.setStatusEnum(DBStatus.LOCAL_MOVED); + card3.setStatusEnum(DBStatus.LOCAL_EDITED_SILENT); + card4.setStatusEnum(DBStatus.LOCAL_DELETED); + card5.setStatusEnum(DBStatus.UP_TO_DATE); + db.getCardDao().update(card1, card2, card3, card4, card5); + + final List<FullCard> locallyChangedCards = db.getCardDao().getLocallyChangedCardsDirectly(account.getId()); + assertEquals(4, locallyChangedCards.size()); + assertTrue(locallyChangedCards.stream().anyMatch((fullCard -> fullCard.getCard().equals(card1)))); + assertTrue(locallyChangedCards.stream().anyMatch((fullCard -> fullCard.getCard().equals(card2)))); + assertTrue(locallyChangedCards.stream().anyMatch((fullCard -> fullCard.getCard().equals(card3)))); + assertTrue(locallyChangedCards.stream().anyMatch((fullCard -> fullCard.getCard().equals(card4)))); + assertFalse(locallyChangedCards.stream().anyMatch((fullCard -> fullCard.getCard().equals(card5)))); + + final List<FullCard> locallyChangedCardsOfStack1 = db.getCardDao().getLocallyChangedCardsByLocalStackIdDirectly(account.getId(), stack1.getLocalId()); + assertEquals(2, locallyChangedCardsOfStack1.size()); + assertTrue(locallyChangedCardsOfStack1.stream().anyMatch((fullCard -> fullCard.getCard().equals(card1)))); + assertTrue(locallyChangedCardsOfStack1.stream().anyMatch((fullCard -> fullCard.getCard().equals(card2)))); + assertFalse(locallyChangedCardsOfStack1.stream().anyMatch((fullCard -> fullCard.getCard().equals(card3)))); + assertFalse(locallyChangedCardsOfStack1.stream().anyMatch((fullCard -> fullCard.getCard().equals(card4)))); + assertFalse(locallyChangedCardsOfStack1.stream().anyMatch((fullCard -> fullCard.getCard().equals(card5)))); + + final List<FullCard> locallyChangedCardsOfStack2 = db.getCardDao().getLocallyChangedCardsByLocalStackIdDirectly(account.getId(), stack2.getLocalId()); + assertEquals(2, locallyChangedCardsOfStack2.size()); + assertFalse(locallyChangedCardsOfStack2.stream().anyMatch((fullCard -> fullCard.getCard().equals(card1)))); + assertFalse(locallyChangedCardsOfStack2.stream().anyMatch((fullCard -> fullCard.getCard().equals(card2)))); + assertTrue(locallyChangedCardsOfStack2.stream().anyMatch((fullCard -> fullCard.getCard().equals(card3)))); + assertTrue(locallyChangedCardsOfStack2.stream().anyMatch((fullCard -> fullCard.getCard().equals(card4)))); + assertFalse(locallyChangedCardsOfStack2.stream().anyMatch((fullCard -> fullCard.getCard().equals(card5)))); + } + + @Test + public void testGetFullCardsForStackDirectly() { + final Stack stack1 = DeckDatabaseTestUtil.createStack(db.getStackDao(), account, board); + final Stack stack2 = DeckDatabaseTestUtil.createStack(db.getStackDao(), account, board); + final Card card1 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack1); + final Card card2 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack1); + final Card card3 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack2); + final Card card4 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack2); + final Card card5 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack2); + + final List<FullCard> locallyChangedCardsOfStack1 = db.getCardDao().getFullCardsForStackDirectly(account.getId(), stack1.getLocalId()); + assertEquals(2, locallyChangedCardsOfStack1.size()); + assertTrue(locallyChangedCardsOfStack1.stream().anyMatch((fullCard -> fullCard.getCard().equals(card1)))); + assertTrue(locallyChangedCardsOfStack1.stream().anyMatch((fullCard -> fullCard.getCard().equals(card2)))); + assertFalse(locallyChangedCardsOfStack1.stream().anyMatch((fullCard -> fullCard.getCard().equals(card3)))); + assertFalse(locallyChangedCardsOfStack1.stream().anyMatch((fullCard -> fullCard.getCard().equals(card4)))); + assertFalse(locallyChangedCardsOfStack1.stream().anyMatch((fullCard -> fullCard.getCard().equals(card5)))); + + final List<FullCard> locallyChangedCardsOfStack2 = db.getCardDao().getFullCardsForStackDirectly(account.getId(), stack2.getLocalId()); + assertEquals(3, locallyChangedCardsOfStack2.size()); + assertFalse(locallyChangedCardsOfStack2.stream().anyMatch((fullCard -> fullCard.getCard().equals(card1)))); + assertFalse(locallyChangedCardsOfStack2.stream().anyMatch((fullCard -> fullCard.getCard().equals(card2)))); + assertTrue(locallyChangedCardsOfStack2.stream().anyMatch((fullCard -> fullCard.getCard().equals(card3)))); + assertTrue(locallyChangedCardsOfStack2.stream().anyMatch((fullCard -> fullCard.getCard().equals(card4)))); + assertTrue(locallyChangedCardsOfStack2.stream().anyMatch((fullCard -> fullCard.getCard().equals(card5)))); + } + + @Test + public void testGetHighestStackOrder() { + final Stack stack = DeckDatabaseTestUtil.createStack(db.getStackDao(), account, board); + final Card card1 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack); + final Card card2 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack); + final Card card3 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack); + final Card card4 = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack); + card1.setOrder(20); + card2.setOrder(10); + card3.setOrder(50); + card4.setOrder(40); + db.getCardDao().update(card1, card2, card3, card4); + assertEquals(Integer.valueOf(50), db.getCardDao().getHighestOrderInStack(stack.getLocalId())); + } + + @Test + public void testGetLocalStackIdByLocalCardId() { + final Stack stack = DeckDatabaseTestUtil.createStack(db.getStackDao(), account, board); + final Card card = DeckDatabaseTestUtil.createCard(db.getCardDao(), account, stack); + assertEquals(stack.getLocalId(), card.getLocalId()); + } +} diff --git a/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/StackDaoTest.java b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/StackDaoTest.java new file mode 100644 index 000000000..6bc5d32b7 --- /dev/null +++ b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/StackDaoTest.java @@ -0,0 +1,47 @@ +package it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao; + +import android.os.Build; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import java.util.List; + +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.Board; +import it.niedermann.nextcloud.deck.model.Stack; +import it.niedermann.nextcloud.deck.model.User; +import it.niedermann.nextcloud.deck.model.full.FullStack; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabaseTestUtil; + +import static org.junit.Assert.assertEquals; + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = {Build.VERSION_CODES.P}) +public class StackDaoTest extends AbstractDaoTest { + + @Test + public void writeAndReadStack() { + final Account account = DeckDatabaseTestUtil.createAccount(db.getAccountDao()); + final User user = DeckDatabaseTestUtil.createUser(db.getUserDao(), account); + final Board board = DeckDatabaseTestUtil.createBoard(db.getBoardDao(), account, user); + + final Stack stackToCreate = new Stack(); + stackToCreate.setAccountId(account.getId()); + stackToCreate.setTitle("Test-Stack"); + stackToCreate.setBoardId(board.getLocalId()); + stackToCreate.setId(1337L); + + long id = db.getStackDao().insert(stackToCreate); + final Stack stack = db.getStackDao().getStackByLocalIdDirectly(id); + + assertEquals("Test-Stack", stack.getTitle()); + assertEquals(stack, db.getStackDao().getFullStackByLocalIdDirectly(id).getStack()); + assertEquals(stack, db.getStackDao().getFullStackByRemoteIdDirectly(account.getId(), board.getLocalId(), stack.getId()).getStack()); + final List<FullStack> stacksOfBoard = db.getStackDao().getFullStacksForBoardDirectly(account.getId(), board.getLocalId()); + assertEquals(1, stacksOfBoard.size()); + assertEquals(stack, stacksOfBoard.get(0).getStack()); + } +} diff --git a/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/UserDaoTest.java b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/UserDaoTest.java new file mode 100644 index 000000000..edb5d8181 --- /dev/null +++ b/app/src/test/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/UserDaoTest.java @@ -0,0 +1,35 @@ +package it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao; + +import android.os.Build; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.User; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DeckDatabaseTestUtil; + +import static org.junit.Assert.assertEquals; + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = {Build.VERSION_CODES.P}) +public class UserDaoTest extends AbstractDaoTest { + + @Test + public void writeAndReadUser() { + final Account account = DeckDatabaseTestUtil.createAccount(db.getAccountDao()); + + final User userToCreate = new User(); + userToCreate.setDisplayname("Test Tester"); + userToCreate.setUid("test"); + userToCreate.setAccountId(account.getId()); + + db.getUserDao().insert(userToCreate); + final User user = db.getUserDao().getUserByUidDirectly(account.getId(), "test"); + + assertEquals("Test Tester", user.getDisplayname()); + } + +} diff --git a/app/src/test/java/it/niedermann/nextcloud/deck/util/AttachmentUtilTest.java b/app/src/test/java/it/niedermann/nextcloud/deck/util/AttachmentUtilTest.java new file mode 100644 index 000000000..782c319c3 --- /dev/null +++ b/app/src/test/java/it/niedermann/nextcloud/deck/util/AttachmentUtilTest.java @@ -0,0 +1,53 @@ +package it.niedermann.nextcloud.deck.util; + +import android.os.Build; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import it.niedermann.nextcloud.deck.model.Attachment; +import it.niedermann.nextcloud.deck.model.ocs.Version; + +import static org.junit.Assert.assertEquals; + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = {Build.VERSION_CODES.P}) +public class AttachmentUtilTest { + + @Test + public void testGetThumbnailUrl() { + final Version versionThatDoesSupportFileAttachments = new Version("1.3.0", 1, 3, 0); + final Version versionThatDoesNotSupportFileAttachments = new Version("1.2.0", 1, 2, 0); + final String accountUrl = "https://example.com"; + + // TODO depends on https://github.com/nextcloud/deck/pull/2638 +// final Attachment attachment1 = new Attachment(); +// attachment1.setFileId("1337"); +// final String thumbnailUrl1 = AttachmentUtil.getThumbnailUrl(versionThatDoesSupportFileAttachments, accountUrl, -1L, attachment1, 500); +// assertEquals("https://example.com/index.php/core/preview?fileId=1337&x=500&y=500", thumbnailUrl1); +// +// final Attachment attachment2 = new Attachment(); +// attachment2.setFileId("0815"); +// final String thumbnailUrl2 = AttachmentUtil.getThumbnailUrl(versionThatDoesSupportFileAttachments, accountUrl, 0L, attachment2, 4711); +// assertEquals("https://example.com/index.php/core/preview?fileId=0815&x=4711&y=4711", thumbnailUrl2); + + // Given there is an invalid fileId... + final Attachment attachment3 = new Attachment(); + attachment3.setId(999L); + attachment3.setFileId(""); + final String thumbnailUrl3 = AttachmentUtil.getThumbnailUrl(versionThatDoesSupportFileAttachments, accountUrl, 15L, attachment3, 205); + // ... a fallback to the attachment itself should be returned + assertEquals("https://example.com/index.php/apps/deck/cards/15/attachment/999", thumbnailUrl3); + + // Given the server version does not support file attachments yet... + final Attachment attachment4 = new Attachment(); + attachment4.setId(111L); + attachment4.setFileId("222"); + final String thumbnailUrl4 = AttachmentUtil.getThumbnailUrl(versionThatDoesNotSupportFileAttachments, accountUrl, 333L, attachment4, 444); + // ... a fallback to the attachment itself should be returned + assertEquals("https://example.com/index.php/apps/deck/cards/333/attachment/111", thumbnailUrl4); + } + +} diff --git a/app/src/test/java/it/niedermann/nextcloud/deck/util/DateUtilTest.java b/app/src/test/java/it/niedermann/nextcloud/deck/util/DateUtilTest.java new file mode 100644 index 000000000..742a7a8b9 --- /dev/null +++ b/app/src/test/java/it/niedermann/nextcloud/deck/util/DateUtilTest.java @@ -0,0 +1,40 @@ +package it.niedermann.nextcloud.deck.util; + +import android.content.Context; +import android.os.Build; + +import androidx.test.core.app.ApplicationProvider; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import java.time.Duration; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.stream.Stream; + +import static org.junit.Assert.assertEquals; + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = {Build.VERSION_CODES.P}) +public class DateUtilTest { + + @Test + public void testGetRelativeDateTimeString() { + final Context appContext = ApplicationProvider.getApplicationContext(); + + Stream.of(10, 20, 30, 40, 50) + .map(secondsAgo -> ZonedDateTime.now().minus(Duration.ofSeconds(secondsAgo)).toInstant().toEpochMilli()) + .forEach(secondsAgoInMillis -> assertEquals("Below one minute diff, it should just print \"seconds\"", "seconds ago", DateUtil.getRelativeDateTimeString(appContext, secondsAgoInMillis))); + + // TODO Robolectric implementation seems to behave different from emulated device +// Stream.of(10, 20, 30, 40, 50) +// .forEach(minutesAgo -> assertEquals("Minutes ago should print the minutes", minutesAgo + " minutes ago", DateUtil.getRelativeDateTimeString(appContext, ZonedDateTime.now().minus(Duration.ofMinutes(minutesAgo)).toInstant().toEpochMilli()))); + + assertEquals("Very long time ago should print the complete date", "4/13/2018", DateUtil.getRelativeDateTimeString(appContext, ZonedDateTime.of(2018, + 4, 13, 10, 45, 0, 0, ZoneId.systemDefault()).toInstant().toEpochMilli())); + } + +} diff --git a/app/src/test/java/it/niedermann/nextcloud/deck/util/DeckColorUtilTest.java b/app/src/test/java/it/niedermann/nextcloud/deck/util/DeckColorUtilTest.java new file mode 100644 index 000000000..986ebcf52 --- /dev/null +++ b/app/src/test/java/it/niedermann/nextcloud/deck/util/DeckColorUtilTest.java @@ -0,0 +1,52 @@ +package it.niedermann.nextcloud.deck.util; + +import android.graphics.Color; +import android.os.Build; + +import androidx.core.util.Pair; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = {Build.VERSION_CODES.P}) +public class DeckColorUtilTest { + + @Test + public void testContrastRatioIsSufficient() { + final List<Pair<Integer, Integer>> sufficientContrastColorPairs = new ArrayList<>(); + sufficientContrastColorPairs.add(new Pair<>(Color.BLACK, Color.WHITE)); + sufficientContrastColorPairs.add(new Pair<>(Color.WHITE, Color.parseColor("#0082C9"))); + + for (Pair<Integer, Integer> colorPair : sufficientContrastColorPairs) { + assert colorPair.first != null; + assert colorPair.second != null; + assertTrue( + "Expect contrast between " + String.format("#%06X", (0xFFFFFF & colorPair.first)) + " and " + String.format("#%06X", (0xFFFFFF & colorPair.second)) + " to be sufficient", + DeckColorUtil.contrastRatioIsSufficient(colorPair.first, colorPair.second) + ); + } + + final List<Pair<Integer, Integer>> insufficientContrastColorPairs = new ArrayList<>(); + insufficientContrastColorPairs.add(new Pair<>(Color.WHITE, Color.WHITE)); + insufficientContrastColorPairs.add(new Pair<>(Color.BLACK, Color.BLACK)); + + for (Pair<Integer, Integer> colorPair : insufficientContrastColorPairs) { + assert colorPair.first != null; + assert colorPair.second != null; + assertFalse( + "Expect contrast between " + String.format("#%06X", (0xFFFFFF & colorPair.first)) + " and " + String.format("#%06X", (0xFFFFFF & colorPair.second)) + " to be insufficient", + DeckColorUtil.contrastRatioIsSufficient(colorPair.first, colorPair.second) + ); + } + } + +} diff --git a/app/src/test/java/it/niedermann/nextcloud/deck/util/SpannableUtilTest.java b/app/src/test/java/it/niedermann/nextcloud/deck/util/SpannableUtilTest.java new file mode 100644 index 000000000..cff0f318e --- /dev/null +++ b/app/src/test/java/it/niedermann/nextcloud/deck/util/SpannableUtilTest.java @@ -0,0 +1,55 @@ +package it.niedermann.nextcloud.deck.util; + +import android.content.Context; +import android.graphics.Typeface; +import android.os.Build; +import android.text.SpannableString; +import android.text.style.ForegroundColorSpan; +import android.text.style.StyleSpan; +import android.text.style.URLSpan; + +import androidx.test.core.app.ApplicationProvider; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import static org.junit.Assert.assertEquals; + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = {Build.VERSION_CODES.P}) +public class SpannableUtilTest { + + @Test + public void testStrong() { + final SpannableString spannableString = SpannableUtil.strong("test"); + assertEquals(1, spannableString.getSpans(0, spannableString.length(), Object.class).length); + assertEquals(1, spannableString.getSpans(0, spannableString.length(), StyleSpan.class).length); + assertEquals(4, spannableString.length()); + assertEquals(Typeface.BOLD, spannableString.getSpans(0, spannableString.length(), StyleSpan.class)[0].getStyle()); + } + + @Test + public void testDisabled() { + final Context appContext = ApplicationProvider.getApplicationContext(); + + final SpannableString spannableString = SpannableUtil.disabled("test", appContext); + assertEquals(2, spannableString.getSpans(0, spannableString.length(), Object.class).length); + assertEquals(1, spannableString.getSpans(0, spannableString.length(), ForegroundColorSpan.class).length); + assertEquals(1, spannableString.getSpans(0, spannableString.length(), StyleSpan.class).length); + assertEquals(4, spannableString.length()); + assertEquals(Typeface.ITALIC, spannableString.getSpans(0, spannableString.length(), StyleSpan.class)[0].getStyle()); + } + + + @Test + public void testUrl() { + final SpannableString spannableString = SpannableUtil.url("test", "https://example.com"); + assertEquals(1, spannableString.getSpans(0, spannableString.length(), Object.class).length); + assertEquals(1, spannableString.getSpans(0, spannableString.length(), URLSpan.class).length); + assertEquals(4, spannableString.length()); + assertEquals("https://example.com", spannableString.getSpans(0, spannableString.length(), URLSpan.class)[0].getURL()); + } + +} |