Commit 8a6d7d69406ad72f4dc412cbc51d53000a63cc90

Authored by Victor Costa
2 parents 96cb988c 3ffde53a

Merge branch 'api' into stable

Conflicts:
	config.ru
	lib/noosfero/plugin.rb
Gemfile
... ... @@ -20,6 +20,16 @@ gem 'gettext', '~> 2.2.1', :require => false
20 20 gem 'locale', '~> 2.0.5'
21 21 gem 'whenever', :require => false
22 22 gem 'eita-jrails', '>= 0.9.5', :require => 'jrails'
  23 +gem 'grape', '~> 0.8.0'
  24 +gem 'grape-entity'
  25 +gem 'grape-swagger'
  26 +gem 'rack-cors'
  27 +gem 'rack-contrib'
  28 +
  29 +#gem 'grape-swagger-rails'
  30 +
  31 +# FIXME list here all actual dependencies (i.e. the ones in debian/control),
  32 +# with their GEM names (not the Debian package names)
23 33  
24 34 group :assets do
25 35 gem 'uglifier', '>= 1.0.3'
... ...
Rakefile
... ... @@ -15,4 +15,21 @@ Noosfero::Application.load_tasks
15 15 Dir.glob(pattern).sort
16 16 end.flatten.each do |taskfile|
17 17 load taskfile
  18 +end
  19 +
  20 +# plugins' tasks
  21 +plugins_tasks = Dir.glob("config/plugins/*/{tasks,lib/tasks,rails/tasks}/**/*.rake").sort +
  22 + Dir.glob("config/plugins/*/vendor/plugins/*/{tasks,lib/tasks,rails/tasks}/**/*.rake").sort
  23 +plugins_tasks.each{ |ext| load ext }
  24 +
  25 +
  26 +desc "Print out grape routes"
  27 +task :grape_routes => :environment do
  28 + #require 'api/api.rb'
  29 + Noosfero::API::API.routes.each do |route|
  30 + puts route
  31 + method = route.route_method
  32 + path = route.route_path
  33 + puts " #{method} #{path}"
  34 + end
18 35 end
... ...
app/controllers/my_profile/cms_controller.rb
... ... @@ -27,20 +27,13 @@ class CmsController < MyProfileController
27 27  
28 28 helper_method :file_types
29 29  
30   - protect_if :only => :upload_files do |c, user, profile|
31   - article_id = c.params[:parent_id]
32   - (!article_id.blank? && profile.articles.find(article_id).allow_create?(user)) ||
33   - (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)))
34   - end
35   -
36   - protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :publish_on_portal_community, :publish_on_communities, :search_communities_to_publish, :upload_files, :new] do |c, user, profile|
  30 + protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :upload_files, :new] do |c, user, profile|
37 31 user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))
38 32 end
39 33  
40   - protect_if :only => :new do |c, user, profile|
41   - article = profile.articles.find_by_id(c.params[:parent_id])
42   - (!article.nil? && (article.allow_create?(user) || article.parent.allow_create?(user))) ||
43   - (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)))
  34 + protect_if :only => [:new, :upload_files] do |c, user, profile|
  35 + parent = profile.articles.find_by_id(c.params[:parent_id])
  36 + user && user.can_post_content?(profile, parent)
44 37 end
45 38  
46 39 protect_if :only => :destroy do |c, user, profile|
... ...
app/models/article.rb
... ... @@ -702,6 +702,11 @@ class Article < ActiveRecord::Base
702 702 person ? person.id : nil
703 703 end
704 704  
  705 + #FIXME make this test
  706 + def author_custom_image(size = :icon)
  707 + author ? author.profile_custom_image(size) : nil
  708 + end
  709 +
705 710 def version_license(version_number = nil)
706 711 return license if version_number.nil?
707 712 profile.environment.licenses.find_by_id(get_version(version_number).license_id)
... ...
app/models/organization.rb
... ... @@ -8,6 +8,13 @@ class Organization < Profile
8 8 :display => %w[compact]
9 9 }
10 10  
  11 + scope :visible_for_person, lambda { |person|
  12 + joins('LEFT JOIN "role_assignments" ON "role_assignments"."resource_id" = "profiles"."id" AND "role_assignments"."resource_type" = \'Profile\'')
  13 + .where(
  14 + ['( ( role_assignments.accessor_type = ? AND role_assignments.accessor_id = ? ) OR
  15 + (profiles.public_profile = ?)) AND (profiles.visible = ?)', Profile.name, person.id, true, true]
  16 + ).uniq
  17 + }
11 18  
12 19 settings_items :closed, :type => :boolean, :default => false
13 20 def closed?
... ...
app/models/person.rb
... ... @@ -39,6 +39,14 @@ roles] }
39 39 { :select => 'DISTINCT profiles.*', :conditions => ['"profiles"."id" NOT IN (SELECT DISTINCT profiles.id FROM "profiles" INNER JOIN "friendships" ON "friendships"."person_id" = "profiles"."id" WHERE "friendships"."friend_id" IN (%s))' % resources.map(&:id)] }
40 40 }
41 41  
  42 + scope :visible_for_person, lambda { |person|
  43 + joins('LEFT JOIN "friendships" ON "friendships"."friend_id" = "profiles"."id"')
  44 + .where(
  45 + ['( ( friendships.person_id = ? ) OR (profiles.public_profile = ?)) AND (profiles.visible = ?)', person.id, true, true]
  46 + ).uniq
  47 + }
  48 +
  49 +
42 50 def has_permission_with_admin?(permission, resource)
43 51 return true if resource.blank? || resource.admins.include?(self)
44 52 return true if resource.kind_of?(Profile) && resource.environment.admins.include?(self)
... ... @@ -123,6 +131,11 @@ roles] }
123 131 self.tracked_notifications.exists?(activity)
124 132 end
125 133  
  134 + def can_post_content?(profile, parent=nil)
  135 + (!parent.nil? && (parent.allow_create?(self))) ||
  136 + (self.has_permission?('post_content', profile) || self.has_permission?('publish_content', profile))
  137 + end
  138 +
126 139 # Sets the identifier for this person. Raises an exception when called on a
127 140 # existing person (since peoples' identifiers cannot be changed)
128 141 def identifier=(value)
... ...
app/models/profile.rb
... ... @@ -124,6 +124,16 @@ class Profile < ActiveRecord::Base
124 124 }
125 125 scope :no_templates, {:conditions => {:is_template => false}}
126 126  
  127 + #FIXME make this test
  128 + scope :newer_than, lambda { |reference_id|
  129 + {:conditions => ["profiles.id > #{reference_id}"]}
  130 + }
  131 +
  132 + #FIXME make this test
  133 + scope :older_than, lambda { |reference_id|
  134 + {:conditions => ["profiles.id < #{reference_id}"]}
  135 + }
  136 +
127 137 def members
128 138 scopes = plugins.dispatch_scopes(:organization_members, self)
129 139 scopes << Person.members_of(self)
... ... @@ -947,6 +957,13 @@ private :generate_url, :url_options
947 957 image.public_filename(:icon) if image.present?
948 958 end
949 959  
  960 + #FIXME make this test
  961 + def profile_custom_image(size = :icon)
  962 + image_path = profile_custom_icon if size == :icon
  963 + image_path ||= image.public_filename(size) if image.present?
  964 + image_path
  965 + end
  966 +
950 967 def jid(options = {})
951 968 domain = options[:domain] || environment.default_hostname
952 969 "#{identifier}@#{domain}"
... ...
app/models/user.rb
1 1 require 'digest/sha1'
2 2 require 'user_activation_job'
  3 +require 'securerandom'
3 4  
4 5 # User models the system users, and is generated by the acts_as_authenticated
5 6 # Rails generator.
... ... @@ -119,6 +120,18 @@ class User &lt; ActiveRecord::Base
119 120 self.update_attribute :last_login_at, Time.now
120 121 end
121 122  
  123 + #FIXME make this test
  124 + def generate_private_token!
  125 + self.private_token = SecureRandom.hex
  126 + self.private_token_generated_at = DateTime.now
  127 + save(:validate => false)
  128 + end
  129 +
  130 + #FIXME make this test
  131 + def private_token_expired?
  132 + self.generate_private_token! if self.private_token.nil? || (self.private_token_generated_at + 2.weeks < DateTime.now)
  133 + end
  134 +
122 135 # Activates the user in the database.
123 136 def activate
124 137 return false unless self.person
... ...
config.ru
... ... @@ -2,11 +2,15 @@
2 2  
3 3 require ::File.expand_path('../config/environment', __FILE__)
4 4  
  5 +#use Rails::Rack::LogTailer
  6 +#use Rails::Rack::Static
  7 +#run ActionController::Dispatcher.news
  8 +
5 9 rails_app = Rack::Builder.new do
6 10 run Noosfero::Application
7 11 end
8 12  
9 13 run Rack::Cascade.new([
10   - API::API,
  14 + Noosfero::API::API,
11 15 rails_app
12 16 ])
... ...
config/application.rb
... ... @@ -135,5 +135,12 @@ module Noosfero
135 135  
136 136 Noosfero::Plugin.setup(config)
137 137  
  138 + config.middleware.use Rack::Cors do
  139 + allow do
  140 + origins '*'
  141 + resource 'api/*', :headers => :any, :methods => [:get, :post]
  142 + end
  143 + end
  144 +
138 145 end
139 146 end
... ...
db/migrate/20150223180807_add_private_token_info_to_users.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class AddPrivateTokenInfoToUsers < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :users, :private_token, :string
  4 + add_column :users, :private_token_generated_at, :datetime
  5 + end
  6 +
  7 + def self.down
  8 + remove_column :users, :private_token
  9 + remove_column :users, :private_token_generated_at
  10 + end
  11 +end
... ...
db/schema.rb
... ... @@ -720,21 +720,21 @@ ActiveRecord::Schema.define(:version =&gt; 20150408231524) do
720 720 create_table "users", :force => true do |t|
721 721 t.string "login"
722 722 t.string "email"
723   - t.string "crypted_password", :limit => 40
724   - t.string "salt", :limit => 40
  723 + t.string "crypted_password", :limit => 40
  724 + t.string "salt", :limit => 40
725 725 t.datetime "created_at"
726 726 t.datetime "updated_at"
727 727 t.string "remember_token"
728 728 t.datetime "remember_token_expires_at"
729 729 t.text "terms_of_use"
730   - t.string "terms_accepted", :limit => 1
  730 + t.string "terms_accepted", :limit => 1
