Commit 8a6d7d69406ad72f4dc412cbc51d53000a63cc90
Exists in
theme-brasil-digital-from-staging
and in
9 other branches
Merge branch 'api' into stable
Conflicts: config.ru lib/noosfero/plugin.rb
Showing
35 changed files
with
2079 additions
and
21 deletions
Show diff stats
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 < 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 => 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" | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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' | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 < 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 | ... | ... |