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