]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-2382 Create a new "reviews" web service API
authorFabrice Bellingard <bellingard@gmail.com>
Thu, 28 Apr 2011 06:50:54 +0000 (08:50 +0200)
committerFabrice Bellingard <bellingard@gmail.com>
Thu, 28 Apr 2011 13:15:49 +0000 (15:15 +0200)
sonar-server/src/main/webapp/WEB-INF/app/controllers/api/reviews_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/controllers/reviews_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/models/review.rb
sonar-server/src/main/webapp/WEB-INF/app/views/reviews/_violation_false_positive_form.html.erb
sonar-ws-client/src/main/java/org/sonar/wsclient/services/Review.java [new file with mode: 0644]
sonar-ws-client/src/main/java/org/sonar/wsclient/services/ReviewQuery.java [new file with mode: 0644]
sonar-ws-client/src/main/java/org/sonar/wsclient/services/Violation.java
sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ReviewUnmarshaller.java [new file with mode: 0644]
sonar-ws-client/src/test/java/org/sonar/wsclient/services/ReviewQueryTest.java [new file with mode: 0644]
sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ReviewUnmarshallerTest.java [new file with mode: 0644]
sonar-ws-client/src/test/resources/reviews/reviews.json [new file with mode: 0644]

index a8f050e6dfa997371d248af0f00db3342a9f3501..bcce88cc58cf9bd0e517b3516d37a80aafd60775 100644 (file)
@@ -46,17 +46,25 @@ class Api::ReviewsController < Api::ApiController
       reviews.each do |review|
         xml.review do
           xml.id(review.id.to_i)
+          xml.createdAt(format_datetime(review.created_at))
           xml.updatedAt(format_datetime(review.updated_at))
           xml.user(review.user.login)
-          xml.assignee(review.assignee.login)
+          xml.assignee(review.assignee.login) if review.assignee
           xml.title(review.title)
           xml.type(review.review_type)
           xml.status(review.status)
           xml.severity(review.severity)
           xml.resource(review.resource.kee)  if review.resource
-          xml.line(review.resource_line) if review.resource_line
-          
-          # Continue here with resource + comments
+          xml.line(review.resource_line) if review.resource_line > 0
+          xml.comments do
+            review.review_comments.each do |comment|
+              xml.comment do
+                xml.author(comment.user.login)
+                xml.updatedAt(format_datetime(comment.updated_at))
+                xml.text(convert_markdown ? markdown_to_html(comment.review_text): comment.review_text)
+              end
+            end
+          end
         end
       end
     end
@@ -69,24 +77,25 @@ class Api::ReviewsController < Api::ApiController
   def review_to_json(review, html=false)
     json = {}
     json['id'] = review.id.to_i
-    json['updatedAt'] = review.updated_at
+    json['createdAt'] = format_datetime(review.created_at)
+    json['updatedAt'] = format_datetime(review.updated_at)
     json['author'] = review.user.login
     json['assignee'] = review.assignee.login if review.assignee
     json['title'] = review.title if review.title
     json['type'] = review.review_type
     json['status'] = review.status
     json['severity'] = review.severity
+    json['resource'] = review.resource.kee if review.resource
+    json['line'] = review.resource_line if review.resource_line > 0
     comments = []
     review.review_comments.each do |comment|
       comments << {
         'author' => comment.user.login,
         'updatedAt' => format_datetime(comment.updated_at),
-        'comment' => (html ? markdown_to_html(comment.review_text): comment.review_text)
+        'text' => (html ? markdown_to_html(comment.review_text): comment.review_text)
       }
     end
     json['comments'] = comments
-    json['line'] = review.resource_line if review.resource_line
-    json['resource'] = review.resource.kee if review.resource
     json
   end
 
index abaa6e11c2487ce68613137f6868f53bea78c922..69848be04e1beb6237041b6120a1b8fe437f2be4 100644 (file)
@@ -292,6 +292,10 @@ class ReviewsController < ApplicationController
       conditions << "status in (:statuses)"
       values[:statuses]=@statuses
     end
