sendcloud-ruby 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 925c78de85ca4fb2cf19a3c3f3c405bd75317b99
4
+ data.tar.gz: 6ac99e7ad7e5afbbfd070fedb88df7e67548352b
5
+ SHA512:
6
+ metadata.gz: f05aa4716beacaaf2918fd93b2aa02d45c1b69d7e3ff2553a766d9cadfcc1e77fec8479928a2d3036c4010a6bd4d9d16b30f3a71201ea22bd91c0d5b9e671541
7
+ data.tar.gz: 3edc1714714bf6477ff289078e74075a99a084068c47eade006a159f5e89163ae00f8b81c5d16d1bc464222f170353f6af0af84936f3bfe43cd1d68594948413
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea/**
19
+ .idea
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem "codeclimate-test-reporter", group: :test, require: nil
4
+
5
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014-2015 PeRo ICT Solutions
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # Sendcloud
2
+
3
+ ***WORK IN PROGRESS***
4
+
5
+ [![wercker status](https://app.wercker.com/status/03866f33222cc05a0e18eb2aac723f5c/m "wercker status")](https://app.wercker.com/project/bykey/03866f33222cc05a0e18eb2aac723f5c)
6
+ [![Gem Version](https://badge.fury.io/rb/sendcloud.svg)](http://badge.fury.io/rb/sendcloud)
7
+ [![Code Climate](https://codeclimate.com/github/pero-ict-solutions/sendcloud/badges/gpa.svg)](https://codeclimate.com/github/pero-ict-solutions/sendcloud)
8
+ [![Test Coverage](https://codeclimate.com/github/pero-ict-solutions/sendcloud/badges/coverage.svg)](https://codeclimate.com/github/pero-ict-solutions/sendcloud)
9
+
10
+ Documentation on [RubyDoc](http://www.rubydoc.info/github/pero-ict-solutions/sendcloud/master)
11
+
12
+ Ruby API Client for the [SendCloud](https://www.sendcloud.nl) delivery platform.
13
+
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ gem 'sendcloud-ruby'
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install sendcloud-ruby
28
+
29
+ ## Contributing
30
+
31
+ 1. Fork it ( http://github.com/pero-ict-solutions/sendcloud/fork )
32
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
33
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
34
+ 4. Push to the branch (`git push origin my-new-feature`)
35
+ 5. Create new Pull Request
36
+
37
+
38
+ Copyright (c) 2014-2015 PeRo ICT Solutions
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/sendcloud.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "sendcloud/version"
2
+ require "sendcloud/base"
3
+ require "sendcloud/shipping_method"
4
+ require "sendcloud/parcel_resource"
5
+ require "sendcloud/shipment_address"
@@ -0,0 +1,30 @@
1
+ require 'httparty'
2
+
3
+ module Sendcloud
4
+ class Base
5
+ include HTTParty
6
+ format :json
7
+ base_uri 'https://panel.sendcloud.nl/api/v2/'
8
+
9
+ attr_accessor :api_key, :api_secret
10
+
11
+ #
12
+ # @param api_key [String] the `apikey` from your account settings
13
+ # @param api_secret [String] the `apisecret` from your account settings
14
+ def initialize(api_key, api_secret)
15
+ self.api_key = api_key
16
+ self.api_secret = api_secret
17
+ end
18
+
19
+ # get the auth hash to use for all the requests
20
+ # since the sendcloud api uses basic authentication
21
+ # it will be used in the subclasses like this:
22
+ # `HTTParty.get("http://twitter.com/statuses/public_timeline.json", :basic_auth => auth)`
23
+ #
24
+ # @return [Hash] the basic auth hash based on the api_key and api_secret
25
+ def auth
26
+ { username: api_key, password: api_secret}
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,61 @@
1
+ module Sendcloud
2
+ class ParcelResourceException < StandardError; end
3
+
4
+ class ParcelResource < Base
5
+ def create_parcel(name, shipment_address, shipment = {id: 1, options: []}, method_params = {})
6
+ response = self.class.post('/parcels',
7
+ body: {
8
+ parcel: {
9
+ name: name,
10
+ address: shipment_address.address,
11
+ city: shipment_address.city,
12
+ postal_code: shipment_address.postal_code,
13
+ country: shipment_address.country,
14
+ shipment: shipment,
15
+ requestShipment: false
16
+ }.merge(method_params).
17
+ merge(telephone: '', email: '', data: [])
18
+ }.to_json,
19
+ basic_auth: auth,
20
+ headers: {'Content-Type' => 'application/json'}
21
+ )
22
+ handle_response_error(response)
23
+ response['parcel']
24
+ end
25
+
26
+ def adjust_parcel(parcel_id)
27
+ response = self.class.put('/parcels',
28
+ body: {
29
+ parcel: {
30
+ id: parcel_id,
31
+ requestShipment: true
32
+ }
33
+ }.to_json,
34
+ basic_auth: auth,
35
+ headers: {'Content-Type' => 'application/json'}
36
+ )
37
+ handle_response_error(response)
38
+ response['parcel']
39
+ end
40
+
41
+ def show_parcel(parcel_id)
42
+ response = self.class.get("/parcels/#{parcel_id}", basic_auth: auth)
43
+ handle_response_error(response)
44
+ response['parcel']
45
+ end
46
+
47
+ def get_label_parcel(parcel_id)
48
+ response = self.class.get("/labels/#{parcel_id}", basic_auth: auth,
49
+ headers: {'Content-Type' => 'application/json'})
50
+ handle_response_error(response)
51
+ response['label']
52
+ end
53
+
54
+ private
55
+ def handle_response_error(response)
56
+ if response['error']
57
+ raise ParcelResourceException.new(response['error']['message'])
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,5 @@
1
+ module Sendcloud
2
+ class ShipmentAddress < Struct.new(:address, :city, :postal_code, :country)
3
+
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ module Sendcloud
2
+ class ShippingMethodException < StandardError; end
3
+
4
+ class ShippingMethod < Base
5
+ def list
6
+ response = self.class.get("/shipping_methods", :basic_auth => auth)
7
+ response["shipping_methods"]
8
+ end
9
+
10
+ def get(shipping_id)
11
+ response = self.class.get("/shipping_methods/#{shipping_id}", :basic_auth => auth)
12
+ if response["error"]
13
+ raise ShippingMethodException.new(response["error"]["message"])
14
+ end
15
+ response["shipping_method"]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module Sendcloud
2
+ VERSION = "1.0.0"
3
+ end
data/sendcloud.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sendcloud/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sendcloud-ruby"
8
+ spec.version = Sendcloud::VERSION
9
+ spec.authors = ["Peter Berkenbosch"]
10
+ spec.email = ["peter@pero-ict.nl"]
11
+ spec.summary = %q{ruby client for the sendcloud api}
12
+ spec.description = spec.summary
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "httparty"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.5"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency 'rspec'
26
+ spec.add_development_dependency 'vcr'
27
+ spec.add_development_dependency 'webmock'
28
+ spec.add_development_dependency 'pry'
29
+ spec.add_development_dependency 'yard'
30
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sendcloud::Base do
4
+
5
+ context ".auth" do
6
+ it "returns a hash for basic_auth with api key and secret" do
7
+ basic_auth_hash = {username: "key", password: "secret"}
8
+ expect(Sendcloud::Base.new("key","secret").auth).to eql basic_auth_hash
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sendcloud::ParcelResource do
4
+ let!(:new_parcel){
5
+ {
6
+ "name"=>"Rob van den Heuvel",
7
+ "shipment_address" => Sendcloud::ShipmentAddress.new('Torenallee', 'Eindhoven', '5617BC', 'NL')
8
+ }
9
+ }
10
+ context 'create Parcel' do
11
+
12
+ it 'with valid params' do
13
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
14
+ VCR.use_cassette('create_parcel') do
15
+ parcel = pr.create_parcel(new_parcel['name'], new_parcel['shipment_address'], {id: 1})
16
+ expect(parcel).not_to be_empty
17
+ expect(parcel).to include('name'=>'Rob van den Heuvel')
18
+ expect(parcel).to include('id')
19
+ end
20
+ end
21
+
22
+ context 'without name' do
23
+ it 'will return a error' do
24
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
25
+ VCR.use_cassette('wrong_create_parcel_without_name') do
26
+ expect{pr.create_parcel(nil, new_parcel['shipment_address'], {id: 1})}.
27
+ to raise_error(Sendcloud::ParcelResourceException, 'Name is required')
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ context 'adjust Parcel' do
34
+ it 'with valid parcel_id' do
35
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
36
+ VCR.use_cassette('adjust_parcel') do
37
+ parcel = pr.create_parcel(new_parcel['name'], new_parcel['shipment_address'], {id: 1})
38
+ adjust_parcel = pr.adjust_parcel(parcel['id'])
39
+ expect(adjust_parcel).not_to be_empty
40
+ expect(adjust_parcel['status']).not_to be_empty
41
+ expect(adjust_parcel).to include('id')
42
+ end
43
+ end
44
+ it 'with invalid parcel_id' do
45
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
46
+ VCR.use_cassette('adjust_with_wrong_parcel_id') do
47
+ parcel_id = 123456
48
+ expect{pr.adjust_parcel(parcel_id)}.to raise_error(Sendcloud::ParcelResourceException,
49
+ "Parcel is not found with ID: #{parcel_id}")
50
+ end
51
+ end
52
+ end
53
+
54
+ context 'get parcel' do
55
+ it 'with valid parcel_id' do
56
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
57
+ VCR.use_cassette('get_parcel_info') do
58
+ parcel = pr.create_parcel(new_parcel['name'], new_parcel['shipment_address'], {id: 1})
59
+ info = pr.show_parcel(parcel['id'])
60
+ expect(info).not_to be_empty
61
+ expect(info['id']).to eql(parcel['id'])
62
+ end
63
+ end
64
+
65
+ it 'with invalid parcel_id' do
66
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
67
+ VCR.use_cassette('get_parcel_error_with_invalid_pracel_id') do
68
+ parcel_id = 123456
69
+ expect{pr.show_parcel(parcel_id)}.to raise_error(Sendcloud::ParcelResourceException,
70
+ "You aren't authorized to get this parcel")
71
+ end
72
+ end
73
+ end
74
+
75
+ context 'get label' do
76
+ it 'with valid parcel_id' do
77
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
78
+ VCR.use_cassette('get_label_for_parcel') do
79
+ parcel = pr.create_parcel(new_parcel['name'], new_parcel['shipment_address'], {id: 1})
80
+ adjust_parcel = pr.adjust_parcel(parcel['id'])
81
+ label = pr.get_label_parcel(adjust_parcel['id'])
82
+ expect(label['normal_printer']).not_to be_empty
83
+ expect(label['label_printer']).not_to be_empty
84
+ end
85
+ end
86
+
87
+ it 'with invalid parcel_id' do
88
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
89
+ VCR.use_cassette('get_label_for_parcel_with_invalid_id') do
90
+ parcel_id = 123456
91
+ expect{pr.get_label_parcel(parcel_id)}.to raise_error(Sendcloud::ParcelResourceException,
92
+ "Cannot find parcel with given Parcel ID (#{parcel_id})")
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sendcloud::ShippingMethod do
4
+
5
+ context ".list" do
6
+ it "returns the list of available shipping methods" do
7
+ sm = Sendcloud::ShippingMethod.new("key", "secret")
8
+ VCR.use_cassette('get_shipping_methods') do
9
+ methods = sm.list
10
+ expect(methods).to_not be_empty
11
+ end
12
+ end
13
+ end
14
+
15
+ context ".get" do
16
+
17
+ context "with correct shipping_method id" do
18
+
19
+ let(:post_nl_shipping_method_hash) {
20
+ {
21
+ "id"=>1,
22
+ "name"=>"Pakket Nederland (PostNL)",
23
+ "countries"=>[
24
+ {
25
+ "id"=>2,
26
+ "iso_3"=>"NLD",
27
+ "iso_2"=>"NL",
28
+ "name"=>"Nederland",
29
+ "price"=>5.8
30
+ }
31
+ ],
32
+ "price"=>5.8,
33
+ "options"=>[],
34
+ "combinations"=>[{"id"=>1, "name"=>"Normaal pakket"}]
35
+ }
36
+ }
37
+
38
+ it "will return the shipping method details" do
39
+ sm = Sendcloud::ShippingMethod.new("D74gAPTNto4N28N", "Yb6m0YVBXtWm2zTdk")
40
+ VCR.use_cassette('get_shipping_method') do
41
+ shipping_method = sm.get(1)
42
+ expect(shipping_method).to eql post_nl_shipping_method_hash
43
+ end
44
+ end
45
+ end
46
+
47
+ context "with invalid shipping_method id" do
48
+ it "will return a proper message" do
49
+ sm = Sendcloud::ShippingMethod.new("key", "secret")
50
+ VCR.use_cassette('get_wrong_shipping_method') do
51
+ expect{sm.get(99)}.to raise_error(Sendcloud::ShippingMethodException, "Can't find shipping method with given ID (99)")
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ end
@@ -0,0 +1,30 @@
1
+ require "codeclimate-test-reporter"
2
+ CodeClimate::TestReporter.start
3
+
4
+ require 'sendcloud'
5
+ require 'pry'
6
+ require 'vcr'
7
+ require 'webmock'
8
+
9
+ # This file was generated by the `rspec --init` command. Conventionally, all
10
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
11
+ # Require this file using `require "spec_helper"` to ensure that it is only
12
+ # loaded once.
13
+ #
14
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
15
+ RSpec.configure do |config|
16
+ config.run_all_when_everything_filtered = true
17
+ config.filter_run :focus
18
+
19
+ # Run specs in random order to surface order dependencies. If you find an
20
+ # order dependency and want to debug it, you can fix the order by providing
21
+ # the seed, which is printed after each run.
22
+ # --seed 1234
23
+ config.order = 'random'
24
+ end
25
+
26
+ VCR.configure do |c|
27
+ c.cassette_library_dir = 'spec/vcr_cassettes'
28
+ c.hook_into :webmock # or :fakeweb
29
+ c.ignore_hosts 'codeclimate.com'
30
+ end