/****************************************************************************************
* Copyright (c) 2014 Houssam Salem <houssam.salem.au@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
* Foundation; either version 3 of the License, or (at your option) any later *
* version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
* PARTICULAR PURPOSE. See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************/
package com.ichi2.anki.tests.libanki;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.Suppress;
import com.ichi2.anki.BackupManager;
import com.ichi2.anki.tests.Shared;
import com.ichi2.libanki.Collection;
import com.ichi2.libanki.Media;
import com.ichi2.libanki.Note;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
/**
* Unit tests for {@link Media}.
*/
public class MediaTest extends AndroidTestCase {
public void testAdd() throws IOException {
// open new empty collection
Collection d = Shared.getEmptyCol(getContext());
File dir = Shared.getTestDir(getContext());
BackupManager.removeDir(dir);
dir.mkdirs();
File path = new File(dir, "foo.jpg");
FileOutputStream os;
os = new FileOutputStream(path, false);
os.write("hello".getBytes());
os.close();
// new file, should preserve name
String r = d.getMedia().addFile(path);
assertEquals("foo.jpg", r);
// adding the same file again should not create a duplicate
assertEquals("foo.jpg", d.getMedia().addFile(path));
// but if it has a different md5, it should
os = new FileOutputStream(path, false);
os.write("world".getBytes());
os.close();
assertEquals("foo (1).jpg", d.getMedia().addFile(path));
}
public void testStrings() throws IOException {
Collection d = Shared.getEmptyCol(getContext());
Long mid = d.getModels().getModels().entrySet().iterator().next().getKey();
List<String> expected;
List<String> actual;
expected = Arrays.asList();
actual = d.getMedia().filesInStr(mid, "aoeu");
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
expected = Arrays.asList("foo.jpg");
actual = d.getMedia().filesInStr(mid, "aoeu<img src='foo.jpg'>ao");
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
expected = Arrays.asList("foo.jpg", "bar.jpg");
actual = d.getMedia().filesInStr(mid, "aoeu<img src='foo.jpg'><img src=\"bar.jpg\">ao");
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
expected = Arrays.asList("foo.jpg");
actual = d.getMedia().filesInStr(mid, "aoeu<img src=foo.jpg style=bar>ao");
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
expected = Arrays.asList("one", "two");
actual = d.getMedia().filesInStr(mid, "<img src=one><img src=two>");
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
expected = Arrays.asList("foo.jpg");
actual = d.getMedia().filesInStr(mid, "aoeu<img src=\"foo.jpg\">ao");
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
expected = Arrays.asList("foo.jpg", "fo");
actual = d.getMedia().filesInStr(mid, "aoeu<img src=\"foo.jpg\"><img class=yo src=fo>ao");
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
expected = Arrays.asList("foo.mp3");
actual = d.getMedia().filesInStr(mid, "aou[sound:foo.mp3]aou");
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
assertEquals("aoeu", d.getMedia().strip("aoeu"));
assertEquals("aoeuaoeu", d.getMedia().strip("aoeu[sound:foo.mp3]aoeu"));
assertEquals("aoeu", d.getMedia().strip("a<img src=yo>oeu"));
assertEquals("aoeu", d.getMedia().escapeImages("aoeu"));
assertEquals("<img src='http://foo.com'>", d.getMedia().escapeImages("<img src='http://foo.com'>"));
assertEquals("<img src=\"foo%20bar.jpg\">", d.getMedia().escapeImages("<img src=\"foo bar.jpg\">"));
}
public void testDeckIntegration() throws IOException {
Collection d = Shared.getEmptyCol(getContext());
// create a media dir
d.getMedia().dir();
// Put a file into it
File file = new File(Shared.getTestDir(getContext()), "fake.png");
file.createNewFile();
d.getMedia().addFile(file);
// add a note which references it
Note f = d.newNote();
f.setItem("Front", "one");
f.setItem("Back", "<img src='fake.png'>");
d.addNote(f);
// and one which references a non-existent file
f = d.newNote();
f.setItem("Front", "one");
f.setItem("Back", "<img src='fake2.png'>");
d.addNote(f);
// and add another file which isn't used
FileOutputStream os;
os = new FileOutputStream(new File(d.getMedia().dir(), "foo.jpg"), false);
os.write("test".getBytes());
os.close();
// check media
List<List<String>> ret = d.getMedia().check();
List<String> expected;
List<String> actual;
expected = Arrays.asList("fake2.png");
actual = ret.get(0);
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
expected = Arrays.asList("foo.jpg");
actual = ret.get(1);
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
}
@Suppress
private List<String> added(Collection d) {
return d.getMedia().getDb().queryColumn(String.class, "select fname from media where csum is not null", 0);
}
@Suppress
private List<String> removed(Collection d) {
return d.getMedia().getDb().queryColumn(String.class, "select fname from media where csum is null", 0);
}
public void testChanges() throws IOException {
Collection d = Shared.getEmptyCol(getContext());
assertTrue(d.getMedia()._changed() != null);
assertTrue(added(d).size() == 0);
assertTrue(removed(d).size() == 0);
// add a file
File dir = Shared.getTestDir(getContext());
File path = new File(dir, "foo.jpg");
FileOutputStream os;
os = new FileOutputStream(path, false);
os.write("hello".getBytes());
os.close();
path = new File(d.getMedia().dir(), d.getMedia().addFile(path));
// should have been logged
d.getMedia().findChanges();
assertTrue(added(d).size() > 0);
assertTrue(removed(d).size() == 0);
// if we modify it, the cache won't notice
os = new FileOutputStream(path, true);
os.write("world".getBytes());
os.close();
assertTrue(added(d).size() == 1);
assertTrue(removed(d).size() == 0);
// but if we add another file, it will
path = new File(path.getAbsolutePath()+"2");
os = new FileOutputStream(path, true);
os.write("yo".getBytes());
os.close();
d.getMedia().findChanges(true);
assertTrue(added(d).size() == 2);
assertTrue(removed(d).size() == 0);
// deletions should get noticed too
path.delete();
d.getMedia().findChanges(true);
assertTrue(added(d).size() == 1);
assertTrue(removed(d).size() == 1);
}
public void testIllegal() throws IOException {
Collection d = Shared.getEmptyCol(getContext());
String aString = "a:b|cd\\e/f\0g*h";
String good = "abcdefgh";
assertTrue(d.getMedia().stripIllegal(aString).equals(good));
for (int i = 0; i < aString.length(); i++) {
char c = aString.charAt(i);
boolean bad = d.getMedia().hasIllegal("something" + c + "morestring");
if (bad) {
assertTrue(good.indexOf(c) == -1);
} else {
assertTrue(good.indexOf(c) != -1);
}
}
}
}