Commit d3b8064fb95349a37aea58f43727aac204462b6f
Exists in
api_tasks
and in
3 other branches
Merge branch 'master' into api
Showing
67 changed files
with
661 additions
and
274 deletions
Show diff stats
... | ... | @@ -0,0 +1,23 @@ |
1 | +before_script: | |
2 | + - mkdir -p tmp/pids log | |
3 | + - script/noosfero-plugins disableall | |
4 | + - bundle check || bundle install | |
5 | +# database | |
6 | + - cp config/database.yml.gitlab-ci config/database.yml | |
7 | + - createdb gitlab_ci_test || true | |
8 | + - bundle exec rake db:schema:load | |
9 | + - bundle exec rake db:migrate | |
10 | + | |
11 | +units: | |
12 | + script: 'bundle exec rake test:units' | |
13 | +functionals: | |
14 | + script: 'bundle exec rake test:functionals' | |
15 | +integration: | |
16 | + script: 'bundle exec rake test:integration' | |
17 | +cucumber: | |
18 | + script: 'bundle exec rake cucumber' | |
19 | +selenium: | |
20 | + script: 'bundle exec rake selenium' | |
21 | +plugins: | |
22 | + script: 'bundle exec rake test:noosfero_plugins' | |
23 | + | ... | ... |
... | ... | @@ -0,0 +1,35 @@ |
1 | +language: ruby | |
2 | +rvm: | |
3 | +# for 2.2 support we need to upgrade the pg gem | |
4 | + - 2.1.6 | |
5 | + | |
6 | +before_install: | |
7 | +# dependencies | |
8 | + - sudo apt-get update | |
9 | + - sudo apt-get -y install po4a iso-codes tango-icon-theme pidgin-data openjdk-6-jre curl wget | |
10 | + - sudo apt-get -y install libmagickwand-dev libpq-dev libreadline-dev libsqlite3-dev libxslt1-dev | |
11 | +# selenium support | |
12 | + - export DISPLAY=:99.0 | |
13 | + - sh -e /etc/init.d/xvfb start | |
14 | + | |
15 | +before_script: | |
16 | + - mkdir -p tmp/pids log | |
17 | + - script/noosfero-plugins disableall | |
18 | + - bundle check || bundle install | |
19 | +# database | |
20 | + - cp config/database.yml.travis config/database.yml | |
21 | + - psql -c 'create database myapp_test;' -U postgres | |
22 | + - bundle exec rake db:schema:load | |
23 | + - bundle exec rake db:migrate | |
24 | + | |
25 | +env: | |
26 | + - TASK=test:units | |
27 | + - TASK=test:functionals | |
28 | + - TASK=test:integration | |
29 | + - TASK=cucumber | |
30 | + - TASK=selenium | |
31 | + - TASK=test:noosfero_plugins | |
32 | + | |
33 | +script: | |
34 | + - bundle exec rake $TASK | |
35 | + | ... | ... |
Gemfile
1 | 1 | source "https://rubygems.org" |
2 | -gem 'rails', '~> 3.2.21' | |
2 | +gem 'rails', '~> 3.2.22' | |
3 | 3 | gem 'minitest', '~> 3.2.0' |
4 | 4 | gem 'fast_gettext', '~> 0.6.8' |
5 | 5 | gem 'acts-as-taggable-on', '~> 3.4.2' |
... | ... | @@ -44,6 +44,7 @@ group :test do |
44 | 44 | gem 'rspec', '~> 2.14.0' |
45 | 45 | gem 'rspec-rails', '~> 2.14.1' |
46 | 46 | gem 'mocha', '~> 1.1.0', :require => false |
47 | + gem 'test-unit' if RUBY_VERSION >= '2.2.0' | |
47 | 48 | end |
48 | 49 | |
49 | 50 | group :cucumber do | ... | ... |
app/controllers/my_profile/cms_controller.rb
... | ... | @@ -94,6 +94,11 @@ class CmsController < MyProfileController |
94 | 94 | record_coming |
95 | 95 | if request.post? |
96 | 96 | @article.image = nil if params[:remove_image] == 'true' |
97 | + if @article.image.present? && params[:article][:image_builder] && | |
98 | + params[:article][:image_builder][:label] | |
99 | + @article.image.label = params[:article][:image_builder][:label] | |
100 | + @article.image.save! | |
101 | + end | |
97 | 102 | @article.last_changed_by = user |
98 | 103 | if @article.update_attributes(params[:article]) |
99 | 104 | if !continue | ... | ... |
app/controllers/my_profile/manage_products_controller.rb
... | ... | @@ -35,7 +35,7 @@ class ManageProductsController < ApplicationController |
35 | 35 | end |
36 | 36 | |
37 | 37 | def categories_for_selection |
38 | - @category = Category.find(params[:category_id]) if params[:category_id] | |
38 | + @category = environment.categories.find_by_id params[:category_id] | |
39 | 39 | @object_name = params[:object_name] |
40 | 40 | if @category |
41 | 41 | @categories = @category.children |
... | ... | @@ -95,6 +95,20 @@ class ManageProductsController < ApplicationController |
95 | 95 | end |
96 | 96 | end |
97 | 97 | |
98 | + def show_category_tree | |
99 | + @category = environment.categories.find params[:category_id] | |
100 | + render :partial => 'selected_category_tree' | |
101 | + end | |
102 | + | |
103 | + def search_categories | |
104 | + @term = params[:term].downcase | |
105 | + conditions = ['LOWER(name) LIKE ? OR LOWER(name) LIKE ?', "#{@term}%", "% #{@term}%"] | |
106 | + @categories = ProductCategory.all :conditions => conditions, :limit => 10 | |
107 | + render :json => (@categories.map do |category| | |
108 | + {:label => category.name, :value => category.id} | |
109 | + end) | |
110 | + end | |
111 | + | |
98 | 112 | def add_input |
99 | 113 | @product = @profile.products.find(params[:id]) |
100 | 114 | @input = @product.inputs.build | ... | ... |
app/controllers/my_profile/maps_controller.rb
... | ... | @@ -16,6 +16,7 @@ class MapsController < MyProfileController |
16 | 16 | |
17 | 17 | Profile.transaction do |
18 | 18 | if profile.update_attributes!(params[:profile_data]) |
19 | + BlockSweeper.expire_blocks profile.blocks.select{ |b| b.class == LocationBlock } | |
19 | 20 | session[:notice] = _('Address was updated successfully!') |
20 | 21 | redirect_to :action => 'edit_location' |
21 | 22 | end | ... | ... |
app/helpers/application_helper.rb
... | ... | @@ -1185,7 +1185,7 @@ module ApplicationHelper |
1185 | 1185 | pending_tasks_count = link_to(count.to_s, user.tasks_url, :id => 'pending-tasks-count', :title => _("Manage your pending tasks")) |
1186 | 1186 | end |
1187 | 1187 | |
1188 | - (_("<span class='welcome'>Welcome,</span> %s") % link_to("<i style='background-image:url(#{user.profile_custom_icon(gravatar_default)})'></i><strong>#{user.identifier}</strong>", user.public_profile_url, :id => "homepage-link", :title => _('Go to your homepage'))) + | |
1188 | + (_("<span class='welcome'>Welcome,</span> %s") % link_to("<i style='background-image:url(#{user.profile_custom_icon(gravatar_default)})'></i><strong>#{user.identifier}</strong>", user.url, :id => "homepage-link", :title => _('Go to your homepage'))) + | |
1189 | 1189 | render_environment_features(:usermenu) + |
1190 | 1190 | admin_link + |
1191 | 1191 | manage_enterprises + |
... | ... | @@ -1233,7 +1233,7 @@ module ApplicationHelper |
1233 | 1233 | |
1234 | 1234 | def task_information(task) |
1235 | 1235 | values = {} |
1236 | - values.merge!({:requestor => link_to(task.requestor.name, task.requestor.public_profile_url)}) if task.requestor | |
1236 | + values.merge!({:requestor => link_to(task.requestor.name, task.requestor.url)}) if task.requestor | |
1237 | 1237 | values.merge!({:subject => content_tag('span', task.subject, :class=>'task_target')}) if task.subject |
1238 | 1238 | values.merge!({:linked_subject => link_to(content_tag('span', task.linked_subject[:text], :class => 'task_target'), task.linked_subject[:url])}) if task.linked_subject |
1239 | 1239 | values.merge!(task.information[:variables]) if task.information[:variables] | ... | ... |
app/helpers/comment_helper.rb
... | ... | @@ -16,7 +16,7 @@ module CommentHelper |
16 | 16 | content_tag('span', show_date(article.published_at), :class => 'date') + |
17 | 17 | content_tag('span', [_(", by %s") % link_to(article.author_name, article.author_url)], :class => 'author') + |
18 | 18 | content_tag('span', comments, :class => 'comments'), |
19 | - :class => 'created-at' | |
19 | + :class => 'publishing-info' | |
20 | 20 | ) |
21 | 21 | end |
22 | 22 | title | ... | ... |
app/helpers/content_viewer_helper.rb
... | ... | @@ -30,7 +30,7 @@ module ContentViewerHelper |
30 | 30 | date_format + |
31 | 31 | content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') + |
32 | 32 | content_tag('span', comments, :class => 'comments'), |
33 | - :class => 'created-at' | |
33 | + :class => 'publishing-info' | |
34 | 34 | ) |
35 | 35 | end |
36 | 36 | title | ... | ... |
app/helpers/folder_helper.rb
1 | -require 'short_filename' | |
2 | - | |
3 | 1 | module FolderHelper |
4 | 2 | |
5 | - include ShortFilename | |
6 | 3 | include ArticleHelper |
7 | 4 | |
8 | 5 | def list_contents(configure={}) |
... | ... | @@ -10,8 +7,8 @@ module FolderHelper |
10 | 7 | configure[:list_type] ||= :folder |
11 | 8 | if !configure[:contents].blank? |
12 | 9 | configure[:contents] = configure[:contents].paginate( |
13 | - :order => "updated_at DESC", | |
14 | - :per_page => 10, | |
10 | + :order => "name ASC", | |
11 | + :per_page => 30, | |
15 | 12 | :page => params[:npage] |
16 | 13 | ) |
17 | 14 | ... | ... |
app/helpers/manage_products_helper.rb
... | ... | @@ -75,9 +75,12 @@ module ManageProductsHelper |
75 | 75 | end |
76 | 76 | |
77 | 77 | def categories_container(categories_selection_html, hierarchy_html = '') |
78 | - hidden_field_tag('selected_category_id') + | |
79 | - content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') + | |
80 | - content_tag('div', categories_selection_html, :id => 'categories_container_wrapper') | |
78 | + content_tag 'div', | |
79 | + render('categories_autocomplete') + | |
80 | + hidden_field_tag('selected_category_id') + | |
81 | + content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') + | |
82 | + content_tag('div', categories_selection_html, :id => 'categories_container_wrapper'), | |
83 | + :id => 'categories-container' | |
81 | 84 | end |
82 | 85 | |
83 | 86 | def select_for_categories(categories, level = 0) | ... | ... |
app/models/article.rb
... | ... | @@ -736,8 +736,9 @@ class Article < ActiveRecord::Base |
736 | 736 | paragraphs.empty? ? '' : paragraphs.first.to_html |
737 | 737 | end |
738 | 738 | |
739 | - def lead | |
740 | - abstract.blank? ? first_paragraph.html_safe : abstract.html_safe | |
739 | + def lead(length = nil) | |
740 | + content = abstract.blank? ? first_paragraph.html_safe : abstract.html_safe | |
741 | + length.present? ? content.truncate(length) : content | |
741 | 742 | end |
742 | 743 | |
743 | 744 | def short_lead | ... | ... |
app/models/event.rb
... | ... | @@ -98,47 +98,19 @@ class Event < Article |
98 | 98 | start_date..(end_date||start_date) |
99 | 99 | end |
100 | 100 | |
101 | - # FIXME this shouldn't be needed | |
102 | - include ActionView::Helpers::TagHelper | |
103 | - include ActionView::Helpers::UrlHelper | |
104 | - include DatesHelper | |
101 | + def first_paragraph | |
102 | + paragraphs = Nokogiri::HTML.fragment(self.body).css('p') | |
103 | + paragraphs.empty? ? '' : paragraphs.first.to_html | |
104 | + end | |
105 | 105 | |
106 | 106 | def to_html(options = {}) |
107 | + event = self | |
108 | + format = options[:format] | |
107 | 109 | |
108 | - result = '' | |
109 | - html = ::Builder::XmlMarkup.new(:target => result) | |
110 | - | |
111 | - html.div(:class => 'event-info' ) { | |
112 | - html.ul(:class => 'event-data' ) { | |
113 | - html.li(:class => 'event-dates' ) { | |
114 | - html.span _('When:') | |
115 | - html.text! show_period(start_date, end_date) | |
116 | - } if start_date.present? || end_date.present? | |
117 | - html.li { | |
118 | - html.span _('URL:') | |
119 | - html.a(self.link || "", 'href' => self.link || "") | |
120 | - } if self.link.present? | |
121 | - html.li { | |
122 | - html.span _('Address:') | |
123 | - html.text! self.address || "" | |
124 | - } if self.address.present? | |
125 | - } | |
126 | - | |
127 | - # TODO: some good soul, please clean this ugly hack: | |
128 | - if self.body | |
129 | - html.div('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', :class => 'event-description') | |
130 | - end | |
131 | - } | |
132 | - | |
133 | - if self.body | |
134 | - if options[:format] == 'short' | |
135 | - result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', display_short_format(self)) | |
136 | - else | |
137 | - result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', self.body) | |
138 | - end | |
110 | + proc do | |
111 | + render :file => 'content_viewer/event_page', :locals => { :event => event, | |
112 | + :format => format } | |
139 | 113 | end |
140 | - | |
141 | - result | |
142 | 114 | end |
143 | 115 | |
144 | 116 | def duration | ... | ... |
app/models/image.rb
app/models/organization.rb
... | ... | @@ -171,6 +171,12 @@ class Organization < Profile |
171 | 171 | ] |
172 | 172 | end |
173 | 173 | |
174 | + def short_name chars = 40 | |
175 | + s = self.display_name | |
176 | + s = super(chars) if s.blank? | |
177 | + s | |
178 | + end | |
179 | + | |
174 | 180 | def notification_emails |
175 | 181 | emails = [contact_email].select(&:present?) + admins.map(&:email) |
176 | 182 | if emails.empty? | ... | ... |
app/models/uploaded_file.rb
1 | -require 'short_filename' | |
2 | - | |
3 | 1 | # Article type that handles uploaded files. |
4 | 2 | # |
5 | 3 | # Limitation: only file metadata are versioned. Only the latest version |
... | ... | @@ -14,8 +12,6 @@ class UploadedFile < Article |
14 | 12 | |
15 | 13 | track_actions :upload_image, :after_create, :keep_params => ["view_url", "thumbnail_path", "parent.url", "parent.name"], :if => Proc.new { |a| a.published? && a.image? && !a.parent.nil? && a.parent.gallery? }, :custom_target => :parent |
16 | 14 | |
17 | - include ShortFilename | |
18 | - | |
19 | 15 | def title |
20 | 16 | if self.name.present? then self.name else self.filename end |
21 | 17 | end | ... | ... |
app/models/user.rb
... | ... | @@ -332,6 +332,8 @@ class User < ActiveRecord::Base |
332 | 332 | |
333 | 333 | { |
334 | 334 | 'login' => self.login, |
335 | + 'name' => self.person.name, | |
336 | + 'email' => self.email, | |
335 | 337 | 'avatar' => self.person.profile_custom_icon(gravatar_default), |
336 | 338 | 'is_admin' => self.person.is_admin?, |
337 | 339 | 'since_month' => self.person.created_at.month, | ... | ... |
... | ... | @@ -0,0 +1,29 @@ |
1 | +<% @articles.each do |article| article = FilePresenter.for article %> | |
2 | + <tr title="<%= article.title%>" > | |
3 | + <td class="article-name"> | |
4 | + <%= link_to_article(article) %> | |
5 | + </td> | |
6 | + <% short_description = article.respond_to?(:short_description) ? | |
7 | + article.short_description : | |
8 | + article.class.short_description %> | |
9 | + <td class="article-mime" title=<%= short_description.to_json %>> | |
10 | + <%= short_description %> | |
11 | + </td> | |
12 | + <td class="last-update"> | |
13 | + <%= time_ago_in_words article.updated_at %> | |
14 | + </td> | |
15 | + <td class="article-controls"> | |
16 | + <%= expirable_button article, :edit, _('Edit'), {:action => 'edit', :id => article.id} if !remove_content_button(:edit, article) %> | |
17 | + <%= button_without_text :eyes, _('Public view'), article.view_url %> | |
18 | + <%= display_spread_button(article) unless remove_content_button(:spread, article) %> | |
19 | + <% if user.can_change_homepage? && !remove_content_button(:home, article) %> | |
20 | + <% if profile.home_page != article %> | |
21 | + <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %> | |
22 | + <% else %> | |
23 | + <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %> | |
24 | + <% end %> | |
25 | + <% end %> | |
26 | + <%= display_delete_button(article) if !remove_content_button(:delete, article) %> | |
27 | + </td> | |
28 | + </tr> | |
29 | +<% end %> | ... | ... |
app/views/cms/view.html.erb
... | ... | @@ -37,6 +37,7 @@ |
37 | 37 | <tr> |
38 | 38 | <th><%= _('Name') %></th> |
39 | 39 | <th><%= _('Type') %></th> |
40 | + <th><%= _('Last update') %></th> | |
40 | 41 | <th><%= _('Actions') %></th> |
41 | 42 | </tr> |
42 | 43 | |
... | ... | @@ -54,32 +55,7 @@ |
54 | 55 | </tr> |
55 | 56 | <% end %> |
56 | 57 | |
57 | - <% @articles.each do |article| article = FilePresenter.for article %> | |
58 | - <tr title="<%= article.title%>" > | |
59 | - <td class="article-name"> | |
60 | - <%= link_to_article(article) %> | |
61 | - </td> | |
62 | - <% short_description = article.respond_to?(:short_description) ? | |
63 | - article.short_description : | |
64 | - article.class.short_description %> | |
65 | - <td class="article-mime" title=<%= short_description.to_json %>> | |
66 | - <%= short_description %> | |
67 | - </td> | |
68 | - <td class="article-controls"> | |
69 | - <%= expirable_button article, :edit, _('Edit'), {:action => 'edit', :id => article.id} if !remove_content_button(:edit, article) %> | |
70 | - <%= button_without_text :eyes, _('Public view'), article.view_url %> | |
71 | - <%= display_spread_button(article) unless remove_content_button(:spread, article) %> | |
72 | - <% if user.can_change_homepage? && !remove_content_button(:home, article) %> | |
73 | - <% if profile.home_page != article %> | |
74 | - <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %> | |
75 | - <% else %> | |
76 | - <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %> | |
77 | - <% end %> | |
78 | - <% end %> | |
79 | - <%= display_delete_button(article) if !remove_content_button(:delete, article) %> | |
80 | - </td> | |
81 | - </tr> | |
82 | - <% end %> | |
58 | + <%= render 'view_items' %> | |
83 | 59 | |
84 | 60 | </table> |
85 | 61 | ... | ... |
... | ... | @@ -0,0 +1,20 @@ |
1 | +<% if @page.belongs_to_blog? || @page.belongs_to_forum?%> | |
2 | + <h1 class="title"> | |
3 | + <% if no_link %> | |
4 | + <%= h(@page.title) %> | |
5 | + <% else %> | |
6 | + <%= link_to(@page.name, @page.url) %> | |
7 | + <% end %> | |
8 | + </h1> | |
9 | + <%= render :partial => "publishing_info" %> | |
10 | + <% unless @page.abstract.blank? %> | |
11 | + <div class="preview"> | |
12 | + <%= @page.lead %> | |
13 | + </div> | |
14 | + <% end %> | |
15 | +<% else %> | |
16 | + <h1 class="title"> | |
17 | + <%= h(@page.title) %> | |
18 | + </h1> | |
19 | + <%= render :partial => "publishing_info" %> | |
20 | +<% end %> | ... | ... |
app/views/content_viewer/_article_toolbar.html.erb
... | ... | @@ -64,7 +64,7 @@ |
64 | 64 | <% end %> |
65 | 65 | <%= link_to(image_tag('/images/icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %> |
66 | 66 | <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %> |
67 | - <%= article_title(@page, :no_link => true) %> | |
67 | + <%= render :partial => 'article_title', :locals => {:no_link => true} %> | |
68 | 68 | <%= article_translations(@page) %> |
69 | 69 | </div> |
70 | 70 | </div> | ... | ... |
app/views/content_viewer/_display_compact_format.html.erb
... | ... | @@ -0,0 +1,29 @@ |
1 | +<span class="publishing-info"> | |
2 | + <span class="date"> | |
3 | + <%= show_date(@page.published_at) %> | |
4 | + </span> | |
5 | + <span class="author"> | |
6 | + <%= _(", by %s") % (@page.author ? link_to(@page.author_name, @page.author_url) : @page.author_name) %> | |
7 | + </span> | |
8 | +<% unless @no_comments %> | |
9 | + <span class="comments"> | |
10 | + <%= (" - %s") % link_to_comments(@page)%> | |
11 | + </span> | |
12 | +<% end %> | |
13 | +</span> | |
14 | + | |
15 | +<% if @page.display_hits? || @page.license.present? %> | |
16 | + <div id='article-sub-header'> | |
17 | + <% if @page.display_hits? %> | |
18 | + <div id="article-hits"> | |
19 | + <%= n_('Viewed one time', 'Viewed %{num} times', @page.hits) % { :num => @page.hits } %> | |
20 | + </div> | |
21 | + <% end %> | |
22 | + | |
23 | + <% if @page.license.present? %> | |
24 | + <div id="article-license"> | |
25 | + <%= _('Licensed under %s') % (@page.license.url.present? ? link_to(@page.license.name, @page.license.url, :target => '_blank') : @page.license.name) %> | |
26 | + </div> | |
27 | + <% end %> | |
28 | + </div> | |
29 | +<% end %> | ... | ... |
... | ... | @@ -0,0 +1,41 @@ |
1 | +<div class="event-card"> | |
2 | + <div class="event-image"> | |
3 | + <% if event.image %> | |
4 | + <%= image_tag(event.image.public_filename(:big)) %> | |
5 | + <% end %> | |
6 | + </div> | |
7 | + <div class="about-event"> | |
8 | + <% if event.start_date.present? || event.end_date.present? %> | |
9 | + <span class="event-date"> | |
10 | + <%= show_period(event.start_date, event.end_date) %> | |
11 | + </span> | |
12 | + <% end %> | |
13 | + <% if event.link.present? %> | |
14 | + <span class="event-link"> | |
15 | + <%= link_to event.link, event.link %> | |
16 | + </span> | |
17 | + <% end %> | |
18 | + <% if event.address.present? %> | |
19 | + <span class="event-address"> | |
20 | + <span> | |
21 | + <%= event.address %> | |
22 | + </span> | |
23 | + </span> | |
24 | + <% end %> | |
25 | + </div> | |
26 | +</div> | |
27 | + | |
28 | +<div class="event-body"> | |
29 | + <% if format == 'short' %> | |
30 | + <%= display_short_format event, :comments_link => false, :read_more_link => false %> | |
31 | + <% else %> | |
32 | + <% unless event.abstract.blank? %> | |
33 | + <div class="event-lead"> | |
34 | + <%= event.article_lead %> | |
35 | + </div> | |
36 | + <% end %> | |
37 | + <div class="event-content"> | |
38 | + <%= event.body %> | |
39 | + </div> | |
40 | + <% end %> | |
41 | +</div> | ... | ... |
app/views/content_viewer/view_page.html.erb
... | ... | @@ -24,22 +24,6 @@ |
24 | 24 | <%= render :partial => 'article_toolbar' %> |
25 | 25 | </div> |
26 | 26 | |
27 | -<% if @page.display_hits? || @page.license.present? %> | |
28 | - <div id='article-sub-header'> | |
29 | - <% if @page.display_hits? %> | |
30 | - <div id="article-hits"> | |
31 | - <%= n_('Viewed one time', 'Viewed %{num} times', @page.hits) % { :num => @page.hits } %> | |
32 | - </div> | |
33 | - <% end %> | |
34 | - | |
35 | - <% if @page.license.present? %> | |
36 | - <div id="article-license"> | |
37 | - <%= _('Licensed under %s') % (@page.license.url.present? ? link_to(@page.license.name, @page.license.url, :target => '_blank') : @page.license.name) %> | |
38 | - </div> | |
39 | - <% end %> | |
40 | - </div> | |
41 | -<% end %> | |
42 | - | |
43 | 27 | <% if NOOSFERO_CONF['addthis_enabled'] %> |
44 | 28 | <%= render :partial => 'addthis' %> |
45 | 29 | <% end %> |
... | ... | @@ -47,6 +31,12 @@ |
47 | 31 | <% cache(@page.cache_key(params, user, language)) do %> |
48 | 32 | <div class="<%="article-body article-body-" + @page.css_class_name %>"> |
49 | 33 | <% options = @page.image? ? {:gallery_view => true} : {} %> |
34 | + <% if @page.image.present? && !@page.event? %> | |
35 | + <div class="article-body-img"> | |
36 | + <%= image_tag(@page.image.public_filename) %> | |
37 | + <p><%= @page.image.label%></p> | |
38 | + </div> | |
39 | + <% end %> | |
50 | 40 | <%= article_to_html(@page, options) %> |
51 | 41 | <br style="clear:both" /> |
52 | 42 | </div> <!-- end class="article-body" --> | ... | ... |
app/views/layouts/application-ng.html.erb
app/views/manage_products/_categories_autocomplete.html.erb
0 → 100644
... | ... | @@ -0,0 +1,8 @@ |
1 | +<%= text_field_tag 'product_category_id', '', :placeholder => _('type a category for the product') %> | |
2 | + | |
3 | +<%= javascript_include_tag '/javascripts/product_categories.js' %> | |
4 | +<%= javascript_tag do %> | |
5 | + product_categories.autocomplete.search_url = <%= url_for(:controller => :manage_products, :action => :search_categories).to_json %> | |
6 | + product_categories.autocomplete.select_url = <%= url_for(:controller => :manage_products, :action => :show_category_tree).to_json %> | |
7 | + product_categories.autocomplete.load('#product_category_id') | |
8 | +<% end %> | ... | ... |
app/views/manage_products/_selected_category_tree.html.erb
0 → 100644
app/views/manage_products/edit_category.html.erb
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | |
17 | 17 | <h3><%= _('Edit category of this product:') %></h3> |
18 | 18 | |
19 | - <%= categories_container(selects_for_all_ancestors(@category), hierarchy_category_navigation(@category, :make_links => true)) %> | |
19 | + <%= render 'manage_products/selected_category_tree' %> | |
20 | 20 | |
21 | 21 | <div id='categories_selection_actionbar'> |
22 | 22 | <%= button(:back, _('Back to product'), :action => 'show', :id => @product) %> | ... | ... |
app/views/shared/_change_image.html.erb
1 | - <%= i.file_field( :uploaded_data, { :onchange => 'updateImg(this.value)' } ) %> | |
2 | - <%= button_to_function(:cancel,_('Cancel'),"jQuery('#change-image-link').show(); jQuery('#change-image').html('')", :id => 'cancel-change-image-link', :style => 'display: none')%> | |
1 | +<%= i.file_field( :uploaded_data, { :onchange => 'updateImg(this.value)' } ) %> | |
2 | +<%= labelled_form_field(_("Image Label:"), i.text_field(:label)) %> | |
3 | +<%= button_to_function(:cancel,_('Cancel'),"jQuery('#change-image-link').show(); jQuery('#change-image').html('')", :id => 'cancel-change-image-link', :style => 'display: none')%> | ... | ... |
app/views/shared/_content_item.html.erb
... | ... | @@ -4,8 +4,8 @@ |
4 | 4 | <%= display_content_icon(content) %> |
5 | 5 | </div> |
6 | 6 | <span class="item-description"> |
7 | - <%= link_to(short_filename_upper_ext(content.name), content.url) %> | |
7 | + <%= link_to(content.name, content.url) %> | |
8 | 8 | </span> |
9 | 9 | <span class="item-date"><%= _("Published at: #{show_date(content.updated_at)}") %></span> |
10 | 10 | </div> |
11 | -</div> | |
12 | 11 | \ No newline at end of file |
12 | +</div> | ... | ... |
db/migrate/20140708123314_index_role_assignments_filtered_fields.rb
0 → 100644
... | ... | @@ -0,0 +1,15 @@ |
1 | +class IndexRoleAssignmentsFilteredFields < ActiveRecord::Migration | |
2 | + | |
3 | + def self.up | |
4 | + add_index :role_assignments, [:accessor_id, :accessor_type] | |
5 | + add_index :role_assignments, [:accessor_id, :accessor_type, :role_id], name: :index_on_role_assigments_accessor_role | |
6 | + add_index :role_assignments, [:resource_id, :resource_type] | |
7 | + add_index :role_assignments, [:resource_id, :resource_type, :role_id], name: :index_on_role_assigments_resource_role | |
8 | + add_index :role_assignments, [:accessor_id, :accessor_type, :resource_id, :resource_type], name: :index_on_role_assigments_accessor_resource_role | |
9 | + add_index :profiles, [:type] | |
10 | + add_index :profiles, [:visible] | |
11 | + add_index :profiles, [:enabled] | |
12 | + add_index :profiles, [:validated] | |
13 | + end | |
14 | + | |
15 | +end | ... | ... |
db/schema.rb
... | ... | @@ -11,7 +11,7 @@ |
11 | 11 | # |
12 | 12 | # It's strongly recommended to check this file into your version control system. |
13 | 13 | |
14 | -ActiveRecord::Schema.define(:version => 20150602142030) do | |
14 | +ActiveRecord::Schema.define(:version => 20150603182105) do | |
15 | 15 | |
16 | 16 | create_table "abuse_reports", :force => true do |t| |
17 | 17 | t.integer "reporter_id" |
... | ... | @@ -376,6 +376,7 @@ ActiveRecord::Schema.define(:version => 20150602142030) do |
376 | 376 | t.integer "width" |
377 | 377 | t.integer "height" |
378 | 378 | t.boolean "thumbnails_processed", :default => false |
379 | + t.string "label", :default => "" | |
379 | 380 | end |
380 | 381 | |
381 | 382 | add_index "images", ["parent_id"], :name => "index_images_on_parent_id" | ... | ... |
... | ... | @@ -0,0 +1,30 @@ |
1 | +Feature: article visualization | |
2 | + As a user | |
3 | + I want to change view modes | |
4 | + In order to see articles in fullscreen or not in fullscreen | |
5 | + | |
6 | + Background: | |
7 | + Given the following users | |
8 | + | login | name | | |
9 | + | joaosilva | Joao Silva | | |
10 | + And "joaosilva" has no articles | |
11 | + And the following articles | |
12 | + | owner | name | body | | |
13 | + | joaosilva | Sample Article | This is an article | | |
14 | + And I am logged in as "joaosilva" | |
15 | + | |
16 | + @selenium | |
17 | + Scenario: viewing the article in fullscreen by default | |
18 | + Given I go to /joaosilva/sample-article?fullscreen=1 | |
19 | + Then I should see "Exit full screen" | |
20 | + | |
21 | + @selenium | |
22 | + Scenario: viewing the article not in fullscreen by default | |
23 | + Given I go to /joaosilva/sample-article | |
24 | + Then I should see "Full screen" | |
25 | + | |
26 | + @selenium | |
27 | + Scenario: changing the view mode from not in fullscreen to fullscreen | |
28 | + Given I go to /joaosilva/sample-article | |
29 | + And I follow "Full screen" | |
30 | + Then I should see "Exit full screen" | ... | ... |
features/events.feature
lib/short_filename.rb
... | ... | @@ -1,21 +0,0 @@ |
1 | -module ShortFilename | |
2 | - | |
3 | - def short_filename(filename, limit_chars = 43) | |
4 | - extname = File.extname(filename) | |
5 | - basename = File.basename(filename,extname) | |
6 | - return shrink(basename, extname, limit_chars) + extname | |
7 | - end | |
8 | - | |
9 | - def short_filename_upper_ext(filename, limit_chars = 43) | |
10 | - extname = File.extname(filename) | |
11 | - display_name = shrink(File.basename(filename, extname), extname, limit_chars) | |
12 | - return extname.present? ? (display_name + ' - ' + extname.upcase.delete(".")) : display_name | |
13 | - end | |
14 | - | |
15 | - def shrink(filename, extname, limit_chars) | |
16 | - return filename if filename.size <= limit_chars | |
17 | - str_complement = '(...)' | |
18 | - return filename[0..(limit_chars - extname.size - str_complement.size - 1)] + str_complement | |
19 | - end | |
20 | - | |
21 | -end |
plugins/context_content/views/blocks/context_content.html.erb
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | <%= instance_eval(&block.content_image(content)) if block.show_image %> |
7 | 7 | </div> |
8 | 8 | <% if block.show_name %> |
9 | - <div class="name"><%= short_filename(content.name, 30) %></div> | |
9 | + <div class="name"><%= content.name %></div> | |
10 | 10 | <% end %> |
11 | 11 | </a> |
12 | 12 | </span> | ... | ... |
plugins/metadata/lib/ext/product.rb
... | ... | @@ -7,7 +7,7 @@ class Product |
7 | 7 | url: proc{ |p, plugin| plugin.og_url_for p.url }, |
8 | 8 | gr_hascurrencyvalue: proc{ |p, plugin| p.price.to_f }, |
9 | 9 | gr_hascurrency: proc{ |p, plugin| p.environment.currency_unit }, |
10 | - title: proc{ |a, plugin| "#{p.name} - #{p.profile.name}" }, | |
10 | + title: proc{ |p, plugin| "#{p.name} - #{p.profile.name}" if p }, | |
11 | 11 | description: proc{ |p, plugin| ActionView::Base.full_sanitizer.sanitize p.description }, |
12 | 12 | |
13 | 13 | image: proc{ |p, plugin| "#{p.environment.top_url}#{p.image.public_filename}" if p.image }, |
... | ... | @@ -17,7 +17,7 @@ class Product |
17 | 17 | |
18 | 18 | see_also: [], |
19 | 19 | site_name: proc{ |p, plugin| plugin.og_url_for p.profile.url }, |
20 | - updated_time: proc{ |p, plugin| p.updated_at.iso8601 }, | |
20 | + updated_time: proc{ |p, plugin| p.updated_at.iso8601 if p.updated_at }, | |
21 | 21 | |
22 | 22 | 'locale:locale' => proc{ |p, plugin| p.environment.default_language }, |
23 | 23 | 'locale:alternate' => proc{ |p, plugin| p.environment.languages - [p.environment.default_language] if p.environment.languages }, | ... | ... |
plugins/metadata/test/functional/home_controller_test.rb
... | ... | @@ -12,7 +12,7 @@ class HomeControllerTest < ActionController::TestCase |
12 | 12 | @response = ActionController::TestResponse.new |
13 | 13 | |
14 | 14 | Noosfero::Plugin.stubs(:all).returns([MetadataPlugin.name]) |
15 | - Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([MetadataPlugin.new]) | |
15 | + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([MetadataPlugin.new(@controller)]) | |
16 | 16 | end |
17 | 17 | |
18 | 18 | should 'display meta tags for social media' do | ... | ... |
plugins/metadata/test/functional/manage_products_controller_test.rb
0 → 100644
... | ... | @@ -0,0 +1,27 @@ |
1 | +require 'test_helper' | |
2 | +require 'home_controller' | |
3 | + | |
4 | +# Re-raise errors caught by the controller. | |
5 | +class ManageProductsController; def rescue_action(e) raise e end; end | |
6 | + | |
7 | +class ManageProductsControllerTest < ActionController::TestCase | |
8 | + | |
9 | + def setup | |
10 | + @controller = ManageProductsController.new | |
11 | + @request = ActionController::TestRequest.new | |
12 | + @response = ActionController::TestResponse.new | |
13 | + @enterprise = fast_create(Enterprise, name: 'test', identifier: 'test_ent') | |
14 | + @user = create_user_with_permission('test_user', 'manage_products', @enterprise) | |
15 | + @environment = @enterprise.environment | |
16 | + @environment.enable('products_for_enterprises') | |
17 | + login_as :test_user | |
18 | + | |
19 | + Noosfero::Plugin.stubs(:all).returns([MetadataPlugin.name]) | |
20 | + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([MetadataPlugin.new(@controller)]) | |
21 | + end | |
22 | + | |
23 | + should "not crash on new products" do | |
24 | + get :new, profile: @enterprise.identifier | |
25 | + end | |
26 | + | |
27 | +end | ... | ... |
plugins/shopping_cart/lib/shopping_cart_plugin.rb
1 | 1 | class ShoppingCartPlugin < Noosfero::Plugin |
2 | + include ModalHelper | |
3 | + include ActionView::Helpers::UrlHelper | |
2 | 4 | |
3 | 5 | class << self |
4 | 6 | def plugin_name |
... | ... | @@ -63,4 +65,8 @@ class ShoppingCartPlugin < Noosfero::Plugin |
63 | 65 | |
64 | 66 | buttons |
65 | 67 | end |
68 | + | |
69 | + def controller | |
70 | + context | |
71 | + end | |
66 | 72 | end | ... | ... |
plugins/shopping_cart/lib/shopping_cart_plugin/cart_helper.rb
... | ... | @@ -42,7 +42,7 @@ module ShoppingCartPlugin::CartHelper |
42 | 42 | else |
43 | 43 | delivery = Product.new(:name => delivery_option || _('Delivery'), :price => settings.delivery_options[delivery_option]) |
44 | 44 | end |
45 | - delivery.save(false) | |
45 | + delivery.save(validate: false) | |
46 | 46 | items << [delivery.id, ''] |
47 | 47 | end |
48 | 48 | ... | ... |
plugins/shopping_cart/test/unit/shopping_cart_plugin/cart_helper_test.rb
... | ... | @@ -41,5 +41,19 @@ class ShoppingCartPlugin::CartHelperTest < ActiveSupport::TestCase |
41 | 41 | assert_equal "#{environment.currency_unit}13#{environment.currency_separator}70", float_to_currency_cart(value,environment) |
42 | 42 | end |
43 | 43 | |
44 | -end | |
44 | + should 'return a table of items' do | |
45 | + enterprise = Enterprise.new(name: "Test Enterprise", identifier: "test-enterprise") | |
46 | + enterprise.environment = Environment.default | |
47 | + enterprise.save! | |
48 | + | |
49 | + product_category = fast_create(ProductCategory, :name => 'Products') | |
50 | + product = fast_create(Product, :name => 'test product1', :product_category_id => product_category.id, :profile_id => enterprise.id) | |
51 | + setting = Noosfero::Plugin::Settings.new(enterprise, ShoppingCartPlugin) | |
52 | + setting.delivery = true | |
53 | + setting.save! | |
54 | + | |
55 | + assert_match 'table id="cart-items-table"', items_table([product], enterprise) | |
56 | + assert_match '<td>test product1</td>', items_table([product], enterprise) | |
57 | + end | |
45 | 58 | |
59 | +end | ... | ... |
plugins/shopping_cart/views/cart.html.erb
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | <a href="cart:clean" onclick="Cart.clean(this); return false" class="cart-clean"><%=_('Clean basket')%></a> |
6 | 6 | <ul class="cart-items"></ul> |
7 | 7 | <div class="cart-total"><%=_('Total:')%> <b></b></div> |
8 | - <a href="/plugin/shopping_cart/buy" class="cart-buy modal"><%=_('Shopping checkout')%></a> | |
8 | + <%= modal_link_to _('Shopping checkout'), { controller: 'shopping_cart_plugin', action: 'buy' }, { class: "cart-buy modal" } %> | |
9 | 9 | </div> |
10 | 10 | <a href="#" onclick="Cart.toggle(this); return false" class="cart-toggle"> |
11 | 11 | <span class="str-show"><%=_('Show basket')%></span> | ... | ... |
plugins/shopping_cart/views/shopping_cart_plugin/buy.html.erb
... | ... | @@ -24,7 +24,6 @@ |
24 | 24 | <% end %> |
25 | 25 | <% delivery_option = @settings.delivery_options.first && @settings.delivery_options.first.first %> |
26 | 26 | <%= items_table(@cart[:items], @profile, delivery_option) %> |
27 | - <%= link_to_function '', "noosfero.modal.close();", :class => 'cart-box-close icon-cancel' %> | |
28 | 27 | </div> |
29 | 28 | |
30 | 29 | <%= javascript_include_tag '../plugins/shopping_cart/buy' %> | ... | ... |
plugins/shopping_cart/views/shopping_cart_plugin_profile/buy.html.erb
plugins/social_share_privacy/lib/social_share_privacy_plugin.rb
... | ... | @@ -19,12 +19,14 @@ class SocialSharePrivacyPlugin < Noosfero::Plugin |
19 | 19 | def article_extra_contents(article) |
20 | 20 | proc do |
21 | 21 | settings = Noosfero::Plugin::Settings.new(environment, SocialSharePrivacyPlugin) |
22 | + modules = settings.get_setting(:networks).map { |service| "/plugins/social_share_privacy/socialshareprivacy/javascripts/modules/#{service}.js" } | |
22 | 23 | locale = FastGettext.locale |
23 | - javascript_include_tag('plugins/social_share_privacy/socialshareprivacy/javascripts/socialshareprivacy.js') + | |
24 | - javascript_include_tag('plugins/social_share_privacy/socialshareprivacy/javascripts/localstorage.js') + | |
25 | - javascript_include_tag(settings.get_setting(:networks).map { |service| "plugins/social_share_privacy/socialshareprivacy/javascripts/modules/#{service}.js" }) + | |
26 | - (locale != 'en' ? javascript_include_tag("plugins/social_share_privacy/socialshareprivacy/javascripts/locale/jquery.socialshareprivacy.min.#{locale}.js") : '') + | |
27 | - javascript_tag("jQuery.fn.socialSharePrivacy.settings.path_prefix = '../../plugins/social_share_privacy/socialshareprivacy/'; jQuery.fn.socialSharePrivacy.settings.order = #{settings.get_setting(:networks)}; jQuery(document).ready(function () { jQuery('.social-buttons').socialSharePrivacy({info_link_target: '_blank'});});") + | |
24 | + javascript_include_tag('/plugins/social_share_privacy/socialshareprivacy/javascripts/socialshareprivacy.js') + | |
25 | + javascript_include_tag('/plugins/social_share_privacy/socialshareprivacy/javascripts/localstorage.js') + | |
26 | + (modules.present? ? javascript_include_tag(*modules) : '') + | |
27 | + javascript_include_tag("/plugins/social_share_privacy/socialshareprivacy/javascripts/modules/facebook.js") + | |
28 | + (locale != 'en' ? javascript_include_tag("/plugins/social_share_privacy/socialshareprivacy/javascripts/locale/jquery.socialshareprivacy.min.#{locale}.js") : '') + | |
29 | + javascript_tag("jQuery.fn.socialSharePrivacy.settings.path_prefix = '/plugins/social_share_privacy/socialshareprivacy/'; jQuery.fn.socialSharePrivacy.settings.order = #{settings.get_setting(:networks)}; jQuery(document).ready(function () { jQuery('.social-buttons').socialSharePrivacy({info_link_target: '_blank'});});") + | |
28 | 30 | content_tag(:div, '', :class => "social-buttons") |
29 | 31 | end |
30 | 32 | end | ... | ... |
plugins/social_share_privacy/test/functional/content_viewer_controller_test.rb
... | ... | @@ -23,7 +23,7 @@ class ContentViewerControllerTest < ActionController::TestCase |
23 | 23 | |
24 | 24 | get :view_page, :profile => @profile.identifier, :page => ['test'] |
25 | 25 | |
26 | - assert_tag :tag => 'script', :attributes => {:src => /\/javascripts\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/socialshareprivacy\.js\??\d*/} | |
26 | + assert_tag :tag => 'script', :attributes => {:src => /\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/socialshareprivacy\.js\??\d*/} | |
27 | 27 | assert_tag :tag => 'div', :attributes => {:class => "social-buttons"} |
28 | 28 | end |
29 | 29 | |
... | ... | @@ -34,8 +34,8 @@ class ContentViewerControllerTest < ActionController::TestCase |
34 | 34 | |
35 | 35 | get :view_page, :profile => @profile.identifier, :page => ['test'] |
36 | 36 | |
37 | - assert_tag :tag => 'script', :attributes => {:src => /\/javascripts\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/modules\/twitter\.js\??\d*/} | |
38 | - assert_tag :tag => 'script', :attributes => {:src => /\/javascripts\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/modules\/gplus\.js\??\d*/} | |
37 | + assert_tag :tag => 'script', :attributes => {:src => /\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/modules\/twitter\.js\??\d*/} | |
38 | + assert_tag :tag => 'script', :attributes => {:src => /\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/modules\/gplus\.js\??\d*/} | |
39 | 39 | end |
40 | 40 | |
41 | 41 | should 'add javascript with string translations if not english' do |
... | ... | @@ -45,12 +45,12 @@ class ContentViewerControllerTest < ActionController::TestCase |
45 | 45 | |
46 | 46 | get :view_page, :profile => @profile.identifier, :page => ['test'] |
47 | 47 | |
48 | - assert_tag :tag => 'script', :attributes => {:src => /\/javascripts\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/locale\/jquery\.socialshareprivacy\.min\.pt\.js\??\d*/} | |
48 | + assert_tag :tag => 'script', :attributes => {:src => /\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/locale\/jquery\.socialshareprivacy\.min\.pt\.js\??\d*/} | |
49 | 49 | |
50 | 50 | FastGettext.stubs(:locale).returns('en') |
51 | 51 | |
52 | 52 | get :view_page, :profile => @profile.identifier, :page => ['test'] |
53 | 53 | |
54 | - assert_no_tag :tag => 'script', :attributes => {:src => /\/javascripts\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/locale\/jquery\.socialshareprivacy\.min\.en\.js\??\d*/} | |
54 | + assert_no_tag :tag => 'script', :attributes => {:src => /\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/locale\/jquery\.socialshareprivacy\.min\.en\.js\??\d*/} | |
55 | 55 | end |
56 | 56 | end | ... | ... |
public/designs/themes/base/style.css
... | ... | @@ -1061,15 +1061,18 @@ hr.pre-posts, hr.sep-posts { |
1061 | 1061 | text-decoration: none; |
1062 | 1062 | } |
1063 | 1063 | |
1064 | -#content .main-block .created-at { | |
1064 | +#content .main-block .publishing-info { | |
1065 | 1065 | text-align: left; |
1066 | 1066 | color: #AAA; |
1067 | + font-size: 11px; | |
1068 | + /*padding-top: 20px;*/ | |
1069 | + margin-bottom:15px; | |
1067 | 1070 | } |
1068 | -#content .main-block .created-at a { | |
1071 | +#content .main-block .publishing-info a { | |
1069 | 1072 | color: #AAA; |
1070 | 1073 | text-decoration: none; |
1071 | 1074 | } |
1072 | -#content .main-block .created-at a:hover { | |
1075 | +#content .main-block .publishing-info a:hover { | |
1073 | 1076 | color: #555; |
1074 | 1077 | text-decoration: underline; |
1075 | 1078 | } |
... | ... | @@ -1401,3 +1404,129 @@ table.profile th { |
1401 | 1404 | table#recaptcha_table tr:hover td { |
1402 | 1405 | background-color: #fff; |
1403 | 1406 | } |
1407 | + | |
1408 | +/* product cateogories */ | |
1409 | +#categories-container #product_category_id { | |
1410 | + font-size: 18px; | |
1411 | + width: 100%; | |
1412 | + margin-bottom: 8px; | |
1413 | +} | |
1414 | +#categories-container #product_category_id:focus { | |
1415 | + outline: none; | |
1416 | + border-color: green; | |
1417 | + box-shadow: 0 0 10px green; | |
1418 | + color:#333; | |
1419 | +} | |
1420 | + | |
1421 | +/************************* Article Page *****************************/ | |
1422 | + | |
1423 | +#article-header .preview { | |
1424 | + font-size: 15px; | |
1425 | +} | |
1426 | + | |
1427 | +.article-body-img { | |
1428 | + float: left; | |
1429 | + margin-right: 20px; | |
1430 | + margin-top: 5px; | |
1431 | +} | |
1432 | + | |
1433 | +#content #article .article-body .article-body-img img { | |
1434 | + height: auto; | |
1435 | + width: auto; | |
1436 | + min-height: 120px; | |
1437 | + max-height: 180px; | |
1438 | + max-width: 250px; | |
1439 | + background-position: center center; | |
1440 | + background-repeat: no-repeat; | |
1441 | +} | |
1442 | + | |
1443 | +#content #article .article-body .article-body-img p { | |
1444 | + margin-bottom: 10px; | |
1445 | + font-size: 10px; | |
1446 | + min-height: 20px; | |
1447 | +} | |
1448 | +/* Noosfero Events */ | |
1449 | + | |
1450 | +.event-card { | |
1451 | + float: left; | |
1452 | + padding-top: 25px; | |
1453 | + width: 494px; | |
1454 | + height: 116px; | |
1455 | + background-repeat: no-repeat; | |
1456 | + margin-bottom: 30px; | |
1457 | +} | |
1458 | + | |
1459 | +.event-image { | |
1460 | + position: relative; | |
1461 | + float: left; | |
1462 | + padding-right: 22px; | |
1463 | + max-width: 130px; | |
1464 | + height: 130px; | |
1465 | +} | |
1466 | + | |
1467 | +#content #article .article-body img{ | |
1468 | + max-height: 100%; | |
1469 | +} | |
1470 | + | |
1471 | +.about-event { | |
1472 | + position: relative; | |
1473 | + float: left; | |
1474 | + height: 160px; | |
1475 | + width: 300px; | |
1476 | + max-width: 300px; | |
1477 | +} | |
1478 | + | |
1479 | +.about-event > span { | |
1480 | + display: block; | |
1481 | + max-width: inherit; | |
1482 | + margin-left: 20px; | |
1483 | + padding-left: 21px; | |
1484 | + line-height: 13px; | |
1485 | + margin-right: 11px; | |
1486 | +} | |
1487 | + | |
1488 | +.about-event .event-date { | |
1489 | + margin-top: 3px; | |
1490 | +} | |
1491 | + | |
1492 | +.about-event .event-address { | |
1493 | + margin-top: 19px; | |
1494 | +} | |
1495 | + | |
1496 | +.about-event .event-address span { | |
1497 | + display: block; | |
1498 | + margin-left: 0px; | |
1499 | + margin-top: 4.4px; | |
1500 | + line-height: 14px; | |
1501 | +} | |
1502 | + | |
1503 | +.event-date { | |
1504 | + background: url('/images/calendar_date_select/calendar-icon.png') no-repeat left center; | |
1505 | + padding: 5px; | |
1506 | +} | |
1507 | + | |
1508 | +.event-link { | |
1509 | + background: url('/images/globe-icon.png') no-repeat left center; | |
1510 | + margin-top: 18px; | |
1511 | +} | |
1512 | + | |
1513 | +.event-link a { | |
1514 | +} | |
1515 | + | |
1516 | +.event-address { | |
1517 | + background: url('/images/icone_pin.png') no-repeat left top; | |
1518 | +} | |
1519 | + | |
1520 | +.event-body { | |
1521 | + float: left; | |
1522 | +} | |
1523 | + | |
1524 | +.event-body .event-lead { | |
1525 | + font-size: 15px; | |
1526 | +} | |
1527 | + | |
1528 | +.event-body .event-content p { | |
1529 | + margin-top: 20px; | |
1530 | + width: 494px; | |
1531 | + padding-left: 2px; | |
1532 | +} | ... | ... |
283 Bytes
464 Bytes
51.9 KB
public/javascripts/application.js
... | ... | @@ -14,6 +14,7 @@ |
14 | 14 | *= require jquery.ba-bbq.min.js |
15 | 15 | *= require jquery.tokeninput.js |
16 | 16 | *= require jquery-timepicker-addon/dist/jquery-ui-timepicker-addon.js |
17 | +*= require select-or-die/_src/selectordie | |
17 | 18 | *= require inputosaurus.js |
18 | 19 | *= require reflection.js |
19 | 20 | *= require rails.js |
... | ... | @@ -830,7 +831,7 @@ Array.min = function(array) { |
830 | 831 | |
831 | 832 | function hideAndGetUrl(link) { |
832 | 833 | document.body.style.cursor = 'wait'; |
833 | - link.hide(); | |
834 | + jQuery(link).hide(); | |
834 | 835 | url = jQuery(link).attr('href'); |
835 | 836 | jQuery.get(url, function( data ) { |
836 | 837 | document.body.style.cursor = 'default'; |
... | ... | @@ -1178,7 +1179,10 @@ window.isHidden = function isHidden() { return (typeof(document.hidden) != 'unde |
1178 | 1179 | |
1179 | 1180 | function $_GET(id){ |
1180 | 1181 | var a = new RegExp(id+"=([^&#=]*)"); |
1181 | - return decodeURIComponent(a.exec(window.location.search)[1]); | |
1182 | + var result_of_search = a.exec(window.location.search) | |
1183 | + if(result_of_search != null){ | |
1184 | + return decodeURIComponent(result_of_search[1]); | |
1185 | + } | |
1182 | 1186 | } |
1183 | 1187 | |
1184 | 1188 | var fullwidth=false; |
... | ... | @@ -1206,4 +1210,3 @@ function fullscreenPageLoad(itemId){ |
1206 | 1210 | } |
1207 | 1211 | }); |
1208 | 1212 | } |
1209 | - | ... | ... |
public/javascripts/jquery.tokeninput.js
... | ... | @@ -345,7 +345,7 @@ $.TokenList = function (input, url_or_data, options) { |
345 | 345 | dropdown.appendTo("body"); |
346 | 346 | if (!settings.permanentDropdown) |
347 | 347 | dropdown.appendTo("body"); |
348 | - else | |
348 | + else | |
349 | 349 | $(input).after(dropdown.show()); |
350 | 350 | |
351 | 351 | if (settings.permanentDropdown || settings.showAllResults) { |
... | ... | @@ -382,7 +382,7 @@ $.TokenList = function (input, url_or_data, options) { |
382 | 382 | if(li_data && li_data.length) { |
383 | 383 | $.each(li_data, function (index, value) { |
384 | 384 | insert_token(value); |
385 | - checkTokenLimit(); | |
385 | + checkTokenLimit({init: true}); | |
386 | 386 | }); |
387 | 387 | } |
388 | 388 | |
... | ... | @@ -425,12 +425,12 @@ $.TokenList = function (input, url_or_data, options) { |
425 | 425 | // Private functions |
426 | 426 | // |
427 | 427 | |
428 | - function checkTokenLimit() { | |
428 | + function checkTokenLimit(options) { | |
429 | 429 | if(settings.tokenLimit !== null && token_count >= settings.tokenLimit) { |
430 | 430 | input_box.hide(); |
431 | 431 | hide_dropdown(); |
432 | 432 | return; |
433 | - } else { | |
433 | + } else if (options && !options.init) { | |
434 | 434 | input_box.focus(); |
435 | 435 | } |
436 | 436 | } |
... | ... | @@ -618,7 +618,7 @@ $.TokenList = function (input, url_or_data, options) { |
618 | 618 | if (!settings.showAllResults) |
619 | 619 | dropdown.empty(); |
620 | 620 | selected_dropdown_item = null; |
621 | - } | |
621 | + } | |
622 | 622 | if (settings.showAllResults) |
623 | 623 | show_dropdown_hint(); |
624 | 624 | } |
... | ... | @@ -728,7 +728,7 @@ $.TokenList = function (input, url_or_data, options) { |
728 | 728 | item.addClass(settings.classes.selectedDropdownItem); |
729 | 729 | selected_dropdown_item = item.get(0); |
730 | 730 | |
731 | - isBefore = item[0].offsetTop <= (dropdown[0].scrollTop + dropdown[0].scrollWidth); | |
731 | + isBefore = item[0].offsetTop <= (dropdown[0].scrollTop + dropdown[0].scrollWidth); | |
732 | 732 | isAfter = item[0].offsetTop >= dropdown[0].scrollTop; |
733 | 733 | visible = isBefore && isAfter; |
734 | 734 | if (!visible) { | ... | ... |
... | ... | @@ -0,0 +1,40 @@ |
1 | +product_categories = { | |
2 | + | |
3 | + autocomplete: { | |
4 | + search_url: '', | |
5 | + select_url: '', | |
6 | + | |
7 | + load: function(elem) { | |
8 | + elem = jQuery(elem) | |
9 | + | |
10 | + elem.autocomplete({ | |
11 | + minLength: 3, | |
12 | + selectFirst: true, | |
13 | + | |
14 | + //define callback to retrieve results | |
15 | + source: function(req, add) { | |
16 | + //pass request to server | |
17 | + //The alt attribute contains the wordpress callback action | |
18 | + var params = { term: req.term }; | |
19 | + jQuery.getJSON(product_categories.autocomplete.search_url, params, function(data) { | |
20 | + add(data); | |
21 | + }); | |
22 | + }, | |
23 | + | |
24 | + focus: function( event, ui ) { | |
25 | + jQuery(this).val(ui.item.label); | |
26 | + return false; | |
27 | + }, | |
28 | + | |
29 | + select: function(e, ui) { | |
30 | + jQuery('#categories-container').load(product_categories.autocomplete.select_url, {category_id: ui.item.value}) | |
31 | + | |
32 | + jQuery(this).val("") | |
33 | + }, | |
34 | + | |
35 | + }); | |
36 | + | |
37 | + }, | |
38 | + }, | |
39 | + | |
40 | +}; | ... | ... |
public/stylesheets/application.scss
... | ... | @@ -1054,6 +1054,11 @@ code input { |
1054 | 1054 | margin-top: 10px; |
1055 | 1055 | display: none; |
1056 | 1056 | } |
1057 | + | |
1058 | +#change-image { | |
1059 | + display: table-caption; | |
1060 | +} | |
1061 | + | |
1057 | 1062 | .zoomable-image { |
1058 | 1063 | position: relative; |
1059 | 1064 | display: inline-block; |
... | ... | @@ -1520,13 +1525,13 @@ a.comment-picture { |
1520 | 1525 | text-align: right; |
1521 | 1526 | color: gray; |
1522 | 1527 | } |
1523 | -#content .created-at { | |
1528 | +#content .publishing-info { | |
1524 | 1529 | color: gray; |
1525 | 1530 | font-size: 12px; |
1526 | 1531 | display: block; |
1527 | 1532 | text-align: right; |
1528 | 1533 | } |
1529 | -#content .blog-post .created-at { | |
1534 | +#content .blog-post .publishing-info { | |
1530 | 1535 | text-align: left; |
1531 | 1536 | } |
1532 | 1537 | #content #article .pagination .prev_page { |
... | ... | @@ -1598,7 +1603,7 @@ div.article-body p img { |
1598 | 1603 | .blog-post.not-published a { |
1599 | 1604 | text-decoration: none; |
1600 | 1605 | } |
1601 | -#content .blog-post.not-published .created-at { | |
1606 | +#content .blog-post.not-published .publishing-info { | |
1602 | 1607 | text-align: left; |
1603 | 1608 | } |
1604 | 1609 | .blog-post.not-published .metadata { | ... | ... |
script/gitlab-ci
... | ... | @@ -1,56 +0,0 @@ |
1 | -#!/usr/bin/env ruby | |
2 | - | |
3 | -# These just forward the signals to the whole process group and | |
4 | -# then immediately exit. | |
5 | -pgid = Process.getpgid Process.pid | |
6 | -Signal.trap(:TERM) { Process.kill(:TERM, -pgid); exit } | |
7 | -Signal.trap(:INT) { Process.kill(:INT, -pgid); exit } | |
8 | - | |
9 | -def run command, options = {} | |
10 | - command = "#{command} 2>&1 > /dev/null" if options[:output] == false | |
11 | - #command = "time #{command}" unless options[:runtime] == false | |
12 | - puts "== #{command}" | |
13 | - system command | |
14 | -end | |
15 | - | |
16 | -@id = (0...10).map{ ('a'..'z').to_a[rand(26)] }.join | |
17 | -@db = "gitlab-ci-#{@id}" | |
18 | - | |
19 | -def config | |
20 | - require 'yaml' | |
21 | - db_config = { | |
22 | - 'adapter' => 'postgresql', 'encoding' => 'unicode', | |
23 | - 'database' => @db, 'username' => ENV['USER'], | |
24 | - } | |
25 | - File.write 'config/database.yml', YAML.dump('test' => db_config, 'development' => db_config) | |
26 | -end | |
27 | - | |
28 | -def prepare | |
29 | - run("createdb #{@db}") and | |
30 | - run('mkdir -p tmp/pids log') and | |
31 | - run('bundle check || bundle install') and | |
32 | - run('rake db:schema:load', output: false) and | |
33 | - run('script/noosfero-plugins disableall') and | |
34 | - run('rake db:migrate') | |
35 | -end | |
36 | - | |
37 | -def test | |
38 | - %w[ | |
39 | - test:units | |
40 | - test:functionals | |
41 | - test:integration | |
42 | - cucumber | |
43 | - test:noosfero_plugins | |
44 | - ].each do |task| | |
45 | - run "rake #{task}" | |
46 | - end | |
47 | -end | |
48 | - | |
49 | -def cleanup | |
50 | - run "dropdb #{@db}" | |
51 | -end | |
52 | - | |
53 | -ret = config and prepare and test | |
54 | -cleanup | |
55 | - | |
56 | -exit (if ret == true then 0 else 1 end) |
script/install-dependencies/debian-wheezy.sh
test/functional/cms_controller_test.rb
... | ... | @@ -223,6 +223,20 @@ class CmsControllerTest < ActionController::TestCase |
223 | 223 | assert_equal profile, a.last_changed_by |
224 | 224 | end |
225 | 225 | |
226 | + should 'be able to set label to article image' do | |
227 | + login_as(profile.identifier) | |
228 | + post :new, :type => TextileArticle.name, :profile => profile.identifier, | |
229 | + :article => { | |
230 | + :name => 'adding-image-label', | |
231 | + :image_builder => { | |
232 | + :uploaded_data => fixture_file_upload('/files/tux.png', 'image/png'), | |
233 | + :label => 'test-label' | |
234 | + } | |
235 | + } | |
236 | + a = Article.last | |
237 | + assert_equal a.image.label, 'test-label' | |
238 | + end | |
239 | + | |
226 | 240 | should 'edit by using the correct template to display the editor depending on the mime-type' do |
227 | 241 | a = profile.articles.build(:name => 'test document') |
228 | 242 | a.save! |
... | ... | @@ -318,6 +332,20 @@ class CmsControllerTest < ActionController::TestCase |
318 | 332 | end |
319 | 333 | end |
320 | 334 | |
335 | + should 'be able to edit an image label' do | |
336 | + image = fast_create(Image, :content_type => 'image/png', :filename => 'event-image.png', :label => 'test_label', :size => 1014) | |
337 | + article = fast_create(Article, :profile_id => profile.id, :name => 'test_label_article', :body => 'test_content') | |
338 | + article.image = image | |
339 | + article.save | |
340 | + assert_not_nil article | |
341 | + assert_not_nil article.image | |
342 | + assert_equal 'test_label', article.image.label | |
343 | + | |
344 | + post :edit, :profile => profile.identifier, :id => article.id, :article => {:image_builder => { :label => 'test_label_modified'}} | |
345 | + article.reload | |
346 | + assert_equal 'test_label_modified', article.image.label | |
347 | + end | |
348 | + | |
321 | 349 | should 'be able to upload more than one file at once' do |
322 | 350 | assert_difference 'UploadedFile.count', 2 do |
323 | 351 | post :upload_files, :profile => profile.identifier, :uploaded_files => [fixture_file_upload('/files/test.txt', 'text/plain'), fixture_file_upload('/files/rails.png', 'text/plain')] | ... | ... |
test/functional/content_viewer_controller_test.rb
... | ... | @@ -124,6 +124,19 @@ class ContentViewerControllerTest < ActionController::TestCase |
124 | 124 | assert_tag :tag => 'div', :attributes => { :id => 'article-tags' }, :descendant => { :content => /This article's tags:/ } |
125 | 125 | end |
126 | 126 | |
127 | + should "display image label on article image" do | |
128 | + page = TinyMceArticle.create!( | |
129 | + :profile => profile, | |
130 | + :name => 'myarticle', | |
131 | + :image_builder => { | |
132 | + :uploaded_data => fixture_file_upload('/files/tux.png', 'image/png'), | |
133 | + :label => 'test-label' | |
134 | + } | |
135 | + ) | |
136 | + get :view_page, page.url | |
137 | + assert_match /test-label/, @response.body | |
138 | + end | |
139 | + | |
127 | 140 | should "not display current article's tags" do |
128 | 141 | page = profile.articles.create!(:name => 'myarticle', :body => 'test article') |
129 | 142 | ... | ... |
test/unit/application_helper_test.rb
... | ... | @@ -564,18 +564,6 @@ class ApplicationHelperTest < ActionView::TestCase |
564 | 564 | assert_equal environment.theme, current_theme |
565 | 565 | end |
566 | 566 | |
567 | - should 'trunc to 15 chars the big filename' do | |
568 | - assert_equal 'AGENDA(...).mp3', short_filename('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3',15) | |
569 | - end | |
570 | - | |
571 | - should 'trunc to default limit the big filename' do | |
572 | - assert_equal 'AGENDA_CULTURA_-_FESTA_DE_VAQUEIRO(...).mp3', short_filename('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3') | |
573 | - end | |
574 | - | |
575 | - should 'does not trunc short filename' do | |
576 | - assert_equal 'filename.mp3', short_filename('filename.mp3') | |
577 | - end | |
578 | - | |
579 | 567 | should 'return nil when :show_balloon_with_profile_links_when_clicked is not enabled in environment' do |
580 | 568 | env = Environment.default |
581 | 569 | env.stubs(:enabled?).with(:show_balloon_with_profile_links_when_clicked).returns(false) | ... | ... |
test/unit/event_test.rb
... | ... | @@ -109,17 +109,20 @@ class EventTest < ActiveSupport::TestCase |
109 | 109 | end |
110 | 110 | |
111 | 111 | should 'provide nice display format' do |
112 | - e = build(Event, :start_date => Date.new(2008,1,1), :end_date => Date.new(2008,1,1), :link => 'http://www.myevent.org', :body => 'my somewhat short description') | |
112 | + event = build(Event, :start_date => Date.new(2008,1,1), :end_date => Date.new(2008,1,1), :link => 'http://www.myevent.org', :body => '<p>my somewhat short description</p>') | |
113 | + display = instance_eval(&event.to_html) | |
113 | 114 | |
114 | - assert_tag_in_string e.to_html, :content => Regexp.new("January 1, 2008") | |
115 | - assert_tag_in_string e.to_html, :content => 'my somewhat short description' | |
116 | - assert_tag_in_string e.to_html, :tag => 'a', :attributes => { :href => 'http://www.myevent.org' }, :content => 'http://www.myevent.org' | |
115 | + assert_tag_in_string display, :content => Regexp.new("January 1, 2008") | |
116 | + assert_tag_in_string display, :content => Regexp.new('my somewhat short description') | |
117 | + assert_tag_in_string display, :content => Regexp.new('http://www.myevent.org') | |
117 | 118 | end |
118 | 119 | |
119 | 120 | should 'not crash when body is blank' do |
120 | 121 | e = Event.new |
121 | 122 | assert_nil e.body |
122 | - assert_no_match(/_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____/, e.to_html) | |
123 | + assert_nothing_raised do | |
124 | + instance_eval(&e.to_html) | |
125 | + end | |
123 | 126 | end |
124 | 127 | |
125 | 128 | should 'add http:// to the link if not already present' do |
... | ... | @@ -141,10 +144,19 @@ class EventTest < ActiveSupport::TestCase |
141 | 144 | assert_equal '', a.link |
142 | 145 | end |
143 | 146 | |
147 | + should 'get the first paragraph' do | |
148 | + profile = create_user('testuser').person | |
149 | + event = create(Event, :profile => profile, :name => 'test', | |
150 | + :body => '<p>first paragraph </p><p>second paragraph </p>', | |
151 | + :link => 'www.colivre.coop.br', :start_date => Date.today) | |
152 | + | |
153 | + assert_match '<p>first paragraph </p>', event.first_paragraph | |
154 | + end | |
155 | + | |
144 | 156 | should 'not escape HTML in body' do |
145 | 157 | a = build(Event, :body => '<p>a paragraph of text</p>', :link => 'www.gnu.org') |
146 | 158 | |
147 | - assert_match '<p>a paragraph of text</p>', a.to_html | |
159 | + assert_match '<p>a paragraph of text</p>', instance_eval(&a.to_html) | |
148 | 160 | end |
149 | 161 | |
150 | 162 | should 'filter HTML in body' do |
... | ... | @@ -324,7 +336,7 @@ class EventTest < ActiveSupport::TestCase |
324 | 336 | environment = fast_create(Environment) |
325 | 337 | environment.languages = nil |
326 | 338 | profile = fast_create(Person, :environment_id => environment.id) |
327 | - | |
339 | + | |
328 | 340 | event = Event.new(:profile => profile) |
329 | 341 | |
330 | 342 | assert !event.translatable? |
... | ... | @@ -337,11 +349,11 @@ class EventTest < ActiveSupport::TestCase |
337 | 349 | event = fast_create(Event, :profile_id => profile.id) |
338 | 350 | |
339 | 351 | assert !event.translatable? |
340 | - | |
352 | + | |
341 | 353 | |
342 | 354 | environment.languages = ['en','pt','fr'] |
343 | 355 | environment.save |
344 | - event.reload | |
356 | + event.reload | |
345 | 357 | assert event.translatable? |
346 | 358 | end |
347 | 359 | ... | ... |
test/unit/short_filename_test.rb
... | ... | @@ -1,34 +0,0 @@ |
1 | -require_relative "../test_helper" | |
2 | - | |
3 | -class NoosferoFilenamesTest < ActiveSupport::TestCase | |
4 | - | |
5 | - include ShortFilename | |
6 | - | |
7 | - should 'trunc to 15 chars the big filename' do | |
8 | - assert_equal 'AGENDA(...).mp3', short_filename('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3',15) | |
9 | - end | |
10 | - | |
11 | - should 'trunc to default limit the big filename' do | |
12 | - assert_equal 'AGENDA_CULTURA_-_FESTA_DE_VAQUEIRO(...).mp3', short_filename('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3') | |
13 | - end | |
14 | - | |
15 | - should 'does not trunc short filename' do | |
16 | - assert_equal 'filename.mp3', short_filename('filename.mp3') | |
17 | - end | |
18 | - | |
19 | - should 'highlight the file extansion' do | |
20 | - assert_equal 'AGENDA(...) - MP3', short_filename_upper_ext('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3',15) | |
21 | - | |
22 | - assert_equal 'AGENDA - MP3', short_filename_upper_ext('AGENDA.mp3',15) | |
23 | - end | |
24 | - | |
25 | - should 'return the full filename if its size is smaller than the limit' do | |
26 | - assert_equal 'AGENDA', shrink('AGENDA', 'mp3', 15) | |
27 | - end | |
28 | - | |
29 | - should 'shrink the filename if its size is bigger than the limit' do | |
30 | - assert_equal 'AGENDA(...)', shrink('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA', 'mp3', 14) | |
31 | - end | |
32 | - | |
33 | -end | |
34 | - |