Commit 84cd2030ab795361d9b2ecdf371d522c4173d033

Authored by Rodrigo Souto
2 parents dc423036 d6840a7b

Merge remote branch 'mine/stoa-webservice'

Conflicts:
	test/unit/profile_test.rb
app/models/profile.rb
... ... @@ -112,6 +112,7 @@ class Profile < ActiveRecord::Base
112 112 end
113 113  
114 114 named_scope :visible, :conditions => { :visible => true }
  115 + named_scope :public, :conditions => { :visible => true, :public_profile => true }
115 116 # Subclasses must override these methods
116 117 named_scope :more_popular
117 118 named_scope :more_active
... ...
lib/noosfero/fields_decorator.rb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +class Noosfero::FieldsDecorator
  2 + attr_accessor :object, :context
  3 +
  4 + def initialize(object, context = nil)
  5 + @object = object
  6 + @context = context
  7 + end
  8 +
  9 + def method_missing(m, *args)
  10 + object.send(m, *args)
  11 + end
  12 +
  13 + def fields(field_names = {})
  14 + field_names.inject({}) { |result, field| result.merge!(field => self.send(field))}
  15 + end
  16 +end
... ...
plugins/stoa/controllers/stoa_plugin_controller.rb
  1 +require 'stoa_plugin/person_fields'
  2 +
1 3 class StoaPluginController < PublicController
2 4 append_view_path File.join(File.dirname(__FILE__) + '/../views')
3 5  
  6 + include StoaPlugin::PersonFields
  7 +
4 8 def authenticate
5 9 if request.ssl? && request.post?
6 10 if params[:login].blank?
... ... @@ -11,22 +15,14 @@ class StoaPluginController &lt; PublicController
11 15 end
12 16 user = User.authenticate(login, params[:password], environment)
13 17 if user
14   - result = {
15   - :username => user.login,
16   - :email => user.email,
17   - :name => user.name,
18   - :nusp => user.person.usp_id,
19   - :first_name => user.name.split(' ').first,
20   - :surname => user.name.split(' ',2).last,
21   - :address => user.person.address,
22   - :homepage => url_for(user.person.url),
23   - }
  18 + result = StoaPlugin::PersonApi.new(user.person, self).fields(selected_fields(params[:fields], user))
  19 + result.merge!(:ok => true)
24 20 else
25   - result = { :error => _('Incorrect user/password pair.') }
  21 + result = { :error => _('Incorrect user/password pair.'), :ok => false }
26 22 end
27 23 render :text => result.to_json
28 24 else
29   - render :text => { :error => _('Conection requires SSL certificate and post method.') }.to_json
  25 + render :text => { :error => _('Conection requires SSL certificate and post method.'), :ok => false }.to_json
30 26 end
31 27 end
32 28  
... ...
plugins/stoa/lib/stoa_plugin/person_api.rb 0 → 100644
... ... @@ -0,0 +1,40 @@
  1 +class StoaPlugin::PersonApi < Noosfero::FieldsDecorator
  2 + def username
  3 + user.login
  4 + end
  5 +
  6 + def nusp
  7 + usp_id
  8 + end
  9 +
  10 + def first_name
  11 + name.split(' ').first
  12 + end
  13 +
  14 + def surname
  15 + name.split(' ',2).last
  16 + end
  17 +
  18 + def homepage
  19 + context.url_for(url)
  20 + end
  21 +
  22 + def birth_date
  23 + object.birth_date.present? ? object.birth_date.strftime('%F') : nil
  24 + end
  25 +
  26 + def image_base64
  27 + Base64.encode64(image.current_data) if image && image.current_data
  28 + end
  29 +
  30 + def tags
  31 + articles.published.tag_counts({:order => 'tags.count desc', :limit => 10}).inject({}) do |memo,tag|
  32 + memo[tag.name] = tag.count
  33 + memo
  34 + end
  35 + end
  36 +
  37 + def communities
  38 + object.communities.public.map {|community| {:url => context.url_for(community.url), :name => community.name}}
  39 + end
  40 +end
