From b6e19bf7f6a145573804b5f64866723885aac1c5 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Thu, 19 Jun 2014 20:12:14 +0200 Subject: [PATCH] SONAR-5329 Very first draft of new Quality Profile changelog --- .../resources/org/sonar/l10n/core.properties | 3 +- .../server/activity/RubyActivityService.java | 76 +++++++++ .../server/activity/index/ActivityDoc.java | 11 +- .../server/platform/ServerComponents.java | 148 ++---------------- .../qualityprofile/QProfileActivityQuery.java | 4 +- .../app/controllers/profiles_controller.rb | 12 ++ .../WEB-INF/app/views/profiles/_tabs.html.erb | 3 + .../app/views/profiles/changelog.html.erb | 1 - .../app/views/profiles/changelog2.html.erb | 41 +++++ .../activity/RubyActivityServiceTest.java | 89 +++++++++++ 10 files changed, 246 insertions(+), 142 deletions(-) create mode 100644 sonar-server/src/main/java/org/sonar/server/activity/RubyActivityService.java create mode 100644 sonar-server/src/main/webapp/WEB-INF/app/views/profiles/changelog2.html.erb create mode 100644 sonar-server/src/test/java/org/sonar/server/activity/RubyActivityServiceTest.java diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index a734b36f0eb..5d0a5304351 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -1587,8 +1587,7 @@ quality_profiles.projects_warning=List of projects explicitly associated to this quality_profiles.including_x_overriding.suffix=, incl. {0} overriding quality_profiles.set_parent=Set parent quality_profiles.inherit_rules_from_profile=Inherit rules configuration from the profile -quality_profiles.not_used=This Quality Profile has not yet been used, so change tracking is not in use yet. -quality_profiles.first_use_without_change=No changes have occurred since first use of this Quality Profile. +quality_profiles.changelog.empty=No changes have been done. quality_profiles.changelog_from=Changelog from quality_profiles.no_version=no version quality_profiles.last_version_x_with_date=last version {0} ({1}) diff --git a/sonar-server/src/main/java/org/sonar/server/activity/RubyActivityService.java b/sonar-server/src/main/java/org/sonar/server/activity/RubyActivityService.java new file mode 100644 index 00000000000..43b98eabf3b --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/activity/RubyActivityService.java @@ -0,0 +1,76 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.activity; + +import org.picocontainer.Startable; +import org.sonar.api.ServerComponent; +import org.sonar.server.qualityprofile.QProfileActivity; +import org.sonar.server.qualityprofile.QProfileActivityQuery; +import org.sonar.server.qualityprofile.QProfileService; +import org.sonar.server.search.QueryOptions; +import org.sonar.server.util.RubyUtils; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * @deprecated in 4.4 because Ruby on Rails is deprecated too ! + */ +@Deprecated +public class RubyActivityService implements ServerComponent, Startable { + + private final QProfileService service; + + public RubyActivityService(QProfileService service) { + this.service = service; + } + + /** + * Used in profiles_controller.rb + */ + public List search(Map params) { + QProfileActivityQuery query = new QProfileActivityQuery(); + List profileKeys = RubyUtils.toStrings(params.get("profileKeys")); + if (profileKeys != null) { + query.setQprofileKeys(profileKeys); + } + Date since = RubyUtils.toDate(params.get("since")); + if (since != null) { + query.setSince(since); + } + Date to = RubyUtils.toDate(params.get("to")); + if (to != null) { + query.setTo(to); + } + return service.findActivities(query, new QueryOptions().setMaxLimit()); + } + + @Override + public void start() { + // used to force pico to instantiate the singleton at startup + } + + @Override + public void stop() { + // implement startable + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityDoc.java b/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityDoc.java index c5d1108e2a3..d38c0cb6eb1 100644 --- a/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityDoc.java +++ b/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityDoc.java @@ -22,6 +22,7 @@ package org.sonar.server.activity.index; import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.sonar.core.activity.Activity; import org.sonar.server.search.BaseDoc; +import org.sonar.server.search.IndexUtils; import java.util.Date; import java.util.Map; @@ -37,27 +38,27 @@ public class ActivityDoc extends BaseDoc implements Activity { @Override public Date time() { - return this.getField(ActivityNormalizer.LogFields.CREATED_AT.field()); + return IndexUtils.parseDateTime((String) getField(ActivityNormalizer.LogFields.CREATED_AT.field())); } @Override public String author() { - return this.getField(ActivityNormalizer.LogFields.AUTHOR.field()); + return this.getNullableField(ActivityNormalizer.LogFields.AUTHOR.field()); } @Override public String action() { - return this.getField(ActivityNormalizer.LogFields.ACTION.field()); + return this.getNullableField(ActivityNormalizer.LogFields.ACTION.field()); } @Override public Map details() { - return this.getField(ActivityNormalizer.LogFields.DETAILS.field()); + return this.getNullableField(ActivityNormalizer.LogFields.DETAILS.field()); } @Override public String message() { - return this.getField(ActivityNormalizer.LogFields.MESSAGE.field()); + return this.getNullableField(ActivityNormalizer.LogFields.MESSAGE.field()); } @Override diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index fc892897c6e..40685bd9646 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -52,13 +52,7 @@ import org.sonar.core.measure.db.MeasureFilterDao; import org.sonar.core.metric.DefaultMetricFinder; import org.sonar.core.notification.DefaultNotificationManager; import org.sonar.core.permission.PermissionFacade; -import org.sonar.core.persistence.DaoUtils; -import org.sonar.core.persistence.DatabaseVersion; -import org.sonar.core.persistence.DefaultDatabase; -import org.sonar.core.persistence.MyBatis; -import org.sonar.core.persistence.PreviewDatabaseFactory; -import org.sonar.core.persistence.SemaphoreUpdater; -import org.sonar.core.persistence.SemaphoresImpl; +import org.sonar.core.persistence.*; import org.sonar.core.preview.PreviewCache; import org.sonar.core.profiling.Profiling; import org.sonar.core.purge.PurgeProfiler; @@ -78,6 +72,7 @@ import org.sonar.jpa.session.DatabaseSessionProvider; import org.sonar.jpa.session.DefaultDatabaseConnector; import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory; import org.sonar.server.activity.ActivityService; +import org.sonar.server.activity.RubyActivityService; import org.sonar.server.activity.db.ActivityDao; import org.sonar.server.activity.index.ActivityIndex; import org.sonar.server.activity.index.ActivityNormalizer; @@ -96,33 +91,11 @@ import org.sonar.server.db.DbClient; import org.sonar.server.db.EmbeddedDatabaseFactory; import org.sonar.server.db.migrations.DatabaseMigrations; import org.sonar.server.db.migrations.DatabaseMigrator; -import org.sonar.server.debt.DebtCharacteristicsXMLImporter; -import org.sonar.server.debt.DebtModelBackup; -import org.sonar.server.debt.DebtModelLookup; -import org.sonar.server.debt.DebtModelOperations; -import org.sonar.server.debt.DebtModelPluginRepository; -import org.sonar.server.debt.DebtModelService; -import org.sonar.server.debt.DebtModelXMLExporter; -import org.sonar.server.debt.DebtRulesXMLImporter; +import org.sonar.server.debt.*; import org.sonar.server.duplication.ws.DuplicationsParser; import org.sonar.server.duplication.ws.DuplicationsWriter; import org.sonar.server.duplication.ws.DuplicationsWs; -import org.sonar.server.issue.ActionService; -import org.sonar.server.issue.AssignAction; -import org.sonar.server.issue.CommentAction; -import org.sonar.server.issue.DefaultIssueFinder; -import org.sonar.server.issue.InternalRubyIssueService; -import org.sonar.server.issue.IssueBulkChangeService; -import org.sonar.server.issue.IssueChangelogFormatter; -import org.sonar.server.issue.IssueChangelogService; -import org.sonar.server.issue.IssueCommentService; -import org.sonar.server.issue.IssueService; -import org.sonar.server.issue.IssueStatsFinder; -import org.sonar.server.issue.PlanAction; -import org.sonar.server.issue.PublicRubyIssueService; -import org.sonar.server.issue.ServerIssueStorage; -import org.sonar.server.issue.SetSeverityAction; -import org.sonar.server.issue.TransitionAction; +import org.sonar.server.issue.*; import org.sonar.server.issue.actionplan.ActionPlanService; import org.sonar.server.issue.actionplan.ActionPlanWs; import org.sonar.server.issue.filter.IssueFilterService; @@ -147,83 +120,22 @@ import org.sonar.server.platform.ws.L10nWs; import org.sonar.server.platform.ws.RestartHandler; import org.sonar.server.platform.ws.ServerWs; import org.sonar.server.platform.ws.SystemWs; -import org.sonar.server.plugins.BatchWs; -import org.sonar.server.plugins.InstalledPluginReferentialFactory; -import org.sonar.server.plugins.PluginDownloader; -import org.sonar.server.plugins.ServerExtensionInstaller; -import org.sonar.server.plugins.ServerPluginJarInstaller; -import org.sonar.server.plugins.ServerPluginJarsInstaller; -import org.sonar.server.plugins.ServerPluginRepository; -import org.sonar.server.plugins.UpdateCenterClient; -import org.sonar.server.plugins.UpdateCenterMatrixFactory; +import org.sonar.server.plugins.*; import org.sonar.server.qualitygate.QgateProjectFinder; import org.sonar.server.qualitygate.QualityGates; import org.sonar.server.qualitygate.RegisterQualityGates; -import org.sonar.server.qualitygate.ws.QGatesAppAction; -import org.sonar.server.qualitygate.ws.QGatesCopyAction; -import org.sonar.server.qualitygate.ws.QGatesCreateAction; -import org.sonar.server.qualitygate.ws.QGatesCreateConditionAction; -import org.sonar.server.qualitygate.ws.QGatesDeleteConditionAction; -import org.sonar.server.qualitygate.ws.QGatesDeselectAction; -import org.sonar.server.qualitygate.ws.QGatesDestroyAction; -import org.sonar.server.qualitygate.ws.QGatesListAction; -import org.sonar.server.qualitygate.ws.QGatesRenameAction; -import org.sonar.server.qualitygate.ws.QGatesSearchAction; -import org.sonar.server.qualitygate.ws.QGatesSelectAction; -import org.sonar.server.qualitygate.ws.QGatesSetAsDefaultAction; -import org.sonar.server.qualitygate.ws.QGatesShowAction; -import org.sonar.server.qualitygate.ws.QGatesUnsetDefaultAction; -import org.sonar.server.qualitygate.ws.QGatesUpdateConditionAction; -import org.sonar.server.qualitygate.ws.QGatesWs; -import org.sonar.server.qualityprofile.BuiltInProfiles; -import org.sonar.server.qualityprofile.QProfileBackuper; -import org.sonar.server.qualityprofile.QProfileCopier; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.qualityprofile.QProfileLookup; -import org.sonar.server.qualityprofile.QProfileOperations; -import org.sonar.server.qualityprofile.QProfileProjectLookup; -import org.sonar.server.qualityprofile.QProfileProjectOperations; -import org.sonar.server.qualityprofile.QProfileRepositoryExporter; -import org.sonar.server.qualityprofile.QProfileReset; -import org.sonar.server.qualityprofile.QProfileService; -import org.sonar.server.qualityprofile.QProfiles; -import org.sonar.server.qualityprofile.RegisterQualityProfiles; -import org.sonar.server.qualityprofile.RuleActivator; -import org.sonar.server.qualityprofile.RuleActivatorContextFactory; +import org.sonar.server.qualitygate.ws.*; +import org.sonar.server.qualityprofile.*; import org.sonar.server.qualityprofile.db.ActiveRuleDao; import org.sonar.server.qualityprofile.index.ActiveRuleIndex; import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer; -import org.sonar.server.qualityprofile.ws.BulkRuleActivationActions; -import org.sonar.server.qualityprofile.ws.ProfilesWs; -import org.sonar.server.qualityprofile.ws.QProfileRestoreBuiltInAction; -import org.sonar.server.qualityprofile.ws.QProfilesWs; -import org.sonar.server.qualityprofile.ws.RuleActivationActions; -import org.sonar.server.rule.DeprecatedRulesDefinition; -import org.sonar.server.rule.RegisterRules; -import org.sonar.server.rule.RubyRuleService; -import org.sonar.server.rule.RuleCreator; -import org.sonar.server.rule.RuleDefinitionsLoader; -import org.sonar.server.rule.RuleDeleter; -import org.sonar.server.rule.RuleOperations; -import org.sonar.server.rule.RuleRepositories; -import org.sonar.server.rule.RuleService; -import org.sonar.server.rule.RuleUpdater; +import org.sonar.server.qualityprofile.ws.*; +import org.sonar.server.rule.*; import org.sonar.server.rule.db.RuleDao; import org.sonar.server.rule.index.RuleIndex; import org.sonar.server.rule.index.RuleNormalizer; -import org.sonar.server.rule.ws.ActiveRuleCompleter; -import org.sonar.server.rule.ws.AppAction; -import org.sonar.server.rule.ws.DeleteAction; -import org.sonar.server.rule.ws.RuleMapping; -import org.sonar.server.rule.ws.RulesWebService; -import org.sonar.server.rule.ws.SearchAction; -import org.sonar.server.rule.ws.TagsAction; -import org.sonar.server.rule.ws.UpdateAction; -import org.sonar.server.search.ESNode; -import org.sonar.server.search.IndexClient; -import org.sonar.server.search.IndexQueue; -import org.sonar.server.search.IndexQueueWorker; -import org.sonar.server.search.IndexSynchronizer; +import org.sonar.server.rule.ws.*; +import org.sonar.server.search.*; import org.sonar.server.source.CodeColorizers; import org.sonar.server.source.DeprecatedSourceDecorator; import org.sonar.server.source.HtmlSourceDecorator; @@ -232,27 +144,9 @@ import org.sonar.server.source.ws.ScmAction; import org.sonar.server.source.ws.ScmWriter; import org.sonar.server.source.ws.ShowAction; import org.sonar.server.source.ws.SourcesWs; -import org.sonar.server.startup.CleanPreviewAnalysisCache; -import org.sonar.server.startup.CopyRequirementsFromCharacteristicsToRules; -import org.sonar.server.startup.GeneratePluginIndex; -import org.sonar.server.startup.GwtPublisher; -import org.sonar.server.startup.JdbcDriverDeployer; -import org.sonar.server.startup.LogServerId; -import org.sonar.server.startup.RegisterDashboards; -import org.sonar.server.startup.RegisterDebtModel; -import org.sonar.server.startup.RegisterMetrics; -import org.sonar.server.startup.RegisterNewMeasureFilters; -import org.sonar.server.startup.RegisterPermissionTemplates; -import org.sonar.server.startup.RegisterServletFilters; -import org.sonar.server.startup.RenameDeprecatedPropertyKeys; -import org.sonar.server.startup.ServerMetadataPersister; +import org.sonar.server.startup.*; import org.sonar.server.test.CoverageService; -import org.sonar.server.test.ws.CoverageShowAction; -import org.sonar.server.test.ws.CoverageWs; -import org.sonar.server.test.ws.TestsCoveredFilesAction; -import org.sonar.server.test.ws.TestsShowAction; -import org.sonar.server.test.ws.TestsTestCasesAction; -import org.sonar.server.test.ws.TestsWs; +import org.sonar.server.test.ws.*; import org.sonar.server.text.MacroInterpreter; import org.sonar.server.text.RubyTextService; import org.sonar.server.ui.JRubyI18n; @@ -260,20 +154,9 @@ import org.sonar.server.ui.JRubyProfiling; import org.sonar.server.ui.PageDecorations; import org.sonar.server.ui.Views; import org.sonar.server.updatecenter.ws.UpdateCenterWs; -import org.sonar.server.user.DefaultUserService; -import org.sonar.server.user.DoPrivileged; -import org.sonar.server.user.GroupMembershipFinder; -import org.sonar.server.user.GroupMembershipService; -import org.sonar.server.user.NewUserNotifier; -import org.sonar.server.user.SecurityRealmFactory; +import org.sonar.server.user.*; import org.sonar.server.user.ws.UsersWs; -import org.sonar.server.util.BooleanTypeValidation; -import org.sonar.server.util.FloatTypeValidation; -import org.sonar.server.util.IntegerTypeValidation; -import org.sonar.server.util.StringListTypeValidation; -import org.sonar.server.util.StringTypeValidation; -import org.sonar.server.util.TextTypeValidation; -import org.sonar.server.util.TypeValidations; +import org.sonar.server.util.*; import org.sonar.server.ws.ListingWs; import org.sonar.server.ws.WebServiceEngine; @@ -437,6 +320,7 @@ class ServerComponents { pico.addSingleton(QProfileCopier.class); pico.addSingleton(QProfileBackuper.class); pico.addSingleton(QProfileReset.class); + pico.addSingleton(RubyActivityService.class); // rule pico.addSingleton(AnnotationRuleParser.class); diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileActivityQuery.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileActivityQuery.java index 716339c303d..cc303dab5a1 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileActivityQuery.java +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileActivityQuery.java @@ -31,7 +31,6 @@ import java.util.Collection; */ public class QProfileActivityQuery extends ActivityQuery { - Collection qprofileKeys; public QProfileActivityQuery() { @@ -44,7 +43,8 @@ public class QProfileActivityQuery extends ActivityQuery { return qprofileKeys; } - public void setQprofileKeys(Collection qprofileKeys) { + public QProfileActivityQuery setQprofileKeys(Collection qprofileKeys) { this.qprofileKeys = qprofileKeys; + return this; } } diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb index 0f265b097df..48e6f65be91 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb @@ -285,6 +285,18 @@ class ProfilesController < ApplicationController set_profile_breadcrumbs end + # GET /profiles/changelog?id= + def changelog2 + require_parameters 'id' + + @profile = Internal.quality_profiles.profile(params[:id].to_i) + #search = {'profileKeys' => @profile.key().to_s, 'since' => params[:since], 'to' => params[:to]} + # search = {'profileKeys' => @profile.key().to_s} + @changes = Internal.component(Java::OrgSonarServerActivity::RubyActivityService.java_class).search({}) + + set_profile_breadcrumbs + end + # # # GET /profiles/permalinks?id= diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_tabs.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_tabs.html.erb index 0e686faa0d6..e7efb2952ac 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_tabs.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_tabs.html.erb @@ -18,6 +18,9 @@
  • id="tab-changelog"><%= message('changelog') -%>
  • +
  • + Changelog2 +
  • <% if new_tab %>
  • <%= new_tab -%> diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/changelog.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/changelog.html.erb index 288b3ec1dc0..5817dbeb357 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/changelog.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/changelog.html.erb @@ -69,7 +69,6 @@ else %> <%= message('quality_profiles.parameter_changed_from_x_to_x', :params => [param_change.name, param_change.old_value, param_change.new_value]) -%> <% end %> - <%= "
    " unless param_change == change.parameters.last %> <% end%> diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/changelog2.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/changelog2.html.erb new file mode 100644 index 00000000000..2a563d4e9ec --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/changelog2.html.erb @@ -0,0 +1,41 @@ +
    +<%= render :partial => 'profiles/tabs', :locals => {:selected_tab=>'changelog'} %> + +
    + <% if @changes.empty? %> + <%= message('quality_profiles.changelog.empty') -%> + <% else %> +
    + + <%= message('quality_profiles.changelog_from') -%> + + <%= message('to').downcase -%> + + +
    + + + + + + + + + + + + <% + @changes.each do |change| + %> + + + + + + + <% end %> +
    <%= message('date') -%><%= message('user') -%><%= message('action') -%><%= message('rule') -%><%= message('parameters') -%>
    <%= change.time().to_s -%><%= change.author() ? change.author() : 'System' %><%= change.action() %><%= change.ruleKey() %>
    + + <% end %> +
    +
    diff --git a/sonar-server/src/test/java/org/sonar/server/activity/RubyActivityServiceTest.java b/sonar-server/src/test/java/org/sonar/server/activity/RubyActivityServiceTest.java new file mode 100644 index 00000000000..c4617bafcc5 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/activity/RubyActivityServiceTest.java @@ -0,0 +1,89 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.activity; + +import com.google.common.collect.ImmutableMap; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.api.utils.DateUtils; +import org.sonar.core.activity.Activity; +import org.sonar.server.qualityprofile.QProfileActivityQuery; +import org.sonar.server.qualityprofile.QProfileService; +import org.sonar.server.search.QueryOptions; + +import java.util.Date; + +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.verify; + +@RunWith(MockitoJUnitRunner.class) +public class RubyActivityServiceTest { + + @Mock + QProfileService service; + + @Captor + ArgumentCaptor activityArgumentCaptor; + + @Captor + ArgumentCaptor queryOptionsArgumentCaptor; + + RubyActivityService rubyActivityService; + + @Before + public void setUp() throws Exception { + rubyActivityService = new RubyActivityService(service); + } + + @Test + public void search() throws Exception { + Date since = DateUtils.parseDate("2014-05-19"); + Date to = DateUtils.parseDate("2014-06-19"); + rubyActivityService.search(ImmutableMap.of("profileKeys", "PROFILE_KEY", "since", since, "to", to)); + + verify(service).findActivities(activityArgumentCaptor.capture(), queryOptionsArgumentCaptor.capture()); + + assertThat(queryOptionsArgumentCaptor.getValue().getLimit()).isEqualTo(QueryOptions.MAX_LIMIT); + + assertThat(activityArgumentCaptor.getValue().getQprofileKeys()).containsOnly("PROFILE_KEY"); + assertThat(activityArgumentCaptor.getValue().getTypes()).containsOnly(Activity.Type.QPROFILE); + assertThat(activityArgumentCaptor.getValue().getSince()).isEqualTo(since); + assertThat(activityArgumentCaptor.getValue().getTo()).isEqualTo(to); + } + + @Test + public void search_with_empty_fields() throws Exception { + rubyActivityService.search(ImmutableMap.of()); + + verify(service).findActivities(activityArgumentCaptor.capture(), queryOptionsArgumentCaptor.capture()); + + assertThat(queryOptionsArgumentCaptor.getValue().getLimit()).isEqualTo(QueryOptions.MAX_LIMIT); + + assertThat(activityArgumentCaptor.getValue().getQprofileKeys()).isEmpty(); + assertThat(activityArgumentCaptor.getValue().getSince()).isNull(); + assertThat(activityArgumentCaptor.getValue().getTo()).isNull(); + } +} -- 2.39.5