731 731 t.integer "environment_id"
732 732 t.string "password_type"
733   - t.boolean "enable_email", :default => false
734   - t.string "last_chat_status", :default => ""
735   - t.string "chat_status", :default => ""
  733 + t.boolean "enable_email", :default => false
  734 + t.string "last_chat_status", :default => ""
  735 + t.string "chat_status", :default => ""
736 736 t.datetime "chat_status_at"
737   - t.string "activation_code", :limit => 40
  737 + t.string "activation_code", :limit => 40
738 738 t.datetime "activated_at"
739 739 t.string "return_to"
740 740 t.datetime "last_login_at"
... ...
lib/noosfero/api/api.rb 0 → 100644
... ... @@ -0,0 +1,42 @@
  1 +require 'grape'
  2 +#require 'rack/contrib'
  3 +Dir["#{Rails.root}/lib/noosfero/api/*.rb"].each {|file| require file}
  4 +module Noosfero
  5 + module API
  6 + class API < Grape::API
  7 + use Rack::JSONP
  8 +
  9 + before { start_log }
  10 + before { setup_multitenancy }
  11 + before { detect_stuff_by_domain }
  12 + after { end_log }
  13 +
  14 + version 'v1'
  15 + prefix "api"
  16 + format :json
  17 + content_type :txt, "text/plain"
  18 +
  19 + helpers APIHelpers
  20 +
  21 + mount V1::Articles
  22 + mount V1::Comments
  23 + mount V1::Users
  24 + mount V1::Communities
  25 + mount V1::People
  26 + mount V1::Enterprises
  27 + mount V1::Categories
  28 + mount Session
  29 +
  30 + # hook point which allow plugins to add Grape::API extensions to API::API
  31 + #finds for plugins which has api mount points classes defined (the class should extends Grape::API)
  32 + @plugins = Noosfero::Plugin.all.map { |p| p.constantize }
  33 + @plugins.each do |klass|
  34 + if klass.public_methods.include? 'api_mount_points'
  35 + klass.api_mount_points.each do |mount_class|
  36 + mount mount_class if mount_class && ( mount_class < Grape::API )
  37 + end
  38 + end
  39 + end
  40 + end
  41 + end
  42 +end
... ...
lib/noosfero/api/entities.rb 0 → 100644
... ... @@ -0,0 +1,94 @@
  1 +module Noosfero
  2 + module API
  3 + module Entities
  4 +
  5 + Grape::Entity.format_with :timestamp do |date|
  6 + date.strftime('%Y/%m/%d %H:%M:%S') if date
  7 + end
  8 +
  9 + class Image < Grape::Entity
  10 + root 'images', 'image'
  11 +
  12 + expose :icon_url do |image, options|
  13 + image.public_filename(:icon)
  14 + end
  15 +
  16 + expose :minor_url do |image, options|
  17 + image.public_filename(:minor)
  18 + end
  19 +
  20 + expose :portrait_url do |image, options|
  21 + image.public_filename(:portrait)
  22 + end
  23 +
  24 + expose :thumb_url do |image, options|
  25 + image.public_filename(:thumb)
  26 + end
  27 + end
  28 +
  29 + class Profile < Grape::Entity
  30 + expose :identifier, :name, :id
  31 + expose :created_at, :format_with => :timestamp
  32 + expose :image, :using => Image
  33 + end
  34 +
  35 + class Person < Profile
  36 + root 'people', 'person'
  37 + end
  38 + class Enterprise < Profile
  39 + root 'enterprises', 'enterprise'
  40 + end
  41 + class Community < Profile
  42 + root 'communities', 'community'
  43 + expose :description
  44 + end
  45 +
  46 + class Category < Grape::Entity
  47 + root 'categories', 'category'
  48 + expose :name, :id, :slug
  49 + expose :image, :using => Image
  50 + end
  51 +
  52 +
  53 + class Article < Grape::Entity
  54 + root 'articles', 'article'
  55 + expose :id, :body
  56 + expose :created_at, :format_with => :timestamp
  57 + expose :title, :documentation => {:type => "String", :desc => "Title of the article"}
  58 + expose :created_by, :as => :author, :using => Profile
  59 + expose :profile, :using => Profile
  60 + expose :categories, :using => Category
  61 + expose :parent, :using => Article
  62 + end
  63 +
  64 + class Comment < Grape::Entity
  65 + root 'comments', 'comment'
  66 + expose :body, :title, :id
  67 + expose :created_at, :format_with => :timestamp
  68 + expose :author, :using => Profile
  69 + end
  70 +
  71 +
  72 + class User < Grape::Entity
  73 + root 'users', 'user'
  74 + expose :id
  75 + expose :login
  76 + expose :person, :using => Profile
  77 + expose :permissions do |user, options|
  78 + output = {}
  79 + user.person.role_assignments.map do |role_assigment|
  80 + if role_assigment.resource.respond_to?(:identifier)
  81 + output[role_assigment.resource.identifier] = role_assigment.role.permissions
  82 + end
  83 + end
  84 + output
  85 + end
  86 + end
  87 +
  88 + class UserLogin < User
  89 + expose :private_token
  90 + end
  91 +
  92 + end
  93 + end
  94 +end
... ...
lib/noosfero/api/helpers.rb 0 → 100644
... ... @@ -0,0 +1,196 @@
  1 +module Noosfero
  2 + module API
  3 + module APIHelpers
  4 + PRIVATE_TOKEN_PARAM = :private_token
  5 + ALLOWED_PARAMETERS = ['parent_id', 'from', 'until', 'content_type']
  6 +
  7 + def logger
  8 + @logger ||= Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV']}_api.log"))
  9 + end
  10 +
  11 + def current_user
  12 + private_token = params[PRIVATE_TOKEN_PARAM].to_s if params
  13 + @current_user ||= User.find_by_private_token(private_token)
  14 + @current_user = nil if !@current_user.nil? && @current_user.private_token_expired?
  15 + @current_user
  16 + end
  17 +
  18 + def current_person
  19 + current_user.person unless current_user.nil?
  20 + end
  21 +
  22 + def logout
  23 + @current_user = nil
  24 + end
  25 +
  26 + def environment
  27 + @environment
  28 + end
  29 +
  30 + def limit
  31 + limit = params[:limit].to_i
  32 + limit = default_limit if limit <= 0
  33 + limit
  34 + end
  35 +
  36 + def period(from_date, until_date)
  37 + return nil if from_date.nil? && until_date.nil?
  38 +
  39 + begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date
  40 + end_period = until_date.nil? ? DateTime.now : until_date
  41 +
  42 + begin_period..end_period
  43 + end
  44 +
  45 + def parse_content_type(content_type)
  46 + return nil if content_type.blank?
  47 + content_type.split(',').map do |content_type|
  48 + content_type.camelcase
  49 + end
  50 + end
  51 +
  52 + def find_article(articles, id)
  53 + article = articles.find(id)
  54 + article.display_to?(current_user.person) ? article : forbidden!
  55 + end
  56 +
  57 + def make_conditions_with_parameter(params = {})
  58 + parsed_params = parser_params(params)
  59 + conditions = {}
  60 + from_date = DateTime.parse(parsed_params.delete('from')) if parsed_params['from']
  61 + until_date = DateTime.parse(parsed_params.delete('until')) if parsed_params['until']
  62 +
  63 + conditions[:type] = parse_content_type(parsed_params.delete('content_type')) unless parsed_params['content_type'].nil?
  64 +
  65 + conditions[:created_at] = period(from_date, until_date) if from_date || until_date
  66 + conditions.merge!(parsed_params)
  67 +
  68 + conditions
  69 + end
  70 +
  71 +
  72 + def select_filtered_collection_of(object, method, params)
  73 + conditions = make_conditions_with_parameter(params)
  74 +
  75 + if params[:reference_id]
  76 + objects = object.send(method).send("#{params.key?(:oldest) ? 'older_than' : 'newer_than'}", params[:reference_id]).where(conditions).limit(limit).order("created_at DESC")
  77 + else
  78 + objects = object.send(method).where(conditions).limit(limit).order("created_at DESC")
  79 + end
  80 + objects
  81 + end
  82 +
  83 + def authenticate!
  84 + unauthorized! unless current_user
  85 + end
  86 +
  87 + # Checks the occurrences of uniqueness of attributes, each attribute must be present in the params hash
  88 + # or a Bad Request error is invoked.
  89 + #
  90 + # Parameters:
  91 + # keys (unique) - A hash consisting of keys that must be unique
  92 + def unique_attributes!(obj, keys)
  93 + keys.each do |key|
  94 + cant_be_saved_request!(key) if obj.send("find_by_#{key.to_s}", params[key])
  95 + end
  96 + end
  97 +
  98 + def attributes_for_keys(keys)
  99 + attrs = {}
  100 + keys.each do |key|
  101 + attrs[key] = params[key] if params[key].present? or (params.has_key?(key) and params[key] == false)
  102 + end
  103 + attrs
  104 + end
  105 +
  106 + ##########################################
  107 + # error helpers #
  108 + ##########################################
  109 +
  110 + def forbidden!
  111 + render_api_error!('403 Forbidden', 403)
  112 + end
  113 +
  114 + def cant_be_saved_request!(attribute)
  115 + message = _("(Invalid request) #{attribute} can't be saved")
  116 + render_api_error!(message, 400)
  117 + end
  118 +
  119 + def bad_request!(attribute)
  120 + message = _("(Bad request) #{attribute} not given")
  121 + render_api_error!(message, 400)
  122 + end
  123 +
  124 + def something_wrong!
  125 + message = _("Something wrong happened")
  126 + render_api_error!(message, 400)
  127 + end
  128 +
  129 + def unauthorized!
  130 + render_api_error!(_('Unauthorized'), 401)
  131 + end
  132 +
  133 + def not_allowed!
  134 + render_api_error!(_('Method Not Allowed'), 405)
  135 + end
  136 +
  137 + def render_api_error!(message, status)
  138 + error!({'message' => message, :code => status}, status)
  139 + end
  140 +
  141 + def render_api_errors!(messages)
  142 + render_api_error!(messages.join(','), 400)
  143 + end
  144 + protected
  145 +
  146 + def start_log
  147 + logger.info "Started #{request.path} #{request.params.except('password')}"
  148 + end
  149 + def end_log
  150 + logger.info "Completed #{request.path}"
  151 + end
  152 +
  153 + def setup_multitenancy
  154 + Noosfero::MultiTenancy.setup!(request.host)
  155 + end
  156 +
  157 + def detect_stuff_by_domain
  158 + @domain = Domain.find_by_name(request.host)
  159 + if @domain.nil?
  160 + @environment = Environment.default
  161 + if @environment.nil? && Rails.env.development?
  162 + # This should only happen in development ...
  163 + @environment = Environment.create!(:name => "Noosfero", :is_default => true)
  164 + end
  165 + else
  166 + @environment = @domain.environment
  167 + end
  168 + end
  169 +
  170 + private
  171 +
  172 + def parser_params(params)
  173 + params.select{|k,v| ALLOWED_PARAMETERS.include?(k)}
  174 + end
  175 +
  176 + def default_limit
  177 + 20
  178 + end
  179 +
  180 + def parse_content_type(content_type)
  181 + return nil if content_type.blank?
  182 + content_type.split(',').map do |content_type|
  183 + content_type.camelcase
  184 + end
  185 + end
  186 +
  187 + def period(from_date, until_date)
  188 + begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date
  189 + end_period = until_date.nil? ? DateTime.now : until_date
  190 +
  191 + begin_period..end_period
  192 + end
  193 +
  194 + end
  195 + end
  196 +end
