Commit 05b6b3868ceed5b14c11afce1068f28fee8488c6
1 parent
493dd777
Exists in
theme-brasil-digital-from-staging
and in
9 other branches
merging with branch AI3033-serpro_integration of rails 2.3
Showing
25 changed files
with
1180 additions
and
40 deletions
Show diff stats
app/controllers/public/account_controller.rb
... | ... | @@ -17,6 +17,8 @@ class AccountController < ApplicationController |
17 | 17 | @user = User.find_by_activation_code(params[:activation_code]) if params[:activation_code] |
18 | 18 | if @user and @user.activate |
19 | 19 | @message = _("Your account has been activated, now you can log in!") |
20 | + check_redirection | |
21 | + session[:join] = params[:join] unless params[:join].blank? | |
20 | 22 | render :action => 'login', :userlogin => @user.login |
21 | 23 | else |
22 | 24 | session[:notice] = _("It looks like you're trying to activate an account. Perhaps have already activated this account?") |
... | ... | @@ -35,6 +37,7 @@ class AccountController < ApplicationController |
35 | 37 | self.current_user ||= User.authenticate(params[:user][:login], params[:user][:password], environment) if params[:user] |
36 | 38 | |
37 | 39 | if logged_in? |
40 | + check_join_in_community(self.current_user) | |
38 | 41 | if params[:remember_me] == "1" |
39 | 42 | self.current_user.remember_me |
40 | 43 | cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at } |
... | ... | @@ -91,6 +94,7 @@ class AccountController < ApplicationController |
91 | 94 | if session[:may_be_a_bot] |
92 | 95 | return false unless verify_recaptcha :model=>@user, :message=>_('Captcha (the human test)') |
93 | 96 | end |
97 | + @user.community_to_join = session[:join] | |
94 | 98 | @user.signup! |
95 | 99 | owner_role = Role.find_by_name('owner') |
96 | 100 | @user.person.affiliate(@user.person, [owner_role]) if owner_role |
... | ... | @@ -101,6 +105,7 @@ class AccountController < ApplicationController |
101 | 105 | end |
102 | 106 | if @user.activated? |
103 | 107 | self.current_user = @user |
108 | + check_join_in_community(@user) | |
104 | 109 | go_to_signup_initial_page |
105 | 110 | else |
106 | 111 | @register_pending = true |
... | ... | @@ -388,12 +393,6 @@ class AccountController < ApplicationController |
388 | 393 | end |
389 | 394 | |
390 | 395 | def go_to_initial_page |
391 | - if params[:redirection] | |
392 | - session[:return_to] = @user.return_to | |
393 | - @user.return_to = nil | |
394 | - @user.save | |
395 | - end | |
396 | - | |
397 | 396 | if params[:return_to] |
398 | 397 | redirect_to params[:return_to] |
399 | 398 | elsif environment.enabled?('allow_change_of_redirection_after_login') |
... | ... | @@ -444,4 +443,19 @@ class AccountController < ApplicationController |
444 | 443 | redirect_back_or_default(default) |
445 | 444 | end |
446 | 445 | end |
446 | + | |
447 | + def check_redirection | |
448 | + unless params[:redirection].blank? | |
449 | + session[:return_to] = @user.return_to | |
450 | + @user.update_attributes(:return_to => nil) | |
451 | + end | |
452 | + end | |
453 | + | |
454 | + def check_join_in_community(user) | |
455 | + profile_to_join = session[:join] | |
456 | + unless profile_to_join.blank? | |
457 | + environment.profiles.find_by_identifier(profile_to_join).add_member(user.person) | |
458 | + session.delete(:join) | |
459 | + end | |
460 | + end | |
447 | 461 | end | ... | ... |
app/controllers/public/profile_controller.rb
... | ... | @@ -3,7 +3,7 @@ class ProfileController < PublicController |
3 | 3 | needs_profile |
4 | 4 | before_filter :check_access_to_profile, :except => [:join, :join_not_logged, :index, :add] |
5 | 5 | before_filter :store_location, :only => [:join, :join_not_logged, :report_abuse, :send_mail] |
6 | - before_filter :login_required, :only => [:add, :join, :join_not_logged, :leave, :unblock, :leave_scrap, :remove_scrap, :remove_activity, :view_more_activities, :view_more_network_activities, :report_abuse, :register_report, :leave_comment_on_activity, :send_mail] | |
6 | + before_filter :login_required, :only => [:add, :join, :leave, :unblock, :leave_scrap, :remove_scrap, :remove_activity, :view_more_activities, :view_more_network_activities, :report_abuse, :register_report, :leave_comment_on_activity, :send_mail] | |
7 | 7 | |
8 | 8 | helper TagsHelper |
9 | 9 | |
... | ... | @@ -97,21 +97,12 @@ class ProfileController < PublicController |
97 | 97 | end |
98 | 98 | |
99 | 99 | def join_not_logged |
100 | - if request.post? | |
101 | - profile.add_member(user) | |
102 | - session[:notice] = _('%s administrator still needs to accept you as member.') % profile.name if profile.closed? | |
103 | - redirect_to_previous_location | |
100 | + session[:join] = profile.identifier | |
101 | + | |
102 | + if user | |
103 | + redirect_to :controller => 'profile', :action => 'join' | |
104 | 104 | else |
105 | - if user.memberships.include?(profile) | |
106 | - session[:notice] = _('You are already a member of %s.') % profile.name | |
107 | - redirect_to profile.url | |
108 | - return | |
109 | - end | |
110 | - if request.xhr? | |
111 | - render :layout => false | |
112 | - else | |
113 | - redirect_to profile.url | |
114 | - end | |
105 | + redirect_to :controller => '/account', :action => 'login' | |
115 | 106 | end |
116 | 107 | end |
117 | 108 | ... | ... |
app/models/user.rb
... | ... | @@ -63,6 +63,9 @@ class User < ActiveRecord::Base |
63 | 63 | self.person.preferred_domain && self.person.preferred_domain.name || self.environment.default_hostname(true) |
64 | 64 | end |
65 | 65 | |
66 | + # virtual attribute used to stash which community to join on signup or login | |
67 | + attr_accessor :community_to_join | |
68 | + | |
66 | 69 | class Mailer < ActionMailer::Base |
67 | 70 | def activation_email_notify(user) |
68 | 71 | user_email = "#{user.login}@#{user.email_domain}" |
... | ... | @@ -85,7 +88,8 @@ class User < ActiveRecord::Base |
85 | 88 | :activation_code => user.activation_code, |
86 | 89 | :environment => user.environment.name, |
87 | 90 | :url => user.environment.top_url, |
88 | - :redirection => (true if user.return_to) | |
91 | + :redirection => (true if user.return_to), | |
92 | + :join => (user.community_to_join if user.community_to_join) | |
89 | 93 | end |
90 | 94 | |
91 | 95 | def signup_welcome_email(user) | ... | ... |
features/login.feature
... | ... | @@ -207,3 +207,18 @@ Feature: login |
207 | 207 | | Password | 123456 | |
208 | 208 | When I press "Log in" |
209 | 209 | Then I should be on joaosilva's control panel |
210 | + | |
211 | + Scenario: join community on login | |
212 | + Given the following users | |
213 | + | login | name | | |
214 | + | mariasilva | Maria Silva | | |
215 | + And the following communities | |
216 | + | name | identifier | owner | | |
217 | + | Free Software | freesoftware | mariasilva | | |
218 | + And I am on /freesoftware | |
219 | + When I follow "Join" | |
220 | + And I fill in the following: | |
221 | + | Username / Email | joaosilva | | |
222 | + | Password | 123456 | | |
223 | + And I press "Log in" | |
224 | + Then "Joao Silva" should be a member of "Free Software" | ... | ... |
features/signup.feature
... | ... | @@ -250,3 +250,51 @@ Feature: signup |
250 | 250 | And I fill in "Password" with "secret" |
251 | 251 | And I press "Log in" |
252 | 252 | Then I should be on the homepage |
253 | + | |
254 | + @selenium | |
255 | + Scenario: join community on signup | |
256 | + Given the following users | |
257 | + | login | name | | |
258 | + | mariasilva | Maria Silva | | |
259 | + And the following communities | |
260 | + | name | identifier | owner | | |
261 | + | Free Software | freesoftware | mariasilva | | |
262 | + And feature "skip_new_user_email_confirmation" is disabled on environment | |
263 | + And I am on /freesoftware | |
264 | + When I follow "Join" | |
265 | + And I follow "New user" | |
266 | + And I fill in the following within ".no-boxes": | |
267 | + | e-Mail | josesilva@example.com | | |
268 | + | Username | josesilva | | |
269 | + | Password | secret | | |
270 | + | Password confirmation | secret | | |
271 | + | Full name | José da Silva | | |
272 | + And wait for the captcha signup time | |
273 | + And I press "Create my account" | |
274 | + And I go to josesilva's confirmation URL | |
275 | + And I fill in "Username" with "josesilva" | |
276 | + And I fill in "Password" with "secret" | |
277 | + And I press "Log in" | |
278 | + Then "José da Silva" should be a member of "Free Software" | |
279 | + | |
280 | + @selenium | |
281 | + Scenario: join community on direct signup | |
282 | + Given the following users | |
283 | + | login | name | | |
284 | + | mariasilva | Maria Silva | | |
285 | + And the following communities | |
286 | + | name | identifier | owner | | |
287 | + | Free Software | freesoftware | mariasilva | | |
288 | + And feature "skip_new_user_email_confirmation" is enabled on environment | |
289 | + And I am on /freesoftware | |
290 | + When I follow "Join" | |
291 | + And I follow "New user" | |
292 | + And I fill in the following within ".no-boxes": | |
293 | + | e-Mail | josesilva@example.com | | |
294 | + | Username | josesilva | | |
295 | + | Password | secret | | |
296 | + | Password confirmation | secret | | |
297 | + | Full name | José da Silva | | |
298 | + And wait for the captcha signup time | |
299 | + And I press "Create my account" | |
300 | + Then "José da Silva" should be a member of "Free Software" | ... | ... |
plugins/serpro_integration/controllers/serpro_integration_plugin_myprofile_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,13 @@ |
1 | +class SerproIntegrationPluginMyprofileController < MyProfileController | |
2 | + append_view_path File.join(File.dirname(__FILE__) + '/../views') | |
3 | + | |
4 | + def create_gitlab | |
5 | + profile.create_gitlab_project | |
6 | + render :update do |page| | |
7 | + page.replace_html 'gitlab', :partial => 'gitlab' | |
8 | +# page.replace_html 'gitlab', 'teste' | |
9 | + end | |
10 | +# raise 'teste my profile' | |
11 | + end | |
12 | + | |
13 | +end | ... | ... |
... | ... | @@ -0,0 +1,15 @@ |
1 | +Feature: require authentication to comment | |
2 | + | |
3 | + Background: | |
4 | + Given plugin RequireAuthToCommentPlugin is enabled on environment | |
5 | + And the following users | |
6 | + | login | | |
7 | + | bozo | | |
8 | + | |
9 | + Scenario: enabling unauthenticated comment per profile | |
10 | + Given I am logged in as "bozo" | |
11 | + When I edit my profile | |
12 | + And I check "Accept comments from unauthenticated users" | |
13 | + And I press "Save" | |
14 | + Then I edit my profile | |
15 | + And the "Accept comments from unauthenticated users" checkbox should be checked | ... | ... |
... | ... | @@ -0,0 +1,220 @@ |
1 | +require_dependency 'community' | |
2 | +require 'gitlab' | |
3 | +#require 'jenkins_api_client' | |
4 | + | |
5 | +class Community | |
6 | + | |
7 | + settings_items :allow_sonar_integration, :type => :boolean, :default => true | |
8 | + settings_items :allow_gitlab_integration, :type => :boolean, :default => true | |
9 | + settings_items :allow_jenkins_integration, :type => :boolean, :default => true | |
10 | + | |
11 | + #FIXME make test for default option | |
12 | + settings_items :serpro_integration_plugin, :type => Hash, :default => {} | |
13 | + | |
14 | + ########################################## | |
15 | + # Gitlab stuff # | |
16 | + ########################################## | |
17 | + | |
18 | + after_create :create_gitlab_project | |
19 | + | |
20 | + def gitlab= params | |
21 | + self.serpro_integration_plugin[:gitlab] = params | |
22 | + end | |
23 | + | |
24 | + def gitlab | |
25 | + self.serpro_integration_plugin[:gitlab] ||= {} | |
26 | + self.serpro_integration_plugin[:gitlab] | |
27 | + end | |
28 | + | |
29 | + def create_gitlab_project | |
30 | + Gitlab.endpoint = self.gitlab_host | |
31 | + Gitlab.private_token = self.gitlab_private_token | |
32 | + | |
33 | + user = nil | |
34 | + | |
35 | + #Find user by email | |
36 | + begin | |
37 | + user = Gitlab.users(:search => email) | |
38 | + rescue Gitlab::Error::NotFound, Gitlab::Error::Parsing | |
39 | + user = nil | |
40 | + end | |
41 | + | |
42 | + #User not found, create user | |
43 | + if user == nil || user.count == 0 | |
44 | + user = self.admins.first | |
45 | + gitlab_user = Gitlab.create_user(user.email, '123456', {:username => user.identifier, :name => user.name, :provider => 'ldap'}) | |
46 | + end | |
47 | + | |
48 | + if gitlab_user.nil? | |
49 | + self.gitlab[:errors] = _('Gitlab user could not be created') | |
50 | + return nil | |
51 | + end | |
52 | + | |
53 | + #Create project for user | |
54 | + begin | |
55 | + #FIXME Why this? | |
56 | + if gitlab_user.is_a?(Array) | |
57 | + gitlab_user = user[0] | |
58 | + end | |
59 | + | |
60 | + project_options = {} | |
61 | + project_options[:user_id] = gitlab_user.id | |
62 | + project_options[:issues_enabled ] = true | |
63 | + project_options[:wall_enabled] = true | |
64 | + project_options[:wiki_enabled] = true | |
65 | + project_options[:public] = true | |
66 | + project = Gitlab.create_project(self.identifier, project_options) | |
67 | + | |
68 | + #Create Web Hook for Jenkins' integration | |
69 | +# Gitlab.add_project_hook(project.id, "#{self.jenkins[:url]}/gitlab/build_now") | |
70 | +# createJenkinsJob(project.name, project.path_with_namespace, project.web_url, project.http_url_to_repo) | |
71 | + | |
72 | + rescue Gitlab::Error::NotFound, Gitlab::Error::Parsing | |
73 | + #Project already exists | |
74 | + end | |
75 | + | |
76 | + self.gitlab[:errors] = nil | |
77 | + end | |
78 | + | |
79 | + # set an API endpoint | |
80 | + def gitlab_host | |
81 | + self.serpro_integration_plugin[:gitlab_host] | |
82 | + end | |
83 | + | |
84 | + # set a user private token | |
85 | + def gitlab_private_token | |
86 | + self.serpro_integration_plugin[:gitlab_private_token] | |
87 | + end | |
88 | + | |
89 | + ########################################## | |
90 | + # Sonar stuff # | |
91 | + ########################################## | |
92 | + | |
93 | +# after_create :create_sonar_project | |
94 | + | |
95 | + def sonar= params | |
96 | + self.serpro_integration_plugin[:sonar] = params | |
97 | + end | |
98 | + | |
99 | + def sonar | |
100 | + self.serpro_integration_plugin[:sonar] ||= {} | |
101 | + self.serpro_integration_plugin[:sonar] | |
102 | + end | |
103 | + | |
104 | + ########################################## | |
105 | + # Jenkins stuff # | |
106 | + ########################################## | |
107 | + | |
108 | +# after_create :create_jenkis_project | |
109 | + | |
110 | + def jenkins= params | |
111 | + self.serpro_integration_plugin[:jenkins] = params | |
112 | + end | |
113 | + | |
114 | + def jenkins | |
115 | + self.serpro_integration_plugin[:jenkins] ||= {} | |
116 | + url = "#{self.serpro_integration_plugin[:jenkins][:host]}:" | |
117 | + url += "#{self.serpro_integration_plugin[:jenkins][:port]}/" | |
118 | + url += "#{self.serpro_integration_plugin[:jenkins][:context_name]}" | |
119 | + self.serpro_integration_plugin[:jenkins][:url] = url | |
120 | + self.serpro_integration_plugin[:jenkins] | |
121 | + end | |
122 | + | |
123 | + | |
124 | + #FIXME make jenkins integration works | |
125 | + def create_jenkis_project | |
126 | +#(projectName, repositoryPath, webUrl, gitUrl) | |
127 | + | |
128 | + @client = JenkinsApi::Client.new(:server_url => "#{$jenkins_url}/", | |
129 | + :password => $jenkins_private_token, | |
130 | + :username => $jenkins_user) | |
131 | + | |
132 | + xmlJenkins = " | |
133 | + <maven2-moduleset plugin='maven-plugin@1.509'> | |
134 | + <actions/> | |
135 | + <description>Projeto criado para o repositório #{repositoryPath} do Gitlab - #{webUrl}</description> | |
136 | + <logRotator class='hudson.tasks.LogRotator'> | |
137 | + <daysToKeep>-1</daysToKeep> | |
138 | + <numToKeep>2</numToKeep> | |
139 | + <artifactDaysToKeep>-1</artifactDaysToKeep> | |
140 | + <artifactNumToKeep>-1</artifactNumToKeep> | |
141 | + </logRotator> | |
142 | + <keepDependencies>false</keepDependencies> | |
143 | + <properties/> | |
144 | + <scm class='hudson.plugins.git.GitSCM' plugin='git@2.2.1'> | |
145 | + <configVersion>2</configVersion> | |
146 | + <userRemoteConfigs> | |
147 | + <hudson.plugins.git.UserRemoteConfig> | |
148 | + <url>#{gitUrl}</url> | |
149 | + </hudson.plugins.git.UserRemoteConfig> | |
150 | + </userRemoteConfigs> | |
151 | + <branches> | |
152 | + <hudson.plugins.git.BranchSpec> | |
153 | + <name>*/master</name> | |
154 | + </hudson.plugins.git.BranchSpec> | |
155 | + </branches> | |
156 | + <doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations> | |
157 | + <submoduleCfg class='list'/> | |
158 | + <extensions/> | |
159 | + </scm> | |
160 | + <canRoam>true</canRoam> | |
161 | + <disabled>false</disabled> | |
162 | + <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding> | |
163 | + <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding> | |
164 | + <jdk>(Inherit From Job)</jdk> | |
165 | + <triggers class='vector'/> | |
166 | + <concurrentBuild>false</concurrentBuild> | |
167 | + <goals>clean package install deploy</goals> | |
168 | + <aggregatorStyleBuild>true</aggregatorStyleBuild> | |
169 | + <incrementalBuild>false</incrementalBuild> | |
170 | + <perModuleEmail>true</perModuleEmail> | |
171 | + <ignoreUpstremChanges>false</ignoreUpstremChanges> | |
172 | + <archivingDisabled>false</archivingDisabled> | |
173 | + <resolveDependencies>false</resolveDependencies> | |
174 | + <processPlugins>false</processPlugins> | |
175 | + <mavenValidationLevel>-1</mavenValidationLevel> | |
176 | + <runHeadless>false</runHeadless> | |
177 | + <disableTriggerDownstreamProjects>false</disableTriggerDownstreamProjects> | |
178 | + <settings class='jenkins.mvn.DefaultSettingsProvider'/> | |
179 | + <globalSettings class='jenkins.mvn.DefaultGlobalSettingsProvider'/> | |
180 | + <reporters> | |
181 | + <hudson.maven.reporters.MavenMailer> | |
182 | + <recipients/> | |
183 | + <dontNotifyEveryUnstableBuild>false</dontNotifyEveryUnstableBuild> | |
184 | + <sendToIndividuals>true</sendToIndividuals> | |
185 | + <perModuleEmail>true</perModuleEmail> | |
186 | + </hudson.maven.reporters.MavenMailer> | |
187 | + </reporters> | |
188 | + <publishers> | |
189 | + <hudson.plugins.sonar.SonarPublisher plugin='sonar@2.1'> | |
190 | + <jdk>(Inherit From Job)</jdk> | |
191 | + <branch/> | |
192 | + <language/> | |
193 | + <mavenOpts/> | |
194 | + <jobAdditionalProperties/> | |
195 | + <settings class='jenkins.mvn.DefaultSettingsProvider'/> | |
196 | + <globalSettings class='jenkins.mvn.DefaultGlobalSettingsProvider'/> | |
197 | + <usePrivateRepository>false</usePrivateRepository> | |
198 | + </hudson.plugins.sonar.SonarPublisher> | |
199 | + </publishers> | |
200 | + <buildWrappers/> | |
201 | + <prebuilders/> | |
202 | + <postbuilders/> | |
203 | + <runPostStepsIfResult> | |
204 | + <name>FAILURE</name> | |
205 | + <ordinal>2</ordinal> | |
206 | + <color>RED</color> | |
207 | + </runPostStepsIfResult> | |
208 | + </maven2-moduleset> | |
209 | + " | |
210 | + | |
211 | + begin | |
212 | + @client.job.create(projectName, xmlJenkins) | |
213 | + rescue JenkinsApi::Exceptions::ApiException | |
214 | + | |
215 | + end | |
216 | + | |
217 | + end | |
218 | + | |
219 | + | |
220 | +end | ... | ... |
... | ... | @@ -0,0 +1,9 @@ |
1 | +require_dependency 'profile' | |
2 | + | |
3 | +class Profile | |
4 | + settings_items :allow_sonar_integration, :type => :boolean, :default => true | |
5 | + settings_items :allow_gitlab_integration, :type => :boolean, :default => true | |
6 | + | |
7 | + #FIXME make test for default option | |
8 | + settings_items :serpro_integration_plugin, :type => Hash, :default => {} | |
9 | +end | ... | ... |
plugins/serpro_integration/lib/serpro_integration_plugin.rb
0 → 100644
... | ... | @@ -0,0 +1,64 @@ |
1 | +class SerproIntegrationPlugin < Noosfero::Plugin | |
2 | + | |
3 | +#include ActionController::UrlWriter | |
4 | +# include ActionView::Helpers::TagHelper | |
5 | +# include ActionView::Helpers::FormTagHelper | |
6 | +# include FormsHelper | |
7 | + | |
8 | + | |
9 | +# include ActionView::Helpers | |
10 | +# include FormsHelper | |
11 | + | |
12 | + def self.plugin_name | |
13 | + "Serpro Integration Plugin" | |
14 | + end | |
15 | + | |
16 | + def self.plugin_description | |
17 | + _("Make integration with serpro servers.") | |
18 | + end | |
19 | + | |
20 | +# def filter_comment(c) | |
21 | +# c.reject! unless logged_in? || allowed_by_profile | |
22 | +# end | |
23 | + | |
24 | + #FIXME make this test | |
25 | + # User could not have this block | |
26 | + def self.extra_blocks | |
27 | + { SonarPlugin::SonarWidgetBlock => {:type => [Community] }, | |
28 | + SonarPlugin::SmileBlock => {:type => [Community] } | |
29 | + } | |
30 | + end | |
31 | + | |
32 | + #FIXME make this test | |
33 | + def profile_editor_extras | |
34 | + lambda do | |
35 | + render :file => 'profile-editor-extras' | |
36 | + end | |
37 | + end | |
38 | + | |
39 | + def profile_id | |
40 | + context.profile | |
41 | + end | |
42 | + | |
43 | + def stylesheet? | |
44 | + true | |
45 | + end | |
46 | + | |
47 | +# FIXME make this test | |
48 | + def js_files | |
49 | + ['smile_face.js'] | |
50 | + end | |
51 | + | |
52 | +# def body_beginning | |
53 | +# "<meta name='profile.allow_unauthenticated_comments'/>" if allowed_by_profile | |
54 | +# end | |
55 | +# | |
56 | +# protected | |
57 | +# | |
58 | +# delegate :logged_in?, :to => :context | |
59 | +# | |
60 | +# def allowed_by_profile | |
61 | +# context.profile && context.profile.allow_unauthenticated_comments | |
62 | +# end | |
63 | + | |
64 | +end | ... | ... |
plugins/serpro_integration/lib/serpro_integration_plugin/smile_block.rb
0 → 100644
... | ... | @@ -0,0 +1,100 @@ |
1 | +require 'open-uri' | |
2 | +require 'json' | |
3 | + | |
4 | +class SonarPlugin::SmileBlock < Block | |
5 | + | |
6 | + | |
7 | + METRIC_SUCCESS_DENSITY = 'test_success_density' | |
8 | + METRIC_LOC = 'ncloc' | |
9 | + METRIC_UNCOVERED_LINE = 'uncovered_lines' | |
10 | + METRIC_COVERAGE = 'coverage' | |
11 | + | |
12 | + #FIXME make this test | |
13 | + settings_items :sonar_info, :type => Hash, :default => {} | |
14 | + | |
15 | + def self.description | |
16 | + _('Sonar Smile') | |
17 | + end | |
18 | + | |
19 | + def help | |
20 | + _('This block adds a smile face that make tecnical debits visible with funny way.') | |
21 | + end | |
22 | + | |
23 | + #FIXME make this test | |
24 | + def sonar_host | |
25 | + self.owner.sonar_plugin['host'] | |
26 | + end | |
27 | + | |
28 | + #FIXME make this test | |
29 | + def sonar_project | |
30 | + self.owner.sonar_plugin['project'] #|| '' | |
31 | + end | |
32 | + | |
33 | +#FIXME make this test | |
34 | + def smile_factor | |
35 | + collect_sonar_information | |
36 | + factor = (self.sonar_info[METRIC_COVERAGE] * self.sonar_info[METRIC_SUCCESS_DENSITY]).to_f/1000 | |
37 | + factor | |
38 | + end | |
39 | + | |
40 | + #FIXME make this test | |
41 | + def content(args={}) | |
42 | + smile_face_id = 'smileFace-' + self.id.to_s | |
43 | + | |
44 | + content_tag(:div, | |
45 | + content_tag(:canvas, '', :id => smile_face_id, :width => '95%', :height => '95%' ) + | |
46 | + "<script type='text/javascript'>drawFace('#{smile_face_id}', '#{self.smile_factor}')</script>", | |
47 | + :class => 'smile' | |
48 | + ) | |
49 | + end | |
50 | + | |
51 | + #FIXME make this test | |
52 | + def self.metrics | |
53 | + [ | |
54 | + METRIC_SUCCESS_DENSITY, | |
55 | + METRIC_LOC, | |
56 | + METRIC_UNCOVERED_LINE, | |
57 | + METRIC_COVERAGE | |
58 | + ] | |
59 | + end | |
60 | + | |
61 | + private | |
62 | + | |
63 | + #FIXME make this test | |
64 | + def collect_sonar_information | |
65 | + return false unless cache_expired? | |
66 | + begin | |
67 | + data = open("#{self.sonar_host}/api/resources?resource=#{self.sonar_project}&metrics=ncloc,coverage,weighted_violations,uncovered_lines,test_success_density&format=json").read | |
68 | + self.sonar_info = parse_sonar_resource(JSON.parse(data).first) | |
69 | + rescue | |
70 | + self.sonar_info = {} | |
71 | + end | |
72 | + self.sonar_info[:updated_at] = Time.now | |
73 | + self.save | |
74 | + end | |
75 | + | |
76 | + #FIXME make this test | |
77 | + def parse_sonar_resource(data) | |
78 | + parsed_data = {} | |
79 | + return {} if data['msr'].nil? | |
80 | + data['msr'].map do |metric| | |
81 | + self.class.metrics.map do |defined_metric| | |
82 | + parsed_data[defined_metric] = metric['val'] if metric['key'] == defined_metric | |
83 | + end | |
84 | + end | |
85 | + parsed_data | |
86 | + end | |
87 | + | |
88 | + #FIXME make this test | |
89 | + def cache_expired? | |
90 | + return true if self.sonar_info[:updated_at].nil? | |
91 | + (Time.now - self.sonar_info[:updated_at]) > cache_timestamp | |
92 | + end | |
93 | + | |
94 | + #FIXME make this test | |
95 | + # Cach time to load new data in seconds | |
96 | + def cache_timestamp | |
97 | + 60 * 60 | |
98 | + end | |
99 | + | |
100 | +end | ... | ... |
plugins/serpro_integration/lib/serpro_integration_plugin/sonar_widget_block.rb
0 → 100644
... | ... | @@ -0,0 +1,81 @@ |
1 | +class SerproIntegrationrPlugin::SonarWidgetBlock < Block | |
2 | + | |
3 | + #FIXME make this test | |
4 | + AVAILABLE_WIDGETS = { | |
5 | + 'project_motion_chart' => 'Project Motion Chart', | |
6 | + 'timeline' => 'Timeline', | |
7 | + 'complexity' => 'Complexity' | |
8 | + } | |
9 | + | |
10 | + #FIXME make this test. Make test for default widget | |
11 | + settings_items :widget, :type => String, :default => 'timeline' | |
12 | + | |
13 | + def self.description | |
14 | + _('Sonar Widgets') | |
15 | + end | |
16 | + | |
17 | + def help | |
18 | + _('This block adds sonar widgets on profile.') | |
19 | + end | |
20 | + | |
21 | + #FIXME make this test | |
22 | + def sonar_host | |
23 | + self.owner.serpro_integration_plugin['host'] | |
24 | + end | |
25 | + | |
26 | + #FIXME make this test | |
27 | + def sonar_project | |
28 | + self.owner.serpro_integration_plugin['project'] | |
29 | + end | |
30 | + | |
31 | + #FIXME make this test | |
32 | + def widget_url | |
33 | + self.sonar_host + 'widget?id=' + self.widget + '&resource=' + self.sonar_project + '&metric1=complexity&metric2=ncloc' | |
34 | + end | |
35 | + | |
36 | + #FIXME make this test | |
37 | + def is_widget_well_formed_url? | |
38 | + !self.widget_url.match(/http[s]?:\/\/[\w|.|\/]+\/widget\?id=[\w]+&resource=[\w|\W]+/).nil? | |
39 | + end | |
40 | + | |
41 | + #FIXME make this test | |
42 | + def widget_width | |
43 | + case widget | |
44 | + when 'project_motion_chart' | |
45 | + '360px' | |
46 | + when 'timeline' | |
47 | + '100%' | |
48 | + when 'complexity' | |
49 | + '100%' | |
50 | + else | |
51 | + '300px' | |
52 | + end | |
53 | + end | |
54 | + | |
55 | + #FIXME make this test | |
56 | + def widget_height | |
57 | + case widget | |
58 | + when 'project_motion_chart' | |
59 | + '450px' | |
60 | + when 'timeline' | |
61 | + '205px' | |
62 | + when 'complexity' | |
63 | + '170px' | |
64 | + else | |
65 | + '300px' | |
66 | + end | |
67 | + end | |
68 | + | |
69 | + def content(args={}) | |
70 | +# render this url | |
71 | +#http://sonar.serpro/widget?id=timeline&resource=br.gov.fazenda.coaf.siscoaf:siscoaf-parent&metric1=complexity&metric2=ncloc | |
72 | + | |
73 | + block = self | |
74 | + | |
75 | + lambda do | |
76 | + render :file => 'sonar_widget_block', :locals => { :block => block } | |
77 | + end | |
78 | + | |
79 | + end | |
80 | + | |
81 | +end | ... | ... |
... | ... | @@ -0,0 +1,129 @@ |
1 | +function drawBaseFace(element_id) { | |
2 | + var canvas = document.getElementById(element_id); | |
3 | + var ctx = canvas.getContext("2d"); | |
4 | + | |
5 | + var x = canvas.width / 2; | |
6 | + var y = canvas.height / 2; | |
7 | + var radius = canvas.width/2 - 1; | |
8 | + var startAngle = 0; | |
9 | + var endAngle = 2 * Math.PI; | |
10 | + | |
11 | + ctx.beginPath(); | |
12 | + ctx.arc(x, y, radius, startAngle, endAngle); | |
13 | + ctx.stroke(); | |
14 | + ctx.fillStyle = "yellow"; | |
15 | + ctx.fill(); | |
16 | +} | |
17 | + | |
18 | +function drawSmile(element_id, factor){ | |
19 | + var canvas = document.getElementById(element_id); | |
20 | + var ctx = canvas.getContext("2d"); | |
21 | + var x = canvas.width / 2; | |
22 | + var y = canvas.height / 2 | |
23 | + var radius = canvas.width/2 - canvas.width/4; | |
24 | + | |
25 | + var startAngle = 0; | |
26 | + var endAngle = 0; | |
27 | + var delta = 0; | |
28 | + | |
29 | + ctx.beginPath(); | |
30 | + ctx.lineWidth = canvas.width/100 * 2; | |
31 | + | |
32 | + if (factor >= 0 && factor < 5){ | |
33 | + //Draw sadness mouth | |
34 | + delta = 0.5 - factor* 0.1 | |
35 | + startAngle = (1.5 - delta) * Math.PI; | |
36 | + endAngle = (1.5 + delta) * Math.PI; | |
37 | + radius = radius - radius*delta; | |
38 | + y = y + (radius + radius*(1 - delta)); | |
39 | + ctx.arc(x, y, radius, startAngle, endAngle); | |
40 | + } else if (factor == 5) { | |
41 | + //Draw normal mouth | |
42 | + ctx.moveTo(x-canvas.width/8,y+canvas.width/8); | |
43 | + ctx.lineTo(x-canvas.width/8+(canvas.width/4),y+canvas.width/8); | |
44 | + } else if (factor > 5 && factor <= 10) { | |
45 | + //Draw happiness mouth | |
46 | + delta = 1 - factor * 0.1 | |
47 | + startAngle = delta * Math.PI; | |
48 | + endAngle = (1 - delta) * Math.PI; | |
49 | + radius = radius - radius*delta; | |
50 | + y = y - (radius - radius*(1-delta)); | |
51 | + ctx.arc(x, y, radius, startAngle, endAngle); | |
52 | + }else{ | |
53 | + //Draw scare mouth | |
54 | + radius = radius*0.4 | |
55 | + y = y + radius; | |
56 | + ctx.ellipse(x,y,radius*0.4, radius,0,0,2 * Math.PI, false); | |
57 | + ctx.fill(); | |
58 | + } | |
59 | + | |
60 | + | |
61 | + // line color | |
62 | + ctx.strokeStyle = 'black'; | |
63 | + ctx.stroke(); | |
64 | +} | |
65 | + | |
66 | +function drawEyes(element_id){ | |
67 | + var canvas = document.getElementById(element_id); | |
68 | + var ctx = canvas.getContext("2d"); | |
69 | + var centerX = canvas.width/5; | |
70 | + var centerY = 0; | |
71 | + var radius = canvas.width * 0.05; | |
72 | + | |
73 | + // save state | |
74 | + ctx.save(); | |
75 | + | |
76 | + // translate context so height is 1/3'rd from top of enclosing circle | |
77 | + ctx.translate(canvas.width / 2, canvas.height / 3); | |
78 | + | |
79 | + // scale context horizontally by 50% | |
80 | + ctx.scale(.5, 1); | |
81 | + | |
82 | + // draw circle which will be stretched into an oval | |
83 | + ctx.beginPath(); | |
84 | + ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false); | |
85 | + | |
86 | + // restore to original state | |
87 | + ctx.restore(); | |
88 | + | |
89 | + // apply styling | |
90 | + ctx.fillStyle = 'black'; | |
91 | + ctx.fill(); | |
92 | + ctx.lineWidth = 2; | |
93 | + ctx.strokeStyle = 'black'; | |
94 | + ctx.stroke(); | |
95 | + | |
96 | + | |
97 | + //left eye | |
98 | + centerX = centerX * -1; | |
99 | + | |
100 | + // save state | |
101 | + ctx.save(); | |
102 | + | |
103 | + // translate context so height is 1/3'rd from top of enclosing circle | |
104 | + ctx.translate(canvas.width / 2, canvas.height / 3); | |
105 | + | |
106 | + // scale context horizontally by 50% | |
107 | + ctx.scale(.5, 1); | |
108 | + | |
109 | + // draw circle which will be stretched into an oval | |
110 | + ctx.beginPath(); | |
111 | + ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false); | |
112 | + | |
113 | + // restore to original state | |
114 | + ctx.restore(); | |
115 | + | |
116 | + // apply styling | |
117 | + ctx.fillStyle = 'black'; | |
118 | + ctx.fill(); | |
119 | + ctx.lineWidth = 2; | |
120 | + ctx.strokeStyle = 'black'; | |
121 | + ctx.stroke(); | |
122 | +} | |
123 | + | |
124 | + | |
125 | +function drawFace(element_id, factor){ | |
126 | + drawBaseFace(element_id); | |
127 | + drawEyes(element_id); | |
128 | + drawSmile(element_id, factor); | |
129 | +} | ... | ... |
... | ... | @@ -0,0 +1,142 @@ |
1 | +<html> | |
2 | + <head> </head> | |
3 | + <body> | |
4 | + <canvas id="smileFace" width="60" height="60"></canvas> | |
5 | +<script> | |
6 | + | |
7 | +function drawBaseFace() { | |
8 | + var canvas = document.getElementById("smileFace"); | |
9 | + var ctx = canvas.getContext("2d"); | |
10 | + | |
11 | + var x = canvas.width / 2; | |
12 | + var y = canvas.height / 2; | |
13 | + var radius = canvas.width/2 - 1; | |
14 | + var startAngle = 0; | |
15 | + var endAngle = 2 * Math.PI; | |
16 | + | |
17 | + ctx.beginPath(); | |
18 | + ctx.arc(x, y, radius, startAngle, endAngle); | |
19 | + ctx.stroke(); | |
20 | + ctx.fillStyle = "yellow"; | |
21 | + ctx.fill(); | |
22 | +} | |
23 | + | |
24 | +function drawSmile(factor){ | |
25 | + var canvas = document.getElementById("smileFace"); | |
26 | + var ctx = canvas.getContext("2d"); | |
27 | + var x = canvas.width / 2; | |
28 | + var y = canvas.height / 2 | |
29 | + var radius = canvas.width/2 - canvas.width/4; | |
30 | + | |
31 | + var startAngle = 0; | |
32 | + var endAngle = 0; | |
33 | + var delta = 0; | |
34 | + | |
35 | + ctx.beginPath(); | |
36 | + ctx.lineWidth = canvas.width/100 * 2; | |
37 | + | |
38 | + if (factor >= 0 && factor < 5){ | |
39 | + //Draw sadness mouth | |
40 | + delta = 0.5 - factor* 0.1 | |
41 | + startAngle = (1.5 - delta) * Math.PI; | |
42 | + endAngle = (1.5 + delta) * Math.PI; | |
43 | + radius = radius - radius*delta; | |
44 | + y = y + (radius + radius*(1 - delta)); | |
45 | + ctx.arc(x, y, radius, startAngle, endAngle); | |
46 | + } else if (factor == 5) { | |
47 | + //Draw normal mouth | |
48 | + ctx.moveTo(x-canvas.width/8,y+canvas.width/8); | |
49 | + ctx.lineTo(x-canvas.width/8+(canvas.width/4),y+canvas.width/8); | |
50 | + } else if (factor > 5 && factor <= 10) { | |
51 | + //Draw happiness mouth | |
52 | + delta = 1 - factor * 0.1 | |
53 | + startAngle = delta * Math.PI; | |
54 | + endAngle = (1 - delta) * Math.PI; | |
55 | + radius = radius - radius*delta; | |
56 | + y = y - (radius - radius*(1-delta)); | |
57 | + ctx.arc(x, y, radius, startAngle, endAngle); | |
58 | + }else{ | |
59 | + //Draw scare mouth | |
60 | + radius = radius*0.4 | |
61 | + y = y + radius; | |
62 | + ctx.ellipse(x,y,radius*0.4, radius,0,0,2 * Math.PI, false); | |
63 | + ctx.fill(); | |
64 | + } | |
65 | + | |
66 | + | |
67 | + // line color | |
68 | + ctx.strokeStyle = 'black'; | |
69 | + ctx.stroke(); | |
70 | +} | |
71 | + | |
72 | +function drawEyes(){ | |
73 | + var canvas = document.getElementById("smileFace"); | |
74 | + var ctx = canvas.getContext("2d"); | |
75 | + var centerX = canvas.width/5; | |
76 | + var centerY = 0; | |
77 | + var radius = canvas.width * 0.05; | |
78 | + | |
79 | + // save state | |
80 | + ctx.save(); | |
81 | + | |
82 | + // translate context so height is 1/3'rd from top of enclosing circle | |
83 | + ctx.translate(canvas.width / 2, canvas.height / 3); | |
84 | + | |
85 | + // scale context horizontally by 50% | |
86 | + ctx.scale(.5, 1); | |
87 | + | |
88 | + // draw circle which will be stretched into an oval | |
89 | + ctx.beginPath(); | |
90 | + ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false); | |
91 | + | |
92 | + // restore to original state | |
93 | + ctx.restore(); | |
94 | + | |
95 | + // apply styling | |
96 | + ctx.fillStyle = 'black'; | |
97 | + ctx.fill(); | |
98 | + ctx.lineWidth = 2; | |
99 | + ctx.strokeStyle = 'black'; | |
100 | + ctx.stroke(); | |
101 | + | |
102 | + | |
103 | + //left eye | |
104 | + centerX = centerX * -1; | |
105 | + | |
106 | + // save state | |
107 | + ctx.save(); | |
108 | + | |
109 | + // translate context so height is 1/3'rd from top of enclosing circle | |
110 | + ctx.translate(canvas.width / 2, canvas.height / 3); | |
111 | + | |
112 | + // scale context horizontally by 50% | |
113 | + ctx.scale(.5, 1); | |
114 | + | |
115 | + // draw circle which will be stretched into an oval | |
116 | + ctx.beginPath(); | |
117 | + ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false); | |
118 | + | |
119 | + // restore to original state | |
120 | + ctx.restore(); | |
121 | + | |
122 | + // apply styling | |
123 | + ctx.fillStyle = 'black'; | |
124 | + ctx.fill(); | |
125 | + ctx.lineWidth = 2; | |
126 | + ctx.strokeStyle = 'black'; | |
127 | + ctx.stroke(); | |
128 | +} | |
129 | + | |
130 | + | |
131 | +function drawFace(factor){ | |
132 | + drawBaseFace(); | |
133 | + drawEyes(); | |
134 | + drawSmile(factor); | |
135 | +} | |
136 | + | |
137 | +drawFace(9); | |
138 | + | |
139 | +</script> | |
140 | + | |
141 | + </body> | |
142 | +</html> | ... | ... |
plugins/serpro_integration/test/unit/sonar_plugin_test.rb
0 → 100644
... | ... | @@ -0,0 +1,41 @@ |
1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | |
2 | + | |
3 | +class RequireAuthToCommentPluginTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @plugin = RequireAuthToCommentPlugin.new | |
7 | + @comment = Comment.new | |
8 | + end | |
9 | + | |
10 | + attr_reader :plugin, :comment | |
11 | + | |
12 | + should 'reject comments for unauthenticated users' do | |
13 | + plugin.context = logged_in(false) | |
14 | + plugin.filter_comment(comment) | |
15 | + assert comment.rejected? | |
16 | + end | |
17 | + | |
18 | + should 'allow comments from authenticated users' do | |
19 | + plugin.context = logged_in(true) | |
20 | + plugin.filter_comment(comment) | |
21 | + assert !comment.rejected? | |
22 | + end | |
23 | + | |
24 | + should 'allow comments from unauthenticated users if allowed by profile' do | |
25 | + plugin.context = logged_in(false) | |
26 | + plugin.context.profile.allow_unauthenticated_comments = true | |
27 | + | |
28 | + plugin.filter_comment(comment) | |
29 | + assert !comment.rejected? | |
30 | + end | |
31 | + | |
32 | + protected | |
33 | + | |
34 | + def logged_in(boolean) | |
35 | + controller = mock() | |
36 | + controller.stubs(:logged_in?).returns(boolean) | |
37 | + controller.stubs(:profile).returns(Profile.new) | |
38 | + controller | |
39 | + end | |
40 | + | |
41 | +end | ... | ... |
plugins/serpro_integration/views/profile-editor-extras.html.erb
0 → 100644
... | ... | @@ -0,0 +1,49 @@ |
1 | + | |
2 | +<div id='serpro-integration'> | |
3 | + <div id='gitlab' class='gitlab'> | |
4 | + <%= render :partial => 'gitlab' %> | |
5 | + </div> | |
6 | + | |
7 | + <div> | |
8 | + <%= labelled_check_box(_('Uses sonar integration'), 'profile_data[allow_sonar_integration]', true, profile.allow_sonar_integration) %> | |
9 | + </div> | |
10 | + | |
11 | + <ul class='sonar'> | |
12 | + <h2><%= _('Sonar Integration') %></h2> | |
13 | + <li> | |
14 | + <%= labelled_text_field(_('Server Host'), 'profile_data[sonar]host]', profile.sonar[:host]) %> | |
15 | + </li> | |
16 | + <li> | |
17 | + <%= labelled_text_field(_('Project: '), 'profile_data[sonar][project]', profile.sonar[:project]) %> | |
18 | + </li> | |
19 | + </ul> | |
20 | + | |
21 | + | |
22 | + <div> | |
23 | + <%= labelled_check_box(_('Uses Jenkins integration'), 'profile_data[allow_jenkins_integration]', true, profile.allow_jenkins_integration) %> | |
24 | + </div> | |
25 | + | |
26 | + <ul class='jenkins'> | |
27 | + <h2><%= _('Jenkins Integration') %></h2> | |
28 | + <li> | |
29 | + <%= labelled_text_field(_('Server Host'), 'profile_data[jenkins][host]', profile.jenkins[:host]) %> | |
30 | + </li> | |
31 | + <li> | |
32 | + <%= labelled_text_field(_('Server Port'), 'profile_data[jenkins][port]', profile.jenkins[:port]) %> | |
33 | + </li> | |
34 | + <li> | |
35 | + <%= labelled_text_field(_('Server Context Name'), 'profile_data[jenkins][context_name]', profile.jenkins[:context_name]) %> | |
36 | + </li> | |
37 | + <li> | |
38 | + <%= labelled_text_field(_('Server User'), 'profile_data[jenkins][user]', profile.jenkins[:user]) %> | |
39 | + </li> | |
40 | + <li> | |
41 | + <%= labelled_text_field(_('Server Private Token'), 'profile_data[jenkins][private_token]', profile.jenkins[:private_token]) %> | |
42 | + </li> | |
43 | + <li> | |
44 | + <%= labelled_text_field(_('Server Url'), 'profile_data[jenkins][url]', profile.jenkins[:url], {:disabled => true}) %> | |
45 | + </li> | |
46 | + | |
47 | + </ul> | |
48 | + | |
49 | +</div> | ... | ... |
plugins/serpro_integration/views/profile_design/sonar_plugin/_sonar_widget_block.rhtml
0 → 100644
plugins/serpro_integration/views/profile_editor/_gitlab.html.erb
0 → 100644
... | ... | @@ -0,0 +1,22 @@ |
1 | +<div class='option'> | |
2 | + <%= labelled_check_box(_('Uses Gitlab integration'), 'profile_data[allow_gitlab_integration]', true, profile.allow_gitlab_integration) %> | |
3 | +</div> | |
4 | + | |
5 | +<ul> | |
6 | + <h2> | |
7 | + <%= _('Gitlab Integration') %> | |
8 | + <%= link_to_remote _('Force'), :url => {:controller => 'serpro_integration_plugin_myprofile', :action => 'create_gitlab'} %> | |
9 | + | |
10 | + </h2> | |
11 | + <li> | |
12 | + <%= labelled_text_field(_('Server Host'), 'profile_data[gitlab][host]', profile.gitlab[:host]) %> | |
13 | + </li> | |
14 | + <li> | |
15 | + <%= labelled_text_field(_('User private token: '), 'profile_data[gitlab][private_token]', profile.gitlab[:private_token]) %> | |
16 | + </li> | |
17 | + <li> | |
18 | + <%= _('Erros: %s') % (profile.gitlab[:errors] || _('None')) %> | |
19 | + </li> | |
20 | + | |
21 | +</ul> | |
22 | + | ... | ... |
plugins/serpro_integration/views/sonar_widget_block.rhtml
0 → 100644
... | ... | @@ -0,0 +1,10 @@ |
1 | +<div class='widget'> | |
2 | + <% if block.is_widget_well_formed_url? %> | |
3 | + <iframe width='<%=block.widget_width%>' height='<%=block.widget_height%>' src='<%=block.widget_url%>' frameborder="0" allowfullscreen></iframe> | |
4 | + <% else %> | |
5 | + <div class='wrong'> | |
6 | + <iframe width='<%=block.widget_width%>' height='<%=block.widget_height%>' src='<%=block.widget_url%>' frameborder="0" allowfullscreen></iframe> | |
7 | + <%= _('Something wrong happened. Please see your sonar configuration.') %> | |
8 | + </div> | |
9 | + <% end %> | |
10 | +</div> | ... | ... |
test/fixtures/files/500.html
... | ... | @@ -0,0 +1,151 @@ |
1 | +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
2 | +<html xmlns="http://www.w3.org/1999/xhtml" > | |
3 | + <head> | |
4 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | |
5 | + <meta http-equiv="refresh" content="60"/> | |
6 | + <title>Technical problems</title> | |
7 | + <link rel="stylesheet" type="text/css" href="/designs/themes/default/errors.css"/> | |
8 | + <link rel="shortcut icon" href='/designs/themes/default/favicon.ico' type="image/x-icon" /> | |
9 | + <script type='text/javascript' src='/javascripts/prototype.js'></script> | |
10 | + <script type='text/javascript' src='/javascripts/errors.js'></script> | |
11 | +</head> | |
12 | +<body onload='display_error_message()'> | |
13 | + <div id='wrap'> | |
14 | + <div id='header'> | |
15 | + <div id='logo'> | |
16 | + | |
17 | + </div> | |
18 | + </div> | |
19 | + | |
20 | + | |
21 | + <div id='de' style='display: none' class='message'> | |
22 | + <h1>Kurzzeitiges Systemproblem</h1> | |
23 | + <p> | |
24 | + Unser technisches Team arbeitet gerade daran, bitte probieren Sie es nachher erneut. Wir entschuldigen uns für die Unannehmlichkeiten. | |
25 | + </p> | |
26 | + <ul> | |
27 | + <li><a href='javascript: history.back()'>Zurück</a></li> | |
28 | + <li><a href='/'>Gehe zur Homepage</a></li> | |
29 | + </ul> | |
30 | + </div> | |
31 | + | |
32 | + | |
33 | + <div id='en' style='display: none' class='message'> | |
34 | + <h1>Temporary system problem</h1> | |
35 | + <p> | |
36 | + Our technical team is working on it, please try again later. Sorry for the inconvenience. | |
37 | + </p> | |
38 | + <ul> | |
39 | + <li><a href='javascript: history.back()'>Go back</a></li> | |
40 | + <li><a href='/'>Go to the site home page</a></li> | |
41 | + </ul> | |
42 | + </div> | |
43 | + | |
44 | + | |
45 | + <div id='eo' style='display: none' class='message'> | |
46 | + <h1>Temporary system problem</h1> | |
47 | + <p> | |
48 | + Our technical team is working on it, please try again later. Sorry for the inconvenience. | |
49 | + </p> | |
50 | + <ul> | |
51 | + <li><a href='javascript: history.back()'>Go back</a></li> | |
52 | + <li><a href='/'>Go to the site home page</a></li> | |
53 | + </ul> | |
54 | + </div> | |
55 | + | |
56 | + | |
57 | + <div id='es' style='display: none' class='message'> | |
58 | + <h1>Problema temporal del sistema</h1> | |
59 | + <p> | |
60 | + Nuestro equipo técnico está trabajando en ello, por favor, inténtalo de nuevo más tarde. Disculpa las molestias. | |
61 | + </p> | |
62 | + <ul> | |
63 | + <li><a href='javascript: history.back()'>Regresar</a></li> | |
64 | + <li><a href='/'>Ir a la página de inicio del sitio</a></li> | |
65 | + </ul> | |
66 | + </div> | |
67 | + | |
68 | + | |
69 | + <div id='fr' style='display: none' class='message'> | |
70 | + <h1>Problème temporaire du système.</h1> | |
71 | + <p> | |
72 | + Notre équipe technique est en train d'y travailler. Merci de réessayer plus tard. Nous sommes désolés de la gêne occasionnée. | |
73 | + </p> | |
74 | + <ul> | |
75 | + <li><a href='javascript: history.back()'>Retour</a></li> | |
76 | + <li><a href='/'>Aller à la page d'accueil du site</a></li> | |
77 | + </ul> | |
78 | + </div> | |
79 | + | |
80 | + | |
81 | + <div id='hy' style='display: none' class='message'> | |
82 | + <h1>Temporary system problem</h1> | |
83 | + <p> | |
84 | + Our technical team is working on it, please try again later. Sorry for the inconvenience. | |
85 | + </p> | |
86 | + <ul> | |
87 | + <li><a href='javascript: history.back()'>Վերադառնալ</a></li> | |
88 | + <li><a href='/'>Go to the site home page</a></li> | |
89 | + </ul> | |
90 | + </div> | |
91 | + | |
92 | + | |
93 | + <div id='it' style='display: none' class='message'> | |
94 | + <h1>Temporary system problem</h1> | |
95 | + <p> | |
96 | + Our technical team is working on it, please try again later. Sorry for the inconvenience. | |
97 | + </p> | |
98 | + <ul> | |
99 | + <li><a href='javascript: history.back()'>Go back</a></li> | |
100 | + <li><a href='/'>Go to the site home page</a></li> | |
101 | + </ul> | |
102 | + </div> | |
103 | + | |
104 | + | |
105 | + <div id='pt' style='display: none' class='message'> | |
106 | + <h1>Problema temporário no sistema</h1> | |
107 | + <p> | |
108 | + Nossa equipe técnica está trabalhando nele, por favor tente mais tarde. Perdoe o incoveniente. | |
109 | + </p> | |
110 | + <ul> | |
111 | + <li><a href='javascript: history.back()'>Voltar</a></li> | |
112 | + <li><a href='/'>Ir para a página inicial do site.</a></li> | |
113 | + </ul> | |
114 | + </div> | |
115 | + | |
116 | + | |
117 | + <div id='ru' style='display: none' class='message'> | |
118 | + <h1>Временная ошибка системы</h1> | |
119 | + <p> | |
120 | + Техники уже работают над проблемой, пожалуйста, попробуйте позже. | |
121 | + </p> | |
122 | + <ul> | |
123 | + <li><a href='javascript: history.back()'>Назад</a></li> | |
124 | + <li><a href='/'>Перейти на домашнюю страницу сайта</a></li> | |
125 | + </ul> | |
126 | + </div> | |
127 | + | |
128 | + <div id='languages'> | |
129 | + | |
130 | + <a href="javascript: display_error_message('de')">Deutsch</a> | |
131 | + | |
132 | + <a href="javascript: display_error_message('en')">English</a> | |
133 | + | |
134 | + <a href="javascript: display_error_message('eo')">Esperanto</a> | |
135 | + | |
136 | + <a href="javascript: display_error_message('es')">Español</a> | |
137 | + | |
138 | + <a href="javascript: display_error_message('fr')">Français</a> | |
139 | + | |
140 | + <a href="javascript: display_error_message('hy')">հայերեն լեզու</a> | |
141 | + | |
142 | + <a href="javascript: display_error_message('it')">Italiano</a> | |
143 | + | |
144 | + <a href="javascript: display_error_message('pt')">Português</a> | |
145 | + | |
146 | + <a href="javascript: display_error_message('ru')">русский язык</a> | |
147 | + | |
148 | + </div> | |
149 | + </div> | |
150 | +</body> | |
151 | +</html> | ... | ... |
test/functional/profile_controller_test.rb
... | ... | @@ -474,17 +474,23 @@ class ProfileControllerTest < ActionController::TestCase |
474 | 474 | assert_equal "/profile/#{community.identifier}", @request.session[:previous_location] |
475 | 475 | end |
476 | 476 | |
477 | - should 'redirect to location before login after join community' do | |
477 | + should 'redirect to login after user not logged asks to join a community' do | |
478 | 478 | community = Community.create!(:name => 'my test community') |
479 | 479 | |
480 | - @request.expects(:referer).returns("/profile/#{community.identifier}/to_go") | |
481 | - login_as(profile.identifier) | |
480 | + get :join_not_logged, :profile => community.identifier | |
482 | 481 | |
483 | - post :join_not_logged, :profile => community.identifier | |
482 | + assert_equal community.identifier, @request.session[:join] | |
483 | + assert_redirected_to :controller => :account, :action => :login | |
484 | + end | |
484 | 485 | |
485 | - assert_redirected_to "/profile/#{community.identifier}/to_go" | |
486 | + should 'redirect to join after user logged asks to join_not_logged a community' do | |
487 | + community = Community.create!(:name => 'my test community') | |
488 | + | |
489 | + login_as(profile.identifier) | |
490 | + get :join_not_logged, :profile => community.identifier | |
486 | 491 | |
487 | - assert_nil @request.session[:previous_location] | |
492 | + assert_equal community.identifier, @request.session[:join] | |
493 | + assert_redirected_to :controller => :profile, :action => :join | |
488 | 494 | end |
489 | 495 | |
490 | 496 | should 'show number of published events in index' do |
... | ... | @@ -1186,7 +1192,7 @@ class ProfileControllerTest < ActionController::TestCase |
1186 | 1192 | 20.times {comment = fast_create(Comment, :source_id => article, :title => 'a comment', :body => 'lalala', :created_at => Time.now)} |
1187 | 1193 | article.reload |
1188 | 1194 | get :index, :profile => profile.identifier |
1189 | - assert_tag 'ul', :attributes => {:class => 'profile-wall-activities-comments'}, :children => {:count => 0 } | |
1195 | + assert_tag 'ul', :attributes => {:class => 'profile-wall-activities-comments'}, :children => {:count => 0 } | |
1190 | 1196 | end |
1191 | 1197 | |
1192 | 1198 | should "view more comments paginated" do |
... | ... | @@ -1212,7 +1218,7 @@ class ProfileControllerTest < ActionController::TestCase |
1212 | 1218 | 20.times {fast_create(Scrap, :sender_id => profile.id, :receiver_id => profile.id, :scrap_id => scrap.id)} |
1213 | 1219 | profile.reload |
1214 | 1220 | get :index, :profile => profile.identifier |
1215 | - assert_tag 'ul', :attributes => {:class => 'profile-wall-activities-comments scrap-replies'}, :children => {:count => 0 } | |
1221 | + assert_tag 'ul', :attributes => {:class => 'profile-wall-activities-comments scrap-replies'}, :children => {:count => 0 } | |
1216 | 1222 | end |
1217 | 1223 | |
1218 | 1224 | should "view more replies paginated" do |
... | ... | @@ -1269,15 +1275,6 @@ class ProfileControllerTest < ActionController::TestCase |
1269 | 1275 | assert_tag :tag => 'div', :content => /#{instance_eval(&plugin2.profile_tabs[:content])}/, :attributes => {:id => /#{plugin2.profile_tabs[:id]}/} |
1270 | 1276 | end |
1271 | 1277 | |
1272 | - should 'redirect to profile page when try to request join_not_logged via GET method' do | |
1273 | - community = Community.create!(:name => 'my test community') | |
1274 | - login_as(profile.identifier) | |
1275 | - get :join_not_logged, :profile => community.identifier | |
1276 | - assert_nothing_raised do | |
1277 | - assert_redirected_to community.url | |
1278 | - end | |
1279 | - end | |
1280 | - | |
1281 | 1278 | should 'check different profile from the domain profile' do |
1282 | 1279 | default = Environment.default |
1283 | 1280 | default.domains.create!(:name => 'environment.com') | ... | ... |
test/functional/profile_editor_controller_test.rb
... | ... | @@ -894,6 +894,23 @@ class ProfileEditorControllerTest < ActionController::TestCase |
894 | 894 | assert_tag :tag => 'input', :attributes => {:id => 'field_added_by_plugin', :value => 'value_of_field_added_by_plugin'} |
895 | 895 | end |
896 | 896 | |
897 | + should 'add extra content with block provided by plugins on edit' do | |
898 | + class TestProfileEditPlugin < Noosfero::Plugin | |
899 | + def profile_editor_extras | |
900 | + lambda do | |
901 | + render :text => "<input id='field_added_by_plugin' value='value_of_field_added_by_plugin'/>" | |
902 | + end | |
903 | + end | |
904 | + end | |
905 | + Noosfero::Plugin.stubs(:all).returns([TestProfileEditPlugin.to_s]) | |
906 | + | |
907 | + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestProfileEditPlugin.new]) | |
908 | + | |
909 | + get :edit, :profile => profile.identifier | |
910 | + | |
911 | + assert_tag :tag => 'input', :attributes => {:id => 'field_added_by_plugin', :value => 'value_of_field_added_by_plugin'} | |
912 | + end | |
913 | + | |
897 | 914 | should 'show image upload field from profile editor' do |
898 | 915 | env = Environment.default |
899 | 916 | env.custom_person_fields = { } | ... | ... |