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,13 +184,7 @@ class ApplicationController < ActionController::Base | ||
184 | end | 184 | end |
185 | 185 | ||
186 | include SearchTermHelper | 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 | def find_suggestions(query, context, asset, options={}) | 189 | def find_suggestions(query, context, asset, options={}) |
196 | plugins.dispatch_first(:find_suggestions, query, context, asset, options) | 190 | plugins.dispatch_first(:find_suggestions, query, context, asset, options) |
config/docker/dev/Dockerfile
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | # | 2 | # |
3 | # VERSION 0.0.1 | 3 | # VERSION 0.0.1 |
4 | 4 | ||
5 | -FROM debian:wheezy | 5 | +FROM debian:jessie |
6 | MAINTAINER Noosfero Development Team <noosfero-dev@listas.softwarelivre.org> | 6 | MAINTAINER Noosfero Development Team <noosfero-dev@listas.softwarelivre.org> |
7 | 7 | ||
8 | LABEL Description="This dockerfile builds a noosfero development environment." | 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,4 +13,6 @@ RUN git clone --depth 1 https://gitlab.com/noosfero/noosfero.git . | ||
13 | 13 | ||
14 | RUN sh script/quick-start --skip-translations | 14 | RUN sh script/quick-start --skip-translations |
15 | 15 | ||
16 | +RUN service postgresql start && sleep 2 && ruby script/sample-data | ||
17 | + | ||
16 | EXPOSE 3000 | 18 | EXPOSE 3000 |
lib/create_thumbnails_job.rb
@@ -3,5 +3,9 @@ class CreateThumbnailsJob < Struct.new(:class_name, :file_id) | @@ -3,5 +3,9 @@ class CreateThumbnailsJob < Struct.new(:class_name, :file_id) | ||
3 | return unless class_name.constantize.exists?(file_id) | 3 | return unless class_name.constantize.exists?(file_id) |
4 | file = class_name.constantize.find(file_id) | 4 | file = class_name.constantize.find(file_id) |
5 | file.create_thumbnails | 5 | file.create_thumbnails |
6 | + article = Article.where(:image_id => file_id).first | ||
7 | + if article | ||
8 | + article.touch | ||
9 | + end | ||
6 | end | 10 | end |
7 | end | 11 | end |
@@ -0,0 +1,11 @@ | @@ -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 | require 'grape' | 1 | require 'grape' |
2 | #require 'rack/contrib' | 2 | #require 'rack/contrib' |
3 | - | ||
4 | Dir["#{Rails.root}/lib/noosfero/api/*.rb"].each {|file| require file unless file =~ /api\.rb/} | 3 | Dir["#{Rails.root}/lib/noosfero/api/*.rb"].each {|file| require file unless file =~ /api\.rb/} |
4 | + | ||
5 | module Noosfero | 5 | module Noosfero |
6 | module API | 6 | module API |
7 | class API < Grape::API | 7 | class API < Grape::API |
@@ -17,7 +17,6 @@ module Noosfero | @@ -17,7 +17,6 @@ module Noosfero | ||
17 | end | 17 | end |
18 | 18 | ||
19 | @@NOOSFERO_CONF = nil | 19 | @@NOOSFERO_CONF = nil |
20 | - | ||
21 | def self.NOOSFERO_CONF | 20 | def self.NOOSFERO_CONF |
22 | if @@NOOSFERO_CONF | 21 | if @@NOOSFERO_CONF |
23 | @@NOOSFERO_CONF | 22 | @@NOOSFERO_CONF |
@@ -27,9 +26,11 @@ module Noosfero | @@ -27,9 +26,11 @@ module Noosfero | ||
27 | end | 26 | end |
28 | end | 27 | end |
29 | 28 | ||
29 | + before { set_locale } | ||
30 | before { setup_multitenancy } | 30 | before { setup_multitenancy } |
31 | before { detect_stuff_by_domain } | 31 | before { detect_stuff_by_domain } |
32 | before { filter_disabled_plugins_endpoints } | 32 | before { filter_disabled_plugins_endpoints } |
33 | + before { init_noosfero_plugins } | ||
33 | after { set_session_cookie } | 34 | after { set_session_cookie } |
34 | 35 | ||
35 | version 'v1' | 36 | version 'v1' |
@@ -41,11 +42,17 @@ module Noosfero | @@ -41,11 +42,17 @@ module Noosfero | ||
41 | 42 | ||
42 | mount V1::Articles | 43 | mount V1::Articles |
43 | mount V1::Comments | 44 | mount V1::Comments |
45 | + mount V1::Users | ||
44 | mount V1::Communities | 46 | mount V1::Communities |
45 | mount V1::People | 47 | mount V1::People |
46 | mount V1::Enterprises | 48 | mount V1::Enterprises |
47 | mount V1::Categories | 49 | mount V1::Categories |
48 | mount V1::Tasks | 50 | mount V1::Tasks |
51 | + mount V1::Tags | ||
52 | + mount V1::Environments | ||
53 | + mount V1::Search | ||
54 | + mount V1::Contacts | ||
55 | + | ||
49 | mount Session | 56 | mount Session |
50 | 57 | ||
51 | # hook point which allow plugins to add Grape::API extensions to API::API | 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 +6,35 @@ module Noosfero | ||
6 | date.strftime('%Y/%m/%d %H:%M:%S') if date | 6 | date.strftime('%Y/%m/%d %H:%M:%S') if date |
7 | end | 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 | class Image < Entity | 38 | class Image < Entity |
10 | root 'images', 'image' | 39 | root 'images', 'image' |
11 | 40 | ||
@@ -30,66 +59,81 @@ module Noosfero | @@ -30,66 +59,81 @@ module Noosfero | ||
30 | end | 59 | end |
31 | end | 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 | class Profile < Entity | 83 | class Profile < Entity |
34 | expose :identifier, :name, :id | 84 | expose :identifier, :name, :id |
35 | expose :created_at, :format_with => :timestamp | 85 | expose :created_at, :format_with => :timestamp |
36 | expose :updated_at, :format_with => :timestamp | 86 | expose :updated_at, :format_with => :timestamp |
37 | expose :image, :using => Image | 87 | expose :image, :using => Image |
88 | + expose :region, :using => Region | ||
38 | end | 89 | end |
39 | 90 | ||
40 | - class User < Entity | 91 | + class UserBasic < Entity |
41 | expose :id | 92 | expose :id |
42 | expose :login | 93 | expose :login |
43 | end | 94 | end |
44 | 95 | ||
45 | class Person < Profile | 96 | class Person < Profile |
46 | root 'people', 'person' | 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 | end | 99 | end |
100 | + | ||
49 | class Enterprise < Profile | 101 | class Enterprise < Profile |
50 | root 'enterprises', 'enterprise' | 102 | root 'enterprises', 'enterprise' |
51 | end | 103 | end |
104 | + | ||
52 | class Community < Profile | 105 | class Community < Profile |
53 | root 'communities', 'community' | 106 | root 'communities', 'community' |
54 | expose :description | 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 | end | 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 | end | 113 | end |
74 | 114 | ||
75 | class ArticleBase < Entity | 115 | class ArticleBase < Entity |
76 | root 'articles', 'article' | 116 | root 'articles', 'article' |
77 | expose :id | 117 | expose :id |
78 | expose :body | 118 | expose :body |
79 | - expose :abstract | 119 | + expose :abstract, documentation: {type: 'String', desc: 'Teaser of the body'} |
80 | expose :created_at, :format_with => :timestamp | 120 | expose :created_at, :format_with => :timestamp |
81 | expose :updated_at, :format_with => :timestamp | 121 | expose :updated_at, :format_with => :timestamp |
82 | expose :title, :documentation => {:type => "String", :desc => "Title of the article"} | 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 | expose :categories, :using => Category | 125 | expose :categories, :using => Category |
86 | expose :image, :using => Image | 126 | expose :image, :using => Image |
87 | - #TODO Apply vote stuff in core and make this test | ||
88 | expose :votes_for | 127 | expose :votes_for |
89 | expose :votes_against | 128 | expose :votes_against |
90 | expose :setting | 129 | expose :setting |
91 | expose :position | 130 | expose :position |
92 | expose :hits | 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 | expose :path | 137 | expose :path |
94 | end | 138 | end |
95 | 139 | ||
@@ -106,8 +150,32 @@ module Noosfero | @@ -106,8 +150,32 @@ module Noosfero | ||
106 | expose :author, :using => Profile | 150 | expose :author, :using => Profile |
107 | end | 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 | class UserLogin < User | 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 | end | 179 | end |
112 | 180 | ||
113 | class Task < Entity | 181 | class Task < Entity |
@@ -116,6 +184,16 @@ module Noosfero | @@ -116,6 +184,16 @@ module Noosfero | ||
116 | expose :type | 184 | expose :type |
117 | end | 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 | end | 197 | end |
120 | end | 198 | end |
121 | end | 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 | PRIVATE_TOKEN_PARAM = :private_token | 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 | def current_user | 23 | def current_user |
8 | private_token = (params[PRIVATE_TOKEN_PARAM] || headers['Private-Token']).to_s | 24 | private_token = (params[PRIVATE_TOKEN_PARAM] || headers['Private-Token']).to_s |
@@ -23,6 +39,22 @@ module Noosfero | @@ -23,6 +39,22 @@ module Noosfero | ||
23 | @environment | 39 | @environment |
24 | end | 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 | def limit | 58 | def limit |
27 | limit = params[:limit].to_i | 59 | limit = params[:limit].to_i |
28 | limit = default_limit if limit <= 0 | 60 | limit = default_limit if limit <= 0 |
@@ -50,7 +82,7 @@ module Noosfero | @@ -50,7 +82,7 @@ module Noosfero | ||
50 | 82 | ||
51 | def find_article(articles, id) | 83 | def find_article(articles, id) |
52 | article = articles.find(id) | 84 | article = articles.find(id) |
53 | - article.display_to?(current_user.person) ? article : forbidden! | 85 | + article.display_to?(current_person) ? article : forbidden! |
54 | end | 86 | end |
55 | 87 | ||
56 | def post_article(asset, params) | 88 | def post_article(asset, params) |
@@ -75,12 +107,25 @@ module Noosfero | @@ -75,12 +107,25 @@ module Noosfero | ||
75 | present article, :with => Entities::Article, :fields => params[:fields] | 107 | present article, :with => Entities::Article, :fields => params[:fields] |
76 | end | 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 | present articles, :with => Entities::Article, :fields => params[:fields] | 116 | present articles, :with => Entities::Article, :fields => params[:fields] |
82 | end | 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 | def find_task(asset, id) | 129 | def find_task(asset, id) |
85 | task = asset.tasks.find(id) | 130 | task = asset.tasks.find(id) |
86 | current_person.has_permission?(task.permission, asset) ? task : forbidden! | 131 | current_person.has_permission?(task.permission, asset) ? task : forbidden! |
@@ -127,8 +172,27 @@ module Noosfero | @@ -127,8 +172,27 @@ module Noosfero | ||
127 | conditions | 172 | conditions |
128 | end | 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 | end | 196 | end |
133 | 197 | ||
134 | def make_page_number_with_parameters(params) | 198 | def make_page_number_with_parameters(params) |
@@ -152,25 +216,36 @@ module Noosfero | @@ -152,25 +216,36 @@ module Noosfero | ||
152 | end | 216 | end |
153 | 217 | ||
154 | def by_reference(scope, params) | 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 | else | 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 | scope | 231 | scope |
232 | + else | ||
233 | + scope.joins(:categories).where(:categories => {:id => category_ids}) | ||
160 | end | 234 | end |
161 | end | 235 | end |
162 | 236 | ||
163 | def select_filtered_collection_of(object, method, params) | 237 | def select_filtered_collection_of(object, method, params) |
164 | conditions = make_conditions_with_parameter(params) | 238 | conditions = make_conditions_with_parameter(params) |
165 | - order = make_order_with_parameters(params) | 239 | + order = make_order_with_parameters(object,method,params) |
166 | page_number = make_page_number_with_parameters(params) | 240 | page_number = make_page_number_with_parameters(params) |
167 | per_page = make_per_page_with_parameters(params) | 241 | per_page = make_per_page_with_parameters(params) |
168 | timestamp = make_timestamp_with_parameters_and_method(params, method) | 242 | timestamp = make_timestamp_with_parameters_and_method(params, method) |
169 | 243 | ||
170 | objects = object.send(method) | 244 | objects = object.send(method) |
171 | objects = by_reference(objects, params) | 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 | objects | 250 | objects |
176 | end | 251 | end |
@@ -179,6 +254,7 @@ module Noosfero | @@ -179,6 +254,7 @@ module Noosfero | ||
179 | unauthorized! unless current_user | 254 | unauthorized! unless current_user |
180 | end | 255 | end |
181 | 256 | ||
257 | + | ||
182 | # Checks the occurrences of uniqueness of attributes, each attribute must be present in the params hash | 258 | # Checks the occurrences of uniqueness of attributes, each attribute must be present in the params hash |
183 | # or a Bad Request error is invoked. | 259 | # or a Bad Request error is invoked. |
184 | # | 260 | # |
@@ -198,20 +274,6 @@ module Noosfero | @@ -198,20 +274,6 @@ module Noosfero | ||
198 | attrs | 274 | attrs |
199 | end | 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 | # error helpers # | 278 | # error helpers # |
217 | ########################################## | 279 | ########################################## |
@@ -247,13 +309,22 @@ module Noosfero | @@ -247,13 +309,22 @@ module Noosfero | ||
247 | render_api_error!(_('Method Not Allowed'), 405) | 309 | render_api_error!(_('Method Not Allowed'), 405) |
248 | end | 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 | end | 321 | end |
253 | 322 | ||
254 | def render_api_errors!(messages) | 323 | def render_api_errors!(messages) |
324 | + messages = messages.to_a if messages.class == ActiveModel::Errors | ||
255 | render_api_error!(messages.join(','), 400) | 325 | render_api_error!(messages.join(','), 400) |
256 | end | 326 | end |
327 | + | ||
257 | protected | 328 | protected |
258 | 329 | ||
259 | def set_session_cookie | 330 | def set_session_cookie |
@@ -278,7 +349,7 @@ module Noosfero | @@ -278,7 +349,7 @@ module Noosfero | ||
278 | end | 349 | end |
279 | 350 | ||
280 | def filter_disabled_plugins_endpoints | 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 | end | 353 | end |
283 | 354 | ||
284 | private | 355 | private |
@@ -305,7 +376,6 @@ module Noosfero | @@ -305,7 +376,6 @@ module Noosfero | ||
305 | def period(from_date, until_date) | 376 | def period(from_date, until_date) |
306 | begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date | 377 | begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date |
307 | end_period = until_date.nil? ? DateTime.now : until_date | 378 | end_period = until_date.nil? ? DateTime.now : until_date |
308 | - | ||
309 | begin_period..end_period | 379 | begin_period..end_period |
310 | end | 380 | end |
311 | 381 |
lib/noosfero/api/session.rb
@@ -2,7 +2,6 @@ require "uri" | @@ -2,7 +2,6 @@ require "uri" | ||
2 | 2 | ||
3 | module Noosfero | 3 | module Noosfero |
4 | module API | 4 | module API |
5 | - | ||
6 | class Session < Grape::API | 5 | class Session < Grape::API |
7 | 6 | ||
8 | # Login to get token | 7 | # Login to get token |
@@ -14,11 +13,15 @@ module Noosfero | @@ -14,11 +13,15 @@ module Noosfero | ||
14 | # Example Request: | 13 | # Example Request: |
15 | # POST http://localhost:3000/api/v1/login?login=adminuser&password=admin | 14 | # POST http://localhost:3000/api/v1/login?login=adminuser&password=admin |
16 | post "/login" do | 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 | return unauthorized! unless user | 22 | return unauthorized! unless user |
20 | @current_user = user | 23 | @current_user = user |
21 | - present user, :with => Entities::UserLogin | 24 | + present user, :with => Entities::UserLogin, :current_person => current_person |
22 | end | 25 | end |
23 | 26 | ||
24 | # Create user. | 27 | # Create user. |
@@ -28,34 +31,103 @@ module Noosfero | @@ -28,34 +31,103 @@ module Noosfero | ||
28 | # password (required) - Password | 31 | # password (required) - Password |
29 | # login - login | 32 | # login - login |
30 | # Example Request: | 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 | params do | 35 | params do |
33 | requires :email, type: String, desc: _("Email") | 36 | requires :email, type: String, desc: _("Email") |
34 | requires :login, type: String, desc: _("Login") | 37 | requires :login, type: String, desc: _("Login") |
35 | requires :password, type: String, desc: _("Password") | 38 | requires :password, type: String, desc: _("Password") |
36 | end | 39 | end |
40 | + | ||
37 | post "/register" do | 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 | render_api_error!(message, 400) | 53 | render_api_error!(message, 400) |
57 | end | 54 | end |
58 | end | 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 | end | 131 | end |
60 | end | 132 | end |
61 | end | 133 | end |
lib/noosfero/api/v1/articles.rb
@@ -2,7 +2,6 @@ module Noosfero | @@ -2,7 +2,6 @@ module Noosfero | ||
2 | module API | 2 | module API |
3 | module V1 | 3 | module V1 |
4 | class Articles < Grape::API | 4 | class Articles < Grape::API |
5 | - before { authenticate! } | ||
6 | 5 | ||
7 | ARTICLE_TYPES = Article.descendants.map{|a| a.to_s} | 6 | ARTICLE_TYPES = Article.descendants.map{|a| a.to_s} |
8 | 7 | ||
@@ -17,39 +16,148 @@ module Noosfero | @@ -17,39 +16,148 @@ module Noosfero | ||
17 | # | 16 | # |
18 | # Example Request: | 17 | # Example Request: |
19 | # GET host/api/v1/articles?from=2013-04-04-14:41:43&until=2015-04-04-14:41:43&limit=10&private_token=e96fff37c2238fdab074d1dcea8e6317 | 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 | get do | 33 | get do |
21 | - present_articles(environment) | 34 | + present_articles_for_asset(environment) |
22 | end | 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 | present_article(environment) | 45 | present_article(environment) |
27 | end | 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 | get ':id/children' do | 122 | get ':id/children' do |
30 | article = find_article(environment.articles, params[:id]) | 123 | article = find_article(environment.articles, params[:id]) |
31 | 124 | ||
32 | #TODO make tests for this situation | 125 | #TODO make tests for this situation |
33 | votes_order = params.delete(:order) if params[:order]=='votes_score' | 126 | votes_order = params.delete(:order) if params[:order]=='votes_score' |
34 | articles = select_filtered_collection_of(article, 'children', params) | 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 | #TODO make tests for this situation | 130 | #TODO make tests for this situation |
39 | if votes_order | 131 | if votes_order |
40 | articles = articles.joins('left join votes on articles.id=votes.voteable_id').group('articles.id').reorder('sum(coalesce(votes.vote, 0)) DESC') | 132 | articles = articles.joins('left join votes on articles.id=votes.voteable_id').group('articles.id').reorder('sum(coalesce(votes.vote, 0)) DESC') |
41 | end | 133 | end |
42 | - | ||
43 | Article.hit(articles) | 134 | Article.hit(articles) |
44 | - present articles, :with => Entities::Article, :fields => params[:fields] | 135 | + present_articles(articles) |
45 | end | 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 | get ':id/children/:child_id' do | 145 | get ':id/children/:child_id' do |
48 | article = find_article(environment.articles, params[:id]) | 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 | end | 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 | post ':id/children/suggest' do | 159 | post ':id/children/suggest' do |
160 | + authenticate! | ||
53 | parent_article = environment.articles.find(params[:id]) | 161 | parent_article = environment.articles.find(params[:id]) |
54 | 162 | ||
55 | suggest_article = SuggestArticle.new | 163 | suggest_article = SuggestArticle.new |
@@ -66,8 +174,15 @@ module Noosfero | @@ -66,8 +174,15 @@ module Noosfero | ||
66 | 174 | ||
67 | # Example Request: | 175 | # Example Request: |
68 | # POST api/v1/articles/:id/children?private_token=234298743290432&article[name]=title&article[body]=body | 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 | post ':id/children' do | 184 | post ':id/children' do |
70 | - | 185 | + authenticate! |
71 | parent_article = environment.articles.find(params[:id]) | 186 | parent_article = environment.articles.find(params[:id]) |
72 | return forbidden! unless parent_article.allow_create?(current_person) | 187 | return forbidden! unless parent_article.allow_create?(current_person) |
73 | 188 | ||
@@ -95,11 +210,37 @@ module Noosfero | @@ -95,11 +210,37 @@ module Noosfero | ||
95 | resource kind.pluralize.to_sym do | 210 | resource kind.pluralize.to_sym do |
96 | segment "/:#{kind}_id" do | 211 | segment "/:#{kind}_id" do |
97 | resource :articles do | 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 | get do | 221 | get do |
99 | profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | 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 | end | 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 | get ':id' do | 244 | get ':id' do |
104 | profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | 245 | profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) |
105 | present_article(profile) | 246 | present_article(profile) |
@@ -107,6 +248,13 @@ module Noosfero | @@ -107,6 +248,13 @@ module Noosfero | ||
107 | 248 | ||
108 | # Example Request: | 249 | # Example Request: |
109 | # POST api/v1/{people,communities,enterprises}/:asset_id/articles?private_token=234298743290432&article[name]=title&article[body]=body | 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 | post do | 258 | post do |
111 | profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | 259 | profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) |
112 | post_article(profile, params) | 260 | post_article(profile, params) |
lib/noosfero/api/v1/comments.rb
@@ -30,8 +30,8 @@ module Noosfero | @@ -30,8 +30,8 @@ module Noosfero | ||
30 | # POST api/v1/articles/12/comments?private_token=2298743290432&body=new comment&title=New | 30 | # POST api/v1/articles/12/comments?private_token=2298743290432&body=new comment&title=New |
31 | post ":id/comments" do | 31 | post ":id/comments" do |
32 | article = find_article(environment.articles, params[:id]) | 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 | end | 35 | end |
36 | end | 36 | end |
37 | 37 |
@@ -0,0 +1,28 @@ | @@ -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 @@ | @@ -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,6 +48,13 @@ module Noosfero | ||
48 | present person, :with => Entities::Person | 48 | present person, :with => Entities::Person |
49 | end | 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 | # Example Request: | 58 | # Example Request: |
52 | # POST api/v1/people?person[login]=some_login&person[password]=some_password&person[name]=Jack | 59 | # POST api/v1/people?person[login]=some_login&person[password]=some_password&person[name]=Jack |
53 | desc "Create person" | 60 | desc "Create person" |
@@ -0,0 +1,43 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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,7 +14,7 @@ class NewsletterPluginNewsletters < ActiveRecord::Migration | ||
14 | t.boolean :moderated | 14 | t.boolean :moderated |
15 | t.text :unsubscribers | 15 | t.text :unsubscribers |
16 | end | 16 | end |
17 | - add_index :newsletter_plugin_newsletters, :environment_id, :uniq => true | 17 | + add_index :newsletter_plugin_newsletters, :environment_id, :unique => true |
18 | end | 18 | end |
19 | 19 | ||
20 | def down | 20 | def down |
plugins/newsletter/lib/newsletter_plugin/newsletter.rb
1 | require 'csv' | 1 | require 'csv' |
2 | 2 | ||
3 | -class NewsletterPlugin::Newsletter < Noosfero::Plugin::ActiveRecord | 3 | +class NewsletterPlugin::Newsletter < ActiveRecord::Base |
4 | 4 | ||
5 | belongs_to :environment | 5 | belongs_to :environment |
6 | belongs_to :person | 6 | belongs_to :person |
@@ -123,11 +123,11 @@ class NewsletterPlugin::Newsletter < Noosfero::Plugin::ActiveRecord | @@ -123,11 +123,11 @@ class NewsletterPlugin::Newsletter < Noosfero::Plugin::ActiveRecord | ||
123 | end | 123 | end |
124 | 124 | ||
125 | def post_with_image(post) | 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 | end | 127 | end |
128 | 128 | ||
129 | def post_without_image(post) | 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 | end | 131 | end |
132 | 132 | ||
133 | def body(data = {}) | 133 | def body(data = {}) |
@@ -177,10 +177,6 @@ class NewsletterPlugin::Newsletter < Noosfero::Plugin::ActiveRecord | @@ -177,10 +177,6 @@ class NewsletterPlugin::Newsletter < Noosfero::Plugin::ActiveRecord | ||
177 | last_mailing.nil? ? nil : last_mailing.created_at | 177 | last_mailing.nil? ? nil : last_mailing.created_at |
178 | end | 178 | end |
179 | 179 | ||
180 | - def sanitize(html) | ||
181 | - html.gsub(/<\/?p>/, '') | ||
182 | - end | ||
183 | - | ||
184 | def has_posts_in_the_period? | 180 | def has_posts_in_the_period? |
185 | ! self.posts.empty? | 181 | ! self.posts.empty? |
186 | end | 182 | end |
plugins/newsletter/public/style.css
@@ -14,7 +14,7 @@ | @@ -14,7 +14,7 @@ | ||
14 | } | 14 | } |
15 | 15 | ||
16 | #newsletter-moderation-preview { | 16 | #newsletter-moderation-preview { |
17 | - margin-left: 25px; | 17 | + margin-left: 10px; |
18 | } | 18 | } |
19 | 19 | ||
20 | #newsletter-moderation-preview input[type=checkbox] { | 20 | #newsletter-moderation-preview input[type=checkbox] { |
plugins/newsletter/test/unit/newsletter_plugin_newsletter_test.rb
@@ -351,15 +351,30 @@ EOS | @@ -351,15 +351,30 @@ EOS | ||
351 | post = fast_create(TextArticle, :parent_id => blog.id, | 351 | post = fast_create(TextArticle, :parent_id => blog.id, |
352 | :name => 'the last news 1', | 352 | :name => 'the last news 1', |
353 | :profile_id => community.id, | 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 | newsletter = NewsletterPlugin::Newsletter.create!( | 356 | newsletter = NewsletterPlugin::Newsletter.create!( |
357 | :environment => environment, | 357 | :environment => environment, |
358 | :blog_ids => [blog.id], | 358 | :blog_ids => [blog.id], |
359 | :person => fast_create(Person)) | 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 | end | 378 | end |
364 | 379 | ||
365 | should 'filter posts when listing posts for newsletter' do | 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 | OrdersPlugin.send :remove_const, :Item if defined? OrdersPlugin::Item | 1 | OrdersPlugin.send :remove_const, :Item if defined? OrdersPlugin::Item |
2 | OrdersPlugin.send :remove_const, :Order if defined? OrdersPlugin::Order | 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 | acts_as_having_settings :field => :data | 5 | acts_as_having_settings :field => :data |
6 | 6 | ||
7 | module Status | 7 | module Status |
@@ -16,10 +16,10 @@ class Profile | @@ -16,10 +16,10 @@ class Profile | ||
16 | has_many :orders, :class_name => 'OrdersPlugin::Order' | 16 | has_many :orders, :class_name => 'OrdersPlugin::Order' |
17 | end | 17 | end |
18 | 18 | ||
19 | -class OrdersPlugin::Item < Noosfero::Plugin::ActiveRecord | 19 | +class OrdersPlugin::Item < ActiveRecord::Base |
20 | belongs_to :order, :class_name => 'OrdersPlugin::Order' | 20 | belongs_to :order, :class_name => 'OrdersPlugin::Order' |
21 | end | 21 | end |
22 | -class OrdersPlugin::Order < Noosfero::Plugin::ActiveRecord | 22 | +class OrdersPlugin::Order < ActiveRecord::Base |
23 | has_many :items, :class_name => 'OrdersPlugin::Item', :foreign_key => :order_id | 23 | has_many :items, :class_name => 'OrdersPlugin::Item', :foreign_key => :order_id |
24 | 24 | ||
25 | extend CodeNumbering::ClassMethods | 25 | extend CodeNumbering::ClassMethods |
script/quick-start
@@ -133,6 +133,9 @@ if [ ! -f .gitignore ]; then | @@ -133,6 +133,9 @@ if [ ! -f .gitignore ]; then | ||
133 | ln -s gitignore.example .gitignore | 133 | ln -s gitignore.example .gitignore |
134 | fi | 134 | fi |
135 | 135 | ||
136 | +# remove obsolete symbolic link added by old versions | ||
137 | +rm -f vendor/rails | ||
138 | + | ||
136 | # you can now start the server | 139 | # you can now start the server |
137 | say "I: Congratulations, you are ready to run Noosfero." | 140 | say "I: Congratulations, you are ready to run Noosfero." |
138 | say "I: To execute Noosfero in development mode, run \`./script/development\` and browse to http://localhost:3000" | 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,7 +31,7 @@ class ArticlesTest < ActiveSupport::TestCase | ||
31 | end | 31 | end |
32 | 32 | ||
33 | should 'not return article if user has no permission to view it' do | 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 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) | 35 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) |
36 | assert !article.published? | 36 | assert !article.published? |
37 | 37 | ||
@@ -48,8 +48,17 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -48,8 +48,17 @@ class ArticlesTest < ActiveSupport::TestCase | ||
48 | assert_equivalent [child1.id, child2.id], json["articles"].map { |a| a["id"] } | 48 | assert_equivalent [child1.id, child2.id], json["articles"].map { |a| a["id"] } |
49 | end | 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 | should 'not list children of forbidden article' do | 60 | should 'not list children of forbidden article' do |
52 | - person = fast_create(Person) | 61 | + person = fast_create(Person, :environment_id => environment.id) |
53 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) | 62 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) |
54 | child1 = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing") | 63 | child1 = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing") |
55 | child2 = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing") | 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,7 +67,7 @@ class ArticlesTest < ActiveSupport::TestCase | ||
58 | end | 67 | end |
59 | 68 | ||
60 | should 'not return child of forbidden article' do | 69 | should 'not return child of forbidden article' do |
61 | - person = fast_create(Person) | 70 | + person = fast_create(Person, :environment_id => environment.id) |
62 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) | 71 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) |
63 | child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing") | 72 | child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing") |
64 | get "/api/v1/articles/#{article.id}/children/#{child.id}?#{params.to_query}" | 73 | get "/api/v1/articles/#{article.id}/children/#{child.id}?#{params.to_query}" |
@@ -66,7 +75,7 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -66,7 +75,7 @@ class ArticlesTest < ActiveSupport::TestCase | ||
66 | end | 75 | end |
67 | 76 | ||
68 | should 'not return private child' do | 77 | should 'not return private child' do |
69 | - person = fast_create(Person) | 78 | + person = fast_create(Person, :environment_id => environment.id) |
70 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing") | 79 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing") |
71 | child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing", :published => false) | 80 | child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing", :published => false) |
72 | get "/api/v1/articles/#{article.id}/children/#{child.id}?#{params.to_query}" | 81 | get "/api/v1/articles/#{article.id}/children/#{child.id}?#{params.to_query}" |
@@ -74,7 +83,7 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -74,7 +83,7 @@ class ArticlesTest < ActiveSupport::TestCase | ||
74 | end | 83 | end |
75 | 84 | ||
76 | should 'not list private child' do | 85 | should 'not list private child' do |
77 | - person = fast_create(Person) | 86 | + person = fast_create(Person, :environment_id => environment.id) |
78 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing") | 87 | article = fast_create(Article, :profile_id => person.id, :name => "Some thing") |
79 | child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing", :published => false) | 88 | child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing", :published => false) |
80 | get "/api/v1/articles/#{article.id}/children?#{params.to_query}" | 89 | get "/api/v1/articles/#{article.id}/children?#{params.to_query}" |
@@ -82,6 +91,74 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -82,6 +91,74 @@ class ArticlesTest < ActiveSupport::TestCase | ||
82 | assert_not_includes json['articles'].map {|a| a['id']}, child.id | 91 | assert_not_includes json['articles'].map {|a| a['id']}, child.id |
83 | end | 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 | should 'list articles with pagination' do | 162 | should 'list articles with pagination' do |
86 | Article.destroy_all | 163 | Article.destroy_all |
87 | article_one = fast_create(Article, :profile_id => user.person.id, :name => "Another thing", :created_at => 2.days.ago) | 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,7 +203,7 @@ class ArticlesTest < ActiveSupport::TestCase | ||
126 | profile_kinds = %w(community person enterprise) | 203 | profile_kinds = %w(community person enterprise) |
127 | profile_kinds.each do |kind| | 204 | profile_kinds.each do |kind| |
128 | should "return article by #{kind}" do | 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 | article = fast_create(Article, :profile_id => profile.id, :name => "Some thing") | 207 | article = fast_create(Article, :profile_id => profile.id, :name => "Some thing") |
131 | get "/api/v1/#{kind.pluralize}/#{profile.id}/articles/#{article.id}?#{params.to_query}" | 208 | get "/api/v1/#{kind.pluralize}/#{profile.id}/articles/#{article.id}?#{params.to_query}" |
132 | json = JSON.parse(last_response.body) | 209 | json = JSON.parse(last_response.body) |
@@ -134,7 +211,7 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -134,7 +211,7 @@ class ArticlesTest < ActiveSupport::TestCase | ||
134 | end | 211 | end |
135 | 212 | ||
136 | should "not return article by #{kind} if user has no permission to view it" do | 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 | article = fast_create(Article, :profile_id => profile.id, :name => "Some thing", :published => false) | 215 | article = fast_create(Article, :profile_id => profile.id, :name => "Some thing", :published => false) |
139 | assert !article.published? | 216 | assert !article.published? |
140 | 217 | ||
@@ -143,7 +220,7 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -143,7 +220,7 @@ class ArticlesTest < ActiveSupport::TestCase | ||
143 | end | 220 | end |
144 | 221 | ||
145 | should "not list forbidden article when listing articles by #{kind}" do | 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 | article = fast_create(Article, :profile_id => profile.id, :name => "Some thing", :published => false) | 224 | article = fast_create(Article, :profile_id => profile.id, :name => "Some thing", :published => false) |
148 | assert !article.published? | 225 | assert !article.published? |
149 | 226 | ||
@@ -151,6 +228,29 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -151,6 +228,29 @@ class ArticlesTest < ActiveSupport::TestCase | ||
151 | json = JSON.parse(last_response.body) | 228 | json = JSON.parse(last_response.body) |
152 | assert_not_includes json['articles'].map {|a| a['id']}, article.id | 229 | assert_not_includes json['articles'].map {|a| a['id']}, article.id |
153 | end | 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 | end | 254 | end |
155 | 255 | ||
156 | ############################# | 256 | ############################# |
@@ -160,7 +260,7 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -160,7 +260,7 @@ class ArticlesTest < ActiveSupport::TestCase | ||
160 | group_kinds = %w(community enterprise) | 260 | group_kinds = %w(community enterprise) |
161 | group_kinds.each do |kind| | 261 | group_kinds.each do |kind| |
162 | should "#{kind}: create article" do | 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 | give_permission(user.person, 'post_content', profile) | 264 | give_permission(user.person, 'post_content', profile) |
165 | params[:article] = {:name => "Title"} | 265 | params[:article] = {:name => "Title"} |
166 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" | 266 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" |
@@ -169,16 +269,16 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -169,16 +269,16 @@ class ArticlesTest < ActiveSupport::TestCase | ||
169 | end | 269 | end |
170 | 270 | ||
171 | should "#{kind}: do not create article if user has no permission to post content" do | 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 | give_permission(user.person, 'invite_members', profile) | 273 | give_permission(user.person, 'invite_members', profile) |
174 | params[:article] = {:name => "Title"} | 274 | params[:article] = {:name => "Title"} |
175 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" | 275 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" |
176 | assert_equal 403, last_response.status | 276 | assert_equal 403, last_response.status |
177 | end | 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 | article = fast_create(Article) | 282 | article = fast_create(Article) |
183 | 283 | ||
184 | params[:article] = {:name => "Title", :parent_id => article.id} | 284 | params[:article] = {:name => "Title", :parent_id => article.id} |
@@ -187,9 +287,9 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -187,9 +287,9 @@ class ArticlesTest < ActiveSupport::TestCase | ||
187 | assert_equal article.id, json["article"]["parent"]["id"] | 287 | assert_equal article.id, json["article"]["parent"]["id"] |
188 | end | 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 | Article.delete_all | 294 | Article.delete_all |
195 | params[:article] = {:name => "Title"} | 295 | params[:article] = {:name => "Title"} |
@@ -201,8 +301,8 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -201,8 +301,8 @@ class ArticlesTest < ActiveSupport::TestCase | ||
201 | end | 301 | end |
202 | 302 | ||
203 | should "#{kind}: create article of TinyMceArticle type if no content type is passed as parameter" do | 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 | params[:article] = {:name => "Title"} | 307 | params[:article] = {:name => "Title"} |
208 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" | 308 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" |
@@ -212,7 +312,7 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -212,7 +312,7 @@ class ArticlesTest < ActiveSupport::TestCase | ||
212 | end | 312 | end |
213 | 313 | ||
214 | should "#{kind}: not create article with invalid article content type" do | 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 | profile.add_member(user.person) | 316 | profile.add_member(user.person) |
217 | 317 | ||
218 | params[:article] = {:name => "Title"} | 318 | params[:article] = {:name => "Title"} |
@@ -223,20 +323,20 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -223,20 +323,20 @@ class ArticlesTest < ActiveSupport::TestCase | ||
223 | assert_equal 403, last_response.status | 323 | assert_equal 403, last_response.status |
224 | end | 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 | params[:article] = {:name => "Title"} | 330 | params[:article] = {:name => "Title"} |
231 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" | 331 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" |
232 | json = JSON.parse(last_response.body) | 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 | end | 335 | end |
236 | 336 | ||
237 | should "#{kind}: create article defining the created_by" do | 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 | params[:article] = {:name => "Title"} | 341 | params[:article] = {:name => "Title"} |
242 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" | 342 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" |
@@ -246,8 +346,8 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -246,8 +346,8 @@ class ArticlesTest < ActiveSupport::TestCase | ||
246 | end | 346 | end |
247 | 347 | ||
248 | should "#{kind}: create article defining the last_changed_by" do | 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 | params[:article] = {:name => "Title"} | 352 | params[:article] = {:name => "Title"} |
253 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" | 353 | post "/api/v1/#{kind.pluralize}/#{profile.id}/articles?#{params.to_query}" |
@@ -269,7 +369,7 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -269,7 +369,7 @@ class ArticlesTest < ActiveSupport::TestCase | ||
269 | end | 369 | end |
270 | 370 | ||
271 | should 'person do not create article if user has no permission to post content' do | 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 | params[:article] = {:name => "Title"} | 373 | params[:article] = {:name => "Title"} |
274 | post "/api/v1/people/#{person.id}/articles?#{params.to_query}" | 374 | post "/api/v1/people/#{person.id}/articles?#{params.to_query}" |
275 | assert_equal 403, last_response.status | 375 | assert_equal 403, last_response.status |
@@ -376,4 +476,99 @@ class ArticlesTest < ActiveSupport::TestCase | @@ -376,4 +476,99 @@ class ArticlesTest < ActiveSupport::TestCase | ||
376 | assert_equal [0, 1, 1], [a1.reload.hits, a2.reload.hits, a3.reload.hits] | 476 | assert_equal [0, 1, 1], [a1.reload.hits, a2.reload.hits, a3.reload.hits] |
377 | end | 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 | end | 574 | end |
test/unit/api/categories_test.rb
@@ -7,25 +7,25 @@ class CategoriesTest < ActiveSupport::TestCase | @@ -7,25 +7,25 @@ class CategoriesTest < ActiveSupport::TestCase | ||
7 | end | 7 | end |
8 | 8 | ||
9 | should 'list categories' do | 9 | should 'list categories' do |
10 | - category = fast_create(Category) | 10 | + category = fast_create(Category, :environment_id => environment.id) |
11 | get "/api/v1/categories/?#{params.to_query}" | 11 | get "/api/v1/categories/?#{params.to_query}" |
12 | json = JSON.parse(last_response.body) | 12 | json = JSON.parse(last_response.body) |
13 | assert_includes json["categories"].map { |c| c["name"] }, category.name | 13 | assert_includes json["categories"].map { |c| c["name"] }, category.name |
14 | end | 14 | end |
15 | 15 | ||
16 | should 'get category by id' do | 16 | should 'get category by id' do |
17 | - category = fast_create(Category) | 17 | + category = fast_create(Category, :environment_id => environment.id) |
18 | get "/api/v1/categories/#{category.id}/?#{params.to_query}" | 18 | get "/api/v1/categories/#{category.id}/?#{params.to_query}" |
19 | json = JSON.parse(last_response.body) | 19 | json = JSON.parse(last_response.body) |
20 | assert_equal category.name, json["category"]["name"] | 20 | assert_equal category.name, json["category"]["name"] |
21 | end | 21 | end |
22 | 22 | ||
23 | should 'list parent and children when get category by id' do | 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 | category.parent = parent | 29 | category.parent = parent |
30 | category.children << child_1 | 30 | category.children << child_1 |
31 | category.children << child_2 | 31 | category.children << child_2 |
@@ -33,16 +33,16 @@ class CategoriesTest < ActiveSupport::TestCase | @@ -33,16 +33,16 @@ class CategoriesTest < ActiveSupport::TestCase | ||
33 | 33 | ||
34 | get "/api/v1/categories/#{category.id}/?#{params.to_query}" | 34 | get "/api/v1/categories/#{category.id}/?#{params.to_query}" |
35 | json = JSON.parse(last_response.body) | 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 | assert_equivalent [child_1.id, child_2.id], json['category']['children'].map { |c| c['id'] } | 37 | assert_equivalent [child_1.id, child_2.id], json['category']['children'].map { |c| c['id'] } |
38 | end | 38 | end |
39 | 39 | ||
40 | should 'include parent in categories list if params is true' do | 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 | parent_2.parent = parent_1 | 46 | parent_2.parent = parent_1 |
47 | parent_2.children << child_1 | 47 | parent_2.children << child_1 |
48 | parent_2.children << child_2 | 48 | parent_2.children << child_2 |
@@ -60,10 +60,10 @@ class CategoriesTest < ActiveSupport::TestCase | @@ -60,10 +60,10 @@ class CategoriesTest < ActiveSupport::TestCase | ||
60 | end | 60 | end |
61 | 61 | ||
62 | should 'include children in categories list if params is true' do | 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 | category.children << child_1 | 68 | category.children << child_1 |
69 | category.children << child_2 | 69 | category.children << child_2 |
@@ -83,4 +83,15 @@ class CategoriesTest < ActiveSupport::TestCase | @@ -83,4 +83,15 @@ class CategoriesTest < ActiveSupport::TestCase | ||
83 | json["categories"].map{ |c| c['children'].map{ |child| child['id'] }.sort } | 83 | json["categories"].map{ |c| c['children'].map{ |child| child['id'] }.sort } |
84 | end | 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 | end | 97 | end |
test/unit/api/comments_test.rb
@@ -65,4 +65,17 @@ class CommentsTest < ActiveSupport::TestCase | @@ -65,4 +65,17 @@ class CommentsTest < ActiveSupport::TestCase | ||
65 | assert_equal 201, last_response.status | 65 | assert_equal 201, last_response.status |
66 | assert_equal body, json['comment']['body'] | 66 | assert_equal body, json['comment']['body'] |
67 | end | 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 | end | 81 | end |
test/unit/api/communities_test.rb
@@ -8,8 +8,8 @@ class CommunitiesTest < ActiveSupport::TestCase | @@ -8,8 +8,8 @@ class CommunitiesTest < ActiveSupport::TestCase | ||
8 | end | 8 | end |
9 | 9 | ||
10 | should 'list only communities' do | 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 | get "/api/v1/communities?#{params.to_query}" | 13 | get "/api/v1/communities?#{params.to_query}" |
14 | json = JSON.parse(last_response.body) | 14 | json = JSON.parse(last_response.body) |
15 | assert_not_includes json['communities'].map {|c| c['id']}, enterprise.id | 15 | assert_not_includes json['communities'].map {|c| c['id']}, enterprise.id |
@@ -17,16 +17,16 @@ class CommunitiesTest < ActiveSupport::TestCase | @@ -17,16 +17,16 @@ class CommunitiesTest < ActiveSupport::TestCase | ||
17 | end | 17 | end |
18 | 18 | ||
19 | should 'list all communities' do | 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 | get "/api/v1/communities?#{params.to_query}" | 22 | get "/api/v1/communities?#{params.to_query}" |
23 | json = JSON.parse(last_response.body) | 23 | json = JSON.parse(last_response.body) |
24 | assert_equivalent [community1.id, community2.id], json['communities'].map {|c| c['id']} | 24 | assert_equivalent [community1.id, community2.id], json['communities'].map {|c| c['id']} |
25 | end | 25 | end |
26 | 26 | ||
27 | should 'not list invisible communities' do | 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 | get "/api/v1/communities?#{params.to_query}" | 31 | get "/api/v1/communities?#{params.to_query}" |
32 | json = JSON.parse(last_response.body) | 32 | json = JSON.parse(last_response.body) |
@@ -34,8 +34,8 @@ class CommunitiesTest < ActiveSupport::TestCase | @@ -34,8 +34,8 @@ class CommunitiesTest < ActiveSupport::TestCase | ||
34 | end | 34 | end |
35 | 35 | ||
36 | should 'not list private communities without permission' do | 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 | get "/api/v1/communities?#{params.to_query}" | 40 | get "/api/v1/communities?#{params.to_query}" |
41 | json = JSON.parse(last_response.body) | 41 | json = JSON.parse(last_response.body) |
@@ -43,8 +43,8 @@ class CommunitiesTest < ActiveSupport::TestCase | @@ -43,8 +43,8 @@ class CommunitiesTest < ActiveSupport::TestCase | ||
43 | end | 43 | end |
44 | 44 | ||
45 | should 'list private community for members' do | 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 | c2.add_member(person) | 48 | c2.add_member(person) |
49 | 49 | ||
50 | get "/api/v1/communities?#{params.to_query}" | 50 | get "/api/v1/communities?#{params.to_query}" |
@@ -66,7 +66,7 @@ class CommunitiesTest < ActiveSupport::TestCase | @@ -66,7 +66,7 @@ class CommunitiesTest < ActiveSupport::TestCase | ||
66 | end | 66 | end |
67 | 67 | ||
68 | should 'get community' do | 68 | should 'get community' do |
69 | - community = fast_create(Community) | 69 | + community = fast_create(Community, :environment_id => environment.id) |
70 | 70 | ||
71 | get "/api/v1/communities/#{community.id}?#{params.to_query}" | 71 | get "/api/v1/communities/#{community.id}?#{params.to_query}" |
72 | json = JSON.parse(last_response.body) | 72 | json = JSON.parse(last_response.body) |
@@ -74,7 +74,7 @@ class CommunitiesTest < ActiveSupport::TestCase | @@ -74,7 +74,7 @@ class CommunitiesTest < ActiveSupport::TestCase | ||
74 | end | 74 | end |
75 | 75 | ||
76 | should 'not get invisible community' do | 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 | get "/api/v1/communities/#{community.id}?#{params.to_query}" | 79 | get "/api/v1/communities/#{community.id}?#{params.to_query}" |
80 | json = JSON.parse(last_response.body) | 80 | json = JSON.parse(last_response.body) |
@@ -82,8 +82,8 @@ class CommunitiesTest < ActiveSupport::TestCase | @@ -82,8 +82,8 @@ class CommunitiesTest < ActiveSupport::TestCase | ||
82 | end | 82 | end |
83 | 83 | ||
84 | should 'not get private communities without permission' do | 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 | get "/api/v1/communities/#{community.id}?#{params.to_query}" | 88 | get "/api/v1/communities/#{community.id}?#{params.to_query}" |
89 | json = JSON.parse(last_response.body) | 89 | json = JSON.parse(last_response.body) |
@@ -91,17 +91,18 @@ class CommunitiesTest < ActiveSupport::TestCase | @@ -91,17 +91,18 @@ class CommunitiesTest < ActiveSupport::TestCase | ||
91 | end | 91 | end |
92 | 92 | ||
93 | should 'get private community for members' do | 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 | community.add_member(person) | 95 | community.add_member(person) |
96 | 96 | ||
97 | + | ||
97 | get "/api/v1/communities/#{community.id}?#{params.to_query}" | 98 | get "/api/v1/communities/#{community.id}?#{params.to_query}" |
98 | json = JSON.parse(last_response.body) | 99 | json = JSON.parse(last_response.body) |
99 | assert_equal community.id, json['community']['id'] | 100 | assert_equal community.id, json['community']['id'] |
100 | end | 101 | end |
101 | 102 | ||
102 | should 'list person communities' do | 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 | community.add_member(person) | 106 | community.add_member(person) |
106 | 107 | ||
107 | get "/api/v1/people/#{person.id}/communities?#{params.to_query}" | 108 | get "/api/v1/people/#{person.id}/communities?#{params.to_query}" |
@@ -110,8 +111,8 @@ class CommunitiesTest < ActiveSupport::TestCase | @@ -110,8 +111,8 @@ class CommunitiesTest < ActiveSupport::TestCase | ||
110 | end | 111 | end |
111 | 112 | ||
112 | should 'not list person communities invisible' do | 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 | c1.add_member(person) | 116 | c1.add_member(person) |
116 | c2.add_member(person) | 117 | c2.add_member(person) |
117 | 118 |
test/unit/api/enterprises_test.rb
@@ -8,8 +8,8 @@ class EnterprisesTest < ActiveSupport::TestCase | @@ -8,8 +8,8 @@ class EnterprisesTest < ActiveSupport::TestCase | ||
8 | end | 8 | end |
9 | 9 | ||
10 | should 'list only enterprises' do | 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 | get "/api/v1/enterprises?#{params.to_query}" | 13 | get "/api/v1/enterprises?#{params.to_query}" |
14 | json = JSON.parse(last_response.body) | 14 | json = JSON.parse(last_response.body) |
15 | assert_includes json['enterprises'].map {|c| c['id']}, enterprise.id | 15 | assert_includes json['enterprises'].map {|c| c['id']}, enterprise.id |
@@ -17,15 +17,15 @@ class EnterprisesTest < ActiveSupport::TestCase | @@ -17,15 +17,15 @@ class EnterprisesTest < ActiveSupport::TestCase | ||
17 | end | 17 | end |
18 | 18 | ||
19 | should 'list all enterprises' do | 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 | get "/api/v1/enterprises?#{params.to_query}" | 22 | get "/api/v1/enterprises?#{params.to_query}" |
23 | json = JSON.parse(last_response.body) | 23 | json = JSON.parse(last_response.body) |
24 | assert_equivalent [enterprise1.id, enterprise2.id], json['enterprises'].map {|c| c['id']} | 24 | assert_equivalent [enterprise1.id, enterprise2.id], json['enterprises'].map {|c| c['id']} |
25 | end | 25 | end |
26 | 26 | ||
27 | should 'not list invisible enterprises' do | 27 | should 'not list invisible enterprises' do |
28 | - enterprise1 = fast_create(Enterprise) | 28 | + enterprise1 = fast_create(Enterprise, :environment_id => environment.id) |
29 | fast_create(Enterprise, :visible => false) | 29 | fast_create(Enterprise, :visible => false) |
30 | 30 | ||
31 | get "/api/v1/enterprises?#{params.to_query}" | 31 | get "/api/v1/enterprises?#{params.to_query}" |
@@ -34,8 +34,8 @@ class EnterprisesTest < ActiveSupport::TestCase | @@ -34,8 +34,8 @@ class EnterprisesTest < ActiveSupport::TestCase | ||
34 | end | 34 | end |
35 | 35 | ||
36 | should 'not list private enterprises without permission' do | 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 | get "/api/v1/enterprises?#{params.to_query}" | 40 | get "/api/v1/enterprises?#{params.to_query}" |
41 | json = JSON.parse(last_response.body) | 41 | json = JSON.parse(last_response.body) |
@@ -43,8 +43,8 @@ class EnterprisesTest < ActiveSupport::TestCase | @@ -43,8 +43,8 @@ class EnterprisesTest < ActiveSupport::TestCase | ||
43 | end | 43 | end |
44 | 44 | ||
45 | should 'list private enterprise for members' do | 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 | c2.add_member(person) | 48 | c2.add_member(person) |
49 | 49 | ||
50 | get "/api/v1/enterprises?#{params.to_query}" | 50 | get "/api/v1/enterprises?#{params.to_query}" |
@@ -53,7 +53,7 @@ class EnterprisesTest < ActiveSupport::TestCase | @@ -53,7 +53,7 @@ class EnterprisesTest < ActiveSupport::TestCase | ||
53 | end | 53 | end |
54 | 54 | ||
55 | should 'get enterprise' do | 55 | should 'get enterprise' do |
56 | - enterprise = fast_create(Enterprise) | 56 | + enterprise = fast_create(Enterprise, :environment_id => environment.id) |
57 | 57 | ||
58 | get "/api/v1/enterprises/#{enterprise.id}?#{params.to_query}" | 58 | get "/api/v1/enterprises/#{enterprise.id}?#{params.to_query}" |
59 | json = JSON.parse(last_response.body) | 59 | json = JSON.parse(last_response.body) |
@@ -69,8 +69,8 @@ class EnterprisesTest < ActiveSupport::TestCase | @@ -69,8 +69,8 @@ class EnterprisesTest < ActiveSupport::TestCase | ||
69 | end | 69 | end |
70 | 70 | ||
71 | should 'not get private enterprises without permission' do | 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 | get "/api/v1/enterprises/#{enterprise.id}?#{params.to_query}" | 75 | get "/api/v1/enterprises/#{enterprise.id}?#{params.to_query}" |
76 | json = JSON.parse(last_response.body) | 76 | json = JSON.parse(last_response.body) |
@@ -87,8 +87,8 @@ class EnterprisesTest < ActiveSupport::TestCase | @@ -87,8 +87,8 @@ class EnterprisesTest < ActiveSupport::TestCase | ||
87 | end | 87 | end |
88 | 88 | ||
89 | should 'list person enterprises' do | 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 | enterprise.add_member(person) | 92 | enterprise.add_member(person) |
93 | 93 | ||
94 | get "/api/v1/people/#{person.id}/enterprises?#{params.to_query}" | 94 | get "/api/v1/people/#{person.id}/enterprises?#{params.to_query}" |
@@ -97,8 +97,8 @@ class EnterprisesTest < ActiveSupport::TestCase | @@ -97,8 +97,8 @@ class EnterprisesTest < ActiveSupport::TestCase | ||
97 | end | 97 | end |
98 | 98 | ||
99 | should 'not list person enterprises invisible' do | 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 | c1.add_member(person) | 102 | c1.add_member(person) |
103 | c2.add_member(person) | 103 | c2.add_member(person) |
104 | 104 |
test/unit/api/helpers_test.rb
@@ -25,15 +25,6 @@ class APIHelpersTest < ActiveSupport::TestCase | @@ -25,15 +25,6 @@ class APIHelpersTest < ActiveSupport::TestCase | ||
25 | assert_equal user, current_user | 25 | assert_equal user, current_user |
26 | end | 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 | should 'get the person of current user' do | 28 | should 'get the person of current user' do |
38 | user = create_user('someuser') | 29 | user = create_user('someuser') |
39 | user.generate_private_token! | 30 | user.generate_private_token! |
@@ -161,6 +152,39 @@ class APIHelpersTest < ActiveSupport::TestCase | @@ -161,6 +152,39 @@ class APIHelpersTest < ActiveSupport::TestCase | ||
161 | assert_nil make_conditions_with_parameter[:type] | 152 | assert_nil make_conditions_with_parameter[:type] |
162 | end | 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 | should 'render not_found if endpoint is unavailable' do | 188 | should 'render not_found if endpoint is unavailable' do |
165 | Noosfero::API::API.stubs(:endpoint_unavailable?).returns(true) | 189 | Noosfero::API::API.stubs(:endpoint_unavailable?).returns(true) |
166 | self.expects(:not_found!) | 190 | self.expects(:not_found!) |
test/unit/api/people_test.rb
@@ -148,4 +148,21 @@ class PeopleTest < ActiveSupport::TestCase | @@ -148,4 +148,21 @@ class PeopleTest < ActiveSupport::TestCase | ||
148 | get "/api/v1/people/#{some_person.id}/permissions?#{params.to_query}" | 148 | get "/api/v1/people/#{some_person.id}/permissions?#{params.to_query}" |
149 | assert_equal 403, last_response.status | 149 | assert_equal 403, last_response.status |
150 | end | 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 | end | 168 | end |
@@ -0,0 +1,139 @@ | @@ -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,7 +10,7 @@ class SessionTest < ActiveSupport::TestCase | ||
10 | params = {:login => "testapi", :password => "testapi"} | 10 | params = {:login => "testapi", :password => "testapi"} |
11 | post "/api/v1/login?#{params.to_query}" | 11 | post "/api/v1/login?#{params.to_query}" |
12 | json = JSON.parse(last_response.body) | 12 | json = JSON.parse(last_response.body) |
13 | - assert !json["private_token"].blank? | 13 | + assert !json['user']["private_token"].blank? |
14 | end | 14 | end |
15 | 15 | ||
16 | should 'return 401 when login fails' do | 16 | should 'return 401 when login fails' do |
@@ -21,22 +21,165 @@ class SessionTest < ActiveSupport::TestCase | @@ -21,22 +21,165 @@ class SessionTest < ActiveSupport::TestCase | ||
21 | end | 21 | end |
22 | 22 | ||
23 | should 'register a user' do | 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 | post "/api/v1/register?#{params.to_query}" | 26 | post "/api/v1/register?#{params.to_query}" |
26 | assert_equal 201, last_response.status | 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 | end | 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 | post "/api/v1/register?#{params.to_query}" | 55 | post "/api/v1/register?#{params.to_query}" |
32 | assert_equal 400, last_response.status | 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 | end | 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 | post "/api/v1/register?#{params.to_query}" | 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 | post "/api/v1/register?#{params.to_query}" | 80 | post "/api/v1/register?#{params.to_query}" |
39 | assert_equal 400, last_response.status | 81 | assert_equal 400, last_response.status |
40 | end | 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 | end | 185 | end |
test/unit/api/test_helper.rb
1 | -require 'test_helper' | 1 | +require_relative '../../test_helper' |
2 | 2 | ||
3 | class ActiveSupport::TestCase | 3 | class ActiveSupport::TestCase |
4 | 4 | ||
@@ -9,16 +9,22 @@ class ActiveSupport::TestCase | @@ -9,16 +9,22 @@ class ActiveSupport::TestCase | ||
9 | end | 9 | end |
10 | 10 | ||
11 | def login_api | 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 | @user.activate | 14 | @user.activate |
14 | @person = @user.person | 15 | @person = @user.person |
15 | 16 | ||
16 | post "/api/v1/login?login=testapi&password=testapi" | 17 | post "/api/v1/login?login=testapi&password=testapi" |
17 | json = JSON.parse(last_response.body) | 18 | json = JSON.parse(last_response.body) |
18 | @private_token = json["private_token"] | 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 | @params = {:private_token => @private_token} | 25 | @params = {:private_token => @private_token} |
20 | end | 26 | end |
21 | - attr_accessor :private_token, :user, :person, :params | 27 | + attr_accessor :private_token, :user, :person, :params, :environment |
22 | 28 | ||
23 | private | 29 | private |
24 | 30 |
@@ -0,0 +1,105 @@ | @@ -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,4 +34,16 @@ class CreateThumbnailsJobTest < ActiveSupport::TestCase | ||
34 | end | 34 | end |
35 | end | 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 | end | 49 | end |