package tests;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import models.Question;
import models.User;
import models.database.IDatabase;
import models.database.HotDatabase.HotDatabase;
import models.database.importers.Importer;
import models.database.importers.SemanticError;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.SAXException;
public class XMLReadingTest extends MockedUnitTest {
private final String xml = "<?xml version=\"1.0\"?>\n"
+
"<QA>"
+
" <users>"
+
" <user id=\"277826\">"
+
" <displayname>sdaau</displayname>"
+
" <age>37</age>"
+
" <ismoderator>false</ismoderator>"
+
" <email>sdaau@gmail.com</email>"
+
" <password>secret</password>"
+
" <aboutme>My name is sdaau</aboutme>"
+
" <location/>"
+
" <website/>"
+
" </user>"
+
" </users>"
+
""
+
" <questions>"
+
" <question id=\"4119991\">"
+
" <ownerid>277826</ownerid>"
+
" <creationdate>1289168092</creationdate>"
+
" <lastactivity>1289176685</lastactivity>"
+
" <body><![CDATA[The content with < HTML > tags]]></body>"
+
" <title>Bash: call script with customized keyboard shortcuts?</title>"
+
" <lastedit>1289176685</lastedit>"
+
" <acceptedanswer>-1</acceptedanswer>"
+
" <tags>"
+
" <tag id=\"0\">linux</tag> "
+
" <tag id=\"1\">bash</tag>"
+
" <tag id=\"2\">keyboard-shortcuts</tag>"
+
" <tag id=\"3\">readline</tag>"
+
" <tag id=\"4\">customize</tag>"
+
" </tags>"
+
" </question>"
+
" </questions>"
+
""
+
" <answers>"
+
" <answer id=\"4120453\"> "
+
" <ownerid>277826</ownerid>"
+
" <questionid>4119991</questionid>"
+
" <creationdate>1289175652</creationdate>"
+
" <lastactivity>1289175652</lastactivity>"
+
" <body><![CDATA[The content with < HTML > tags]]></body>"
+
" <title>Bash: call script with customized keyboard shortcuts?</title>"
+
" <lastedit>-1</lastedit>" +
" <accepted>false</accepted>" +
" </answer>" +
" </answers>" +
"" +
"</QA>";
private IDatabase db;
private Importer importer;
@Before
public void clean() {
this.db = new HotDatabase();
this.importer = new Importer(this.db);
}
@Test
public void shouldReadTom() throws SAXException, IOException,
ParserConfigurationException {
this.importer.importXML(this.xml);
assertFalse(this.db.users().isAvailable("sdaau"));
}
@Test
public void shouldReadQuestion() throws SAXException, IOException,
ParserConfigurationException {
assertEquals(0, this.db.questions().count());
this.importer.importXML(this.xml);
assertEquals(1, this.db.questions().count());
}
@Test
public void shouldReadAnswerToo() throws SAXException, IOException,
ParserConfigurationException {
assertEquals(0, this.db.questions().countAllAnswers());
this.importer.importXML(this.xml);
assertEquals(1, this.db.questions().countAllAnswers());
}
@Test
public void shouldNotContainCDATA() throws SAXException, IOException,
ParserConfigurationException {
this.importer.importXML(this.xml);
Question question = this.db.questions().all().get(0);
assertFalse(question.content().startsWith("<![CDATA["));
assertFalse(question.answers().get(0).content().contains("<![CDATA["));
}
@Test
public void shouldCheckSemantics() throws SAXException, IOException,
ParserConfigurationException {
boolean hasThrown = false;
try {
this.importer.importXML("<invalid />");
} catch (SemanticError err) {
hasThrown = true;
}
assertTrue(hasThrown);
hasThrown = false;
try {
this.importer
.importXML("<QA><answers><answer><ownerid>666</ownerid><questionid>999</questionid></answer></answers></QA>");
} catch (SemanticError err) {
hasThrown = true;
}
assertTrue(hasThrown);
hasThrown = false;
try {
this.importer
.importXML("<QA><questions><question/></questions></QA>");
} catch (SemanticError err) {
hasThrown = true;
}
assertTrue(hasThrown);
hasThrown = false;
try {
this.importer.importXML(xml.replace("title>", "ignored>"));
} catch (SemanticError err) {
hasThrown = true;
}
assertTrue(hasThrown);
hasThrown = false;
try {
this.importer.importXML(xml.replace("<ownerid>277826</ownerid>",
"<ownerid>13</ownerid>"));
} catch (SemanticError err) {
hasThrown = true;
}
assertTrue(hasThrown);
hasThrown = false;
try {
// we are somewhat lenient here and produce new questions for
// answers not matching an existing question
this.importer.importXML(xml.replace(
"<questionid>4119991</questionid>",
"<questionid>37</questionid>"));
} catch (SemanticError err) {
hasThrown = true;
}
assertFalse(hasThrown);
}
@Test
public void shouldTolerateInvalidAge() throws SAXException, IOException,
ParserConfigurationException {
this.importer.importXML(xml);
User user = this.db.users().get("sdaau");
assertEquals(37, user.getAge());
this.db.clear(false);
this.importer.importXML(xml.replace("<age>37</age>", "<age>-1</age>"));
user = this.db.users().get("sdaau");
assertEquals(0, user.getAge());
}
@Test
public void shouldTolerateSomeMissingValues() throws SAXException,
IOException, ParserConfigurationException {
this.importer.importXML(xml.replace("<ownerid>277826</ownerid>",
"<ownerid/>").replace("<answer id=\"4120453\">", "<answer>"));
Question question = this.db.questions().all().get(0);
assertNull(question.owner());
assertNull(question.answers().get(0).owner());
}
}