Loading app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java +9 −23 Original line number Diff line number Diff line Loading @@ -166,7 +166,7 @@ public abstract class NotesDatabase extends RoomDatabase { @NonNull @MainThread public LiveData<Note> addNoteAndSync(Account account, Note note) { Note entity = new Note(0, null, note.getModified(), note.getTitle(), note.getContent(), note.getCategory(), note.getFavorite(), note.getETag(), DBStatus.LOCAL_EDITED, account.getId(), generateNoteExcerpt(note.getContent(), note.getTitle()), 0); final Note entity = new Note(0, null, note.getModified(), note.getTitle(), note.getContent(), note.getCategory(), note.getFavorite(), note.getETag(), DBStatus.LOCAL_EDITED, account.getId(), generateNoteExcerpt(note.getContent(), note.getTitle()), 0); final MutableLiveData<Note> ret = new MutableLiveData<>(); new Thread(() -> ret.postValue(addNote(account.getId(), entity))).start(); return map(ret, newNote -> { Loading @@ -178,36 +178,22 @@ public abstract class NotesDatabase extends RoomDatabase { /** * Inserts a note directly into the Database. * Excerpt will be generated and {@link DBStatus#LOCAL_EDITED} will be applied. * No Synchronisation will be triggered! Use addNoteAndSync()! * * @param note Note to be added. Locally created Notes must be of Type {@link Note} (with {@link DBStatus#LOCAL_EDITED})! * @param note {@link Note} to be added. */ @NonNull @WorkerThread public Note addNote(long accountId, Note note) { Note entity = new Note(); if (note.getId() > 0) { entity.setId(note.getId()); entity.setStatus(note.getStatus()); entity.setAccountId(note.getAccountId()); entity.setExcerpt(note.getExcerpt()); } else { entity.setStatus(DBStatus.LOCAL_EDITED); entity.setAccountId(accountId); entity.setExcerpt(generateNoteExcerpt(note.getContent(), note.getTitle())); } entity.setRemoteId(note.getRemoteId()); entity.setTitle(note.getTitle()); entity.setModified(note.getModified()); entity.setContent(note.getContent()); entity.setFavorite(note.getFavorite()); entity.setCategory(note.getCategory()); entity.setETag(note.getETag()); return getNoteDao().getNoteById(getNoteDao().addNote(entity)); public Note addNote(long accountId, @NonNull Note note) { note.setStatus(DBStatus.LOCAL_EDITED); note.setAccountId(accountId); note.setExcerpt(generateNoteExcerpt(note.getContent(), note.getTitle())); return getNoteDao().getNoteById(getNoteDao().addNote(note)); } @MainThread public LiveData<Note> moveNoteToAnotherAccount(Account account, Note note) { public LiveData<Note> moveNoteToAnotherAccount(Account account, @NonNull Note note) { return switchMap(getNoteDao().getContent$(note.getId()), (content) -> { final Note fullNote = new Note(null, note.getModified(), note.getTitle(), content, note.getCategory(), note.getFavorite(), null); deleteNoteAndSync(account, note.getId()); Loading app/src/test/java/it/niedermann/owncloud/notes/persistence/AccountDaoTest.java 0 → 100644 +69 −0 Original line number Diff line number Diff line package it.niedermann.owncloud.notes.persistence; import android.database.sqlite.SQLiteConstraintException; import android.os.Build; import androidx.annotation.NonNull; import androidx.arch.core.executor.testing.InstantTaskExecutorRule; import androidx.room.Room; import androidx.test.core.app.ApplicationProvider; import com.nextcloud.android.sso.exceptions.NextcloudHttpRequestFailedException; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import java.util.Calendar; import java.util.List; import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.persistence.entity.CategoryWithNotesCount; import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.shared.model.Capabilities; import static it.niedermann.owncloud.notes.shared.model.DBStatus.LOCAL_DELETED; import static it.niedermann.owncloud.notes.shared.model.DBStatus.LOCAL_EDITED; import static it.niedermann.owncloud.notes.shared.model.DBStatus.VOID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @RunWith(RobolectricTestRunner.class) @Config(sdk = {Build.VERSION_CODES.P}) public class AccountDaoTest { @Rule public InstantTaskExecutorRule instantTaskExecutorRule = new InstantTaskExecutorRule(); @NonNull private NotesDatabase db; @Before public void setupDB() { db = Room .inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), NotesDatabase.class) .allowMainThreadQueries() .build(); } @After public void closeDb() { db.close(); } @Test public void insertAccount() throws NextcloudHttpRequestFailedException { final long createdId = db.getAccountDao().insert(new Account("https://äöüß.example.com", "彼得", "彼得@äöüß.example.com", new Capabilities("{ocs: {}}", null))); final Account createdAccount = db.getAccountDao().getAccountById(createdId); assertEquals("https://äöüß.example.com", createdAccount.getUrl()); assertEquals("彼得", createdAccount.getUserName()); assertEquals("彼得@äöüß.example.com", createdAccount.getAccountName()); } } No newline at end of file app/src/test/java/it/niedermann/owncloud/notes/persistence/NotesDatabaseTest.java +51 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ import com.nextcloud.android.sso.exceptions.NextcloudHttpRequestFailedException; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -26,10 +27,14 @@ import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.shared.model.Capabilities; import static it.niedermann.owncloud.notes.persistence.NotesDatabaseTestUtil.getOrAwaitValue; import static it.niedermann.owncloud.notes.shared.model.DBStatus.LOCAL_DELETED; import static it.niedermann.owncloud.notes.shared.model.DBStatus.LOCAL_EDITED; import static it.niedermann.owncloud.notes.shared.model.DBStatus.VOID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; @RunWith(RobolectricTestRunner.class) @Config(sdk = {Build.VERSION_CODES.P}) Loading Loading @@ -89,4 +94,50 @@ public class NotesDatabaseTest { assertEquals(Long.valueOf(8L), idMapOfSecondAccount.get(1008L)); } @Test public void testAddAccount() throws NextcloudHttpRequestFailedException, InterruptedException { final Account createdAccount = getOrAwaitValue(db.addAccount("https://äöüß.example.com", "彼得", "彼得@äöüß.example.com", new Capabilities("{ocs: {}}", null))); assertEquals("https://äöüß.example.com", createdAccount.getUrl()); assertEquals("彼得", createdAccount.getUserName()); assertEquals("彼得@äöüß.example.com", createdAccount.getAccountName()); } @Test public void testAddNote() { final Note createdNote = db.addNote(account.getId(), new Note(null, Calendar.getInstance(), "Fancy Title", "MyContent", "Samples", false, "123")); assertEquals(LOCAL_EDITED, createdNote.getStatus()); assertEquals("MyContent", createdNote.getExcerpt()); } @Test public void updateApiVersion() { assertThrows(IllegalArgumentException.class, () -> db.updateApiVersion(account.getId(), "")); assertThrows(IllegalArgumentException.class, () -> db.updateApiVersion(account.getId(), "asdf")); assertThrows(IllegalArgumentException.class, () -> db.updateApiVersion(account.getId(), "{}")); db.updateApiVersion(account.getId(), null); assertNull(db.getAccountDao().getAccountById(account.getId()).getApiVersion()); db.updateApiVersion(account.getId(), "[]"); assertNull(db.getAccountDao().getAccountById(account.getId()).getApiVersion()); db.updateApiVersion(account.getId(), "[1.0]"); assertEquals("[1.0]", db.getAccountDao().getAccountById(account.getId()).getApiVersion()); db.updateApiVersion(account.getId(), "[0.2, 1.0]"); assertEquals("[0.2, 1.0]", db.getAccountDao().getAccountById(account.getId()).getApiVersion()); // TODO is this really indented? db.updateApiVersion(account.getId(), "[0.2, abc]"); assertEquals("[0.2, abc]", db.getAccountDao().getAccountById(account.getId()).getApiVersion()); } @Test @Ignore("Need to find a way to stub deleteAndSync method") public void moveNoteToAnotherAccount() throws InterruptedException { final Note noteToMove = db.getNoteDao().getNoteById(1); assertEquals(3, db.getNoteDao().getLocalModifiedNotes(secondAccount.getId()).size()); final Note movedNote = getOrAwaitValue(db.moveNoteToAnotherAccount(secondAccount, noteToMove)); assertEquals(4, db.getNoteDao().getLocalModifiedNotes(secondAccount.getId()).size()); assertEquals(LOCAL_EDITED, movedNote.getStatus()); // TODO assert deleteAndSync has been called } } No newline at end of file Loading
app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java +9 −23 Original line number Diff line number Diff line Loading @@ -166,7 +166,7 @@ public abstract class NotesDatabase extends RoomDatabase { @NonNull @MainThread public LiveData<Note> addNoteAndSync(Account account, Note note) { Note entity = new Note(0, null, note.getModified(), note.getTitle(), note.getContent(), note.getCategory(), note.getFavorite(), note.getETag(), DBStatus.LOCAL_EDITED, account.getId(), generateNoteExcerpt(note.getContent(), note.getTitle()), 0); final Note entity = new Note(0, null, note.getModified(), note.getTitle(), note.getContent(), note.getCategory(), note.getFavorite(), note.getETag(), DBStatus.LOCAL_EDITED, account.getId(), generateNoteExcerpt(note.getContent(), note.getTitle()), 0); final MutableLiveData<Note> ret = new MutableLiveData<>(); new Thread(() -> ret.postValue(addNote(account.getId(), entity))).start(); return map(ret, newNote -> { Loading @@ -178,36 +178,22 @@ public abstract class NotesDatabase extends RoomDatabase { /** * Inserts a note directly into the Database. * Excerpt will be generated and {@link DBStatus#LOCAL_EDITED} will be applied. * No Synchronisation will be triggered! Use addNoteAndSync()! * * @param note Note to be added. Locally created Notes must be of Type {@link Note} (with {@link DBStatus#LOCAL_EDITED})! * @param note {@link Note} to be added. */ @NonNull @WorkerThread public Note addNote(long accountId, Note note) { Note entity = new Note(); if (note.getId() > 0) { entity.setId(note.getId()); entity.setStatus(note.getStatus()); entity.setAccountId(note.getAccountId()); entity.setExcerpt(note.getExcerpt()); } else { entity.setStatus(DBStatus.LOCAL_EDITED); entity.setAccountId(accountId); entity.setExcerpt(generateNoteExcerpt(note.getContent(), note.getTitle())); } entity.setRemoteId(note.getRemoteId()); entity.setTitle(note.getTitle()); entity.setModified(note.getModified()); entity.setContent(note.getContent()); entity.setFavorite(note.getFavorite()); entity.setCategory(note.getCategory()); entity.setETag(note.getETag()); return getNoteDao().getNoteById(getNoteDao().addNote(entity)); public Note addNote(long accountId, @NonNull Note note) { note.setStatus(DBStatus.LOCAL_EDITED); note.setAccountId(accountId); note.setExcerpt(generateNoteExcerpt(note.getContent(), note.getTitle())); return getNoteDao().getNoteById(getNoteDao().addNote(note)); } @MainThread public LiveData<Note> moveNoteToAnotherAccount(Account account, Note note) { public LiveData<Note> moveNoteToAnotherAccount(Account account, @NonNull Note note) { return switchMap(getNoteDao().getContent$(note.getId()), (content) -> { final Note fullNote = new Note(null, note.getModified(), note.getTitle(), content, note.getCategory(), note.getFavorite(), null); deleteNoteAndSync(account, note.getId()); Loading
app/src/test/java/it/niedermann/owncloud/notes/persistence/AccountDaoTest.java 0 → 100644 +69 −0 Original line number Diff line number Diff line package it.niedermann.owncloud.notes.persistence; import android.database.sqlite.SQLiteConstraintException; import android.os.Build; import androidx.annotation.NonNull; import androidx.arch.core.executor.testing.InstantTaskExecutorRule; import androidx.room.Room; import androidx.test.core.app.ApplicationProvider; import com.nextcloud.android.sso.exceptions.NextcloudHttpRequestFailedException; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import java.util.Calendar; import java.util.List; import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.persistence.entity.CategoryWithNotesCount; import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.shared.model.Capabilities; import static it.niedermann.owncloud.notes.shared.model.DBStatus.LOCAL_DELETED; import static it.niedermann.owncloud.notes.shared.model.DBStatus.LOCAL_EDITED; import static it.niedermann.owncloud.notes.shared.model.DBStatus.VOID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @RunWith(RobolectricTestRunner.class) @Config(sdk = {Build.VERSION_CODES.P}) public class AccountDaoTest { @Rule public InstantTaskExecutorRule instantTaskExecutorRule = new InstantTaskExecutorRule(); @NonNull private NotesDatabase db; @Before public void setupDB() { db = Room .inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), NotesDatabase.class) .allowMainThreadQueries() .build(); } @After public void closeDb() { db.close(); } @Test public void insertAccount() throws NextcloudHttpRequestFailedException { final long createdId = db.getAccountDao().insert(new Account("https://äöüß.example.com", "彼得", "彼得@äöüß.example.com", new Capabilities("{ocs: {}}", null))); final Account createdAccount = db.getAccountDao().getAccountById(createdId); assertEquals("https://äöüß.example.com", createdAccount.getUrl()); assertEquals("彼得", createdAccount.getUserName()); assertEquals("彼得@äöüß.example.com", createdAccount.getAccountName()); } } No newline at end of file
app/src/test/java/it/niedermann/owncloud/notes/persistence/NotesDatabaseTest.java +51 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ import com.nextcloud.android.sso.exceptions.NextcloudHttpRequestFailedException; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -26,10 +27,14 @@ import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.shared.model.Capabilities; import static it.niedermann.owncloud.notes.persistence.NotesDatabaseTestUtil.getOrAwaitValue; import static it.niedermann.owncloud.notes.shared.model.DBStatus.LOCAL_DELETED; import static it.niedermann.owncloud.notes.shared.model.DBStatus.LOCAL_EDITED; import static it.niedermann.owncloud.notes.shared.model.DBStatus.VOID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; @RunWith(RobolectricTestRunner.class) @Config(sdk = {Build.VERSION_CODES.P}) Loading Loading @@ -89,4 +94,50 @@ public class NotesDatabaseTest { assertEquals(Long.valueOf(8L), idMapOfSecondAccount.get(1008L)); } @Test public void testAddAccount() throws NextcloudHttpRequestFailedException, InterruptedException { final Account createdAccount = getOrAwaitValue(db.addAccount("https://äöüß.example.com", "彼得", "彼得@äöüß.example.com", new Capabilities("{ocs: {}}", null))); assertEquals("https://äöüß.example.com", createdAccount.getUrl()); assertEquals("彼得", createdAccount.getUserName()); assertEquals("彼得@äöüß.example.com", createdAccount.getAccountName()); } @Test public void testAddNote() { final Note createdNote = db.addNote(account.getId(), new Note(null, Calendar.getInstance(), "Fancy Title", "MyContent", "Samples", false, "123")); assertEquals(LOCAL_EDITED, createdNote.getStatus()); assertEquals("MyContent", createdNote.getExcerpt()); } @Test public void updateApiVersion() { assertThrows(IllegalArgumentException.class, () -> db.updateApiVersion(account.getId(), "")); assertThrows(IllegalArgumentException.class, () -> db.updateApiVersion(account.getId(), "asdf")); assertThrows(IllegalArgumentException.class, () -> db.updateApiVersion(account.getId(), "{}")); db.updateApiVersion(account.getId(), null); assertNull(db.getAccountDao().getAccountById(account.getId()).getApiVersion()); db.updateApiVersion(account.getId(), "[]"); assertNull(db.getAccountDao().getAccountById(account.getId()).getApiVersion()); db.updateApiVersion(account.getId(), "[1.0]"); assertEquals("[1.0]", db.getAccountDao().getAccountById(account.getId()).getApiVersion()); db.updateApiVersion(account.getId(), "[0.2, 1.0]"); assertEquals("[0.2, 1.0]", db.getAccountDao().getAccountById(account.getId()).getApiVersion()); // TODO is this really indented? db.updateApiVersion(account.getId(), "[0.2, abc]"); assertEquals("[0.2, abc]", db.getAccountDao().getAccountById(account.getId()).getApiVersion()); } @Test @Ignore("Need to find a way to stub deleteAndSync method") public void moveNoteToAnotherAccount() throws InterruptedException { final Note noteToMove = db.getNoteDao().getNoteById(1); assertEquals(3, db.getNoteDao().getLocalModifiedNotes(secondAccount.getId()).size()); final Note movedNote = getOrAwaitValue(db.moveNoteToAnotherAccount(secondAccount, noteToMove)); assertEquals(4, db.getNoteDao().getLocalModifiedNotes(secondAccount.getId()).size()); assertEquals(LOCAL_EDITED, movedNote.getStatus()); // TODO assert deleteAndSync has been called } } No newline at end of file