require 'spec_helper'
require 'debci/self_service'
require 'debci/admin'

describe Debci::Admin do
  include WebAppHelper

  class Admin < Debci::Admin
    set :raise_errors, true
    set :show_exceptions, false
  end

  def app
    Rack::Builder.new do
      map "/user" do
        run Debci::SelfService
      end
      map "/admin" do
        run Admin
      end
    end
  end

  context 'not authenticated' do
    it 'needs to login first' do
      get '/admin/'
      expect(last_response.status).to eq(302)
      expect(last_response.location).to match(%r{/user/login$})
    end
  end

  context 'unauthorized user' do
    it 'has no access' do
      login("user")
      get '/admin/'
      expect(last_response.status).to eq(403)
    end
  end

  context 'admin user' do
    before do
      @admin = Debci::User.create!(username: 'admin', uid: 'admin', admin: true)
      @user1 = Debci::User.create!(username: 'user1', uid: 'user1')
      @user2 = Debci::User.create!(username: 'user2', uid: 'user2')
      login('admin', 'admin')
    end

    it 'can see the admin page' do
      get '/admin/'
      expect(last_response.status).to eq(200)
    end

    it 'sees the list of users' do
      get '/admin/users/'
      expect(last_response.body).to match('user1')
      expect(last_response.body).to match('user2')
    end

    it 'can edit an user' do
      get "/admin/users/#{@user1.id}/"
      expect(last_response.status).to eq(200)
    end

    it 'can update an user' do
      post "/admin/users/#{@user1.id}/", admin: "true"
      expect(Debci::User.find_by(username: 'user1')).to be_admin
    end

    it 'can show form to create new user' do
      get '/admin/users/new/'
      expect(last_response.status).to eq(200)
    end

    it 'can create an user' do
      post "/admin/users/new/", username: 'user3', uid: 'user3'
      expect(Debci::User.where(username: 'user3')).to exist
    end

    it 'handles missing ids as 404' do
      get '/admin/users/999999/'
      expect(last_response.status).to eq(404)
    end

    it 'is able to search' do
      get '/admin/users/', q: "user1"
      expect(last_response.body).to match('user1')
      expect(last_response.body).to_not match('user2')
    end

    context "handling packages" do
      it 'converts human size to integer (MB)' do
        pkg = Debci::Package.create!(name: "foobar")
        post "/admin/packages/#{pkg.id}/", storage_limit: '1 MB'
        pkg.reload
        expect(pkg.storage_limit).to eq(1.megabyte)
      end
      it 'converts human size to integer (GB)' do
        pkg = Debci::Package.create!(name: "foobar")
        post "/admin/packages/#{pkg.id}/", storage_limit: '1 GB'
        pkg.reload
        expect(pkg.storage_limit).to eq(1.gigabyte)
      end
      it 'supports fractionary numbers' do
        pkg = Debci::Package.create!(name: "foobar")
        post "/admin/packages/#{pkg.id}/", storage_limit: '1.5 GB'
        pkg.reload
        expect(pkg.storage_limit).to eq(1.5.gigabyte)
      end
    end
  end
end
