Java tutorial
/* * Copyright 2012-2014 MarkLogic Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.marklogic.samplestack.integration.service; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.marklogic.samplestack.domain.ClientRole; import com.marklogic.samplestack.domain.Contributor; import com.marklogic.samplestack.domain.QnADocument; import com.marklogic.samplestack.impl.DatabaseContext; import com.marklogic.samplestack.service.QnAService; import com.marklogic.samplestack.testing.IntegrationTests; import com.marklogic.samplestack.testing.Utils; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { DatabaseContext.class }) @Category(IntegrationTests.class) public class QnAServiceIT extends MarkLogicIntegrationIT { private final Logger logger = LoggerFactory.getLogger(QnAServiceIT.class); @Autowired QnAService service; @Autowired ObjectMapper mapper; @Test /** * In this test we exercise the search/ask/answer/accept flow * @throws JsonProcessingException */ public void testAskAndAnswerFlow() throws JsonProcessingException { // a fresh question QnADocument newQuestion; // state after submission QnADocument submittedQuestionAndAnswer; // same document, having searched for it QnADocument questionFromSearch; // state after answering QnADocument answeredQuestion; // state after two answers QnADocument answeredTwiceQuestion; // state after acceptance QnADocument acceptedQuestion; // check for existing answers with a naive question String question = "How do I get to know MarkLogic quickly?"; // first step -- send question to the server, get back results // TODO expand this first step. service.findOne(ClientRole.SAMPLESTACK_CONTRIBUTOR, question, 1); newQuestion = new QnADocument(mapper, question, "I mean, there are several reasons. \n* bullet\n*bullet And so it goes.", "xquery", "javascript", "programming"); // ask a question. submittedQuestionAndAnswer = service.ask(Utils.joeUser.getUserName(), newQuestion); assertEquals(newQuestion.getJson().get("title"), submittedQuestionAndAnswer.getJson().get("title")); assertEquals(newQuestion.getJson().get("tags"), submittedQuestionAndAnswer.getJson().get("tags")); // search for my original question. questionFromSearch = service.findOne(ClientRole.SAMPLESTACK_CONTRIBUTOR, question, 1); logger.info(mapper.writeValueAsString(questionFromSearch)); assertEquals("Title was set properly on ingested question", newQuestion.getJson().get("title"), questionFromSearch.getJson().get("title")); JsonNode ownerNode = questionFromSearch.getJson().get("owner"); assertEquals("The question has an owner/userName", Utils.joeUser.getUserName(), ownerNode.get("userName").asText()); // TODO somehow assert the question I just asked is in this list? answeredQuestion = service.answer(Utils.maryUser.getUserName(), submittedQuestionAndAnswer.getId(), "I think your question is very good."); logger.debug(mapper.writeValueAsString(answeredQuestion)); JsonNode answer = answeredQuestion.getJson().get("answers").get(0); assertEquals("answered question has an answer", Utils.maryUser.getUserName(), answer.get("owner").get("userName").asText()); // add another answer answeredTwiceQuestion = service.answer(Utils.maryUser.getUserName(), answeredQuestion.getId(), "I think the question has merit, but is inherently unanswerable."); assertEquals("twice answered question has two answers", 2, answeredTwiceQuestion.getJson().get("answers").size()); String firstAnswerId = answer.get("id").asText(); String secondAnswerId = answeredTwiceQuestion.getJson().get("answers").get(1).get("id").asText(); acceptedQuestion = service.accept(firstAnswerId); assertEquals("Accepted answer id is correct", firstAnswerId, acceptedQuestion.getJson().get("acceptedAnswerId").asText()); assertTrue("The right answer has been accepted", acceptedQuestion.getJson().get("answers").get(0).get("accepted").asBoolean()); // accept another answer acceptedQuestion = service.accept(secondAnswerId); assertEquals("Accepted answer id is correct", secondAnswerId, acceptedQuestion.getJson().get("acceptedAnswerId").asText()); assertTrue("The right answer has been accepted", acceptedQuestion.getJson().get("answers").get(1).get("accepted").asBoolean()); } @Test public void testVoting() { QnADocument newQuestion = new QnADocument(mapper, "How does voting work?", "I want lots of up votes on my document", "voting", "votes"); QnADocument submitted = service.ask(Utils.joeUser.getUserName(), newQuestion); int docScore = submitted.getJson().get("docScore").asInt(); QnADocument answered = service.answer(Utils.maryUser.getUserName(), submitted.getId(), "I think your question is very good. I want lots of votes too."); String answerId = answered.getJson().get("answers").get(0).get("id").asText(); // vote up int joesReputation = Utils.joeUser.getReputation(); int marysReputation = Utils.joeUser.getReputation(); // joe votes his own question up, reputation +1 for joe. service.voteUp(Utils.joeUser.getUserName(), submitted.getId()); QnADocument votedOn = service.get(ClientRole.SAMPLESTACK_CONTRIBUTOR, submitted.getId()); int newScore = votedOn.getJson().get("docScore").asInt(); assertEquals("Vote score should be one higher than before", docScore + 1, newScore); try { service.voteUp(Utils.joeUser.getUserName(), submitted.getId()); fail("Same person cannot vote twice on same post"); } catch (Exception e) { // pass } try { service.voteDown(Utils.joeUser.getUserName(), submitted.getId()); fail("Same person cannot vote twice on same post"); } catch (Exception e) { // pass } // mary votes her own answer down, her rep should be -1 service.voteDown(Utils.maryUser.getUserName(), answerId); QnADocument votedTwiceOn = service.get(ClientRole.SAMPLESTACK_CONTRIBUTOR, submitted.getId()); int newerScore = votedTwiceOn.getJson().get("docScore").asInt(); assertEquals("Vote score should be one higher than before", newScore - 1, newerScore); Contributor joesState = contributorService.get(Utils.joeUser.getId()); assertEquals("joe has voted once", 1, joesState.getVotes().size()); assertTrue("joe voted on this", joesState.hasVotedOn(submitted.getId())); assertEquals("joe reputation has gained", joesReputation + 1, joesState.getReputation()); Contributor marysState = contributorService.get(Utils.maryUser.getId()); assertEquals("mary has voted once", 1, marysState.getVotes().size()); assertTrue("mary voted on this", marysState.hasVotedOn(answerId)); assertEquals("marys reputation has suffered", marysReputation - 1, marysState.getReputation()); } @Test public void testComments() { QnADocument newQuestion = new QnADocument(mapper, "How do comments work?", "I could go on and on but would rather solicit commentary", "commentary"); QnADocument submitted = service.ask(Utils.joeUser.getUserName(), newQuestion); QnADocument answered = service.answer(Utils.maryUser.getUserName(), submitted.getId(), "I think your question is very good."); String answerId = answered.getJson().get("answers").get(0).get("id").asText(); String c1 = "Here's ONE comment on your question"; String c2 = "Here's TWO comment on your question"; String c3 = "Here's ONE comment on your answer"; service.comment(Utils.joeUser.getUserName(), submitted.getId(), c1); service.comment(Utils.joeUser.getUserName(), submitted.getId(), c2); QnADocument finalDocument = service.comment(Utils.joeUser.getUserName(), answerId, c3); assertEquals("Comment 1", c1, finalDocument.getJson().get("comments").get(0).get("text").asText()); assertEquals("Comment 2", c2, finalDocument.getJson().get("comments").get(1).get("text").asText()); assertEquals("Comment 3", c3, finalDocument.getJson().get("answers").get(0).get("comments").get(0).get("text").asText()); } @Test public void testCRUD() throws JsonProcessingException { QnADocument question = new QnADocument(mapper, "What is my first question?", "Its body is suspiciously short, like a unit test's.", "tag1", "tag2"); Contributor joeUser = Utils.joeUser; QnADocument question2 = service.ask(joeUser.getUserName(), question); logger.debug(mapper.writeValueAsString(question2.getJson())); assertEquals("Persisted question", "What is my first question?", question2.getJson().get("title").asText()); assertNotNull("Persisted question has ts", question2.getJson().get("creationDate")); } @Test public void testDefaultSearchService() throws JsonProcessingException { testComments(); // get a document in there. JsonNode structuredQuery = getTestJson("queries/blank.json"); // test view-all ObjectNode jsonResults = service.rawSearch(ClientRole.SAMPLESTACK_CONTRIBUTOR, structuredQuery, 1); logger.info(mapper.writeValueAsString(jsonResults)); assertTrue("Blank query got back results", jsonResults.get("results").size() > 0); assertEquals("Blank query got back facets", 2, jsonResults.get("facets").size()); assertNotNull("Blank query got back date facet", jsonResults.get("facets").get("date")); assertNotNull("Blank query got back tag facet", jsonResults.get("facets").get("tag")); } }