... ...
lib/noosfero/api/session.rb 0 → 100644
... ... @@ -0,0 +1,50 @@
  1 +module Noosfero
  2 + module API
  3 +
  4 + class Session < Grape::API
  5 +
  6 + # Login to get token
  7 + #
  8 + # Parameters:
  9 + # login (*required) - user login or email
  10 + # password (required) - user password
  11 + #
  12 + # Example Request:
  13 + # POST http://localhost:3000/api/v1/login?login=adminuser&password=admin
  14 + post "/login" do
  15 + user ||= User.authenticate(params[:login], params[:password], environment)
  16 +
  17 + return unauthorized! unless user
  18 + user.generate_private_token!
  19 + present user, :with => Entities::UserLogin
  20 + end
  21 +
  22 + # Create user.
  23 + #
  24 + # Parameters:
  25 + # email (required) - Email
  26 + # password (required) - Password
  27 + # login - login
  28 + # Example Request:
  29 + # POST /register?email=some@mail.com&password=pas&login=some
  30 + params do
  31 + requires :email, type: String, desc: _("Email")
  32 + requires :login, type: String, desc: _("Login")
  33 + requires :password, type: String, desc: _("Password")
  34 + end
  35 + post "/register" do
  36 + unique_attributes! User, [:email, :login]
  37 + attrs = attributes_for_keys [:email, :login, :password]
  38 + attrs[:password_confirmation] = attrs[:password]
  39 + user = User.new(attrs)
  40 + if user.save
  41 + user.activate
  42 + present user, :with => Entities::User
  43 + else
  44 + something_wrong!
  45 + end
  46 + end
  47 +
  48 + end
  49 + end
  50 +end
... ...
lib/noosfero/api/v1/articles.rb 0 → 100644
... ... @@ -0,0 +1,169 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class Articles < Grape::API
  5 + before { authenticate! }
  6 +
  7 + ARTICLE_TYPES = Article.descendants.map{|a| a.to_s}
  8 +
  9 + resource :articles do
  10 +
  11 + # Collect articles
  12 + #
  13 + # Parameters:
  14 + # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created
  15 + # oldest - Collect the oldest articles. If nothing is passed the newest articles are collected
  16 + # limit - amount of articles returned. The default value is 20
  17 + #
  18 + # Example Request:
  19 + # GET host/api/v1/articles?from=2013-04-04-14:41:43&until=2015-04-04-14:41:43&limit=10&private_token=e96fff37c2238fdab074d1dcea8e6317
  20 + get do
  21 + articles = select_filtered_collection_of(environment, 'articles', params)
  22 + articles = articles.display_filter(current_person, nil)
  23 + present articles, :with => Entities::Article
  24 + end
  25 +
  26 + desc "Return the article id"
  27 + get ':id' do
  28 + article = find_article(environment.articles, params[:id])
  29 + present article, :with => Entities::Article
  30 + end
  31 +
  32 + get ':id/children' do
  33 + article = find_article(environment.articles, params[:id])
  34 + articles = select_filtered_collection_of(article, 'children', params)
  35 + articles = articles.display_filter(current_person, nil)
  36 + present articles, :with => Entities::Article
  37 + end
  38 +
  39 + get ':id/children/:child_id' do
  40 + article = find_article(environment.articles, params[:id])
  41 + present find_article(article.children, params[:child_id]), :with => Entities::Article
  42 + end
  43 +
  44 + end
  45 +
  46 + resource :communities do
  47 + segment '/:community_id' do
  48 + resource :articles do
  49 + get do
  50 + community = environment.communities.find(params[:community_id])
  51 + articles = select_filtered_collection_of(community, 'articles', params)
  52 + articles = articles.display_filter(current_person, community)
  53 + present articles, :with => Entities::Article
  54 + end
  55 +
  56 + get ':id' do
  57 + community = environment.communities.find(params[:community_id])
  58 + article = find_article(community.articles, params[:id])
  59 + present article, :with => Entities::Article
  60 + end
  61 +
  62 + # Example Request:
  63 + # POST api/v1/communites/:community_id/articles?private_token=234298743290432&article[name]=title&article[body]=body
  64 + post do
  65 + community = environment.communities.find(params[:community_id])
  66 + return forbidden! unless current_person.can_post_content?(community)
  67 +
  68 + klass_type= params[:content_type].nil? ? 'TinyMceArticle' : params[:content_type]
  69 + return forbidden! unless ARTICLE_TYPES.include?(klass_type)
  70 +
  71 + article = klass_type.constantize.new(params[:article])
  72 + article.last_changed_by = current_person
  73 + article.created_by= current_person
  74 + article.profile = community
  75 +
  76 + if !article.save
  77 + render_api_errors!(article.errors.full_messages)
  78 + end
  79 + present article, :with => Entities::Article
  80 + end
  81 +
  82 + end
  83 + end
  84 +
  85 + end
  86 +
  87 + resource :people do
  88 + segment '/:person_id' do
  89 + resource :articles do
  90 + get do
  91 + person = environment.people.find(params[:person_id])
  92 + articles = select_filtered_collection_of(person, 'articles', params)
  93 + articles = articles.display_filter(current_person, person)
  94 + present articles, :with => Entities::Article
  95 + end
  96 +
  97 + get ':id' do
  98 + person = environment.people.find(params[:person_id])
  99 + article = find_article(person.articles, params[:id])
  100 + present article, :with => Entities::Article
  101 + end
  102 +
  103 + post do
  104 + person = environment.people.find(params[:person_id])
  105 + return forbidden! unless current_person.can_post_content?(person)
  106 +
  107 + klass_type= params[:content_type].nil? ? 'TinyMceArticle' : params[:content_type]
  108 + return forbidden! unless ARTICLE_TYPES.include?(klass_type)
  109 +
  110 + article = klass_type.constantize.new(params[:article])
  111 + article.last_changed_by = current_person
  112 + article.created_by= current_person
  113 + article.profile = person
  114 +
  115 + if !article.save
  116 + render_api_errors!(article.errors.full_messages)
  117 + end
  118 + present article, :with => Entities::Article
  119 + end
  120 +
  121 + end
  122 + end
  123 +
  124 + end
  125 +
  126 + resource :enterprises do
  127 + segment '/:enterprise_id' do
  128 + resource :articles do
  129 + get do
  130 + enterprise = environment.enterprises.find(params[:enterprise_id])
  131 + articles = select_filtered_collection_of(enterprise, 'articles', params)
  132 + articles = articles.display_filter(current_person, enterprise)
  133 + present articles, :with => Entities::Article
  134 + end
  135 +
  136 + get ':id' do
  137 + enterprise = environment.enterprises.find(params[:enterprise_id])
  138 + article = find_article(enterprise.articles, params[:id])
  139 + present article, :with => Entities::Article
  140 + end
  141 +
  142 + post do
  143 + enterprise = environment.enterprises.find(params[:enterprise_id])
  144 + return forbidden! unless current_person.can_post_content?(enterprise)
  145 +
  146 + klass_type= params[:content_type].nil? ? 'TinyMceArticle' : params[:content_type]
  147 + return forbidden! unless ARTICLE_TYPES.include?(klass_type)
  148 +
  149 + article = klass_type.constantize.new(params[:article])
  150 + article.last_changed_by = current_person
  151 + article.created_by= current_person
  152 + article.profile = enterprise
  153 +
  154 + if !article.save
  155 + render_api_errors!(article.errors.full_messages)
  156 + end
  157 + present article, :with => Entities::Article
  158 + end
  159 +
  160 + end
  161 + end
  162 +
  163 + end
  164 +
  165 +
  166 + end
  167 + end
  168 + end
  169 +end
... ...
lib/noosfero/api/v1/categories.rb 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class Categories < Grape::API
  5 + before { authenticate! }
  6 +
  7 + resource :categories do
  8 +
  9 + get do
  10 + type = params[:category_type]
  11 + categories = type.nil? ? environment.categories : environment.categories.find(:all, :conditions => {:type => type})
  12 + present categories, :with => Entities::Category
  13 + end
  14 +
  15 + desc "Return the category by id"
  16 + get ':id' do
  17 + present environment.categories.find(params[:id]), :with => Entities::Category
  18 + end
  19 +
  20 + end
  21 +
  22 + end
  23 + end
  24 + end
  25 +end
... ...
lib/noosfero/api/v1/comments.rb 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class Comments < Grape::API
  5 + before { authenticate! }
  6 +
  7 + resource :articles do
  8 + # Collect comments from articles
  9 + #
  10 + # Parameters:
  11 + # reference_id - comment id used as reference to collect comment
  12 + # oldest - Collect the oldest comments from reference_id comment. If nothing is passed the newest comments are collected
  13 + # limit - amount of comments returned. The default value is 20
  14 + #
  15 + # Example Request:
  16 + # GET /articles/12/comments?oldest&limit=10&reference_id=23
  17 + get ":id/comments" do
  18 +
  19 + conditions = make_conditions_with_parameter(params)
  20 + article = find_article(environment.articles, params[:id])
  21 +
  22 + if params[:reference_id]
  23 + comments = article.comments.send("#{params.key?(:oldest) ? 'older_than' : 'newer_than'}", params[:reference_id]).reorder("created_at DESC").find(:all, :conditions => conditions, :limit => limit)
  24 + else
  25 + comments = article.comments.reorder("created_at DESC").find(:all, :conditions => conditions, :limit => limit)
  26 + end
  27 + present comments, :with => Entities::Comment
  28 +
  29 + end
  30 +
  31 + get ":id/comments/:comment_id" do
  32 + article = find_article(environment.articles, params[:id])
  33 + present article.comments.find(params[:comment_id]), :with => Entities::Comment
  34 + end
  35 +
  36 + # Example Request:
  37 + # POST api/v1/articles/12/comments?private_toke=234298743290432&body=new comment
  38 + post ":id/comments" do
  39 + article = find_article(environment.articles, params[:id])
  40 + present article.comments.create(:author => current_person, :body => params[:body]), :with => Entities::Comment
  41 + end
  42 + end
  43 +
  44 + end
  45 + end
  46 + end
  47 +end
