Skip to content
Snippets Groups Projects
Commit 881ae407 authored by Paul-Christian Volkmer's avatar Paul-Christian Volkmer
Browse files

Merge branch 'master' into ldap_integration

parents 72990a71 0c9d870c
No related merge requests found
Showing
with 222 additions and 39 deletions
......@@ -318,6 +318,12 @@
<version>2.25.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<!--
<dependency>
<groupId>org.codehaus.groovy</groupId>
......
......@@ -181,11 +181,11 @@ public class LecturerQuestionController extends AbstractController {
@RequestMapping(value = "/unanswered", method = RequestMethod.GET)
@ResponseBody
public final List<String> getUnAnsweredSkillQuestions(
public final List<String> getUnAnsweredSkillQuestionIds(
@RequestParam final String sessionkey,
final HttpServletResponse response
) {
List<String> answers = questionService.getUnAnsweredQuestions(sessionkey);
List<String> answers = questionService.getUnAnsweredQuestionIds(sessionkey);
if (answers == null || answers.isEmpty()) {
throw new NoContentException();
}
......
......@@ -39,7 +39,6 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import de.thm.arsnova.connector.model.Course;
import de.thm.arsnova.entities.LoggedIn;
import de.thm.arsnova.entities.Question;
import de.thm.arsnova.entities.Session;
import de.thm.arsnova.entities.User;
import de.thm.arsnova.services.ISessionService;
......@@ -65,6 +64,13 @@ public class SessionController extends AbstractController {
return sessionService.joinSession(sessionkey);
}
@RequestMapping(value = "/{sessionkey}", method = RequestMethod.DELETE)
@ResponseBody
public final void deleteSession(@PathVariable final String sessionkey) {
User user = userService.getCurrentUser();
sessionService.deleteSession(sessionkey, user);
}
@RequestMapping(value = "/{sessionkey}/online", method = RequestMethod.POST)
@ResponseBody
@ResponseStatus(HttpStatus.CREATED)
......@@ -160,7 +166,7 @@ public class SessionController extends AbstractController {
return sessions;
}
@RequestMapping(value = "/{sessionkey}/lock", method = RequestMethod.POST)
@ResponseBody
public final Session lockSession(
......
......@@ -557,14 +557,14 @@ 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
// automatically
q.put("number", 0); // TODO: This number is now unused. A clean up is necessary.
q.put("releasedFor", question.getReleasedFor());
q.put("possibleAnswers", question.getPossibleAnswers());
q.put("noCorrect", question.isNoCorrect());
q.put("piRound", question.getPiRound());
q.put("showStatistic", question.isShowStatistic());
q.put("showAnswer", question.isShowAnswer());
q.put("abstention", question.isAbstention());
try {
database.saveDocument(q);
question.set_id(q.getId());
......@@ -589,6 +589,7 @@ public class CouchDBDao implements IDatabaseDao {
q.put("piRound", question.getPiRound());
q.put("showStatistic", question.isShowStatistic());
q.put("showAnswer", question.isShowAnswer());
q.put("abstention", question.isAbstention());
this.database.saveDocument(q);
question.set_rev(q.getRev());
......@@ -772,7 +773,7 @@ public class CouchDBDao implements IDatabaseDao {
}
@Override
public final void deleteQuestion(final Question question) {
public final void deleteQuestionWithAnswers(final Question question) {
try {
this.deleteAnswers(question);
this.deleteDocument(question.get_id());
......@@ -802,7 +803,7 @@ public class CouchDBDao implements IDatabaseDao {
}
@Override
public final List<String> getUnAnsweredQuestions(final Session session, final User user) {
public final List<String> getUnAnsweredQuestionIds(final Session session, final User user) {
try {
View view = new View("answer/by_user");
view.setKey(
......@@ -987,7 +988,7 @@ public class CouchDBDao implements IDatabaseDao {
@Override
public List<Answer> getFreetextAnswers(String questionId) {
try {
View view = new View("skill_question/freetext_answers");
View view = new View("skill_question/freetext_answers_full");
view.setKey(URLEncoder.encode("\"" + questionId + "\"", "UTF-8"));
ViewResults results = this.getDatabase().view(view);
if (results.getResults().isEmpty()) {
......@@ -996,8 +997,6 @@ public class CouchDBDao implements IDatabaseDao {
List<Answer> answers = new ArrayList<Answer>();
for (Document d : results.getResults()) {
Answer a = (Answer) JSONObject.toBean(d.getJSONObject().getJSONObject("value"), Answer.class);
a.setAnswerSubject(d.getJSONObject().getJSONObject("value").getString("subject"));
a.setAnswerText(d.getJSONObject().getJSONObject("value").getString("text"));
a.setQuestionId(questionId);
answers.add(a);
}
......@@ -1021,7 +1020,7 @@ public class CouchDBDao implements IDatabaseDao {
}
try {
View view = new View("answer/by_user_and_session");
View view = new View("answer/by_user_and_session_full");
view.setKey(
"[" + URLEncoder.encode("\"" + user.getUsername() + "\",\"" + s.get_id() + "\"", "UTF-8") + "]"
);
......@@ -1359,6 +1358,7 @@ public class CouchDBDao implements IDatabaseDao {
a.put("timestamp", answer.getTimestamp());
a.put("user", user.getUsername());
a.put("piRound", answer.getPiRound());
a.put("abstention", answer.isAbstention());
this.database.saveDocument(a);
answer.set_id(a.getId());
answer.set_rev(a.getRev());
......@@ -1376,6 +1376,7 @@ public class CouchDBDao implements IDatabaseDao {
a.put("answerSubject", answer.getAnswerSubject());
a.put("answerText", answer.getAnswerText());
a.put("timestamp", answer.getTimestamp());
a.put("abstention", answer.isAbstention());
this.database.saveDocument(a);
answer.set_rev(a.getRev());
return answer;
......@@ -1507,4 +1508,13 @@ public class CouchDBDao implements IDatabaseDao {
}
return null;
}
@Override
public void deleteSession(Session session) {
try {
this.deleteDocument(session.get_id());
} catch (IOException e) {
LOGGER.error("Could not delete session {}", session);
}
}
}
......@@ -68,9 +68,9 @@ public interface IDatabaseDao {
List<String> getQuestionIds(Session session, User user);
void deleteQuestion(Question question);
void deleteQuestionWithAnswers(Question question);
List<String> getUnAnsweredQuestions(Session session, User user);
List<String> getUnAnsweredQuestionIds(Session session, User user);
Answer getMyAnswer(String questionId, int piRound);
......@@ -135,4 +135,6 @@ public interface IDatabaseDao {
Session lockSession(Session session, Boolean lock);
List<String> getActiveUsers(int timeDifference);
void deleteSession(Session session);
}
......@@ -14,6 +14,7 @@ public class Answer {
private String user;
private long timestamp;
private int answerCount = 1;
private boolean abstention; // Currently available only for freetext answers!
public Answer() {
this.type = "skill_question_answer";
......@@ -106,6 +107,14 @@ public class Answer {
public final void setAnswerCount(final int answerCount) {
this.answerCount = answerCount;
}
public boolean isAbstention() {
return abstention;
}
public void setAbstention(boolean abstention) {
this.abstention = abstention;
}
@Override
public final String toString() {
......
......@@ -39,6 +39,7 @@ public class Question {
private int piRound;
private boolean showStatistic; // sic
private boolean showAnswer;
private boolean abstention;
private String _id;
private String _rev;
......@@ -178,6 +179,14 @@ public class Question {
this.showAnswer = showAnswer;
}
public boolean isAbstention() {
return abstention;
}
public void setAbstention(boolean abstention) {
this.abstention = abstention;
}
public final String get_id() {
return _id;
}
......
......@@ -19,7 +19,8 @@
package de.thm.arsnova.services;
import java.util.HashSet;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -128,8 +129,8 @@ public class FeedbackService implements IFeedbackService {
this.server.reportDeletedFeedback(e.getKey(), e.getValue());
}
}
for(String session : allAffectedSessions) {
this.server.reportUpdatedFeedbackForSession(session);
for (String session : allAffectedSessions) {
this.server.reportUpdatedFeedbackForSession(session);
}
}
......@@ -138,4 +139,82 @@ public class FeedbackService implements IFeedbackService {
public final Integer getMyFeedback(final String keyword, final User user) {
return this.databaseDao.getMyFeedback(keyword, user);
}
private static class FeedbackStorageObject {
private int value;
private Date timestamp;
public FeedbackStorageObject(int initValue) {
this.value = initValue;
this.timestamp = new Date();
}
public int getValue() {
return value;
}
public Date getTimestamp() {
return timestamp;
}
}
private static class FeedbackStorage {
private Map<String, Map<String, FeedbackStorageObject>> data;
public Feedback getFeedback(String keyword) {
int a = 0;
int b = 0;
int c = 0;
int d = 0;
if (data.get(keyword) == null) {
return new Feedback(0, 0, 0, 0);
}
for (FeedbackStorageObject fso : data.get(keyword).values()) {
switch (fso.getValue()) {
case 0:
a++;
break;
case 1:
b++;
break;
case 2:
c++;
break;
case 3:
d++;
break;
}
}
return new Feedback(a, b, c, d);
}
public boolean saveFeedback(String keyword, int value, User user) {
if (data.get(keyword) == null) {
data.put(keyword, new HashMap<String, FeedbackStorageObject>());
}
data.get(keyword).put(user.getUsername(), new FeedbackStorageObject(value));
return true;
}
public void cleanFeedbackVotes(int cleanupFeedbackDelay) {
for (String keyword : data.keySet()) {
this.cleanSessionFeedbackVotes(keyword, cleanupFeedbackDelay);
}
}
private void cleanSessionFeedbackVotes(String keyword, int cleanupFeedbackDelay) {
final long timelimitInMillis = 60000 * (long) cleanupFeedbackDelay;
final long maxAllowedTimeInMillis = System.currentTimeMillis() - timelimitInMillis;
Map<String, FeedbackStorageObject> sessionFeedbacks = data.get(keyword);
for ( FeedbackStorageObject fso : sessionFeedbacks.values() ) {
if (fso.getTimestamp().getTime() < maxAllowedTimeInMillis) {
sessionFeedbacks.remove(fso);
}
}
}
}
}
......@@ -41,7 +41,7 @@ public interface IQuestionService {
void deleteQuestion(String questionId);
List<String> getUnAnsweredQuestions(String sessionKey);
List<String> getUnAnsweredQuestionIds(String sessionKey);
Answer getMyAnswer(String questionId);
......
......@@ -49,4 +49,6 @@ public interface ISessionService {
Session setActive(String sessionkey, Boolean lock);
Session joinSession(String keyword, UUID socketId);
void deleteSession(String sessionkey, User user);
}
......@@ -146,7 +146,7 @@ public class QuestionService implements IQuestionService {
if (user == null || session == null || !session.isCreator(user)) {
throw new UnauthorizedException();
}
databaseDao.deleteQuestion(question);
databaseDao.deleteQuestionWithAnswers(question);
}
@Override
......@@ -182,7 +182,7 @@ public class QuestionService implements IQuestionService {
@Override
@Authenticated
public List<String> getUnAnsweredQuestions(String sessionKey) {
public List<String> getUnAnsweredQuestionIds(String sessionKey) {
User user = userService.getCurrentUser();
if (user == null) {
throw new UnauthorizedException();
......@@ -191,7 +191,7 @@ public class QuestionService implements IQuestionService {
if (session == null) {
throw new NotFoundException();
}
return databaseDao.getUnAnsweredQuestions(session, user);
return databaseDao.getUnAnsweredQuestionIds(session, user);
}
@Override
......
......@@ -21,7 +21,6 @@ package de.thm.arsnova.services;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
......@@ -36,6 +35,7 @@ import de.thm.arsnova.connector.client.ConnectorClient;
import de.thm.arsnova.connector.model.Course;
import de.thm.arsnova.dao.IDatabaseDao;
import de.thm.arsnova.entities.LoggedIn;
import de.thm.arsnova.entities.Question;
import de.thm.arsnova.entities.Session;
import de.thm.arsnova.entities.User;
import de.thm.arsnova.exceptions.ForbiddenException;
......@@ -56,7 +56,7 @@ public class SessionService implements ISessionService {
@Autowired
private ARSnovaSocketIOServer socketIoServer;
@Autowired(required=false)
@Autowired(required = false)
private ConnectorClient connectorClient;
public void setDatabaseDao(final IDatabaseDao newDatabaseDao) {
......@@ -117,26 +117,22 @@ public class SessionService implements ISessionService {
if (connectorClient == null) {
return mySessions;
}
List<Session> courseSessions = databaseDao.getCourseSessions(
connectorClient.getCourses(user.getUsername()).getCourse()
);
Map<String, Session> allAvailableSessions = new HashMap<String, Session>();
for (Session session : mySessions) {
allAvailableSessions.put(session.get_id(), session);
}
for (Session session : courseSessions) {
allAvailableSessions.put(session.get_id(), session);
}
List<Session> result = new ArrayList<Session>(allAvailableSessions.values());
return result;
return new ArrayList<Session>(allAvailableSessions.values());
}
@Override
public final List<Session> getMyVisitedSessions(final User user) {
return databaseDao.getMyVisitedSessions(user);
......@@ -152,7 +148,6 @@ public class SessionService implements ISessionService {
throw new ForbiddenException();
}
}
return databaseDao.saveSession(session);
}
......@@ -196,7 +191,7 @@ public class SessionService implements ISessionService {
Session session = databaseDao.getSessionFromKeyword(sessionkey);
return databaseDao.countActiveUsers(session, since);
}
public static class SessionNameComperator implements Comparator<Session>, Serializable {
private static final long serialVersionUID = 1L;
......@@ -205,8 +200,8 @@ public class SessionService implements ISessionService {
return session1.getName().compareToIgnoreCase(session2.getName());
}
}
public static class SessionShortNameComperator implements Comparator<Session>, Serializable{
public static class SessionShortNameComperator implements Comparator<Session>, Serializable {
private static final long serialVersionUID = 1L;
@Override
......@@ -229,4 +224,17 @@ public class SessionService implements ISessionService {
Session session = databaseDao.getSessionFromKeyword(sessionkey);
return databaseDao.lockSession(session, lock);
}
@Override
@Authenticated
public void deleteSession(String sessionkey, User user) {
Session session = databaseDao.getSession(sessionkey);
if (!session.isCreator(user)) {
throw new ForbiddenException();
}
for (Question q : databaseDao.getSkillQuestions(sessionkey)) {
databaseDao.deleteQuestionWithAnswers(q);
}
databaseDao.deleteSession(session);
}
}
......@@ -367,7 +367,7 @@ public class StubDatabaseDao implements IDatabaseDao {
}
@Override
public List<String> getUnAnsweredQuestions(Session session, User user) {
public List<String> getUnAnsweredQuestionIds(Session session, User user) {
// TODO Auto-generated method stub
return null;
}
......@@ -379,7 +379,7 @@ public class StubDatabaseDao implements IDatabaseDao {
}
@Override
public void deleteQuestion(Question question) {
public void deleteQuestionWithAnswers(Question question) {
// TODO Auto-generated method stub
}
......@@ -432,4 +432,9 @@ public class StubDatabaseDao implements IDatabaseDao {
// TODO Auto-generated method stub
return null;
}
@Override
public void deleteSession(Session session) {
// TODO Auto-generated method stub
}
}
......@@ -22,14 +22,23 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import static org.mockito.Mockito.*;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.util.ReflectionTestUtils;
import de.thm.arsnova.dao.IDatabaseDao;
import de.thm.arsnova.dao.StubDatabaseDao;
import de.thm.arsnova.entities.Question;
import de.thm.arsnova.entities.Session;
import de.thm.arsnova.exceptions.NotFoundException;
import de.thm.arsnova.exceptions.UnauthorizedException;
......@@ -55,7 +64,7 @@ public class SessionServiceTest {
databaseDao.cleanupTestData();
userService.setUserAuthenticated(false);
}
@Test
public void testShouldGenerateSessionKeyword() {
System.out.println(sessionService.generateKeyword());
......@@ -104,4 +113,42 @@ public class SessionServiceTest {
sessionService.saveSession(session);
assertNotNull(sessionService.joinSession("11111111"));
}
@Test
public void testShouldDeleteAllSessionData() {
IDatabaseDao tempDatabase = (IDatabaseDao) ReflectionTestUtils.getField(getTargetObject(sessionService), "databaseDao");
try {
userService.setUserAuthenticated(true);
Session session = new Session();
session.setCreator(userService.getCurrentUser().getUsername());
Question q1 = new Question();
Question q2 = new Question();
IDatabaseDao mockDatabase = mock(IDatabaseDao.class);
when(mockDatabase.getSkillQuestions(anyString())).thenReturn(Arrays.asList(q1, q2));
when(mockDatabase.getSession(anyString())).thenReturn(session);
ReflectionTestUtils.setField(getTargetObject(sessionService), "databaseDao", mockDatabase);
sessionService.deleteSession(session.getKeyword(), userService.getCurrentUser());
verify(mockDatabase).deleteQuestionWithAnswers(q1);
verify(mockDatabase).deleteQuestionWithAnswers(q2);
verify(mockDatabase).deleteSession(session);
} finally {
ReflectionTestUtils.setField(getTargetObject(sessionService), "databaseDao", tempDatabase);
}
}
@SuppressWarnings("unchecked")
public static <T> T getTargetObject(Object proxy) {
if ((AopUtils.isJdkDynamicProxy(proxy))) {
try {
return (T) getTargetObject(((Advised) proxy).getTargetSource().getTarget());
} catch (Exception e) {
throw new RuntimeException("Failed to unproxy target.", e);
}
}
return (T) proxy;
}
}
\ No newline at end of file
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