import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
+import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.issue.Issue;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.utils.KeyValueFormat;
+import org.sonar.core.persistence.MyBatis;
import org.sonar.core.resource.ResourceDao;
import org.sonar.core.resource.ResourceDto;
+import org.sonar.core.user.AuthorizationDao;
+
+import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
private static final Logger LOG = LoggerFactory.getLogger(DefaultIssueFinder.class);
+ /**
+ * The role required to access issues
+ */
+ private static final String ROLE = "user";
+
+ private final MyBatis myBatis;
private final IssueDao issueDao;
private final ResourceDao resourceDao;
+ private final AuthorizationDao authorizationDao;
private final RuleFinder ruleFinder;
- public DefaultIssueFinder(IssueDao issueDao, ResourceDao resourceDao, RuleFinder ruleFinder) {
+ public DefaultIssueFinder(MyBatis myBatis, IssueDao issueDao, ResourceDao resourceDao,
+ AuthorizationDao authorizationDao, RuleFinder ruleFinder) {
+ this.myBatis = myBatis;
this.issueDao = issueDao;
this.resourceDao = resourceDao;
+ this.authorizationDao = authorizationDao;
this.ruleFinder = ruleFinder;
}
- public Results find(IssueQuery query) {
+ public Results find(IssueQuery query, @Nullable Integer currentUserId) {
LOG.debug("IssueQuery : {}", query);
- List<IssueDto> dtoList = issueDao.select(query);
-
- final Set<Integer> componentIds = Sets.newLinkedHashSet();
- final Set<Integer> ruleIds = Sets.newLinkedHashSet();
- for (IssueDto dto : dtoList) {
- componentIds.add(dto.getResourceId());
- ruleIds.add(dto.getRuleId());
- }
- final Map<Integer, Rule> rules = Maps.newHashMap();
- for (Integer ruleId : ruleIds) {
- Rule rule = ruleFinder.findById(ruleId);
- if (rule != null) {
- rules.put(rule.getId(), rule);
+ SqlSession sqlSession = myBatis.openSession();
+ try {
+ List<IssueDto> issueDtos = issueDao.select(query, sqlSession);
+
+ Set<Integer> componentIds = Sets.newLinkedHashSet();
+ Set<Integer> ruleIds = Sets.newLinkedHashSet();
+ for (IssueDto issueDto : issueDtos) {
+ componentIds.add(issueDto.getResourceId());
+ ruleIds.add(issueDto.getRuleId());
}
- }
- final Map<Integer, ResourceDto> resources = Maps.newHashMap();
- for (Integer componentId : componentIds) {
- ResourceDto resource = resourceDao.getResource(componentId);
- if (resource != null) {
- resources.put(resource.getId().intValue(), resource);
- }
- }
- // TODO verify authorization
+ componentIds = authorizationDao.keepAuthorizedComponentIds(componentIds, currentUserId, ROLE, sqlSession);
- List<Issue> issues = ImmutableList.copyOf(Iterables.transform(dtoList, new Function<IssueDto, Issue>() {
- @Override
- public Issue apply(IssueDto dto) {
- Rule rule = rules.get(dto.getRuleId());
- ResourceDto resource = resources.get(dto.getResourceId());
- return toIssue(dto, rule, resource);
+ final Map<Integer, Rule> rules = Maps.newHashMap();
+ for (Integer ruleId : ruleIds) {
+ Rule rule = ruleFinder.findById(ruleId);
+ if (rule != null) {
+ rules.put(rule.getId(), rule);
+ }
+ }
+ final Map<Integer, ResourceDto> resources = Maps.newHashMap();
+ for (Integer componentId : componentIds) {
+ // TODO replace N+1 SQL requests by a single one
+ ResourceDto resource = resourceDao.getResource(componentId);
+ if (resource != null) {
+ resources.put(resource.getId().intValue(), resource);
+ }
}
- }));
- return new DefaultResults(issues);
+ List<Issue> issues = ImmutableList.copyOf(Iterables.transform(issueDtos, new Function<IssueDto, Issue>() {
+ @Override
+ public Issue apply(IssueDto dto) {
+ Rule rule = rules.get(dto.getRuleId());
+ ResourceDto resource = resources.get(dto.getResourceId());
+ return toIssue(dto, rule, resource);
+ }
+ }));
+
+ return new DefaultResults(issues);
+ } finally {
+ MyBatis.closeQuietly(sqlSession);
+ }
}
public Issue findByKey(String key) {
public List<IssueDto> select(IssueQuery query) {
SqlSession session = mybatis.openSession();
try {
- // TODO support ordering
-
- return session.selectList("org.sonar.core.issue.IssueMapper.select", query, new RowBounds(query.offset(), query.limit()));
-
+ return select(query, session);
} finally {
MyBatis.closeQuietly(session);
}
}
+ public List<IssueDto> select(IssueQuery query, SqlSession session) {
+ // TODO support ordering
+
+ return session.selectList("org.sonar.core.issue.IssueMapper.select", query, new RowBounds(query.offset(), query.limit()));
+ }
+
}
import org.sonar.core.source.jdbc.SnapshotDataDao;
import org.sonar.core.template.LoadedTemplateDao;
import org.sonar.core.user.AuthorDao;
+import org.sonar.core.user.AuthorizationDao;
import org.sonar.core.user.UserDao;
import java.util.List;
return ImmutableList.of(
ActiveDashboardDao.class,
AuthorDao.class,
+ AuthorizationDao.class,
DashboardDao.class,
DuplicationDao.class,
GraphDao.class,
};
loadMappers(conf, mappers);
loadMapper(conf, "org.sonar.core.issue.IssueMapper");
+ loadMapper(conf, "org.sonar.core.user.AuthorizationMapper");
configureLogback(mappers);
sessionFactory = new SqlSessionFactoryBuilder().build(conf);
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.core.user;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+import org.apache.ibatis.session.SqlSession;
+import org.sonar.api.ServerComponent;
+import org.sonar.core.persistence.MyBatis;
+
+import javax.annotation.Nullable;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+public class AuthorizationDao implements ServerComponent {
+
+ private final MyBatis mybatis;
+
+ public AuthorizationDao(MyBatis mybatis) {
+ this.mybatis = mybatis;
+ }
+
+ public Set<Integer> keepAuthorizedComponentIds(Set<Integer> componentIds, @Nullable Integer userId, String role) {
+ SqlSession session = mybatis.openSession();
+ try {
+ return keepAuthorizedComponentIds(componentIds, userId, role, session);
+
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public Set<Integer> keepAuthorizedComponentIds(Set<Integer> componentIds, @Nullable Integer userId, String role, SqlSession session) {
+ if (componentIds.isEmpty()) {
+ return Collections.emptySet();
+ }
+ String sql;
+ Map<String, Object> params;
+ if (userId == null) {
+ sql = "keepAuthorizedComponentIdsForAnonymous";
+ params = ImmutableMap.of("role", role, "componentIds", componentIds);
+ } else {
+ sql = "keepAuthorizedComponentIdsForUser";
+ params = ImmutableMap.of("userId", userId, "role", role, "componentIds", componentIds);
+ }
+
+ return Sets.newHashSet(session.<Integer>selectList(sql, params));
+ }
+}
i.closed_at as closedAt
</sql>
- <insert id="insert" parameterType="Issue" useGeneratedKeys="true" keyProperty ="id">
+ <insert id="insert" parameterType="Issue" useGeneratedKeys="true" keyProperty="id">
INSERT INTO issues (uuid, resource_id, rule_id, severity, manual_severity, manual_issue, title, message, line, cost, status,
resolution, checksum, user_login, assignee_login, person_id, data, created_at, updated_at, closed_at)
VALUES (#{uuid}, #{resourceId}, #{ruleId}, #{severity}, #{manualSeverity}, #{manualIssue}, #{title}, #{message}, #{line}, #{cost}, #{status},
</insert>
<!-- Oracle -->
- <insert id="insert" databaseId="oracle" parameterType="Issue" keyColumn="id" useGeneratedKeys="true" keyProperty ="id">
- <selectKey order="BEFORE" resultType="Long" keyProperty="id" >
+ <insert id="insert" databaseId="oracle" parameterType="Issue" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
+ <selectKey order="BEFORE" resultType="Long" keyProperty="id">
select issues_seq.NEXTVAL from DUAL
</selectKey>
INSERT INTO issues (id, uuid, resource_id, rule_id, severity, manual_severity, manual_issue, title, message, line, cost, status,
</update>
<select id="selectById" parameterType="long" resultType="Issue">
- select <include refid="issueColumns"/>
+ select
+ <include refid="issueColumns"/>
from issues i
where i.id=#{id}
</select>
<select id="selectByKey" parameterType="String" resultType="Issue">
- select <include refid="issueColumns"/>
+ select
+ <include refid="issueColumns"/>
from issues i
where i.uuid=#{uuid}
</select>
<select id="select" parameterType="map" resultType="Issue">
- select <include refid="issueColumns"/> from issues i
+ select
+ <include refid="issueColumns"/>
+ <include refid="selectQueryConditions"/>
+ </select>
+
+ <sql id="selectQueryConditions">
+ from issues i
<if test="components != null and components.size() > 0">
, projects p, snapshots root, snapshots s
</if>
</foreach>
</if>
</where>
- </select>
+ </sql>
</mapper>
*/
package org.sonar.core.issue;
+import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.IssueFinder;
import org.sonar.api.issue.IssueQuery;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
+import org.sonar.core.persistence.MyBatis;
import org.sonar.core.resource.ResourceDao;
import org.sonar.core.resource.ResourceDto;
+import org.sonar.core.user.AuthorizationDao;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anySet;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class DefaultIssueFinderTest {
- private DefaultIssueFinder finder;
- private IssueDao issueDao;
- private ResourceDao resourceDao;
- private RuleFinder ruleFinder;
+ MyBatis mybatis;
+ DefaultIssueFinder finder;
+ IssueDao issueDao;
+ ResourceDao resourceDao;
+ RuleFinder ruleFinder;
+ AuthorizationDao authorizationDao;
@Before
public void before() {
+ mybatis = mock(MyBatis.class);
issueDao = mock(IssueDao.class);
resourceDao = mock(ResourceDao.class);
ruleFinder = mock(RuleFinder.class);
- finder = new DefaultIssueFinder(issueDao, resourceDao, ruleFinder);
+ authorizationDao = mock(AuthorizationDao.class);
+ finder = new DefaultIssueFinder(mybatis, issueDao, resourceDao, authorizationDao, ruleFinder);
}
@Test
public void should_find_issues() {
+ grantAccessRights();
IssueQuery issueQuery = mock(IssueQuery.class);
IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setResourceId(123);
IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setResourceId(123);
List<IssueDto> dtoList = newArrayList(issue1, issue2);
- when(issueDao.select(issueQuery)).thenReturn(dtoList);
+ when(issueDao.select(eq(issueQuery), any(SqlSession.class))).thenReturn(dtoList);
Rule rule = Rule.create("repo", "key");
rule.setId(50);
when(ruleFinder.findById(anyInt())).thenReturn(rule);
when(resourceDao.getResource(anyInt())).thenReturn(new ResourceDto().setKey("componentKey").setId(123L));
- IssueFinder.Results results = finder.find(issueQuery);
+ IssueFinder.Results results = finder.find(issueQuery, null);
assertThat(results.issues()).hasSize(2);
Issue issue = results.issues().iterator().next();
assertThat(issue.componentKey()).isEqualTo("componentKey");
assertThat(issue.ruleKey()).isEqualTo("key");
assertThat(issue.ruleRepositoryKey()).isEqualTo("repo");
}
+
+ private void grantAccessRights() {
+ when(authorizationDao.keepAuthorizedComponentIds(anySet(), anyInt(), anyString(), any(SqlSession.class)))
+ .thenAnswer(new Answer<Object>() {
+ @Override
+ public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
+ return invocationOnMock.getArguments()[0];
+ }
+ });
+ }
}
package org.sonar.api.issue;
-import org.sonar.api.component.Component;
import org.sonar.api.component.Perspective;
import java.util.Collection;
IssueBuilder newIssue();
Collection<Issue> issues();
-
- @Override
- Component component();
-
}
import org.sonar.api.component.Component;
import org.sonar.api.rules.Rule;
+import javax.annotation.Nullable;
+
import java.util.Collection;
import java.util.List;
List<Issue> issues();
}
- Results find(IssueQuery issueQuery);
+ Results find(IssueQuery issueQuery, @Nullable Integer currentUserId);
Issue findByKey(String key);
import java.util.List;
/**
+ * TODO add javadoc
+ *
* @since 3.6
*/
public class IssueQuery {
* Search for issues.
*
* <p>
- * Ruby: <code>Api.issues.find(hash)</code>
+ * Ruby: <code>Api.issues.find(hash_of_parameters, current_user.id)</code>
* </p>
*
* <p>Parameters</p>
* TODO document parameters
* </ul>
*/
- IssueFinder.Results find(Map<String, Object> parameters);
+ IssueFinder.Results find(Map<String, Object> parameters, Integer currentUserId);
}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.server.issue;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import org.sonar.api.issue.IssueFinder;
+import org.sonar.api.issue.IssueQuery;
+import org.sonar.api.issue.JRubyIssues;
+import org.sonar.server.ui.JRubyFacades;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Facade of issue components for JRuby on Rails webapp
+ *
+ * @since 3.6
+ */
+public class DefaultJRubyIssues implements JRubyIssues {
+
+ private final IssueFinder finder;
+
+ public DefaultJRubyIssues(IssueFinder f) {
+ this.finder = f;
+ JRubyFacades.setIssues(this);
+ }
+
+ public IssueFinder.Results find(Map<String, Object> params, Integer currentUserId) {
+ return finder.find(newQuery(params), currentUserId);
+ }
+
+ IssueQuery newQuery(Map<String, Object> props) {
+ IssueQuery.Builder builder = IssueQuery.builder();
+ builder.keys(toStringList(props.get("keys")));
+ builder.severities(toStringList(props.get("severities")));
+ builder.statuses(toStringList(props.get("statuses")));
+ builder.resolutions(toStringList(props.get("resolutions")));
+ builder.components(toStringList(props.get("components")));
+ builder.userLogins(toStringList(props.get("userLogins")));
+ builder.assigneeLogins(toStringList(props.get("assigneeLogins")));
+ builder.limit(toInteger(props.get("limit")));
+ builder.offset(toInteger(props.get("offset")));
+ return builder.build();
+ }
+
+ List<String> toStringList(Object o) {
+ List<String> result = null;
+ if (o != null) {
+ if (o instanceof List) {
+ // assume that it contains only strings
+ result = (List) o;
+ } else if (o instanceof CharSequence) {
+ result = Lists.newArrayList(Splitter.on(',').omitEmptyStrings().split((CharSequence) o));
+ }
+ }
+ return result;
+ }
+
+ Integer toInteger(Object o) {
+ if (o instanceof Integer) {
+ return (Integer) o;
+ }
+ if (o instanceof String) {
+ return Integer.parseInt((String) o);
+ }
+ return null;
+ }
+
+ public void start() {
+ // used to force pico to instantiate the singleton at startup
+ }
+}
import org.sonar.server.configuration.Backup;
import org.sonar.server.configuration.ProfilesManager;
import org.sonar.server.database.EmbeddedDatabaseFactory;
+import org.sonar.server.issue.DefaultJRubyIssues;
import org.sonar.server.macro.MacroInterpreter;
import org.sonar.server.notifications.NotificationCenter;
import org.sonar.server.notifications.NotificationService;
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.server.ui;
-
-import com.google.common.base.Splitter;
-import com.google.common.collect.Lists;
-import org.sonar.api.issue.IssueFinder;
-import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.issue.JRubyIssues;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Facade of issue components for JRuby on Rails webapp
- *
- * @since 3.6
- */
-public class DefaultJRubyIssues implements JRubyIssues {
-
- private final IssueFinder finder;
-
- public DefaultJRubyIssues(IssueFinder f) {
- this.finder = f;
- JRubyFacades.setIssues(this);
- }
-
- public IssueFinder.Results find(Map<String, Object> params) {
- return finder.find(newQuery(params));
- }
-
- IssueQuery newQuery(Map<String, Object> props) {
- IssueQuery.Builder builder = IssueQuery.builder();
- builder.keys(toStringList(props.get("keys")));
- builder.severities(toStringList(props.get("severities")));
- builder.statuses(toStringList(props.get("statuses")));
- builder.resolutions(toStringList(props.get("resolutions")));
- builder.components(toStringList(props.get("components")));
- builder.userLogins(toStringList(props.get("userLogins")));
- builder.assigneeLogins(toStringList(props.get("assigneeLogins")));
- builder.limit(toInteger(props.get("limit")));
- builder.offset(toInteger(props.get("offset")));
- return builder.build();
- }
-
- List<String> toStringList(Object o) {
- List<String> result = null;
- if (o != null) {
- if (o instanceof List) {
- // assume that it contains only strings
- result = (List) o;
- } else if (o instanceof CharSequence) {
- result = Lists.newArrayList(Splitter.on(',').omitEmptyStrings().split((CharSequence) o));
- }
- }
- return result;
- }
-
- Integer toInteger(Object o) {
- if (o instanceof Integer) {
- return (Integer) o;
- }
- if (o instanceof String) {
- return Integer.parseInt((String) o);
- }
- return null;
- }
-
- public void start() {
- // used to force pico to instantiate the singleton at startup
- }
-}
private static JRubyIssues issues = null;
- static void setIssues(JRubyIssues i) {
+ public static void setIssues(JRubyIssues i) {
JRubyFacades.issues = i;
}
# GET /api/issues/search?<parameters>
def search
- results = find_issues(params)
+ results = Api.issues.find(params, current_user.id)
render :json => jsonp(issues_to_json(results.issues))
end
private
- def find_issues(map)
- Api.issues.find(map)
- end
-
def issues_to_json(issues)
json = []
issues.each do |issue|
@issues = find_issues({}).issues
end
-
protected
def find_issues(map)
- Api.issues.find(map)
+ Api.issues.find(map, current_user.id)
end
end
\ No newline at end of file
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.server.issue;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import org.junit.Test;
+import org.mockito.ArgumentMatcher;
+import org.sonar.api.issue.IssueFinder;
+import org.sonar.api.issue.IssueQuery;
+import org.sonar.server.issue.DefaultJRubyIssues;
+
+import java.util.Map;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Maps.newHashMap;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+public class DefaultJRubyIssuesTest {
+
+ IssueFinder finder = mock(IssueFinder.class);
+ DefaultJRubyIssues facade = new DefaultJRubyIssues(finder);
+
+ @Test
+ public void test_find() throws Exception {
+ facade.find(ImmutableMap.<String, Object>of("keys", Lists.newArrayList("ABCDE")), 123);
+ verify(finder).find(argThat(new ArgumentMatcher<IssueQuery>() {
+ @Override
+ public boolean matches(Object o) {
+ return ((IssueQuery) o).keys().contains("ABCDE");
+ }
+ }), eq(123));
+ }
+
+ @Test
+ public void should_create_query_from_parameters() {
+ Map<String, Object> map = newHashMap();
+ map.put("keys", newArrayList("ABCDE1234"));
+ map.put("severities", newArrayList("MAJOR", "MINOR"));
+ map.put("statuses", newArrayList("CLOSED"));
+ map.put("resolutions", newArrayList("FALSE-POSITIVE"));
+ map.put("components", newArrayList("org.apache"));
+ map.put("userLogins", newArrayList("marilyn"));
+ map.put("assigneeLogins", newArrayList("joanna"));
+ map.put("limit", 10);
+ map.put("offset", 50);
+
+ IssueQuery query = new DefaultJRubyIssues(finder).newQuery(map);
+ assertThat(query.keys()).containsOnly("ABCDE1234");
+ assertThat(query.severities()).containsExactly("MAJOR", "MINOR");
+ assertThat(query.statuses()).containsOnly("CLOSED");
+ assertThat(query.resolutions()).containsOnly("FALSE-POSITIVE");
+ assertThat(query.userLogins()).containsOnly("marilyn");
+ assertThat(query.assigneeLogins()).containsOnly("joanna");
+ assertThat(query.limit()).isEqualTo(10);
+ assertThat(query.offset()).isEqualTo(50);
+ }
+
+ @Test
+ public void should_start() throws Exception {
+ facade.start();
+ // nothing is done
+ verifyZeroInteractions(finder);
+ }
+}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.server.ui;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import org.junit.Test;
-import org.mockito.ArgumentMatcher;
-import org.sonar.api.issue.IssueFinder;
-import org.sonar.api.issue.IssueQuery;
-
-import java.util.Map;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Maps.newHashMap;
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-public class DefaultJRubyIssuesTest {
-
- IssueFinder finder = mock(IssueFinder.class);
- DefaultJRubyIssues facade = new DefaultJRubyIssues(finder);
-
- @Test
- public void test_find() throws Exception {
- facade.find(ImmutableMap.<String, Object>of("keys", Lists.newArrayList("ABCDE")));
- verify(finder).find(argThat(new ArgumentMatcher<IssueQuery>() {
- @Override
- public boolean matches(Object o) {
- return ((IssueQuery) o).keys().contains("ABCDE");
- }
- }));
- }
-
- @Test
- public void should_create_query_from_parameters() {
- Map<String, Object> map = newHashMap();
- map.put("keys", newArrayList("ABCDE1234"));
- map.put("severities", newArrayList("MAJOR", "MINOR"));
- map.put("statuses", newArrayList("CLOSED"));
- map.put("resolutions", newArrayList("FALSE-POSITIVE"));
- map.put("components", newArrayList("org.apache"));
- map.put("userLogins", newArrayList("marilyn"));
- map.put("assigneeLogins", newArrayList("joanna"));
- map.put("limit", 10);
- map.put("offset", 50);
-
- IssueQuery query = new DefaultJRubyIssues(finder).newQuery(map);
- assertThat(query.keys()).containsOnly("ABCDE1234");
- assertThat(query.severities()).containsExactly("MAJOR", "MINOR");
- assertThat(query.statuses()).containsOnly("CLOSED");
- assertThat(query.resolutions()).containsOnly("FALSE-POSITIVE");
- assertThat(query.userLogins()).containsOnly("marilyn");
- assertThat(query.assigneeLogins()).containsOnly("joanna");
- assertThat(query.limit()).isEqualTo(10);
- assertThat(query.offset()).isEqualTo(50);
- }
-
- @Test
- public void should_start() throws Exception {
- facade.start();
- // nothing is done
- verifyZeroInteractions(finder);
- }
-}
package org.sonar.server.ui;
import org.junit.Test;
+import org.sonar.server.issue.DefaultJRubyIssues;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;