Commit 9b5b1527b33ef28f6f83de4b0f56207b43ceaab2

Authored by Marcos Pereira
2 parents b6cb1220 3a430590

Merge branch 'api_update_user_data' into 'master'

Add steps to upload image using people's endpoint

With this merge, the frontend will be able to send a image(converted to base64) to the api,and save it in database.

It's possible to extend this feature to other models that have image, as articles.

See merge request !876
lib/noosfero/api/helpers.rb
1 1 require 'grape'
  2 +require 'base64'
  3 +require 'tempfile'
2 4 require_relative '../../find_by_contents'
3 5  
4   - module Noosfero;
5   - module API
6   - module APIHelpers
  6 +module Noosfero;
  7 + module API
  8 + module APIHelpers
7 9 PRIVATE_TOKEN_PARAM = :private_token
8 10 DEFAULT_ALLOWED_PARAMETERS = [:parent_id, :from, :until, :content_type, :author_id, :identifier, :archived]
9 11  
... ... @@ -231,7 +233,7 @@ require_relative '../../find_by_contents'
231 233 else
232 234 created_at = scope.find(reference_id).created_at
233 235 scope.send("#{params.key?(:oldest) ? 'older_than' : 'younger_than'}", created_at)
234   - end
  236 + end
235 237 end
236 238  
237 239 def by_categories(scope, params)
... ... @@ -368,6 +370,30 @@ require_relative '../../find_by_contents'
368 370 not_found! if Noosfero::API::API.endpoint_unavailable?(self, @environment)
369 371 end
370 372  
  373 + def asset_with_image params
  374 + if params.has_key? :image_builder
  375 + asset_api_params = params
  376 + asset_api_params[:image_builder] = base64_to_uploadedfile(asset_api_params[:image_builder])
  377 + return asset_api_params
  378 + end
  379 + params
  380 + end
  381 +
  382 + def base64_to_uploadedfile(base64_image)
  383 + tempfile = base64_to_tempfile base64_image
  384 + converted_image = base64_image
  385 + converted_image[:tempfile] = tempfile
  386 + return {uploaded_data: ActionDispatch::Http::UploadedFile.new(converted_image)}
  387 + end
  388 +
  389 + def base64_to_tempfile base64_image
  390 + base64_img_str = base64_image[:tempfile]
  391 + decoded_base64_str = Base64.decode64(base64_img_str)
  392 + tempfile = Tempfile.new(base64_image[:filename])
  393 + tempfile.write(decoded_base64_str.encode("ascii-8bit").force_encoding("utf-8"))
  394 + tempfile.rewind
  395 + tempfile
  396 + end
371 397 private
372 398  
373 399 def parser_params(params)
... ... @@ -394,7 +420,6 @@ require_relative '../../find_by_contents'
394 420 end_period = until_date.nil? ? DateTime.now : until_date
395 421 begin_period..end_period
396 422 end
397   -
398 423 end
399 424 end
400 425 end
... ...
lib/noosfero/api/v1/articles.rb
... ... @@ -51,7 +51,7 @@ module Noosfero
51 51 post ':id' do
52 52 article = environment.articles.find(params[:id])
53 53 return forbidden! unless article.allow_edit?(current_person)
54   - article.update_attributes!(params[:article])
  54 + article.update_attributes!(asset_with_image(params[:article]))
55 55 present_partial article, :with => Entities::Article
56 56 end
57 57  
... ...
lib/noosfero/api/v1/people.rb
... ... @@ -55,11 +55,10 @@ module Noosfero
55 55 post ':id' do
56 56 authenticate!
57 57 return forbidden! if current_person.id.to_s != params[:id]
58   - current_person.update_attributes!(params[:person])
  58 + current_person.update_attributes!(asset_with_image(params[:person]))
59 59 present current_person, :with => Entities::Person, :current_person => current_person
60 60 end
61   -
62   - # Example Request:
  61 +
63 62 # POST api/v1/people?person[login]=some_login&person[password]=some_password&person[name]=Jack
64 63 # for each custom field for person, add &person[field_name]=field_value to the request
65 64 desc "Create person"
... ... @@ -76,7 +75,7 @@ module Noosfero
76 75 params[:person][:custom_values][key]=params[:person].delete(key) if Person.custom_fields(environment).any?{|cf| cf.name==key}
77 76 end
78 77  
79   - user = User.build(user_data, params[:person], environment)
  78 + user = User.build(user_data, asset_with_image(params[:person]), environment)
80 79  
81 80 begin
82 81 user.signup!
... ...
test/api/helpers_test.rb
1 1 require_relative 'test_helper'
  2 +require "base64"
2 3 require 'noosfero/api/helpers'
3 4  
4 5 class APIHelpersTest < ActiveSupport::TestCase
... ... @@ -238,6 +239,24 @@ class APIHelpersTest &lt; ActiveSupport::TestCase
238 239 present_partial(model, {})
239 240 end
240 241  
  242 + should 'create a :uploaded_data hash, expected by image_builder ' do
  243 + base64_image = create_base64_image
  244 + uploadedfile = base64_to_uploadedfile base64_image
  245 + assert uploadedfile.has_key? :uploaded_data
  246 + assert_equal uploadedfile[:uploaded_data].original_filename, base64_image[:filename]
  247 + assert_equal uploadedfile[:uploaded_data].content_type, base64_image[:type]
  248 + assert uploadedfile[:uploaded_data].tempfile
  249 + end
  250 +
  251 + should 'return a params copy with a UploadedFile object' do
  252 + base64_image = create_base64_image
  253 + params = {}
  254 + params.merge!({image_builder: base64_image})
  255 + asset_params = asset_with_image params
  256 + assert !asset_params[:image_builder][:uploaded_data].nil?
  257 + assert asset_params[:image_builder][:uploaded_data].is_a? ActionDispatch::Http::UploadedFile
  258 + end
  259 +
241 260 protected
242 261  
243 262 def error!(info, status)
... ...
test/api/people_test.rb
... ... @@ -386,4 +386,15 @@ class PeopleTest &lt; ActiveSupport::TestCase
386 386 assert_not_nil json['person'][attribute]
387 387 end
388 388 end
  389 +
  390 + should 'update person image' do
  391 + login_api
  392 + base64_image = create_base64_image
  393 + params.merge!({person: {image_builder: base64_image}})
  394 + assert_nil person.image
  395 + post "/api/v1/people/#{person.id}?#{params.to_query}"
  396 + person.reload
  397 + assert_not_nil person.image
  398 + assert_equal person.image.filename, base64_image[:filename]
  399 + end
389 400 end
... ...
test/api/test_helper.rb
... ... @@ -37,6 +37,18 @@ class ActiveSupport::TestCase
37 37  
38 38 attr_accessor :private_token, :user, :person, :params, :environment
39 39  
  40 + def create_base64_image
  41 + image_path = File.absolute_path(Rails.root + 'public/images/noosfero-network.png')
  42 + image_name = File.basename(image_path)
  43 + image_type = "image/#{File.extname(image_name).delete "."}"
  44 + encoded_base64_img = Base64.encode64(File.open(image_path) {|io| io.read })
  45 + base64_image = {}
  46 + base64_image[:tempfile] = encoded_base64_img
  47 + base64_image[:filename] = image_name
  48 + base64_image[:type] = image_type
  49 + base64_image
  50 + end
  51 +
40 52 private
41 53  
42 54 def json_response_ids(kind)
... ...