]> source.dussan.org Git - sonarqube.git/commitdiff
Add some unit tests
authorJulien Lancelot <julien.lancelot@gmail.com>
Wed, 21 Aug 2013 15:15:40 +0000 (17:15 +0200)
committerJulien Lancelot <julien.lancelot@gmail.com>
Wed, 21 Aug 2013 15:15:40 +0000 (17:15 +0200)
sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotTest.java
sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
sonar-plugin-api/src/test/java/org/sonar/api/issue/IssueQueryTest.java
sonar-plugin-api/src/test/java/org/sonar/api/issue/internal/DefaultIssueTest.java
sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceTest.java

index 97cdacea26cc25d54bf6e75431f27780abad5475..2440064362c636b193d54ce8d6807efca2ced364 100644 (file)
  */
 package org.sonar.batch.components;
 
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.startsWith;
-import static org.junit.Assert.assertThat;
-
 import org.junit.Test;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.resources.Qualifiers;
 
 import java.util.Date;
 
+import static org.fest.assertions.Assertions.assertThat;
+
 public class PastSnapshotTest {
 
+  @Test
+  public void test_some_setters_and_getters() {
+    Snapshot snapshot = new Snapshot().setQualifier(Qualifiers.FILE).setCreatedAt(new Date());
+    snapshot.setId(10);
+    PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_VERSION, new Date(),
+      snapshot)
+      .setModeParameter("2.3")
+      .setIndex(1);
+
+    assertThat(pastSnapshot.getModeParameter()).isEqualTo("2.3");
+    assertThat(pastSnapshot.getIndex()).isEqualTo(1);
+    assertThat(pastSnapshot.getQualifier()).isEqualTo(Qualifiers.FILE);
+    assertThat(pastSnapshot.getDate()).isNotNull();
+    assertThat(pastSnapshot.getProjectSnapshotId()).isEqualTo(10);
+  }
+
+  @Test
+  public void test_some_setters_and_getters2() {
+    PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_VERSION, new Date(), new Snapshot());
+
+    assertThat(pastSnapshot.getQualifier()).isNull();
+    assertThat(pastSnapshot.getDate()).isNull();
+    assertThat(pastSnapshot.getProjectSnapshotId()).isNull();
+  }
+
   @Test
   public void testToStringForVersion() {
     PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_VERSION, new Date()).setModeParameter("2.3");
-    assertThat(pastSnapshot.toString(), startsWith("Compare to version 2.3"));
+    assertThat(pastSnapshot.toString()).startsWith("Compare to version 2.3");
   }
 
   @Test
   public void testToStringForVersionWithoutDate() {
     PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_VERSION).setModeParameter("2.3");
-    assertThat(pastSnapshot.toString(), equalTo("Compare to version 2.3"));
+    assertThat(pastSnapshot.toString()).isEqualTo("Compare to version 2.3");
   }
 
   @Test
   public void testToStringForNumberOfDays() {
     PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_DAYS, new Date()).setModeParameter("30");
-    assertThat(pastSnapshot.toString(), startsWith("Compare over 30 days ("));
+    assertThat(pastSnapshot.toString()).startsWith("Compare over 30 days (");
   }
 
   @Test
   public void testToStringForNumberOfDaysWithSnapshot() {
     PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_DAYS, new Date(), new Snapshot().setCreatedAt(new Date())).setModeParameter("30");
-    assertThat(pastSnapshot.toString(), startsWith("Compare over 30 days ("));
+    assertThat(pastSnapshot.toString()).startsWith("Compare over 30 days (");
   }
 
   @Test
   public void testToStringForDate() {
     PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_DATE, new Date());
-    assertThat(pastSnapshot.toString(), startsWith("Compare to date "));
+    assertThat(pastSnapshot.toString()).startsWith("Compare to date ");
   }
 
   @Test
   public void testToStringForDateWithSnapshot() {
     PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_DATE, new Date(), new Snapshot().setCreatedAt(new Date()));
-    assertThat(pastSnapshot.toString(), startsWith("Compare to date "));
+    assertThat(pastSnapshot.toString()).startsWith("Compare to date ");
   }
 
   @Test
   public void testToStringForPreviousAnalysis() {
     PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, new Date(), new Snapshot().setCreatedAt(new Date()));
