bitballoon 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bitballoon.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,43 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ bitballoon (0.0.2)
5
+ highline
6
+ oauth2 (>= 0.9.2)
7
+ slop
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ addressable (2.3.3)
13
+ crack (0.3.2)
14
+ faraday (0.8.8)
15
+ multipart-post (~> 1.2.0)
16
+ highline (1.6.14)
17
+ httpauth (0.2.0)
18
+ jwt (0.1.8)
19
+ multi_json (>= 1.5)
20
+ minitest (5.0.8)
21
+ multi_json (1.8.0)
22
+ multi_xml (0.5.5)
23
+ multipart-post (1.2.0)
24
+ oauth2 (0.9.2)
25
+ faraday (~> 0.8)
26
+ httpauth (~> 0.2)
27
+ jwt (~> 0.1.4)
28
+ multi_json (~> 1.0)
29
+ multi_xml (~> 0.5)
30
+ rack (~> 1.2)
31
+ rack (1.5.2)
32
+ slop (3.4.3)
33
+ webmock (1.11.0)
34
+ addressable (>= 2.2.7)
35
+ crack (>= 0.3.2)
36
+
37
+ PLATFORMS
38
+ ruby
39
+
40
+ DEPENDENCIES
41
+ bitballoon!
42
+ minitest
43
+ webmock
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Mathias Biilmann Christensen
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,130 @@
1
+ BitBalloon Ruby Client
2
+ ======================
3
+
4
+ BitBalloon is a hosting service for the programmable web. It understands your documents, processes forms and lets you do deploys, manage forms submissions, inject javascript snippets into sites and do intelligent updates of HTML documents through it's API.
5
+
6
+ Installation
7
+ ============
8
+
9
+ Install the gem by running
10
+
11
+ gem install bitballoon
12
+
13
+ or put it in a Gemfile and run `bundle install`
14
+
15
+ gem bitballoon
16
+
17
+
18
+ Authenticating
19
+ ==============
20
+
21
+ You'll need an application client id and a client secret before you can access the BitBalloon API. Please contact us at team@bitballoon.com for your credentials.
22
+
23
+ Once you have your credentials you can instantiate a BitBalloon client.
24
+
25
+ bitballoon = BitBalloon::Client.new(:client_id => "YOUR_API_KEY", :client_secret => "YOUR_API_SECRET")
26
+
27
+ Before you can make any requests to the API, you'll need to authenticate with OAuth2. The BitBalloon client supports two OAuth2 flows.
28
+
29
+ If you're authenticating on behalf of a user, you'll need to get a valid access token for that user. Use the BitBalloon client to request an authentication URL:
30
+
31
+ url = bitballoon.authorize_url(:redirect_uri => "http://www.example.com/callback")
32
+
33
+ The user then visits that URL and will be prompted to authorize your application to access his BitBalloon sites. If she grants permission, she'll be redirected back to the `redirect_uri` provided in the `authorize_url` call. This URL must match the redirect url configured for your BitBalloon application. Once the user comes back to your app, you'll be able to access a `code` query parameter that gives you an authorization code. Use this to finish the OAuth2 flow:
34
+
35
+ bitballoon.authorize!(token, :redirect_uri => "http://www.example.com/callback")
36
+
37
+
38
+ Sites
39
+ =====
40
+
41
+ Getting a list of all sites you have access to:
42
+
43
+ bitballoon.sites.each do |site|
44
+ puts site.url
45
+ end
46
+
47
+ Getting a specific site by id:
48
+
49
+ site = bitballoon.sites.get(id)
50
+
51
+ Creating a site from a directory:
52
+
53
+ site = bitballoon.sites.create(:dir => "/tmp/my-site")
54
+
55
+ Creating a site from a zip file:
56
+
57
+ site = bitballoon.sites.create(:zip => "/tmp/my-site.zip")
58
+
59
+ Both methods will create the site and upload the files. The site will then be processing.
60
+
61
+ site.state == "processing"
62
+ site.processing? == true
63
+
64
+ Refresh a site to update the state:
65
+
66
+ site.refresh
67
+
68
+ Use `wait_until_ready` to wait until a site has finished processing.
69
+
70
+ site = bitballoon.sites.create(:dir => "/tmp/my-site")
71
+ site.wait_for_ready
72
+ site.state == "ready"
73
+
74
+ Update the name of the site (its subdomain), the custom domain and the notification email for form submissions:
75
+
76
+ site.update(:subdomain => "my-site", :custom_domain => "www.example.com", :notification_email => "me@example.com")
77
+
78
+ Deleting a site:
79
+
80
+ site.destroy!
81
+
82
+ Forms
83
+ =====
84
+
85
+ Access all forms you have access to:
86
+
87
+ bitballoon.forms
88
+
89
+ Access forms for a specific site:
90
+
91
+ site = bitballoon.sites.get(id)
92
+ site.forms
93
+
94
+ Access a specific form:
95
+
96
+ form = bitballoon.forms.get(id)
97
+
98
+ Access a list of all form submissions you have access to:
99
+
100
+ bitballoon.submissions
101
+
102
+ Access submissions from a specific site
103
+
104
+ site = bitballoon.sites.get(id)
105
+ site.submissions
106
+
107
+ Access submissions from a specific form
108
+
109
+ form = bitballoon.forms.get(id)
110
+ form.submissions
111
+
112
+ Get a specific submission
113
+
114
+ bitballoon.submissions.get(id)
115
+
116
+ Files
117
+ =====
118
+
119
+ Access all files in a site:
120
+
121
+ site = bitballoon.sites.get(id)
122
+ site.files
123
+
124
+ Get a specific file:
125
+
126
+ file = site.files.get(path) # Example paths: "/css/main.css", "/index.html"
127
+
128
+ Reading a file:
129
+
130
+ file.read
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ t.pattern = "test/*_test.rb"
7
+ end
data/bin/bitballoon ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'slop'
4
+ require 'bitballoon'
5
+ require 'highline/import'
6
+
7
+ opts = Slop.parse do
8
+ on '-v', 'Print the version' do
9
+ puts "Version #{BitBalloon::VERSION}"
10
+ end
11
+
12
+ command 'deploy' do
13
+ run do |opts, args|
14
+ path = args.first ? File.expand_path(args.first) : Dir.getwd
15
+
16
+ raise "File or dir doesn't exist: #{path}" unless File.exist?(path)
17
+ raise "Can't deploy a single file" if File.file?(path) && !path.match(/\.zip$/)
18
+
19
+
20
+
21
+ credentials_path = File.exist?(File.expand_path(".bitballoon")) ? File.expand_path(".bitballoon") : "#{Dir.home}/.bitballoon"
22
+ if File.exist?(credentials_path)
23
+ access_token = JSON.parse(File.read(credentials_path))['access_token']
24
+ client = BitBalloon::Client.new(:access_token => access_token)
25
+ else
26
+ puts "Please enter your BitBalloon API Credentials (if you don't have any, you can create your credentials at https://www.bitballoon.com/applications)"
27
+ client_id = ask("Client ID:")
28
+ client_secret = ask("Client Secret:")
29
+ client = BitBalloon::Client.new(:client_id => client_id, :client_secret => client_secret)
30
+ client.authorize_from_credentials!
31
+ File.open(credentials_path, "w") do |file|
32
+ file.write(JSON.generate(:access_token => client.access_token))
33
+ end
34
+ puts "Wrote access token to '#{credentials_path}'"
35
+ end
36
+
37
+ site = path.match(/\.zip$/) ? client.sites.create(:zip => path) : client.sites.create(:dir => path)
38
+ puts "Waiting for processing"
39
+ site.wait_for_ready do |site|
40
+ puts "Polling site: #{site.id} - #{site.state}"
41
+ end
42
+ puts "Site deployed: #{site.url}"
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bitballoon/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "bitballoon"
8
+ gem.version = BitBalloon::VERSION
9
+ gem.authors = ["Mathias Biilmann Christensen"]
10
+ gem.email = ["mathias@bitballoon.com"]
11
+ gem.description = %q{API Client for BitBalloon}
12
+ gem.summary = %q{API Client for BitBalloon}
13
+ gem.homepage = "https://www.bitballoon.com"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency "oauth2", ">= 0.9.2"
21
+ gem.add_dependency "slop"
22
+ gem.add_dependency "highline"
23
+ gem.add_development_dependency "minitest"
24
+ gem.add_development_dependency "webmock"
25
+ end
data/lib/bitballoon.rb ADDED
@@ -0,0 +1,13 @@
1
+ require "json"
2
+ require "bitballoon/version"
3
+ require "bitballoon/client"
4
+ require "bitballoon/collection_proxy"
5
+ require "bitballoon/model"
6
+ require "bitballoon/sites"
7
+ require "bitballoon/forms"
8
+ require "bitballoon/submissions"
9
+ require "bitballoon/files"
10
+
11
+ module BitBalloon
12
+ # Your code goes here...
13
+ end
@@ -0,0 +1,49 @@
1
+ require 'oauth2'
2
+
3
+ module BitBalloon
4
+ class Client
5
+ ENDPOINT = ENV['OAUTH_CLIENT_API_URL'] || 'https://www.bitballoon.com'
6
+ API_VERSION = "v1"
7
+
8
+ attr_accessor :client_id, :client_secret, :oauth, :access_token
9
+
10
+ def initialize(options)
11
+ self.client_id = options[:client_id]
12
+ self.client_secret = options[:client_secret]
13
+ self.access_token = options[:access_token]
14
+ self.oauth = OAuth2::Client.new(client_id, client_secret, :site => ENDPOINT, :connection_build => lambda {|f|
15
+ f.request :multipart
16
+ f.request :url_encoded
17
+ f.adapter :net_http
18
+ })
19
+ end
20
+
21
+ def authorize_url(options)
22
+ oauth.auth_code.authorize_url(options)
23
+ end
24
+
25
+ def authorize_from_code!(authorization_code, options)
26
+ @oauth_token = oauth.auth_code.get_token(authorization_code, options)
27
+ self.access_token = oauth_token.token
28
+ end
29
+
30
+ def authorize_from_credentials!
31
+ @oauth_token = oauth.client_credentials.get_token
32
+ self.access_token = oauth_token.token
33
+ end
34
+
35
+ def sites
36
+ Sites.new(self)
37
+ end
38
+
39
+ def request(verb, path, opts={}, &block)
40
+ raise "Authorize with BitBalloon before making requests" unless oauth_token
41
+ oauth_token.request(verb, ::File.join("/api", API_VERSION, path), opts, &block)
42
+ end
43
+
44
+ private
45
+ def oauth_token
46
+ @oauth_token ||= access_token && OAuth2::AccessToken.new(oauth, access_token)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,43 @@
1
+ module BitBalloon
2
+ class CollectionProxy
3
+ include Enumerable
4
+
5
+ attr_accessor :client, :prefix
6
+
7
+ def self.path(value = nil)
8
+ return @path unless value
9
+ @path = value
10
+ end
11
+
12
+ def self.model(value = nil)
13
+ @model ||= BitBalloon.const_get(to_s.split("::").last.sub(/s$/, ''))
14
+ end
15
+
16
+ def initialize(client, prefix = nil)
17
+ self.client = client
18
+ self.prefix = prefix
19
+ end
20
+
21
+ def all
22
+ response = client.request(:get, [prefix, path].compact.join("/"))
23
+ response.parsed.map {|attributes| model.new(client, attributes) } if response.parsed
24
+ end
25
+
26
+ def each(&block)
27
+ all.each(&block)
28
+ end
29
+
30
+ def get(id)
31
+ response = client.request(:get, ::File.join(path, id))
32
+ model.new(client, response.parsed) if response.parsed
33
+ end
34
+
35
+ def model
36
+ self.class.model
37
+ end
38
+
39
+ def path
40
+ self.class.path
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,7 @@
1
+ module BitBalloon
2
+ class File < Model
3
+ fields :id, :path, :sha, :mime_type, :size
4
+
5
+
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require "bitballoon/file"
2
+
3
+ module BitBalloon
4
+ class Files < CollectionProxy
5
+ path "/files"
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module BitBalloon
2
+ class Form < Model
3
+ fields :id, :site_id, :name, :paths, :submission_count, :fields, :created_at
4
+
5
+ def submissions
6
+ Submissions.new(client, path).all
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ require "bitballoon/form"
2
+
3
+ module BitBalloon
4
+ class Forms < CollectionProxy
5
+ path "/forms"
6
+ end
7
+ end
@@ -0,0 +1,53 @@
1
+ module BitBalloon
2
+ class Model
3
+ attr_reader :client
4
+
5
+ def self.fields(*names)
6
+ return @fields if names.empty?
7
+
8
+ @fields ||= []
9
+
10
+ names.each do |name|
11
+ define_method name do
12
+ @attributes[name.to_sym]
13
+ end
14
+
15
+ define_method "#{name}=" do |value|
16
+ @attributes[name.to_sym] = value
17
+ end
18
+
19
+ @fields.push(name.to_sym)
20
+ end
21
+ end
22
+
23
+ def self.collection(value = nil)
24
+ @collection ||= BitBalloon.const_get(to_s.split("::").last + "s")
25
+ end
26
+
27
+ def initialize(client, attributes)
28
+ @client = client
29
+ @attributes = {}
30
+ process(attributes)
31
+ end
32
+
33
+ def process(attributes)
34
+ self.class.fields.each do |field|
35
+ @attributes[field] = attributes[field] || attributes[field.to_s]
36
+ end
37
+ self
38
+ end
39
+
40
+ def refresh
41
+ response = client.request(:get, path)
42
+ process(response.parsed)
43
+ end
44
+
45
+ def collection
46
+ self.class.collection
47
+ end
48
+
49
+ def path
50
+ ::File.join(collection.path, id)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,63 @@
1
+ require 'digest/sha1'
2
+
3
+ module BitBalloon
4
+ class Site < Model
5
+ fields :id, :state, :premium, :claimed, :name, :custom_domain, :url,
6
+ :admin_url, :screenshot_url, :created_at, :updated_at, :user_id,
7
+ :required
8
+
9
+ def upload_dir(dir)
10
+ return unless state == "uploading"
11
+
12
+ shas = {}
13
+ Dir[::File.join(dir, "**", "*")].each do |file|
14
+ next unless ::File.file?(file)
15
+ pathname = ::File.join("/", file[dir.length..-1])
16
+ next if pathname.match(/(^\/?__MACOSX\/|\/\.)/)
17
+ shas[Digest::SHA1.hexdigest(::File.read(file))] = pathname
18
+ end
19
+
20
+ (required || []).each do |sha|
21
+ client.request(:put, ::File.join(path, "files", shas[sha]), :body => ::File.read(::File.join(dir, shas[sha])))
22
+ end
23
+
24
+ refresh
25
+ end
26
+
27
+ def ready?
28
+ state == "ready"
29
+ end
30
+
31
+ def wait_for_ready(timeout = 900)
32
+ start = Time.now
33
+ while !ready?
34
+ sleep 5
35
+ refresh
36
+ yield(self) if block_given?
37
+ raise "Timeout while waiting for ready" if Time.now - start > timeout
38
+ end
39
+ self
40
+ end
41
+
42
+ def update(attributes)
43
+ raise "Not implemented yet"
44
+ end
45
+
46
+ def destroy!
47
+ client.request(:delete, path)
48
+ true
49
+ end
50
+
51
+ def forms
52
+ Forms.new(client, path)
53
+ end
54
+
55
+ def submissions
56
+ Submissions.new(client, path)
57
+ end
58
+
59
+ def files
60
+ Files.new(client, path)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,36 @@
1
+ require "bitballoon/site"
2
+ require "digest/sha1"
3
+
4
+ module BitBalloon
5
+ class Sites < CollectionProxy
6
+ path "/sites"
7
+
8
+ def create(attributes = {})
9
+ if attributes[:dir]
10
+ dir = attributes[:dir]
11
+ response = client.request(:post, "/sites", :body => JSON.generate({:files => inventory(dir)}), :headers => {"Content-Type" => "application/json"})
12
+ Site.new(client, response.parsed).tap do |site|
13
+ site.upload_dir(dir)
14
+ end
15
+ elsif attributes[:zip]
16
+ ::File.open(attributes[:zip]) do |file|
17
+ response = client.request(:post, "/sites", :body => {
18
+ :zip => Faraday::UploadIO.new(file, 'application/zip')
19
+ })
20
+ Site.new(client, response.parsed)
21
+ end
22
+ end
23
+ end
24
+
25
+ private
26
+ def inventory(dir)
27
+ files = {}
28
+ Dir[::File.join(dir, "**", "*")].each do |file|
29
+ next unless ::File.file?(file)
30
+ path = ::File.join("/", file[dir.length..-1])
31
+ files[path] = Digest::SHA1.hexdigest(::File.read(file))
32
+ end
33
+ files
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,6 @@
1
+ module BitBalloon
2
+ class Submission < Model
3
+ fields :id, :number, :title, :email, :name, :first_name, :last_name,
4
+ :company, :summary, :body, :data, :created_at, :site_url
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ require "bitballoon/submission"
2
+
3
+ module BitBalloon
4
+ class Submissions < CollectionProxy
5
+ path "/submissions"
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module BitBalloon
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,73 @@
1
+ require 'test_helper'
2
+
3
+ class ClientTest < MiniTest::Unit::TestCase
4
+ attr_reader :client
5
+
6
+ def setup
7
+ @client = BitBalloon::Client.new(:client_id => "client_id", :client_secret => "client_secret")
8
+ end
9
+
10
+ def test_authorize_url
11
+ expected = "https://www.bitballoon.com/oauth/authorize?response_type=code&client_id=client_id&redirect_uri=http%3A%2F%2Fexample.com%2Fcallback"
12
+ assert_equal expected, client.authorize_url(:redirect_uri => "http://example.com/callback")
13
+ end
14
+
15
+ def test_authorize_from_code
16
+ stub_request(:post, "https://www.bitballoon.com/oauth/token").to_return(
17
+ :headers => {'Content-Type' => 'application/json'},
18
+ :body => {
19
+ "access_token" => "2YotnFZFEjr1zCsicMWpAA"
20
+ })
21
+ client.authorize_from_code!("authorization_code", :redirect_uri => "http://example.com/callback")
22
+ assert_equal "2YotnFZFEjr1zCsicMWpAA", client.access_token
23
+ end
24
+
25
+ def test_authorize_from_credentials
26
+ stub_request(:post, "https://client_id:client_secret@www.bitballoon.com/oauth/token").to_return(
27
+ :headers => {'Content-Type' => 'application/json'},
28
+ :body => {
29
+ "access_token" => "2YotnFZFEjr1zCsicMWpAA"
30
+ })
31
+
32
+ client.authorize_from_credentials!
33
+ assert_equal "2YotnFZFEjr1zCsicMWpAA", client.access_token
34
+ end
35
+
36
+ def test_simple_get_request
37
+ stub_request(:get, "https://www.bitballoon.com/api/v1/sites")
38
+ .with(:headers => {'Authorization' => "Bearer access_token"})
39
+ .to_return(
40
+ :headers => {'Content-Type' => 'application/json'},
41
+ :body => []
42
+ )
43
+
44
+ client.access_token = "access_token"
45
+ response = client.request(:get, "/sites")
46
+ assert_equal [], response.parsed
47
+ end
48
+
49
+ def test_sites
50
+ stub_request(:get, "https://www.bitballoon.com/api/v1/sites")
51
+ .with(:headers => {'Authorization' => "Bearer access_token"})
52
+ .to_return(
53
+ :headers => {'Content-Type' => 'application/json'},
54
+ :body => JSON.generate([{:url => "http://www.example.com"}])
55
+ )
56
+ client.access_token = "access_token"
57
+ sites = client.sites.all
58
+ assert_equal "http://www.example.com", sites.first.url
59
+ end
60
+
61
+ def test_get_site
62
+ stub_request(:get, "https://www.bitballoon.com/api/v1/sites/1234")
63
+ .with(:headers => {'Authorization' => "Bearer access_token"})
64
+ .to_return(
65
+ :headers => {'Content-Type' => 'application/json'},
66
+ :body => {:url => "http://www.example.com"}
67
+ )
68
+
69
+ client.access_token = "access_token"
70
+ site = client.sites.get("1234")
71
+ assert_equal "http://www.example.com", site.url
72
+ end
73
+ end
Binary file
@@ -0,0 +1,5 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head><title>Test Document</title></head>
4
+ <body><h1>Test</h1></body>
5
+ </html>
@@ -0,0 +1,52 @@
1
+ require 'test_helper'
2
+ require 'digest/sha1'
3
+
4
+ class SitesTest < MiniTest::Unit::TestCase
5
+ attr_reader :client
6
+ attr_accessor :_assertions
7
+
8
+ def setup
9
+ @client = BitBalloon::Client.new(:client_id => "client_id", :client_secret => "client_secret")
10
+ @client.access_token = "access_token"
11
+ self._assertions = 0
12
+ end
13
+
14
+ def test_create_from_dir
15
+ body = nil
16
+ dir = ::File.expand_path("../files/site-dir", __FILE__)
17
+ index_sha = Digest::SHA1.hexdigest(::File.read(::File.join(dir, "index.html")))
18
+
19
+ stub_request(:post, "https://www.bitballoon.com/api/v1/sites")
20
+ .to_return {|request|
21
+ body = JSON.parse(request.body)
22
+ {
23
+ :headers => {'Content-Type' => 'application/json'},
24
+ :body => JSON.generate({:id => "1234", :state => "uploading", :required => [index_sha]})
25
+ }
26
+ }
27
+ stub_request(:put, "https://www.bitballoon.com/api/v1/sites/1234/files/index.html")
28
+ stub_request(:get, "https://www.bitballoon.com/api/v1/sites/1234")
29
+ .to_return(:headers => {'Content-Type' => 'application/json'}, :body => {:id => "1234", :state => "processing"})
30
+
31
+ site = client.sites.create(:dir => dir)
32
+
33
+ assert_equal 'processing', site.state
34
+ assert_equal index_sha, body['files']['/index.html']
35
+
36
+ assert_requested :put, "https://www.bitballoon.com/api/v1/sites/1234/files/index.html",
37
+ :body => ::File.read(::File.join(dir, "index.html")), :times => 1 # ===> Success
38
+ end
39
+
40
+ def test_create_from_zip
41
+ stub_request(:post, "https://www.bitballoon.com/api/v1/sites")
42
+ .to_return({
43
+ :headers => {'Content-Type' => 'application/json'},
44
+ :body => JSON.generate({:id => "1234", :state => "processing", :required => []})
45
+ })
46
+
47
+ zip = ::File.expand_path("../files/site-dir.zip", __FILE__)
48
+ site = client.sites.create(:zip => zip)
49
+
50
+ assert_equal 'processing', site.state
51
+ end
52
+ end
@@ -0,0 +1,6 @@
1
+ require 'bitballoon'
2
+ require 'json'
3
+ require 'minitest'
4
+ require 'minitest/autorun'
5
+ # require 'minitest/pride'
6
+ require 'webmock/minitest'
metadata ADDED
@@ -0,0 +1,157 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bitballoon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mathias Biilmann Christensen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-09-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: oauth2
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.9.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.9.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: slop
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: highline
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: minitest
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: webmock
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: API Client for BitBalloon
95
+ email:
96
+ - mathias@bitballoon.com
97
+ executables:
98
+ - bitballoon
99
+ extensions: []
100
+ extra_rdoc_files: []
101
+ files:
102
+ - Gemfile
103
+ - Gemfile.lock
104
+ - LICENSE.txt
105
+ - README.md
106
+ - Rakefile
107
+ - bin/bitballoon
108
+ - bitballoon.gemspec
109
+ - lib/bitballoon.rb
110
+ - lib/bitballoon/client.rb
111
+ - lib/bitballoon/collection_proxy.rb
112
+ - lib/bitballoon/file.rb
113
+ - lib/bitballoon/files.rb
114
+ - lib/bitballoon/form.rb
115
+ - lib/bitballoon/forms.rb
116
+ - lib/bitballoon/model.rb
117
+ - lib/bitballoon/site.rb
118
+ - lib/bitballoon/sites.rb
119
+ - lib/bitballoon/submission.rb
120
+ - lib/bitballoon/submissions.rb
121
+ - lib/bitballoon/version.rb
122
+ - test/client_test.rb
123
+ - test/files/site-dir.zip
124
+ - test/files/site-dir/index.html
125
+ - test/sites_test.rb
126
+ - test/test_helper.rb
127
+ homepage: https://www.bitballoon.com
128
+ licenses: []
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ none: false
135
+ requirements:
136
+ - - ! '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ! '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 1.8.23
148
+ signing_key:
149
+ specification_version: 3
150
+ summary: API Client for BitBalloon
151
+ test_files:
152
+ - test/client_test.rb
153
+ - test/files/site-dir.zip
154
+ - test/files/site-dir/index.html
155
+ - test/sites_test.rb
156
+ - test/test_helper.rb
157
+ has_rdoc: