require 'spec_helper'

resource "Account" do

  # build the object which will be used for CRUD actions
  let(:account) { Factory.build(:buyer_account, provider_account: provider) }

  let(:resource) do
    FieldsDefinition.create_defaults(master)
    provider.reload
    account
  end

  # define the api namespace and optional formats it supports
  api 'accounts' do
    # get method to the following url will test :index action
    get '/admin/api/accounts.:format', action: :index

    # similar as above, :show action is defined in spec/support/api/crud.rb
    get '/admin/api/accounts/:id.:format', action: :show

    # actions are named as methods in controllers
    delete '/admin/api/accounts/:id.:format', action: :destroy

    # you can pass a block to the definition
    # in the block you can set up parameters valid for that api endpoint
    # and set values for the parameters
    put '/admin/api/accounts/:id.:format', action: :update do
      parameter :name, 'Account Org Name'

      let(:name) { 'some org name' }
    end

    # also you can make custom actions using already defined ones
    get '/admin/api/accounts/find.:format', action: :show do
      parameter :username, 'User username'
      parameter :email, 'User email address'

      let(:username) { resource.users.first.username }
    end

    # or you can just say that it is resource or collection
    # and appropriate callbacks and values will be set in place
    put '/admin/api/accounts/:id/make_pending.:format', :resource do
      before { resource.approve! }
      before { resource.state.should_not == "pending" }

      # the response code and body are checked automatically
      # you can adjust it by setting:
      #   status: number # status code
      #   body: boolean # if body should be sent or not

      request "Make #{model} pending" do
        resource.reload.state == "pending"
      end
    end

    put '/admin/api/accounts/:id/approve.:format', :resource do
      before { resource.make_pending! }
      before { resource.state.should_not == "approved" }

      request "Approve #{model}" do
        resource.reload.state == "approved"
      end
    end

    put '/admin/api/accounts/:id/reject.:format', :resource do
      before { resource.make_pending! }
      before { resource.state.should_not == "rejected" }

      request "Reject #{model}" do
        resource.reload.state == "rejected"
      end
    end

    post '/admin/api/signup.:format', action: :create do
      let(:serialized) { representer.send(serialization_format, with_apps: true) }

      parameter :org_name, 'Organization Name of the buyer account'
      parameter :username, 'Username od the admin user (on the new buyer account)'
      parameter :email, 'Email of the admin user'
      parameter :password, 'Password of the admin user'

      let(:password) { 'password' }
      let(:email) { 'email@example.com' }
      let(:username) { 'new_user' }
      let(:org_name) { 'New Signup' }
    end

  end

  # we use roar gem and it's representers to extend our objects
  # the extension is done by the responder - lib/three_scale/responder.rb
  #
  # thee representers are in app/representers/ and their purpose is:
  #
  # * extract serialization from the model
  # * have hypermedia links in the json api
  # * act as decorator for the model

  # for testing json/xml output:
  #
  # these actions are for testing json/xml output
  # json(:resource) means that the subject of the context will be:
  # resource.extend(representer).to_json
  json(:resource) do
    let(:root) { 'account' }

    it do
      should have_properties('id', 'org_name').from(resource)
      should have_properties('state', 'credit_card_stored').from(resource)
      should have_properties('created_at', 'updated_at')
      should have_links('self', 'users')
    end

  end

  # collection is similar as resource, but the object is:
  # [resource].extend(collection_representer).to_json
  json(:collection) do
    let(:root) { 'accounts' }
    it { should be_an(Array) }
  end

  # for xml it would be to_xml
end


__END__
admin_api_accounts GET    /admin/api/accounts(.:format)      admin/api/accounts#index {:format=>"xml"}
 admin_api_account GET    /admin/api/accounts/:id(.:format)  admin/api/accounts#show {:format=>"xml"}
                   PUT    /admin/api/accounts/:id(.:format)  admin/api/accounts#update {:format=>"xml"}
                   DELETE /admin/api/accounts/:id(.:format)  admin/api/accounts#destroy {:format=>"xml"}

       find_admin_api_accounts GET    /admin/api/accounts/find(.:format)                admin/api/accounts#find {:format=>"xml"}
 change_plan_admin_api_account PUT    /admin/api/accounts/:id/change_plan(.:format)     admin/api/accounts#change_plan {:format=>"xml"}
make_pending_admin_api_account PUT    /admin/api/accounts/:id/make_pending(.:format)    admin/api/accounts#make_pending {:format=>"xml"}
     approve_admin_api_account PUT    /admin/api/accounts/:id/approve(.:format)         admin/api/accounts#approve {:format=>"xml"}
      reject_admin_api_account PUT    /admin/api/accounts/:id/reject(.:format)          admin/api/accounts#reject {:format=>"xml"}

 buy_admin_api_account_application_plan POST   /admin/api/accounts/:account_id/application_plans/:id/buy(.:format) admin/api/buyers_application_plans#buy {:format=>"xml"}
    admin_api_account_application_plans GET    /admin/api/accounts/:account_id/application_plans(.:format)         admin/api/buyers_application_plans#index {:format=>"xml"}
   admin_api_account_buyer_account_plan GET    /admin/api/accounts/:account_id/plan(.:format)                      admin/api/buyer_account_plans#show {:format=>"xml"}
     buy_admin_api_account_service_plan POST   /admin/api/accounts/:account_id/service_plans/:id/buy(.:format)     admin/api/buyers_service_plans#buy {:format=>"xml"}
        admin_api_account_service_plans GET    /admin/api/accounts/:account_id/service_plans(.:format)             admin/api/buyers_service_plans#index {:format=>"xml"}
