lce 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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE +21 -0
  8. data/README.md +98 -0
  9. data/Rakefile +5 -0
  10. data/lce.gemspec +30 -0
  11. data/lib/lce.rb +72 -0
  12. data/lib/lce/client.rb +34 -0
  13. data/lib/lce/client/connection.rb +23 -0
  14. data/lib/lce/client/errors.rb +25 -0
  15. data/lib/lce/client/request.rb +80 -0
  16. data/lib/lce/offer.rb +25 -0
  17. data/lib/lce/order.rb +51 -0
  18. data/lib/lce/quote.rb +34 -0
  19. data/lib/lce/version.rb +4 -0
  20. data/lib/paginated_array.rb +25 -0
  21. data/spec/fixtures/access_denied +20 -0
  22. data/spec/fixtures/account_disabled +20 -0
  23. data/spec/fixtures/check +464 -0
  24. data/spec/fixtures/offers/available_delivery_locations/found +785 -0
  25. data/spec/fixtures/offers/find/found +66 -0
  26. data/spec/fixtures/offers/find/not_found +15 -0
  27. data/spec/fixtures/order_params +23 -0
  28. data/spec/fixtures/orders/all/page_1 +111 -0
  29. data/spec/fixtures/orders/find/found +106 -0
  30. data/spec/fixtures/orders/find/not_found +15 -0
  31. data/spec/fixtures/orders/labels/labels.pdf +0 -0
  32. data/spec/fixtures/orders/labels/response +0 -0
  33. data/spec/fixtures/orders/place/created +106 -0
  34. data/spec/fixtures/orders/place/empty_params +15 -0
  35. data/spec/fixtures/orders/place/missing_params +15 -0
  36. data/spec/fixtures/orders/tracking +30 -0
  37. data/spec/fixtures/quote_params +25 -0
  38. data/spec/fixtures/quotes/all/page_1 +11594 -0
  39. data/spec/fixtures/quotes/all/page_2 +1665 -0
  40. data/spec/fixtures/quotes/find/found +492 -0
  41. data/spec/fixtures/quotes/find/not_found +15 -0
  42. data/spec/fixtures/quotes/request/created +492 -0
  43. data/spec/fixtures/quotes/request/empty_quote +15 -0
  44. data/spec/fixtures/quotes/request/missing_params +15 -0
  45. data/spec/lce/client_spec.rb +41 -0
  46. data/spec/lce/offer_spec.rb +85 -0
  47. data/spec/lce/order_spec.rb +136 -0
  48. data/spec/lce/quote_spec.rb +111 -0
  49. data/spec/lce_spec.rb +109 -0
  50. data/spec/paginated_array_spec.rb +55 -0
  51. data/spec/spec_helper.rb +17 -0
  52. data/tasks/rspec.rake +3 -0
  53. metadata +239 -0