-    assertThat(pastSnapshot.toString(), startsWith("Compare to previous analysis "));
+    assertThat(pastSnapshot.toString()).startsWith("Compare to previous analysis ");
   }
 
   @Test
   public void testToStringForPreviousAnalysisWithoutDate() {
     PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS);
-    assertThat(pastSnapshot.toString(), equalTo("Compare to previous analysis"));
+    assertThat(pastSnapshot.toString()).isEqualTo("Compare to previous analysis");
   }
 }
index cef290c6f00085699b37c0f4d5975cb6764e3dfc..be5cc3c4540a54f15a991c310c93d4d3676a86ce 100644 (file)
@@ -42,28 +42,29 @@ import org.sonar.batch.issue.DeprecatedViolations;
 import org.sonar.batch.issue.ScanIssues;
 import org.sonar.core.component.ScanGraph;
 
-import static org.hamcrest.Matchers.nullValue;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
+import static com.google.common.collect.Lists.newArrayList;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 public class DefaultIndexTest {
 
   private DefaultIndex index = null;
+  private DeprecatedViolations deprecatedViolations;
   private DefaultResourceCreationLock lock;
   private Rule rule;
   private RuleFinder ruleFinder;
 
   @Before
   public void createIndex() {
+    deprecatedViolations = mock(DeprecatedViolations.class);
     lock = new DefaultResourceCreationLock(new Settings());
     MetricFinder metricFinder = mock(MetricFinder.class);
     when(metricFinder.findByKey("ncloc")).thenReturn(CoreMetrics.NCLOC);
     ruleFinder = mock(RuleFinder.class);
 
-    index = new DefaultIndex(mock(PersistenceManager.class), lock, mock(ProjectTree.class), metricFinder, mock(ScanGraph.class),
-      mock(DeprecatedViolations.class));
+    index = new DefaultIndex(mock(PersistenceManager.class), lock, mock(ProjectTree.class), metricFinder, mock(ScanGraph.class), deprecatedViolations);
     Project project = new Project("project");
 
     ResourceFilter filter = new ResourceFilter() {
@@ -83,26 +84,26 @@ public class DefaultIndexTest {
   @Test
   public void shouldCreateUID() {
     Project project = new Project("my_project");
-    assertThat(DefaultIndex.createUID(project, project), is("my_project"));
+    assertThat(DefaultIndex.createUID(project, project)).isEqualTo("my_project");
 
     JavaPackage javaPackage = new JavaPackage("org.foo");
-    assertThat(DefaultIndex.createUID(project, javaPackage), is("my_project:org.foo"));
+    assertThat(DefaultIndex.createUID(project, javaPackage)).isEqualTo("my_project:org.foo");
 
     Library library = new Library("junit:junit", "4.7");
-    assertThat(DefaultIndex.createUID(project, library), is("junit:junit"));
+    assertThat(DefaultIndex.createUID(project, library)).isEqualTo("junit:junit");
   }
 
   @Test
   public void shouldIndexParentOfDeprecatedFiles() {
     File file = new File("org/foo/Bar.java");
-    assertThat(index.index(file), is(true));
+    assertThat(index.index(file)).isTrue();
 
     Directory reference = new Directory("org/foo");
-    assertThat(index.getResource(reference).getName(), is("org/foo"));
-    assertThat(index.isIndexed(reference, true), is(true));
-    assertThat(index.isExcluded(reference), is(false));
-    assertThat(index.getChildren(reference).size(), is(1));
-    assertThat(index.getParent(reference), is(Project.class));
+    assertThat(index.getResource(reference).getName()).isEqualTo("org/foo");
+    assertThat(index.isIndexed(reference, true)).isTrue();
+    assertThat(index.isExcluded(reference)).isFalse();
+    assertThat(index.getChildren(reference)).hasSize(1);
+    assertThat(index.getParent(reference)).isInstanceOf(Project.class);
   }
 
   @Test
@@ -111,27 +112,27 @@ public class DefaultIndexTest {
     File file = new File("org/foo/Bar.java");
     file.setLanguage(Java.INSTANCE);
 
-    assertThat(index.index(directory), is(true));
-    assertThat(index.index(file, directory), is(true));
+    assertThat(index.index(directory)).isTrue();
+    assertThat(index.index(file, directory)).isTrue();
 
     File fileRef = new File("org/foo/Bar.java");
-    assertThat(index.getResource(fileRef).getKey(), is("org/foo/Bar.java"));
-    assertThat(index.getResource(fileRef).getLanguage(), is((Language) Java.INSTANCE));
-    assertThat(index.isIndexed(fileRef, true), is(true));
-    assertThat(index.isExcluded(fileRef), is(false));
-    assertThat(index.getChildren(fileRef).size(), is(0));
-    assertThat(index.getParent(fileRef), is(Directory.class));
+    assertThat(index.getResource(fileRef).getKey()).isEqualTo("org/foo/Bar.java");
+    assertThat(index.getResource(fileRef).getLanguage().getKey()).isEqualTo("java");
+    assertThat(index.isIndexed(fileRef, true)).isTrue();
+    assertThat(index.isExcluded(fileRef)).isFalse();
+    assertThat(index.getChildren(fileRef)).isEmpty();
+    assertThat(index.getParent(fileRef)).isInstanceOf(Directory.class);
   }
 
   @Test
   public void shouldIndexLibraryOutsideProjectTree() {
     Library lib = new Library("junit", "4.8");
-    assertThat(index.index(lib), is(true));
+    assertThat(index.index(lib)).isTrue();
 
     Library reference = new Library("junit", "4.8");
-    assertThat(index.getResource(reference).getQualifier(), is(Qualifiers.LIBRARY));
-    assertThat(index.isIndexed(reference, true), is(true));
-    assertThat(index.isExcluded(reference), is(false));
+    assertThat(index.getResource(reference).getQualifier()).isEqualTo(Qualifiers.LIBRARY);
+    assertThat(index.isIndexed(reference, true)).isTrue();
+    assertThat(index.isExcluded(reference)).isFalse();
   }
 
   @Test
@@ -139,14 +140,14 @@ public class DefaultIndexTest {
     Directory directory = new Directory("org/other");
     File file = new File("org/foo/Bar.java");
 
-    assertThat(index.index(file, directory), is(false));
+    assertThat(index.index(file, directory)).isFalse();
 
     File fileRef = new File("org/foo/Bar.java");
-    assertThat(index.isIndexed(directory, true), is(false));
-    assertThat(index.isIndexed(fileRef, true), is(false));
-    assertThat(index.isExcluded(fileRef), is(false));
-    assertThat(index.getChildren(fileRef).size(), is(0));
-    assertThat(index.getParent(fileRef), nullValue());
+    assertThat(index.isIndexed(directory, true)).isFalse();
+    assertThat(index.isIndexed(fileRef, true)).isFalse();
+    assertThat(index.isExcluded(fileRef)).isFalse();
+    assertThat(index.getChildren(fileRef)).isEmpty();
+    assertThat(index.getParent(fileRef)).isNull();
   }
 
   /**
@@ -157,8 +158,8 @@ public class DefaultIndexTest {
     lock.lock();
 
     Directory dir = new Directory("org/foo");
-    assertThat(index.index(dir), is(true));
-    assertThat(index.isIndexed(dir, true), is(true));
+    assertThat(index.index(dir)).isTrue();
+    assertThat(index.isIndexed(dir, true)).isTrue();
   }
 
   @Test(expected = SonarException.class)
@@ -173,10 +174,10 @@ public class DefaultIndexTest {
   @Test
   public void shouldBeExcluded() {
     File file = new File("org/foo/ExcludedBar.java");
-    assertThat(index.index(file), is(false));
-    assertThat(index.isIndexed(file, true), is(true));
-    assertThat(index.isIndexed(file, false), is(false));
-    assertThat(index.isExcluded(file), is(true));
+    assertThat(index.index(file)).isFalse();
+    assertThat(index.isIndexed(file, true)).isTrue();
+    assertThat(index.isIndexed(file, false)).isFalse();
+    assertThat(index.isExcluded(file)).isTrue();
   }
 
   @Test
@@ -184,8 +185,8 @@ public class DefaultIndexTest {
     Resource dir = new Directory("org/foo");
     index.addMeasure(dir, new Measure("ncloc").setValue(50.0));
 
-    assertThat(index.isIndexed(dir, true), is(true));
-    assertThat(index.getMeasures(dir, MeasuresFilters.metric("ncloc")).getIntValue(), is(50));
+    assertThat(index.isIndexed(dir, true)).isTrue();
+    assertThat(index.getMeasures(dir, MeasuresFilters.metric("ncloc")).getIntValue()).isEqualTo(50);
   }
 
   /**
@@ -197,7 +198,7 @@ public class DefaultIndexTest {
     Violation violation = Violation.create((Rule) null, file);
     index.addViolation(violation);
 
-    assertThat(index.getViolations(file).size(), is(0));
+    assertThat(index.getViolations(file)).isEmpty();
   }
 
   /**
@@ -211,7 +212,45 @@ public class DefaultIndexTest {
     Violation violation = Violation.create(ruleWithoutID, file);
     index.addViolation(violation);
 
-    assertThat(index.getViolations(file).size(), is(0));
+    assertThat(index.getViolations(file)).isEmpty();
+  }
+
+  @Test
+  public void should_get_violation() {
+    Rule rule = Rule.create("repoKey", "ruleKey", "Rule");
+    File file = new File("org/foo/Bar.java");
+    Violation violation = Violation.create(rule, file);
+    when(deprecatedViolations.get(anyString())).thenReturn(newArrayList(violation));
+
+    index.addViolation(violation);
+
+    assertThat(index.getViolations(file)).hasSize(1);
+  }
+
+  @Test
+  public void should_get_filtered_violation_with_off_switch_mode() {
+    Rule rule = Rule.create("repoKey", "ruleKey", "Rule");
+    File file = new File("org/foo/Bar.java");
+    Violation violation = Violation.create(rule, file).setSwitchedOff(true);
+
+    when(deprecatedViolations.get(anyString())).thenReturn(newArrayList(violation));
+
+    index.addViolation(violation);
+
+    assertThat(index.getViolations(ViolationQuery.create().forResource(file).setSwitchMode(ViolationQuery.SwitchMode.OFF))).hasSize(1);
+  }
+
+  @Test
+  public void should_get_filtered_violation_with_on_switch_mode() {
+    Rule rule = Rule.create("repoKey", "ruleKey", "Rule");
+    File file = new File("org/foo/Bar.java");
+    Violation violation = Violation.create(rule, file).setSwitchedOff(false);
+
+    when(deprecatedViolations.get(anyString())).thenReturn(newArrayList(violation));
+
+    index.addViolation(violation);
+
+    assertThat(index.getViolations(ViolationQuery.create().forResource(file).setSwitchMode(ViolationQuery.SwitchMode.ON))).hasSize(1);
   }
 
   @Test(expected = IllegalArgumentException.class)
index 35ddc49119407d704d84ed76fc989383de36096b..4fb8450de139f9c65bd83f64507530b3d6842e9b 100644 (file)
@@ -50,6 +50,7 @@ public class IssueQueryTest {
       .assigned(true)
       .createdAfter(new Date())
       .createdBefore(new Date())
+      .createdAt(new Date())
       .planned(true)
       .resolved(true)
       .sort(IssueQuery.SORT_BY_ASSIGNEE)
@@ -71,6 +72,7 @@ public class IssueQueryTest {
     assertThat(query.actionPlans()).containsOnly("AP1", "AP2");
     assertThat(query.createdAfter()).isNotNull();
     assertThat(query.createdBefore()).isNotNull();
+    assertThat(query.createdAt()).isNotNull();
     assertThat(query.planned()).isTrue();
     assertThat(query.resolved()).isTrue();
     assertThat(query.sort()).isEqualTo(IssueQuery.SORT_BY_ASSIGNEE);
@@ -84,11 +86,15 @@ public class IssueQueryTest {
   public void should_build_query_without_dates() throws Exception {
     IssueQuery query = IssueQuery.builder()
       .issueKeys(newArrayList("ABCDE"))
+      .createdAfter(null)
+      .createdBefore(null)
+      .createdAt(null)
       .build();
 
     assertThat(query.issueKeys()).containsOnly("ABCDE");
     assertThat(query.createdAfter()).isNull();
     assertThat(query.createdBefore()).isNull();
+    assertThat(query.createdAt()).isNull();
   }
 
   @Test
index b50e7f32594d0d904390925474ce15ec600e0af2..40646371131b169a7811ee86d8ea26e62c067b81 100644 (file)
@@ -22,8 +22,11 @@ package org.sonar.api.issue.internal;
 import com.google.common.collect.ImmutableMap;
 import org.apache.commons.lang.StringUtils;
 import org.junit.Test;
+import org.sonar.api.issue.Issue;
 import org.sonar.api.issue.IssueComment;
+import org.sonar.api.rule.RuleKey;
 
+import java.text.SimpleDateFormat;
 import java.util.List;
 
 import static org.fest.assertions.Assertions.assertThat;
@@ -34,6 +37,77 @@ public class DefaultIssueTest {
 
   DefaultIssue issue = new DefaultIssue();
 
+  @Test
+  public void test_setters_and_getters() throws Exception {
+    issue.setKey("ABCD")
+      .setComponentKey("org.sample.Sample")
+      .setProjectKey("Sample")
+      .setRuleKey(RuleKey.of("squid", "S100"))
+      .setSeverity("MINOR")
+      .setManualSeverity(true)
+      .setMessage("a message")
+      .setLine(7)
+      .setEffortToFix(1.2d)
+      .setActionPlanKey("BCDE")
+      .setStatus(Issue.STATUS_CLOSED)
+      .setResolution(Issue.RESOLUTION_FIXED)
+      .setReporter("simon")
+      .setAssignee("julien")
+      .setAuthorLogin("steph")
+      .setChecksum("c7b5db46591806455cf082bb348631e8")
+      .setNew(true)
+      .setEndOfLife(true)
+      .setOnDisabledRule(true)
+      .setChanged(true)
+      .setSendNotifications(true)
+      .setCreationDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-19"))
+      .setUpdateDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-20"))
+      .setCloseDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-21"))
+      .setSelectedAt(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-22"))
+    ;
+
+    assertThat(issue.key()).isEqualTo("ABCD");
+    assertThat(issue.componentKey()).isEqualTo("org.sample.Sample");
+    assertThat(issue.projectKey()).isEqualTo("Sample");
+    assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("squid", "S100"));
+    assertThat(issue.severity()).isEqualTo("MINOR");
+    assertThat(issue.manualSeverity()).isTrue();
+    assertThat(issue.message()).isEqualTo("a message");
+    assertThat(issue.line()).isEqualTo(7);
+    assertThat(issue.effortToFix()).isEqualTo(1.2d);
+    assertThat(issue.actionPlanKey()).isEqualTo("BCDE");
+    assertThat(issue.status()).isEqualTo(Issue.STATUS_CLOSED);
+    assertThat(issue.resolution()).isEqualTo(Issue.RESOLUTION_FIXED);
+    assertThat(issue.reporter()).isEqualTo("simon");
+    assertThat(issue.assignee()).isEqualTo("julien");
+    assertThat(issue.authorLogin()).isEqualTo("steph");
+    assertThat(issue.checksum()).isEqualTo("c7b5db46591806455cf082bb348631e8");
+    assertThat(issue.isNew()).isTrue();
+    assertThat(issue.isEndOfLife()).isTrue();
+    assertThat(issue.isOnDisabledRule()).isTrue();
+    assertThat(issue.isChanged()).isTrue();
+    assertThat(issue.mustSendNotifications()).isTrue();
+    assertThat(issue.creationDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-19"));
+    assertThat(issue.updateDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-20"));
+    assertThat(issue.closeDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-21"));
+    assertThat(issue.selectedAt()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-22"));
+  }
+
+  @Test
+  public void should_set_empty_dates() throws Exception {
+    issue
+      .setCreationDate(null)
+      .setUpdateDate(null)
+      .setCloseDate(null)
+      .setSelectedAt(null)
+    ;
+
+    assertThat(issue.creationDate()).isNull();
+    assertThat(issue.updateDate()).isNull();
+    assertThat(issue.closeDate()).isNull();
+    assertThat(issue.selectedAt()).isNull();
+  }
+
   @Test
   public void test_attributes() throws Exception {
     assertThat(issue.attribute("foo")).isNull();
index a759f85107a698e54316729f4a2142c9a3d692a0..1b2e9e2df560cc25345f8adf28f05effb92521aa 100644 (file)
@@ -22,25 +22,34 @@ package org.sonar.server.issue;
 
 import com.google.common.collect.Lists;
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.IssueComment;
 import org.sonar.api.issue.IssueQuery;
 import org.sonar.api.issue.IssueQueryResult;
+import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.issue.internal.DefaultIssueComment;
+import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.api.web.UserRole;
 import org.sonar.core.issue.DefaultIssueQueryResult;
 import org.sonar.core.issue.IssueNotifications;
 import org.sonar.core.issue.IssueUpdater;
 import org.sonar.core.issue.db.IssueChangeDao;
+import org.sonar.core.issue.db.IssueChangeDto;
 import org.sonar.core.issue.db.IssueStorage;
 import org.sonar.core.permission.Permission;
 import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.user.MockUserSession;
 
+import static com.google.common.collect.Lists.newArrayList;
 import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.stub;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
 
 public class IssueCommentServiceTest {
 
@@ -54,8 +63,8 @@ public class IssueCommentServiceTest {
   @Rule
   public ExpectedException throwable = ExpectedException.none();
 
-  @BeforeClass
-  public static void setUpUser() {
+  @Before
+  public void setUpUser() {
     MockUserSession.set().setLogin("admin").setPermissions(Permission.SYSTEM_ADMIN);
   }
 
@@ -67,7 +76,7 @@ public class IssueCommentServiceTest {
 
     finder = mock(DefaultIssueFinder.class);
     Issue issue = mock(Issue.class);
-    IssueQueryResult result = new DefaultIssueQueryResult(Lists.newArrayList(issue));
+    IssueQueryResult result = new DefaultIssueQueryResult(newArrayList(issue));
     stub(finder.find(any(IssueQuery.class))).toReturn(result);
 
     issueNotifications = mock(IssueNotifications.class);
@@ -75,11 +84,49 @@ public class IssueCommentServiceTest {
     issueCommentService = new IssueCommentService(updater, changeDao, storage, finder, issueNotifications);
   }
 
+  @Test
+  public void should_find_comment() throws Exception {
+    issueCommentService.findComment("ABCD");
+    verify(changeDao).selectCommentByKey("ABCD");
+  }
+
+  @Test
+  public void should_add_comment() throws Exception {
+    DefaultIssue issue = mock(DefaultIssue.class);
+    when(issue.comments()).thenReturn(Lists.<IssueComment>newArrayList(new DefaultIssueComment()));
+
+    IssueQueryResult issueQueryResult = new DefaultIssueQueryResult(Lists.<Issue>newArrayList(issue));
+    when(finder.find(any(IssueQuery.class))).thenReturn(issueQueryResult);
+
+    issueCommentService.addComment("myIssue", "my comment", MockUserSession.get());
+
+    verify(updater).addComment(eq(issue), eq("my comment"), any(IssueChangeContext.class));
+    verify(storage).save(eq(issue));
+    verify(issueNotifications).sendChanges(eq(issue), any(IssueChangeContext.class), eq(issueQueryResult), eq("my comment"));
+  }
+
+  @Test
+  public void should_be_logged_when_adding_comment() throws Exception {
+    throwable.expect(UnauthorizedException.class);
+
+    MockUserSession.set().setLogin(null);
+
+    issueCommentService.addComment("myIssue", "my comment", MockUserSession.get());
+
+    verify(updater, never()).addComment(any(DefaultIssue.class), anyString(), any(IssueChangeContext.class));
+    verify(storage, never()).save(any(DefaultIssue.class));
+    verify(issueNotifications, never()).sendChanges(any(DefaultIssue.class), any(IssueChangeContext.class), any(IssueQueryResult.class), anyString());
+  }
+
   @Test
   public void should_prevent_adding_empty_comment() throws Exception {
     throwable.expect(BadRequestException.class);
 
     issueCommentService.addComment("myIssue", " ", MockUserSession.get());
+
+    verify(updater, never()).addComment(any(DefaultIssue.class), anyString(), any(IssueChangeContext.class));
+    verify(storage, never()).save(any(DefaultIssue.class));
+    verify(issueNotifications, never()).sendChanges(any(DefaultIssue.class), any(IssueChangeContext.class), any(IssueQueryResult.class), anyString());
   }
 
   @Test
@@ -87,19 +134,91 @@ public class IssueCommentServiceTest {
     throwable.expect(BadRequestException.class);
 
     issueCommentService.addComment("myIssue", null, MockUserSession.get());
+
+    verify(updater, never()).addComment(any(DefaultIssue.class), anyString(), any(IssueChangeContext.class));
+    verify(storage, never()).save(any(DefaultIssue.class));
+    verify(issueNotifications, never()).sendChanges(any(DefaultIssue.class), any(IssueChangeContext.class), any(IssueQueryResult.class), anyString());
+  }
+
+  @Test
+  public void should_delete_comment() throws Exception {
+    when(changeDao.selectCommentByKey("ABCD")).thenReturn(new DefaultIssueComment().setUserLogin("admin").setIssueKey("EFGH"));
+
+    issueCommentService.deleteComment("ABCD", MockUserSession.get());
+
+    verify(changeDao).delete("ABCD");
+    verify(finder).findByKey(eq("EFGH"), eq(UserRole.USER));
+  }
+
+  @Test
+  public void should_not_delete_not_found_comment() throws Exception {
+    throwable.expect(NotFoundException.class);
+
+    when(changeDao.selectCommentByKey("ABCD")).thenReturn(null);
+
+    issueCommentService.deleteComment("ABCD", MockUserSession.get());
+
+    verify(changeDao, never()).delete(anyString());
+  }
+
+  @Test
+  public void should_prevent_delete_others_comment() throws Exception {
+    throwable.expect(ForbiddenException.class);
+
+    when(changeDao.selectCommentByKey("ABCD")).thenReturn(new DefaultIssueComment().setUserLogin("julien"));
+
+    issueCommentService.deleteComment("ABCD", MockUserSession.get());
+
+    verify(changeDao, never()).delete(anyString());
+  }
+
+  @Test
+  public void should_update_comment() throws Exception {
+    when(changeDao.selectCommentByKey("ABCD")).thenReturn(new DefaultIssueComment().setIssueKey("EFGH").setUserLogin("admin"));
+
+    issueCommentService.editComment("ABCD", "updated comment", MockUserSession.get());
+
+    verify(changeDao).update(any(IssueChangeDto.class));
+    verify(finder).findByKey(eq("EFGH"), eq(UserRole.USER));
+  }
+
+  @Test
+  public void should_not_update_not_found_comment() throws Exception {
+    throwable.expect(NotFoundException.class);
+
+    when(changeDao.selectCommentByKey("ABCD")).thenReturn(null);
+
+    issueCommentService.editComment("ABCD", "updated comment", MockUserSession.get());
+
+    verify(changeDao, never()).update(any(IssueChangeDto.class));
   }
 
   @Test
   public void should_prevent_updating_empty_comment() throws Exception {
     throwable.expect(BadRequestException.class);
 
-    issueCommentService.editComment("myComment", "", MockUserSession.get());
+    issueCommentService.editComment("ABCD", "", MockUserSession.get());
+
+    verify(changeDao, never()).update(any(IssueChangeDto.class));
   }
 
   @Test
   public void should_prevent_updating_null_comment() throws Exception {
     throwable.expect(BadRequestException.class);
 
-    issueCommentService.editComment("myComment", null, MockUserSession.get());
+    issueCommentService.editComment("ABCD", null, MockUserSession.get());
+
+    verify(changeDao, never()).update(any(IssueChangeDto.class));
+  }
+
+  @Test
+  public void should_prevent_updating_others_comment() throws Exception {
+    throwable.expect(ForbiddenException.class);
+
+    when(changeDao.selectCommentByKey("ABCD")).thenReturn(new DefaultIssueComment().setUserLogin("julien"));
+
+    issueCommentService.editComment("ABCD", "updated comment", MockUserSession.get());
+
+    verify(changeDao, never()).update(any(IssueChangeDto.class));
   }
 }