vault_client 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,47 @@
1
+ module BillableEventsClient
2
+ extend self
3
+ extend VaultHelper
4
+
5
+ Open = "open"
6
+ Close = "close"
7
+
8
+ def make_request(action, args)
9
+ case action
10
+ when :open
11
+ open(args)
12
+ when :close
13
+ close(args)
14
+ end
15
+ end
16
+
17
+ def open(args)
18
+ assert_args!(args, :hid, :event_id, :qty, :time, :rate_code)
19
+ res = resource(args[:hid], args[:event_id])
20
+ res.put(
21
+ :qty => args[:qty],
22
+ :time => encode_time(args[:time]),
23
+ :state => Open,
24
+ :rate_code => args[:rate_code],
25
+ :product_name => args[:product_name]
26
+ )
27
+ end
28
+
29
+ def close(args)
30
+ assert_args!(args, :hid, :event_id, :time, :rate_code)
31
+ res = resource(args[:hid], args[:event_id])
32
+ res.put(
33
+ :time => encode_time(args[:time]),
34
+ :state => Close,
35
+ :rate_code => args[:rate_code]
36
+ )
37
+ end
38
+
39
+ def resource(hid, event_id)
40
+ url = VaultClient.url.dup
41
+ url << "/resources/#{hid}/billable_events/#{event_id}"
42
+ @resource ||= begin
43
+ RestClient::Resource.new(url, :headers => {:accept => "application/json"})
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,32 @@
1
+ module VaultClient
2
+ module DataTransferObject
3
+ module UsageReport
4
+ extend VaultHelper
5
+ extend self
6
+
7
+ def make_request(action, args)
8
+ case action
9
+ when :query
10
+ query(args)
11
+ else
12
+ raise "Unkown Action"
13
+ end
14
+ end
15
+
16
+ def query(args)
17
+ assert_args!(args, :account_id, :from, :to)
18
+ res = resource(args[:account_id])
19
+ JSON.parse res.get(:params => {:from => encode_time(args[:from]), :to => encode_time(args[:to])})
20
+ end
21
+
22
+ def resource(account_id)
23
+ url = VaultClient.url.dup
24
+ url << "/accounts/#{account_id}/usage_reports"
25
+ @resource ||= begin
26
+ RestClient::Resource.new(url, :headers => {:accept => "application/json"})
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ module VaultClient
2
+ class BillableUnit
3
+ attr_accessor(
4
+ :hid,
5
+ :from,
6
+ :to,
7
+ :qty,
8
+ :total,
9
+ :rate,
10
+ :rate_period,
11
+ :product_group,
12
+ :product_name
13
+ )
14
+
15
+ def initialize(args_hash)
16
+ @hid = args_hash["hid"]
17
+ @from = args_hash["from"]
18
+ @to = args_hash["to"]
19
+ @qty = args_hash["qty"]
20
+ @rate = args_hash["rate"]
21
+ @rate_period = args_hash["rate_period"]
22
+ @product_name = args_hash["product_name"]
23
+ @product_group = args_hash["product_group"]
24
+ end
25
+
26
+ def id
27
+ #TODO remove stub
28
+ Time.now.to_i
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,21 @@
1
+ module VaultClient
2
+ class LineItem
3
+
4
+ attr_reader :unit_groups
5
+
6
+ def initialize(unit_groups)
7
+ @unit_groups = unit_groups
8
+ end
9
+
10
+ def app_name
11
+ @unit_groups.first.hid
12
+ end
13
+
14
+ def total
15
+ @unit_groups.inject(0) {|memo, unit_group| unit_group.total}
16
+ end
17
+
18
+ end
19
+ end
20
+
21
+
@@ -0,0 +1,60 @@
1
+ module VaultClient
2
+ class UnitGroup
3
+ InvalidUnitGroup = Class.new(Exception)
4
+
5
+ attr_reader :units
6
+
7
+ def initialize(units)
8
+ @units = units
9
+ check_rates
10
+ end
11
+
12
+ def check_rates
13
+ if @units.map(&:rate).uniq.length > 1
14
+ raise(InvalidUnitGroup, "Rates must be homogenius.")
15
+ end
16
+ end
17
+
18
+ def name
19
+ @name ||= units.first.product_name
20
+ end
21
+
22
+ def hid
23
+ units.first.hid
24
+ end
25
+
26
+ def total
27
+ units.inject(0) {|memo, unit| unit.rate * unit.qty}
28
+ end
29
+
30
+ def dyno_type?
31
+ sample_unit.product_group == "dyno"
32
+ end
33
+
34
+ def add_on_type?
35
+ sample_unit.product_group == "addon"
36
+ end
37
+
38
+ def run_type?
39
+ return false
40
+ sample_unit.product_name == "run"
41
+ end
42
+
43
+ def description
44
+ sample_unit.product_name
45
+ end
46
+
47
+ def qty
48
+ @units.inject(0) {|memo, unit| unit.qty}
49
+ end
50
+
51
+ def rate
52
+ sample_unit.rate
53
+ end
54
+
55
+ def sample_unit
56
+ @sample_unit ||= @units.first
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,21 @@
1
+ module VaultClient
2
+ class UsageReport
3
+
4
+ attr_accessor(
5
+ :account_id,
6
+ :from,
7
+ :to,
8
+ :billable_units,
9
+ :total
10
+ )
11
+
12
+ def initialize(account_id, from, to, billable_units, total)
13
+ @account_id = from
14
+ @from = from
15
+ @to = to
16
+ @billable_units = billable_units
17
+ @total = total
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ module VaultClient
2
+ class BasePresenter
3
+
4
+ def money(cents)
5
+ return if cents.nil?
6
+ pennies_to_dollar(cents.to_i)
7
+ end
8
+
9
+ def pennies_to_dollar(qty)
10
+ sprintf("%.2f", qty / 100.0)
11
+ end
12
+
13
+ def trunc_hours(hrs)
14
+ sprintf("%.3f", hrs)
15
+ end
16
+
17
+ def date_range(s, f)
18
+ s.strftime('%d %b %H:%M ') + " - " + f.strftime('%d %b %H:%M ')
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,68 @@
1
+ module VaultClient
2
+ class LineItemPresenter < BasePresenter
3
+
4
+ def initialize(line_item)
5
+ @line_item = line_item
6
+ end
7
+
8
+ def add_on_unit_group_total
9
+ result = add_on_unit_group_presenters.map do |ugp|
10
+ ugp.unit_group
11
+ end.inject(0) do |memo, ug|
12
+ ug.total
13
+ end
14
+ money(result)
15
+ end
16
+
17
+ def dyno_unit_group_total
18
+ result = dyno_unit_group_presenters.map do |ugp|
19
+ ugp.unit_group
20
+ end.inject(0) do |memo, ug|
21
+ ug.total
22
+ end
23
+ money(result)
24
+ end
25
+
26
+ def dyno_unit_group_rate
27
+ 0.05
28
+ end
29
+
30
+ def dyno_unit_group_qty
31
+ dyno_unit_group_presenters.map do |upg|
32
+ upg.unit_group
33
+ end.inject(0) do |memo, ug|
34
+ ug.qty
35
+ end
36
+ end
37
+
38
+ def dyno_unit_group_presenters
39
+ unit_group_presenters.select {|ugp| ugp.unit_group.dyno_type?}
40
+ end
41
+
42
+ def add_on_unit_group_presenters
43
+ unit_group_presenters.select {|ugp| ugp.unit_group.add_on_type?}
44
+ end
45
+
46
+ def unit_group_presenters
47
+ if defined?(@unit_group_presenters)
48
+ @unit_group_presenters
49
+ else
50
+ @unit_group_presenters = unit_groups.map {|ug| UnitGroupPresenter.new(ug)}
51
+ end
52
+ end
53
+
54
+ def total
55
+ money(@line_item.total)
56
+ end
57
+
58
+ def name
59
+ @line_item.app_name
60
+ end
61
+
62
+ def unit_groups
63
+ @unit_groups ||= @line_item.unit_groups
64
+ end
65
+
66
+ end
67
+ end
68
+
@@ -0,0 +1,17 @@
1
+ module VaultClient
2
+ class ReportPresenter < BasePresenter
3
+
4
+ def initialize(units)
5
+ @units = units
6
+ end
7
+
8
+ def line_item_presenters
9
+ @line_item_presenters ||= begin
10
+ LineItemBuilder.build(@units).map do |li|
11
+ LineItemPresenter.new(li)
12
+ end
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,78 @@
1
+ module VaultClient
2
+ class UnitGroupPresenter < BasePresenter
3
+
4
+ attr_reader :unit_group
5
+
6
+ def initialize(unit_group)
7
+ @unit_group = unit_group
8
+ end
9
+
10
+ def id
11
+ [:hid, :name].map {|m| unit_group.send(m)}.join("_").gsub("-", "_")
12
+ end
13
+
14
+ def unit_presenters
15
+ if defined?(@unit_presenters)
16
+ @unit_presenters
17
+ else
18
+ @unit_presenters = @unit_group.units.map {|u| UnitPresenter.new(u)}
19
+ end
20
+ end
21
+
22
+ def template
23
+ if @unit_group.dyno_type?
24
+ "line_item_types/dyno"
25
+ elsif @unit_group.add_on_type?
26
+ "line_item_types/add_on"
27
+ elsif @unit_group.additional_type?
28
+ "line_item_types/additional"
29
+ end
30
+ end
31
+
32
+ def detail_template
33
+ if @unit_group.run_type?
34
+ "unit_group_types/flat"
35
+ elsif @unit_group.dyno_type?
36
+ "unit_group_types/metered"
37
+ else
38
+ "unit_group_types/brief"
39
+ end
40
+ end
41
+
42
+ def daily_report_url
43
+ #TODO remove stub
44
+ #payments_uri("/billable_units/daily")
45
+ "/billable_units/daily"
46
+ end
47
+
48
+ def compacted_reports
49
+ #TODO remove stub
50
+ #BillableUnitReporter.compacted(@unit_group.units)
51
+ []
52
+ end
53
+
54
+ def name
55
+ @unit_group.name
56
+ end
57
+
58
+ def description
59
+ @unit_group.description
60
+ end
61
+
62
+ def qty
63
+ trunc_hours(@unit_group.qty)
64
+ end
65
+
66
+ def rate
67
+ end
68
+
69
+ def unit_of_measure
70
+ end
71
+
72
+ def total
73
+ money(@unit_group.total)
74
+ end
75
+
76
+ end
77
+ end
78
+
@@ -0,0 +1,34 @@
1
+ module VaultClient
2
+ class UnitPresenter < BasePresenter
3
+
4
+ def initialize(unit)
5
+ @unit = unit
6
+ end
7
+
8
+ def total
9
+ money(@unit.rate * @unit.qty)
10
+ end
11
+
12
+ def rate
13
+ [money(@unit.rate), @unit.rate_period].join("/")
14
+ end
15
+
16
+ def qty
17
+ trunc_hours(@unit.qty)
18
+ end
19
+
20
+ def start
21
+ @unit.from
22
+ end
23
+
24
+ def end
25
+ @unit.to
26
+ end
27
+
28
+ def description
29
+ @unit.subresource
30
+ end
31
+
32
+ end
33
+ end
34
+
@@ -0,0 +1,55 @@
1
+ module ResourceOwnershipClient
2
+ extend self
3
+ extend VaultHelper
4
+
5
+ def make_request(action, args)
6
+ case action
7
+ when :activate
8
+ activate(args)
9
+ when :transfer
10
+ transfer(args)
11
+ when :deactivate
12
+ deactivate(args)
13
+ when :query
14
+ query(args)
15
+ else
16
+ raise(ArgumentError, "Resource Ownership API does not respond to #{action}")
17
+ end
18
+ end
19
+
20
+ def activate(args)
21
+ assert_args!(args, :account_id, :event_id, :hid, :time)
22
+ res = resource(args[:account_id], args[:event_id])
23
+ res.post(:hid => args[:hid], :time => encode_time(args[:time]))
24
+ end
25
+
26
+ def transfer(args)
27
+ assert_args!(args, :account_id, :prev_account_id, :event_id, :prev_event_id, :hid, :time)
28
+ res = resource(args[:prev_account_id], args[:prev_event_id])
29
+ res.put(:account_id => args[:account_id], :event_id => args[:event_id], :hid => args[:hid], :time => encode_time(args[:time]))
30
+ end
31
+
32
+ def deactivate(args)
33
+ assert_args!(args, :account_id, :event_id, :hid, :time)
34
+ res = resource(args[:account_id])["#{args[:event_id]}?hid=#{args[:hid]}&time=#{encode_time(args[:time])}"]
35
+ res.delete
36
+ end
37
+
38
+ def query(args)
39
+ assert_args!(args, :account_id)
40
+ res = resource(args[:account_id])
41
+ res.get
42
+ end
43
+
44
+ def resource(account_id, event_id=nil)
45
+ url = VaultClient.url.dup
46
+ url << "/accounts/#{account_id}/resource_ownerships"
47
+ if event_id
48
+ url << "/#{event_id}"
49
+ end
50
+ @resource ||= begin
51
+ RestClient::Resource.new(url, :headers => {:accept => "application/json"})
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,17 @@
1
+ module VaultClient
2
+ module LineItemBuilder
3
+ extend self
4
+
5
+ # Give build() a collection of units and it will return a
6
+ # collection of line_items. Each line_item will have a collection
7
+ # of unit_groups wich will hold a collection of units
8
+
9
+ def build(units)
10
+ units.group_by(&:hid).map do |hid, units_by_hid|
11
+ units_by_hid.group_by(&:product_name).map do |product_name, units_by_name|
12
+ UnitGroup.new(units_by_name)
13
+ end
14
+ end.map {|unit_groups| LineItem.new(unit_groups)}.flatten
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module VaultClient
2
+ module ReportBuilder
3
+ extend self
4
+
5
+ def usage_report(account_id, from, to)
6
+ dto = DataTransferObject::UsageReport.query(:account_id => account_id, :from => from, :to => to)
7
+ billable_units = dto["billable_units"].map{|bu| BillableUnit.new(bu)}
8
+ from = Time.parse(dto["from"])
9
+ to = Time.parse(dto["to"])
10
+ total = dto["total"].to_i
11
+ UsageReport.new(account_id, from, to, billable_units, total)
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ module UsageReportsClient
2
+ extend VaultHelper
3
+ extend self
4
+
5
+ def make_request(action, args)
6
+ case action
7
+ when :query
8
+ query(args)
9
+ else
10
+ raise "Unkown Action"
11
+ end
12
+ end
13
+
14
+ def query(args)
15
+ assert_args!(args, :account_id, :from, :to)
16
+ res = resource(args[:account_id])
17
+ res.get(:from => encode_time(args[:from]), :to => encode_time(args[:to]))
18
+ end
19
+
20
+ def resource(account_id)
21
+ url = VaultClient.url.dup
22
+ url << "/accounts/#{account_id}/usage_reports"
23
+ @resource ||= begin
24
+ RestClient::Resource.new(url, :headers => {:accept => "application/json"})
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,88 @@
1
+ require 'rest-client'
2
+ require 'json'
3
+ require 'vault_helper'
4
+ require 'resource_ownership_client'
5
+ require 'billable_events_client'
6
+ require 'usage_reports_client'
7
+
8
+ module VaultClient
9
+
10
+ AuthenticationError = Class.new(Exception)
11
+ AuthorizationError = Class.new(Exception)
12
+ ServiceDownError = Class.new(Exception)
13
+ UnexpectedError = Class.new(Exception)
14
+ SymanticError = Class.new(Exception)
15
+
16
+ attr_accessor :url
17
+
18
+ extend self
19
+
20
+ def resource_ownerships(action, args={})
21
+ if ENV["VAULT_CLIENT_UNSAFE"] == "true"
22
+ make_unsafe_request! {ResourceOwnershipClient.make_request(action, args)}
23
+ else
24
+ make_http_request {ResourceOwnershipClient.make_request(action, args)}
25
+ end
26
+ end
27
+
28
+ def billable_events(action, args={})
29
+ if ENV["VAULT_CLIENT_UNSAFE"] == "true"
30
+ make_unsafe_request! {BillableEventsClient.make_request(action, args)}
31
+ else
32
+ make_http_request {BillableEventsClient.make_request(action, args)}
33
+ end
34
+ end
35
+
36
+ def make_unsafe_request!
37
+ begin
38
+ resp = yield
39
+ JSON.parse(resp.body)
40
+ rescue RestClient => e
41
+ return e.inspect
42
+ end
43
+ end
44
+
45
+ def make_http_request(&block)
46
+ block.call() do |resp, req, res|
47
+ response_body = JSON.parse(resp.body)
48
+ case resp.code
49
+ when 200, 201
50
+ response_body
51
+ when 400, 401,
52
+ raise(AuthenticationError, response_body)
53
+ when 403
54
+ raise(AuthorizationError, response_body)
55
+ when 404
56
+ raise(NotFound, response_body)
57
+ when 422
58
+ raise(SymanticError, response_body)
59
+ when 500
60
+ raise(UnexpectedError)
61
+ when 503
62
+ raise(ServiceDownError)
63
+ end
64
+ end
65
+ end
66
+
67
+ def url
68
+ @url || ENV["VAULT_URL"]
69
+ end
70
+
71
+ end
72
+
73
+ $:.unshift("lib")
74
+
75
+ require 'models/usage_report'
76
+ require 'models/billable_unit'
77
+ require 'models/unit_group'
78
+ require 'models/line_item'
79
+
80
+ require 'services/line_item_builder'
81
+ require 'services/report_builder'
82
+
83
+ require 'dto/usage_report'
84
+
85
+ require 'presenters/base_presenter'
86
+ require 'presenters/report_presenter'
87
+ require 'presenters/line_item_presenter'
88
+ require 'presenters/unit_group_presenter'
@@ -0,0 +1,15 @@
1
+ require 'cgi'
2
+
3
+ module VaultHelper
4
+
5
+ def encode_time(time)
6
+ CGI.escape(time.to_s)
7
+ end
8
+
9
+ def assert_args!(args, *list_of_things_that_should_be)
10
+ unless list_of_things_that_should_be.all? {|key| args.include?(key)}
11
+ raise(ArgumentError, "Arguments should include: [#{list_of_things_that_should_be}]. You passed: [#{args}]")
12
+ end
13
+ end
14
+
15
+ end
data/readme.md ADDED
@@ -0,0 +1,68 @@
1
+ # The Vault Client
2
+
3
+ ## Purpose
4
+
5
+ This gem wraps the APIs defined [here](https://github.com/heroku/shushu/tree/master/doc).
6
+
7
+ ## Usage
8
+
9
+ ### Setup
10
+
11
+ ```bash
12
+ $ gem install vault_client
13
+ ```
14
+
15
+ ### Configure
16
+
17
+ ```bash
18
+ # Optional. When set, vault_client will ignore bad responses from The Vault's API.
19
+ # Default: false
20
+ $VAULT_CLIENT_UNSAFE=true
21
+
22
+ # Required
23
+ # Default: nil
24
+ $VAULT_URL=https://vault-stg.heroku.com
25
+ ```
26
+
27
+ **Ruby configuration will take precedence over environment variables.**
28
+
29
+ ```ruby
30
+ VaultClient.url = "https://core:secret@vault-stg.heroku.com"
31
+ ```
32
+
33
+ ### Resource Ownership
34
+
35
+ ```ruby
36
+ # When a new app is created, activate a new resource_ownership record.
37
+ VaultClient.resource_ownerships(:activate, hid, vault_account_id, time, event_id)
38
+ #=> {"hid"=>"123", "account_id"=>"1", "event_id"=>"event123"}
39
+
40
+
41
+ # When an app is transfered to another vault account, transfer the resource_ownership record.
42
+ VaultClient.resource_ownerships(:transfer, hid, prev_vault_account_id, new_vault_account_id, time, prev_event_id, event_id)
43
+ #=> {"hid"=>"123", "account_id"=>"1", "event_id"=>"event123"}
44
+
45
+ # When an app is destroyed, deactivate the resource_ownership record.
46
+ VaultClient.resource_ownerships(:deactivate, hid, new_vault_account_id, time, event_id)
47
+ #=> {"hid"=>"123", "account_id"=>"1", "event_id"=>"event123"}
48
+ ```
49
+
50
+ ## Hacking
51
+
52
+ ### Supporting a vault endpoint
53
+
54
+ Define a method in the VaultClient module that looks like the name of the http
55
+ resource. Have this method dispatch the call to another modle that implements
56
+ the detail of the api. The aforementioned API client module should only return
57
+ the data that is needed by rest-client to submit the request.
58
+
59
+ ### Running the tests
60
+
61
+ We only test that our API client modules return the http parameters and the body
62
+ for the http request. We trust that when rest-client is used correctly it will
63
+ work.
64
+
65
+ ```bash
66
+ $ bundle
67
+ $ bundle turn test/
68
+ ```
data/test/fixtures.rb ADDED
@@ -0,0 +1,29 @@
1
+ module Fixtures
2
+ extend self
3
+
4
+ def billable_units
5
+ [
6
+ {
7
+ :hid => 123,
8
+ :from => Time.mktime(2000,1),
9
+ :to => Time.mktime(2000,2),
10
+ :qty => 744,
11
+ :rate => 5,
12
+ :rate_period => "hour",
13
+ :product_group => "dyno",
14
+ :product_name => "web"
15
+ },
16
+ {
17
+ :hid => 123,
18
+ :from => Time.mktime(2000,1),
19
+ :to => Time.mktime(2000,2),
20
+ :qty => 744,
21
+ :rate => 5,
22
+ :rate_period => "hour",
23
+ :product_group => "dyno",
24
+ :product_name => "worker"
25
+ }
26
+ ]
27
+ end
28
+
29
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ class UsageReportTest < MiniTest::Unit::TestCase
4
+
5
+ def test_init_report
6
+ usage_report = VaultClient::UsageReport.new(account_id, from, to, Fixtures.billable_units)
7
+ assert(!usage_report.nil?, "Expected a usage report. Got nil")
8
+ end
9
+
10
+ def test_report_returns_from
11
+ usage_report = VaultClient::UsageReport.new(account_id, from, to, Fixtures.billable_units)
12
+ assert(!usage_report.from.nil?, "Expected #from to return a Time. Got nil")
13
+ end
14
+
15
+ def test_report_returns_to
16
+ usage_report = VaultClient::UsageReport.new(account_id, from, to, Fixtures.billable_units)
17
+ assert(!usage_report.to.nil?, "Expected #to to return a Time. Got nil")
18
+ end
19
+
20
+ def test_report_returns_billable_units
21
+ usage_report = VaultClient::UsageReport.new(account_id, from, to, Fixtures.billable_units)
22
+ assert(!usage_report.billable_units.nil?, "Expected #billable_units to return a collection of billable_units. Got nil")
23
+ assert_equal(VaultClient::BillableUnit, usage_report.billable_units.first.class)
24
+ end
25
+
26
+ def account_id
27
+ 1
28
+ end
29
+
30
+ def from
31
+ Time.mktime(2000,1)
32
+ end
33
+
34
+ def to
35
+ Time.mktime(2000,2)
36
+ end
37
+
38
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ class ReportPresenterTest < VaultClientTest
4
+
5
+ def test_init
6
+ presenter = VaultClient::ReportPresenter.new(units)
7
+ assert(!presenter.nil?)
8
+ end
9
+
10
+ def test_returns_line_item_presenters
11
+ presenter = VaultClient::ReportPresenter.new(units)
12
+ lip = presenter.line_item_presenters
13
+ assert_equal(VaultClient::LineItemPresenter, lip.first.class)
14
+ end
15
+
16
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class ResourceOwnershipClientTest < MiniTest::Unit::TestCase
4
+
5
+ def test_activate
6
+ verb, uri, body = ResourceOwnershipClient.build_request(:activate, [123, 456])
7
+ assert_equal(:post, verb)
8
+ assert_equal("/resource_ownerships", uri)
9
+ assert_equal({:hid => 123, :account_id => 456}, body)
10
+ end
11
+
12
+ def test_deactivate
13
+ verb, uri, body = ResourceOwnershipClient.build_request(:deactivate, [123, 456])
14
+ assert_equal(:put, verb)
15
+ assert_equal("/resource_ownerships", uri)
16
+ assert_equal({:hid => 123, :prev_account_id => 456}, body)
17
+ end
18
+
19
+ def test_transfer
20
+ verb, uri, body = ResourceOwnershipClient.build_request(:transfer, [123, 456, 789])
21
+ assert_equal(:put, verb)
22
+ assert_equal("/resource_ownerships", uri)
23
+ assert_equal({:hid => 123,:prev_account_id => 456, :account_id => 789}, body)
24
+ end
25
+
26
+ def test_query_with_account_id
27
+ verb, uri = ResourceOwnershipClient.build_request(:query, :account_id => 1)
28
+ assert_equal(:get, verb)
29
+ assert_equal("/resource_ownerships?account_id=1", uri)
30
+ end
31
+
32
+ def test_query_with_hid
33
+ verb, uri = ResourceOwnershipClient.build_request(:query, :hid => 1)
34
+ assert_equal(:get, verb)
35
+ assert_equal("/resource_ownerships?hid=1", uri)
36
+ end
37
+
38
+ def test_query_with_account_id_and_hid
39
+ assert_raises(ArgumentError) {ResourceOwnershipClient.build_request(:query, :hid => 1, :account_id => 2)}
40
+ end
41
+
42
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ class LineItemBuilderTest < VaultClientTest
4
+
5
+ def test_build
6
+ line_items = VaultClient::LineItemBuilder.build(units)
7
+ assert(!line_items.nil?)
8
+ end
9
+
10
+ def test_build_creates_line_item_by_hid
11
+ line_items = VaultClient::LineItemBuilder.build(units)
12
+ assert_equal(1, line_items.length)
13
+ end
14
+
15
+ def test_build_creates_one_unit_group_for_line_item
16
+ line_item = VaultClient::LineItemBuilder.build(units).pop
17
+ assert_equal(1, line_item.unit_groups.length)
18
+ end
19
+
20
+ def test_build_puts_both_units_on_unit_group
21
+ line_item = VaultClient::LineItemBuilder.build(units).pop
22
+ unit_group = line_item.unit_groups.pop
23
+ assert_equal(2, unit_group.units.length)
24
+ end
25
+
26
+ end
@@ -0,0 +1,21 @@
1
+ $:.unshift("lib")
2
+ $:.unshift("test")
3
+
4
+ ENV["RACK_ENV"] = "test"
5
+
6
+ require "rubygems"
7
+ require "bundler"
8
+ Bundler.require(:default, :test)
9
+
10
+ require "minitest/autorun"
11
+ require "webmock/minitest"
12
+ require "vault_client"
13
+ require "fixtures"
14
+
15
+ class VaultClientTest < MiniTest::Unit::TestCase
16
+
17
+ def units
18
+ Fixtures.billable_units.map{|h| VaultClient::BillableUnit.new(h)}
19
+ end
20
+
21
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vault_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ryan Smith
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-16 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rest-client
16
+ requirement: &8576100 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.6.7
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *8576100
25
+ - !ruby/object:Gem::Dependency
26
+ name: json
27
+ requirement: &8572460 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.6.1
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *8572460
36
+ description: A ruby wrapper around The Vault's HTTP API.
37
+ email: ryan@heroku.com
38
+ executables: []
39
+ extensions: []
40
+ extra_rdoc_files: []
41
+ files:
42
+ - readme.md
43
+ - lib/dto/usage_report.rb
44
+ - lib/presenters/base_presenter.rb
45
+ - lib/presenters/unit_presenter.rb
46
+ - lib/presenters/unit_group_presenter.rb
47
+ - lib/presenters/report_presenter.rb
48
+ - lib/presenters/line_item_presenter.rb
49
+ - lib/usage_reports_client.rb
50
+ - lib/vault_client.rb
51
+ - lib/models/unit_group.rb
52
+ - lib/models/line_item.rb
53
+ - lib/models/usage_report.rb
54
+ - lib/models/billable_unit.rb
55
+ - lib/billable_events_client.rb
56
+ - lib/vault_helper.rb
57
+ - lib/services/line_item_builder.rb
58
+ - lib/services/report_builder.rb
59
+ - lib/resource_ownership_client.rb
60
+ - test/presenters/report_presenter_test.rb
61
+ - test/fixtures.rb
62
+ - test/models/usage_report_test.rb
63
+ - test/resource_ownership_client_test.rb
64
+ - test/services/line_item_builder_test.rb
65
+ - test/test_helper.rb
66
+ homepage: http://github.com/heroku/vault_client
67
+ licenses: []
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 1.8.10
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: The Vault
90
+ test_files:
91
+ - test/presenters/report_presenter_test.rb
92
+ - test/models/usage_report_test.rb
93
+ - test/resource_ownership_client_test.rb
94
+ - test/services/line_item_builder_test.rb