... ...
lib/noosfero/api/v1/communities.rb 0 → 100644
... ... @@ -0,0 +1,72 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class Communities < Grape::API
  5 + before { authenticate! }
  6 +
  7 + resource :communities do
  8 +
  9 + # Collect comments from articles
  10 + #
  11 + # Parameters:
  12 + # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created
  13 + # oldest - Collect the oldest comments from reference_id comment. If nothing is passed the newest comments are collected
  14 + # limit - amount of comments returned. The default value is 20
  15 + #
  16 + # Example Request:
  17 + # GET /communities?from=2013-04-04-14:41:43&until=2014-04-04-14:41:43&limit=10
  18 + # GET /communities?reference_id=10&limit=10&oldest
  19 + get do
  20 + communities = select_filtered_collection_of(environment, 'communities', params)
  21 + communities = communities.visible_for_person(current_person)
  22 + present communities, :with => Entities::Community
  23 + end
  24 +
  25 +
  26 + # Example Request:
  27 + # POST api/v1/communties?private_token=234298743290432&community[name]=some_name
  28 + post do
  29 + params[:community] ||= {}
  30 + begin
  31 + community = Community.create_after_moderation(current_person, params[:community].merge({:environment => environment}))
  32 + rescue
  33 + community = Community.new(params[:community])
  34 + end
  35 +
  36 + if !community.save
  37 + render_api_errors!(community.errors.full_messages)
  38 + end
  39 +
  40 + present community, :with => Entities::Community
  41 + end
  42 +
  43 + get ':id' do
  44 + community = environment.communities.visible.find_by_id(params[:id])
  45 + present community, :with => Entities::Community
  46 + end
  47 +
  48 + end
  49 +
  50 + resource :people do
  51 +
  52 + segment '/:person_id' do
  53 +
  54 + resource :communities do
  55 +
  56 + get do
  57 + person = environment.people.find(params[:person_id])
  58 + communities = select_filtered_collection_of(person, 'communities', params)
  59 + communities = communities.visible
  60 + present communities, :with => Entities::Community
  61 + end
  62 +
  63 + end
  64 +
  65 + end
  66 +
  67 + end
  68 +
  69 + end
  70 + end
  71 + end
  72 +end
... ...
lib/noosfero/api/v1/enterprises.rb 0 → 100644
... ... @@ -0,0 +1,56 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class Enterprises < Grape::API
  5 + before { authenticate! }
  6 +
  7 + resource :enterprises do
  8 +
  9 + # Collect comments from articles
  10 + #
  11 + # Parameters:
  12 + # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created
  13 + # oldest - Collect the oldest comments from reference_id comment. If nothing is passed the newest comments are collected
  14 + # limit - amount of comments returned. The default value is 20
  15 + #
  16 + # Example Request:
  17 + # GET /enterprises?from=2013-04-04-14:41:43&until=2014-04-04-14:41:43&limit=10
  18 + # GET /enterprises?reference_id=10&limit=10&oldest
  19 + get do
  20 + enterprises = select_filtered_collection_of(environment, 'enterprises', params)
  21 + enterprises = enterprises.visible_for_person(current_person)
  22 + present enterprises, :with => Entities::Enterprise
  23 + end
  24 +
  25 + desc "Return one enterprise by id"
  26 + get ':id' do
  27 + enterprise = environment.enterprises.visible.find_by_id(params[:id])
  28 + present enterprise, :with => Entities::Enterprise
  29 + end
  30 +
  31 + end
  32 +
  33 + resource :people do
  34 +
  35 + segment '/:person_id' do
  36 +
  37 + resource :enterprises do
  38 +
  39 + get do
  40 + person = environment.people.find(params[:person_id])
  41 + enterprises = select_filtered_collection_of(person, 'enterprises', params)
  42 + enterprises = enterprises.visible
  43 + present enterprises, :with => Entities::Enterprise
  44 + end
  45 +
  46 + end
  47 +
  48 + end
  49 +
  50 + end
  51 +
  52 +
  53 + end
  54 + end
  55 + end
  56 +end
... ...
lib/noosfero/api/v1/people.rb 0 → 100644
... ... @@ -0,0 +1,42 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class People < Grape::API
  5 + before { authenticate! }
  6 +
  7 + resource :people do
  8 +
  9 + # Collect comments from articles
  10 + #
  11 + # Parameters:
  12 + # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created
  13 + # oldest - Collect the oldest comments from reference_id comment. If nothing is passed the newest comments are collected
  14 + # limit - amount of comments returned. The default value is 20
  15 + #
  16 + # Example Request:
  17 + # GET /people?from=2013-04-04-14:41:43&until=2014-04-04-14:41:43&limit=10
  18 + # GET /people?reference_id=10&limit=10&oldest
  19 + get do
  20 + people = select_filtered_collection_of(environment, 'people', params)
  21 + people = people.visible_for_person(current_person)
  22 + present people, :with => Entities::Person
  23 + end
  24 +
  25 + desc "Return the person information"
  26 + get ':id' do
  27 + person = environment.people.visible.find_by_id(params[:id])
  28 + present person, :with => Entities::Person
  29 + end
  30 +
  31 + desc "Return the person friends"
  32 + get ':id/friends' do
  33 + friends = current_person.friends.visible
  34 + present friends, :with => Entities::Person
  35 + end
  36 +
  37 + end
  38 +
  39 + end
  40 + end
  41 + end
  42 +end
... ...
lib/noosfero/api/v1/users.rb 0 → 100644
... ... @@ -0,0 +1,48 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class Users < Grape::API
  5 + before { authenticate! }
  6 +
  7 + resource :users do
  8 +
  9 + #FIXME make the pagination
  10 + #FIXME put it on environment context
  11 + get do
  12 + present environment.users, :with => Entities::User
  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
  26 + end
  27 +
  28 + get ":id" do
  29 + present environment.users.find_by_id(params[:id]), :with => Entities::User
  30 + end
  31 +
  32 + get ":id/permissions" do
  33 + user = environment.users.find(params[:id])
  34 + output = {}
  35 + user.person.role_assignments.map do |role_assigment|
  36 + if role_assigment.resource.respond_to?(:identifier) && role_assigment.resource.identifier == params[:profile]
  37 + output[:permissions] = role_assigment.role.permissions
  38 + end
  39 + end
  40 + present output
  41 + end
  42 +
  43 + end
  44 +
  45 + end
  46 + end
  47 + end
  48 +end
... ...
lib/noosfero/plugin.rb
... ... @@ -141,7 +141,7 @@ class Noosfero::Plugin
141 141 def available_plugin_names
142 142 available_plugins.map { |f| File.basename(f).camelize }
143 143 end
144   -
  144 +