+    unless @projects == [""]
+      conditions << "project_id in (:projects)"
+      values[:projects]=@projects
+    end
     unless @severities == [""]
       conditions << "severity in (:severities)"
       values[:severities]=@severities
index f6d7bdc0939f9062439218a5019a48000b67c048..88deba8df15a2b101e83a34df33639f9a79b74bd 100644 (file)
@@ -50,9 +50,18 @@ class Review < ActiveRecord::Base
   end
 
   def self.search(options={})
-    conditions=['review_type<>:not_type']
-    values={:not_type => Review::TYPE_FALSE_POSITIVE}
-
+    conditions=[]
+    values={}
+      
+    review_type = options['review_type']
+    if review_type
+      conditions << "review_type=:type"
+      values[:type] = review_type.upcase
+    else
+      conditions=['review_type<>:not_type']
+      values={:not_type => Review::TYPE_FALSE_POSITIVE}
+    end
+    
     ids=options['ids']
     if options[:id]
       conditions << "id=:id"
@@ -68,6 +77,18 @@ class Review < ActiveRecord::Base
       values[:statuses]=statuses
     end
 
+    projects=options['projects']
+    if projects && projects.size>0 && !projects[0].blank?
+      conditions << "project_id in (:projects)"
+      values[:projects]=projects
+    end
+
+    resources=options['resources']
+    if resources && resources.size>0 && !resources[0].blank?
+      conditions << "resource_id in (:resources)"
+      values[:resources]=resources
+    end
+
     severities=options['severities']
     if severities && severities.size>0 && !severities[0].blank?
       conditions << "severity in (:severities)"
@@ -86,7 +107,7 @@ class Review < ActiveRecord::Base
       values[:assignees]=User.logins_to_ids(assignees)
     end
 
-    Review.find(:all, :order => "created_at DESC", :conditions => [conditions.join(" AND "), values], :limit => 200)
+    Review.find(:all, :include => [ 'review_comments' ], :order => "created_at DESC", :conditions => [conditions.join(" AND "), values], :limit => 200)
   end
   
   private
index f0e5574fd2227b320081e239f3c9b0aed7d40fb2..e78ea5e7dd8c9688778b84c7e00b69c3eafa591f 100644 (file)
@@ -15,5 +15,6 @@
   <h3><%= title -%></h3>
   <textarea id="commentText<%= params[:id] -%>"  rows="8" name="comment" style="width: 100%" onkeyup="if (this.value=='') $('submit_btn').disabled='true'; else $('submit_btn').disabled='';"></textarea>
   <%= submit_to_remote "submit_btn", button, :url => { :action => 'violation_flag_as_false_positive' }, :html => { :id => "submit_btn", :disabled => "true" }, :update => 'vId'+params[:id] -%>
