Commit 3ce46bb6b85c5c1b001c3ee576b557255c40564b
Exists in
master
and in
20 other branches
Merge branch 'noosfero' into rails4
Showing
46 changed files
with
2126 additions
and
45 deletions
Show diff stats
.travis.yml
app/mailers/mailing.rb
1 | -require 'mailing_job' | |
1 | +require_dependency 'mailing_job' | |
2 | 2 | |
3 | 3 | class Mailing < ActiveRecord::Base |
4 | 4 | |
... | ... | @@ -40,10 +40,8 @@ class Mailing < ActiveRecord::Base |
40 | 40 | begin |
41 | 41 | Mailing::Sender.notification(self, recipient.email).deliver |
42 | 42 | self.mailing_sents.create(:person => recipient) |
43 | - rescue Exception | |
44 | - # FIXME should not discard errors silently. An idea is to collect all | |
45 | - # errors and generate a task (notification) for the +source+ | |
46 | - # (environment/organization) listing these errors. | |
43 | + rescue Exception => ex | |
44 | + Rails.logger.error("#{ex.class.to_s} - #{ex.to_s} at #{__FILE__}:#{__LINE__}") | |
47 | 45 | end |
48 | 46 | end |
49 | 47 | end | ... | ... |
app/models/add_friend.rb
... | ... | @@ -14,8 +14,8 @@ class AddFriend < Task |
14 | 14 | alias :friend :target |
15 | 15 | alias :friend= :target= |
16 | 16 | |
17 | - validates :requestor, :kind_of => { :kind => Person } | |
18 | - validates :target, :kind_of => { :kind => Person } | |
17 | + validates :requestor, :kind_of => { :kind => Person } | |
18 | + validates :target, :kind_of => { :kind => Person } | |
19 | 19 | |
20 | 20 | after_create do |task| |
21 | 21 | TaskMailer.invitation_notification(task).deliver unless task.friend | ... | ... |
app/models/community.rb
1 | 1 | class Community < Organization |
2 | 2 | |
3 | - attr_accessible :accessor_id, :accessor_type, :role_id, :resource_id, :resource_type, :address_reference, :district, :tag_list, :language | |
3 | + attr_accessible :accessor_id, :accessor_type, :role_id, :resource_id, :resource_type | |
4 | + attr_accessible :address_reference, :district, :tag_list, :language, :description | |
4 | 5 | after_destroy :check_invite_member_for_destroy |
5 | 6 | |
6 | 7 | def self.type_name | ... | ... |
app/models/create_community.rb
... | ... | @@ -9,11 +9,15 @@ class CreateCommunity < Task |
9 | 9 | alias :environment :target |
10 | 10 | alias :environment= :target= |
11 | 11 | |
12 | + attr_accessible :environment, :requestor, :target | |
13 | + attr_accessible :reject_explanation, :template_id | |
14 | + | |
12 | 15 | acts_as_having_image |
13 | 16 | |
14 | - DATA_FIELDS = Community.fields + ['name', 'closed'] | |
17 | + DATA_FIELDS = Community.fields + ['name', 'closed', 'description'] | |
15 | 18 | DATA_FIELDS.each do |field| |
16 | 19 | settings_items field.to_sym |
20 | + attr_accessible field.to_sym | |
17 | 21 | end |
18 | 22 | |
19 | 23 | def validate | ... | ... |
app/models/event.rb
app/models/textile_article.rb
app/views/mailing/sender/notification.html.erb
config/schedule.rb
... | ... | @@ -28,3 +28,15 @@ end |
28 | 28 | every 30.days do |
29 | 29 | runner "ProfileSuggestion.generate_all_profile_suggestions" |
30 | 30 | end |
31 | + | |
32 | +# Loads "schedule.rb" files from plugins | |
33 | +# | |
34 | +# Allows Noosfero's plugins schedule jobs using `whenever` Ruby gem the same | |
35 | +# way we do here, just create the file "config/schedule.rb" into the plugin | |
36 | +# root directory and write jobs using the same syntax used here (see example in | |
37 | +# the `newsletter` plugin) | |
38 | + | |
39 | +Dir.glob("config/plugins/*/config/schedule.rb").each do |filename| | |
40 | + filecontent = IO.read(filename) | |
41 | + instance_eval(Whenever::NumericSeconds.process_string(filecontent), filename) | |
42 | +end | ... | ... |
features/create_community.feature
... | ... | @@ -39,44 +39,47 @@ Feature: create community |
39 | 39 | Then I should see "Creating new community" |
40 | 40 | |
41 | 41 | Scenario: environment admin receive a task when a user creates a community |
42 | - Given I am logged in as admin | |
42 | + Given I am logged in as "joaosilva" | |
43 | 43 | And feature "admin_must_approve_new_communities" is enabled on environment |
44 | - When I create community "Community for approval" | |
44 | + Given "joaosilva" creates the community "Community for approval" | |
45 | + Given I am logged in as admin | |
45 | 46 | And I go to admin_user's control panel |
46 | - Then I should see "admin_user wants to create community Community for approval" | |
47 | + Then I should see "Joao Silva wants to create community Community for approval" | |
47 | 48 | |
48 | 49 | Scenario: environment admin accepts new community task |
49 | - Given I am logged in as admin | |
50 | + Given I am logged in as "joaosilva" | |
50 | 51 | And feature "admin_must_approve_new_communities" is enabled on environment |
51 | - When I create community "Community for approval" | |
52 | + Given "joaosilva" creates the community "Community for approval" | |
53 | + Given I am logged in as admin | |
52 | 54 | And I go to admin_user's control panel |
53 | 55 | And I follow "Process requests" |
54 | - And I should see "admin_user wants to create community Community for approval" | |
56 | + And I should see "Joao Silva wants to create community Community for approval" | |
55 | 57 | And I choose "Accept" |
56 | 58 | When I press "Apply!" |
57 | - Then I should not see "admin_user wants to create community Community for approval" | |
58 | - And I go to admin_user's control panel | |
59 | + Then I should not see "Joao Silva wants to create community Community for approval" | |
60 | + And I go to joaosilva's control panel | |
59 | 61 | And I follow "Manage my groups" |
60 | 62 | Then I should see "Community for approval" |
61 | 63 | |
62 | 64 | Scenario: environment admin rejects new community task |
63 | - Given I am logged in as admin | |
65 | + Given I am logged in as "joaosilva" | |
64 | 66 | And feature "admin_must_approve_new_communities" is enabled on environment |
65 | - When I create community "Community for approval" | |
67 | + Given "joaosilva" creates the community "Community for approval" | |
68 | + Given I am logged in as admin | |
66 | 69 | And I go to admin_user's control panel |
67 | 70 | And I follow "Process requests" |
68 | - And I should see "admin_user wants to create community Community for approval" | |
71 | + And I should see "Joao Silva wants to create community Community for approval" | |
69 | 72 | And I choose "Reject" |
70 | 73 | When I press "Apply!" |
71 | - Then I should not see "admin_user wants to create community Community for approval" | |
72 | - And I go to admin_user's control panel | |
74 | + Then I should not see "Joao Silva wants to create community Community for approval" | |
75 | + And I go to joaosilva's control panel | |
73 | 76 | And I follow "Manage my groups" |
74 | 77 | Then I should not see "Community for approval" |
75 | 78 | |
76 | 79 | Scenario: new community is listed after approval |
77 | 80 | Given I am logged in as admin |
78 | 81 | And feature "admin_must_approve_new_communities" is enabled on environment |
79 | - When I create community "Community for approval" | |
82 | + Given "admin_user" creates the community "Community for approval" | |
80 | 83 | And I approve community "Community for approval" |
81 | 84 | And I go to admin_user's control panel |
82 | 85 | And I follow "Manage my groups" |
... | ... | @@ -85,8 +88,9 @@ Feature: create community |
85 | 88 | Scenario: new community is not listed after rejection |
86 | 89 | Given I am logged in as admin |
87 | 90 | And feature "admin_must_approve_new_communities" is enabled on environment |
88 | - When I create community "Community for approval" | |
91 | + Given "admin_user" creates the community "Community for approval" | |
89 | 92 | And I reject community "Community for approval" |
90 | 93 | And I go to admin_user's control panel |
91 | 94 | And I follow "Manage my groups" |
92 | 95 | Then I should not see "Community for approval" |
96 | + | ... | ... |
features/step_definitions/create_community_steps.rb
... | ... | @@ -8,6 +8,14 @@ Given /^I create community "(.+)"$/ do |community| |
8 | 8 | click_button("Create") |
9 | 9 | end |
10 | 10 | |
11 | +Given /^"(.+)" creates the community "(.+)"$/ do |username, community| | |
12 | + When %{I go to #{username}'s control panel} | |
13 | + click_link('Manage my groups') | |
14 | + click_link('Create a new community') | |
15 | + fill_in("Name", :with => community) | |
16 | + click_button("Create") | |
17 | +end | |
18 | + | |
11 | 19 | Given /^I approve community "(.+)"$/ do |community| |
12 | 20 | task = CreateCommunity.all.select {|c| c.name == community}.first |
13 | 21 | step %{I go to admin_user's control panel} | ... | ... |
lib/acts_as_having_image.rb
... | ... | @@ -5,7 +5,8 @@ module ActsAsHavingImage |
5 | 5 | belongs_to :image, dependent: :destroy |
6 | 6 | scope :with_image, -> { where "#{table_name}.image_id IS NOT NULL" } |
7 | 7 | scope :without_image, -> { where "#{table_name}.image_id IS NULL" } |
8 | - self.send(:include, ActsAsHavingImage) | |
8 | + attr_accessible :image_builder | |
9 | + include ActsAsHavingImage | |
9 | 10 | end |
10 | 11 | end |
11 | 12 | ... | ... |
plugins/newsletter/controllers/newsletter_plugin_admin_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,48 @@ |
1 | +class NewsletterPluginAdminController < PluginAdminController | |
2 | + | |
3 | + def index | |
4 | + @newsletter = NewsletterPlugin::Newsletter.where(environment_id: environment.id).first_or_initialize | |
5 | + | |
6 | + if request.post? | |
7 | + # token input gives the param as a comma separated string | |
8 | + params[:newsletter][:blog_ids] = (params[:newsletter][:blog_ids] || '').split(',') | |
9 | + | |
10 | + params[:newsletter][:person_id] = user.id | |
11 | + | |
12 | + file = params[:file] | |
13 | + if file && file[:recipients].present? | |
14 | + @newsletter.import_recipients(file[:recipients], file[:name], file[:email], file[:headers].present?) | |
15 | + end | |
16 | + | |
17 | + if !@newsletter.errors.any? && @newsletter.update_attributes(params[:newsletter]) | |
18 | + if params['visualize'] | |
19 | + @message = @newsletter.body | |
20 | + render :file => 'mailing/sender/notification', :layout => false | |
21 | + else | |
22 | + session[:notice] = _('Newsletter updated.') | |
23 | + end | |
24 | + else | |
25 | + session[:notice] = _('Newsletter could not be saved.') | |
26 | + end | |
27 | + end | |
28 | + | |
29 | + @blogs = Blog.includes(:profile).find_all_by_id(@newsletter.blog_ids) | |
30 | + end | |
31 | + | |
32 | + #TODO: Make this query faster | |
33 | + def search_communities | |
34 | + communities = environment.communities | |
35 | + blogs = Blog.joins(:profile).where(profiles: {environment_id: environment.id}) | |
36 | + | |
37 | + found_communities = find_by_contents(:communities, environment, communities, params['q'], {:page => 1})[:results] | |
38 | + found_blogs = find_by_contents(:blogs, environment, blogs, params['q'], {:page => 1})[:results] | |
39 | + | |
40 | + results = (found_blogs + found_communities.map(&:blogs).flatten).uniq | |
41 | + render :text => results.map { |blog| {:id => blog.id, :name => _("%s in %s") % [blog.name, blog.profile.name]} }.to_json | |
42 | + end | |
43 | + | |
44 | + def recipients | |
45 | + @additional_recipients = NewsletterPlugin::Newsletter.where(environment_id: environment.id).first_or_initialize.additional_recipients | |
46 | + end | |
47 | + | |
48 | +end | ... | ... |
plugins/newsletter/controllers/newsletter_plugin_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,24 @@ |
1 | +class NewsletterPluginController < PublicController | |
2 | + | |
3 | + before_filter :login_required, :only => :confirm_unsubscription | |
4 | + | |
5 | + def mailing | |
6 | + if NewsletterPlugin::NewsletterMailing.exists?(params[:id]) | |
7 | + mailing = NewsletterPlugin::NewsletterMailing.find(params[:id]) | |
8 | + @message = mailing.body | |
9 | + render :file => 'mailing/sender/notification', :layout => false | |
10 | + else | |
11 | + render :action => 'mailing_not_found' | |
12 | + end | |
13 | + end | |
14 | + | |
15 | + def confirm_unsubscription | |
16 | + if request.post? | |
17 | + session[:notice] = _('You was unsubscribed from newsletter.') | |
18 | + @newsletter = NewsletterPlugin::Newsletter.where(environment_id: environment.id).first | |
19 | + @newsletter.unsubscribe(current_user.email) | |
20 | + redirect_to :controller => :home | |
21 | + end | |
22 | + end | |
23 | + | |
24 | +end | ... | ... |
plugins/newsletter/db/migrate/20150717195546_newsletter_plugin_newsletters.rb
0 → 100644
... | ... | @@ -0,0 +1,24 @@ |
1 | +class NewsletterPluginNewsletters < ActiveRecord::Migration | |
2 | + def up | |
3 | + create_table :newsletter_plugin_newsletters do |t| | |
4 | + t.references :environment, :null => false | |
5 | + t.references :person, :null => false | |
6 | + t.boolean :enabled, :default => false | |
7 | + t.string :subject | |
8 | + t.integer :periodicity, :default => 0 | |
9 | + t.integer :posts_per_blog, :default => 0 | |
10 | + t.integer :image_id | |
11 | + t.text :footer | |
12 | + t.text :blog_ids | |
13 | + t.text :additional_recipients | |
14 | + t.boolean :moderated | |
15 | + t.text :unsubscribers | |
16 | + end | |
17 | + add_index :newsletter_plugin_newsletters, :environment_id, :uniq => true | |
18 | + end | |
19 | + | |
20 | + def down | |
21 | + remove_index :newsletter_plugin_newsletters, :environment_id | |
22 | + drop_table :newsletter_plugin_newsletters | |
23 | + end | |
24 | +end | ... | ... |
... | ... | @@ -0,0 +1,40 @@ |
1 | +Feature: newsletter plugin | |
2 | + | |
3 | + Background: | |
4 | + Given the following users | |
5 | + | login | name | | |
6 | + | joaosilva | Joao Silva | | |
7 | + And I am logged in as "joaosilva" | |
8 | + | |
9 | + Scenario: as admin I can configure plugin | |
10 | + Given I am logged in as admin | |
11 | + When I go to the environment control panel | |
12 | + And I follow "Plugins" | |
13 | + Then I should see "Configuration" linking to "/admin/plugin/newsletter" | |
14 | + | |
15 | + Scenario: in the newsletter settings I can see the field to enable/disable | |
16 | + Given I am logged in as admin | |
17 | + When I go to the environment control panel | |
18 | + And I follow "Plugins" | |
19 | + And I follow "Configuration" | |
20 | + Then I should see "Enable send of newsletter to members on this environment" | |
21 | + | |
22 | + Scenario: redirect to newsletter visualization after save and visualize | |
23 | + Given I am logged in as admin | |
24 | + And "NewsletterPlugin" plugin is enabled | |
25 | + When I go to the environment control panel | |
26 | + And I follow "Plugins" | |
27 | + And I follow "Configuration" | |
28 | + And I press "Save and visualize" | |
29 | + Then I should see "If you can't view this email, click here" | |
30 | + And I should not see "Newsletter settings" | |
31 | + | |
32 | + Scenario: stay on newsletter settings page after save | |
33 | + Given I am logged in as admin | |
34 | + And "NewsletterPlugin" plugin is enabled | |
35 | + When I go to the environment control panel | |
36 | + And I follow "Plugins" | |
37 | + And I follow "Configuration" | |
38 | + And I press "Save" | |
39 | + Then I should see "Newsletter settings" | |
40 | + And I should not see "If you can't view this email, click here" | ... | ... |
... | ... | @@ -0,0 +1,41 @@ |
1 | +class NewsletterPlugin < Noosfero::Plugin | |
2 | + | |
3 | + def self.plugin_name | |
4 | + "Newsletter" | |
5 | + end | |
6 | + | |
7 | + def self.plugin_description | |
8 | + _("Periodically sends newsletter via email to network users") | |
9 | + end | |
10 | + | |
11 | + def js_files | |
12 | + 'newsletter_plugin.js' | |
13 | + end | |
14 | + | |
15 | + def stylesheet? | |
16 | + true | |
17 | + end | |
18 | + | |
19 | + def self.compile_and_send_newsletters | |
20 | + NewsletterPlugin::Newsletter.enabled.each do |newsletter| | |
21 | + if newsletter.must_be_sent_today? && newsletter.has_posts_in_the_period? | |
22 | + if newsletter.moderated | |
23 | + NewsletterPlugin::ModerateNewsletter.create!( | |
24 | + :newsletter_id => newsletter.id, | |
25 | + :environment => newsletter.environment | |
26 | + ) | |
27 | + else | |
28 | + mailing = NewsletterPlugin::NewsletterMailing.create!( | |
29 | + :source => newsletter, | |
30 | + :subject => newsletter.subject, | |
31 | + :body => newsletter.body, | |
32 | + :person => newsletter.person, | |
33 | + :locale => newsletter.environment.default_locale, | |
34 | + ) | |
35 | + mailing.update_attribute(:body, mailing.body.gsub('{mailing_url}', mailing.url)) | |
36 | + end | |
37 | + end | |
38 | + end | |
39 | + end | |
40 | + | |
41 | +end | ... | ... |
plugins/newsletter/lib/newsletter_plugin/moderate_newsletter.rb
0 → 100644
... | ... | @@ -0,0 +1,53 @@ |
1 | +class NewsletterPlugin::ModerateNewsletter < Task | |
2 | + | |
3 | + settings_items :newsletter_id, :post_ids | |
4 | + validates_presence_of :newsletter_id | |
5 | + | |
6 | + alias :environment :target | |
7 | + alias :environment= :target= | |
8 | + | |
9 | + def perform | |
10 | + newsletter = NewsletterPlugin::Newsletter.find(newsletter_id) | |
11 | + self.post_ids ||= [] | |
12 | + mailing = NewsletterPlugin::NewsletterMailing.create!( | |
13 | + :source => newsletter, | |
14 | + :subject => newsletter.subject, | |
15 | + :body => newsletter.body(:post_ids => self.post_ids.reject{|id| id.to_i.zero?}), | |
16 | + :person => newsletter.person, | |
17 | + :locale => newsletter.environment.default_locale, | |
18 | + ) | |
19 | + mailing.update_attribute(:body, mailing.body.gsub('{mailing_url}', mailing.url)) | |
20 | + end | |
21 | + | |
22 | + def title | |
23 | + _("Moderate newsletter") | |
24 | + end | |
25 | + | |
26 | + def subject | |
27 | + nil | |
28 | + end | |
29 | + | |
30 | + def linked_subject | |
31 | + nil | |
32 | + end | |
33 | + | |
34 | + def information | |
35 | + {:message => _('You have to moderate a newsletter.') } | |
36 | + end | |
37 | + | |
38 | + def accept_details | |
39 | + true | |
40 | + end | |
41 | + | |
42 | + def icon | |
43 | + {:type => :defined_image, :src => "/images/control-panel/email.png", :name => 'Newsletter'} | |
44 | + end | |
45 | + | |
46 | + def target_notification_message | |
47 | + _('A newsletter was generated and you need to review it before it is sent to users.') | |
48 | + end | |
49 | + | |
50 | + def target_notification_description | |
51 | + _('You need to moderate a newsletter.') | |
52 | + end | |
53 | +end | ... | ... |
... | ... | @@ -0,0 +1,191 @@ |
1 | +require 'csv' | |
2 | + | |
3 | +class NewsletterPlugin::Newsletter < Noosfero::Plugin::ActiveRecord | |
4 | + | |
5 | + belongs_to :environment | |
6 | + belongs_to :person | |
7 | + validates_presence_of :environment, :person | |
8 | + validates_uniqueness_of :environment_id | |
9 | + validates_numericality_of :periodicity, only_integer: true, greater_than: -1, message: _('must be a positive number') | |
10 | + validates_numericality_of :posts_per_blog, only_integer: true, greater_than: -1, message: _('must be a positive number') | |
11 | + | |
12 | + attr_accessible :environment, :enabled, :periodicity, :subject, :posts_per_blog, :footer, :blog_ids, :additional_recipients, :person, :person_id, :moderated | |
13 | + | |
14 | + scope :enabled, :conditions => { :enabled => true } | |
15 | + | |
16 | + # These methods are used by NewsletterMailing | |
17 | + def people | |
18 | + list = unsubscribers.map{|i| "'#{i}'"}.join(',') | |
19 | + if list.empty? | |
20 | + environment.people | |
21 | + else | |
22 | + environment.people.all( | |
23 | + :joins => "LEFT OUTER JOIN users ON (users.id = profiles.user_id)", | |
24 | + :conditions => "users.email NOT IN (#{list})" | |
25 | + ) | |
26 | + end | |
27 | + end | |
28 | + | |
29 | + def name | |
30 | + environment.name | |
31 | + end | |
32 | + | |
33 | + def contact_email | |
34 | + environment.noreply_email | |
35 | + end | |
36 | + | |
37 | + def top_url | |
38 | + environment.top_url | |
39 | + end | |
40 | + | |
41 | + def unsubscribe_url | |
42 | + "#{top_url}/plugin/newsletter/unsubscribe" | |
43 | + end | |
44 | + | |
45 | + serialize :blog_ids, Array | |
46 | + serialize :additional_recipients, Array | |
47 | + | |
48 | + def blog_ids | |
49 | + self[:blog_ids].map(&:to_i) || [] | |
50 | + end | |
51 | + | |
52 | + validates_each :blog_ids do |record, attr, value| | |
53 | + if record.environment | |
54 | + unless value.delete_if(&:zero?).select { |id| !Blog.find_by_id(id) || Blog.find(id).environment != record.environment }.empty? | |
55 | + record.errors.add(attr, _('must be valid')) | |
56 | + end | |
57 | + end | |
58 | + unless value.uniq.length == value.length | |
59 | + record.errors.add(attr, _('must not have duplicates')) | |
60 | + end | |
61 | + end | |
62 | + | |
63 | + validates_each :additional_recipients do |record, attr, value| | |
64 | + unless value.reject { |recipient| recipient[:email] =~ Noosfero::Constants::EMAIL_FORMAT }.empty? | |
65 | + record.errors.add(attr, _('must have only valid emails')) | |
66 | + end | |
67 | + end | |
68 | + | |
69 | + def next_send_at | |
70 | + (self.last_send_at || DateTime.now) + self.periodicity.days | |
71 | + end | |
72 | + | |
73 | + def must_be_sent_today? | |
74 | + return true unless self.last_send_at | |
75 | + Date.today >= self.next_send_at.to_date | |
76 | + end | |
77 | + | |
78 | + def blogs | |
79 | + Blog.where(:id => blog_ids) | |
80 | + end | |
81 | + | |
82 | + def posts(data = {}) | |
83 | + limit = self.posts_per_blog.zero? ? nil : self.posts_per_blog | |
84 | + posts = if self.last_send_at.nil? | |
85 | + self.blogs.map{|blog| blog.posts.all(:limit => limit)}.flatten | |
86 | + else | |
87 | + self.blogs.map{|blog| blog.posts.where("published_at >= :last_send_at", {last_send_at: self.last_send_at}).all(:limit => limit)}.flatten | |
88 | + end | |
89 | + data[:post_ids].nil? ? posts : posts.select{|post| data[:post_ids].include?(post.id.to_s)} | |
90 | + end | |
91 | + | |
92 | + CSS = { | |
93 | + 'breakingnews-wrap' => 'background-color: #EFEFEF; padding: 40px 0', | |
94 | + 'breakingnews' => 'width: 640px; margin: auto; background-color: white; border: 1px solid #ddd; border-spacing: 0; padding: 0', | |
95 | + 'newsletter-public-link' => 'width: 640px; margin: auto; font-size: small; color: #555; font-style: italic; text-align: right; margin-bottom: 15px; font-family: sans;', | |
96 | + 'newsletter-header' => 'padding: 0', | |
97 | + 'header-image' => 'width: 100%', | |
98 | + 'post-image' => 'padding-left: 20px; width: 25%; border-bottom: 1px dashed #DDD', | |
99 | + 'post-info' => 'font-family: Arial, Verdana; padding: 20px; width: 75%; border-bottom: 1px dashed #DDD', | |
100 | + 'post-date' => 'font-size: 12px;', | |
101 | + 'post-lead' => 'font-size: 14px; text-align: justify', | |
102 | + 'post-title' => 'color: #000; text-decoration: none; font-size: 16px; text-align: justify', | |
103 | + 'read-more-line' => 'text-align: right', | |
104 | + 'read-more-link' => 'color: #000; font-size: 12px;', | |
105 | + 'newsletter-unsubscribe' => 'width: 640px; margin: auto; font-size: small; color: #555; font-style: italic; text-align: center; margin-top: 15px; font-family: sans;' | |
106 | + } | |
107 | + | |
108 | + # to be able to generate HTML | |
109 | + include ActionView::Helpers | |
110 | + include Rails.application.routes.url_helpers | |
111 | + include DatesHelper | |
112 | + | |
113 | + def message_to_public_link | |
114 | + content_tag(:p, N_("If you can't view this email, %s.") % link_to(N_('click here'), '{mailing_url}'), :id => 'newsletter-public-link') | |
115 | + end | |
116 | + | |
117 | + def message_to_unsubscribe | |
118 | + content_tag(:div, N_("This is an automatically generated email, please do not reply. If you do not wish to receive future newsletter emails, %s.") % link_to(N_("cancel your subscription here"), self.unsubscribe_url, :style => CSS['public-link']), :style => CSS['newsletter-unsubscribe'], :id => 'newsletter-unsubscribe') | |
119 | + end | |
120 | + | |
121 | + def read_more(link_address) | |
122 | + content_tag(:p, link_to(N_('Read more'), link_address, :style => CSS['read-more-link']), :style => CSS['read-more-line']) | |
123 | + end | |
124 | + | |
125 | + def post_with_image(post) | |
126 | + content_tag(:tr,content_tag(:td,tag(:img, :src => "#{self.environment.top_url}#{post.image.public_filename(:big)}", :id => post.id),:style => CSS['post-image'])+content_tag(:td,content_tag(:span, show_date(post.published_at), :style => CSS['post-date'])+content_tag(:h3, link_to(h(post.title), post.url, :style => CSS['post-title']))+content_tag(:p,sanitize(post.lead(190)),:style => CSS['post-lead'])+read_more(post.url), :style => CSS['post-info'])) | |
127 | + end | |
128 | + | |
129 | + def post_without_image(post) | |
130 | + content_tag(:tr, content_tag(:td,content_tag(:span, show_date(post.published_at),:style => CSS['post-date'], :id => post.id)+content_tag(:h3, link_to(h(post.title), post.url,:style => CSS['post-title']))+content_tag(:p,sanitize(post.lead(360)),:style => CSS['post-lead'])+read_more(post.url),:colspan => 2, :style => CSS['post-info'])) | |
131 | + end | |
132 | + | |
133 | + def body(data = {}) | |
134 | + content_tag(:div, content_tag(:div, message_to_public_link, :style => CSS['newsletter-public-link'])+content_tag(:table,(self.image.nil? ? '' : content_tag(:tr, content_tag(:th, tag(:img, :src => "#{self.environment.top_url}#{self.image.public_filename}", :style => CSS['header-image']),:colspan => 2),:style => CSS['newsletter-header']))+self.posts(data).map do |post| | |
135 | + if post.image | |
136 | + post_with_image(post) | |
137 | + else | |
138 | + post_without_image(post) | |
139 | + end | |
140 | + end.join()+content_tag(:tr, content_tag(:td, self.footer, :colspan => 2)),:style => CSS['breakingnews'])+content_tag(:div,message_to_unsubscribe, :style => CSS['newsletter-unsubscribe']),:style => CSS['breakingnews-wrap']) | |
141 | + end | |
142 | + | |
143 | + def default_subject | |
144 | + N_('Breaking news') | |
145 | + end | |
146 | + | |
147 | + def subject | |
148 | + self[:subject] || default_subject | |
149 | + end | |
150 | + | |
151 | + def import_recipients(file, name_column = nil, email_column = nil, headers = nil) | |
152 | + name_column ||= 1 | |
153 | + email_column ||= 2 | |
154 | + headers ||= false | |
155 | + | |
156 | + if File.extname(file.original_filename) == '.csv' | |
157 | + parsed_recipients = [] | |
158 | + CSV.foreach(file.path, headers: headers) do |row| | |
159 | + parsed_recipients << {name: row[name_column.to_i - 1], email: row[email_column.to_i - 1]} | |
160 | + end | |
161 | + self.additional_recipients = parsed_recipients | |
162 | + else | |
163 | + #FIXME find a better way to deal with errors | |
164 | + self.errors.add(:additional_recipients, _("have unknown file type: %s" % file.original_filename)) | |
165 | + end | |
166 | + end | |
167 | + | |
168 | + acts_as_having_image | |
169 | + | |
170 | + def last_send_at | |
171 | + last_mailing = NewsletterPlugin::NewsletterMailing.last( | |
172 | + :conditions => {:source_id => self.id} | |
173 | + ) | |
174 | + last_mailing.nil? ? nil : last_mailing.created_at | |
175 | + end | |
176 | + | |
177 | + def sanitize(html) | |
178 | + html.gsub(/<\/?p>/, '') | |
179 | + end | |
180 | + | |
181 | + def has_posts_in_the_period? | |
182 | + ! self.posts.empty? | |
183 | + end | |
184 | + | |
185 | + serialize :unsubscribers, Array | |
186 | + | |
187 | + def unsubscribe(email) | |
188 | + unsubscribers.push(email).uniq! | |
189 | + end | |
190 | + | |
191 | +end | ... | ... |
plugins/newsletter/lib/newsletter_plugin/newsletter_mailing.rb
0 → 100644
... | ... | @@ -0,0 +1,26 @@ |
1 | +class NewsletterPlugin::NewsletterMailing < EnvironmentMailing | |
2 | + | |
3 | + attr_accessible :source, :person, :locale | |
4 | + | |
5 | + validates_presence_of :person | |
6 | + | |
7 | + def url | |
8 | + "#{self.source.top_url}/plugin/newsletter/mailing/#{self.id}" | |
9 | + end | |
10 | + | |
11 | + def source | |
12 | + NewsletterPlugin::Newsletter.find(source_id) | |
13 | + end | |
14 | + | |
15 | + def deliver | |
16 | + source.additional_recipients.each do |recipient| | |
17 | + begin | |
18 | + Mailing::Sender.notification(self, recipient[:email]).deliver | |
19 | + rescue Exception => ex | |
20 | + Rails.logger.error("#{ex.class.to_s} - #{ex.to_s} at #{__FILE__}:#{__LINE__}") | |
21 | + end | |
22 | + end | |
23 | + super | |
24 | + end | |
25 | + | |
26 | +end | ... | ... |
... | ... | @@ -0,0 +1,21 @@ |
1 | +jQuery(function($) { | |
2 | + $(".newsletter-toggle-link").live('click', function(){ | |
3 | + element_id = this.getAttribute('element_id'); | |
4 | + toggle_link = this; | |
5 | + $(element_id).slideToggle(400, function() { | |
6 | + if ($(toggle_link).find('.ui-icon').hasClass('ui-icon-triangle-1-s')) | |
7 | + $(toggle_link).find('.ui-icon') | |
8 | + .removeClass('ui-icon-triangle-1-s') | |
9 | + .addClass('ui-icon-triangle-1-n'); | |
10 | + else | |
11 | + $(toggle_link).find('.ui-icon') | |
12 | + .removeClass('ui-icon-triangle-1-n') | |
13 | + .addClass('ui-icon-triangle-1-s'); | |
14 | + }); | |
15 | + return false; | |
16 | + }); | |
17 | + | |
18 | + $('#file_recipients').change(function(){ | |
19 | + $('#newsletter-file-options input').enable(); | |
20 | + }); | |
21 | +}); | ... | ... |
... | ... | @@ -0,0 +1,24 @@ |
1 | +.newsletter-toggle-link { | |
2 | + cursor: pointer; | |
3 | +} | |
4 | +#newsletter-footer-field { | |
5 | + display: none; | |
6 | +} | |
7 | +#newsletter-enabled-field input#settings_enabled { | |
8 | + margin-right: 6px; | |
9 | +} | |
10 | + | |
11 | +#newsletter-moderation-preview #newsletter-public-link, | |
12 | +#newsletter-moderation-preview #newsletter-unsubscribe { | |
13 | + display: none; | |
14 | +} | |
15 | + | |
16 | +#newsletter-moderation-preview { | |
17 | + margin-left: 25px; | |
18 | +} | |
19 | + | |
20 | +#newsletter-moderation-preview input[type=checkbox] { | |
21 | + margin-left: -27px; | |
22 | + margin-top: 16px; | |
23 | + float: left; | |
24 | +} | ... | ... |
plugins/newsletter/test/functional/newsletter_plugin_admin_controller_test.rb
0 → 100644
... | ... | @@ -0,0 +1,176 @@ |
1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | |
2 | + | |
3 | +class NewsletterPluginAdminControllerTest < ActionController::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @controller = NewsletterPluginAdminController.new | |
7 | + @request = ActionController::TestRequest.new | |
8 | + @response = ActionController::TestResponse.new | |
9 | + | |
10 | + @admin = create_user('admin_newsletter').person | |
11 | + @environment = @admin.environment | |
12 | + @environment.add_admin(@admin) | |
13 | + | |
14 | + @environment.enable_plugin(NewsletterPlugin) | |
15 | + @controller.stubs(:environment).returns(@environment) | |
16 | + end | |
17 | + | |
18 | + should 'allow access to admin' do | |
19 | + login_as @admin.identifier | |
20 | + get :index | |
21 | + assert_response :success | |
22 | + end | |
23 | + | |
24 | + should 'save footer setting' do | |
25 | + login_as @admin.identifier | |
26 | + post :index, | |
27 | + :newsletter => { :footer => 'footer of newsletter' } | |
28 | + | |
29 | + assert_equal 'footer of newsletter', assigns(:newsletter).footer | |
30 | + end | |
31 | + | |
32 | + | |
33 | + should 'save header image' do | |
34 | + login_as @admin.identifier | |
35 | + post :index, | |
36 | + :newsletter => { | |
37 | + :image_builder => { | |
38 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | |
39 | + } | |
40 | + } | |
41 | + assert_equal 'rails.png', assigns(:newsletter).image.filename | |
42 | + end | |
43 | + | |
44 | + should 'save enabled newsletter information' do | |
45 | + login_as @admin.identifier | |
46 | + post :index, | |
47 | + :newsletter => { :enabled => 'true' } | |
48 | + | |
49 | + newsletter = NewsletterPlugin::Newsletter.find_by_environment_id(@environment.id) | |
50 | + | |
51 | + assert newsletter.enabled | |
52 | + end | |
53 | + | |
54 | + should 'save periodicity newsletter information' do | |
55 | + login_as @admin.identifier | |
56 | + post :index, | |
57 | + :newsletter => { :periodicity => '10' } | |
58 | + | |
59 | + newsletter = NewsletterPlugin::Newsletter.find_by_environment_id(@environment.id) | |
60 | + | |
61 | + assert_equal 10, newsletter.periodicity | |
62 | + end | |
63 | + | |
64 | + should 'save number of posts per blog setting' do | |
65 | + login_as @admin.identifier | |
66 | + post :index, | |
67 | + :newsletter => { :posts_per_blog => '6' } | |
68 | + | |
69 | + assert_equal 6, assigns(:newsletter).posts_per_blog | |
70 | + end | |
71 | + | |
72 | + should 'show error if number of posts per blog is not a positive number' do | |
73 | + login_as @admin.identifier | |
74 | + post :index, | |
75 | + :newsletter => { :posts_per_blog => '-4' } | |
76 | + | |
77 | + assert_select 'li', 'Posts per blog must be a positive number' | |
78 | + end | |
79 | + | |
80 | + should 'save blogs for compiling newsletter setting' do | |
81 | + login_as @admin.identifier | |
82 | + | |
83 | + blog1 = fast_create(Blog) | |
84 | + blog1.profile = fast_create(Profile, environment_id: @environment.id) | |
85 | + blog1.save | |
86 | + | |
87 | + blog2 = fast_create(Blog) | |
88 | + blog2.profile = fast_create(Profile, environment_id: @environment.id) | |
89 | + blog2.save | |
90 | + | |
91 | + post :index, | |
92 | + :newsletter => { :blog_ids => "#{blog1.id},#{blog2.id}" } | |
93 | + | |
94 | + assert_equivalent [blog1.id,blog2.id], assigns(:newsletter).blog_ids | |
95 | + end | |
96 | + | |
97 | + should 'show error if blog is not in environment' do | |
98 | + login_as @admin.identifier | |
99 | + | |
100 | + blog = fast_create(Blog) | |
101 | + blog.profile = fast_create(Profile, environment_id: fast_create(Environment).id) | |
102 | + blog.save | |
103 | + | |
104 | + post :index, | |
105 | + :newsletter => { :blog_ids => "#{blog.id}" } | |
106 | + | |
107 | + assert_select 'li', 'Blog ids must be valid' | |
108 | + end | |
109 | + | |
110 | + should 'save logged in admin as person' do | |
111 | + login_as @admin.identifier | |
112 | + post :index, :newsletter => { } | |
113 | + | |
114 | + assert_equal @admin, assigns(:newsletter).person | |
115 | + end | |
116 | + | |
117 | + should 'receive csv file from user' do | |
118 | + content = <<-EOS | |
119 | +Coop1,name1@example.com | |
120 | +Coop2,name2@example.com | |
121 | +Coop3,name3@example.com | |
122 | +EOS | |
123 | + | |
124 | + file = Tempfile.new(['recipients', '.csv']) | |
125 | + file.write(content) | |
126 | + file.rewind | |
127 | + | |
128 | + login_as @admin.identifier | |
129 | + post :index, newsletter: {}, :file => { recipients: Rack::Test::UploadedFile.new(file, 'text/csv') } | |
130 | + | |
131 | + file.close | |
132 | + file.unlink | |
133 | + | |
134 | + assert_equivalent ["name1@example.com", "name2@example.com", "name3@example.com"], assigns(:newsletter).additional_recipients.map { |recipient| recipient[:email] } | |
135 | + assert_equivalent ["Coop1", "Coop2", "Coop3"], assigns(:newsletter).additional_recipients.map { |recipient| recipient[:name] } | |
136 | + end | |
137 | + | |
138 | + should 'parse csv file with configuration set by user' do | |
139 | + content = <<-EOS | |
140 | +Id,Name,City,Email | |
141 | +1,Coop1,Moscow,name1@example.com | |
142 | +2,Coop2,Beijing,name2@example.com | |
143 | +3,Coop3,Paris,name3@example.com | |
144 | +EOS | |
145 | + | |
146 | + file = Tempfile.new(['recipients', '.csv']) | |
147 | + file.write(content) | |
148 | + file.rewind | |
149 | + | |
150 | + login_as @admin.identifier | |
151 | + post :index, newsletter: {}, :file => { recipients: Rack::Test::UploadedFile.new(file, 'text/csv'), headers: 1, name: 2, email: 4 } | |
152 | + | |
153 | + file.close | |
154 | + file.unlink | |
155 | + | |
156 | + assert_equivalent ["name1@example.com", "name2@example.com", "name3@example.com"], assigns(:newsletter).additional_recipients.map { |recipient| recipient[:email] } | |
157 | + assert_equivalent ["Coop1", "Coop2", "Coop3"], assigns(:newsletter).additional_recipients.map { |recipient| recipient[:name] } | |
158 | + end | |
159 | + | |
160 | + should 'list additional recipients' do | |
161 | + login_as @admin.identifier | |
162 | + get :recipients | |
163 | + assert_select 'p', 'There are no additional recipients.' | |
164 | + | |
165 | + newsletter = NewsletterPlugin::Newsletter.create!(environment: @environment, person: fast_create(Person)) | |
166 | + newsletter.additional_recipients = [ {name: 'Coop1', email: 'name1@example.com'} ] | |
167 | + newsletter.save! | |
168 | + | |
169 | + get :recipients | |
170 | + assert_select 'tr' do | |
171 | + assert_select 'td', 'Coop1' | |
172 | + assert_select 'td', 'name1@example.com' | |
173 | + end | |
174 | + end | |
175 | + | |
176 | +end | ... | ... |
plugins/newsletter/test/functional/newsletter_plugin_controller_test.rb
0 → 100644
... | ... | @@ -0,0 +1,37 @@ |
1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | |
2 | + | |
3 | +class NewsletterPluginControllerTest < ActionController::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @controller = NewsletterPluginController.new | |
7 | + @request = ActionController::TestRequest.new | |
8 | + @response = ActionController::TestResponse.new | |
9 | + environment = fast_create(Environment) | |
10 | + environment.enable_plugin(NewsletterPlugin) | |
11 | + @controller.stubs(:environment).returns(environment) | |
12 | + end | |
13 | + | |
14 | + should 'require login to confirm unsubscription' do | |
15 | + post :confirm_unsubscription | |
16 | + assert_response 302 | |
17 | + end | |
18 | + | |
19 | + should 'open unsubscription page for anonymous' do | |
20 | + get :unsubscribe | |
21 | + assert_response :success | |
22 | + end | |
23 | + | |
24 | + should 'add user email from unsubscribers list' do | |
25 | + NewsletterPlugin::Newsletter.create!( | |
26 | + :environment => @controller.environment, | |
27 | + :person => fast_create(Person) | |
28 | + ) | |
29 | + maria = create_user("maria").person | |
30 | + login_as("maria") | |
31 | + post :confirm_unsubscription | |
32 | + assert_response :redirect | |
33 | + assert_redirected_to :controller => 'home' | |
34 | + assert_includes assigns(:newsletter).unsubscribers, maria.email | |
35 | + end | |
36 | + | |
37 | +end | ... | ... |
plugins/newsletter/test/unit/newsletter_plugin_moderate_newsletter_test.rb
0 → 100644
... | ... | @@ -0,0 +1,50 @@ |
1 | +require 'test_helper' | |
2 | + | |
3 | +class NewsletterPluginModerateNewsletterTest < ActiveSupport::TestCase | |
4 | + | |
5 | + should 'validates presence of newsletter_id' do | |
6 | + task = NewsletterPlugin::ModerateNewsletter.new | |
7 | + task.valid? | |
8 | + assert task.errors.include?(:newsletter_id) | |
9 | + | |
10 | + task.newsletter_id = 1 | |
11 | + task.valid? | |
12 | + refute task.errors.include?(:newsletter_id) | |
13 | + end | |
14 | + | |
15 | + should 'create mailing on perform' do | |
16 | + person = create_user('john').person | |
17 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => fast_create(Environment), :person => person, :enabled => true) | |
18 | + task = NewsletterPlugin::ModerateNewsletter.create!( | |
19 | + :newsletter_id => newsletter.id, | |
20 | + :target => newsletter.environment | |
21 | + ) | |
22 | + | |
23 | + assert_difference 'NewsletterPlugin::NewsletterMailing.count', 1 do | |
24 | + task.finish | |
25 | + end | |
26 | + end | |
27 | + | |
28 | + should 'set posts for mailing body on perform' do | |
29 | + person = create_user('john').person | |
30 | + blog = fast_create(Blog, profile_id: person.id) | |
31 | + post_1 = fast_create(TextileArticle, :name => 'First post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | |
32 | + post_2 = fast_create(TextileArticle, :name => 'Second post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | |
33 | + post_3 = fast_create(TextileArticle, :name => 'Third post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | |
34 | + | |
35 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => person.environment, :person => person, :enabled => true) | |
36 | + newsletter.blog_ids = [blog.id] | |
37 | + newsletter.save! | |
38 | + | |
39 | + task = NewsletterPlugin::ModerateNewsletter.create!( | |
40 | + :newsletter_id => newsletter.id, | |
41 | + :target => newsletter.environment, | |
42 | + :post_ids => [post_1.id.to_s,post_2.id.to_s] | |
43 | + ) | |
44 | + | |
45 | + task.finish | |
46 | + assert_match /First post/, NewsletterPlugin::NewsletterMailing.last.body | |
47 | + assert_match /Second post/, NewsletterPlugin::NewsletterMailing.last.body | |
48 | + assert_not_match /Third post/, NewsletterPlugin::NewsletterMailing.last.body | |
49 | + end | |
50 | +end | ... | ... |
plugins/newsletter/test/unit/newsletter_plugin_newsletter_mailing_test.rb
0 → 100644
... | ... | @@ -0,0 +1,72 @@ |
1 | +require 'test_helper' | |
2 | + | |
3 | +class NewsletterPluginNewsletterMailingTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + ActionMailer::Base.delivery_method = :test | |
7 | + ActionMailer::Base.perform_deliveries = true | |
8 | + ActionMailer::Base.deliveries = [] | |
9 | + end | |
10 | + | |
11 | + should 'require source id' do | |
12 | + mailing = NewsletterPlugin::NewsletterMailing.new | |
13 | + mailing.valid? | |
14 | + assert mailing.errors[:source_id].any? | |
15 | + | |
16 | + mailing.source_id = NewsletterPlugin::Newsletter.create!(:environment => fast_create(Environment), :person => fast_create(Person)).id | |
17 | + mailing.valid? | |
18 | + refute mailing.errors[:source_id].any? | |
19 | + end | |
20 | + | |
21 | + should 'deliver mail from noreply environment email address' do | |
22 | + environment = fast_create(Environment, :noreply_email => 'noreply@localhost') | |
23 | + person = fast_create Person | |
24 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => environment, :person => person, :enabled => true) | |
25 | + mailing = NewsletterPlugin::NewsletterMailing.create!( | |
26 | + :source => newsletter, | |
27 | + :subject => newsletter.subject, | |
28 | + :body => newsletter.body, | |
29 | + :person => newsletter.person, | |
30 | + :locale => environment.default_locale, | |
31 | + ) | |
32 | + response = NewsletterPlugin::NewsletterMailing::Sender.notification(mailing, 'recipient@example.com').deliver | |
33 | + assert_equal 'noreply@localhost', response.from.join | |
34 | + end | |
35 | + | |
36 | + should 'also send to additional recipients' do | |
37 | + environment = fast_create(Environment, :name => 'Network') | |
38 | + person = create_user('betty', :environment_id => environment.id).person | |
39 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => environment, :person => person) | |
40 | + | |
41 | + newsletter.additional_recipients = [{name: 'example', email: 'exemple@mail.co'}, {name: 'jon', email: 'jonsnow@mail.co'}] | |
42 | + newsletter.save! | |
43 | + | |
44 | + mailing = NewsletterPlugin::NewsletterMailing.create!( | |
45 | + :source => newsletter, | |
46 | + :subject => newsletter.subject, | |
47 | + :body => newsletter.body, | |
48 | + :person => newsletter.person, | |
49 | + :locale => newsletter.environment.default_locale, | |
50 | + ) | |
51 | + | |
52 | + process_delayed_job_queue | |
53 | + assert_equal 3, ActionMailer::Base.deliveries.count | |
54 | + end | |
55 | + | |
56 | + should 'generate url to view mailing' do | |
57 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
58 | + :environment => fast_create(Environment), | |
59 | + :person => fast_create(Person), | |
60 | + :enabled => true | |
61 | + ) | |
62 | + mailing = NewsletterPlugin::NewsletterMailing.create!( | |
63 | + :source => newsletter, | |
64 | + :subject => newsletter.subject, | |
65 | + :body => newsletter.body, | |
66 | + :person => newsletter.person, | |
67 | + :locale => newsletter.environment.default_locale, | |
68 | + ) | |
69 | + assert_equal "http://localhost/plugin/newsletter/mailing/#{mailing.id}", mailing.url | |
70 | + end | |
71 | + | |
72 | +end | ... | ... |
plugins/newsletter/test/unit/newsletter_plugin_newsletter_test.rb
0 → 100644
... | ... | @@ -0,0 +1,414 @@ |
1 | +require 'test_helper' | |
2 | + | |
3 | +class NewsletterPluginNewsletterTest < ActiveSupport::TestCase | |
4 | + | |
5 | + should 'throws exception when try to create newsletters without reference do environment' do | |
6 | + assert_raises ActiveRecord::RecordInvalid do |e| | |
7 | + NewsletterPlugin::Newsletter.create! | |
8 | + assert_match /Profile can't be blank/, e.to_s | |
9 | + end | |
10 | + end | |
11 | + | |
12 | + should 'allow save only one newsletter by environment' do | |
13 | + environment = fast_create Environment | |
14 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person)) | |
15 | + assert_raises ActiveRecord::RecordInvalid do |e| | |
16 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person)) | |
17 | + assert_match /Profile has already been taken/, e.to_s | |
18 | + end | |
19 | + end | |
20 | + | |
21 | + should 'collect enabled newsletters' do | |
22 | + enabled_newsletters = [] | |
23 | + 5.times do | |
24 | + environment = fast_create(Environment) | |
25 | + enabled = environment.id % 2 == 0 | |
26 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
27 | + :environment => environment, | |
28 | + :enabled => enabled, | |
29 | + :person => fast_create(Person)) | |
30 | + enabled_newsletters << newsletter.id if enabled | |
31 | + end | |
32 | + assert_equal enabled_newsletters, NewsletterPlugin::Newsletter.enabled.map(&:id) | |
33 | + end | |
34 | + | |
35 | + should 'people of newsletters are the same environment members' do | |
36 | + 3.times do | |
37 | + environment = fast_create(Environment) | |
38 | + 3.times do | |
39 | + fast_create(Person, environment_id: environment) | |
40 | + end | |
41 | + NewsletterPlugin::Newsletter.create!( | |
42 | + :environment => environment, | |
43 | + :enabled => true, | |
44 | + :person => fast_create(Person)) | |
45 | + end | |
46 | + NewsletterPlugin::Newsletter.enabled.each do |newsletter| | |
47 | + assert_not_equal [], newsletter.people | |
48 | + assert_equal newsletter.environment.people, newsletter.people | |
49 | + end | |
50 | + end | |
51 | + | |
52 | + should 'save period for newsletter' do | |
53 | + environment = fast_create Environment | |
54 | + NewsletterPlugin::Newsletter.create!( | |
55 | + :environment => environment, | |
56 | + :periodicity => '3', | |
57 | + :person => fast_create(Person)) | |
58 | + | |
59 | + assert_equal 3, NewsletterPlugin::Newsletter.find_by_environment_id(environment.id).periodicity | |
60 | + end | |
61 | + | |
62 | + should 'save period as number only' do | |
63 | + environment = fast_create Environment | |
64 | + assert_raises ActiveRecord::RecordInvalid do |e| | |
65 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :periodicity => 'one week' ) | |
66 | + assert_match /Periodicity must be a positive number/, e.to_s | |
67 | + end | |
68 | + end | |
69 | + | |
70 | + should 'save period as a positive number only' do | |
71 | + environment = fast_create Environment | |
72 | + assert_raises ActiveRecord::RecordInvalid do |e| | |
73 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :periodicity => -1 ) | |
74 | + assert_match /Periodicity must be a positive number/, e.to_s | |
75 | + end | |
76 | + end | |
77 | + | |
78 | + should 'save reference to environment blog' do | |
79 | + environment = fast_create Environment | |
80 | + blog = fast_create(Blog) | |
81 | + blog.profile = fast_create(Profile, environment_id: environment.id) | |
82 | + blog.save | |
83 | + assert_nothing_raised ActiveRecord::RecordInvalid do | |
84 | + NewsletterPlugin::Newsletter.create!( | |
85 | + :environment => environment, | |
86 | + :blog_ids => [blog.id], | |
87 | + :person => fast_create(Person)) | |
88 | + end | |
89 | + end | |
90 | + | |
91 | + should 'not save reference to unknown blog' do | |
92 | + environment = fast_create Environment | |
93 | + blog = fast_create(Blog) | |
94 | + blog.profile = fast_create(Profile, environment_id: fast_create(Environment).id) | |
95 | + blog.save | |
96 | + assert_raises ActiveRecord::RecordInvalid do |e| | |
97 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :blog_ids => [blog.id]) | |
98 | + assert_match /Blog ids must be valid/, e.to_s | |
99 | + end | |
100 | + assert_raises ActiveRecord::RecordInvalid do |e| | |
101 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :blog_ids => [blog.id*2]) | |
102 | + assert_match /Blog ids must be valid/, e.to_s | |
103 | + end | |
104 | + end | |
105 | + | |
106 | + should 'not save duplicates for blog ids' do | |
107 | + environment = fast_create Environment | |
108 | + blog = fast_create(Blog) | |
109 | + blog.profile = fast_create(Profile, environment_id: environment.id) | |
110 | + blog.save | |
111 | + assert_raises ActiveRecord::RecordInvalid do |e| | |
112 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :blog_ids => [blog.id, blog.id]) | |
113 | + assert_match /Blog ids must not have duplicates/, e.to_s | |
114 | + end | |
115 | + end | |
116 | + | |
117 | + should "not send newsletters if periodicity isn't expired" do | |
118 | + newsletter = NewsletterPlugin::Newsletter.new | |
119 | + newsletter.periodicity = 10 | |
120 | + newsletter.stubs(:last_send_at).returns(DateTime.parse("2015-01-01")) | |
121 | + Date.stubs(:today).returns(Date.parse("2015-01-07")) | |
122 | + assert_equal false, newsletter.must_be_sent_today? | |
123 | + end | |
124 | + | |
125 | + should 'send newsletters when periodicity expires' do | |
126 | + newsletter = NewsletterPlugin::Newsletter.new | |
127 | + newsletter.periodicity = 10 | |
128 | + newsletter.stubs(:last_send_at).returns(DateTime.parse("2015-01-01")) | |
129 | + Date.stubs(:today).returns(Date.parse("2015-01-15")) | |
130 | + assert_equal true, newsletter.must_be_sent_today? | |
131 | + end | |
132 | + | |
133 | + should 'send now if never send before' do | |
134 | + newsletter = NewsletterPlugin::Newsletter.new(:environment => fast_create(Environment)) | |
135 | + newsletter.periodicity = 10 | |
136 | + assert newsletter.must_be_sent_today? | |
137 | + end | |
138 | + | |
139 | + should 'validate email format for additional recipients' do | |
140 | + environment = fast_create Environment | |
141 | + assert_raises ActiveRecord::RecordInvalid do |e| | |
142 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person), additional_recipients: [{name: 'Cooperative', email: 'cooperative@example'}]) | |
143 | + assert_match /Additional recipients must have only valid emails/, e.to_s | |
144 | + end | |
145 | + assert_nothing_raised ActiveRecord::RecordInvalid do |e| | |
146 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person), additional_recipients: [{name: 'Cooperative', email: 'cooperative@example.com'}]) | |
147 | + end | |
148 | + end | |
149 | + | |
150 | + should 'parse additional recipients' do | |
151 | + content = <<-EOS | |
152 | +Coop1,name1@example.com | |
153 | +Coop2,name2@example.com | |
154 | +Coop3,name3@example.com | |
155 | +EOS | |
156 | + | |
157 | + file = Tempfile.new(['recipients', '.csv']) | |
158 | + file.write(content) | |
159 | + file.rewind | |
160 | + | |
161 | + environment = fast_create Environment | |
162 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person)) | |
163 | + newsletter.import_recipients(Rack::Test::UploadedFile.new(file, 'text/csv')) | |
164 | + | |
165 | + file.close | |
166 | + file.unlink | |
167 | + | |
168 | + assert_equivalent ["name1@example.com", "name2@example.com", "name3@example.com"], newsletter.additional_recipients.map { |recipient| recipient[:email] } | |
169 | + assert_equivalent ["Coop1", "Coop2", "Coop3"], newsletter.additional_recipients.map { |recipient| recipient[:name] } | |
170 | + end | |
171 | + | |
172 | + should 'only parse csv files' do | |
173 | + content = <<-EOS | |
174 | +Coop1,name1@example.com | |
175 | +Coop2,name2@example.com | |
176 | +Coop3,name3@example.com | |
177 | +EOS | |
178 | + | |
179 | + file = Tempfile.new(['recipients', '.txt']) | |
180 | + file.write(content) | |
181 | + file.rewind | |
182 | + | |
183 | + environment = fast_create Environment | |
184 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person)) | |
185 | + newsletter.import_recipients(Rack::Test::UploadedFile.new(file)) | |
186 | + | |
187 | + file.close | |
188 | + file.unlink | |
189 | + | |
190 | + assert_equal [], newsletter.additional_recipients | |
191 | + assert_match /Additional recipients have unknown file type.*/, newsletter.errors.full_messages[0] | |
192 | + end | |
193 | + | |
194 | + should 'parse additional recipients with given column number and header' do | |
195 | + content = <<-EOS | |
196 | +Id,Name,City,Email | |
197 | +1,Coop1,Moscow,name1@example.com | |
198 | +2,Coop2,Beijing,name2@example.com | |
199 | +3,Coop3,Paris,name3@example.com | |
200 | +EOS | |
201 | + | |
202 | + file = Tempfile.new(['recipients', '.csv']) | |
203 | + file.write(content) | |
204 | + file.rewind | |
205 | + | |
206 | + environment = fast_create Environment | |
207 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person)) | |
208 | + newsletter.import_recipients(Rack::Test::UploadedFile.new(file, 'text/csv'), 2, 4, true) | |
209 | + | |
210 | + file.close | |
211 | + file.unlink | |
212 | + | |
213 | + assert_equivalent ["name1@example.com", "name2@example.com", "name3@example.com"], newsletter.additional_recipients.map { |recipient| recipient[:email] } | |
214 | + assert_equivalent ["Coop1", "Coop2", "Coop3"], newsletter.additional_recipients.map { |recipient| recipient[:name] } | |
215 | + end | |
216 | + | |
217 | + should 'retrieve blogs related to newsletter' do | |
218 | + environment = fast_create Environment | |
219 | + community = fast_create(Community, :environment_id => environment.id) | |
220 | + blog1 = fast_create(Blog, :profile_id => community.id) | |
221 | + blog2 = fast_create(Blog, :profile_id => community.id) | |
222 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
223 | + :environment => environment, :blog_ids => [blog1.id, blog2.id], :person => fast_create(Person) | |
224 | + ) | |
225 | + assert_equivalent [blog1, blog2], newsletter.blogs | |
226 | + end | |
227 | + | |
228 | + should 'return empty if has no related blogs' do | |
229 | + environment = fast_create Environment | |
230 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person)) | |
231 | + assert_empty newsletter.blogs | |
232 | + end | |
233 | + | |
234 | + should 'list posts for all selected blogs' do | |
235 | + environment = fast_create Environment | |
236 | + community = fast_create(Community, :environment_id => environment.id) | |
237 | + blog = fast_create(Blog, :profile_id => community.id) | |
238 | + post = fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news') | |
239 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
240 | + :environment => environment, | |
241 | + :blog_ids => [blog.id], | |
242 | + :person => fast_create(Person)) | |
243 | + assert_includes newsletter.posts, post | |
244 | + end | |
245 | + | |
246 | + should 'generate HTML content using posts of selected blogs' do | |
247 | + environment = fast_create Environment | |
248 | + community = fast_create(Community, :environment_id => environment.id) | |
249 | + blog = fast_create(Blog, :profile_id => community.id) | |
250 | + fast_create(TextArticle, :profile_id => community.id, :parent_id => blog.id, :name => 'the last news') | |
251 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
252 | + :environment => environment, | |
253 | + :blog_ids => [blog.id], | |
254 | + :person => fast_create(Person)) | |
255 | + assert_tag_in_string newsletter.body, :tag => 'a', :content => 'the last news' | |
256 | + end | |
257 | + | |
258 | + should 'limit the number of posts per blog' do | |
259 | + environment = fast_create Environment | |
260 | + community = fast_create(Community, :environment_id => environment.id) | |
261 | + blog = fast_create(Blog, :profile_id => community.id) | |
262 | + fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 1') | |
263 | + fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 2') | |
264 | + fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 3') | |
265 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
266 | + :environment => environment, | |
267 | + :blog_ids => [blog.id], | |
268 | + :person => fast_create(Person), | |
269 | + :posts_per_blog => 2) | |
270 | + assert_equal 2, newsletter.posts.count | |
271 | + end | |
272 | + | |
273 | + should 'include all posts before today' do | |
274 | + environment = fast_create Environment | |
275 | + community = fast_create(Community, :environment_id => environment.id) | |
276 | + blog = fast_create(Blog, :profile_id => community.id) | |
277 | + | |
278 | + post1 = fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 1', | |
279 | + :published_at => DateTime.parse("2015-01-01")) | |
280 | + post2 = fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 2', | |
281 | + :published_at => DateTime.parse("2015-01-09")) | |
282 | + | |
283 | + Date.stubs(:today).returns(DateTime.parse("2015-01-10").to_date) | |
284 | + | |
285 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
286 | + :environment => environment, | |
287 | + :blog_ids => [blog.id], | |
288 | + :person => fast_create(Person)) | |
289 | + | |
290 | + newsletter_posts = newsletter.posts | |
291 | + assert_includes newsletter_posts, post1 | |
292 | + assert_includes newsletter_posts, post2 | |
293 | + end | |
294 | + | |
295 | + should 'not include posts already sent' do | |
296 | + environment = fast_create Environment | |
297 | + community = fast_create(Community, :environment_id => environment.id) | |
298 | + blog = fast_create(Blog, :profile_id => community.id) | |
299 | + | |
300 | + post1 = fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 1', | |
301 | + :published_at => DateTime.parse("2015-01-01")) | |
302 | + post2 = fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 2', | |
303 | + :published_at => DateTime.parse("2015-01-09")) | |
304 | + | |
305 | + Date.stubs(:today).returns(DateTime.parse("2015-01-10").to_date) | |
306 | + | |
307 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
308 | + :environment => environment, | |
309 | + :blog_ids => [blog.id], | |
310 | + :person => fast_create(Person)) | |
311 | + newsletter.stubs(:last_send_at).returns(DateTime.parse("2015-01-05")) | |
312 | + | |
313 | + newsletter_posts = newsletter.posts | |
314 | + assert_not_includes newsletter_posts, post1 | |
315 | + assert_includes newsletter_posts, post2 | |
316 | + end | |
317 | + | |
318 | + should 'sanitize tags <p> from news lead' do | |
319 | + environment = fast_create Environment | |
320 | + community = fast_create(Community, :environment_id => environment.id) | |
321 | + blog = fast_create(Blog, :profile_id => community.id) | |
322 | + post = fast_create(TextArticle, :parent_id => blog.id, | |
323 | + :name => 'the last news 1', | |
324 | + :profile_id => community.id, | |
325 | + :body => "<p>paragraph of news</p>") | |
326 | + | |
327 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
328 | + :environment => environment, | |
329 | + :blog_ids => [blog.id], | |
330 | + :person => fast_create(Person)) | |
331 | + | |
332 | + assert_match /<p>paragraph of news<\/p>/, post.body | |
333 | + assert_not_match /<p>paragraph of news<\/p>/, newsletter.body | |
334 | + end | |
335 | + | |
336 | + should 'filter posts when listing posts for newsletter' do | |
337 | + person = fast_create(Person) | |
338 | + blog = fast_create(Blog, profile_id: person.id) | |
339 | + | |
340 | + post_1 = fast_create(TextileArticle, :name => 'First post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | |
341 | + post_2 = fast_create(TextileArticle, :name => 'Second post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | |
342 | + post_3 = fast_create(TextileArticle, :name => 'Third post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | |
343 | + | |
344 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
345 | + :environment => person.environment, | |
346 | + :blog_ids => [blog.id], | |
347 | + :person => person) | |
348 | + | |
349 | + assert_equivalent [post_2.id, post_3.id], newsletter.posts({post_ids: [post_2.id.to_s, post_3.id.to_s]}).map(&:id) | |
350 | + end | |
351 | + | |
352 | + should 'filter posts in body for newsletter' do | |
353 | + person = fast_create(Person) | |
354 | + blog = fast_create(Blog, profile_id: person.id) | |
355 | + | |
356 | + post_1 = fast_create(TextileArticle, :name => 'First post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | |
357 | + post_2 = fast_create(TextileArticle, :name => 'Second post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | |
358 | + post_3 = fast_create(TextileArticle, :name => 'Third post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | |
359 | + | |
360 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
361 | + :environment => person.environment, | |
362 | + :blog_ids => [blog.id], | |
363 | + :person => person) | |
364 | + | |
365 | + assert_match /First post/, NewsletterPlugin::Newsletter.last.body({post_ids: [post_1.id.to_s, post_3.id.to_s]}) | |
366 | + assert_not_match /Second post/, NewsletterPlugin::Newsletter.last.body({post_ids: [post_1.id.to_s, post_3.id.to_s]}) | |
367 | + assert_match /Third post/, NewsletterPlugin::Newsletter.last.body({post_ids: [post_1.id.to_s, post_3.id.to_s]}) | |
368 | + end | |
369 | + | |
370 | + should 'add email to unsubscribers list' do | |
371 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
372 | + :environment => fast_create(Environment), | |
373 | + :person => fast_create(Person) | |
374 | + ) | |
375 | + newsletter.unsubscribe("ze@localhost.localdomain") | |
376 | + assert_includes newsletter.unsubscribers, "ze@localhost.localdomain" | |
377 | + end | |
378 | + | |
379 | + should 'not add same email twice to unsubscribers list' do | |
380 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
381 | + :environment => fast_create(Environment), | |
382 | + :person => fast_create(Person) | |
383 | + ) | |
384 | + newsletter.unsubscribe("ze@localhost.localdomain") | |
385 | + newsletter.unsubscribe("ze@localhost.localdomain") | |
386 | + assert_equal ["ze@localhost.localdomain"], newsletter.unsubscribers | |
387 | + end | |
388 | + | |
389 | + should "filter newsletter's recipients using unsubscribers list" do | |
390 | + environment = fast_create Environment | |
391 | + p1 = create_user("person1", :environment_id => environment.id).person | |
392 | + p2 = create_user("person2", :environment_id => environment.id).person | |
393 | + p3 = create_user("person3", :environment_id => environment.id).person | |
394 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
395 | + :environment => environment, | |
396 | + :person => fast_create(Person) | |
397 | + ) | |
398 | + newsletter.unsubscribe(p2.email) | |
399 | + assert_equivalent [p1, p3], newsletter.people | |
400 | + end | |
401 | + | |
402 | + should "no filter newsletter's recipients if unsubscribers list empty" do | |
403 | + environment = fast_create Environment | |
404 | + p1 = create_user("person1", :environment_id => environment.id).person | |
405 | + p2 = create_user("person2", :environment_id => environment.id).person | |
406 | + p3 = create_user("person3", :environment_id => environment.id).person | |
407 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
408 | + :environment => environment, | |
409 | + :person => fast_create(Person) | |
410 | + ) | |
411 | + assert_equivalent [p1, p2, p3], newsletter.people | |
412 | + end | |
413 | + | |
414 | +end | ... | ... |
... | ... | @@ -0,0 +1,113 @@ |
1 | +require 'test_helper' | |
2 | + | |
3 | +class NewsletterPluginTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + NewsletterPlugin::Newsletter.any_instance.stubs(:must_be_sent_today?).returns(true) | |
7 | + NewsletterPlugin::Newsletter.any_instance.stubs(:has_posts_in_the_period?).returns(true) | |
8 | + end | |
9 | + | |
10 | + should 'update newsletter send date only for enabled newsletters' do | |
11 | + newsletter_enabled = NewsletterPlugin::Newsletter.create!( | |
12 | + :environment => fast_create(Environment), | |
13 | + :enabled => true, | |
14 | + :subject => 'newsletter test', | |
15 | + :person => fast_create(Person)) | |
16 | + | |
17 | + newsletter_disabled = NewsletterPlugin::Newsletter.create!( | |
18 | + :environment => fast_create(Environment), | |
19 | + :enabled => false, | |
20 | + :subject => 'newsletter test', | |
21 | + :person => fast_create(Person)) | |
22 | + | |
23 | + NewsletterPlugin.compile_and_send_newsletters | |
24 | + | |
25 | + newsletter_enabled.reload | |
26 | + newsletter_disabled.reload | |
27 | + | |
28 | + assert_not_nil newsletter_enabled.last_send_at | |
29 | + assert_nil newsletter_disabled.last_send_at | |
30 | + end | |
31 | + | |
32 | + should 'create and schedule newsletter mailing if not moderated' do | |
33 | + NewsletterPlugin::Newsletter.create!( | |
34 | + :environment => fast_create(Environment), | |
35 | + :enabled => true, | |
36 | + :moderated => false, | |
37 | + :subject => 'newsletter test', | |
38 | + :person => fast_create(Person)) | |
39 | + | |
40 | + assert_difference 'NewsletterPlugin::NewsletterMailing.count', 1 do | |
41 | + NewsletterPlugin.compile_and_send_newsletters | |
42 | + end | |
43 | + | |
44 | + assert_equal 0, NewsletterPlugin::ModerateNewsletter.count | |
45 | + end | |
46 | + | |
47 | + should 'use same environment locale on mailing' do | |
48 | + NewsletterPlugin::Newsletter.create!( | |
49 | + :environment => fast_create(Environment, :default_language => 'pt_BR'), | |
50 | + :enabled => true, | |
51 | + :subject => 'newsletter test', | |
52 | + :person => fast_create(Person)) | |
53 | + | |
54 | + NewsletterPlugin.compile_and_send_newsletters | |
55 | + assert_equal 'pt_BR', NewsletterPlugin::NewsletterMailing.last.locale | |
56 | + end | |
57 | + | |
58 | + should 'create newsletter moderation task if newsletter is moderated' do | |
59 | + adminuser = create_user.person | |
60 | + Environment.any_instance.stubs(:admins).returns([adminuser]) | |
61 | + | |
62 | + NewsletterPlugin::Newsletter.create!( | |
63 | + :environment => fast_create(Environment), | |
64 | + :enabled => true, | |
65 | + :moderated => true, | |
66 | + :subject => 'newsletter test', | |
67 | + :person => fast_create(Person)) | |
68 | + | |
69 | + assert_difference 'NewsletterPlugin::ModerateNewsletter.count', 1 do | |
70 | + NewsletterPlugin.compile_and_send_newsletters | |
71 | + end | |
72 | + | |
73 | + assert_equal 0, NewsletterPlugin::NewsletterMailing.count | |
74 | + end | |
75 | + | |
76 | + should 'not create mailing if has no posts in the period' do | |
77 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
78 | + :environment => fast_create(Environment), | |
79 | + :person => fast_create(Person), | |
80 | + :enabled => true | |
81 | + ) | |
82 | + NewsletterPlugin::Newsletter.any_instance.stubs(:must_be_sent_today?).returns(true) | |
83 | + NewsletterPlugin::Newsletter.any_instance.stubs(:has_posts_in_the_period?).returns(false) | |
84 | + assert_no_difference 'NewsletterPlugin::NewsletterMailing.count' do | |
85 | + NewsletterPlugin.compile_and_send_newsletters | |
86 | + end | |
87 | + end | |
88 | + | |
89 | + should 'not create mailing if doesnt must be sent today' do | |
90 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
91 | + :environment => fast_create(Environment), | |
92 | + :person => fast_create(Person), | |
93 | + :enabled => true | |
94 | + ) | |
95 | + NewsletterPlugin::Newsletter.any_instance.stubs(:must_be_sent_today?).returns(false) | |
96 | + NewsletterPlugin::Newsletter.any_instance.stubs(:has_posts_in_the_period?).returns(true) | |
97 | + assert_no_difference 'NewsletterPlugin::NewsletterMailing.count' do | |
98 | + NewsletterPlugin.compile_and_send_newsletters | |
99 | + end | |
100 | + end | |
101 | + | |
102 | + should 'create mailing' do | |
103 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
104 | + :environment => fast_create(Environment), | |
105 | + :person => fast_create(Person), | |
106 | + :enabled => true | |
107 | + ) | |
108 | + assert_difference 'NewsletterPlugin::NewsletterMailing.count' do | |
109 | + NewsletterPlugin.compile_and_send_newsletters | |
110 | + end | |
111 | + end | |
112 | + | |
113 | +end | ... | ... |
plugins/newsletter/views/newsletter_plugin/mailing_not_found.html.erb
0 → 100644
plugins/newsletter/views/newsletter_plugin/unsubscribe.html.erb
0 → 100644
... | ... | @@ -0,0 +1,11 @@ |
1 | +<h1><%= _('Cancel newsletter subscription') %></h1> | |
2 | + | |
3 | +<h4> | |
4 | +<%= _("I don't want to receive future newsletter emails from this network.") %> | |
5 | +</h4> | |
6 | + | |
7 | +<%= _('Send an email to %s requesting your unsubscription or click on the button below.') % link_to(environment.contact_email, "mailto:#{environment.contact_email}?subject=#{_('Cancel newsletter subscription')}") %> | |
8 | + | |
9 | +<% button_bar do %> | |
10 | + <%= button :ok, _('Confirm unsubscription'), {:action => 'confirm_unsubscription'}, :method => 'post' %> | |
11 | +<% end %> | ... | ... |
plugins/newsletter/views/newsletter_plugin_admin/index.html.erb
0 → 100644
... | ... | @@ -0,0 +1,92 @@ |
1 | +<h1><%= _('Newsletter settings') %></h1> | |
2 | + | |
3 | +<%= render :file => 'shared/tiny_mce' %> | |
4 | + | |
5 | +<%= error_messages_for :newsletter %> | |
6 | + | |
7 | +<%= form_for(:newsletter, html: { multipart: true }) do |f| %> | |
8 | + <%= labelled_form_field( | |
9 | + content_tag('h3', hidden_field_tag('newsletter[enabled]', false) + | |
10 | + f.check_box('enabled') + | |
11 | + _('Enable send of newsletter to members on this environment'), :id => 'newsletter-enabled-field'), | |
12 | + nil) | |
13 | + %> | |
14 | + | |
15 | + <%= labelled_form_field( | |
16 | + content_tag('span', hidden_field_tag('newsletter[moderated]', false) + f.check_box('moderated') + _('Moderate newsletter each time before sending to users.')), nil) | |
17 | + %> | |
18 | + | |
19 | + <h2> | |
20 | + <%= _('Content') %> | |
21 | + </h2> | |
22 | + | |
23 | + <%= labelled_form_field( | |
24 | + _('Period (in days) for news compilation'), f.number_field(:periodicity, min: '0')) | |
25 | + %> | |
26 | + | |
27 | + <%= labelled_form_field( | |
28 | + _('Number of posts compiled per blog (choose 0 for all posts since last newsletter)'), f.number_field(:posts_per_blog, min: '0')) | |
29 | + %> | |
30 | + | |
31 | + <p><%= _('Blogs from which news will be compiled') %></p> | |
32 | + <% search_action = url_for(:action => 'search_communities') %> | |
33 | + <% selected_blogs = @blogs.map { |blog| {:id => blog.id, :name => _("%s in %s") % [blog.name, blog.profile.name]} } %> | |
34 | + <%= token_input_field_tag( | |
35 | + 'newsletter[blog_ids]', 'search-communities', search_action, | |
36 | + { hint_text: _('Type in the communities\' or blogs\' names'), | |
37 | + focus: false, pre_populate: selected_blogs }) %> | |
38 | + | |
39 | + <br/> | |
40 | + | |
41 | + <h2> | |
42 | + <%= _('Recipients') %> | |
43 | + </h2> | |
44 | + | |
45 | + <p> | |
46 | + <%= _('You can follow the link below to see which e-mails are currently being used as additional recipients for this newsletter.') %> | |
47 | + </p> | |
48 | + <p> | |
49 | + <%= link_to 'Currently set additional recipients', {action: :recipients}, target: '_blank' %> | |
50 | + </p> | |
51 | + | |
52 | + <p><%= _('You can set additional e-mails to send the newsletter to in addition to all environment\'s users that already receive the newsletter by default. To do that, you need to upload a CSV file that contains a column for the person\'s or enterprise\'s name as well as a column with their e-mail.') %></p> | |
53 | + | |
54 | + <%= labelled_form_field( | |
55 | + _('Additional recipients for newsletter'), file_field_tag('file[recipients]', accept: '.csv')) | |
56 | + %> | |
57 | + | |
58 | + <div id='newsletter-file-options'> | |
59 | + <%= labelled_form_field( | |
60 | + content_tag('span', check_box_tag('file[headers]', 1, false, disabled: true) + _('The CSV file contains a header row')), nil) | |
61 | + %> | |
62 | + | |
63 | + <%= labelled_form_field( | |
64 | + _('Number of colunm with name field'), number_field_tag('file[name]', '1', min: '1', disabled: true)) | |
65 | + %> | |
66 | + | |
67 | + <%= labelled_form_field( | |
68 | + _('Number of colunm with email field'), number_field_tag('file[email]', '2', min: '1', disabled: true)) | |
69 | + %> | |
70 | + </div> | |
71 | + | |
72 | + <h2> | |
73 | + <%= _('Layout') %> | |
74 | + </h2> | |
75 | + | |
76 | + <%= f.fields_for :image_builder, @newsletter.image do |i| %> | |
77 | + <%= file_field_or_thumbnail(_('Header image (images with 640px width):'), @newsletter.image, i) %> | |
78 | + <% end %> | |
79 | + | |
80 | + <%= labelled_form_field( | |
81 | + content_tag('h3', ui_icon('ui-icon-triangle-1-s') + | |
82 | + _('Newsletter footer'), :class => 'newsletter-toggle-link', :element_id => '#newsletter-footer-field'), | |
83 | + content_tag('div', | |
84 | + f.text_area(:footer, :style => 'width: 100%', :class => 'mceEditor'), | |
85 | + :id => 'newsletter-footer-field' | |
86 | + )) | |
87 | + %> | |
88 | + <% button_bar do %> | |
89 | + <%= submit_button :save, _('Save') %> | |
90 | + <%= submit_button :save, _('Save and visualize'), :name => "visualize", :cancel => {:controller => 'plugins'} %> | |
91 | + <% end %> | |
92 | +<% end %> | ... | ... |
plugins/newsletter/views/newsletter_plugin_admin/recipients.html.erb
0 → 100644
... | ... | @@ -0,0 +1,21 @@ |
1 | +<h1><%= _('Additional recipients') %></h1> | |
2 | + | |
3 | +<% if @additional_recipients.present? %> | |
4 | + <table border="0" cellspacing="5" cellpadding="5"> | |
5 | + <tr> | |
6 | + <th><%= _('Name') %></th> | |
7 | + <th><%= _('E-mail') %></th> | |
8 | + </tr> | |
9 | + <% @additional_recipients.each do |recipient| %> | |
10 | + <tr> | |
11 | + <td><%= recipient[:name] %></td> | |
12 | + <td><%= recipient[:email] %></td> | |
13 | + </tr> | |
14 | + <% end %> | |
15 | + </table> | |
16 | +<% else %> | |
17 | + <p><%= _('There are no additional recipients.') %></p> | |
18 | +<% end %> | |
19 | + | |
20 | +<br/> | |
21 | +<%= button :back, _('Back'), action: :index %> | ... | ... |
plugins/newsletter/views/tasks/newsletter_plugin/_moderate_newsletter_accept_details.html.erb
0 → 100644
... | ... | @@ -0,0 +1,17 @@ |
1 | +<% newsletter = NewsletterPlugin::Newsletter.find(task.newsletter_id) %> | |
2 | + | |
3 | +<h1><%= _('Check posts you want to include') %></h1> | |
4 | + | |
5 | +<div id='newsletter-moderation-preview'> | |
6 | + <% newsletter_content = newsletter.body.gsub(/width: 640px;/,'').sub(/#{NewsletterPlugin::Newsletter::CSS['breaking-news-wrap']}/, '') %> | |
7 | + | |
8 | + <% newsletter.posts.each do |post| %> | |
9 | + <% input_name = "tasks[#{task.id}][task][post_ids][]" %> | |
10 | + <% post_check_box = hidden_field_tag(input_name, '0') +check_box_tag(input_name, post.id, true) %> | |
11 | + | |
12 | + <% newsletter_content.gsub!(/<span id="#{post.id}"/, post_check_box+ '<span') %> | |
13 | + <% newsletter_content.gsub!(/<img id="#{post.id}"/, post_check_box+ '<img') %> | |
14 | + <% end %> | |
15 | + | |
16 | + <%= newsletter_content %> | |
17 | +</div> | ... | ... |
plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb
... | ... | @@ -12,7 +12,7 @@ class OrganizationRatingsPluginProfileController < ProfileController |
12 | 12 | if @rating_available |
13 | 13 | create_new_rate |
14 | 14 | else |
15 | - session[:notice] = _("You can not vote on this %s") % profile.class.name | |
15 | + session[:notice] = _("You can not vote on this %s") % _(profile.class.name) | |
16 | 16 | end |
17 | 17 | end |
18 | 18 | end | ... | ... |
plugins/organization_ratings/lib/create_organization_rating_comment.rb
... | ... | @@ -63,7 +63,7 @@ class CreateOrganizationRatingComment < Task |
63 | 63 | |
64 | 64 | def information |
65 | 65 | message = _("<a href=%{requestor_url}>%{requestor}</a> wants to create a comment in this %{target_class}") % |
66 | - {:requestor_url => url_for(self.requestor.url), :requestor => self.requestor.name, :target_class => self.target.class.name.downcase} | |
66 | + {:requestor_url => url_for(self.requestor.url), :requestor => self.requestor.name, :target_class => _(self.target.class.name)} | |
67 | 67 | |
68 | 68 | {:message => message} |
69 | 69 | end |
... | ... | @@ -88,20 +88,20 @@ class CreateOrganizationRatingComment < Task |
88 | 88 | |
89 | 89 | def target_notification_description |
90 | 90 | _("%{requestor} wants to create a comment in this \"%{target}\"") % |
91 | - {:requestor => self.requestor.name, :target => self.target.class.name.downcase } | |
91 | + {:requestor => self.requestor.name, :target => _(self.target.class.name.downcase) } | |
92 | 92 | end |
93 | 93 | |
94 | 94 | def target_notification_message |
95 | - _("User \"%{user}\" just requested to create a comment in the %{target_class} | |
95 | + _("User \"%{user}\" requested to create a comment in the %{target_class} | |
96 | 96 | \"%{target_name}\". |
97 | 97 | You have to approve or reject it through the \"Pending Validations\" |
98 | 98 | section in your control panel.\n") % |
99 | - { :user => self.requestor.name, :target_class => self.target.class.name.downcase, :target_name => self.target.name } | |
99 | + { :user => self.requestor.name, :target_class => _(self.target.class.name.downcase), :target_name => self.target.name } | |
100 | 100 | end |
101 | 101 | |
102 | 102 | def task_created_message |
103 | 103 | _("Your request for commenting at %{target} was |
104 | - just sent. Environment administrator will receive it and will approve or | |
104 | + just sent. The administrator will receive it and will approve or | |
105 | 105 | reject your request according to his methods and criteria. |
106 | 106 | You will be notified as soon as environment administrator has a position |
107 | 107 | about your request.") % |
... | ... | @@ -110,16 +110,16 @@ class CreateOrganizationRatingComment < Task |
110 | 110 | |
111 | 111 | def task_cancelled_message |
112 | 112 | _("Your request for commenting at %{target} was |
113 | - not approved by the environment administrator. The following explanation | |
113 | + not approved by the administrator. The following explanation | |
114 | 114 | was given: \n\n%{explanation}") % |
115 | 115 | { :target => self.target.name, |
116 | 116 | :explanation => self.reject_explanation } |
117 | 117 | end |
118 | 118 | |
119 | 119 | def task_finished_message |
120 | - _('Your request for commenting was approved. | |
120 | + _('Your request for commenting at %{target} was approved. | |
121 | 121 | You can access %{url} to see your comment.') % |
122 | - { :url => ratings_url } | |
122 | + { :target => self.target.name, :url => ratings_url } | |
123 | 123 | end |
124 | 124 | |
125 | 125 | private | ... | ... |
plugins/organization_ratings/lib/organization_ratings_block.rb
plugins/organization_ratings/po/organization_ratings.pot
0 → 100644
... | ... | @@ -0,0 +1,250 @@ |
1 | +# SOME DESCRIPTIVE TITLE. | |
2 | +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
3 | +# This file is distributed under the same license as the PACKAGE package. | |
4 | +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
5 | +# | |
6 | +#, fuzzy | |
7 | +msgid "" | |
8 | +msgstr "" | |
9 | +"Project-Id-Version: 1.2-478-gee4ad04\n" | |
10 | +"POT-Creation-Date: 2015-09-11 18:11-0300\n" | |
11 | +"PO-Revision-Date: 2015-09-11 18:56-0000\n" | |
12 | +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | |
13 | +"Language-Team: LANGUAGE <LL@li.org>\n" | |
14 | +"Language: \n" | |
15 | +"MIME-Version: 1.0\n" | |
16 | +"Content-Type: text/plain; charset=UTF-8\n" | |
17 | +"Content-Transfer-Encoding: 8bit\n" | |
18 | +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" | |
19 | + | |
20 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:31 | |
21 | +msgid "Comment waiting for approval" | |
22 | +msgstr "" | |
23 | + | |
24 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:48 | |
25 | +msgid "Comment rejected" | |
26 | +msgstr "" | |
27 | + | |
28 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:52 | |
29 | +#: plugins/organization_ratings/views/shared/_user_rating_container.html.erb:28 | |
30 | +msgid "No comment" | |
31 | +msgstr "" | |
32 | + | |
33 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:61 | |
34 | +msgid "New Comment" | |
35 | +msgstr "" | |
36 | + | |
37 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:65 | |
38 | +msgid "" | |
39 | +"<a href=%{requestor_url}>%{requestor}</a> wants to create a comment in this " | |
40 | +"%{target_class}" | |
41 | +msgstr "" | |
42 | + | |
43 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:90 | |
44 | +msgid "%{requestor} wants to create a comment in this \"%{target}\"" | |
45 | +msgstr "" | |
46 | + | |
47 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:95 | |
48 | +msgid "" | |
49 | +"User \"%{user}\" requested to create a comment in the %{target_class}\n" | |
50 | +" \"%{target_name}\".\n" | |
51 | +" You have to approve or reject it through the \"Pending Validations\"\n" | |
52 | +" section in your control panel.\n" | |
53 | +msgstr "" | |
54 | + | |
55 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:103 | |
56 | +msgid "" | |
57 | +"Your request for commenting at %{target} was\n" | |
58 | +" just sent. The administrator will receive it and will approve or\n" | |
59 | +" reject your request according to his methods and criteria.\n" | |
60 | +" You will be notified as soon as environment administrator has a " | |
61 | +"position\n" | |
62 | +" about your request." | |
63 | +msgstr "" | |
64 | + | |
65 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:112 | |
66 | +msgid "" | |
67 | +"Your request for commenting at %{target} was\n" | |
68 | +" not approved by the administrator. The following explanation\n" | |
69 | +" was given: \n" | |
70 | +"\n" | |
71 | +"%{explanation}" | |
72 | +msgstr "" | |
73 | + | |
74 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:120 | |
75 | +msgid "" | |
76 | +"Your request for commenting at %{target} was approved.\n" | |
77 | +" You can access %{url} to see your comment." | |
78 | +msgstr "" | |
79 | + | |
80 | +#: plugins/organization_ratings/lib/organization_ratings_config.rb:8 | |
81 | +msgid "More Recent" | |
82 | +msgstr "" | |
83 | + | |
84 | +#: plugins/organization_ratings/lib/organization_ratings_config.rb:8 | |
85 | +msgid "Best Ratings" | |
86 | +msgstr "" | |
87 | + | |
88 | +#: plugins/organization_ratings/lib/organization_ratings_block.rb:5 | |
89 | +msgid "Organization Ratings" | |
90 | +msgstr "" | |
91 | + | |
92 | +#: plugins/organization_ratings/lib/organization_ratings_block.rb:9 | |
93 | +msgid "This block displays the organization ratings." | |
94 | +msgstr "" | |
95 | + | |
96 | +#: plugins/organization_ratings/lib/average_rating_block.rb:5 | |
97 | +msgid "Organization Average Rating" | |
98 | +msgstr "" | |
99 | + | |
100 | +#: plugins/organization_ratings/lib/average_rating_block.rb:9 | |
101 | +msgid "This block displays the organization average rating." | |
102 | +msgstr "" | |
103 | + | |
104 | +#: plugins/organization_ratings/lib/organization_ratings_plugin.rb:9 | |
105 | +msgid "A plugin that allows you to rate a organization and comment about it." | |
106 | +msgstr "" | |
107 | + | |
108 | +#: plugins/organization_ratings/lib/organization_rating.rb:10 | |
109 | +msgid "must be between 1 and 5" | |
110 | +msgstr "" | |
111 | + | |
112 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_admin_controller.rb:12 | |
113 | +msgid "Configuration updated successfully." | |
114 | +msgstr "" | |
115 | + | |
116 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_admin_controller.rb:14 | |
117 | +msgid "Configuration could not be saved." | |
118 | +msgstr "" | |
119 | + | |
120 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb:15 | |
121 | +msgid "You can not vote on this %s" | |
122 | +msgstr "" | |
123 | + | |
124 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb:47 | |
125 | +msgid "%s successfully rated!" | |
126 | +msgstr "" | |
127 | + | |
128 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb:49 | |
129 | +msgid "Sorry, there were problems rating this profile." | |
130 | +msgstr "" | |
131 | + | |
132 | +#: plugins/organization_ratings/views/shared/_make_report_block.html.erb:11 | |
133 | +msgid "User not logged" | |
134 | +msgstr "" | |
135 | + | |
136 | +#: plugins/organization_ratings/views/shared/_make_report_block.html.erb:17 | |
137 | +msgid "Report your experiences." | |
138 | +msgstr "" | |
139 | + | |
140 | +#: plugins/organization_ratings/views/shared/_make_report_block.html.erb:24 | |
141 | +msgid "* You must be logged in to submit a report." | |
142 | +msgstr "" | |
143 | + | |
144 | +#: plugins/organization_ratings/views/shared/_rating_button.html.erb:3 | |
145 | +msgid "Rate %s " | |
146 | +msgstr "" | |
147 | + | |
148 | +#: plugins/organization_ratings/views/shared/_rating_button.html.erb:7 | |
149 | +msgid "Log in" | |
150 | +msgstr "" | |
151 | + | |
152 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:3 | |
153 | +msgid "Organization Rating Settings" | |
154 | +msgstr "" | |
155 | + | |
156 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:10 | |
157 | +msgid "Value" | |
158 | +msgstr "" | |
159 | + | |
160 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:13 | |
161 | +msgid "Default amount of stars marked on evaluations" | |
162 | +msgstr "" | |
163 | + | |
164 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:17 | |
165 | +msgid "Users can rate an organization only once" | |
166 | +msgstr "" | |
167 | + | |
168 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:21 | |
169 | +msgid "The comments are moderated" | |
170 | +msgstr "" | |
171 | + | |
172 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:26 | |
173 | +msgid "Time in hours between evaluations from the same user." | |
174 | +msgstr "" | |
175 | + | |
176 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:27 | |
177 | +msgid "To disable cooldown use zero (0) value." | |
178 | +msgstr "" | |
179 | + | |
180 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:35 | |
181 | +msgid "Order ratings by" | |
182 | +msgstr "" | |
183 | + | |
184 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:41 | |
185 | +msgid "Ratings amount per page" | |
186 | +msgstr "" | |
187 | + | |
188 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:50 | |
189 | +msgid "Back" | |
190 | +msgstr "" | |
191 | + | |
192 | +#: plugins/organization_ratings/views/tasks/_create_organization_rating_comment_accept_details.html.erb:2 | |
193 | +msgid "Comment:" | |
194 | +msgstr "" | |
195 | + | |
196 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:39 | |
197 | +msgid "Rated as" | |
198 | +msgstr "" | |
199 | + | |
200 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:39 | |
201 | +msgid "stars" | |
202 | +msgstr "" | |
203 | + | |
204 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:46 | |
205 | +msgid "Comment (Optional):" | |
206 | +msgstr "" | |
207 | + | |
208 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:53 | |
209 | +msgid "Save" | |
210 | +msgstr "" | |
211 | + | |
212 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:63 | |
213 | +msgid "Hi, %s! The administrators set that you can vote" | |
214 | +msgstr "" | |
215 | + | |
216 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:64 | |
217 | +msgid "only once" | |
218 | +msgstr "" | |
219 | + | |
220 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:65 | |
221 | +msgid "for this %s." | |
222 | +msgstr "" | |
223 | + | |
224 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:70 | |
225 | +msgid "Hi, %s! The administrators set the minimum time of" | |
226 | +msgstr "" | |
227 | + | |
228 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:71 | |
229 | +msgid "%s hour(s)" | |
230 | +msgstr "" | |
231 | + | |
232 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:72 | |
233 | +msgid "between each evaluation." | |
234 | +msgstr "" | |
235 | + | |
236 | +#: plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb:4 | |
237 | +msgid "Rating: " | |
238 | +msgstr "" | |
239 | + | |
240 | +#: plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb:18 | |
241 | +msgid "Be the first to rate!" | |
242 | +msgstr "" | |
243 | + | |
244 | +#: plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb:23 | |
245 | +msgid "Rate this %s" | |
246 | +msgstr "" | |
247 | + | |
248 | +#: plugins/organization_ratings/views/blocks/organization_ratings_block.html.erb:17 | |
249 | +msgid "See more" | |
250 | +msgstr "" | ... | ... |
plugins/organization_ratings/po/pt/organization_ratings.po
0 → 100644
... | ... | @@ -0,0 +1,274 @@ |
1 | +# SOME DESCRIPTIVE TITLE. | |
2 | +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
3 | +# This file is distributed under the same license as the PACKAGE package. | |
4 | +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
5 | +# | |
6 | +#, fuzzy | |
7 | +msgid "" | |
8 | +msgstr "" | |
9 | +"Project-Id-Version: 1.2-478-gee4ad04\n" | |
10 | +"POT-Creation-Date: 2015-09-11 18:11-0300\n" | |
11 | +"PO-Revision-Date: 2015-09-11 18:56-0000\n" | |
12 | +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | |
13 | +"Language-Team: LANGUAGE <LL@li.org>\n" | |
14 | +"Language: \n" | |
15 | +"MIME-Version: 1.0\n" | |
16 | +"Content-Type: text/plain; charset=UTF-8\n" | |
17 | +"Content-Transfer-Encoding: 8bit\n" | |
18 | +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" | |
19 | + | |
20 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:31 | |
21 | +msgid "Comment waiting for approval" | |
22 | +msgstr "Comentario aguardando aprovação" | |
23 | + | |
24 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:48 | |
25 | +msgid "Comment rejected" | |
26 | +msgstr "Comentário rejeitado" | |
27 | + | |
28 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:52 | |
29 | +#: plugins/organization_ratings/views/shared/_user_rating_container.html.erb:28 | |
30 | +msgid "No comment" | |
31 | +msgstr "Sem comentário" | |
32 | + | |
33 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:61 | |
34 | +msgid "New Comment" | |
35 | +msgstr "Novo Comentário" | |
36 | + | |
37 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:65 | |
38 | +msgid "" | |
39 | +"<a href=%{requestor_url}>%{requestor}</a> wants to create a comment in this " | |
40 | +"%{target_class}" | |
41 | +msgstr "" | |
42 | +"<a href=%{requestor_url}>%{requestor}</a> deseja criar um comentário " | |
43 | +"neste(a) %{target_class}" | |
44 | + | |
45 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:90 | |
46 | +msgid "%{requestor} wants to create a comment in this \"%{target}\"" | |
47 | +msgstr "%{requestor} deseja criar um comentário neste(a) \"%{target}\"" | |
48 | + | |
49 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:95 | |
50 | +msgid "" | |
51 | +"User \"%{user}\" requested to create a comment in the %{target_class}\n" | |
52 | +" \"%{target_name}\".\n" | |
53 | +" You have to approve or reject it through the \"Pending Validations\"\n" | |
54 | +" section in your control panel.\n" | |
55 | +msgstr "" | |
56 | +"O usuário \"%{user}\" requisitou a criação de um comentário na " | |
57 | +"%{target_class}\n" | |
58 | +" \"%{target_name}\".\n" | |
59 | +" Você deve aprová-lo ou rejeitá-lo através da seção de \"Validações " | |
60 | +"Pendentes\"\n" | |
61 | +" no seu painel de controle.\n" | |
62 | + | |
63 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:103 | |
64 | +msgid "" | |
65 | +"Your request for commenting at %{target} was\n" | |
66 | +" just sent. The administrator will receive it and will approve or\n" | |
67 | +" reject your request according to his methods and criteria.\n" | |
68 | +" You will be notified as soon as environment administrator has a " | |
69 | +"position\n" | |
70 | +" about your request." | |
71 | +msgstr "" | |
72 | +"Seu pedido para comentar em %{target} foi\n" | |
73 | +" enviado. O administrador irá recebê-lo e aprovarou\n" | |
74 | +" rejeitar seu pedido de acordo com seus métodos e critérios.\n" | |
75 | +" Você será notificado assim que o administrador tenha umaposição\n" | |
76 | +" sobre seu pedido." | |
77 | + | |
78 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:112 | |
79 | +msgid "" | |
80 | +"Your request for commenting at %{target} was\n" | |
81 | +" not approved by the administrator. The following explanation\n" | |
82 | +" was given: \n" | |
83 | +"\n" | |
84 | +"%{explanation}" | |
85 | +msgstr "" | |
86 | +"Seu pedido para comentar em %{target} não\n" | |
87 | +" foi aprovado pelo administrador. A seguinte explicação\n" | |
88 | +" foi dada: \n" | |
89 | +"\n" | |
90 | +"%{explanation}" | |
91 | + | |
92 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:120 | |
93 | +msgid "" | |
94 | +"Your request for commenting at %{target} was approved.\n" | |
95 | +" You can access %{url} to see your comment." | |
96 | +msgstr "" | |
97 | +"Seu pedido para comentar em %{target} foi aprovado.\n" | |
98 | +"\tVocê pode acessar %{url} para ver seu comentário." | |
99 | + | |
100 | +#: plugins/organization_ratings/lib/organization_ratings_config.rb:8 | |
101 | +msgid "More Recent" | |
102 | +msgstr "Mais Recentes" | |
103 | + | |
104 | +#: plugins/organization_ratings/lib/organization_ratings_config.rb:8 | |
105 | +msgid "Best Ratings" | |
106 | +msgstr "Melhores Avaliações" | |
107 | + | |
108 | +#: plugins/organization_ratings/lib/organization_ratings_block.rb:5 | |
109 | +msgid "Organization Ratings" | |
110 | +msgstr "Avaliações da Organização" | |
111 | + | |
112 | +#: plugins/organization_ratings/lib/organization_ratings_block.rb:9 | |
113 | +msgid "This block displays the organization ratings." | |
114 | +msgstr "Este bloco mostra as avaliações da organização." | |
115 | + | |
116 | +#: plugins/organization_ratings/lib/average_rating_block.rb:5 | |
117 | +msgid "Organization Average Rating" | |
118 | +msgstr "Média de Avaliações da Organização" | |
119 | + | |
120 | +#: plugins/organization_ratings/lib/average_rating_block.rb:9 | |
121 | +msgid "This block displays the organization average rating." | |
122 | +msgstr "Este bloco mostra a média de avaliações da organização." | |
123 | + | |
124 | +#: plugins/organization_ratings/lib/organization_ratings_plugin.rb:9 | |
125 | +msgid "A plugin that allows you to rate a organization and comment about it." | |
126 | +msgstr "" | |
127 | +"Um plugin que permite que você avalie uma organização e comente sobre ela." | |
128 | + | |
129 | +#: plugins/organization_ratings/lib/organization_rating.rb:10 | |
130 | +msgid "must be between 1 and 5" | |
131 | +msgstr "deve ser entre 1 e 5" | |
132 | + | |
133 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_admin_controller.rb:12 | |
134 | +msgid "Configuration updated successfully." | |
135 | +msgstr "Configurações atualizadas com sucesso." | |
136 | + | |
137 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_admin_controller.rb:14 | |
138 | +msgid "Configuration could not be saved." | |
139 | +msgstr "Configurações não puderam ser salvas." | |
140 | + | |
141 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb:15 | |
142 | +msgid "You can not vote on this %s" | |
143 | +msgstr "Você não pode votar nesta %s" | |
144 | + | |
145 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb:47 | |
146 | +msgid "%s successfully rated!" | |
147 | +msgstr "%s avaliada com sucesso!" | |
148 | + | |
149 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb:49 | |
150 | +msgid "Sorry, there were problems rating this profile." | |
151 | +msgstr "Desculpe, ocorreram problemas na avaliação deste perfil." | |
152 | + | |
153 | +#: plugins/organization_ratings/views/shared/_make_report_block.html.erb:11 | |
154 | +msgid "User not logged" | |
155 | +msgstr "Usuário não logado" | |
156 | + | |
157 | +#: plugins/organization_ratings/views/shared/_make_report_block.html.erb:17 | |
158 | +msgid "Report your experiences." | |
159 | +msgstr "Relate suas experiências." | |
160 | + | |
161 | +#: plugins/organization_ratings/views/shared/_make_report_block.html.erb:24 | |
162 | +msgid "* You must be logged in to submit a report." | |
163 | +msgstr "* Você precisa estar logado para enviar um relato." | |
164 | + | |
165 | +#: plugins/organization_ratings/views/shared/_rating_button.html.erb:3 | |
166 | +msgid "Rate %s " | |
167 | +msgstr "Avaliar %s " | |
168 | + | |
169 | +#: plugins/organization_ratings/views/shared/_rating_button.html.erb:7 | |
170 | +msgid "Log in" | |
171 | +msgstr "Entrar" | |
172 | + | |
173 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:3 | |
174 | +msgid "Organization Rating Settings" | |
175 | +msgstr "Configuração para Avaliações em Organizações" | |
176 | + | |
177 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:10 | |
178 | +msgid "Value" | |
179 | +msgstr "Valor" | |
180 | + | |
181 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:13 | |
182 | +msgid "Default amount of stars marked on evaluations" | |
183 | +msgstr "Quantidade padrão de estrelas marcadas nas avaliações" | |
184 | + | |
185 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:17 | |
186 | +msgid "Users can rate an organization only once" | |
187 | +msgstr "Usuários podem avaliar uma organização apenas uma vez" | |
188 | + | |
189 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:21 | |
190 | +msgid "The comments are moderated" | |
191 | +msgstr "Os comentários são moderados" | |
192 | + | |
193 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:26 | |
194 | +msgid "Time in hours between evaluations from the same user." | |
195 | +msgstr "Tempo em horas entre avaliações do mesmo usuário." | |
196 | + | |
197 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:27 | |
198 | +msgid "To disable cooldown use zero (0) value." | |
199 | +msgstr "Bara desabilitar o tempo de espera utilize o valor zero (0)." | |
200 | + | |
201 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:35 | |
202 | +msgid "Order ratings by" | |
203 | +msgstr "Ordenar avaliações por" | |
204 | + | |
205 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:41 | |
206 | +msgid "Ratings amount per page" | |
207 | +msgstr "Quantidade de avaliações por página" | |
208 | + | |
209 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:50 | |
210 | +msgid "Back" | |
211 | +msgstr "Voltar" | |
212 | + | |
213 | +#: plugins/organization_ratings/views/tasks/_create_organization_rating_comment_accept_details.html.erb:2 | |
214 | +msgid "Comment:" | |
215 | +msgstr "Comentário:" | |
216 | + | |
217 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:39 | |
218 | +msgid "Rated as" | |
219 | +msgstr "Avaliado em" | |
220 | + | |
221 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:39 | |
222 | +msgid "stars" | |
223 | +msgstr "estrelas" | |
224 | + | |
225 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:46 | |
226 | +msgid "Comment (Optional):" | |
227 | +msgstr "Comentário (Opcional):" | |
228 | + | |
229 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:53 | |
230 | +msgid "Save" | |
231 | +msgstr "Salvar" | |
232 | + | |
233 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:63 | |
234 | +msgid "Hi, %s! The administrators set that you can vote" | |
235 | +msgstr "Olá, %s! Os administradores configuraram que você pode votar apenas" | |
236 | + | |
237 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:64 | |
238 | +msgid "only once" | |
239 | +msgstr "uma vez" | |
240 | + | |
241 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:65 | |
242 | +msgid "for this %s." | |
243 | +msgstr "para esta %s." | |
244 | + | |
245 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:70 | |
246 | +msgid "Hi, %s! The administrators set the minimum time of" | |
247 | +msgstr "Olá, %s! Os administradores configuraram o tempo mínimo de " | |
248 | + | |
249 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:71 | |
250 | +msgid "%s hour(s)" | |
251 | +msgstr "%s hora(s)" | |
252 | + | |
253 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:72 | |
254 | +msgid "between each evaluation." | |
255 | +msgstr "entre cada avaliação." | |
256 | + | |
257 | +#: plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb:4 | |
258 | +msgid "Rating: " | |
259 | +msgstr "Avaliação:" | |
260 | + | |
261 | +#: plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb:18 | |
262 | +msgid "Be the first to rate!" | |
263 | +msgstr "Seja o primeiro a avaliar!" | |
264 | + | |
265 | +#: plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb:23 | |
266 | +msgid "Rate this %s" | |
267 | +msgstr "Avalie esta %s" | |
268 | + | |
269 | +#: plugins/organization_ratings/views/blocks/organization_ratings_block.html.erb:17 | |
270 | +msgid "See more" | |
271 | +msgstr "Veja mais" | |
272 | + | |
273 | +#~ msgid "community" | |
274 | +#~ msgstr "comunidade" | ... | ... |
plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb
... | ... | @@ -20,6 +20,6 @@ |
20 | 20 | <% end %> |
21 | 21 | |
22 | 22 | <div class="rate-this-organization"> |
23 | - <%= link_to _("Rate this %s" % profile.class.name), url_for(:controller => "organization_ratings_plugin_profile", :action => "new_rating", :profile=>profile_identifier) %> | |
23 | + <%= link_to _("Rate this %s" % _(profile.class.name)), url_for(:controller => "organization_ratings_plugin_profile", :action => "new_rating", :profile=>profile_identifier) %> | |
24 | 24 | </div> |
25 | 25 | </div> |
26 | 26 | \ No newline at end of file | ... | ... |
plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb
1 | 1 | <% config = env_organization_ratings_config %> |
2 | 2 | |
3 | -<h1><%= _("Organization Rating Management") %> </h1> | |
3 | +<h1><%= _("Organization Rating Settings") %> </h1> | |
4 | 4 | |
5 | 5 | <%= labelled_form_for(:organization_ratings_config, :url => {:action => 'update'}) do |f| %> |
6 | 6 | <%= labelled_fields_for(:organization_ratings_config, config) do |c| %> |
... | ... | @@ -14,7 +14,7 @@ |
14 | 14 | <td><%= c.select :default_rating, (config.minimum_ratings)..5 %></td> |
15 | 15 | </tr> |
16 | 16 | <tr> |
17 | - <td><%= _('Can rate an organization only once') %></td> | |
17 | + <td><%= _('Users can rate an organization only once') %></td> | |
18 | 18 | <td><%= c.check_box :vote_once %></td> |
19 | 19 | </tr> |
20 | 20 | <tr> |
... | ... | @@ -38,7 +38,7 @@ |
38 | 38 | <td><%= c.select :order, order_options %></td> |
39 | 39 | </tr> |
40 | 40 | <tr> |
41 | - <td><%= _('Ratings per page') %></td> | |
41 | + <td><%= _('Ratings amount per page') %></td> | |
42 | 42 | <td> |
43 | 43 | <%= c.select :per_page, 5..20 %> |
44 | 44 | </td> | ... | ... |
plugins/organization_ratings/views/shared/_make_report_block.html.erb
plugins/organization_ratings/views/shared/_rating_button.html.erb
script/quick-start
script/sample-articles
... | ... | @@ -65,3 +65,22 @@ for subject in EVENT_SUBJECTS |
65 | 65 | end |
66 | 66 | end |
67 | 67 | done |
68 | + | |
69 | +print "Creating some posts: " | |
70 | +for subject in SUBJECTS | |
71 | + rand(20).times do |i| | |
72 | + profile = profiles.sample | |
73 | + name = "%s #{subject}" % profile.name | |
74 | + article = TinyMceArticle.new( | |
75 | + :name => name, | |
76 | + :body => name, | |
77 | + :tag_list => [TAGS.sample, TAGS.sample], | |
78 | + :profile => profile, | |
79 | + :parent_id => profile.blog.id | |
80 | + ) | |
81 | + save article do | |
82 | + article.add_category categories.sample | |
83 | + end | |
84 | + end | |
85 | +end | |
86 | +done | ... | ... |
util/debian-install/install