145 145 def all
146 146 @all ||= available_plugins.map{ |dir| (File.basename(dir) + "_plugin").camelize }
147 147 end
... ... @@ -711,7 +711,6 @@ class Noosfero::Plugin
711 711 %w[edit delete spread locale suggest home new upload undo]
712 712 end
713 713  
714   -
715 714 end
716 715  
717 716 require 'noosfero/plugin/hot_spot'
... ...
test/unit/api/articles_test.rb 0 → 100644
... ... @@ -0,0 +1,446 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class ArticlesTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + login_api
  7 + end
  8 +
  9 + should 'list articles' do
  10 + article = fast_create(Article, :profile_id => user.person.id, :name => "Some thing")
  11 + get "/api/v1/articles/?#{params.to_query}"
  12 + json = JSON.parse(last_response.body)
  13 + assert_includes json["articles"].map { |a| a["id"] }, article.id
  14 + end
  15 +
  16 + should 'not list forbidden article when listing articles' do
  17 + person = fast_create(Person)
  18 + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false)
  19 + assert !article.published?
  20 +
  21 + get "/api/v1/articles?#{params.to_query}"
  22 + json = JSON.parse(last_response.body)
  23 + assert_not_includes json['articles'].map {|a| a['id']}, article.id
  24 + end
  25 +
  26 + should 'return article by id' do
  27 + article = fast_create(Article, :profile_id => user.person.id, :name => "Some thing")
  28 + get "/api/v1/articles/#{article.id}?#{params.to_query}"
  29 + json = JSON.parse(last_response.body)
  30 + assert_equal article.id, json["article"]["id"]
  31 + end
  32 +
  33 + should 'not return article if user has no permission to view it' do
  34 + person = fast_create(Person)
  35 + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false)
  36 + assert !article.published?
  37 +
  38 + get "/api/v1/articles/#{article.id}?#{params.to_query}"
  39 + assert_equal 403, last_response.status
  40 + end
  41 +
  42 + should 'list article children' do
  43 + article = fast_create(Article, :profile_id => user.person.id, :name => "Some thing")
  44 + child1 = fast_create(Article, :parent_id => article.id, :profile_id => user.person.id, :name => "Some thing")
  45 + child2 = fast_create(Article, :parent_id => article.id, :profile_id => user.person.id, :name => "Some thing")
  46 + get "/api/v1/articles/#{article.id}/children?#{params.to_query}"
  47 + json = JSON.parse(last_response.body)
  48 + assert_equivalent [child1.id, child2.id], json["articles"].map { |a| a["id"] }
  49 + end
  50 +
  51 + should 'not list children of forbidden article' do
  52 + person = fast_create(Person)
  53 + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false)
  54 + child1 = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing")
  55 + child2 = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing")
  56 + get "/api/v1/articles/#{article.id}/children?#{params.to_query}"
  57 + assert_equal 403, last_response.status
  58 + end
  59 +
  60 + should 'not return child of forbidden article' do
  61 + person = fast_create(Person)
  62 + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false)
  63 + child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing")
  64 + get "/api/v1/articles/#{article.id}/children/#{child.id}?#{params.to_query}"
  65 + assert_equal 403, last_response.status
  66 + end
  67 +
  68 + should 'not return private child' do
  69 + person = fast_create(Person)
  70 + article = fast_create(Article, :profile_id => person.id, :name => "Some thing")
  71 + child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing", :published => false)
  72 + get "/api/v1/articles/#{article.id}/children/#{child.id}?#{params.to_query}"
  73 + assert_equal 403, last_response.status
  74 + end
  75 +
  76 + should 'not list private child' do
  77 + person = fast_create(Person)
  78 + article = fast_create(Article, :profile_id => person.id, :name => "Some thing")
  79 + child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing", :published => false)
  80 + get "/api/v1/articles/#{article.id}/children?#{params.to_query}"
  81 + json = JSON.parse(last_response.body)
  82 + assert_not_includes json['articles'].map {|a| a['id']}, child.id
  83 + end
  84 +
  85 + #############################
  86 + # Community Articles #
  87 + #############################
  88 +
  89 + should 'return article by community' do
  90 + community = fast_create(Community)
  91 + article = fast_create(Article, :profile_id => community.id, :name => "Some thing")
  92 + get "/api/v1/communities/#{community.id}/articles/#{article.id}?#{params.to_query}"
  93 + json = JSON.parse(last_response.body)
  94 + assert_equal article.id, json["article"]["id"]
  95 + end
  96 +
  97 + should 'not return article by community if user has no permission to view it' do
  98 + community = fast_create(Community)
  99 + article = fast_create(Article, :profile_id => community.id, :name => "Some thing", :published => false)
  100 + assert !article.published?
  101 +
  102 + get "/api/v1/communities/#{community.id}/articles/#{article.id}?#{params.to_query}"
  103 + assert_equal 403, last_response.status
  104 + end
  105 +
  106 + should 'not list forbidden article when listing articles by community' do
  107 + community = fast_create(Community)
  108 + article = fast_create(Article, :profile_id => community.id, :name => "Some thing", :published => false)
  109 + assert !article.published?
  110 +
  111 + get "/api/v1/communities/#{community.id}/articles?#{params.to_query}"
  112 + json = JSON.parse(last_response.body)
  113 + assert_not_includes json['articles'].map {|a| a['id']}, article.id
  114 + end
  115 +
  116 + should 'create article in a community' do
  117 + community = fast_create(Community)
  118 + give_permission(user.person, 'post_content', community)
  119 + params[:article] = {:name => "Title"}
  120 + post "/api/v1/communities/#{community.id}/articles?#{params.to_query}"
  121 + json = JSON.parse(last_response.body)
  122 + assert_equal "Title", json["article"]["title"]
  123 + end
  124 +
  125 + should 'do not create article if user has no permission to post content' do
  126 + community = fast_create(Community)
  127 + give_permission(user.person, 'invite_members', community)
  128 + params[:article] = {:name => "Title"}
  129 + post "/api/v1/communities/#{community.id}/articles?#{params.to_query}"
  130 + assert_equal 403, last_response.status
  131 + end
  132 +
  133 + should 'create article with parent' do
  134 + community = fast_create(Community)
  135 + community.add_member(user.person)
  136 + article = fast_create(Article)
  137 +
  138 + params[:article] = {:name => "Title", :parent_id => article.id}
  139 + post "/api/v1/communities/#{community.id}/articles?#{params.to_query}"
  140 + json = JSON.parse(last_response.body)
  141 + assert_equal article.id, json["article"]["parent"]["id"]
  142 + end
  143 +
  144 + should 'create article with content type passed as parameter' do
  145 + community = fast_create(Community)
  146 + community.add_member(user.person)
  147 +
  148 + Article.delete_all
  149 + params[:article] = {:name => "Title"}
  150 + params[:content_type] = 'TextArticle'
  151 + post "/api/v1/communities/#{community.id}/articles?#{params.to_query}"
  152 + json = JSON.parse(last_response.body)
  153 +
  154 + assert_kind_of TextArticle, Article.last
  155 + end
  156 +
  157 + should 'create article of TinyMceArticle type if no content type is passed as parameter' do
  158 + community = fast_create(Community)
  159 + community.add_member(user.person)
  160 +
  161 + params[:article] = {:name => "Title"}
  162 + post "/api/v1/communities/#{community.id}/articles?#{params.to_query}"
  163 + json = JSON.parse(last_response.body)
  164 +
  165 + assert_kind_of TinyMceArticle, Article.last
  166 + end
  167 +
  168 + should 'not create article with invalid article content type' do
  169 + community = fast_create(Community)
  170 + community.add_member(user.person)
  171 +
  172 + params[:article] = {:name => "Title"}
  173 + params[:content_type] = 'Person'
  174 + post "/api/v1/communities/#{community.id}/articles?#{params.to_query}"
  175 + json = JSON.parse(last_response.body)
  176 +
  177 + assert_equal 403, last_response.status
  178 + end
  179 +
  180 + should 'create article defining the correct profile' do
  181 + community = fast_create(Community)
  182 + community.add_member(user.person)
  183 +
  184 + params[:article] = {:name => "Title"}
  185 + post "/api/v1/communities/#{community.id}/articles?#{params.to_query}"
  186 + json = JSON.parse(last_response.body)
  187 +
  188 + assert_equal community, Article.last.profile
  189 + end
  190 +
  191 + should 'create article defining the created_by' do
  192 + community = fast_create(Community)
  193 + community.add_member(user.person)
  194 +
  195 + params[:article] = {:name => "Title"}
  196 + post "/api/v1/communities/#{community.id}/articles?#{params.to_query}"
  197 + json = JSON.parse(last_response.body)
  198 +
  199 + assert_equal user.person, Article.last.created_by
  200 + end
  201 +
  202 + should 'create article defining the last_changed_by' do
  203 + community = fast_create(Community)
  204 + community.add_member(user.person)
  205 +
  206 + params[:article] = {:name => "Title"}
  207 + post "/api/v1/communities/#{community.id}/articles?#{params.to_query}"
  208 + json = JSON.parse(last_response.body)
  209 +
  210 + assert_equal user.person, Article.last.last_changed_by
  211 + end
  212 +
  213 + #############################
  214 + # Person Articles #
  215 + #############################
  216 +
  217 + should 'return article by person' do
  218 + person = fast_create(Person)
  219 + article = fast_create(Article, :profile_id => person.id, :name => "Some thing")
  220 + get "/api/v1/people/#{person.id}/articles/#{article.id}?#{params.to_query}"
  221 + json = JSON.parse(last_response.body)
  222 + assert_equal article.id, json["article"]["id"]
  223 + end
  224 +
  225 + should 'not return article by person if user has no permission to view it' do
  226 + person = fast_create(Person)
  227 + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false)
  228 + assert !article.published?
  229 +
  230 + get "/api/v1/people/#{person.id}/articles/#{article.id}?#{params.to_query}"
  231 + assert_equal 403, last_response.status
  232 + end
  233 +
  234 + should 'not list forbidden article when listing articles by person' do
  235 + person = fast_create(Person)
  236 + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false)
  237 + assert !article.published?
  238 + get "/api/v1/people/#{person.id}/articles?#{params.to_query}"
  239 + json = JSON.parse(last_response.body)
  240 + assert_not_includes json['articles'].map {|a| a['id']}, article.id
  241 + end
  242 +
  243 + should 'create article in a person' do
  244 + params[:article] = {:name => "Title"}
  245 + post "/api/v1/people/#{user.person.id}/articles?#{params.to_query}"
  246 + json = JSON.parse(last_response.body)
  247 + assert_equal "Title", json["article"]["title"]
  248 + end
  249 +
  250 + should 'person do not create article if user has no permission to post content' do
  251 + person = fast_create(Person)
  252 + params[:article] = {:name => "Title"}
  253 + post "/api/v1/people/#{person.id}/articles?#{params.to_query}"
  254 + assert_equal 403, last_response.status
  255 + end
  256 +
  257 + should 'person create article with parent' do
  258 + article = fast_create(Article)
  259 +
  260 + params[:article] = {:name => "Title", :parent_id => article.id}
  261 + post "/api/v1/people/#{user.person.id}/articles?#{params.to_query}"
  262 + json = JSON.parse(last_response.body)
  263 + assert_equal article.id, json["article"]["parent"]["id"]
  264 + end
  265 +
  266 + should 'person create article with content type passed as parameter' do
  267 + Article.delete_all
  268 + params[:article] = {:name => "Title"}
  269 + params[:content_type] = 'TextArticle'
  270 + post "/api/v1/people/#{user.person.id}/articles?#{params.to_query}"
  271 + json = JSON.parse(last_response.body)
  272 +
  273 + assert_kind_of TextArticle, Article.last
  274 + end
  275 +
  276 + should 'person create article of TinyMceArticle type if no content type is passed as parameter' do
  277 + params[:article] = {:name => "Title"}
  278 + post "/api/v1/people/#{user.person.id}/articles?#{params.to_query}"
  279 + json = JSON.parse(last_response.body)
  280 +
  281 + assert_kind_of TinyMceArticle, Article.last
  282 + end
  283 +
  284 + should 'person not create article with invalid article content type' do
  285 + params[:article] = {:name => "Title"}
  286 + params[:content_type] = 'Person'
  287 + post "/api/v1/people/#{user.person.id}/articles?#{params.to_query}"
  288 + json = JSON.parse(last_response.body)
  289 +
  290 + assert_equal 403, last_response.status
  291 + end
  292 +
  293 + should 'person create article defining the correct profile' do
  294 + params[:article] = {:name => "Title"}
  295 + post "/api/v1/people/#{user.person.id}/articles?#{params.to_query}"
  296 + json = JSON.parse(last_response.body)
  297 +
  298 + assert_equal user.person, Article.last.profile
  299 + end
  300 +
  301 + should 'person create article defining the created_by' do
  302 + params[:article] = {:name => "Title"}
  303 + post "/api/v1/people/#{user.person.id}/articles?#{params.to_query}"
  304 + json = JSON.parse(last_response.body)
  305 +
  306 + assert_equal user.person, Article.last.created_by
  307 + end
  308 +
  309 + should 'person create article defining the last_changed_by' do
  310 + params[:article] = {:name => "Title"}
  311 + post "/api/v1/people/#{user.person.id}/articles?#{params.to_query}"
  312 + json = JSON.parse(last_response.body)
  313 +
  314 + assert_equal user.person, Article.last.last_changed_by
  315 + end
  316 +
  317 + #############################
  318 + # Enterprise Articles #
  319 + #############################
  320 +
  321 + should 'return article by enterprise' do
  322 + enterprise = fast_create(Enterprise)
  323 + article = fast_create(Article, :profile_id => enterprise.id, :name => "Some thing")
  324 + get "/api/v1/enterprises/#{enterprise.id}/articles/#{article.id}?#{params.to_query}"
  325 + json = JSON.parse(last_response.body)
  326 + assert_equal article.id, json["article"]["id"]
  327 + end
  328 +
  329 + should 'not return article by enterprise if user has no permission to view it' do
  330 + enterprise = fast_create(Enterprise)
  331 + article = fast_create(Article, :profile_id => enterprise.id, :name => "Some thing", :published => false)
  332 + assert !article.published?
  333 +
  334 + get "/api/v1/enterprises/#{enterprise.id}/articles/#{article.id}?#{params.to_query}"
  335 + assert_equal 403, last_response.status
  336 + end
  337 +
  338 + should 'not list forbidden article when listing articles by enterprise' do
  339 + enterprise = fast_create(Enterprise)
  340 + article = fast_create(Article, :profile_id => enterprise.id, :name => "Some thing", :published => false)
  341 + assert !article.published?
  342 +
  343 + get "/api/v1/enterprises/#{enterprise.id}/articles?#{params.to_query}"
  344 + json = JSON.parse(last_response.body)
  345 + assert_not_includes json['articles'].map {|a| a['id']}, article.id
  346 + end
  347 +
  348 + should 'create article in a enterprise' do
  349 + enterprise = fast_create(Enterprise)
  350 + give_permission(user.person, 'post_content', enterprise)
  351 + params[:article] = {:name => "Title"}
  352 + post "/api/v1/enterprises/#{enterprise.id}/articles?#{params.to_query}"
  353 + json = JSON.parse(last_response.body)
  354 + assert_equal "Title", json["article"]["title"]
  355 + end
  356 +
  357 + should 'enterprise: do not create article if user has no permission to post content' do
  358 + enterprise = fast_create(Enterprise)
  359 + give_permission(user.person, 'invite_members', enterprise)
  360 + params[:article] = {:name => "Title"}
  361 + post "/api/v1/enterprises/#{enterprise.id}/articles?#{params.to_query}"
  362 + assert_equal 403, last_response.status
  363 + end
  364 +
  365 + should 'enterprise: create article with parent' do
  366 + enterprise = fast_create(Enterprise)
  367 + enterprise.add_member(user.person)
  368 + article = fast_create(Article)
  369 +
  370 + params[:article] = {:name => "Title", :parent_id => article.id}
  371 + post "/api/v1/enterprises/#{enterprise.id}/articles?#{params.to_query}"
  372 + json = JSON.parse(last_response.body)
  373 + assert_equal article.id, json["article"]["parent"]["id"]
  374 + end
  375 +
  376 + should 'enterprise: create article with content type passed as parameter' do
  377 + enterprise = fast_create(Enterprise)
  378 + enterprise.add_member(user.person)
  379 +
  380 + Article.delete_all
  381 + params[:article] = {:name => "Title"}
  382 + params[:content_type] = 'TextArticle'
  383 + post "/api/v1/enterprises/#{enterprise.id}/articles?#{params.to_query}"
  384 + json = JSON.parse(last_response.body)
  385 +
  386 + assert_kind_of TextArticle, Article.last
  387 + end
  388 +
  389 + should 'enterprise: create article of TinyMceArticle type if no content type is passed as parameter' do
  390 + enterprise = fast_create(Enterprise)
  391 + enterprise.add_member(user.person)
  392 +
  393 + params[:article] = {:name => "Title"}
  394 + post "/api/v1/enterprises/#{enterprise.id}/articles?#{params.to_query}"
  395 + json = JSON.parse(last_response.body)
  396 +
  397 + assert_kind_of TinyMceArticle, Article.last
  398 + end
  399 +
  400 + should 'enterprise: not create article with invalid article content type' do
  401 + enterprise = fast_create(Enterprise)
  402 + enterprise.add_member(user.person)
  403 +
  404 + params[:article] = {:name => "Title"}
  405 + params[:content_type] = 'Person'
  406 + post "/api/v1/enterprises/#{enterprise.id}/articles?#{params.to_query}"
  407 + json = JSON.parse(last_response.body)
  408 +
  409 + assert_equal 403, last_response.status
  410 + end
  411 +
  412 + should 'enterprise: create article defining the correct profile' do
  413 + enterprise = fast_create(Enterprise)
  414 + enterprise.add_member(user.person)
  415 +
  416 + params[:article] = {:name => "Title"}
  417 + post "/api/v1/enterprises/#{enterprise.id}/articles?#{params.to_query}"
  418 + json = JSON.parse(last_response.body)
  419 +
  420 + assert_equal enterprise, Article.last.profile
  421 + end
  422 +
  423 + should 'enterprise: create article defining the created_by' do
  424 + enterprise = fast_create(Enterprise)
  425 + enterprise.add_member(user.person)
  426 +
  427 + params[:article] = {:name => "Title"}
  428 + post "/api/v1/enterprises/#{enterprise.id}/articles?#{params.to_query}"
  429 + json = JSON.parse(last_response.body)
  430 +
  431 + assert_equal user.person, Article.last.created_by
  432 + end
  433 +
  434 + should 'enterprise: create article defining the last_changed_by' do
  435 + enterprise = fast_create(Enterprise)
  436 + enterprise.add_member(user.person)
  437 +
  438 + params[:article] = {:name => "Title"}
  439 + post "/api/v1/enterprises/#{enterprise.id}/articles?#{params.to_query}"
  440 + json = JSON.parse(last_response.body)
  441 +
  442 + assert_equal user.person, Article.last.last_changed_by
  443 + end
  444 +
  445 +
  446 +end