@@ -0,0 +1,15 @@
1
+ HTTP/1.1 500 Internal Server Error
2
+ Server: nginx/1.6.0
3
+ Date: Tue, 12 Aug 2014 12:59:10 GMT
4
+ Content-Type: application/json
5
+ Content-Length: 471
6
+ Connection: keep-alive
7
+
8
+ {
9
+ "status":"failure",
10
+ "error":{
11
+ "type":"internal",
12
+ "message":"quote[shipper] is missing, quote[shipper][country] is missing, quote[shipper][postal_code] is missing, quote[shipper][city] is missing, quote[recipient] is missing, quote[recipient][country] is missing, quote[recipient][is_a_company] is missing, quote[recipient][postal_code] is missing, quote[recipient][city] is missing, quote[parcels] is missing"
13
+ },
14
+ "self":"https://test.lce.io/v1/quotes"
15
+ }
@@ -0,0 +1,15 @@
1
+ HTTP/1.1 500 Internal Server Error
2
+ Server: nginx/1.6.0
3
+ Date: Wed, 13 Aug 2014 12:47:00 GMT
4
+ Content-Type: application/json
5
+ Content-Length: 156
6
+ Connection: keep-alive
7
+
8
+ {
9
+ "status":"failure",
10
+ "error":{
11
+ "type":"internal",
12
+ "message":"quote[recipient][city] is missing"
13
+ },
14
+ "self":"https://test.lce.io/v1/quotes"
15
+ }
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lce::Client do
4
+ describe "#http_adapter" do
5
+ it "uses default faraday's adapter as a default" do
6
+ expect(subject.http_adapter).to be(Faraday.default_adapter)
7
+
8
+ end
9
+ end
10
+ describe "#host" do
11
+ it 'returns the correct host for the staging environment' do
12
+ expect(subject.host).to eql('https://test.lce.io')
13
+ end
14
+
15
+ it 'returns the correct host for the production environment' do
16
+ Lce.configuration.environment = :production
17
+ expect(subject.host).to eql('https://api.lce.io')
18
+ end
19
+ end
20
+ describe "#api version" do
21
+ it 'returns a string of the API version' do
22
+ expect(subject.api_version).to eql('v1')
23
+ end
24
+ it 'needs a valid version' do
25
+ Lce.configuration.api_version = 'api_version'
26
+ expect { subject.api_version }.to raise_error(Lce::Client::Errors::VersionError)
27
+ end
28
+ end
29
+ describe "#path" do
30
+ it 'returns a root path as default' do
31
+ expect(subject.send(:path).to_s).to eql('/')
32
+ end
33
+ context 'with a resource' do
34
+ it 'returns a path with aversion and a resource' do
35
+ Lce.configuration.api_version = 1
36
+ expect(subject.send(:path, :quotes).to_s).to eql('/v1/quotes')
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lce::Offer do
4
+ before do
5
+ Lce.configure do |config|
6
+ config.environment = :staging
7
+ config.login = 'login'
8
+ config.password = 'password'
9
+ config.logger.level = Logger::FATAL
10
+ end
11
+ end
12
+ describe ".find" do
13
+ let(:id) {'ff75b691-a2e0-46b0-9909-d529b2dbb90c'}
14
+ it 'returns an offer' do
15
+ stub_request(:get, "https://login:password@test.lce.io/v1/offers/#{id}")
16
+ .to_return(fixture('offers/find/found'))
17
+ expect(Lce::Offer.find(id).id).to eql(id)
18
+ end
19
+ context 'inexistant offer' do
20
+ let(:id) {'ff75b691-a2e0-46b0-9909-d529b2dbb90d'}
21
+ it 'raise an exception' do
22
+ stub_request(:get, "https://login:password@test.lce.io/v1/offers/#{id}")
23
+ .to_return(fixture('offers/find/not_found'))
24
+ expect{Lce::Offer.find(id).id}.to raise_error(Lce::Client::Errors::LceError, 'Offer not found')
25
+ end
26
+ end
27
+ end
28
+ describe "#place_order" do
29
+ let(:id) {'ff75b691-a2e0-46b0-9909-d529b2dbb90c'}
30
+ let(:params) {
31
+ {
32
+ shipper: {name: "Firstname Lastname", street: "street", phone: "+33699999999", email: "support@lce.io"},
33
+ recipient: {name: "Firstname Lastname", street: "street", phone: "+33699999999", email: "support@lce.io"},
34
+ parcels: []
35
+ }
36
+ }
37
+ let(:request_params) {
38
+ params.merge(offer_id: id)
39
+ }
40
+ it 'places an order for this offer' do
41
+ stub_request(:get, "https://login:password@test.lce.io/v1/offers/#{id}")
42
+ .to_return(fixture('offers/find/found'))
43
+
44
+ stub_request(:post, "https://login:password@test.lce.io/v1/orders")
45
+ .with(:body => {order: request_params})
46
+ .to_return(fixture('orders/place/created'))
47
+ offer = Lce::Offer.find(id)
48
+ order = offer.place_order(params)
49
+ expect(order).to be_a(Lce::Order)
50
+ end
51
+ end
52
+
53
+ describe "#available_delivery_locations" do
54
+ let(:params) {
55
+ {
56
+ street: "37 Avenue Jean Médecin",
57
+ city: "Nice"
58
+ }
59
+ }
60
+ context 'when the product doesn\'t support preset delivery locations' do
61
+ let(:id) {'ff75b691-a2e0-46b0-9909-d529b2dbb90c'}
62
+ it 'returns an empty array' do
63
+ stub_request(:get, "https://login:password@test.lce.io/v1/offers/#{id}")
64
+ .to_return(fixture('offers/find/found'))
65
+
66
+ offer = Lce::Offer.find(id)
67
+ expect(offer.available_delivery_locations(params).count).to eql(0)
68
+ end
69
+ end
70
+ context 'when the product support preset delivery locations' do
71
+ let(:id) {'563aeac0-4a88-4269-b9b7-48964a8678f0'}
72
+ let(:quote_id) {'cd8d1a03-bfec-4115-87ef-8f8ba91a7199'}
73
+
74
+ it 'looks for available delivery locations for delivery in shop' do
75
+ stub_request(:get, "https://login:password@test.lce.io/v1/quotes/#{quote_id}")
76
+ .to_return(fixture('quotes/find/found'))
77
+ stub_request(:get, "https://login:password@test.lce.io/v1/offers/#{id}/available_delivery_locations?location%5Bcity%5D=Nice&location%5Bstreet%5D=37%20Avenue%20Jean%20M%C3%A9decin")
78
+ .to_return(fixture('offers/available_delivery_locations/found'))
79
+ offer = Lce::Quote.find(quote_id).offers.select{|o| o.id == id}.first
80
+ expect(offer.available_delivery_locations(params).count).to eql(23)
81
+ end
82
+ end
83
+ end
84
+
85
+ end
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lce::Order do
4
+ before do
5
+ Lce.configure do |config|
6
+ config.environment = :staging
7
+ config.login = 'login'
8
+ config.password = 'password'
9
+ config.logger.level = Logger::FATAL
10
+ end
11
+ end
12
+
13
+ describe '.place' do
14
+ context "with invalid parameters" do
15
+ it "raises an error on an empty order" do
16
+ stub_request(:post, "https://login:password@test.lce.io/v1/orders")
17
+ .with(:body => '{"order":{}}')
18
+ .to_return(fixture('orders/place/empty_params'))
19
+
20
+ expect{ Lce::Order.place({})}.to raise_error(Lce::Client::Errors::LceError)
21
+ end
22
+
23
+ it "raises an error with missing params" do
24
+ params = {
25
+ shipper: {name: "Firstname Lastname", street: "street", phone: "+33699999999", email: "support@lce.io"},
26
+ recipient: {name: "Firstname Lastname", street: "street", phone: "+33699999999", email: "support@lce.io"},
27
+ parcels: []
28
+ }
29
+
30
+ stub_request(:post, "https://login:password@test.lce.io/v1/orders")
31
+ .with(:body => {order: params})
32
+ .to_return(fixture('orders/place/missing_params'))
33
+
34
+ expect{ Lce::Order.place(params)}.to raise_error(Lce::Client::Errors::LceError, 'order[offer_id] is missing')
35
+ end
36
+ end
37
+ context "with valid parameters" do
38
+ let(:params) {
39
+ {
40
+ offer_id: "ff75b691-a2e0-46b0-9909-d529b2dbb90c",
41
+ shipper: {name: "Firstname Lastname", street: "street", phone: "+33699999999", email: "support@lce.io"},
42
+ recipient: {name: "Firstname Lastname", street: "street", phone: "+33699999999", email: "support@lce.io"},
43
+ parcels: []
44
+ }
45
+ }
46
+ it "creates an order" do
47
+ stub_request(:post, "https://login:password@test.lce.io/v1/orders")
48
+ .with(:body => {order: params})
49
+ .to_return(fixture('orders/place/created'))
50
+ expect(Lce::Order.place(params)).to be_a(Lce::Order)
51
+ end
52
+ end
53
+ end
54
+
55
+ describe ".find" do
56
+ let(:id) {'8c43a2e1-a7ff-49fd-807e-3877d6dadc28'}
57
+ it 'returns an order' do
58
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders/#{id}")
59
+ .to_return(fixture('orders/find/found'))
60
+ expect(Lce::Order.find(id).id).to eql(id)
61
+ end
62
+ context 'inexistant order' do
63
+ let(:id) {'8c43a2e1-a7ff-49fd-807e-3877d6dadc29'}
64
+ it 'raises an error' do
65
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders/#{id}")
66
+ .to_return(fixture('orders/find/not_found'))
67
+ expect{Lce::Order.find(id).id}.to raise_error(Lce::Client::Errors::LceError, 'Order not found')
68
+ end
69
+ end
70
+ end
71
+ describe ".all" do
72
+ before do
73
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders")
74
+ .to_return(fixture('orders/all/page_1'))
75
+ end
76
+ it 'returns all orders' do
77
+ expect(Lce::Order.all.size).to eql(1)
78
+ end
79
+
80
+ it 'returns order object' do
81
+ expect(Lce::Order.all.first).to be_a(Lce::Order)
82
+ end
83
+
84
+ it 'returns a paginated array' do
85
+ expect(Lce::Order.all).to be_a(PaginatedArray)
86
+ end
87
+ it 'returns total count' do
88
+ expect(Lce::Order.all.total_count).to eql(1)
89
+ end
90
+ it 'returns current_page' do
91
+ expect(Lce::Order.all.current_page).to eql(1)
92
+ end
93
+ it 'returns page size' do
94
+ expect(Lce::Order.all.per_page).to eql(25)
95
+ end
96
+
97
+ end
98
+
99
+ describe "#labels" do
100
+ let(:id) {'8c43a2e1-a7ff-49fd-807e-3877d6dadc28'}
101
+ it 'returns the labels for this order' do
102
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders/#{id}")
103
+ .to_return(fixture('orders/find/found'))
104
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders/#{id}/labels.pdf")
105
+ .to_return(fixture('orders/labels/response'))
106
+
107
+ order = Lce::Order.find(id)
108
+ labels_file = File.read('spec/fixtures/orders/labels/labels.pdf', {mode: 'rb' })
109
+ expect(order.labels).to eql(labels_file)
110
+ end
111
+ end
112
+
113
+ describe "#tracking" do
114
+ let(:id) {'8c43a2e1-a7ff-49fd-807e-3877d6dadc28'}
115
+ it 'returns the tracking for this order' do
116
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders/#{id}")
117
+ .to_return(fixture('orders/find/found'))
118
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders/#{id}/tracking")
119
+ .to_return(fixture('orders/tracking'))
120
+
121
+ tracking_events_by_parcel = [{
122
+ "parcel_index"=>0,
123
+ "events"=> [{
124
+ "code"=>"shipment_created",
125
+ "happened_at"=>"2014-08-19T16:41:00+02:00",
126
+ "label"=>{"fr"=>"Expédition créée", "en"=>"Shipment created"},
127
+ "location"=>{"name"=>"Web Services"}
128
+ }]
129
+ }]
130
+
131
+ order = Lce::Order.find(id)
132
+ expect(order.tracking).to eql(tracking_events_by_parcel)
133
+ end
134
+ end
135
+
136
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lce::Quote do
4
+ before do
5
+ Lce.configure do |config|
6
+ config.environment = :staging
7
+ config.login = 'login'
8
+ config.password = 'password'
9
+ config.logger.level = Logger::FATAL
10
+ end
11
+ end
12
+ describe ".request" do
13
+ context "with invalid parameters" do
14
+ it "raises an error on an empty quote" do
15
+
16
+ stub_request(:post, "https://login:password@test.lce.io/v1/quotes")
17
+ .with(:body => '{"quote":{}}')
18
+ .to_return(fixture('quotes/request/empty_quote'))
19
+
20
+ expect{ Lce::Quote.request({})}.to raise_error(Lce::Client::Errors::LceError)
21
+ end
22
+
23
+ it "raises an error with missing params" do
24
+
25
+ params = {
26
+ shipper: {country: 'FR', postal_code: '31300', city: 'Toulouse'},
27
+ recipient: {country: 'FR', postal_code: '06000', is_a_company: true},
28
+ parcels: [{length: 15, width: 15, height: 15, weight: 2}]
29
+ }
30
+
31
+ stub_request(:post, "https://login:password@test.lce.io/v1/quotes")
32
+ .with(:body => {quote: params})
33
+ .to_return(fixture('quotes/request/missing_params'))
34
+
35
+ expect{ Lce::Quote.request(params)}.to raise_error(Lce::Client::Errors::LceError, 'quote[recipient][city] is missing')
36
+ end
37
+ end
38
+ context "with valid parameters" do
39
+ let(:params) {
40
+ {
41
+ shipper: {country: 'FR', postal_code: '31300', city: 'Toulouse'},
42
+ recipient: {country: 'FR', postal_code: '06000', city: 'Nice',is_a_company: true},
43
+ parcels: [{length: 15, width: 15, height: 15, weight: 2}]
44
+ }
45
+ }
46
+ it "creates a quote" do
47
+ stub_request(:post, "https://login:password@test.lce.io/v1/quotes")
48
+ .with(:body => {quote: params})
49
+ .to_return(fixture('quotes/request/created'))
50
+ expect(Lce::Quote.request(params)).to be_a(Lce::Quote)
51
+ end
52
+ end
53
+ end
54
+ describe ".find" do
55
+ let(:id) {'cd8d1a03-bfec-4115-87ef-8f8ba91a7199'}
56
+ it 'returns a quote' do
57
+ stub_request(:get, "https://login:password@test.lce.io/v1/quotes/#{id}")
58
+ .to_return(fixture('quotes/find/found'))
59
+ expect(Lce::Quote.find(id).id).to eql(id)
60
+ end
61
+ context 'inexistant quote' do
62
+ let(:id) {'cd8d1a03-bfec-4115-87ef-8f8ba91a7198'}
63
+ it 'returns a quote' do
64
+ stub_request(:get, "https://login:password@test.lce.io/v1/quotes/#{id}")
65
+ .to_return(fixture('quotes/find/not_found'))
66
+ expect{Lce::Quote.find(id).id}.to raise_error(Lce::Client::Errors::LceError, 'Quote not found')
67
+ end
68
+ end
69
+ end
70
+ describe ".all" do
71
+ before do
72
+ stub_request(:get, "https://login:password@test.lce.io/v1/quotes")
73
+ .to_return(fixture('quotes/all/page_1'))
74
+ end
75
+ it 'returns all quotes' do
76
+ expect(Lce::Quote.all.size).to eql(25)
77
+ end
78
+
79
+ it 'returns quote object' do
80
+ expect(Lce::Quote.all.first).to be_a(Lce::Quote)
81
+ end
82
+
83
+ it 'returns a paginated array' do
84
+ expect(Lce::Quote.all).to be_a(PaginatedArray)
85
+ end
86
+ it 'returns total count' do
87
+ expect(Lce::Quote.all.total_count).to eql(29)
88
+ end
89
+ it 'returns current_page' do
90
+ expect(Lce::Quote.all.current_page).to eql(1)
91
+ end
92
+ it 'returns page size' do
93
+ expect(Lce::Quote.all.per_page).to eql(25)
94
+ end
95
+ context 'with a second page' do
96
+ before do
97
+ stub_request(:get, "https://login:password@test.lce.io/v1/quotes?page=2")
98
+ .to_return(fixture('quotes/all/page_2'))
99
+ end
100
+ it 'returns all quotes' do
101
+ expect(Lce::Quote.all(2).size).to eql(4)
102
+ end
103
+ it 'returns total count' do
104
+ expect(Lce::Quote.all(2).total_count).to eql(29)
105
+ end
106
+ it 'returns current_page' do
107
+ expect(Lce::Quote.all(2).current_page).to eql(2)
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lce do
4
+ describe ".configure" do
5
+
6
+ it 'has a configuration' do
7
+ Lce.reset
8
+ expect(Lce.configuration).to be_a(Lce::Configuration)
9
+ end
10
+
11
+ it 'has a default environment' do
12
+ Lce.reset
13
+ expect(Lce.configuration.environment).to be :staging
14
+ end
15
+
16
+ it 'raises an exception when an environment is not supported' do
17
+ expect { Lce.configuration.environment = :jungle }.to raise_error
18
+ end
19
+
20
+ it 'doesn\'t have a default login'do
21
+ Lce.reset
22
+ expect(Lce.configuration.login).to be_nil
23
+ end
24
+
25
+ it 'has a default application name' do
26
+ Lce.reset
27
+ expect(Lce.configuration.application).to eql 'ruby-lce'
28
+ end
29
+
30
+ it 'uses the gem\'s version as its default' do
31
+ Lce.reset
32
+ expect(Lce.configuration.version).to be Lce::VERSION
33
+ end
34
+
35
+
36
+ it 'doesn\'t have a default password' do
37
+ Lce.reset
38
+ expect(Lce.configuration.password).to be_nil
39
+ end
40
+
41
+ context 'when configuration is overridden locally' do
42
+ before do
43
+ Lce.configure do |config|
44
+ config.environment = :production
45
+ config.login = 'login'
46
+ config.password = 'password'
47
+ config.application = 'My Great App'
48
+ config.version = 'E.32.R526'
49
+ end
50
+ end
51
+
52
+ it 'can override default values' do
53
+ expect(Lce.configuration.environment).to be :production
54
+ end
55
+
56
+ it 'can set a login' do
57
+ expect(Lce.configuration.login).to eq('login')
58
+ end
59
+
60
+ it 'can set a password' do
61
+ expect(Lce.configuration.password).to eq('password')
62
+ end
63
+
64
+ it 'customizes app name but retains the gem\'s name' do
65
+ expect(Lce.configuration.application).to eq("My Great App (ruby-lce)")
66
+ end
67
+
68
+ it 'customizes app version but retains the gem\'s version' do
69
+ expect(Lce.configuration.version).to eq("E.32.R526 (#{Lce::VERSION})")
70
+ end
71
+
72
+ end
73
+ end
74
+ describe '.check' do
75
+ context 'without authentication' do
76
+ before do
77
+ Lce.configure do |config|
78
+ config.environment = :staging
79
+ config.login = nil
80
+ config.password = nil
81
+ config.logger.level = Logger::FATAL
82
+ end
83
+ end
84
+ it 'raises an AccessDenied exception when not authenticated properly' do
85
+ stub_request(:get, "https://test.lce.io/").to_return(fixture('access_denied'))
86
+ expect {Lce.check}.to raise_error Lce::Client::Errors::AccessDenied
87
+ end
88
+ end
89
+ context 'with authentication' do
90
+ before do
91
+ Lce.configure do |config|
92
+ config.environment = :staging
93
+ config.login = 'login'
94
+ config.password = 'password'
95
+ config.logger.level = Logger::FATAL
96
+ end
97
+ end
98
+ it 'raises an AccountDisabled exception when account is disabled' do
99
+ stub_request(:get, "https://login:password@test.lce.io/").to_return(fixture('account_disabled'))
100
+ expect {Lce.check}.to raise_error Lce::Client::Errors::AccountDisabled
101
+ end
102
+ it 'return a description of the service' do
103
+ stub_request(:get, "https://login:password@test.lce.io/").to_return(fixture('check'))
104
+ expect(Lce.check.host).to eql('test.lce.io')
105
+ end
106
+ end
107
+
108
+ end
109
+ end