... ...
plugins/stoa/lib/stoa_plugin/person_fields.rb 0 → 100644
... ... @@ -0,0 +1,31 @@
  1 +module StoaPlugin::PersonFields
  2 + HEAVY = %w[image_base64]
  3 + FILTER = %w[image]
  4 + EXTRA = %w[tags communities]
  5 + CUSTOM = %w[first_name surname homepage image_base64 tags communities]
  6 +
  7 + ESSENTIAL = %w[username email nusp]
  8 + AVERAGE = ESSENTIAL + %w[name first_name surname address homepage]
  9 + FULL = (AVERAGE + Person.fields + HEAVY + EXTRA - FILTER).uniq
  10 + COMPLETE = FULL - HEAVY
  11 +
  12 + FIELDS = {
  13 + 'none' => {},
  14 + 'essential' => ESSENTIAL,
  15 + 'average' => AVERAGE,
  16 + 'full' => FULL,
  17 + 'complete' => COMPLETE
  18 + }
  19 +
  20 + private
  21 +
  22 + def selected_fields(kind, user)
  23 + fields = FIELDS[kind] || FIELDS['essential']
  24 + return fields.reject { |field| !FIELDS['essential'].include?(field) } unless user.person.public_profile
  25 + fields.reject do |field|
  26 + !user.person.public_fields.include?(field) &&
  27 + !FIELDS['essential'].include?(field) &&
  28 + !CUSTOM.include?(field)
  29 + end
  30 + end
  31 +end
... ...
plugins/stoa/test/functional/stoa_plugin_controller_test.rb
... ... @@ -54,6 +54,112 @@ class StoaPluginControllerTest &lt; ActionController::TestCase
54 54 assert_equal user.login, json_response['username']
55 55 end
56 56  
  57 + should 'authenticate with usp_id' do
  58 + @request.stubs(:ssl?).returns(true)
  59 + post :authenticate, :usp_id => user.person.usp_id.to_s, :password => '123456'
  60 +
  61 + assert_nil json_response['error']
  62 + assert_equal user.login, json_response['username']
  63 + end
  64 +
  65 + should 'return no fields if fields requested was none' do
  66 + @request.stubs(:ssl?).returns(true)
  67 + post :authenticate, :login => user.login, :password => '123456', :fields => 'none'
  68 +
  69 + expected_response = {'ok' => true}
  70 +
  71 + assert_nil json_response['error']
  72 + assert_equal expected_response, json_response
  73 + end
  74 +
  75 + should 'return only the essential fields if no fields requested' do
  76 + @request.stubs(:ssl?).returns(true)
  77 + post :authenticate, :login => user.login, :password => '123456'
  78 + response = json_response.clone
  79 +
  80 + assert_nil response['error']
  81 + assert_equal true, response.delete('ok')
  82 + assert_equal user.login, response.delete('username')
  83 + assert_equal user.email, response.delete('email')
  84 + assert_equal user.person.usp_id.to_s, response.delete('nusp')
  85 + assert response.blank?
  86 + end
  87 +
  88 + should 'return only selected fields' do
  89 + @request.stubs(:ssl?).returns(true)
  90 + Person.any_instance.stubs(:f1).returns('field1')
  91 + Person.any_instance.stubs(:f2).returns('field2')
  92 + Person.any_instance.stubs(:f3).returns('field3')
  93 + @controller.stubs(:selected_fields).returns(%w[f1 f2 f3])
  94 +
  95 + post :authenticate, :login => user.login, :password => '123456', :fields => 'special'
  96 + response = json_response.clone
  97 +
  98 + assert_equal true, response.delete('ok')
  99 + assert_equal 'field1', response.delete('f1')
  100 + assert_equal 'field2', response.delete('f2')
  101 + assert_equal 'field3', response.delete('f3')
  102 + assert response.blank?
  103 + end
  104 +
  105 + should 'not return private fields' do
  106 + @request.stubs(:ssl?).returns(true)
  107 + Person.any_instance.stubs(:f1).returns('field1')
  108 + Person.any_instance.stubs(:f2).returns('field2')
  109 + Person.any_instance.stubs(:f3).returns('field3')
  110 + StoaPluginController::FIELDS['special'] = %w[f1 f2 f3]
  111 + person = user.person
  112 + person.fields_privacy = {:f1 => 'private', :f2 => 'public', :f3 => 'public'}
  113 + person.save!
  114 +
  115 + post :authenticate, :login => user.login, :password => '123456', :fields => 'special'
  116 +
  117 + assert !json_response.keys.include?('f1')
  118 + assert json_response.keys.include?('f2')
  119 + assert json_response.keys.include?('f3')
  120 + end
  121 +
  122 + should 'return essential fields even if they are private' do
  123 + @request.stubs(:ssl?).returns(true)
  124 + person = user.person
  125 + person.fields_privacy = {:email => 'private'}
  126 + person.save!
  127 +
  128 + post :authenticate, :login => user.login, :password => '123456'
  129 +
  130 + assert json_response.keys.include?('email')
  131 + end
  132 +
  133 + should 'return only essential fields when profile is private' do
  134 + @request.stubs(:ssl?).returns(true)
  135 + Person.any_instance.stubs(:f1).returns('field1')
  136 + Person.any_instance.stubs(:f2).returns('field2')
  137 + Person.any_instance.stubs(:f3).returns('field3')
  138 + StoaPluginController::FIELDS['special'] = %w[f1 f2 f3] + StoaPluginController::FIELDS['essential']
  139 + person = user.person
  140 + person.public_profile = false
  141 + person.save!
  142 +
  143 + post :authenticate, :login => user.login, :password => '123456', :fields => 'special'
  144 + response = json_response.clone
  145 +
  146 + assert_nil response['error']
  147 + assert_equal true, response.delete('ok')
  148 + assert_equal user.login, response.delete('username')
  149 + assert_equal user.email, response.delete('email')
  150 + assert_equal user.person.usp_id.to_s, response.delete('nusp')
  151 + assert response.blank?
  152 + end
  153 +
  154 + should 'not crash if usp_id is invalid' do
  155 + @request.stubs(:ssl?).returns(true)
  156 + assert_nothing_raised do
  157 + post :authenticate, :usp_id => 12321123, :password => '123456'
  158 + end
  159 + assert_not_nil json_response['error']
  160 + assert_match /user/,json_response['error']
  161 + end
  162 +
57 163 should 'check valid usp id' do
58 164 usp_id = '12345678'
59 165 StoaPlugin::UspUser.stubs(:exists?).with(usp_id).returns(true)
... ... @@ -91,23 +197,6 @@ class StoaPluginControllerTest &lt; ActionController::TestCase
91 197 assert !json_response['exists']
92 198 end
93 199  
94   - should 'authenticate with usp_id' do
95   - @request.stubs(:ssl?).returns(true)
96   - post :authenticate, :usp_id => user.person.usp_id.to_s, :password => '123456'
97   -
98   - assert_nil json_response['error']
99   - assert_equal user.login, json_response['username']
100   - end
101   -
102   - should 'not crash if usp_id is invalid' do
103   - @request.stubs(:ssl?).returns(true)
104   - assert_nothing_raised do
105   - post :authenticate, :usp_id => 12321123, :password => '123456'
106   - end
107   - assert_not_nil json_response['error']
108   - assert_match /user/,json_response['error']
109   - end
110   -
111 200 private
112 201  
113 202 def json_response
... ...
plugins/stoa/test/unit/person_api_test.rb 0 → 100644
... ... @@ -0,0 +1,145 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +
  3 +class StoaPlugin::PersonApiTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @person = create_user('sample-user').person
  7 + end
  8 +
  9 + attr_accessor :person
  10 +
  11 + should 'provide nusp' do
  12 + person.usp_id = '99999999'
  13 + api = StoaPlugin::PersonApi.new(person)
  14 + assert_equal person.usp_id, api.nusp
  15 + end
  16 +
  17 + should 'provide username' do
  18 + api = StoaPlugin::PersonApi.new(person)
  19 + assert_equal person.user.login, api.username
  20 + end
  21 +
  22 + should 'provide first_name' do
  23 + person.name = "Jean-Luc Picard"
  24 + api = StoaPlugin::PersonApi.new(person)
  25 + assert_equal 'Jean-Luc', api.first_name
  26 + end
  27 +
  28 + should 'provide surname' do
  29 + person.name = "Jean-Luc Picard"
  30 + api = StoaPlugin::PersonApi.new(person)
  31 + assert_equal 'Picard', api.surname
  32 + end
  33 +
  34 + should 'provide homepage' do
  35 + api = StoaPlugin::PersonApi.new(person, self)
  36 + homepage = 'picard.me'
  37 + self.stubs(:url_for).with(person.url).returns(homepage)
  38 + assert_equal homepage, api.homepage
  39 + end
  40 +
  41 + should 'provide image on base64' do
  42 + person.image_builder = {:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')}
  43 + person.save!
  44 + api = StoaPlugin::PersonApi.new(person)
  45 + assert_equal Base64.encode64(person.image.current_data), api.image_base64
  46 + end
  47 +
  48 + should 'not crash on image_base64 if profile has no image' do
  49 + api = StoaPlugin::PersonApi.new(person)
  50 + assert_equal nil, api.image_base64
  51 + end
  52 +
  53 + should 'provide tags' do
  54 + create_article_with_tags(person.id, 'free_software, noosfero, linux')
  55 + create_article_with_tags(person.id, 'free_software, linux')
  56 + create_article_with_tags(person.id, 'free_software')
  57 +
  58 + api = StoaPlugin::PersonApi.new(person)
  59 + assert_equal person.article_tags, api.tags
  60 + end
  61 +
  62 + should 'provide tags limited by 10 most relevant' do
  63 + 13.times {create_article_with_tags(person.id, 'a')}
  64 + 12.times {create_article_with_tags(person.id, 'b')}
  65 + 11.times {create_article_with_tags(person.id, 'c')}
  66 + 10.times {create_article_with_tags(person.id, 'd')}
  67 + 9.times {create_article_with_tags(person.id, 'e')}
  68 + 8.times {create_article_with_tags(person.id, 'f')}
  69 + 7.times {create_article_with_tags(person.id, 'g')}
  70 + 6.times {create_article_with_tags(person.id, 'h')}
  71 + 5.times {create_article_with_tags(person.id, 'i')}
  72 + 4.times {create_article_with_tags(person.id, 'j')}
  73 + 3.times {create_article_with_tags(person.id, 'l')}
  74 + 2.times {create_article_with_tags(person.id, 'm')}
  75 + 1.times {create_article_with_tags(person.id, 'n')}
  76 +
  77 + api = StoaPlugin::PersonApi.new(person)
  78 + tags = api.tags
  79 + assert_equal 10, tags.size
  80 + assert tags['a']
  81 + assert tags['b']
  82 + assert tags['c']
  83 + assert tags['d']
  84 + assert tags['e']
  85 + assert tags['f']
  86 + assert tags['g']
  87 + assert tags['h']
  88 + assert tags['i']
  89 + assert tags['j']
  90 + assert_nil tags['l']
  91 + assert_nil tags['m']
  92 + assert_nil tags['n']
  93 + end
  94 +
  95 + should 'not provide information of private articles tags' do
  96 + create_article_with_tags(person.id, 'free_software, noosfero, linux', {:published => false})
  97 + create_article_with_tags(person.id, 'free_software, linux')
  98 + create_article_with_tags(person.id, 'free_software')
  99 +
  100 + api = StoaPlugin::PersonApi.new(person)
  101 + assert !api.tags.has_key?('noosfero')
  102 + end
  103 +
  104 + should 'provide communities' do
  105 + c1 = fast_create(Community)
  106 + c2 = fast_create(Community)
  107 + c3 = fast_create(Community)
  108 + c1.add_member(person)
  109 + c2.add_member(person)
  110 + c1_homepage = 'c1.org'
  111 + c2_homepage = 'c2.org'
  112 + self.stubs(:url_for).with(c1.url).returns(c1_homepage)
  113 + self.stubs(:url_for).with(c2.url).returns(c2_homepage)
  114 + communities = [{:url => c1_homepage, :name => c1.name}, {:url => c2_homepage, :name => c2.name}]
  115 + api = StoaPlugin::PersonApi.new(person, self)
  116 +
  117 + assert_equivalent communities, api.communities
  118 + end
  119 +
  120 + should 'not provide private communities' do
  121 + c1 = fast_create(Community)
  122 + c2 = fast_create(Community, :public_profile => false)
  123 + c3 = fast_create(Community, :visible => false)
  124 + c1.add_member(person)
  125 + c2.add_member(person)
  126 + c3.add_member(person)
  127 + c1_homepage = 'c1.org'
  128 + c2_homepage = 'c2.org'
  129 + self.stubs(:url_for).with(c1.url).returns(c1_homepage)
  130 + self.stubs(:url_for).with(c2.url).returns(c2_homepage)
  131 + communities = [{:url => c1_homepage, :name => c1.name}]
  132 + api = StoaPlugin::PersonApi.new(person, self)
  133 +
  134 + assert_equivalent communities, api.communities
  135 + end
  136 +
  137 + private
  138 +
  139 + def create_article_with_tags(profile_id, tags = '', options = {})
  140 + article = fast_create(Article, options.merge(:profile_id => profile_id))
  141 + article.tag_list = tags
  142 + article.save!
  143 + article
  144 + end
  145 +end
... ...
test/unit/profile_test.rb
... ... @@ -1908,4 +1908,17 @@ class ProfileTest &lt; ActiveSupport::TestCase
1908 1908 environment.destroy
1909 1909 assert_raise(ActiveRecord::RecordNotFound) {profile.reload}
1910 1910 end
  1911 +
  1912 + should 'list only public profiles' do
  1913 + p1 = fast_create(Profile)
  1914 + p2 = fast_create(Profile, :visible => false)
  1915 + p3 = fast_create(Profile, :public_profile => false)
  1916 + p4 = fast_create(Profile, :visible => false, :public_profile => false)
  1917 +
  1918 + assert_includes Profile.public, p1
  1919 + assert_not_includes Profile.public, p2
  1920 + assert_not_includes Profile.public, p3
  1921 + assert_not_includes Profile.public, p4
  1922 + end
  1923 +
1911 1924 end
... ...