... ...
test/unit/api/categories_test.rb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class CategoriesTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + login_api
  7 + end
  8 +
  9 + should 'list categories' do
  10 + category = fast_create(Category)
  11 + get "/api/v1/categories/?#{params.to_query}"
  12 + json = JSON.parse(last_response.body)
  13 + assert_includes json["categories"].map { |c| c["name"] }, category.name
  14 + end
  15 +
  16 + should 'get category by id' do
  17 + category = fast_create(Category)
  18 + get "/api/v1/categories/#{category.id}/?#{params.to_query}"
  19 + json = JSON.parse(last_response.body)
  20 + assert_equal category.name, json["category"]["name"]
  21 + end
  22 +
  23 +end
... ...
test/unit/api/comments_test.rb 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class CommentsTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + login_api
  7 + end
  8 +
  9 + should 'not list comments if user has no permission to view the source article' do
  10 + person = fast_create(Person)
  11 + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false)
  12 + assert !article.published?
  13 +
  14 + get "/api/v1/articles/#{article.id}/comments?#{params.to_query}"
  15 + assert_equal 403, last_response.status
  16 + end
  17 +
  18 + should 'not return comment if user has no permission to view the source article' do
  19 + person = fast_create(Person)
  20 + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false)
  21 + comment = article.comments.create!(:body => "another comment", :author => user.person)
  22 + assert !article.published?
  23 +
  24 + get "/api/v1/articles/#{article.id}/comments/#{comment.id}?#{params.to_query}"
  25 + assert_equal 403, last_response.status
  26 + end
  27 +
  28 + should 'not comment a article if user has no permission to view it' do
  29 + person = fast_create(Person)
  30 + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false)
  31 + assert !article.published?
  32 +
  33 + post "/api/v1/articles/#{article.id}/comments?#{params.to_query}"
  34 + assert_equal 403, last_response.status
  35 + end
  36 +
  37 + should 'return comments of an article' do
  38 + article = fast_create(Article, :profile_id => user.person.id, :name => "Some thing")
  39 + article.comments.create!(:body => "some comment", :author => user.person)
  40 + article.comments.create!(:body => "another comment", :author => user.person)
  41 +
  42 + get "/api/v1/articles/#{article.id}/comments?#{params.to_query}"
  43 + json = JSON.parse(last_response.body)
  44 + assert_equal 2, json["comments"].length
  45 + end
  46 +
  47 +end
... ...
test/unit/api/communities_test.rb 0 → 100644
... ... @@ -0,0 +1,114 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class CommunitiesTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + Community.delete_all
  7 + login_api
  8 + end
  9 +
  10 + should 'list all communities' do
  11 + community1 = fast_create(Community, :public_profile => true)
  12 + community2 = fast_create(Community)
  13 + get "/api/v1/communities?#{params.to_query}"
  14 + json = JSON.parse(last_response.body)
  15 + assert_equivalent [community1.id, community2.id], json['communities'].map {|c| c['id']}
  16 + end
  17 +
  18 + should 'not list invisible communities' do
  19 + community1 = fast_create(Community)
  20 + fast_create(Community, :visible => false)
  21 +
  22 + get "/api/v1/communities?#{params.to_query}"
  23 + json = JSON.parse(last_response.body)
  24 + assert_equal [community1.id], json['communities'].map {|c| c['id']}
  25 + end
  26 +
  27 + should 'not list private communities without permission' do
  28 + community1 = fast_create(Community)
  29 + fast_create(Community, :public_profile => false)
  30 +
  31 + get "/api/v1/communities?#{params.to_query}"
  32 + json = JSON.parse(last_response.body)
  33 + assert_equal [community1.id], json['communities'].map {|c| c['id']}
  34 + end
  35 +
  36 + should 'list private community for members' do
  37 + c1 = fast_create(Community)
  38 + c2 = fast_create(Community, :public_profile => false)
  39 + c2.add_member(person)
  40 +
  41 + get "/api/v1/communities?#{params.to_query}"
  42 + json = JSON.parse(last_response.body)
  43 + assert_equivalent [c1.id, c2.id], json['communities'].map {|c| c['id']}
  44 + end
  45 +
  46 + should 'create a community' do
  47 + params[:community] = {:name => 'some'}
  48 + post "/api/v1/communities?#{params.to_query}"
  49 + json = JSON.parse(last_response.body)
  50 + assert_equal 'some', json['community']['name']
  51 + end
  52 +
  53 + should 'return 400 status for invalid community creation' do
  54 + post "/api/v1/communities?#{params.to_query}"
  55 + json = JSON.parse(last_response.body)
  56 + assert_equal 400, last_response.status
  57 + end
  58 +
  59 + should 'get community' do
  60 + community = fast_create(Community)
  61 +
  62 + get "/api/v1/communities/#{community.id}?#{params.to_query}"
  63 + json = JSON.parse(last_response.body)
  64 + assert_equal community.id, json['community']['id']
  65 + end
  66 +
  67 + should 'not get invisible community' do
  68 + community = fast_create(Community, :visible => false)
  69 +
  70 + get "/api/v1/communities/#{community.id}?#{params.to_query}"
  71 + json = JSON.parse(last_response.body)
  72 + assert json['community'].blank?
  73 + end
  74 +
  75 + should 'not get private communities without permission' do
  76 + community = fast_create(Community)
  77 + fast_create(Community, :public_profile => false)
  78 +
  79 + get "/api/v1/communities/#{community.id}?#{params.to_query}"
  80 + json = JSON.parse(last_response.body)
  81 + assert_equal community.id, json['community']['id']
  82 + end
  83 +
  84 + should 'get private community for members' do
  85 + community = fast_create(Community, :public_profile => false)
  86 + community.add_member(person)
  87 +
  88 + get "/api/v1/communities/#{community.id}?#{params.to_query}"
  89 + json = JSON.parse(last_response.body)
  90 + assert_equal community.id, json['community']['id']
  91 + end
  92 +
  93 + should 'list person communities' do
  94 + community = fast_create(Community)
  95 + fast_create(Community)
  96 + community.add_member(person)
  97 +
  98 + get "/api/v1/people/#{person.id}/communities?#{params.to_query}"
  99 + json = JSON.parse(last_response.body)
  100 + assert_equivalent [community.id], json['communities'].map {|c| c['id']}
  101 + end
  102 +
  103 + should 'not list person communities invisible' do
  104 + c1 = fast_create(Community)
  105 + c2 = fast_create(Community, :visible => false)
  106 + c1.add_member(person)
  107 + c2.add_member(person)
  108 +
  109 + get "/api/v1/people/#{person.id}/communities?#{params.to_query}"
  110 + json = JSON.parse(last_response.body)
  111 + assert_equivalent [c1.id], json['communities'].map {|c| c['id']}
  112 + end
  113 +
  114 +end
