Skip to content
Snippets Groups Projects
Commit 6664f185 authored by Christoph Thelen's avatar Christoph Thelen
Browse files

Merge branch 'master' into selenium

parents 1f140667 898bb72b
Branches
Tags
No related merge requests found
Showing
with 336 additions and 32 deletions
......@@ -258,7 +258,7 @@
com.github.leleuj.springframework.security
</groupId>
<artifactId>spring-security-oauth-client</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
......
......@@ -219,5 +219,16 @@ public class QuestionController extends AbstractController {
) {
return questionService.getAnswerCount(sessionKey, questionId);
}
@RequestMapping(value = "/session/{sessionKey}/question/{questionId}/freetextanswers", method = RequestMethod.GET)
@ResponseBody
public final List<Answer> getFreetextAnswers(
@PathVariable final String sessionKey,
@PathVariable final String questionId,
final HttpServletResponse response
) {
return questionService.getFreetextAnswers(sessionKey, questionId);
}
}
package de.thm.arsnova.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import de.thm.arsnova.services.IStatisticsService;
@Controller
public class StatisticsController {
@Autowired
private IStatisticsService statisticsService;
@RequestMapping(method = RequestMethod.GET, value = "/statistics/activeusercount")
@ResponseBody
public final int countActiveUsers() {
return statisticsService.countActiveUsers();
}
}
......@@ -142,7 +142,10 @@ public class CouchDBDao implements IDatabaseDao {
} catch (IOException e) {
LOGGER.error("Could not delete Feedback document " + d.getId());
} catch (JSONException e) {
LOGGER.error("Could not delete Feedback document {}, error is: {} ", new Object[] {d.getId(), e});
LOGGER.error(
"Could not delete Feedback document {}, error is: {} ",
new Object[] {d.getId(), e}
);
}
}
if (!results.isEmpty()) {
......@@ -182,7 +185,10 @@ public class CouchDBDao implements IDatabaseDao {
List<Session> result = new ArrayList<Session>();
for (Document d : sessions.getResults()) {
Session session = (Session) JSONObject.toBean(d.getJSONObject().getJSONObject("value"), Session.class);
Session session = (Session) JSONObject.toBean(
d.getJSONObject().getJSONObject("value"),
Session.class
);
session.set_id(d.getId());
result.add(session);
}
......@@ -212,12 +218,18 @@ public class CouchDBDao implements IDatabaseDao {
MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
Morpher dynaMorpher = new BeanMorpher(PossibleAnswer.class, morpherRegistry);
morpherRegistry.registerMorpher(dynaMorpher);
for (Document d : questions.getResults()) {
Question q = (Question) JSONObject.toBean(d.getJSONObject().getJSONObject("value"), Question.class);
Collection<PossibleAnswer> answers = JSONArray.toCollection(d.getJSONObject().getJSONObject("value")
.getJSONArray("possibleAnswers"), PossibleAnswer.class);
q.setPossibleAnswers(new ArrayList<PossibleAnswer>(answers));
result.add(q);
for (Document document : questions.getResults()) {
Question question = (Question) JSONObject.toBean(
document.getJSONObject().getJSONObject("value"),
Question.class
);
Collection<PossibleAnswer> answers = JSONArray.toCollection(
document.getJSONObject().getJSONObject("value")
.getJSONArray("possibleAnswers"),
PossibleAnswer.class
);
question.setPossibleAnswers(new ArrayList<PossibleAnswer>(answers));
result.add(question);
}
return result;
......@@ -254,8 +266,10 @@ public class CouchDBDao implements IDatabaseDao {
if (results.getJSONArray("rows").optJSONObject(0) == null) {
return null;
}
return (Session) JSONObject.toBean(results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"),
Session.class);
return (Session) JSONObject.toBean(
results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"),
Session.class
);
} catch (UnsupportedEncodingException e) {
return null;
}
......@@ -298,7 +312,7 @@ public class CouchDBDao implements IDatabaseDao {
}
private Feedback createFeedbackObject(final ViewResults results) {
int values[] = {0, 0, 0, 0};
int[] values = {0, 0, 0, 0};
JSONArray rows = results.getJSONArray("rows");
try {
......@@ -336,7 +350,11 @@ public class CouchDBDao implements IDatabaseDao {
}
@Override
public final boolean saveFeedback(final String keyword, final int value, final de.thm.arsnova.entities.User user) {
public final boolean saveFeedback(
final String keyword,
final int value,
final de.thm.arsnova.entities.User user
) {
String sessionId = this.getSessionId(keyword);
if (sessionId == null) {
return false;
......@@ -382,7 +400,12 @@ public class CouchDBDao implements IDatabaseDao {
private List<Document> findPreviousFeedback(final String sessionId, final de.thm.arsnova.entities.User user) {
View view = new View("understanding/by_user");
try {
view.setKey(URLEncoder.encode("[\"" + sessionId + "\", \"" + user.getUsername() + "\"]", "UTF-8"));
view.setKey(
URLEncoder.encode(
"[\"" + sessionId + "\",\"" + user.getUsername() + "\"]",
"UTF-8"
)
);
} catch (UnsupportedEncodingException e) {
return Collections.<Document> emptyList();
}
......@@ -468,11 +491,17 @@ public class CouchDBDao implements IDatabaseDao {
private Database getDatabase() {
if (database == null) {
try {
com.fourspaces.couchdb.Session session = new com.fourspaces.couchdb.Session(databaseHost, databasePort);
com.fourspaces.couchdb.Session session = new com.fourspaces.couchdb.Session(
databaseHost,
databasePort
);
database = session.getDatabase(databaseName);
} catch (Exception e) {
LOGGER.error("Cannot connect to CouchDB database '" + databaseName + "' on host '" + databaseHost
+ "' using port " + databasePort);
LOGGER.error(
"Cannot connect to CouchDB database '" + databaseName
+ "' on host '" + databaseHost
+ "' using port " + databasePort
);
}
}
......@@ -488,7 +517,7 @@ public class CouchDBDao implements IDatabaseDao {
q.put("subject", question.getSubject());
q.put("text", question.getText());
q.put("active", question.isActive());
q.put("number", 0); // TODO: This number has to get incremented
q.put("number", 0); // TODO This number has to get incremented
// automatically
q.put("releasedFor", question.getReleasedFor());
q.put("possibleAnswers", question.getPossibleAnswers());
......@@ -517,10 +546,15 @@ public class CouchDBDao implements IDatabaseDao {
}
Question q = (Question) JSONObject.toBean(
results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"), Question.class);
results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"),
Question.class
);
JSONArray possibleAnswers = results.getJSONArray("rows").optJSONObject(0).optJSONObject("value")
.getJSONArray("possibleAnswers");
Collection<PossibleAnswer> answers = JSONArray.toCollection(possibleAnswers, PossibleAnswer.class);
Collection<PossibleAnswer> answers = JSONArray.toCollection(
possibleAnswers,
PossibleAnswer.class
);
q.setPossibleAnswers(new ArrayList<PossibleAnswer>(answers));
if (s.get_id().equals(q.getSessionId())) {
......@@ -601,7 +635,12 @@ public class CouchDBDao implements IDatabaseDao {
}
View view = new View("understanding/by_user");
view.setKey(URLEncoder.encode("[\"" + sessionId + "\", \"" + user.getUsername() + "\"]", "UTF-8"));
view.setKey(
URLEncoder.encode(
"[\"" + sessionId + "\", \"" + user.getUsername() + "\"]",
"UTF-8"
)
);
ViewResults results = this.getDatabase().view(view);
JSONArray rows = results.getJSONArray("rows");
......@@ -676,8 +715,10 @@ public class CouchDBDao implements IDatabaseDao {
} catch (IOException e) {
LOGGER.error(
"IOException: Could not delete question and its answers with id {}. Connection to CouchDB available?",
questionId);
"IOException: Could not delete question and its answers with id {}."
+ " Connection to CouchDB available?",
questionId
);
}
}
......@@ -695,7 +736,13 @@ public class CouchDBDao implements IDatabaseDao {
try {
View view = new View("answer/by_user");
view.setKey("[" + URLEncoder.encode("\"" + user.getUsername() + "\",\"" + s.get_id() + "\"", "UTF-8") + "]");
view.setKey(
"[" + URLEncoder.encode(
"\"" + user.getUsername() + "\",\"" + s.get_id() + "\"",
"UTF-8"
)
+ "]"
);
ViewResults anseweredQuestions = this.getDatabase().view(view);
List<String> answered = new ArrayList<String>();
......@@ -732,13 +779,21 @@ public class CouchDBDao implements IDatabaseDao {
try {
View view = new View("answer/by_question_and_user");
view.setKey("[" + URLEncoder.encode("\"" + questionId + "\",\"" + user.getUsername() + "\"", "UTF-8") + "]");
view.setKey(
"[" + URLEncoder.encode(
"\"" + questionId + "\",\"" + user.getUsername() + "\"",
"UTF-8"
)
+ "]"
);
ViewResults results = this.getDatabase().view(view);
if (results.getResults().isEmpty()) {
throw new NotFoundException();
}
return (Answer) JSONObject.toBean(results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"),
Answer.class);
return (Answer) JSONObject.toBean(
results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"),
Answer.class
);
} catch (UnsupportedEncodingException e) {
LOGGER.error(
"Error while retrieving answer for user {} and question {}, {}",
......@@ -800,4 +855,55 @@ public class CouchDBDao implements IDatabaseDao {
}
return 0;
}
@Override
public final int getActiveUsers(final long since) {
try {
View view = new View("statistic/count_active_users");
view.setStartKey(String.valueOf(since));
ViewResults results = this.getDatabase().view(view);
LOGGER.info("getActiveUsers() {}", results);
if (
results == null
|| results.getResults().isEmpty()
|| results.getJSONArray("rows").size() == 0
) {
return 0;
}
return results.getJSONArray("rows").optJSONObject(0).getInt("value");
} catch (Exception e) {
LOGGER.error("Error while retrieving active users count", e);
}
return 0;
}
@Override
public List<Answer> getFreetextAnswers(String sessionKey, String questionId) {
Session s = this.getSessionFromKeyword(sessionKey);
if (s == null) {
throw new NotFoundException();
}
try {
View view = new View("skill_question/freetext_answers");
view.setKey(URLEncoder.encode("\"" + questionId + "\"", "UTF-8"));
ViewResults results = this.getDatabase().view(view);
if (results.getResults().isEmpty()) {
throw new NotFoundException();
}
List<Answer> answers = new ArrayList<Answer>();
for (Document d : results.getResults()) {
Answer a = (Answer) JSONObject.toBean(d.getJSONObject().getJSONObject("value"), Answer.class);
a.setSessionId(s.get_id());
a.setQuestionId(questionId);
answers.add(a);
}
return answers;
} catch (UnsupportedEncodingException e) {
LOGGER.error("Error while retrieving freetext answers", e);
}
return null;
}
}
......@@ -23,8 +23,8 @@ import java.util.List;
import de.thm.arsnova.entities.Answer;
import de.thm.arsnova.entities.Feedback;
import de.thm.arsnova.entities.Question;
import de.thm.arsnova.entities.LoggedIn;
import de.thm.arsnova.entities.Question;
import de.thm.arsnova.entities.Session;
import de.thm.arsnova.entities.User;
......@@ -70,4 +70,8 @@ public interface IDatabaseDao {
List<Answer> getAnswers(String sessionKey, String questionId);
int getAnswerCount(String sessionKey, String questionId);
List<Answer> getFreetextAnswers(String sessionKey, String questionId);
int getActiveUsers(long since);
}
......@@ -11,6 +11,7 @@ public class Answer {
private String answerText;
private String answerSubject;
private String user;
private long timestamp;
private int answerCount;
public Answer() {
......@@ -65,6 +66,15 @@ public class Answer {
this.answerText = answerText;
}
public final String getText() {
return answerText;
}
public final void setText(final String answerText) {
this.answerText = answerText;
}
public final String getAnswerSubject() {
return answerSubject;
}
......@@ -72,6 +82,14 @@ public class Answer {
public final void setAnswerSubject(final String answerSubject) {
this.answerSubject = answerSubject;
}
public final String getSubject() {
return answerSubject;
}
public final void setSubject(final String answerSubject) {
this.answerSubject = answerSubject;
}
public final String getUser() {
return user;
......@@ -81,6 +99,14 @@ public class Answer {
this.user = user;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public final int getAnswerCount() {
return answerCount;
}
......
package de.thm.arsnova.exceptions;
\ No newline at end of file
package de.thm.arsnova.exceptions;
......@@ -44,4 +44,6 @@ public interface IQuestionService {
List<Answer> getAnswers(String sessionKey, String questionId);
int getAnswerCount(String sessionKey, String questionId);
List<Answer> getFreetextAnswers(String sessionKey, String questionId);
}
package de.thm.arsnova.services;
public interface IStatisticsService {
int countActiveUsers();
}
......@@ -112,4 +112,10 @@ public class QuestionService implements IQuestionService {
public int getAnswerCount(String sessionKey, String questionId) {
return databaseDao.getAnswerCount(sessionKey, questionId);
}
@Override
@Authenticated
public List<Answer> getFreetextAnswers(String sessionKey, String questionId) {
return databaseDao.getFreetextAnswers(sessionKey, questionId);
}
}
package de.thm.arsnova.services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import de.thm.arsnova.dao.IDatabaseDao;
@Service
public class StatisticsService implements IStatisticsService {
private static final int SINCEDURATION = 3 * 60 * 1000;
@Autowired
private IDatabaseDao databaseDao;
@Override
public final int countActiveUsers() {
long since = System.currentTimeMillis() - SINCEDURATION;
return databaseDao.getActiveUsers(since);
}
}
package de.thm.arsnova.services;
\ No newline at end of file
package de.thm.arsnova.services;
package de.thm.arsnova.controller;
import static org.junit.Assert.assertEquals;
import javax.inject.Inject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
import de.thm.arsnova.services.StubUserService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"file:src/main/webapp/WEB-INF/arsnova-servlet.xml",
"file:src/main/webapp/WEB-INF/spring/spring-main.xml",
"file:src/test/resources/test-config.xml"
})
public class StatisticsControllerTest {
@Inject
private ApplicationContext applicationContext;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private HandlerAdapter handlerAdapter;
@Autowired
private StatisticsController statisticsController;
@Autowired
private StubUserService userService;
@Before
public final void setUp() {
this.request = new MockHttpServletRequest();
this.response = new MockHttpServletResponse();
handlerAdapter = applicationContext.getBean(AnnotationMethodHandlerAdapter.class);
}
@Test
public final void testShouldNotGetUnknownSession() throws Exception {
userService.setUserAuthenticated(true);
request.setMethod("GET");
request.setRequestURI("/statistics/activeusercount");
handlerAdapter.handle(request, response, statisticsController);
assertEquals("0", response.getContentAsString());
}
}
package de.thm.arsnova.dao;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
......@@ -218,4 +219,16 @@ public class StubDatabaseDao implements IDatabaseDao {
return 0;
}
@Override
public List<Answer> getFreetextAnswers(String sessionKey, String questionId) {
// TODO Auto-generated method stub
return null;
}
@Override
public int getActiveUsers(long since) {
// TODO Auto-generated method stub
return 0;
}
}
......@@ -40,10 +40,10 @@ import de.thm.arsnova.exceptions.UnauthorizedException;
public class SessionServiceTest {
@Autowired
ISessionService sessionService;
private ISessionService sessionService;
@Autowired
StubUserService userService;
private StubUserService userService;
@Test
public void testShouldGenerateSessionKeyword() {
......
package de.thm.arsnova.services;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"file:src/main/webapp/WEB-INF/arsnova-servlet.xml",
"file:src/main/webapp/WEB-INF/spring/spring-main.xml",
"file:src/test/resources/test-config.xml"
})
public class StatisticsServiceTest {
@Autowired
private IStatisticsService statisticsService;
@Test
public final void testShouldReturnCurrentActiveUsers() {
int actual = statisticsService.countActiveUsers();
//assertEquals(0, actual);
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment