Commit 42b3475d1f217d929e20e076f1fffe0b7cf12cf7
Exists in
master
and in
20 other branches
Merge branch 'master' of gitlab.com:noosfero/noosfero
Showing
35 changed files
with
1489 additions
and
213 deletions
Show diff stats
app/controllers/application_controller.rb
... | ... | @@ -184,13 +184,7 @@ class ApplicationController < ActionController::Base |
184 | 184 | end |
185 | 185 | |
186 | 186 | include SearchTermHelper |
187 | - | |
188 | - def find_by_contents(asset, context, scope, query, paginate_options={:page => 1}, options={}) | |
189 | - scope = scope.with_templates(options[:template_id]) unless options[:template_id].blank? | |
190 | - search = plugins.dispatch_first(:find_by_contents, asset, scope, query, paginate_options, options) | |
191 | - register_search_term(query, scope.count, search[:results].count, context, asset) | |
192 | - search | |
193 | - end | |
187 | + include FindByContents | |
194 | 188 | |
195 | 189 | def find_suggestions(query, context, asset, options={}) |
196 | 190 | plugins.dispatch_first(:find_suggestions, query, context, asset, options) | ... | ... |
config/docker/dev/Dockerfile
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | # |
3 | 3 | # VERSION 0.0.1 |
4 | 4 | |
5 | -FROM debian:wheezy | |
5 | +FROM debian:jessie | |
6 | 6 | MAINTAINER Noosfero Development Team <noosfero-dev@listas.softwarelivre.org> |
7 | 7 | |
8 | 8 | LABEL Description="This dockerfile builds a noosfero development environment." |
... | ... | @@ -13,4 +13,6 @@ RUN git clone --depth 1 https://gitlab.com/noosfero/noosfero.git . |
13 | 13 | |
14 | 14 | RUN sh script/quick-start --skip-translations |
15 | 15 | |
16 | +RUN service postgresql start && sleep 2 && ruby script/sample-data | |
17 | + | |
16 | 18 | EXPOSE 3000 | ... | ... |
lib/create_thumbnails_job.rb
... | ... | @@ -3,5 +3,9 @@ class CreateThumbnailsJob < Struct.new(:class_name, :file_id) |
3 | 3 | return unless class_name.constantize.exists?(file_id) |
4 | 4 | file = class_name.constantize.find(file_id) |
5 | 5 | file.create_thumbnails |
6 | + article = Article.where(:image_id => file_id).first | |
7 | + if article | |
8 | + article.touch | |
9 | + end | |
6 | 10 | end |
7 | 11 | end | ... | ... |
... | ... | @@ -0,0 +1,11 @@ |
1 | +module FindByContents | |
2 | + | |
3 | + def find_by_contents(asset, context, scope, query, paginate_options={:page => 1}, options={}) | |
4 | + scope = scope.with_templates(options[:template_id]) unless options[:template_id].blank? | |
5 | + search = plugins.dispatch_first(:find_by_contents, asset, scope, query, paginate_options, options) | |
6 | + register_search_term(query, scope.count, search[:results].count, context, asset) | |
7 | + search | |
8 | + end | |
9 | + | |
10 | +end | |
11 | + | ... | ... |
lib/noosfero/api/api.rb
1 | 1 | require 'grape' |
2 | 2 | #require 'rack/contrib' |
3 | - | |
4 | 3 | Dir["#{Rails.root}/lib/noosfero/api/*.rb"].each {|file| require file unless file =~ /api\.rb/} |
4 | + | |
5 | 5 | module Noosfero |
6 | 6 | module API |
7 | 7 | class API < Grape::API |
... | ... | @@ -17,7 +17,6 @@ module Noosfero |
17 | 17 | end |
18 | 18 | |
19 | 19 | @@NOOSFERO_CONF = nil |
20 | - | |
21 | 20 | def self.NOOSFERO_CONF |
22 | 21 | if @@NOOSFERO_CONF |
23 | 22 | @@NOOSFERO_CONF |
... | ... | @@ -27,9 +26,11 @@ module Noosfero |
27 | 26 | end |
28 | 27 | end |
29 | 28 | |
29 | + before { set_locale } | |
30 | 30 | before { setup_multitenancy } |
31 | 31 | before { detect_stuff_by_domain } |
32 | 32 | before { filter_disabled_plugins_endpoints } |
33 | + before { init_noosfero_plugins } | |
33 | 34 | after { set_session_cookie } |
34 | 35 | |
35 | 36 | version 'v1' |
... | ... | @@ -41,11 +42,17 @@ module Noosfero |
41 | 42 | |
42 | 43 | mount V1::Articles |
43 | 44 | mount V1::Comments |
45 | + mount V1::Users | |
44 | 46 | mount V1::Communities |
45 | 47 | mount V1::People |
46 | 48 | mount V1::Enterprises |
47 | 49 | mount V1::Categories |
48 | 50 | mount V1::Tasks |
51 | + mount V1::Tags | |
52 | + mount V1::Environments | |
53 | + mount V1::Search | |
54 | + mount V1::Contacts | |
55 | + | |
49 | 56 | mount Session |
50 | 57 | |
51 | 58 | # hook point which allow plugins to add Grape::API extensions to API::API | ... | ... |
lib/noosfero/api/entities.rb
... | ... | @@ -6,6 +6,35 @@ module Noosfero |
6 | 6 | date.strftime('%Y/%m/%d %H:%M:%S') if date |
7 | 7 | end |
8 | 8 | |
9 | + PERMISSIONS = { | |
10 | + :admin => 0, | |
11 | + :self => 10, | |
12 | + :friend => 20, | |
13 | + :logged_user => 30, | |
14 | + :anonymous => 40 | |
15 | + } | |
16 | + | |
17 | + def self.can_display? profile, options, field, permission = :friend | |
18 | + return true if profile.public_fields.include?(field) | |
19 | + current_person = options[:current_person] | |
20 | + | |
21 | + current_permission = if current_person.present? | |
22 | + if current_person.is_admin? | |
23 | + :admin | |
24 | + elsif current_person == profile | |
25 | + :self | |
26 | + elsif current_person.friends.include?(profile) | |
27 | + :friend | |
28 | + else | |
29 | + :logged_user | |
30 | + end | |
31 | + else | |
32 | + :anonymous | |
33 | + end | |
34 | + | |
35 | + PERMISSIONS[current_permission] <= PERMISSIONS[permission] | |
36 | + end | |
37 | + | |
9 | 38 | class Image < Entity |
10 | 39 | root 'images', 'image' |
11 | 40 | |
... | ... | @@ -30,66 +59,81 @@ module Noosfero |
30 | 59 | end |
31 | 60 | end |
32 | 61 | |
62 | + class CategoryBase < Entity | |
63 | + root 'categories', 'category' | |
64 | + expose :name, :id, :slug | |
65 | + end | |
66 | + | |
67 | + class Category < CategoryBase | |
68 | + root 'categories', 'category' | |
69 | + expose :full_name do |category, options| | |
70 | + category.full_name | |
71 | + end | |
72 | + expose :parent, :using => CategoryBase, if: { parent: true } | |
73 | + expose :children, :using => CategoryBase, if: { children: true } | |
74 | + expose :image, :using => Image | |
75 | + expose :display_color | |
76 | + end | |
77 | + | |
78 | + class Region < Category | |
79 | + root 'regions', 'region' | |
80 | + expose :parent_id | |
81 | + end | |
82 | + | |
33 | 83 | class Profile < Entity |
34 | 84 | expose :identifier, :name, :id |
35 | 85 | expose :created_at, :format_with => :timestamp |
36 | 86 | expose :updated_at, :format_with => :timestamp |
37 | 87 | expose :image, :using => Image |
88 | + expose :region, :using => Region | |
38 | 89 | end |
39 | 90 | |
40 | - class User < Entity | |
91 | + class UserBasic < Entity | |
41 | 92 | expose :id |
42 | 93 | expose :login |
43 | 94 | end |
44 | 95 | |
45 | 96 | class Person < Profile |
46 | 97 | root 'people', 'person' |
47 | - expose :user, :using => User | |
98 | + expose :user, :using => UserBasic, documentation: {type: 'User', desc: 'The user data of a person' } | |
48 | 99 | end |
100 | + | |
49 | 101 | class Enterprise < Profile |
50 | 102 | root 'enterprises', 'enterprise' |
51 | 103 | end |
104 | + | |
52 | 105 | class Community < Profile |
53 | 106 | root 'communities', 'community' |
54 | 107 | expose :description |
55 | - expose :categories | |
56 | - expose :members, :using => Person | |
57 | - end | |
58 | - | |
59 | - class CategoryBase < Entity | |
60 | - root 'categories', 'category' | |
61 | - expose :name, :id | |
62 | - end | |
63 | - | |
64 | - class Category < CategoryBase | |
65 | - root 'categories', 'category' | |
66 | - expose :slug | |
67 | - expose :full_name do |category, options| | |
68 | - category.full_name | |
108 | + expose :admins do |community, options| | |
109 | + community.admins.map{|admin| {"name"=>admin.name, "id"=>admin.id}} | |
69 | 110 | end |
70 | - expose :parent, :using => CategoryBase, if: { parent: true } | |
71 | - expose :children, :using => CategoryBase, if: { children: true } | |
72 | - expose :image, :using => Image | |
111 | + expose :categories, :using => Category | |
112 | + expose :members, :using => Person | |
73 | 113 | end |
74 | 114 | |
75 | 115 | class ArticleBase < Entity |
76 | 116 | root 'articles', 'article' |
77 | 117 | expose :id |
78 | 118 | expose :body |
79 | - expose :abstract | |
119 | + expose :abstract, documentation: {type: 'String', desc: 'Teaser of the body'} | |
80 | 120 | expose :created_at, :format_with => :timestamp |
81 | 121 | expose :updated_at, :format_with => :timestamp |
82 | 122 | expose :title, :documentation => {:type => "String", :desc => "Title of the article"} |
83 | - expose :created_by, :as => :author, :using => Profile | |
84 | - expose :profile, :using => Profile | |
123 | + expose :created_by, :as => :author, :using => Profile, :documentation => {type: 'Profile', desc: 'The profile author that create the article'} | |
124 | + expose :profile, :using => Profile, :documentation => {type: 'Profile', desc: 'The profile associated with the article'} | |
85 | 125 | expose :categories, :using => Category |
86 | 126 | expose :image, :using => Image |
87 | - #TODO Apply vote stuff in core and make this test | |
88 | 127 | expose :votes_for |
89 | 128 | expose :votes_against |
90 | 129 | expose :setting |
91 | 130 | expose :position |
92 | 131 | expose :hits |
132 | + expose :start_date | |
133 | + expose :end_date, :documentation => {type: 'DateTime', desc: 'The date of finish of the article'} | |
134 | + expose :tag_list | |
135 | + expose :children_count | |
136 | + expose :slug, :documentation => {:type => "String", :desc => "Trimmed and parsed name of a article"} | |
93 | 137 | expose :path |
94 | 138 | end |
95 | 139 | |
... | ... | @@ -106,8 +150,32 @@ module Noosfero |
106 | 150 | expose :author, :using => Profile |
107 | 151 | end |
108 | 152 | |
153 | + class User < Entity | |
154 | + root 'users', 'user' | |
155 | + | |
156 | + attrs = [:id,:login,:email,:activated?] | |
157 | + aliases = {:activated? => :activated} | |
158 | + | |
159 | + attrs.each do |attribute| | |
160 | + name = aliases.has_key?(attribute) ? aliases[attribute] : attribute | |
161 | + expose attribute, :as => name, :if => lambda{|user,options| Entities.can_display?(user.person, options, attribute)} | |
162 | + end | |
163 | + | |
164 | + expose :person, :using => Person | |
165 | + expose :permissions, :if => lambda{|user,options| Entities.can_display?(user.person, options, :permissions, :self)} do |user, options| | |
166 | + output = {} | |
167 | + user.person.role_assignments.map do |role_assigment| | |
168 | + if role_assigment.resource.respond_to?(:identifier) && !role_assigment.role.nil? | |
169 | + output[role_assigment.resource.identifier] = role_assigment.role.permissions | |
170 | + end | |
171 | + end | |
172 | + output | |
173 | + end | |
174 | + end | |
175 | + | |
109 | 176 | class UserLogin < User |
110 | - expose :private_token | |
177 | + root 'users', 'user' | |
178 | + expose :private_token, documentation: {type: 'String', desc: 'A valid authentication code for post/delete api actions'} | |
111 | 179 | end |
112 | 180 | |
113 | 181 | class Task < Entity |
... | ... | @@ -116,6 +184,16 @@ module Noosfero |
116 | 184 | expose :type |
117 | 185 | end |
118 | 186 | |
187 | + class Environment < Entity | |
188 | + expose :name | |
189 | + end | |
190 | + | |
191 | + class Tag < Entity | |
192 | + root 'tags', 'tag' | |
193 | + expose :name | |
194 | + end | |
195 | + | |
196 | + | |
119 | 197 | end |
120 | 198 | end |
121 | 199 | end | ... | ... |
lib/noosfero/api/helpers.rb
1 | -module Noosfero | |
2 | - module API | |
3 | - module APIHelpers | |
1 | +require 'grape' | |
2 | +require_relative '../../find_by_contents' | |
3 | + | |
4 | + module Noosfero; | |
5 | + module API | |
6 | + module APIHelpers | |
4 | 7 | PRIVATE_TOKEN_PARAM = :private_token |
5 | - DEFAULT_ALLOWED_PARAMETERS = [:parent_id, :from, :until, :content_type] | |
8 | + DEFAULT_ALLOWED_PARAMETERS = [:parent_id, :from, :until, :content_type, :author_id] | |
9 | + | |
10 | + include SanitizeParams | |
11 | + include Noosfero::Plugin::HotSpot | |
12 | + include ForgotPasswordHelper | |
13 | + include SearchTermHelper | |
14 | + | |
15 | + def set_locale | |
16 | + I18n.locale = (params[:lang] || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en') | |
17 | + end | |
18 | + | |
19 | + def init_noosfero_plugins | |
20 | + plugins | |
21 | + end | |
6 | 22 | |
7 | 23 | def current_user |
8 | 24 | private_token = (params[PRIVATE_TOKEN_PARAM] || headers['Private-Token']).to_s |
... | ... | @@ -23,6 +39,22 @@ module Noosfero |
23 | 39 | @environment |
24 | 40 | end |
25 | 41 | |
42 | + include FindByContents | |
43 | + | |
44 | + #################################################################### | |
45 | + #### SEARCH | |
46 | + #################################################################### | |
47 | + def multiple_search?(searches=nil) | |
48 | + ['index', 'category_index'].include?(params[:action]) || (searches && searches.size > 1) | |
49 | + end | |
50 | + #################################################################### | |
51 | + | |
52 | + def logger | |
53 | + logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log")) | |
54 | + logger.formatter = GrapeLogging::Formatters::Default.new | |
55 | + logger | |
56 | + end | |
57 | + | |
26 | 58 | def limit |
27 | 59 | limit = params[:limit].to_i |
28 | 60 | limit = default_limit if limit <= 0 |
... | ... | @@ -50,7 +82,7 @@ module Noosfero |
50 | 82 | |
51 | 83 | def find_article(articles, id) |
52 | 84 | article = articles.find(id) |
53 | - article.display_to?(current_user.person) ? article : forbidden! | |
85 | + article.display_to?(current_person) ? article : forbidden! | |
54 | 86 | end |
55 | 87 | |
56 | 88 | def post_article(asset, params) |
... | ... | @@ -75,12 +107,25 @@ module Noosfero |
75 | 107 | present article, :with => Entities::Article, :fields => params[:fields] |
76 | 108 | end |
77 | 109 | |
78 | - def present_articles(asset) | |
79 | - articles = select_filtered_collection_of(asset, 'articles', params) | |
80 | - articles = articles.display_filter(current_person, nil) | |
110 | + def present_articles_for_asset(asset, method = 'articles') | |
111 | + articles = find_articles(asset, method) | |
112 | + present_articles(articles) | |
113 | + end | |
114 | + | |
115 | + def present_articles(articles) | |
81 | 116 | present articles, :with => Entities::Article, :fields => params[:fields] |
82 | 117 | end |
83 | 118 | |
119 | + def find_articles(asset, method = 'articles') | |
120 | + articles = select_filtered_collection_of(asset, method, params) | |
121 | + if current_person.present? | |
122 | + articles = articles.display_filter(current_person, nil) | |
123 | + else | |
124 | + articles = articles.published | |
125 | + end | |
126 | + articles | |
127 | + end | |
128 | + | |
84 | 129 | def find_task(asset, id) |
85 | 130 | task = asset.tasks.find(id) |
86 | 131 | current_person.has_permission?(task.permission, asset) ? task : forbidden! |
... | ... | @@ -127,8 +172,27 @@ module Noosfero |
127 | 172 | conditions |
128 | 173 | end |
129 | 174 | |
130 | - def make_order_with_parameters(params) | |
131 | - params[:order] || "created_at DESC" | |
175 | + # changing make_order_with_parameters to avoid sql injection | |
176 | + def make_order_with_parameters(object, method, params) | |
177 | + order = "created_at DESC" | |
178 | + unless params[:order].blank? | |
179 | + if params[:order].include? '\'' or params[:order].include? '"' | |
180 | + order = "created_at DESC" | |
181 | + elsif ['RANDOM()', 'RANDOM'].include? params[:order].upcase | |
182 | + order = 'RANDOM()' | |
183 | + else | |
184 | + field_name, direction = params[:order].split(' ') | |
185 | + assoc = object.class.reflect_on_association(method.to_sym) | |
186 | + if !field_name.blank? and assoc | |
187 | + if assoc.klass.attribute_names.include? field_name | |
188 | + if direction.present? and ['ASC','DESC'].include? direction.upcase | |
189 | + order = "#{field_name} #{direction.upcase}" | |
190 | + end | |
191 | + end | |
192 | + end | |
193 | + end | |
194 | + end | |
195 | + return order | |
132 | 196 | end |
133 | 197 | |
134 | 198 | def make_page_number_with_parameters(params) |
... | ... | @@ -152,25 +216,36 @@ module Noosfero |
152 | 216 | end |
153 | 217 | |
154 | 218 | def by_reference(scope, params) |
155 | - if params[:reference_id] | |
156 | - created_at = scope.find(params[:reference_id]).created_at | |
157 | - scope.send("#{params.key?(:oldest) ? 'older_than' : 'younger_than'}", created_at) | |
219 | + reference_id = params[:reference_id].to_i == 0 ? nil : params[:reference_id].to_i | |
220 | + if reference_id.nil? | |
221 | + scope | |
158 | 222 | else |
223 | + created_at = scope.find(reference_id).created_at | |
224 | + scope.send("#{params.key?(:oldest) ? 'older_than' : 'younger_than'}", created_at) | |
225 | + end | |
226 | + end | |
227 | + | |
228 | + def by_categories(scope, params) | |
229 | + category_ids = params[:category_ids] | |
230 | + if category_ids.nil? | |
159 | 231 | scope |
232 | + else | |
233 | + scope.joins(:categories).where(:categories => {:id => category_ids}) | |
160 | 234 | end |
161 | 235 | end |
162 | 236 | |
163 | 237 | def select_filtered_collection_of(object, method, params) |
164 | 238 | conditions = make_conditions_with_parameter(params) |
165 | - order = make_order_with_parameters(params) | |
239 | + order = make_order_with_parameters(object,method,params) | |
166 | 240 | page_number = make_page_number_with_parameters(params) |
167 | 241 | per_page = make_per_page_with_parameters(params) |
168 | 242 | timestamp = make_timestamp_with_parameters_and_method(params, method) |
169 | 243 | |
170 | 244 | objects = object.send(method) |
171 | 245 | objects = by_reference(objects, params) |
246 | + objects = by_categories(objects, params) | |
172 | 247 | |
173 | - objects = objects.where(conditions).where(timestamp).page(page_number).per_page(per_page).order(order) | |
248 | + objects = objects.where(conditions).where(timestamp).page(page_number).per_page(per_page).reorder(order) | |
174 | 249 | |
175 | 250 | objects |
176 | 251 | end |
... | ... | @@ -179,6 +254,7 @@ module Noosfero |
179 | 254 | unauthorized! unless current_user |
180 | 255 | end |
181 | 256 | |
257 | + | |
182 | 258 | # Checks the occurrences of uniqueness of attributes, each attribute must be present in the params hash |
183 | 259 | # or a Bad Request error is invoked. |
184 | 260 | # |
... | ... | @@ -198,20 +274,6 @@ module Noosfero |
198 | 274 | attrs |
199 | 275 | end |
200 | 276 | |
201 | - def verify_recaptcha_v2(remote_ip, g_recaptcha_response, private_key, api_recaptcha_verify_uri) | |
202 | - verify_hash = { | |
203 | - "secret" => private_key, | |
204 | - "remoteip" => remote_ip, | |
205 | - "response" => g_recaptcha_response | |
206 | - } | |
207 | - uri = URI(api_recaptcha_verify_uri) | |
208 | - https = Net::HTTP.new(uri.host, uri.port) | |
209 | - https.use_ssl = true | |
210 | - request = Net::HTTP::Post.new(uri.path) | |
211 | - request.set_form_data(verify_hash) | |
212 | - JSON.parse(https.request(request).body) | |
213 | - end | |
214 | - | |
215 | 277 | ########################################## |
216 | 278 | # error helpers # |
217 | 279 | ########################################## |
... | ... | @@ -247,13 +309,22 @@ module Noosfero |
247 | 309 | render_api_error!(_('Method Not Allowed'), 405) |
248 | 310 | end |
249 | 311 | |
250 | - def render_api_error!(message, status) | |
251 | - error!({'message' => message, :code => status}, status) | |
312 | + # javascript_console_message is supposed to be executed as console.log() | |
313 | + def render_api_error!(user_message, status, log_message = nil, javascript_console_message = nil) | |
314 | + message_hash = {'message' => user_message, :code => status} | |
315 | + message_hash[:javascript_console_message] = javascript_console_message if javascript_console_message.present? | |
316 | + log_msg = "#{status}, User message: #{user_message}" | |
317 | + log_msg = "#{log_message}, #{log_msg}" if log_message.present? | |
318 | + log_msg = "#{log_msg}, Javascript Console Message: #{javascript_console_message}" if javascript_console_message.present? | |
319 | + logger.error log_msg unless Rails.env.test? | |
320 | + error!(message_hash, status) | |
252 | 321 | end |
253 | 322 | |
254 | 323 | def render_api_errors!(messages) |
324 | + messages = messages.to_a if messages.class == ActiveModel::Errors | |
255 | 325 | render_api_error!(messages.join(','), 400) |
256 | 326 | end |
327 | + | |
257 | 328 | protected |
258 | 329 | |
259 | 330 | def set_session_cookie |
... | ... | @@ -278,7 +349,7 @@ module Noosfero |
278 | 349 | end |
279 | 350 | |
280 | 351 | def filter_disabled_plugins_endpoints |
281 | - not_found! if Noosfero::API::API.endpoint_unavailable?(self, !@environment) | |
352 | + not_found! if Noosfero::API::API.endpoint_unavailable?(self, @environment) | |
282 | 353 | end |
283 | 354 | |
284 | 355 | private |
... | ... | @@ -305,7 +376,6 @@ module Noosfero |
305 | 376 | def period(from_date, until_date) |
306 | 377 | begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date |
307 | 378 | end_period = until_date.nil? ? DateTime.now : until_date |
308 | - | |
309 | 379 | begin_period..end_period |
310 | 380 | end |
311 | 381 | ... | ... |
lib/noosfero/api/session.rb
... | ... | @@ -2,7 +2,6 @@ require "uri" |
2 | 2 | |
3 | 3 | module Noosfero |
4 | 4 | module API |
5 | - | |
6 | 5 | class Session < Grape::API |
7 | 6 | |
8 | 7 | # Login to get token |
... | ... | @@ -14,11 +13,15 @@ module Noosfero |
14 | 13 | # Example Request: |
15 | 14 | # POST http://localhost:3000/api/v1/login?login=adminuser&password=admin |
16 | 15 | post "/login" do |
17 | - user ||= User.authenticate(params[:login], params[:password], environment) | |
16 | + begin | |
17 | + user ||= User.authenticate(params[:login], params[:password], environment) | |
18 | + rescue NoosferoExceptions::UserNotActivated => e | |
19 | + render_api_error!(e.message, 401) | |
20 | + end | |
18 | 21 | |
19 | 22 | return unauthorized! unless user |
20 | 23 | @current_user = user |
21 | - present user, :with => Entities::UserLogin | |
24 | + present user, :with => Entities::UserLogin, :current_person => current_person | |
22 | 25 | end |
23 | 26 | |
24 | 27 | # Create user. |
... | ... | @@ -28,34 +31,103 @@ module Noosfero |
28 | 31 | # password (required) - Password |
29 | 32 | # login - login |
30 | 33 | # Example Request: |
31 | - # POST /register?email=some@mail.com&password=pas&login=some | |
34 | + # POST /register?email=some@mail.com&password=pas&password_confirmation=pas&login=some | |
32 | 35 | params do |
33 | 36 | requires :email, type: String, desc: _("Email") |
34 | 37 | requires :login, type: String, desc: _("Login") |
35 | 38 | requires :password, type: String, desc: _("Password") |
36 | 39 | end |
40 | + | |
37 | 41 | post "/register" do |
38 | - unique_attributes! User, [:email, :login] | |
39 | - attrs = attributes_for_keys [:email, :login, :password] | |
40 | - attrs[:password_confirmation] = attrs[:password] | |
41 | - | |
42 | - #Commented for stress tests | |
43 | - | |
44 | - # remote_ip = (request.respond_to?(:remote_ip) && request.remote_ip) || (env && env['REMOTE_ADDR']) | |
45 | - # private_key = API.NOOSFERO_CONF['api_recaptcha_private_key'] | |
46 | - # api_recaptcha_verify_uri = API.NOOSFERO_CONF['api_recaptcha_verify_uri'] | |
47 | - # captcha_result = verify_recaptcha_v2(remote_ip, params['g-recaptcha-response'], private_key, api_recaptcha_verify_uri) | |
48 | - user = User.new(attrs) | |
49 | -# if captcha_result["success"] and user.save | |
50 | - if user.save | |
51 | - user.activate | |
52 | - user.generate_private_token! | |
53 | - present user, :with => Entities::UserLogin | |
54 | - else | |
55 | - message = user.errors.to_json | |
42 | + attrs = attributes_for_keys [:email, :login, :password, :password_confirmation] + environment.signup_person_fields | |
43 | + name = params[:name].present? ? params[:name] : attrs[:email] | |
44 | + attrs[:password_confirmation] = attrs[:password] if !attrs.has_key?(:password_confirmation) | |
45 | + user = User.new(attrs.merge(:name => name)) | |
46 | + | |
47 | + begin | |
48 | + user.signup! | |
49 | + user.generate_private_token! if user.activated? | |
50 | + present user, :with => Entities::UserLogin, :current_person => user.person | |
51 | + rescue ActiveRecord::RecordInvalid | |
52 | + message = user.errors.as_json.merge((user.person.present? ? user.person.errors : {}).as_json).to_json | |
56 | 53 | render_api_error!(message, 400) |
57 | 54 | end |
58 | 55 | end |
56 | + | |
57 | + params do | |
58 | + requires :activation_code, type: String, desc: _("Activation token") | |
59 | + end | |
60 | + | |
61 | + # Activate a user. | |
62 | + # | |
63 | + # Parameter: | |
64 | + # activation_code (required) - Activation token | |
65 | + # Example Request: | |
66 | + # PATCH /activate?activation_code=28259abd12cc6a64ef9399cf3286cb998b96aeaf | |
67 | + patch "/activate" do | |
68 | + user = User.find_by_activation_code(params[:activation_code]) | |
69 | + if user | |
70 | + unless user.environment.enabled?('admin_must_approve_new_users') | |
71 | + if user.activate | |
72 | + user.generate_private_token! | |
73 | + present user, :with => Entities::UserLogin, :current_person => current_person | |
74 | + end | |
75 | + else | |
76 | + if user.create_moderate_task | |
77 | + user.activation_code = nil | |
78 | + user.save! | |
79 | + | |
80 | + # Waiting for admin moderate user registration | |
81 | + status 202 | |
82 | + body({ | |
83 | + :message => 'Waiting for admin moderate user registration' | |
84 | + }) | |
85 | + end | |
86 | + end | |
87 | + else | |
88 | + # Token not found in database | |
89 | + render_api_error!(_('Token is invalid'), 412) | |
90 | + end | |
91 | + end | |
92 | + | |
93 | + # Request a new password. | |
94 | + # | |
95 | + # Parameters: | |
96 | + # value (required) - Email or login | |
97 | + # Example Request: | |
98 | + # POST /forgot_password?value=some@mail.com | |
99 | + post "/forgot_password" do | |
100 | + requestors = fetch_requestors(params[:value]) | |
101 | + not_found! if requestors.blank? | |
102 | + remote_ip = (request.respond_to?(:remote_ip) && request.remote_ip) || (env && env['REMOTE_ADDR']) | |
103 | + requestors.each do |requestor| | |
104 | + ChangePassword.create!(:requestor => requestor) | |
105 | + end | |
106 | + end | |
107 | + | |
108 | + params do | |
109 | + requires :code, type: String, desc: _("Forgot password code") | |
110 | + end | |
111 | + # Change password | |
112 | + # | |
113 | + # Parameters: | |
114 | + # code (required) - Change password code | |
115 | + # password (required) | |
116 | + # password_confirmation (required) | |
117 | + # Example Request: | |
118 | + # PATCH /new_password?code=xxxx&password=secret&password_confirmation=secret | |
119 | + patch "/new_password" do | |
120 | + change_password = ChangePassword.find_by_code(params[:code]) | |
121 | + not_found! if change_password.nil? | |
122 | + | |
123 | + if change_password.update_attributes(:password => params[:password], :password_confirmation => params[:password_confirmation]) | |
124 | + change_password.finish | |
125 | + present change_password.requestor.user, :with => Entities::UserLogin, :current_person => current_person | |
126 | + else | |
127 | + something_wrong! | |
128 | + end | |
129 | + end | |
130 | + | |
59 | 131 | end |
60 | 132 | end |
61 | 133 | end | ... | ... |
lib/noosfero/api/v1/articles.rb
... | ... | @@ -2,7 +2,6 @@ module Noosfero |
2 | 2 | module API |
3 | 3 | module V1 |
4 | 4 | class Articles < Grape::API |
5 | - before { authenticate! } | |
6 | 5 | |
7 | 6 | ARTICLE_TYPES = Article.descendants.map{|a| a.to_s} |
8 | 7 | |
... | ... | @@ -17,39 +16,148 @@ module Noosfero |
17 | 16 | # |
18 | 17 | # Example Request: |
19 | 18 | # GET host/api/v1/articles?from=2013-04-04-14:41:43&until=2015-04-04-14:41:43&limit=10&private_token=e96fff37c2238fdab074d1dcea8e6317 |
19 | + | |
20 | + desc 'Return all articles of all kinds' do | |
21 | + detail 'Get all articles filtered by fields in query params' | |
22 | + params Noosfero::API::Entities::Article.documentation | |
23 | + success Noosfero::API::Entities::Article | |
24 | + failure [[403, 'Forbidden']] | |
25 | + named 'ArticlesList' | |
26 | + headers [ | |
27 | + 'Per-Page' => { | |
28 | + description: 'Total number of records', | |
29 | + required: false | |
30 | + } | |
31 | + ] | |
32 | + end | |
20 | 33 | get do |
21 | - present_articles(environment) | |
34 | + present_articles_for_asset(environment) | |
22 | 35 | end |
23 | 36 | |
24 | - desc "Return the article id" | |
25 | - get ':id' do | |
37 | + desc "Return one article by id" do | |
38 | + detail 'Get only one article by id. If not found the "forbidden" http error is showed' | |
39 | + params Noosfero::API::Entities::Article.documentation | |
40 | + success Noosfero::API::Entities::Article | |
41 | + failure [[403, 'Forbidden']] | |
42 | + named 'ArticleById' | |
43 | + end | |
44 | + get ':id', requirements: {id: /[0-9]+/} do | |
26 | 45 | present_article(environment) |
27 | 46 | end |
28 | 47 | |
48 | + post ':id' do | |
49 | + article = environment.articles.find(params[:id]) | |
50 | + return forbidden! unless article.allow_edit?(current_person) | |
51 | + article.update_attributes!(params[:article]) | |
52 | + present article, :with => Entities::Article, :fields => params[:fields] | |
53 | + end | |
54 | + | |
55 | + desc 'Report a abuse and/or violent content in a article by id' do | |
56 | + detail 'Submit a abuse (in general, a content violation) report about a specific article' | |
57 | + params Noosfero::API::Entities::Article.documentation | |
58 | + failure [[400, 'Bad Request']] | |
59 | + named 'ArticleReportAbuse' | |
60 | + end | |
61 | + post ':id/report_abuse' do | |
62 | + article = find_article(environment.articles, params[:id]) | |
63 | + profile = article.profile | |
64 | + begin | |
65 | + abuse_report = AbuseReport.new(:reason => params[:report_abuse]) | |
66 | + if !params[:content_type].blank? | |
67 | + article = params[:content_type].constantize.find(params[:content_id]) | |
68 | + abuse_report.content = article_reported_version(article) | |
69 | + end | |
70 | + | |
71 | + current_person.register_report(abuse_report, profile) | |
72 | + | |
73 | + if !params[:content_type].blank? | |
74 | + abuse_report = AbuseReport.find_by_reporter_id_and_abuse_complaint_id(current_person.id, profile.opened_abuse_complaint.id) | |
75 | + Delayed::Job.enqueue DownloadReportedImagesJob.new(abuse_report, article) | |
76 | + end | |
77 | + | |
78 | + { | |
79 | + :success => true, | |
80 | + :message => _('Your abuse report was registered. The administrators are reviewing your report.'), | |
81 | + } | |
82 | + rescue Exception => exception | |
83 | + #logger.error(exception.to_s) | |
84 | + render_api_error!(_('Your report couldn\'t be saved due to some problem. Please contact the administrator.'), 400) | |
85 | + end | |
86 | + | |
87 | + end | |
88 | + | |
89 | + desc "Returns the articles I voted" do | |
90 | + detail 'Get the Articles I make a vote' | |
91 | + failure [[403, 'Forbidden']] | |
92 | + named 'ArticleFollowers' | |
93 | + end | |
94 | + #FIXME refactor this method | |
95 | + get 'voted_by_me' do | |
96 | + present_articles(current_person.votes.collect(&:voteable)) | |
97 | + end | |
98 | + | |
99 | + desc 'Perform a vote on a article by id' do | |
100 | + detail 'Vote on a specific article with values: 1 (if you like) or -1 (if not)' | |
101 | + params Noosfero::API::Entities::UserLogin.documentation | |
102 | + failure [[401,'Unauthorized']] | |
103 | + named 'ArticleVote' | |
104 | + end | |
105 | + post ':id/vote' do | |
106 | + authenticate! | |
107 | + value = (params[:value] || 1).to_i | |
108 | + # FIXME verify allowed values | |
109 | + render_api_error!('Vote value not allowed', 400) unless [-1, 1].include?(value) | |
110 | + article = find_article(environment.articles, params[:id]) | |
111 | + vote = Vote.new(:voteable => article, :voter => current_person, :vote => value) | |
112 | + {:vote => vote.save} | |
113 | + end | |
114 | + | |
115 | + desc 'Return the children of a article identified by id' do | |
116 | + detail 'Get all children articles of a specific article' | |
117 | + params Noosfero::API::Entities::Article.documentation | |
118 | + failure [[403, 'Forbidden']] | |
119 | + named 'ArticleChildren' | |
120 | + end | |
121 | + | |
29 | 122 | get ':id/children' do |
30 | 123 | article = find_article(environment.articles, params[:id]) |
31 | 124 | |
32 | 125 | #TODO make tests for this situation |
33 | 126 | votes_order = params.delete(:order) if params[:order]=='votes_score' |
34 | 127 | articles = select_filtered_collection_of(article, 'children', params) |
35 | - articles = articles.display_filter(current_person, nil) | |
36 | - | |
128 | + articles = articles.display_filter(current_person, article.profile) | |
37 | 129 | |
38 | 130 | #TODO make tests for this situation |
39 | 131 | if votes_order |
40 | 132 | articles = articles.joins('left join votes on articles.id=votes.voteable_id').group('articles.id').reorder('sum(coalesce(votes.vote, 0)) DESC') |
41 | 133 | end |
42 | - | |
43 | 134 | Article.hit(articles) |
44 | - present articles, :with => Entities::Article, :fields => params[:fields] | |
135 | + present_articles(articles) | |
45 | 136 | end |
46 | 137 | |
138 | + desc 'Return one child of a article identified by id' do | |
139 | + detail 'Get a child of a specific article' | |
140 | + params Noosfero::API::Entities::Article.documentation | |
141 | + success Noosfero::API::Entities::Article | |
142 | + failure [[403, 'Forbidden']] | |
143 | + named 'ArticleChild' | |
144 | + end | |
47 | 145 | get ':id/children/:child_id' do |
48 | 146 | article = find_article(environment.articles, params[:id]) |
49 | - present find_article(article.children, params[:child_id]), :with => Entities::Article, :fields => params[:fields] | |
147 | + child = find_article(article.children, params[:child_id]) | |
148 | + child.hit | |
149 | + present child, :with => Entities::Article, :fields => params[:fields] | |
50 | 150 | end |
51 | 151 | |
152 | + desc 'Suggest a article to another profile' do | |
153 | + detail 'Suggest a article to another profile (person, community...)' | |
154 | + params Noosfero::API::Entities::Article.documentation | |
155 | + success Noosfero::API::Entities::Task | |
156 | + failure [[401,'Unauthorized']] | |
157 | + named 'ArticleSuggest' | |
158 | + end | |
52 | 159 | post ':id/children/suggest' do |
160 | + authenticate! | |
53 | 161 | parent_article = environment.articles.find(params[:id]) |
54 | 162 | |
55 | 163 | suggest_article = SuggestArticle.new |
... | ... | @@ -66,8 +174,15 @@ module Noosfero |
66 | 174 | |
67 | 175 | # Example Request: |
68 | 176 | # POST api/v1/articles/:id/children?private_token=234298743290432&article[name]=title&article[body]=body |
177 | + desc 'Add a child article to a parent identified by id' do | |
178 | + detail 'Create a new article and associate to a parent' | |
179 | + params Noosfero::API::Entities::Article.documentation | |
180 | + success Noosfero::API::Entities::Article | |
181 | + failure [[401,'Unauthorized']] | |
182 | + named 'ArticleAddChild' | |
183 | + end | |
69 | 184 | post ':id/children' do |
70 | - | |
185 | + authenticate! | |
71 | 186 | parent_article = environment.articles.find(params[:id]) |
72 | 187 | return forbidden! unless parent_article.allow_create?(current_person) |
73 | 188 | |
... | ... | @@ -95,11 +210,37 @@ module Noosfero |
95 | 210 | resource kind.pluralize.to_sym do |
96 | 211 | segment "/:#{kind}_id" do |
97 | 212 | resource :articles do |
213 | + | |
214 | + desc "Return all articles associate with a profile of type #{kind}" do | |
215 | + detail 'Get a list of articles of a profile' | |
216 | + params Noosfero::API::Entities::Article.documentation | |
217 | + success Noosfero::API::Entities::Article | |
218 | + failure [[403, 'Forbidden']] | |
219 | + named 'ArticlesOfProfile' | |
220 | + end | |
98 | 221 | get do |
99 | 222 | profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) |
100 | - present_articles(profile) | |
223 | + | |
224 | + if params[:path].present? | |
225 | + article = profile.articles.find_by_path(params[:path]) | |
226 | + if !article || !article.display_to?(current_person) | |
227 | + article = forbidden! | |
228 | + end | |
229 | + | |
230 | + present article, :with => Entities::Article, :fields => params[:fields] | |
231 | + else | |
232 | + | |
233 | + present_articles_for_asset(profile) | |
234 | + end | |
101 | 235 | end |
102 | 236 | |
237 | + desc "Return a article associate with a profile of type #{kind}" do | |
238 | + detail 'Get only one article of a profile' | |
239 | + params Noosfero::API::Entities::Article.documentation | |
240 | + success Noosfero::API::Entities::Article | |
241 | + failure [[403, 'Forbidden']] | |
242 | + named 'ArticleOfProfile' | |
243 | + end | |
103 | 244 | get ':id' do |
104 | 245 | profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) |
105 | 246 | present_article(profile) |
... | ... | @@ -107,6 +248,13 @@ module Noosfero |
107 | 248 | |
108 | 249 | # Example Request: |
109 | 250 | # POST api/v1/{people,communities,enterprises}/:asset_id/articles?private_token=234298743290432&article[name]=title&article[body]=body |
251 | + desc "Add a new article associated with a profile of type #{kind}" do | |
252 | + detail 'Create a new article and associate with a profile' | |
253 | + params Noosfero::API::Entities::Article.documentation | |
254 | + success Noosfero::API::Entities::Article | |
255 | + failure [[403, 'Forbidden']] | |
256 | + named 'ArticleCreateToProfile' | |
257 | + end | |
110 | 258 | post do |
111 | 259 | profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) |
112 | 260 | post_article(profile, params) | ... | ... |
lib/noosfero/api/v1/comments.rb
... | ... | @@ -30,8 +30,8 @@ module Noosfero |
30 | 30 | # POST api/v1/articles/12/comments?private_token=2298743290432&body=new comment&title=New |
31 | 31 | post ":id/comments" do |
32 | 32 | article = find_article(environment.articles, params[:id]) |
33 | - options = params.select { |key,v| !['id','private_token'].include?(key) }.merge(:author => current_person) | |
34 | - present article.comments.create(options), :with => Entities::Comment | |
33 | + options = params.select { |key,v| !['id','private_token'].include?(key) }.merge(:author => current_person, :source => article) | |
34 | + present Comment.create(options), :with => Entities::Comment | |
35 | 35 | end |
36 | 36 | end |
37 | 37 | ... | ... |
... | ... | @@ -0,0 +1,28 @@ |
1 | +module Noosfero | |
2 | + module API | |
3 | + module V1 | |
4 | + class Contacts < Grape::API | |
5 | + | |
6 | + resource :communities do | |
7 | + | |
8 | + resource ':id/contact' do | |
9 | + #contact => {:name => 'some name', :email => 'test@mail.com', :subject => 'some title', :message => 'some message'} | |
10 | + desc "Send a contact message" | |
11 | + post do | |
12 | + profile = environment.communities.find(params[:id]) | |
13 | + forbidden! unless profile.present? | |
14 | + contact = Contact.new params[:contact].merge(dest: profile) | |
15 | + if contact.deliver | |
16 | + {:success => true} | |
17 | + else | |
18 | + {:success => false} | |
19 | + end | |
20 | + end | |
21 | + | |
22 | + end | |
23 | + end | |
24 | + | |
25 | + end | |
26 | + end | |
27 | + end | |
28 | +end | ... | ... |
... | ... | @@ -0,0 +1,18 @@ |
1 | +module Noosfero | |
2 | + module API | |
3 | + module V1 | |
4 | + class Environments < Grape::API | |
5 | + | |
6 | + resource :environment do | |
7 | + | |
8 | + desc "Return the person information" | |
9 | + get '/signup_person_fields' do | |
10 | + present environment.signup_person_fields | |
11 | + end | |
12 | + | |
13 | + end | |
14 | + | |
15 | + end | |
16 | + end | |
17 | + end | |
18 | +end | ... | ... |
lib/noosfero/api/v1/people.rb
... | ... | @@ -48,6 +48,13 @@ module Noosfero |
48 | 48 | present person, :with => Entities::Person |
49 | 49 | end |
50 | 50 | |
51 | + desc "Update person information" | |
52 | + post ':id' do | |
53 | + return forbidden! if current_person.id.to_s != params[:id] | |
54 | + current_person.update_attributes!(params[:person]) | |
55 | + present current_person, :with => Entities::Person | |
56 | + end | |
57 | + | |
51 | 58 | # Example Request: |
52 | 59 | # POST api/v1/people?person[login]=some_login&person[password]=some_password&person[name]=Jack |
53 | 60 | desc "Create person" | ... | ... |
... | ... | @@ -0,0 +1,43 @@ |
1 | +module Noosfero | |
2 | + module API | |
3 | + module V1 | |
4 | + class Search < Grape::API | |
5 | + | |
6 | + resource :search do | |
7 | + resource :article do | |
8 | + get do | |
9 | + # Security checks | |
10 | + sanitize_params_hash(params) | |
11 | + # APIHelpers | |
12 | + asset = :articles | |
13 | + context = environment | |
14 | + | |
15 | + profile = environment.profiles.find(params[:profile_id]) if params[:profile_id] | |
16 | + scope = profile.nil? ? environment.articles.is_public : profile.articles.is_public | |
17 | + scope = scope.where(:type => params[:type]) if params[:type] && !(params[:type] == 'Article') | |
18 | + scope = scope.where(:parent_id => params[:parent_id]) if params[:parent_id].present? | |
19 | + scope = scope.joins(:categories).where(:categories => {:id => params[:category_ids]}) if params[:category_ids].present? | |
20 | + query = params[:query] || "" | |
21 | + order = "more_recent" | |
22 | + | |
23 | + options = {:filter => order, :template_id => params[:template_id]} | |
24 | + | |
25 | + paginate_options = params.select{|k,v| [:page, :per_page].include?(k.to_sym)}.symbolize_keys | |
26 | + paginate_options.each_pair{|k,v| v=v.to_i} | |
27 | + paginate_options[:page]=1 if !paginate_options.keys.include?(:page) | |
28 | + | |
29 | + search_result = find_by_contents(asset, context, scope, query, paginate_options, options) | |
30 | + | |
31 | + articles = search_result[:results] | |
32 | + | |
33 | + result = present_articles(articles) | |
34 | + | |
35 | + result | |
36 | + end | |
37 | + end | |
38 | + end | |
39 | + | |
40 | + end | |
41 | + end | |
42 | + end | |
43 | +end | ... | ... |
... | ... | @@ -0,0 +1,30 @@ |
1 | +module Noosfero | |
2 | + module API | |
3 | + module V1 | |
4 | + class Tags < Grape::API | |
5 | + before { authenticate! } | |
6 | + | |
7 | + resource :articles do | |
8 | + | |
9 | + resource ':id/tags' do | |
10 | + | |
11 | + get do | |
12 | + article = find_article(environment.articles, params[:id]) | |
13 | + present article.tag_list | |
14 | + end | |
15 | + | |
16 | + desc "Add a tag to an article" | |
17 | + post do | |
18 | + article = find_article(environment.articles, params[:id]) | |
19 | + article.tag_list=params[:tags] | |
20 | + article.save | |
21 | + present article.tag_list | |
22 | + end | |
23 | + | |
24 | + end | |
25 | + end | |
26 | + | |
27 | + end | |
28 | + end | |
29 | + end | |
30 | +end | ... | ... |
... | ... | @@ -0,0 +1,43 @@ |
1 | +module Noosfero | |
2 | + module API | |
3 | + module V1 | |
4 | + class Users < Grape::API | |
5 | + before { authenticate! } | |
6 | + | |
7 | + resource :users do | |
8 | + | |
9 | + get do | |
10 | + users = select_filtered_collection_of(environment, 'users', params) | |
11 | + users = users.select{|u| u.person.display_info_to? current_person} | |
12 | + present users, :with => Entities::User, :current_person => current_person | |
13 | + end | |
14 | + | |
15 | + get "/me" do | |
16 | + present current_user, :with => Entities::User, :current_person => current_person | |
17 | + end | |
18 | + | |
19 | + get ":id" do | |
20 | + user = environment.users.find_by_id(params[:id]) | |
21 | + unless user.person.display_info_to? current_person | |
22 | + unauthorized! | |
23 | + end | |
24 | + present user, :with => Entities::User, :current_person => current_person | |
25 | + end | |
26 | + | |
27 | + get ":id/permissions" do | |
28 | + user = environment.users.find(params[:id]) | |
29 | + output = {} | |
30 | + user.person.role_assignments.map do |role_assigment| | |
31 | + if role_assigment.resource.respond_to?(:identifier) && role_assigment.resource.identifier == params[:profile] | |
32 | + output[:permissions] = role_assigment.role.permissions | |
33 | + end | |
34 | + end | |
35 | + present output | |
36 | + end | |
37 | + | |
38 | + end | |
39 | + | |
40 | + end | |
41 | + end | |
42 | + end | |
43 | +end | ... | ... |
... | ... | @@ -0,0 +1,41 @@ |
1 | +module SanitizeParams | |
2 | + | |
3 | + protected | |
4 | + | |
5 | + # Check each request parameter for | |
6 | + # improper HTML or Script tags | |
7 | + def sanitize_params | |
8 | + sanitize_params_hash(request.params) | |
9 | + end | |
10 | + | |
11 | + # Given a params list sanitize all | |
12 | + def sanitize_params_hash(params) | |
13 | + params.each { |k, v| | |
14 | + if v.is_a?(String) | |
15 | + params[k] = sanitize_param v | |
16 | + elsif v.is_a?(Array) | |
17 | + params[k] = sanitize_array v | |
18 | + elsif v.kind_of?(Hash) | |
19 | + params[k] = sanitize_params_hash(v) | |
20 | + end | |
21 | + } | |
22 | + end | |
23 | + | |
24 | + # If the parameter was an array, | |
25 | + # try to sanitize each element in the array | |
26 | + def sanitize_array(array) | |
27 | + array.map! { |e| | |
28 | + if e.is_a?(String) | |
29 | + sanitize_param e | |
30 | + end | |
31 | + } | |
32 | + return array | |
33 | + end | |
34 | + | |
35 | + # Santitize a single value | |
36 | + def sanitize_param(value) | |
37 | + allowed_tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) | |
38 | + ActionController::Base.helpers.sanitize(value, tags: allowed_tags, attributes: %w(href title)) | |
39 | + end | |
40 | + | |
41 | +end | ... | ... |
plugins/newsletter/db/migrate/20150717195546_newsletter_plugin_newsletters.rb
... | ... | @@ -14,7 +14,7 @@ class NewsletterPluginNewsletters < ActiveRecord::Migration |
14 | 14 | t.boolean :moderated |
15 | 15 | t.text :unsubscribers |
16 | 16 | end |
17 | - add_index :newsletter_plugin_newsletters, :environment_id, :uniq => true | |
17 | + add_index :newsletter_plugin_newsletters, :environment_id, :unique => true | |
18 | 18 | end |
19 | 19 | |
20 | 20 | def down | ... | ... |
plugins/newsletter/lib/newsletter_plugin/newsletter.rb
1 | 1 | require 'csv' |
2 | 2 | |
3 | -class NewsletterPlugin::Newsletter < Noosfero::Plugin::ActiveRecord | |
3 | +class NewsletterPlugin::Newsletter < ActiveRecord::Base | |
4 | 4 | |
5 | 5 | belongs_to :environment |
6 | 6 | belongs_to :person |
... | ... | @@ -123,11 +123,11 @@ class NewsletterPlugin::Newsletter < Noosfero::Plugin::ActiveRecord |
123 | 123 | end |
124 | 124 | |
125 | 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'])) | |
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), tags: %w(strong em b i)),:style => CSS['post-lead'])+read_more(post.url), :style => CSS['post-info'])) | |
127 | 127 | end |
128 | 128 | |
129 | 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'])) | |
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), tags: %w(strong em b i)),:style => CSS['post-lead'])+read_more(post.url),:colspan => 2, :style => CSS['post-info'])) | |
131 | 131 | end |
132 | 132 | |
133 | 133 | def body(data = {}) |
... | ... | @@ -177,10 +177,6 @@ class NewsletterPlugin::Newsletter < Noosfero::Plugin::ActiveRecord |
177 | 177 | last_mailing.nil? ? nil : last_mailing.created_at |
178 | 178 | end |
179 | 179 | |
180 | - def sanitize(html) | |
181 | - html.gsub(/<\/?p>/, '') | |
182 | - end | |
183 | - | |
184 | 180 | def has_posts_in_the_period? |
185 | 181 | ! self.posts.empty? |
186 | 182 | end | ... | ... |
plugins/newsletter/public/style.css
plugins/newsletter/test/unit/newsletter_plugin_newsletter_test.rb
... | ... | @@ -351,15 +351,30 @@ EOS |
351 | 351 | post = fast_create(TextArticle, :parent_id => blog.id, |
352 | 352 | :name => 'the last news 1', |
353 | 353 | :profile_id => community.id, |
354 | - :body => "<p>paragraph of news</p>") | |
354 | + :body => '<p style="text-align: left;">paragraph of news</p>') | |
355 | 355 | |
356 | 356 | newsletter = NewsletterPlugin::Newsletter.create!( |
357 | 357 | :environment => environment, |
358 | 358 | :blog_ids => [blog.id], |
359 | 359 | :person => fast_create(Person)) |
360 | 360 | |
361 | - assert_match /<p>paragraph of news<\/p>/, post.body | |
362 | - assert_not_match /<p>paragraph of news<\/p>/, newsletter.body | |
361 | + assert_match /<p style="text-align: left;">paragraph of news<\/p>/, post.body | |
362 | + assert_not_match /<p style="text-align: left;">paragraph of news<\/p>/, newsletter.body | |
363 | + end | |
364 | + | |
365 | + should 'only include text for posts in HTML generated content' do | |
366 | + environment = fast_create Environment | |
367 | + community = fast_create(Community, :environment_id => environment.id) | |
368 | + blog = fast_create(Blog, :profile_id => community.id) | |
369 | + post = fast_create(TextArticle, :profile_id => community.id, :parent_id => blog.id, :name => 'the last news', :abstract => 'A picture<img src="example.png"> is <em>worth</em> a thousand words. <hr><h1>The main goals of visualization</h1>') | |
370 | + newsletter = NewsletterPlugin::Newsletter.create!( | |
371 | + :environment => environment, | |
372 | + :blog_ids => [blog.id], | |
373 | + :person => fast_create(Person)) | |
374 | + | |
375 | + assert_match /A picture<img src="example.png"> is <em>worth<\/em> a thousand words. <hr><h1>The main goals of visualization<\/h1>/, post.abstract | |
376 | + # Tags for text emphasis are whitelisted | |
377 | + assert_match /A picture is <em>worth<\/em> a thousand words. The main goals of visualization/, newsletter.body | |
363 | 378 | end |
364 | 379 | |
365 | 380 | should 'filter posts when listing posts for newsletter' do | ... | ... |
plugins/shopping_cart/db/migrate/20131226125124_move_shopping_cart_purchase_order_to_orders_plugin_order.rb
1 | 1 | OrdersPlugin.send :remove_const, :Item if defined? OrdersPlugin::Item |
2 | 2 | OrdersPlugin.send :remove_const, :Order if defined? OrdersPlugin::Order |
3 | 3 | |
4 | -class ShoppingCartPlugin::PurchaseOrder < Noosfero::Plugin::ActiveRecord | |
4 | +class ShoppingCartPlugin::PurchaseOrder < ActiveRecord::Base | |
5 | 5 | acts_as_having_settings :field => :data |
6 | 6 | |
7 | 7 | module Status |
... | ... | @@ -16,10 +16,10 @@ class Profile |
16 | 16 | has_many :orders, :class_name => 'OrdersPlugin::Order' |
17 | 17 | end |
18 | 18 | |
19 | -class OrdersPlugin::Item < Noosfero::Plugin::ActiveRecord | |
19 | +class OrdersPlugin::Item < ActiveRecord::Base | |
20 | 20 | belongs_to :order, :class_name => 'OrdersPlugin::Order' |
21 | 21 | end |
22 | -class OrdersPlugin::Order < Noosfero::Plugin::ActiveRecord | |
22 | +class OrdersPlugin::Order < ActiveRecord::Base | |
23 | 23 | has_many :items, :class_name => 'OrdersPlugin::Item', :foreign_key => :order_id |
24 | 24 | |
25 | 25 | extend CodeNumbering::ClassMethods | ... | ... |
script/quick-start
... | ... | @@ -133,6 +133,9 @@ if [ ! -f .gitignore ]; then |
133 | 133 | ln -s gitignore.example .gitignore |
134 | 134 | fi |
135 | 135 | |
136 | +# remove obsolete symbolic link added by old versions | |
137 | +rm -f vendor/rails | |
138 | + | |
136 | 139 | # you can now start the server |
137 | 140 | say "I: Congratulations, you are ready to run Noosfero." |
138 | 141 | say "I: To execute Noosfero in development mode, run \`./script/development\` and browse to http://localhost:3000" | ... | ... |
test/unit/api/articles_test.rb
... | ... | @@ -31,7 +31,7 @@ class ArticlesTest < ActiveSupport::TestCase |
31 | 31 | end |
32 | 32 | |
33 | 33 | should 'not return article if user has no permission to view it' do |
34 | - person = fast_create(Person) | |
34 | + person = fast_create(Person, :environment_id => environment.id) | |
35 | 35 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) |
36 | 36 | assert !article.published? |
37 | 37 | |
... | ... | @@ -48,8 +48,17 @@ class ArticlesTest < ActiveSupport::TestCase |
48 | 48 | assert_equivalent [child1.id, child2.id], json["articles"].map { |a| a["id"] } |
49 | 49 | end |
50 | 50 | |
51 | + should 'list public article children for not logged in access' do | |
52 | + article = fast_create(Article, :profile_id => user.person.id, :name => "Some thing") | |
53 | + child1 = fast_create(Article, :parent_id => article.id, :profile_id => user.person.id, :name => "Some thing") | |
54 | + child2 = fast_create(Article, :parent_id => article.id, :profile_id => user.person.id, :name => "Some thing") | |
55 | + get "/api/v1/articles/#{article.id}/children" | |
56 | + json = JSON.parse(last_response.body) | |
57 | + assert_equivalent [child1.id, child2.id], json["articles"].map { |a| a["id"] } | |
58 | + end | |
59 | + | |
51 | 60 | should 'not list children of forbidden article' do |
52 | - person = fast_create(Person) | |
61 | + person = fast_create(Person, :environment_id => environment.id) | |
53 | 62 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) |
54 | 63 | child1 = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing") |
55 | 64 | child2 = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing") |
... | ... | @@ -58,7 +67,7 @@ class ArticlesTest < ActiveSupport::TestCase |
58 | 67 | end |
59 | 68 | |
60 | 69 | should 'not return child of forbidden article' do |
61 | - person = fast_create(Person) | |
70 | + person = fast_create(Person, :environment_id => environment.id) | |
62 | 71 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) |
63 | 72 | child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing") |
64 | 73 | get "/api/v1/articles/#{article.id}/children/#{child.id}?#{params.to_query}" |
... | ... | @@ -66,7 +75,7 @@ class ArticlesTest < ActiveSupport::TestCase |
66 | 75 | end |
67 | 76 | |
68 | 77 | should 'not return private child' do |
69 | - person = fast_create(Person) | |
78 | + person = fast_create(Person, :environment_id => environment.id) | |
70 | 79 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing") |
71 | 80 | child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing", :published => false) |
72 | 81 | get "/api/v1/articles/#{article.id}/children/#{child.id}?#{params.to_query}" |
... | ... | @@ -74,7 +83,7 @@ class ArticlesTest < ActiveSupport::TestCase |
74 | 83 | end |
75 | 84 | |
76 | 85 | should 'not list private child' do |
77 | - person = fast_create(Person) | |
86 | + person = fast_create(Person, :environment_id => environment.id) | |
78 | 87 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing") |
79 | 88 | child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing", :published => false) |
80 | 89 | get "/api/v1/articles/#{article.id}/children?#{params.to_query}" |
... | ... | @@ -82,6 +91,74 @@ class ArticlesTest < ActiveSupport::TestCase |
82 | 91 | assert_not_includes json['articles'].map {|a| a['id']}, child.id |
83 | 92 | end |
84 | 93 | |
94 | + should 'perform a vote in a article identified by id' do | |
95 | + article = fast_create(Article, :profile_id => @person.id, :name => "Some thing") | |
96 | + @params[:value] = 1 | |
97 | + | |
98 | + post "/api/v1/articles/#{article.id}/vote?#{params.to_query}" | |
99 | + json = JSON.parse(last_response.body) | |
100 | + | |
101 | + assert_not_equal 401, last_response.status | |
102 | + assert_equal true, json['vote'] | |
103 | + end | |
104 | + | |
105 | + expose_attributes = %w(id body abstract created_at title author profile categories image votes_for votes_against setting position hits start_date end_date tag_list parent children children_count) | |
106 | + | |
107 | + expose_attributes.each do |attr| | |
108 | + should "expose article #{attr} attribute by default" do | |
109 | + article = fast_create(Article, :profile_id => user.person.id, :name => "Some thing") | |
110 | + get "/api/v1/articles/?#{params.to_query}" | |
111 | + json = JSON.parse(last_response.body) | |
112 | + assert json["articles"].last.has_key?(attr) | |
113 | + end | |
114 | + end | |
115 | + | |
116 | + should "update body of article created by me" do | |
117 | + new_value = "Another body" | |
118 | + params[:article] = {:body => new_value} | |
119 | + article = fast_create(Article, :profile_id => person.id) | |
120 | + post "/api/v1/articles/#{article.id}?#{params.to_query}" | |
121 | + json = JSON.parse(last_response.body) | |
122 | + assert_equal new_value, json["article"]["body"] | |
123 | + end | |
124 | + | |
125 | + should "update title of article created by me" do | |
126 | + new_value = "Another name" | |
127 | + params[:article] = {:name => new_value} | |
128 | + article = fast_create(Article, :profile_id => person.id) | |
129 | + post "/api/v1/articles/#{article.id}?#{params.to_query}" | |
130 | + json = JSON.parse(last_response.body) | |
131 | + assert_equal new_value, json["article"]["title"] | |
132 | + end | |
133 | + | |
134 | + should 'not update article of another user' do | |
135 | + another_person = fast_create(Person, :environment_id => environment.id) | |
136 | + article = fast_create(Article, :profile_id => another_person.id) | |
137 | + params[:article] = {:title => 'Some title'} | |
138 | + post "/api/v1/articles/#{article.id}?#{params.to_query}" | |
139 | + assert_equal 403, last_response.status | |
140 | + end | |
141 | + | |
142 | + should 'not update article without permission in community' do | |
143 | + community = fast_create(Community, :environment_id => environment.id) | |
144 | + article = fast_create(Article, :profile_id => community.id) | |
145 | + params[:article] = {:name => 'New title'} | |
146 | + post "/api/v1/articles/#{article.id}?#{params.to_query}" | |
147 | + assert_equal 403, last_response.status | |
148 | + end | |
149 | + | |
150 | + | |
151 | + should 'update article of community if user has permission' do | |
152 | + community = fast_create(Community, :environment_id => environment.id) | |
153 | + give_permission(person, 'post_content', community) | |
154 | + article = fast_create(Article, :profile_id => community.id) | |
155 | + new_value = "Another body" | |
156 | + params[:article] = {:body => new_value} | |
157 | + post "/api/v1/articles/#{article.id}?#{params.to_query}" | |
158 | + json = JSON.parse(last_response.body) | |
159 | + assert_equal new_value, json["article"]["body"] | |
160 | + end | |
161 | + | |
85 | 162 | should 'list articles with pagination' do |
86 | 163 | Article.destroy_all |
87 | 164 | article_one = fast_create(Article, :profile_id => user.person.id, :name => "Another thing", :created_at => 2.days.ago) |
... | ... | @@ -126,7 +203,7 @@ class ArticlesTest < ActiveSupport::TestCase |
126 | 203 | profile_kinds = %w(community person enterprise) |
127 | 204 | profile_kinds.each do |kind| |
128 | 205 | should "return article by #{kind}" do |
129 | - profile = fast_create(kind.camelcase.constantize) | |
206 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
130 | 207 | article = fast_create(Article, :profile_id => profile.id, :name => "Some thing") |
131 | 208 | get "/api/v1/#{kind.pluralize}/#{profile.id}/articles/#{article.id}?#{params.to_query}" |
132 | 209 | json = JSON.parse(last_response.body) |
... | ... | @@ -134,7 +211,7 @@ class ArticlesTest < ActiveSupport::TestCase |
134 | 211 | end |
135 | 212 | |
136 | 213 | should "not return article by #{kind} if user has no permission to view it" do |
137 | - profile = fast_create(kind.camelcase.constantize) | |
214 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
138 | 215 | article = fast_create(Article, :profile_id => profile.id, :name => "Some thing", :published => false) |
139 | 216 | assert !article.published? |
140 | 217 | |
... | ... | @@ -143,7 +220,7 @@ class ArticlesTest < ActiveSupport::TestCase |
143 | 220 | end |
144 | 221 | |
145 | 222 | should "not list forbidden article when listing articles by #{kind}" do |
146 | - profile = fast_create(kind.camelcase.constantize) | |
223 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
147 | 224 | article = fast_create(Article, :profile_id => profile.id, :name => "Some thing", :published => false) |
148 | 225 | assert !article.published? |
149 | 226 | |
... | ... | @@ -151,6 +228,29 @@ class ArticlesTest < ActiveSupport::TestCase |
151 | 228 | json = JSON.parse(last_response.body) |
152 | 229 | assert_not_includes json['articles'].map {|a| a['id']}, article.id |
153 | 230 | end |
231 | + | |
232 | + should "return article by #{kind} and path" do | |
233 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
234 | + parent_article = Folder.create!(:profile => profile, :name => "Parent Folder") | |
235 | + article = Article.create!(:profile => profile, :name => "Some thing", :parent => parent_article) | |
236 | + | |
237 | + params[:path] = parent_article.slug+'/'+article.slug | |
238 | + get "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" | |
239 | + json = JSON.parse(last_response.body) | |
240 | + assert_equal article.id, json["article"]["id"] | |
241 | + end | |
242 | + | |
243 | + should "not return article by #{kind} and path if user has no permission to view it" do | |
244 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
245 | + parent_article = Folder.create!(:profile => profile, :name => "Parent Folder") | |
246 | + article = Article.create!(:profile => profile, :name => "Some thing", :parent => parent_article, :published => false) | |
247 | + | |
248 | + assert !article.published? | |
249 | + | |
250 | + params[:path] = parent_article.slug+'/'+article.slug | |
251 | + get "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" | |
252 | + assert_equal 403, last_response.status | |
253 | + end | |
154 | 254 | end |
155 | 255 | |
156 | 256 | ############################# |
... | ... | @@ -160,7 +260,7 @@ class ArticlesTest < ActiveSupport::TestCase |
160 | 260 | group_kinds = %w(community enterprise) |
161 | 261 | group_kinds.each do |kind| |
162 | 262 | should "#{kind}: create article" do |
163 | - profile = fast_create(kind.camelcase.constantize) | |
263 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
164 | 264 | give_permission(user.person, 'post_content', profile) |
165 | 265 | params[:article] = {:name => "Title"} |
166 | 266 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" |
... | ... | @@ -169,16 +269,16 @@ class ArticlesTest < ActiveSupport::TestCase |
169 | 269 | end |
170 | 270 | |
171 | 271 | should "#{kind}: do not create article if user has no permission to post content" do |
172 | - profile = fast_create(kind.camelcase.constantize) | |
272 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
173 | 273 | give_permission(user.person, 'invite_members', profile) |
174 | 274 | params[:article] = {:name => "Title"} |
175 | 275 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" |
176 | 276 | assert_equal 403, last_response.status |
177 | 277 | end |
178 | 278 | |
179 | - should "#{kind}: create article with parent" do | |
180 | - profile = fast_create(kind.camelcase.constantize) | |
181 | - profile.add_member(user.person) | |
279 | + should "#{kind} create article with parent" do | |
280 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
281 | + Person.any_instance.stubs(:can_post_content?).with(profile).returns(true) | |
182 | 282 | article = fast_create(Article) |
183 | 283 | |
184 | 284 | params[:article] = {:name => "Title", :parent_id => article.id} |
... | ... | @@ -187,9 +287,9 @@ class ArticlesTest < ActiveSupport::TestCase |
187 | 287 | assert_equal article.id, json["article"]["parent"]["id"] |
188 | 288 | end |
189 | 289 | |
190 | - should "#{kind}: create article with content type passed as parameter" do | |
191 | - profile = fast_create(kind.camelcase.constantize) | |
192 | - profile.add_member(user.person) | |
290 | + should "#{kind} create article with content type passed as parameter" do | |
291 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
292 | + Person.any_instance.stubs(:can_post_content?).with(profile).returns(true) | |
193 | 293 | |
194 | 294 | Article.delete_all |
195 | 295 | params[:article] = {:name => "Title"} |
... | ... | @@ -201,8 +301,8 @@ class ArticlesTest < ActiveSupport::TestCase |
201 | 301 | end |
202 | 302 | |
203 | 303 | should "#{kind}: create article of TinyMceArticle type if no content type is passed as parameter" do |
204 | - profile = fast_create(kind.camelcase.constantize) | |
205 | - profile.add_member(user.person) | |
304 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
305 | + Person.any_instance.stubs(:can_post_content?).with(profile).returns(true) | |
206 | 306 | |
207 | 307 | params[:article] = {:name => "Title"} |
208 | 308 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" |
... | ... | @@ -212,7 +312,7 @@ class ArticlesTest < ActiveSupport::TestCase |
212 | 312 | end |
213 | 313 | |
214 | 314 | should "#{kind}: not create article with invalid article content type" do |
215 | - profile = fast_create(kind.camelcase.constantize) | |
315 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
216 | 316 | profile.add_member(user.person) |
217 | 317 | |
218 | 318 | params[:article] = {:name => "Title"} |
... | ... | @@ -223,20 +323,20 @@ class ArticlesTest < ActiveSupport::TestCase |
223 | 323 | assert_equal 403, last_response.status |
224 | 324 | end |
225 | 325 | |
226 | - should "#{kind}: create article defining the correct profile" do | |
227 | - profile = fast_create(kind.camelcase.constantize) | |
228 | - profile.add_member(user.person) | |
326 | + should "#{kind} create article defining the correct profile" do | |
327 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
328 | + Person.any_instance.stubs(:can_post_content?).with(profile).returns(true) | |
229 | 329 | |
230 | 330 | params[:article] = {:name => "Title"} |
231 | 331 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" |
232 | 332 | json = JSON.parse(last_response.body) |
233 | 333 | |
234 | - assert_equal profile, Article.last.profile | |
334 | + assert_equal profile.id, json['article']['profile']['id'] | |
235 | 335 | end |
236 | 336 | |
237 | 337 | should "#{kind}: create article defining the created_by" do |
238 | - profile = fast_create(kind.camelcase.constantize) | |
239 | - profile.add_member(user.person) | |
338 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
339 | + Person.any_instance.stubs(:can_post_content?).with(profile).returns(true) | |
240 | 340 | |
241 | 341 | params[:article] = {:name => "Title"} |
242 | 342 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" |
... | ... | @@ -246,8 +346,8 @@ class ArticlesTest < ActiveSupport::TestCase |
246 | 346 | end |
247 | 347 | |
248 | 348 | should "#{kind}: create article defining the last_changed_by" do |
249 | - profile = fast_create(kind.camelcase.constantize) | |
250 | - profile.add_member(user.person) | |
349 | + profile = fast_create(kind.camelcase.constantize, :environment_id => environment.id) | |
350 | + Person.any_instance.stubs(:can_post_content?).with(profile).returns(true) | |
251 | 351 | |
252 | 352 | params[:article] = {:name => "Title"} |
253 | 353 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" |
... | ... | @@ -269,7 +369,7 @@ class ArticlesTest < ActiveSupport::TestCase |
269 | 369 | end |
270 | 370 | |
271 | 371 | should 'person do not create article if user has no permission to post content' do |
272 | - person = fast_create(Person) | |
372 | + person = fast_create(Person, :environment_id => environment.id) | |
273 | 373 | params[:article] = {:name => "Title"} |
274 | 374 | post "/api/v1/people/#{person.id}/articles?#{params.to_query}" |
275 | 375 | assert_equal 403, last_response.status |
... | ... | @@ -376,4 +476,99 @@ class ArticlesTest < ActiveSupport::TestCase |
376 | 476 | assert_equal [0, 1, 1], [a1.reload.hits, a2.reload.hits, a3.reload.hits] |
377 | 477 | end |
378 | 478 | |
479 | + should 'update hit attribute of article specific children' do | |
480 | + a1 = fast_create(Article, :profile_id => user.person.id) | |
481 | + a2 = fast_create(Article, :parent_id => a1.id, :profile_id => user.person.id) | |
482 | + get "/api/v1/articles/#{a1.id}/children/#{a2.id}?#{params.to_query}" | |
483 | + json = JSON.parse(last_response.body) | |
484 | + assert_equal 1, json['article']['hits'] | |
485 | + end | |
486 | + | |
487 | + should 'list all events of a community in a given category' do | |
488 | + co = Community.create(identifier: 'my-community', name: 'name-my-community') | |
489 | + c1 = Category.create(environment: Environment.default, name: 'my-category') | |
490 | + c2 = Category.create(environment: Environment.default, name: 'dont-show-me-this-category') | |
491 | + e1 = fast_create(Event, :profile_id => co.id) | |
492 | + e2 = fast_create(Event, :profile_id => co.id) | |
493 | + e1.categories << c1 | |
494 | + e2.categories << c2 | |
495 | + e1.save! | |
496 | + e2.save! | |
497 | + params['content_type']='Event' | |
498 | + get "api/v1/communities/#{co.id}/articles?#{params.to_query}" | |
499 | + json = JSON.parse(last_response.body) | |
500 | + assert_equal json['articles'].count, 2 | |
501 | + end | |
502 | + | |
503 | + should 'list a event of a community in a given category' do | |
504 | + co = Community.create(identifier: 'my-community', name: 'name-my-community') | |
505 | + c1 = Category.create(environment: Environment.default, name: 'my-category') | |
506 | + c2 = Category.create(environment: Environment.default, name: 'dont-show-me-this-category') | |
507 | + e1 = fast_create(Event, :profile_id => co.id) | |
508 | + e2 = fast_create(Event, :profile_id => co.id) | |
509 | + e1.categories << c1 | |
510 | + e2.categories << c2 | |
511 | + e1.save! | |
512 | + e2.save! | |
513 | + params['category_ids[]']=c1.id | |
514 | + params['content_type']='Event' | |
515 | + get "api/v1/communities/#{co.id}/articles?#{params.to_query}" | |
516 | + json = JSON.parse(last_response.body) | |
517 | + #should show only one article, since the other not in the same category | |
518 | + assert_equal 1, json['articles'].count | |
519 | + assert_equal e1.id, json['articles'][0]['id'] | |
520 | + end | |
521 | + | |
522 | + should 'not list uncategorized event of a community if a category is given' do | |
523 | + co = Community.create(identifier: 'my-community', name: 'name-my-community') | |
524 | + c1 = Category.create(environment: Environment.default, name: 'my-category') | |
525 | + c2 = Category.create(environment: Environment.default, name: 'dont-show-me-this-category') | |
526 | + e1 = fast_create(Event, :profile_id => co.id) | |
527 | + e2 = fast_create(Event, :profile_id => co.id) | |
528 | + e3 = fast_create(Event, :profile_id => co.id) | |
529 | + e1.categories << c1 | |
530 | + e2.categories << c2 | |
531 | + params['category_ids[]']=c1.id | |
532 | + params['content_type']='Event' | |
533 | + get "api/v1/communities/#{co.id}/articles?#{params.to_query}" | |
534 | + json = JSON.parse(last_response.body) | |
535 | + assert_equal 1, json['articles'].count | |
536 | + assert_equal e1.id, json['articles'][0]['id'] | |
537 | + end | |
538 | + | |
539 | + should 'list events of a community in a given 2 categories' do | |
540 | + co = Community.create(identifier: 'my-community', name: 'name-my-community') | |
541 | + c1 = Category.create(environment: Environment.default, name: 'my-category') | |
542 | + c2 = Category.create(environment: Environment.default, name: 'dont-show-me-this-category') | |
543 | + e1 = fast_create(Event, :profile_id => co.id) | |
544 | + e2 = fast_create(Event, :profile_id => co.id) | |
545 | + e1.categories << c1 | |
546 | + e2.categories << c2 | |
547 | + e1.save! | |
548 | + e2.save! | |
549 | + params['content_type']='Event' | |
550 | + params['categories_ids'] = [c1.id, c2.id] | |
551 | + get "api/v1/communities/#{co.id}/articles?#{params.to_query}" | |
552 | + json = JSON.parse(last_response.body) | |
553 | + assert_equal json['articles'].count, 2 | |
554 | + end | |
555 | + | |
556 | + should 'Show 2 events since it uses an IN operator for category instead of an OR' do | |
557 | + co = Community.create(identifier: 'my-community', name: 'name-my-community') | |
558 | + c1 = Category.create(environment: Environment.default, name: 'my-category') | |
559 | + c2 = Category.create(environment: Environment.default, name: 'dont-show-me-this-category') | |
560 | + c3 = Category.create(environment: Environment.default, name: 'extra-category') | |
561 | + e1 = fast_create(Event, :profile_id => co.id) | |
562 | + e2 = fast_create(Event, :profile_id => co.id) | |
563 | + e1.categories << c1 | |
564 | + e2.categories << c2 | |
565 | + e1.save! | |
566 | + e2.save! | |
567 | + params['content_type']='Event' | |
568 | + params['categories_ids'] = [c1.id, c2.id, c3.id] | |
569 | + get "api/v1/communities/#{co.id}/articles?#{params.to_query}" | |
570 | + json = JSON.parse(last_response.body) | |
571 | + assert_equal json['articles'].count, 2 | |
572 | + end | |
573 | + | |
379 | 574 | end | ... | ... |
test/unit/api/categories_test.rb
... | ... | @@ -7,25 +7,25 @@ class CategoriesTest < ActiveSupport::TestCase |
7 | 7 | end |
8 | 8 | |
9 | 9 | should 'list categories' do |
10 | - category = fast_create(Category) | |
10 | + category = fast_create(Category, :environment_id => environment.id) | |
11 | 11 | get "/api/v1/categories/?#{params.to_query}" |
12 | 12 | json = JSON.parse(last_response.body) |
13 | 13 | assert_includes json["categories"].map { |c| c["name"] }, category.name |
14 | 14 | end |
15 | 15 | |
16 | 16 | should 'get category by id' do |
17 | - category = fast_create(Category) | |
17 | + category = fast_create(Category, :environment_id => environment.id) | |
18 | 18 | get "/api/v1/categories/#{category.id}/?#{params.to_query}" |
19 | 19 | json = JSON.parse(last_response.body) |
20 | 20 | assert_equal category.name, json["category"]["name"] |
21 | 21 | end |
22 | 22 | |
23 | 23 | should 'list parent and children when get category by id' do |
24 | - parent = fast_create(Category) | |
25 | - child_1 = fast_create(Category) | |
26 | - child_2 = fast_create(Category) | |
24 | + parent = fast_create(Category, :environment_id => environment.id) | |
25 | + child_1 = fast_create(Category, :environment_id => environment.id) | |
26 | + child_2 = fast_create(Category, :environment_id => environment.id) | |
27 | 27 | |
28 | - category = fast_create(Category) | |
28 | + category = fast_create(Category, :environment_id => environment.id) | |
29 | 29 | category.parent = parent |
30 | 30 | category.children << child_1 |
31 | 31 | category.children << child_2 |
... | ... | @@ -33,16 +33,16 @@ class CategoriesTest < ActiveSupport::TestCase |
33 | 33 | |
34 | 34 | get "/api/v1/categories/#{category.id}/?#{params.to_query}" |
35 | 35 | json = JSON.parse(last_response.body) |
36 | - assert_equal({'id' => parent.id, 'name' => parent.name}, json['category']['parent']) | |
36 | + assert_equal({'id' => parent.id, 'name' => parent.name, 'slug' => parent.slug}, json['category']['parent']) | |
37 | 37 | assert_equivalent [child_1.id, child_2.id], json['category']['children'].map { |c| c['id'] } |
38 | 38 | end |
39 | 39 | |
40 | 40 | should 'include parent in categories list if params is true' do |
41 | - parent_1 = fast_create(Category) # parent_1 has no parent category | |
42 | - child_1 = fast_create(Category) | |
43 | - child_2 = fast_create(Category) | |
41 | + parent_1 = fast_create(Category, :environment_id => environment.id) # parent_1 has no parent category | |
42 | + child_1 = fast_create(Category, :environment_id => environment.id) | |
43 | + child_2 = fast_create(Category, :environment_id => environment.id) | |
44 | 44 | |
45 | - parent_2 = fast_create(Category) | |
45 | + parent_2 = fast_create(Category, :environment_id => environment.id) | |
46 | 46 | parent_2.parent = parent_1 |
47 | 47 | parent_2.children << child_1 |
48 | 48 | parent_2.children << child_2 |
... | ... | @@ -60,10 +60,10 @@ class CategoriesTest < ActiveSupport::TestCase |
60 | 60 | end |
61 | 61 | |
62 | 62 | should 'include children in categories list if params is true' do |
63 | - category = fast_create(Category) | |
64 | - child_1 = fast_create(Category) | |
65 | - child_2 = fast_create(Category) | |
66 | - child_3 = fast_create(Category) | |
63 | + category = fast_create(Category, :environment_id => environment.id) | |
64 | + child_1 = fast_create(Category, :environment_id => environment.id) | |
65 | + child_2 = fast_create(Category, :environment_id => environment.id) | |
66 | + child_3 = fast_create(Category, :environment_id => environment.id) | |
67 | 67 | |
68 | 68 | category.children << child_1 |
69 | 69 | category.children << child_2 |
... | ... | @@ -83,4 +83,15 @@ class CategoriesTest < ActiveSupport::TestCase |
83 | 83 | json["categories"].map{ |c| c['children'].map{ |child| child['id'] }.sort } |
84 | 84 | end |
85 | 85 | |
86 | + expose_attributes = %w(id name full_name image display_color) | |
87 | + | |
88 | + expose_attributes.each do |attr| | |
89 | + should "expose category #{attr} attribute by default" do | |
90 | + category = fast_create(Category, :environment_id => environment.id) | |
91 | + get "/api/v1/categories/?#{params.to_query}" | |
92 | + json = JSON.parse(last_response.body) | |
93 | + assert json["categories"].last.has_key?(attr) | |
94 | + end | |
95 | + end | |
96 | + | |
86 | 97 | end | ... | ... |
test/unit/api/comments_test.rb
... | ... | @@ -65,4 +65,17 @@ class CommentsTest < ActiveSupport::TestCase |
65 | 65 | assert_equal 201, last_response.status |
66 | 66 | assert_equal body, json['comment']['body'] |
67 | 67 | end |
68 | + | |
69 | + should 'comment creation define the source' do | |
70 | + amount = Comment.count | |
71 | + article = fast_create(Article, :profile_id => user.person.id, :name => "Some thing") | |
72 | + body = 'My comment' | |
73 | + params.merge!({:body => body}) | |
74 | + | |
75 | + post "/api/v1/articles/#{article.id}/comments?#{params.to_query}" | |
76 | + assert_equal amount + 1, Comment.count | |
77 | + comment = Comment.last | |
78 | + assert_not_nil comment.source | |
79 | + end | |
80 | + | |
68 | 81 | end | ... | ... |
test/unit/api/communities_test.rb
... | ... | @@ -8,8 +8,8 @@ class CommunitiesTest < ActiveSupport::TestCase |
8 | 8 | end |
9 | 9 | |
10 | 10 | should 'list only communities' do |
11 | - community = fast_create(Community) | |
12 | - enterprise = fast_create(Enterprise) # should not list this enterprise | |
11 | + community = fast_create(Community, :environment_id => environment.id) | |
12 | + enterprise = fast_create(Enterprise, :environment_id => environment.id) # should not list this enterprise | |
13 | 13 | get "/api/v1/communities?#{params.to_query}" |
14 | 14 | json = JSON.parse(last_response.body) |
15 | 15 | assert_not_includes json['communities'].map {|c| c['id']}, enterprise.id |
... | ... | @@ -17,16 +17,16 @@ class CommunitiesTest < ActiveSupport::TestCase |
17 | 17 | end |
18 | 18 | |
19 | 19 | should 'list all communities' do |
20 | - community1 = fast_create(Community, :public_profile => true) | |
21 | - community2 = fast_create(Community) | |
20 | + community1 = fast_create(Community, :environment_id => environment.id, :public_profile => true) | |
21 | + community2 = fast_create(Community, :environment_id => environment.id) | |
22 | 22 | get "/api/v1/communities?#{params.to_query}" |
23 | 23 | json = JSON.parse(last_response.body) |
24 | 24 | assert_equivalent [community1.id, community2.id], json['communities'].map {|c| c['id']} |
25 | 25 | end |
26 | 26 | |
27 | 27 | should 'not list invisible communities' do |
28 | - community1 = fast_create(Community) | |
29 | - fast_create(Community, :visible => false) | |
28 | + community1 = fast_create(Community, :environment_id => environment.id) | |
29 | + fast_create(Community, :environment_id => environment.id, :visible => false) | |
30 | 30 | |
31 | 31 | get "/api/v1/communities?#{params.to_query}" |
32 | 32 | json = JSON.parse(last_response.body) |
... | ... | @@ -34,8 +34,8 @@ class CommunitiesTest < ActiveSupport::TestCase |
34 | 34 | end |
35 | 35 | |
36 | 36 | should 'not list private communities without permission' do |
37 | - community1 = fast_create(Community) | |
38 | - fast_create(Community, :public_profile => false) | |
37 | + community1 = fast_create(Community, :environment_id => environment.id) | |
38 | + fast_create(Community, :environment_id => environment.id, :public_profile => false) | |
39 | 39 | |
40 | 40 | get "/api/v1/communities?#{params.to_query}" |
41 | 41 | json = JSON.parse(last_response.body) |
... | ... | @@ -43,8 +43,8 @@ class CommunitiesTest < ActiveSupport::TestCase |
43 | 43 | end |
44 | 44 | |
45 | 45 | should 'list private community for members' do |
46 | - c1 = fast_create(Community) | |
47 | - c2 = fast_create(Community, :public_profile => false) | |
46 | + c1 = fast_create(Community, :environment_id => environment.id) | |
47 | + c2 = fast_create(Community, :environment_id => environment.id, :public_profile => false) | |
48 | 48 | c2.add_member(person) |
49 | 49 | |
50 | 50 | get "/api/v1/communities?#{params.to_query}" |
... | ... | @@ -66,7 +66,7 @@ class CommunitiesTest < ActiveSupport::TestCase |
66 | 66 | end |
67 | 67 | |
68 | 68 | should 'get community' do |
69 | - community = fast_create(Community) | |
69 | + community = fast_create(Community, :environment_id => environment.id) | |
70 | 70 | |
71 | 71 | get "/api/v1/communities/#{community.id}?#{params.to_query}" |
72 | 72 | json = JSON.parse(last_response.body) |
... | ... | @@ -74,7 +74,7 @@ class CommunitiesTest < ActiveSupport::TestCase |
74 | 74 | end |
75 | 75 | |
76 | 76 | should 'not get invisible community' do |
77 | - community = fast_create(Community, :visible => false) | |
77 | + community = fast_create(Community, :environment_id => environment.id, :visible => false) | |
78 | 78 | |
79 | 79 | get "/api/v1/communities/#{community.id}?#{params.to_query}" |
80 | 80 | json = JSON.parse(last_response.body) |
... | ... | @@ -82,8 +82,8 @@ class CommunitiesTest < ActiveSupport::TestCase |
82 | 82 | end |
83 | 83 | |
84 | 84 | should 'not get private communities without permission' do |
85 | - community = fast_create(Community) | |
86 | - fast_create(Community, :public_profile => false) | |
85 | + community = fast_create(Community, :environment_id => environment.id) | |
86 | + fast_create(Community, :environment_id => environment.id, :public_profile => false) | |
87 | 87 | |
88 | 88 | get "/api/v1/communities/#{community.id}?#{params.to_query}" |
89 | 89 | json = JSON.parse(last_response.body) |
... | ... | @@ -91,17 +91,18 @@ class CommunitiesTest < ActiveSupport::TestCase |
91 | 91 | end |
92 | 92 | |
93 | 93 | should 'get private community for members' do |
94 | - community = fast_create(Community, :public_profile => false) | |
94 | + community = fast_create(Community, :environment_id => environment.id, :public_profile => false, :visible => true) | |
95 | 95 | community.add_member(person) |
96 | 96 | |
97 | + | |
97 | 98 | get "/api/v1/communities/#{community.id}?#{params.to_query}" |
98 | 99 | json = JSON.parse(last_response.body) |
99 | 100 | assert_equal community.id, json['community']['id'] |
100 | 101 | end |
101 | 102 | |
102 | 103 | should 'list person communities' do |
103 | - community = fast_create(Community) | |
104 | - fast_create(Community) | |
104 | + community = fast_create(Community, :environment_id => environment.id) | |
105 | + fast_create(Community, :environment_id => environment.id) | |
105 | 106 | community.add_member(person) |
106 | 107 | |
107 | 108 | get "/api/v1/people/#{person.id}/communities?#{params.to_query}" |
... | ... | @@ -110,8 +111,8 @@ class CommunitiesTest < ActiveSupport::TestCase |
110 | 111 | end |
111 | 112 | |
112 | 113 | should 'not list person communities invisible' do |
113 | - c1 = fast_create(Community) | |
114 | - c2 = fast_create(Community, :visible => false) | |
114 | + c1 = fast_create(Community, :environment_id => environment.id) | |
115 | + c2 = fast_create(Community, :environment_id => environment.id, :visible => false) | |
115 | 116 | c1.add_member(person) |
116 | 117 | c2.add_member(person) |
117 | 118 | ... | ... |
test/unit/api/enterprises_test.rb
... | ... | @@ -8,8 +8,8 @@ class EnterprisesTest < ActiveSupport::TestCase |
8 | 8 | end |
9 | 9 | |
10 | 10 | should 'list only enterprises' do |
11 | - community = fast_create(Community) # should not list this community | |
12 | - enterprise = fast_create(Enterprise, :public_profile => true) | |
11 | + community = fast_create(Community, :environment_id => environment.id) # should not list this community | |
12 | + enterprise = fast_create(Enterprise, :environment_id => environment.id, :public_profile => true) | |
13 | 13 | get "/api/v1/enterprises?#{params.to_query}" |
14 | 14 | json = JSON.parse(last_response.body) |
15 | 15 | assert_includes json['enterprises'].map {|c| c['id']}, enterprise.id |
... | ... | @@ -17,15 +17,15 @@ class EnterprisesTest < ActiveSupport::TestCase |
17 | 17 | end |
18 | 18 | |
19 | 19 | should 'list all enterprises' do |
20 | - enterprise1 = fast_create(Enterprise, :public_profile => true) | |
21 | - enterprise2 = fast_create(Enterprise) | |
20 | + enterprise1 = fast_create(Enterprise, :environment_id => environment.id, :public_profile => true) | |
21 | + enterprise2 = fast_create(Enterprise, :environment_id => environment.id) | |
22 | 22 | get "/api/v1/enterprises?#{params.to_query}" |
23 | 23 | json = JSON.parse(last_response.body) |
24 | 24 | assert_equivalent [enterprise1.id, enterprise2.id], json['enterprises'].map {|c| c['id']} |
25 | 25 | end |
26 | 26 | |
27 | 27 | should 'not list invisible enterprises' do |
28 | - enterprise1 = fast_create(Enterprise) | |
28 | + enterprise1 = fast_create(Enterprise, :environment_id => environment.id) | |
29 | 29 | fast_create(Enterprise, :visible => false) |
30 | 30 | |
31 | 31 | get "/api/v1/enterprises?#{params.to_query}" |
... | ... | @@ -34,8 +34,8 @@ class EnterprisesTest < ActiveSupport::TestCase |
34 | 34 | end |
35 | 35 | |
36 | 36 | should 'not list private enterprises without permission' do |
37 | - enterprise1 = fast_create(Enterprise) | |
38 | - fast_create(Enterprise, :public_profile => false) | |
37 | + enterprise1 = fast_create(Enterprise, :environment_id => environment.id) | |
38 | + fast_create(Enterprise, :environment_id => environment.id, :public_profile => false) | |
39 | 39 | |
40 | 40 | get "/api/v1/enterprises?#{params.to_query}" |
41 | 41 | json = JSON.parse(last_response.body) |
... | ... | @@ -43,8 +43,8 @@ class EnterprisesTest < ActiveSupport::TestCase |
43 | 43 | end |
44 | 44 | |
45 | 45 | should 'list private enterprise for members' do |
46 | - c1 = fast_create(Enterprise) | |
47 | - c2 = fast_create(Enterprise, :public_profile => false) | |
46 | + c1 = fast_create(Enterprise, :environment_id => environment.id) | |
47 | + c2 = fast_create(Enterprise, :environment_id => environment.id, :public_profile => false) | |
48 | 48 | c2.add_member(person) |
49 | 49 | |
50 | 50 | get "/api/v1/enterprises?#{params.to_query}" |
... | ... | @@ -53,7 +53,7 @@ class EnterprisesTest < ActiveSupport::TestCase |
53 | 53 | end |
54 | 54 | |
55 | 55 | should 'get enterprise' do |
56 | - enterprise = fast_create(Enterprise) | |
56 | + enterprise = fast_create(Enterprise, :environment_id => environment.id) | |
57 | 57 | |
58 | 58 | get "/api/v1/enterprises/#{enterprise.id}?#{params.to_query}" |
59 | 59 | json = JSON.parse(last_response.body) |
... | ... | @@ -69,8 +69,8 @@ class EnterprisesTest < ActiveSupport::TestCase |
69 | 69 | end |
70 | 70 | |
71 | 71 | should 'not get private enterprises without permission' do |
72 | - enterprise = fast_create(Enterprise) | |
73 | - fast_create(Enterprise, :public_profile => false) | |
72 | + enterprise = fast_create(Enterprise, :environment_id => environment.id) | |
73 | + fast_create(Enterprise, :environment_id => environment.id, :public_profile => false) | |
74 | 74 | |
75 | 75 | get "/api/v1/enterprises/#{enterprise.id}?#{params.to_query}" |
76 | 76 | json = JSON.parse(last_response.body) |
... | ... | @@ -87,8 +87,8 @@ class EnterprisesTest < ActiveSupport::TestCase |
87 | 87 | end |
88 | 88 | |
89 | 89 | should 'list person enterprises' do |
90 | - enterprise = fast_create(Enterprise) | |
91 | - fast_create(Enterprise) | |
90 | + enterprise = fast_create(Enterprise, :environment_id => environment.id) | |
91 | + fast_create(Enterprise, :environment_id => environment.id) | |
92 | 92 | enterprise.add_member(person) |
93 | 93 | |
94 | 94 | get "/api/v1/people/#{person.id}/enterprises?#{params.to_query}" |
... | ... | @@ -97,8 +97,8 @@ class EnterprisesTest < ActiveSupport::TestCase |
97 | 97 | end |
98 | 98 | |
99 | 99 | should 'not list person enterprises invisible' do |
100 | - c1 = fast_create(Enterprise) | |
101 | - c2 = fast_create(Enterprise, :visible => false) | |
100 | + c1 = fast_create(Enterprise, :environment_id => environment.id) | |
101 | + c2 = fast_create(Enterprise, :environment_id => environment.id, :visible => false) | |
102 | 102 | c1.add_member(person) |
103 | 103 | c2.add_member(person) |
104 | 104 | ... | ... |
test/unit/api/helpers_test.rb
... | ... | @@ -25,15 +25,6 @@ class APIHelpersTest < ActiveSupport::TestCase |
25 | 25 | assert_equal user, current_user |
26 | 26 | end |
27 | 27 | |
28 | - should 'not get the current user with expired token' do | |
29 | - user = create_user('someuser') | |
30 | - user.generate_private_token! | |
31 | - user.private_token_generated_at = DateTime.now.prev_year | |
32 | - user.save | |
33 | - self.params = {:private_token => user.private_token} | |
34 | - assert_nil current_user | |
35 | - end | |
36 | - | |
37 | 28 | should 'get the person of current user' do |
38 | 29 | user = create_user('someuser') |
39 | 30 | user.generate_private_token! |
... | ... | @@ -161,6 +152,39 @@ class APIHelpersTest < ActiveSupport::TestCase |
161 | 152 | assert_nil make_conditions_with_parameter[:type] |
162 | 153 | end |
163 | 154 | |
155 | + #test_should_make_order_with_parameters_return_order_if attribute_is_found_at_object_association | |
156 | + should 'make_order_with_parameters return order if attribute is found at object association' do | |
157 | + environment = Environment.new | |
158 | + params = {:order => "name ASC"} | |
159 | + assert_equal "name ASC", make_order_with_parameters(environment, "articles", params) | |
160 | + end | |
161 | + | |
162 | + # test added to check for eventual sql injection vunerabillity | |
163 | + #test_should_make_order_with_parameters_return_default_order_if_attributes_not_exists | |
164 | + should 'make_order_with_parameters return default order if attributes not exists' do | |
165 | + environment = Environment.new | |
166 | + params = {:order => "CRAZY_FIELD ASC"} # quote used to check sql injection vunerabillity | |
167 | + assert_equal "created_at DESC", make_order_with_parameters(environment, "articles", params) | |
168 | + end | |
169 | + | |
170 | + should 'make_order_with_parameters return default order if sql injection detected' do | |
171 | + environment = Environment.new | |
172 | + params = {:order => "name' ASC"} # quote used to check sql injection vunerabillity | |
173 | + assert_equal "created_at DESC", make_order_with_parameters(environment, "articles", params) | |
174 | + end | |
175 | + | |
176 | + should 'make_order_with_parameters return RANDOM() if random is passed' do | |
177 | + environment = Environment.new | |
178 | + params = {:order => "random"} # quote used to check sql injection vunerabillity | |
179 | + assert_equal "RANDOM()", make_order_with_parameters(environment, "articles", params) | |
180 | + end | |
181 | + | |
182 | + should 'make_order_with_parameters return RANDOM() if random function is passed' do | |
183 | + environment = Environment.new | |
184 | + params = {:order => "random()"} # quote used to check sql injection vunerabillity | |
185 | + assert_equal "RANDOM()", make_order_with_parameters(environment, "articles", params) | |
186 | + end | |
187 | + | |
164 | 188 | should 'render not_found if endpoint is unavailable' do |
165 | 189 | Noosfero::API::API.stubs(:endpoint_unavailable?).returns(true) |
166 | 190 | self.expects(:not_found!) | ... | ... |
test/unit/api/people_test.rb
... | ... | @@ -148,4 +148,21 @@ class PeopleTest < ActiveSupport::TestCase |
148 | 148 | get "/api/v1/people/#{some_person.id}/permissions?#{params.to_query}" |
149 | 149 | assert_equal 403, last_response.status |
150 | 150 | end |
151 | + | |
152 | + should 'not update another person' do | |
153 | + person = fast_create(Person, :environment_id => environment.id) | |
154 | + post "/api/v1/people/#{person.id}?#{params.to_query}" | |
155 | + assert_equal 403, last_response.status | |
156 | + end | |
157 | + | |
158 | + should 'update yourself' do | |
159 | + another_name = 'Another Name' | |
160 | + params[:person] = {} | |
161 | + params[:person][:name] = another_name | |
162 | + assert_not_equal another_name, person.name | |
163 | + post "/api/v1/people/#{person.id}?#{params.to_query}" | |
164 | + person.reload | |
165 | + assert_equal another_name, person.name | |
166 | + end | |
167 | + | |
151 | 168 | end | ... | ... |
... | ... | @@ -0,0 +1,139 @@ |
1 | +require_relative 'test_helper' | |
2 | + | |
3 | +class SearchTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @person = create_user('testing').person | |
7 | + end | |
8 | + attr_reader :person | |
9 | + | |
10 | + should 'not list unpublished articles' do | |
11 | + Article.delete_all | |
12 | + article = fast_create(Article, :profile_id => person.id, :published => false) | |
13 | + assert !article.published? | |
14 | + get "/api/v1/search/article" | |
15 | + json = JSON.parse(last_response.body) | |
16 | + assert_empty json['articles'] | |
17 | + end | |
18 | + | |
19 | + should 'list articles' do | |
20 | + fast_create(Article, :profile_id => person.id) | |
21 | + get "/api/v1/search/article" | |
22 | + json = JSON.parse(last_response.body) | |
23 | + assert_not_empty json['articles'] | |
24 | + end | |
25 | + | |
26 | + should 'invalid search string articles' do | |
27 | + fast_create(Article, :profile_id => person.id, :name => 'some article') | |
28 | + get "/api/v1/search/article?query=test" | |
29 | + json = JSON.parse(last_response.body) | |
30 | + assert_empty json['articles'] | |
31 | + end | |
32 | + | |
33 | + should 'do not list articles of wrong type' do | |
34 | + fast_create(Article, :profile_id => person.id) | |
35 | + get "/api/v1/search/article?type=TinyMceArticle" | |
36 | + json = JSON.parse(last_response.body) | |
37 | + assert_empty json['articles'] | |
38 | + end | |
39 | + | |
40 | + should 'list articles of one type' do | |
41 | + fast_create(Article, :profile_id => person.id) | |
42 | + article = fast_create(TinyMceArticle, :profile_id => person.id) | |
43 | + | |
44 | + get "/api/v1/search/article?type=TinyMceArticle" | |
45 | + json = JSON.parse(last_response.body) | |
46 | + assert_equal article.id, json['articles'].first['id'] | |
47 | + end | |
48 | + | |
49 | + should 'list articles of one type and query string' do | |
50 | + fast_create(Article, :profile_id => person.id, :name => 'some article') | |
51 | + fast_create(Article, :profile_id => person.id, :name => 'Some thing') | |
52 | + article = fast_create(TinyMceArticle, :profile_id => person.id, :name => 'Some thing') | |
53 | + get "/api/v1/search/article?type=TinyMceArticle&query=thing" | |
54 | + json = JSON.parse(last_response.body) | |
55 | + assert_equal 1, json['articles'].count | |
56 | + assert_equal article.id, json['articles'].first['id'] | |
57 | + end | |
58 | + | |
59 | + should 'not return more entries than page limit' do | |
60 | + 1.upto(5).each do |n| | |
61 | + fast_create(Article, :profile_id => person.id, :name => "Article #{n}") | |
62 | + end | |
63 | + | |
64 | + get "/api/v1/search/article?query=Article&per_page=3" | |
65 | + json = JSON.parse(last_response.body) | |
66 | + | |
67 | + assert_equal 3, json['articles'].count | |
68 | + end | |
69 | + | |
70 | + should 'return entries second page' do | |
71 | + 1.upto(5).each do |n| | |
72 | + fast_create(Article, :profile_id => person.id, :name => "Article #{n}") | |
73 | + end | |
74 | + | |
75 | + get "/api/v1/search/article?query=Article&per_page=3&page=2" | |
76 | + json = JSON.parse(last_response.body) | |
77 | + | |
78 | + assert_equal 2, json['articles'].count | |
79 | + end | |
80 | + | |
81 | + should 'search articles in profile' do | |
82 | + person2 = fast_create(Person) | |
83 | + fast_create(Article, :profile_id => person.id) | |
84 | + fast_create(Article, :profile_id => person.id) | |
85 | + article = fast_create(Article, :profile_id => person2.id) | |
86 | + | |
87 | + get "/api/v1/search/article?query=Article&profile_id=#{person2.id}" | |
88 | + json = JSON.parse(last_response.body) | |
89 | + assert_equal article.id, json['articles'].first['id'] | |
90 | + end | |
91 | + | |
92 | + should 'search and return values specified in fields parameter' do | |
93 | + fast_create(Article, :profile_id => person.id) | |
94 | + get "/api/v1/search/article?fields=title" | |
95 | + json = JSON.parse(last_response.body) | |
96 | + assert_not_empty json['articles'] | |
97 | + assert_equal ['title'], json['articles'].first.keys | |
98 | + end | |
99 | + | |
100 | + should 'search with parent' do | |
101 | + parent = fast_create(Folder, :profile_id => person.id) | |
102 | + fast_create(Article, :profile_id => person.id) | |
103 | + article = fast_create(Article, :profile_id => person.id, :parent_id => parent.id) | |
104 | + get "/api/v1/search/article?parent_id=#{parent.id}" | |
105 | + json = JSON.parse(last_response.body) | |
106 | + assert_equal 1, json['articles'].count | |
107 | + assert_equal article.id, json['articles'].first["id"] | |
108 | + end | |
109 | + | |
110 | + should 'search filter by category' do | |
111 | + Article.delete_all | |
112 | + fast_create(Article, :profile_id => person.id) | |
113 | + article = fast_create(Article, :profile_id => person.id) | |
114 | + category = fast_create(Category) | |
115 | + article.categories<< category | |
116 | + get "/api/v1/search/article?category_ids=#{category.id}" | |
117 | + json = JSON.parse(last_response.body) | |
118 | + assert_equal 1, json['articles'].count | |
119 | + assert_equal article.id, json['articles'].first["id"] | |
120 | + end | |
121 | + | |
122 | + should 'search filter by more than one category' do | |
123 | + Article.delete_all | |
124 | + fast_create(Article, :profile_id => person.id) | |
125 | + article1 = fast_create(Article, :profile_id => person.id) | |
126 | + article2 = fast_create(Article, :profile_id => person.id) | |
127 | + category1 = fast_create(Category) | |
128 | + category2 = fast_create(Category) | |
129 | + article1.categories<< category1 | |
130 | + article2.categories<< category2 | |
131 | + get "/api/v1/search/article?category_ids[]=#{category1.id}&category_ids[]=#{category2.id}" | |
132 | + json = JSON.parse(last_response.body) | |
133 | + ids = [article1.id, article2.id] | |
134 | + assert_equal 2, json['articles'].count | |
135 | + assert_includes ids, json['articles'].first["id"] | |
136 | + assert_includes ids, json['articles'].last["id"] | |
137 | + end | |
138 | + | |
139 | +end | ... | ... |
test/unit/api/session_test.rb
... | ... | @@ -10,7 +10,7 @@ class SessionTest < ActiveSupport::TestCase |
10 | 10 | params = {:login => "testapi", :password => "testapi"} |
11 | 11 | post "/api/v1/login?#{params.to_query}" |
12 | 12 | json = JSON.parse(last_response.body) |
13 | - assert !json["private_token"].blank? | |
13 | + assert !json['user']["private_token"].blank? | |
14 | 14 | end |
15 | 15 | |
16 | 16 | should 'return 401 when login fails' do |
... | ... | @@ -21,22 +21,165 @@ class SessionTest < ActiveSupport::TestCase |
21 | 21 | end |
22 | 22 | |
23 | 23 | should 'register a user' do |
24 | - params = {:login => "newuserapi", :password => "newuserapi", :email => "newuserapi@email.com" } | |
24 | + Environment.default.enable('skip_new_user_email_confirmation') | |
25 | + params = {:login => "newuserapi", :password => "newuserapi", :password_confirmation => "newuserapi", :email => "newuserapi@email.com" } | |
25 | 26 | post "/api/v1/register?#{params.to_query}" |
26 | 27 | assert_equal 201, last_response.status |
28 | + json = JSON.parse(last_response.body) | |
29 | + assert User['newuserapi'].activated? | |
30 | + assert json['user']['activated'] | |
31 | + assert json['user']['private_token'].present? | |
32 | + end | |
33 | + | |
34 | + should 'register a user with name' do | |
35 | + Environment.default.enable('skip_new_user_email_confirmation') | |
36 | + params = {:login => "newuserapi", :password => "newuserapi", :password_confirmation => "newuserapi", :email => "newuserapi@email.com", :name => "Little John" } | |
37 | + post "/api/v1/register?#{params.to_query}" | |
38 | + assert_equal 201, last_response.status | |
39 | + json = JSON.parse(last_response.body) | |
40 | + assert json['user']['activated'] | |
41 | + assert json['user']['private_token'].present? | |
42 | + end | |
43 | + | |
44 | + should 'register an inactive user' do | |
45 | + params = {:login => "newuserapi", :password => "newuserapi", :password_confirmation => "newuserapi", :email => "newuserapi@email.com" } | |
46 | + post "/api/v1/register?#{params.to_query}" | |
47 | + assert_equal 201, last_response.status | |
48 | + json = JSON.parse(last_response.body) | |
49 | + assert !json['activated'] | |
50 | + assert json['private_token'].blank? | |
27 | 51 | end |
28 | 52 | |
29 | - should 'do not register a user without email' do | |
30 | - params = {:login => "newuserapi", :password => "newuserapi", :email => nil } | |
53 | + should 'not register a user with invalid login' do | |
54 | + params = {:login => "c", :password => "newuserapi", :password_confirmation => "newuserapi", :email => "newuserapi@email.com" } | |
31 | 55 | post "/api/v1/register?#{params.to_query}" |
32 | 56 | assert_equal 400, last_response.status |
57 | + json = JSON.parse(last_response.body) | |
58 | + msg = json['message'].split(':') | |
59 | + key = msg[0][2, 5] | |
60 | + val = msg[1][2, 38] | |
61 | + assert_equal "login", key | |
62 | + assert_equal "is too short (minimum is 2 characters)", val | |
33 | 63 | end |
34 | 64 | |
35 | - should 'do not register a duplicated user' do | |
36 | - params = {:login => "newuserapi", :password => "newuserapi", :email => "newuserapi@email.com" } | |
65 | + should 'not register a user with invalid login pt' do | |
66 | + I18n.locale = "pt-BR" | |
67 | + params = {:lang => "pt-BR", :login => "c", :password => "newuserapi", :password_confirmation => "newuserapi", :email => "newuserapi@email.com" } | |
37 | 68 | post "/api/v1/register?#{params.to_query}" |
69 | + assert_equal 400, last_response.status | |
70 | + json = JSON.parse(last_response.body) | |
71 | + msg = json['message'].split(':') | |
72 | + key = msg[0][2, 5] | |
73 | + val = msg[1][2, 35] | |
74 | + assert_equal "login", key | |
75 | + assert val.include? "muito curto" | |
76 | + end | |
77 | + | |
78 | + should 'not register a user without email' do | |
79 | + params = {:login => "newuserapi", :password => "newuserapi", :password_confirmation => "newuserapi", :email => nil } | |
38 | 80 | post "/api/v1/register?#{params.to_query}" |
39 | 81 | assert_equal 400, last_response.status |
40 | 82 | end |
41 | 83 | |
84 | + should 'not register a duplicated user' do | |
85 | + params = {:login => "newuserapi", :password => "newuserapi", :password_confirmation => "newuserapi", :email => "newuserapi@email.com" } | |
86 | + post "/api/v1/register?#{params.to_query}" | |
87 | + post "/api/v1/register?#{params.to_query}" | |
88 | + assert_equal 400, last_response.status | |
89 | + json = JSON.parse(last_response.body) | |
90 | + end | |
91 | + | |
92 | + # TODO: Add another test cases to check register situations | |
93 | + should 'activate a user' do | |
94 | + params = { | |
95 | + :login => "newuserapi", | |
96 | + :password => "newuserapi", | |
97 | + :password_confirmation => "newuserapi", | |
98 | + :email => "newuserapi@email.com" | |
99 | + } | |
100 | + user = User.new(params) | |
101 | + user.save! | |
102 | + | |
103 | + params = { activation_code: user.activation_code} | |
104 | + patch "/api/v1/activate?#{params.to_query}" | |
105 | + assert_equal 200, last_response.status | |
106 | + end | |
107 | + | |
108 | + should 'do not activate a user if admin must approve him' do | |
109 | + params = { | |
110 | + :login => "newuserapi", | |
111 | + :password => "newuserapi", | |
112 | + :password_confirmation => "newuserapi", | |
113 | + :email => "newuserapi@email.com", | |
114 | + :environment => Environment.default | |
115 | + } | |
116 | + user = User.new(params) | |
117 | + user.environment.enable('admin_must_approve_new_users') | |
118 | + user.save! | |
119 | + | |
120 | + params = { activation_code: user.activation_code} | |
121 | + patch "/api/v1/activate?#{params.to_query}" | |
122 | + assert_equal 202, last_response.status | |
123 | + assert_equal 'Waiting for admin moderate user registration', JSON.parse(last_response.body)["message"] | |
124 | + end | |
125 | + | |
126 | + should 'do not activate a user if the token is invalid' do | |
127 | + params = { | |
128 | + :login => "newuserapi", | |
129 | + :password => "newuserapi", | |
130 | + :password_confirmation => "newuserapi", | |
131 | + :email => "newuserapi@email.com", | |
132 | + :environment => Environment.default | |
133 | + } | |
134 | + user = User.new(params) | |
135 | + user.save! | |
136 | + | |
137 | + params = { activation_code: '70250abe20cc6a67ef9399cf3286cb998b96aeaf'} | |
138 | + patch "/api/v1/activate?#{params.to_query}" | |
139 | + assert_equal 412, last_response.status | |
140 | + end | |
141 | + | |
142 | + should 'create task to change password by user login' do | |
143 | + user = create_user | |
144 | + params = {:value => user.login} | |
145 | + assert_difference 'ChangePassword.count' do | |
146 | + post "/api/v1/forgot_password?#{params.to_query}" | |
147 | + end | |
148 | + end | |
149 | + | |
150 | + should 'not create task to change password when user is not found' do | |
151 | + params = {:value => 'wronglogin'} | |
152 | + assert_no_difference 'ChangePassword.count' do | |
153 | + post "/api/v1/forgot_password?#{params.to_query}" | |
154 | + end | |
155 | + assert_equal 404, last_response.status | |
156 | + end | |
157 | + | |
158 | + should 'change user password and close task' do | |
159 | + task = ChangePassword.create!(:requestor => @person) | |
160 | + params.merge!({:code => task.code, :password => 'secret', :password_confirmation => 'secret'}) | |
161 | + patch "/api/v1/new_password?#{params.to_query}" | |
162 | + assert_equal Task::Status::FINISHED, task.reload.status | |
163 | + assert user.reload.authenticated?('secret') | |
164 | + json = JSON.parse(last_response.body) | |
165 | + assert_equal user.id, json['user']['id'] | |
166 | + end | |
167 | + | |
168 | + should 'do not change user password when password confirmation is wrong' do | |
169 | + user = create_user | |
170 | + user.activate | |
171 | + task = ChangePassword.create!(:requestor => user.person) | |
172 | + params = {:code => task.code, :password => 'secret', :password_confirmation => 's3cret'} | |
173 | + patch "/api/v1/new_password?#{params.to_query}" | |
174 | + assert_equal Task::Status::ACTIVE, task.reload.status | |
175 | + assert !user.reload.authenticated?('secret') | |
176 | + assert_equal 400, last_response.status | |
177 | + end | |
178 | + | |
179 | + should 'render not found when provide a wrong code on password change' do | |
180 | + params = {:code => "wrongcode", :password => 'secret', :password_confirmation => 'secret'} | |
181 | + patch "/api/v1/new_password?#{params.to_query}" | |
182 | + assert_equal 404, last_response.status | |
183 | + end | |
184 | + | |
42 | 185 | end | ... | ... |
test/unit/api/test_helper.rb
1 | -require 'test_helper' | |
1 | +require_relative '../../test_helper' | |
2 | 2 | |
3 | 3 | class ActiveSupport::TestCase |
4 | 4 | |
... | ... | @@ -9,16 +9,22 @@ class ActiveSupport::TestCase |
9 | 9 | end |
10 | 10 | |
11 | 11 | def login_api |
12 | - @user = User.create!(:login => 'testapi', :password => 'testapi', :password_confirmation => 'testapi', :email => 'test@test.org', :environment => Environment.default) | |
12 | + @environment = Environment.default | |
13 | + @user = User.create!(:login => 'testapi', :password => 'testapi', :password_confirmation => 'testapi', :email => 'test@test.org', :environment => @environment) | |
13 | 14 | @user.activate |
14 | 15 | @person = @user.person |
15 | 16 | |
16 | 17 | post "/api/v1/login?login=testapi&password=testapi" |
17 | 18 | json = JSON.parse(last_response.body) |
18 | 19 | @private_token = json["private_token"] |
20 | + unless @private_token | |
21 | + @user.generate_private_token! | |
22 | + @private_token = @user.private_token | |
23 | + end | |
24 | + | |
19 | 25 | @params = {:private_token => @private_token} |
20 | 26 | end |
21 | - attr_accessor :private_token, :user, :person, :params | |
27 | + attr_accessor :private_token, :user, :person, :params, :environment | |
22 | 28 | |
23 | 29 | private |
24 | 30 | ... | ... |
... | ... | @@ -0,0 +1,105 @@ |
1 | +# encoding: UTF-8 | |
2 | +require_relative 'test_helper' | |
3 | + | |
4 | +class UsersTest < ActiveSupport::TestCase | |
5 | + | |
6 | + def setup | |
7 | + login_api | |
8 | + end | |
9 | + | |
10 | + should 'list users' do | |
11 | + get "/api/v1/users/?#{params.to_query}" | |
12 | + json = JSON.parse(last_response.body) | |
13 | + assert_includes json["users"].map { |a| a["login"] }, user.login | |
14 | + end | |
15 | + | |
16 | + should 'get user' do | |
17 | + get "/api/v1/users/#{user.id}?#{params.to_query}" | |
18 | + json = JSON.parse(last_response.body) | |
19 | + assert_equal user.id, json['user']['id'] | |
20 | + end | |
21 | + | |
22 | + should 'list user permissions' do | |
23 | + community = fast_create(Community) | |
24 | + community.add_admin(person) | |
25 | + get "/api/v1/users/#{user.id}/?#{params.to_query}" | |
26 | + json = JSON.parse(last_response.body) | |
27 | + assert_includes json["user"]["permissions"], community.identifier | |
28 | + end | |
29 | + | |
30 | + should 'get logged user' do | |
31 | + get "/api/v1/users/me?#{params.to_query}" | |
32 | + json = JSON.parse(last_response.body) | |
33 | + assert_equal user.id, json['user']['id'] | |
34 | + end | |
35 | + | |
36 | + should 'not show permissions to logged user' do | |
37 | + target_person = create_user('some-user').person | |
38 | + get "/api/v1/users/#{target_person.user.id}/?#{params.to_query}" | |
39 | + json = JSON.parse(last_response.body) | |
40 | + refute json["user"].has_key?("permissions") | |
41 | + end | |
42 | + | |
43 | + should 'show permissions to self' do | |
44 | + get "/api/v1/users/#{user.id}/?#{params.to_query}" | |
45 | + json = JSON.parse(last_response.body) | |
46 | + assert json["user"].has_key?("permissions") | |
47 | + end | |
48 | + | |
49 | + should 'not show permissions to friend' do | |
50 | + target_person = create_user('some-user').person | |
51 | + | |
52 | + f = Friendship.new | |
53 | + f.friend = target_person | |
54 | + f.person = person | |
55 | + f.save! | |
56 | + | |
57 | + get "/api/v1/users/#{target_person.user.id}/?#{params.to_query}" | |
58 | + json = JSON.parse(last_response.body) | |
59 | + refute json["user"].has_key?("permissions") | |
60 | + end | |
61 | + | |
62 | + should 'not show private attribute to logged user' do | |
63 | + target_person = create_user('some-user').person | |
64 | + get "/api/v1/users/#{target_person.user.id}/?#{params.to_query}" | |
65 | + json = JSON.parse(last_response.body) | |
66 | + refute json["user"].has_key?("email") | |
67 | + end | |
68 | + | |
69 | + should 'show private attr to friend' do | |
70 | + target_person = create_user('some-user').person | |
71 | + f = Friendship.new | |
72 | + f.friend = target_person | |
73 | + f.person = person | |
74 | + f.save! | |
75 | + get "/api/v1/users/#{target_person.user.id}/?#{params.to_query}" | |
76 | + json = JSON.parse(last_response.body) | |
77 | + assert json["user"].has_key?("email") | |
78 | + assert_equal target_person.email, json["user"]["email"] | |
79 | + end | |
80 | + | |
81 | + should 'show public attribute to logged user' do | |
82 | + target_person = create_user('some-user').person | |
83 | + target_person.fields_privacy={:email=> 'public'} | |
84 | + target_person.save! | |
85 | + get "/api/v1/users/#{target_person.user.id}/?#{params.to_query}" | |
86 | + json = JSON.parse(last_response.body) | |
87 | + assert json["user"].has_key?("email") | |
88 | + assert_equal json["user"]["email"],target_person.email | |
89 | + end | |
90 | + | |
91 | + should 'show public and private field to admin' do | |
92 | + Environment.default.add_admin(person) | |
93 | + | |
94 | + target_person = create_user('some-user').person | |
95 | + target_person.fields_privacy={:email=> 'public'} | |
96 | + target_person.save! | |
97 | + | |
98 | + get "/api/v1/users/#{target_person.user.id}/?#{params.to_query}" | |
99 | + json = JSON.parse(last_response.body) | |
100 | + assert json["user"].has_key?("email") | |
101 | + assert json["user"].has_key?("permissions") | |
102 | + assert json["user"].has_key?("activated") | |
103 | + end | |
104 | + | |
105 | +end | ... | ... |
test/unit/create_thumbnails_job_test.rb
... | ... | @@ -34,4 +34,16 @@ class CreateThumbnailsJobTest < ActiveSupport::TestCase |
34 | 34 | end |
35 | 35 | end |
36 | 36 | |
37 | + should 'expire cache of articles that use an image that just got a thumbnail' do | |
38 | + person = create_user('test_user').person | |
39 | + file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :profile => person) | |
40 | + article = create(Article, :name => 'test', :image_builder => { | |
41 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | |
42 | + }, :profile_id => person.id) | |
43 | + old_cache_key = article.cache_key | |
44 | + job = CreateThumbnailsJob.new(file.class.name, file.id) | |
45 | + job.perform | |
46 | + process_delayed_job_queue | |
47 | + assert_not_equal old_cache_key, Article.find(article.id).reload.cache_key | |
48 | + end | |
37 | 49 | end | ... | ... |