... ...
test/unit/api/enterprises_test.rb 0 → 100644
... ... @@ -0,0 +1,101 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class EnterprisesTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + Enterprise.delete_all
  7 + login_api
  8 + end
  9 +
  10 + should 'list all enterprises' do
  11 + enterprise1 = fast_create(Enterprise, :public_profile => true)
  12 + enterprise2 = fast_create(Enterprise)
  13 + get "/api/v1/enterprises?#{params.to_query}"
  14 + json = JSON.parse(last_response.body)
  15 + assert_equivalent [enterprise1.id, enterprise2.id], json['enterprises'].map {|c| c['id']}
  16 + end
  17 +
  18 + should 'not list invisible enterprises' do
  19 + enterprise1 = fast_create(Enterprise)
  20 + fast_create(Enterprise, :visible => false)
  21 +
  22 + get "/api/v1/enterprises?#{params.to_query}"
  23 + json = JSON.parse(last_response.body)
  24 + assert_equal [enterprise1.id], json['enterprises'].map {|c| c['id']}
  25 + end
  26 +
  27 + should 'not list private enterprises without permission' do
  28 + enterprise1 = fast_create(Enterprise)
  29 + fast_create(Enterprise, :public_profile => false)
  30 +
  31 + get "/api/v1/enterprises?#{params.to_query}"
  32 + json = JSON.parse(last_response.body)
  33 + assert_equal [enterprise1.id], json['enterprises'].map {|c| c['id']}
  34 + end
  35 +
  36 + should 'list private enterprise for members' do
  37 + c1 = fast_create(Enterprise)
  38 + c2 = fast_create(Enterprise, :public_profile => false)
  39 + c2.add_member(person)
  40 +
  41 + get "/api/v1/enterprises?#{params.to_query}"
  42 + json = JSON.parse(last_response.body)
  43 + assert_equivalent [c1.id, c2.id], json['enterprises'].map {|c| c['id']}
  44 + end
  45 +
  46 + should 'get enterprise' do
  47 + enterprise = fast_create(Enterprise)
  48 +
  49 + get "/api/v1/enterprises/#{enterprise.id}?#{params.to_query}"
  50 + json = JSON.parse(last_response.body)
  51 + assert_equal enterprise.id, json['enterprise']['id']
  52 + end
  53 +
  54 + should 'not get invisible enterprise' do
  55 + enterprise = fast_create(Enterprise, :visible => false)
  56 +
  57 + get "/api/v1/enterprises/#{enterprise.id}?#{params.to_query}"
  58 + json = JSON.parse(last_response.body)
  59 + assert json['enterprise'].blank?
  60 + end
  61 +
  62 + should 'not get private enterprises without permission' do
  63 + enterprise = fast_create(Enterprise)
  64 + fast_create(Enterprise, :public_profile => false)
  65 +
  66 + get "/api/v1/enterprises/#{enterprise.id}?#{params.to_query}"
  67 + json = JSON.parse(last_response.body)
  68 + assert_equal enterprise.id, json['enterprise']['id']
  69 + end
  70 +
  71 + should 'get private enterprise for members' do
  72 + enterprise = fast_create(Enterprise, :public_profile => false)
  73 + enterprise.add_member(person)
  74 +
  75 + get "/api/v1/enterprises/#{enterprise.id}?#{params.to_query}"
  76 + json = JSON.parse(last_response.body)
  77 + assert_equal enterprise.id, json['enterprise']['id']
  78 + end
  79 +
  80 + should 'list person enterprises' do
  81 + enterprise = fast_create(Enterprise)
  82 + fast_create(Enterprise)
  83 + enterprise.add_member(person)
  84 +
  85 + get "/api/v1/people/#{person.id}/enterprises?#{params.to_query}"
  86 + json = JSON.parse(last_response.body)
  87 + assert_equivalent [enterprise.id], json['enterprises'].map {|c| c['id']}
  88 + end
  89 +
  90 + should 'not list person enterprises invisible' do
  91 + c1 = fast_create(Enterprise)
  92 + c2 = fast_create(Enterprise, :visible => false)
  93 + c1.add_member(person)
  94 + c2.add_member(person)
  95 +
  96 + get "/api/v1/people/#{person.id}/enterprises?#{params.to_query}"
  97 + json = JSON.parse(last_response.body)
  98 + assert_equivalent [c1.id], json['enterprises'].map {|c| c['id']}
  99 + end
  100 +
  101 +end
... ...
test/unit/api/helpers_test.rb 0 → 100644
... ... @@ -0,0 +1,157 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +require File.expand_path(File.dirname(__FILE__) + "/../../../lib/noosfero/api/helpers")
  3 +
  4 +class APITest < ActiveSupport::TestCase
  5 +
  6 + include Noosfero::API::APIHelpers
  7 +
  8 + should 'get the current user with valid token' do
  9 + user = create_user('someuser')
  10 + user.generate_private_token!
  11 + self.params = {:private_token => user.private_token}
  12 + assert_equal user, current_user
  13 + end
  14 +
  15 + should 'not get the current user with expired token' do
  16 + user = create_user('someuser')
  17 + user.generate_private_token!
  18 + user.private_token_generated_at = DateTime.now.prev_year
  19 + user.save
  20 + self.params = {:private_token => user.private_token}
  21 + assert_nil current_user
  22 + end
  23 +
  24 + should 'get the person of current user' do
  25 + user = create_user('someuser')
  26 + user.generate_private_token!
  27 + self.params = {:private_token => user.private_token}
  28 + assert_equal user.person, current_person
  29 + end
  30 +
  31 +# #FIXME see how to make this test. Get the current_user variable
  32 +# should 'set current_user to nil after logout' do
  33 +# user = create_user('someuser')
  34 +# user.stubs(:private_token_expired?).returns(false)
  35 +# User.stubs(:find_by_private_token).returns(user)
  36 +# assert_not_nil current_user
  37 +# assert false
  38 +# logout
  39 +# end
  40 +
  41 + should 'limit be defined as the params limit value' do
  42 + local_limit = 30
  43 + self.params= {:limit => local_limit}
  44 + assert_equal local_limit, limit
  45 + end
  46 +
  47 + should 'return default limit if the limit parameter is minor than zero' do
  48 + self.params= {:limit => -1}
  49 + assert_equal 20, limit
  50 + end
  51 +
  52 + should 'the default limit be 20' do
  53 + assert_equal 20, limit
  54 + end
  55 +
  56 + should 'the beginning of the period be the first existent date if no from date is passsed as parameter' do
  57 + assert_equal Time.at(0).to_datetime, period(nil, nil).to_a[0]
  58 + end
  59 +
  60 + should 'the beginning of the period be from date passsed as parameter' do
  61 + from = DateTime.now
  62 + assert_equal from, period(from, nil).min
  63 + end
  64 +
  65 + should 'the end of the period be now if no until date is passsed as parameter' do
  66 + assert_in_delta DateTime.now, period(nil, nil).max
  67 + end
  68 +
  69 + should 'the end of the period be until date passsed as parameter' do
  70 + until_date = DateTime.now
  71 + assert_equal until_date, period(nil, until_date).max
  72 + end
  73 +
  74 + should 'parse_content_type return nil if its blank' do
  75 + assert_nil parse_content_type("")
  76 + end
  77 +
  78 + should 'parse_content_type be an array' do
  79 + assert_kind_of Array, parse_content_type("text_article")
  80 + end
  81 +
  82 + should 'parse_content_type return all content types as an array' do
  83 + assert_equivalent ['TextArticle','TinyMceArticle'], parse_content_type("TextArticle,TinyMceArticle")
  84 + end
  85 +
  86 + should 'find_article return article by id in list passed for user with permission' do
  87 + user = create_user('someuser')
  88 + a = fast_create(Article, :profile_id => user.person.id)
  89 + fast_create(Article, :profile_id => user.person.id)
  90 + fast_create(Article, :profile_id => user.person.id)
  91 +
  92 + user.generate_private_token!
  93 + User.expects(:find_by_private_token).returns(user)
  94 + assert_equal a, find_article(user.person.articles, a.id)
  95 + end
  96 +
  97 + should 'find_article return forbidden when a user try to access an article without permission' do
  98 + user = create_user('someuser')
  99 + p = fast_create(Profile)
  100 + a = fast_create(Article, :published => false, :profile_id => p.id)
  101 + fast_create(Article, :profile_id => p.id)
  102 +
  103 + user.generate_private_token!
  104 + User.expects(:find_by_private_token).returns(user)
  105 + assert_equal 403, find_article(p.articles, a.id).last
  106 + end
  107 +
  108 + should 'make_conditions_with_parameter return no created at parameter if it was not defined from or until parameters' do
  109 + assert_nil make_conditions_with_parameter[:created_at]
  110 + end
  111 +
  112 + should 'make_conditions_with_parameter return created_at parameter if from period is defined' do
  113 + assert_not_nil make_conditions_with_parameter(:from => '2010-10-10')[:created_at]
  114 + end
  115 +
  116 + should 'make_conditions_with_parameter return created_at parameter if until period is defined' do
  117 + assert_not_nil make_conditions_with_parameter(:until => '2010-10-10')[:created_at]
  118 + end
  119 +
  120 +# should 'the beginning of the period be the first existent date if no from date is passsed as parameter' do
  121 + should 'make_conditions_with_parameter return created_at as the first existent date as parameter if only until is defined' do
  122 + assert_equal Time.at(0).to_datetime, make_conditions_with_parameter(:until => '2010-10-10')[:created_at].min
  123 + end
  124 +
  125 + should 'make_conditions_with_parameter: the minimal created_at date be the from date passed as parameter' do
  126 + date = '2010-10-10'
  127 + assert_equal DateTime.parse(date), make_conditions_with_parameter(:from => date)[:created_at].min
  128 + end
  129 +
  130 + should 'make_conditions_with_parameter: the maximum created_at date be the until date passed as parameter' do
  131 + date = '2010-10-10'
  132 + assert_equal DateTime.parse(date), make_conditions_with_parameter(:until => date)[:created_at].max
  133 + end
  134 +
  135 + should 'make_conditions_with_parameter return the until date passed as parameter' do
  136 + date = '2010-10-10'
  137 + assert_equal DateTime.parse(date), make_conditions_with_parameter(:from => '2010-10-10')[:created_at].min
  138 + end
  139 +
  140 + should 'make_conditions_with_parameter return no type parameter if it was not defined any content type' do
  141 + assert_nil make_conditions_with_parameter[:type]
  142 + end
  143 +
  144 + protected
  145 +
  146 + def error!(info, status)
  147 + [info, status]
  148 + end
  149 +
  150 + def params
  151 + @params ||= {}
  152 + end
  153 +
  154 + def params= value
  155 + @params = value
  156 + end
  157 +end