+  &nbsp;
   <%= link_to_remote 'Cancel', :url => {:action => 'display_violation', :id => params[:id]}, :update => 'vId' + params[:id] -%>
 </form>
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Review.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Review.java
new file mode 100644 (file)
index 0000000..e2c1756
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.wsclient.services;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @since 2.8
+ */
+public class Review extends Model {
+
+  private Long id;
+  private Date createdAt = null;
+  private Date updatedAt = null;
+  private String authorLogin = null;
+  private String assigneeLogin = null;
+  private String title = null;
+  private String type = null;
+  private String status = null;
+  private String severity = null;
+  private String resourceKee = null;
+  private Integer line = null;
+  private List<Review.Comment> comments = new ArrayList<Review.Comment>();
+
+  /**
+   * @return the id
+   */
+  public Long getId() {
+    return id;
+  }
+
+  /**
+   * @param id
+   *          the id to set
+   */
+  public void setId(Long id) {
+    this.id = id;
+  }
+
+  /**
+   * @return the createdAt
+   */
+  public Date getCreatedAt() {
+    return createdAt;
+  }
+
+  /**
+   * @param createdAt
+   *          the createdAt to set
+   */
+  public void setCreatedAt(Date createdAt) {
+    this.createdAt = createdAt;
+  }
+
+  /**
+   * @return the updatedAt
+   */
+  public Date getUpdatedAt() {
+    return updatedAt;
+  }
+
+  /**
+   * @param updatedAt
+   *          the updatedAt to set
+   */
+  public void setUpdatedAt(Date updatedAt) {
+    this.updatedAt = updatedAt;
+  }
+
+  /**
+   * @return the authorLogin
+   */
+  public String getAuthorLogin() {
+    return authorLogin;
+  }
+
+  /**
+   * @param authorLogin
+   *          the authorLogin to set
+   */
+  public void setAuthorLogin(String authorLogin) {
+    this.authorLogin = authorLogin;
+  }
+
+  /**
+   * @return the assigneeLogin
+   */
+  public String getAssigneeLogin() {
+    return assigneeLogin;
+  }
+
+  /**
+   * @param assigneeLogin
+   *          the assigneeLogin to set
+   */
+  public void setAssigneeLogin(String assigneeLogin) {
+    this.assigneeLogin = assigneeLogin;
+  }
+
+  /**
+   * @return the title
+   */
+  public String getTitle() {
+    return title;
+  }
+
+  /**
+   * @param title
+   *          the title to set
+   */
+  public void setTitle(String title) {
+    this.title = title;
+  }
+
+  /**
+   * @return the type
+   */
+  public String getType() {
+    return type;
+  }
+
+  /**
+   * @param type
+   *          the type to set
+   */
+  public void setType(String type) {
+    this.type = type;
+  }
+
+  /**
+   * @return the status
+   */
+  public String getStatus() {
+    return status;
+  }
+
+  /**
+   * @param status
+   *          the status to set
+   */
+  public void setStatus(String status) {
+    this.status = status;
+  }
+
+  /**
+   * @return the severity
+   */
+  public String getSeverity() {
+    return severity;
+  }
+
+  /**
+   * @param severity
+   *          the severity to set
+   */
+  public void setSeverity(String severity) {
+    this.severity = severity;
+  }
+
+  /**
+   * @return the resourceKee
+   */
+  public String getResourceKee() {
+    return resourceKee;
+  }
+
+  /**
+   * @param resourceKee
+   *          the resourceKee to set
+   */
+  public void setResourceKee(String resourceKee) {
+    this.resourceKee = resourceKee;
+  }
+
+  /**
+   * @return the line
+   */
+  public Integer getLine() {
+    return line;
+  }
+
+  /**
+   * @param line
+   *          the line to set
+   */
+  public void setLine(Integer line) {
+    this.line = line;
+  }
+
+  /**
+   * @return the comments
+   */
+  public List<Review.Comment> getComments() {
+    return comments;
+  }
+
+  /**
+   * @param comments
+   *          the comments to set
+   */
+  public void addComments(Date updatedAt, String authorLogin, String text) {
+    this.comments.add(new Review.Comment(updatedAt, authorLogin, text));
+  }
+
+  /**
+   * @since 2.8
+   */
+  public class Comment extends Model {
+
+    private String authorLogin = null;
+    private Date updatedAt = null;
+    private String text = null;
+
+    private Comment(Date updatedAt, String authorLogin, String text) {
+      this.updatedAt = updatedAt;
+      this.authorLogin = authorLogin;
+      this.text = text;
+    }
+
+    /**
+     * @return the authorLogin
+     */
+    public String getAuthorLogin() {
+      return authorLogin;
+    }
+
+    /**
+     * @return the updatedAt
+     */
+    public Date getUpdatedAt() {
+      return updatedAt;
+    }
+
+    /**
+     * @return the text
+     */
+    public String getText() {
+      return text;
+    }
+  }
+
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/ReviewQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/ReviewQuery.java
new file mode 100644 (file)
index 0000000..0df5e01
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.wsclient.services;
+
+/**
+ * @since 2.8
+ */
+public class ReviewQuery extends Query<Review> {
+
+  public static final String BASE_URL = "/api/reviews";
+
+  private String reviewType;
+  private Long id;
+  private Long[] ids;
+  private String[] statuses;
+  private String[] severities;
+  private Long[] projects;
+  private Long[] resources;
+  private Long[] authors;
+  private Long[] assignees;
+  private Boolean html;
+
+  public ReviewQuery() {
+  }
+
+  /**
+   * @return the reviewType
+   */
+  public String getReviewType() {
+    return reviewType;
+  }
+
+  /**
+   * @param reviewType
+   *          the reviewType to set
+   */
+  public ReviewQuery setReviewType(String reviewType) {
+    this.reviewType = reviewType;
+    return this;
+  }
+
+  /**
+   * @return the id
+   */
+  public Long getId() {
+    return id;
+  }
+
+  /**
+   * @param id
+   *          the id to set
+   */
+  public ReviewQuery setId(Long id) {
+    this.id = id;
+    return this;
+  }
+
+  /**
+   * @return the ids
+   */
+  public Long[] getIds() {
+    return ids;
+  }
+
+  /**
+   * @param ids
+   *          the ids to set
+   */
+  public ReviewQuery setIds(Long... ids) {
+    this.ids = ids;
+    return this;
+  }
+
+  /**
+   * @return the statuses
+   */
+  public String[] getStatuses() {
+    return statuses;
+  }
+
+  /**
+   * @param statuses
+   *          the statuses to set
+   */
+  public ReviewQuery setStatuses(String... statuses) {
+    this.statuses = statuses;
+    return this;
+  }
+
+  /**
+   * @return the severities
+   */
+  public String[] getSeverities() {
+    return severities;
+  }
+
+  /**
+   * @param severities
+   *          the severities to set
+   */
+  public ReviewQuery setSeverities(String... severities) {
+    this.severities = severities;
+    return this;
+  }
+
+  /**
+   * @return the projects
+   */
+  public Long[] getProjects() {
+    return projects;
+  }
+
+  /**
+   * Specify the IDs of the projects.
+   * 
+   * @param projects
+   *          the project IDs to set
+   */
+  public ReviewQuery setProjects(Long... projects) {
+    this.projects = projects;
+    return this;
+  }
+
+  /**
+   * @return the resources
+   */
+  public Long[] getResources() {
+    return resources;
+  }
+
+  /**
+   * Specify the IDs of the resources.
+   * 
+   * @param resources
+   *          the resource IDs to set
+   */
+  public ReviewQuery setResources(Long... resources) {
+    this.resources = resources;
+    return this;
+  }
+
+  /**
+   * @return the authors
+   */
+  public Long[] getAuthors() {
+    return authors;
+  }
+
+  /**
+   * Specify the IDs of the authors.
+   * 
+   * @param authors
+   *          the author IDs to set
+   */
+  public ReviewQuery setAuthors(Long... authors) {
+    this.authors = authors;
+    return this;
+  }
+
+  /**
+   * @return the assignees
+   */
+  public Long[] getAssignees() {
+    return assignees;
+  }
+
+  /**
+   * Specify the IDs of the assignees.
+   * 
+   * @param assignees
+   *          the assignee IDs to set
+   */
+  public ReviewQuery setAssignees(Long... assignees) {
+    this.assignees = assignees;
+    return this;
+  }
+  
+  /**
+   * @return the html
+   */
+  public Boolean getHtml() {
+    return html;
+  }
+  
+  /**
+   * If true, the comments will be generated in HTML. Otherwise, they will be in raw text.
+   * 
+   * @param html the html to set
+   */
+  public ReviewQuery setHtml(Boolean html) {
+    this.html = html;
+    return this;
+  }
+
+  @Override
+  public String getUrl() {
+    StringBuilder url = new StringBuilder(BASE_URL);
+    url.append('?');
+    if (id != null) {
+      appendUrlParameter(url, "id", id);
+    } else if (ids != null) {
+      appendUrlParameter(url, "ids", ids);
+    }
+    appendUrlParameter(url, "review_type", reviewType);
+    appendUrlParameter(url, "statuses", statuses);
+    appendUrlParameter(url, "severities", severities);
+    appendUrlParameter(url, "projects", projects);
+    appendUrlParameter(url, "resources", resources);
+    appendUrlParameter(url, "authors", authors);
+    appendUrlParameter(url, "assignees", assignees);
+    appendUrlParameter(url, "html", html);
+
+    return url.toString();
+  }
+
+  @Override
+  public Class<Review> getModelClass() {
+    return Review.class;
+  }
+
+  public static ReviewQuery createForResource(Resource resource) {
+    return new ReviewQuery().setId(new Long(resource.getId()));
+  }
+
+}
index d077ac974953098c01fbab3e67a17937947031f8..1c74a823b521f69f99a32822551236514577b043 100644 (file)
@@ -192,10 +192,16 @@ public class Violation extends Model {
     return switchedOff;
   }
 
+  /**
+   * @since 2.8
+   */
   public Long getReviewId() {
     return reviewId;
   }
 
+  /**
+   * @since 2.8
+   */
   public Violation setReviewId(Long l) {
     this.reviewId = l;
     return this;
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ReviewUnmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ReviewUnmarshaller.java
new file mode 100644 (file)
index 0000000..cdaf3c2
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.wsclient.unmarshallers;
+
+import org.sonar.wsclient.services.Review;
+import org.sonar.wsclient.services.WSUtils;
+
+/**
+ * @since 2.8
+ */
+public class ReviewUnmarshaller extends AbstractUnmarshaller<Review> {
+
+  @Override
+  protected Review parse(Object json) {
+    WSUtils utils = WSUtils.getINSTANCE();
+
+    Review review = new Review();
+    review.setId(utils.getLong(json, "id"));
+    review.setCreatedAt(utils.getDateTime(json, "createdAt"));
+    review.setUpdatedAt(utils.getDateTime(json, "updatedAt"));
+    review.setAuthorLogin(utils.getString(json, "author"));
+    review.setAssigneeLogin(utils.getString(json, "assignee"));
+    review.setTitle(utils.getString(json, "title"));
+    review.setType(utils.getString(json, "type"));
+    review.setStatus(utils.getString(json, "status"));
+    review.setSeverity(utils.getString(json, "severity"));
+    review.setResourceKee(utils.getString(json, "resource"));
+    review.setLine(utils.getInteger(json, "line"));
+
+    Object comments = utils.getField(json, "comments");
+    if (comments != null) {
+      for (int i = 0; i < utils.getArraySize(comments); i++) {
+        Object comment = utils.getArrayElement(comments, i);
+        review.addComments(utils.getDateTime(comment, "updatedAt"), utils.getString(comment, "author"), utils.getString(comment, "text"));
+      }
+    }
+
+    return review;
+  }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ReviewQueryTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ReviewQueryTest.java
new file mode 100644 (file)
index 0000000..340a27d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.wsclient.services;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+
+public class ReviewQueryTest extends QueryTestCase {
+
+  @Test
+  public void testSimpleQueryForResource() {
+    Resource resource = mock(Resource.class);
+    when(resource.getId()).thenReturn(69);
+    ReviewQuery query = ReviewQuery.createForResource(resource);
+    assertThat(query.getUrl(), is("/api/reviews?id=69&"));
+    assertThat(query.getModelClass().getName(), is(Review.class.getName()));
+  }
+
+  @Test
+  public void resourceTreeViolations() {
+    ReviewQuery query = new ReviewQuery();
+    query.setIds(10L, 11L);
+    query.setReviewType("FALSE_POSITIVE");
+    query.setStatuses("OPEN");
+    query.setSeverities("MINOR", "INFO");
+    query.setProjects(1L);
+    query.setResources(2L, 3L);
+    query.setAuthors(20L);
+    query.setAssignees(21L);
+    query.setHtml(Boolean.TRUE);
+    assertThat(
+        query.getUrl(),
+        is("/api/reviews?ids=10,11&review_type=FALSE_POSITIVE&statuses=OPEN&severities=MINOR,INFO&projects=1&resources=2,3&authors=20&assignees=21&html=true&"));
+  }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ReviewUnmarshallerTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ReviewUnmarshallerTest.java
new file mode 100644 (file)
index 0000000..22a6ae0
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.wsclient.unmarshallers;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.sonar.wsclient.services.Review;
+import org.sonar.wsclient.services.Review.Comment;
+
+public class ReviewUnmarshallerTest extends UnmarshallerTestCase {
+
+  @Test
+  public void testToModels() {
+    Review review = new ReviewUnmarshaller().toModel("[]");
+    assertThat(review, nullValue());
+
+    List<Review> reviews = new ReviewUnmarshaller().toModels(loadFile("/reviews/reviews.json"));
+    assertThat(reviews.size(), is(2));
+
+    review = reviews.get(0);
+    assertThat(review.getAssigneeLogin(), nullValue());
+
+    review = reviews.get(1);
+    assertThat(review.getId(), is(3L));
+    assertNotNull(review.getCreatedAt());
+    assertNotNull(review.getUpdatedAt());
+    assertThat(review.getAuthorLogin(), is("admin"));
+    assertThat(review.getAssigneeLogin(), is("admin"));
+    assertThat(review.getTitle(), is("'static' modifier out of order with the JLS suggestions."));
+    assertThat(review.getType(), is("VIOLATION"));
+    assertThat(review.getStatus(), is("OPEN"));
+    assertThat(review.getSeverity(), is("MINOR"));
+    assertThat(review.getResourceKee(), is("org.codehaus.sonar:sonar-channel:org.sonar.channel.CodeReaderConfiguration"));
+    assertThat(review.getLine(), is(33));
+    List<Comment> comments = review.getComments();
+    assertThat(comments.size(), is(4));
+    Comment comment = comments.get(0);
+    assertNotNull(comment.getUpdatedAt());
+    assertThat(comment.getAuthorLogin(), is("admin"));
+    assertThat(comment.getText(), is("This is a review.<br/>And this is on multiple lines...<br/><br/><code>Wouhou!!!!!</code>"));
+  }
+
+}
diff --git a/sonar-ws-client/src/test/resources/reviews/reviews.json b/sonar-ws-client/src/test/resources/reviews/reviews.json
new file mode 100644 (file)
index 0000000..83a90bb
--- /dev/null
@@ -0,0 +1 @@
+[{"id":9,"createdAt":"2011-04-27T14:37:20+0200","updatedAt":"2011-04-27T14:37:20+0200","author":"admin","title":"New exception is thrown in catch block, original stack trace may be lost","type":"VIOLATION","status":"OPEN","severity":"MAJOR","resource":"org.codehaus.sonar:sonar-channel:org.sonar.channel.CodeReader","line":84,"comments":[{"author":"admin","updatedAt":"2011-04-27T14:37:20+0200","text":"Wazzaaaa"}]},{"id":3,"createdAt":"2011-04-26T15:44:42+0200","updatedAt":"2011-04-26T15:44:42+0200","author":"admin","assignee":"admin","title":"'static' modifier out of order with the JLS suggestions.","type":"VIOLATION","status":"OPEN","severity":"MINOR","resource":"org.codehaus.sonar:sonar-channel:org.sonar.channel.CodeReaderConfiguration","line":33,"comments":[{"author":"admin","updatedAt":"2011-04-26T15:44:42+0200","text":"This is a review.<br/>And this is on multiple lines...<br/><br/><code>Wouhou!!!!!</code>"},{"author":"admin","updatedAt":"2011-04-26T17:10:19+0200","text":"<em>Bold on multiple line?</em>"},{"author":"admin","updatedAt":"2011-04-26T17:11:02+0200","text":"And the bullets:<br/><ul><li>1 bullet</li>\n<li>2 bullets</li></ul>"},{"author":"admin","updatedAt":"2011-04-26T17:27:37+0200","text":"Wazzaa"}]}]
\ No newline at end of file