... ...
test/unit/api/people_test.rb 0 → 100644
... ... @@ -0,0 +1,102 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class PeopleTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + Person.delete_all
  7 + login_api
  8 + end
  9 +
  10 + should 'list all people' do
  11 + person1 = fast_create(Person, :public_profile => true)
  12 + person2 = fast_create(Person)
  13 + get "/api/v1/people?#{params.to_query}"
  14 + json = JSON.parse(last_response.body)
  15 + assert_equivalent [person1.id, person2.id, person.id], json['people'].map {|c| c['id']}
  16 + end
  17 +
  18 + should 'not list invisible people' do
  19 + person1 = fast_create(Person)
  20 + fast_create(Person, :visible => false)
  21 +
  22 + get "/api/v1/people?#{params.to_query}"
  23 + json = JSON.parse(last_response.body)
  24 + assert_equivalent [person1.id, person.id], json['people'].map {|c| c['id']}
  25 + end
  26 +
  27 + should 'not list private people without permission' do
  28 + person1 = fast_create(Person)
  29 + fast_create(Person, :public_profile => false)
  30 +
  31 + get "/api/v1/people?#{params.to_query}"
  32 + json = JSON.parse(last_response.body)
  33 + assert_equivalent [person1.id, person.id], json['people'].map {|c| c['id']}
  34 + end
  35 +
  36 + should 'list private person for friends' do
  37 + p1 = fast_create(Person)
  38 + p2 = fast_create(Person, :public_profile => false)
  39 + person.add_friend(p2)
  40 + p2.add_friend(person)
  41 +
  42 + get "/api/v1/people?#{params.to_query}"
  43 + json = JSON.parse(last_response.body)
  44 + assert_equivalent [p1.id, p2.id, person.id], json['people'].map {|c| c['id']}
  45 + end
  46 +
  47 + should 'get person' do
  48 + person = fast_create(Person)
  49 +
  50 + get "/api/v1/people/#{person.id}?#{params.to_query}"
  51 + json = JSON.parse(last_response.body)
  52 + assert_equal person.id, json['person']['id']
  53 + end
  54 +
  55 + should 'not get invisible person' do
  56 + person = fast_create(Person, :visible => false)
  57 +
  58 + get "/api/v1/people/#{person.id}?#{params.to_query}"
  59 + json = JSON.parse(last_response.body)
  60 + assert json['person'].blank?
  61 + end
  62 +
  63 + should 'not get private people without permission' do
  64 + person = fast_create(Person)
  65 + fast_create(Person, :public_profile => false)
  66 +
  67 + get "/api/v1/people/#{person.id}?#{params.to_query}"
  68 + json = JSON.parse(last_response.body)
  69 + assert_equal person.id, json['person']['id']
  70 + end
  71 +
  72 + should 'get private person for friends' do
  73 + person = fast_create(Person, :public_profile => false)
  74 + person.add_friend(person)
  75 +
  76 + get "/api/v1/people/#{person.id}?#{params.to_query}"
  77 + json = JSON.parse(last_response.body)
  78 + assert_equal person.id, json['person']['id']
  79 + end
  80 +
  81 + should 'list person friends' do
  82 + p = fast_create(Person)
  83 + fast_create(Person)
  84 + person.add_friend(p)
  85 +
  86 + get "/api/v1/people/#{person.id}/friends?#{params.to_query}"
  87 + json = JSON.parse(last_response.body)
  88 + assert_equivalent [p.id], json['people'].map {|c| c['id']}
  89 + end
  90 +
  91 + should 'not list person friends invisible' do
  92 + p1 = fast_create(Person)
  93 + p2 = fast_create(Person, :visible => false)
  94 + person.add_friend(p1)
  95 + person.add_friend(p2)
  96 +
  97 + get "/api/v1/people/#{person.id}/friends?#{params.to_query}"
  98 + json = JSON.parse(last_response.body)
  99 + assert_equivalent [p1.id], json['people'].map {|c| c['id']}
  100 + end
  101 +
  102 +end
... ...
test/unit/api/session_test.rb 0 → 100644
... ... @@ -0,0 +1,42 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class APITest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + login_api
  7 + end
  8 +
  9 + should 'generate private token when login' do
  10 + params = {:login => "testapi", :password => "testapi"}
  11 + post "/api/v1/login?#{params.to_query}"
  12 + json = JSON.parse(last_response.body)
  13 + assert !json["private_token"].blank?
  14 + end
  15 +
  16 + should 'return 401 when login fails' do
  17 + user.destroy
  18 + params = {:login => "testapi", :password => "testapi"}
  19 + post "/api/v1/login?#{params.to_query}"
  20 + assert_equal 401, last_response.status
  21 + end
  22 +
  23 + should 'register a user' do
  24 + params = {:login => "newuserapi", :password => "newuserapi", :email => "newuserapi@email.com" }
  25 + post "/api/v1/register?#{params.to_query}"
  26 + assert_equal 201, last_response.status
  27 + end
  28 +
  29 + should 'do not register a user without email' do
  30 + params = {:login => "newuserapi", :password => "newuserapi", :email => nil }
  31 + post "/api/v1/register?#{params.to_query}"
  32 + assert_equal 400, last_response.status
  33 + end
  34 +
  35 + should 'do not register a duplicated user' do
  36 + params = {:login => "newuserapi", :password => "newuserapi", :email => "newuserapi@email.com" }
  37 + post "/api/v1/register?#{params.to_query}"
  38 + post "/api/v1/register?#{params.to_query}"
  39 + assert_equal 400, last_response.status
  40 + end
  41 +
  42 +end
... ...
test/unit/api/test_helper.rb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +require File.dirname(__FILE__) + '/../../test_helper'
  2 +
  3 +class ActiveSupport::TestCase
  4 +
  5 + include Rack::Test::Methods
  6 +
  7 + def app
  8 + Noosfero::API::API
  9 + end
  10 +
  11 + def login_api
  12 + @user = User.create!(:login => 'testapi', :password => 'testapi', :password_confirmation => 'testapi', :email => 'test@test.org', :environment => Environment.default)
  13 + @user.activate
  14 + @person = @user.person
  15 +
  16 + post "/api/v1/login?login=testapi&password=testapi"
  17 + json = JSON.parse(last_response.body)
  18 + @private_token = json["private_token"]
  19 + @params = {:private_token => @private_token}
  20 + end
  21 + attr_accessor :private_token, :user, :person, :params
  22 +
  23 +end
... ...
test/unit/api/users_test.rb 0 → 100644
... ... @@ -0,0 +1,43 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class UsersTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + login_api
  7 + end
  8 +
  9 + should 'list users' do
  10 + get "/api/v1/users/?#{params.to_query}"
  11 + json = JSON.parse(last_response.body)
  12 + assert_includes json["users"].map { |a| a["login"] }, user.login
  13 + end
  14 +
  15 + should 'create a user' do
  16 + params[:user] = {:login => 'some', :password => '123456', :password_confirmation => '123456', :email => 'some@some.com'}
  17 + post "/api/v1/users?#{params.to_query}"
  18 + json = JSON.parse(last_response.body)
  19 + assert_equal 'some', json['user']['login']
  20 + end
  21 +
  22 + should 'return 400 status for invalid user creation' do
  23 + params[:user] = {:login => 'some'}
  24 + post "/api/v1/users?#{params.to_query}"
  25 + json = JSON.parse(last_response.body)
  26 + assert_equal 400, last_response.status
  27 + end
  28 +
  29 + should 'get user' do
  30 + get "/api/v1/users/#{user.id}?#{params.to_query}"
  31 + json = JSON.parse(last_response.body)
  32 + assert_equal user.id, json['user']['id']
  33 + end
  34 +
  35 + should 'list user permissions' do
  36 + community = fast_create(Community)
  37 + community.add_admin(person)
  38 + get "/api/v1/users/#{user.id}/?#{params.to_query}"
  39 + json = JSON.parse(last_response.body)
  40 + assert_includes json["user"]["permissions"], community.identifier
  41 + end
  42 +
  43 +end
... ...
test/unit/person_test.rb
... ... @@ -1638,4 +1638,27 @@ class PersonTest &lt; ActiveSupport::TestCase
1638 1638 assert_equal false, person.follows?(nil)
1639 1639 end
1640 1640  
  1641 + should 'allow posting content when has post_content permission' do
  1642 + person = create_user('person').person
  1643 + profile = mock
  1644 + person.expects(:has_permission?).with('post_content', profile).returns(true)
  1645 + assert person.can_post_content?(profile)
  1646 + end
  1647 +
  1648 + should 'allow posting content when has publish_content permission' do
  1649 + person = create_user('person').person
  1650 + profile = mock
  1651 + person.expects(:has_permission?).with('post_content', profile).returns(false)
  1652 + person.expects(:has_permission?).with('publish_content', profile).returns(true)
  1653 + assert person.can_post_content?(profile)
  1654 + end
  1655 +
  1656 + should 'allow posting content when has permission in the parent' do
  1657 + person = create_user('person').person
  1658 + profile = mock
  1659 + parent = mock
  1660 + parent.expects(:allow_create?).with(person).returns(true)
  1661 + assert person.can_post_content?(profile, parent)
  1662 + end
  1663 +
1641 1664 end
... ...