box_view 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NDM0ZmZhYjA5OTFmM2NiN2IxYTQ3ZDcyYjJjZTNmZTA2ZDJkZWEzYQ==
5
+ data.tar.gz: !binary |-
6
+ NzkzZWU2NWE2ZTc1ZWNlYWU2ZTQyZTk4YmM2ZWIwMmFlMGNhZDQ0Mw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ N2I2OGY2NzAyNzk5MjQxMDNmZmZjZjYzMDBjNTU2YmM4YmM0MGVhZWRlOGZh
10
+ NmI0NjY5OWM4NWVlMjIxMTNjNzQxZDc4NDE1NGM0Yzg2ZjA3NzYzMTlkMzI1
11
+ OGQwZDAyZDNmYTgxZjJmZGM4MDI2NDYwYjI3OTNlYTcwYjc1N2M=
12
+ data.tar.gz: !binary |-
13
+ ZDJjMjE3YjgwZGZkYzU5Y2VjOThhNTA2ZmY4MDNlM2IxMTAwYzlhNmVkYTkw
14
+ OTg1NzI2NmY5Y2YyMDVjZGUwYWMxNjdlMjBhY2YxMTMzZWFiMGQ1MDNkMDgw
15
+ OTJjNmYwOGU0ZjNkNTQ5NDdmY2Y2MmIyYmI3YmNiMWFmYTllZjI=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
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
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in box_view.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 reillyforshaw
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,72 @@
1
+ # BoxView
2
+
3
+ A ruby client for [Box's View API](http://developers.box.com/view/).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'box_view'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install box_view
18
+
19
+ ## Usage
20
+
21
+ Configure with your Box View API key.
22
+
23
+ BoxView::Session.config do |config|
24
+ config.box_view_token = YOUR_API_KEY
25
+ end
26
+
27
+ Or configure a session and pass it to the API when you instatiate it.
28
+
29
+ session = BoxView::Session.new(token: YOUR_API_KEY)
30
+ BoxView::Api::Document.new(session)
31
+
32
+ Upload a document at a url.
33
+
34
+ doc = BoxView::Api::Document.new.upload("http://www.example.com/myfile.pdf", "My File")
35
+
36
+ Check the document's `status`. When it is "done", you're ready to generate a viewing session.
37
+
38
+ doc = doc.reload
39
+ if doc.status == "done"
40
+ document_session = doc.document_session
41
+ view_url = document_session.view_url
42
+ end
43
+
44
+ Remove the document from Box View.
45
+
46
+ doc.destroy
47
+
48
+ List all of your Box View documents.
49
+
50
+ docs = BoxView::Api::Document.new.list
51
+
52
+ Generate a thumbnail of a document
53
+
54
+ f = File.open("myfile.pdf", 'w')
55
+ f.write(doc.thumbnail(100, 100))
56
+ f.flush
57
+ f.close
58
+
59
+ Download the conents in pdf or zip format
60
+
61
+ f = File.open("myfile.pdf", 'w')
62
+ f.write(doc.content("pdf"))
63
+ f.flush
64
+ f.close
65
+
66
+ ## Contributing
67
+
68
+ 1. Fork it
69
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
70
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
71
+ 4. Push to the branch (`git push origin my-new-feature`)
72
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ desc "Open an irb session preloaded with this library"
4
+ task :console do
5
+ sh "irb -rubygems -I lib -r box_view.rb"
6
+ end
data/box_view.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'box_view/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "box_view"
8
+ spec.version = BoxView::VERSION
9
+ spec.authors = ["Reilly Forshaw"]
10
+ spec.email = ["reilly.forshaw@goclio.com"]
11
+ spec.description = "API client for Box View"
12
+ spec.summary = "A ruby library to interact with Box View"
13
+ spec.homepage = "https://github.com/reillyforshaw/box_view"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
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_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
@@ -0,0 +1,20 @@
1
+ module BoxView
2
+ module Api
3
+ module Actions
4
+ module Crudable
5
+
6
+ def create(params)
7
+ data_item(session.post(endpoint_url, session.convert_params(params).to_json), session)
8
+ end
9
+
10
+ def update(id, params)
11
+ data_item(session.put("#{endpoint_url}/#{id}", session.convert_params(params).to_json), session)
12
+ end
13
+
14
+ def destroy(id)
15
+ session.delete("#{endpoint_url}/#{id}", false)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ module BoxView
2
+ module Api
3
+ module Actions
4
+ module Findable
5
+
6
+ def find(id)
7
+ data_item(session.get("#{endpoint_url}/#{id}"), session)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module BoxView
2
+ module Api
3
+ module Actions
4
+ module Listable
5
+
6
+ def list(params={})
7
+ session.get(endpoint_url, params)["document_collection"]["entries"].collect{ |item| data_item(item, session) }
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,22 @@
1
+ module BoxView
2
+ module Api
3
+ class Base
4
+
5
+ attr_accessor :session
6
+
7
+ def initialize(session=nil)
8
+ self.session = session || BoxView::Session.new
9
+ end
10
+
11
+ private
12
+
13
+ def data_item(params, session)
14
+ data_klass.new(params, session)
15
+ end
16
+
17
+ def data_klass
18
+ raise NotImplementedError.new
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,47 @@
1
+ module BoxView
2
+ module Api
3
+ class Document < Base
4
+
5
+ include BoxView::Api::Actions::Findable
6
+ include BoxView::Api::Actions::Listable
7
+ include BoxView::Api::Actions::Crudable
8
+
9
+ def self.supported_filetypes
10
+ [:pdf, :doc, :docx, :ppt, :pptx]
11
+ end
12
+
13
+ def self.supported_filetype?(filetype)
14
+ supported_filetypes.include?(filetype.to_sym)
15
+ end
16
+
17
+ def create(*args)
18
+ raise NotImplementedError
19
+ end
20
+
21
+ def upload(url, name)
22
+ data_item(session.post(endpoint_url, { url: url, name: name }.to_json), session)
23
+ end
24
+
25
+ def thumbnail(id, width, height)
26
+ session.get("#{endpoint_url}/#{id}/thumbnail", { width: width, height: height }, false)
27
+ end
28
+
29
+ def content(id, extension=nil)
30
+ supported_extensions = %w(zip pdf)
31
+ raise ArgumentError.new("Unsupported content extension #{extension}. Must use one of #{supported_extensions} or nil.") unless supported_extensions.include?(extension) || extension.nil?
32
+
33
+ extension = ".#{extension}" if extension
34
+ session.get("#{endpoint_url}/#{id}/content#{extension}", {}, false)
35
+ end
36
+
37
+ private
38
+
39
+ def data_klass
40
+ BoxView::Models::Document
41
+ end
42
+
43
+ def endpoint_url; "documents"; end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,25 @@
1
+ module BoxView
2
+ module Api
3
+ class DocumentSession < Base
4
+
5
+ include BoxView::Api::Actions::Crudable
6
+
7
+ def update(*args)
8
+ raise NotImplementedError
9
+ end
10
+
11
+ def destroy(*args)
12
+ raise NotImplementedError
13
+ end
14
+
15
+ private
16
+
17
+ def data_klass
18
+ BoxView::Models::DocumentSession
19
+ end
20
+
21
+ def endpoint_url; "sessions"; end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,80 @@
1
+ module BoxView
2
+ module Http
3
+
4
+ require 'time'
5
+
6
+ def base_uri(path, params = {})
7
+ uri = URI.parse("https://view-api.box.com")
8
+ uri.path = path
9
+ uri.query = URI.encode_www_form(convert_params(params)) if params.any?
10
+ uri
11
+ end
12
+
13
+ def get(path, params={}, parse=true)
14
+ uri = base_uri("#{api_prefix}/#{path}", params)
15
+ req = Net::HTTP::Get.new(uri.to_s)
16
+ make_api_request(req, uri, parse)
17
+ end
18
+
19
+
20
+ def post(path, body="", parse=true)
21
+ uri = base_uri("#{api_prefix}/#{path}")
22
+ req = Net::HTTP::Post.new(uri.request_uri)
23
+ req.body = body
24
+ req.add_field("Content-Type", "application/json")
25
+ make_api_request(req, uri, parse)
26
+ end
27
+
28
+ def put(path, body="", parse=true)
29
+ uri = base_uri("#{api_prefix}/#{path}")
30
+ req = Net::HTTP::Put.new(uri.request_uri)
31
+ req.body = body
32
+ req.add_field("Content-Type", "application/json")
33
+ make_api_request(req, uri, parse)
34
+ end
35
+
36
+ def delete(path, parse=true)
37
+ uri = base_uri("#{api_prefix}/#{path}")
38
+ req = Net::HTTP::Delete.new(uri.request_uri)
39
+ make_api_request(req, uri, parse)
40
+ end
41
+
42
+ def make_api_request(req, uri, parse=true)
43
+ puts "BoxView::Http#make_api_request token not availble #{uri}" if self.token.nil? || self.token.empty?
44
+ return if self.token.nil? || self.token.empty?
45
+ req.add_field("Authorization", "Token #{self.token}")
46
+ make_request(req, uri, parse)
47
+ end
48
+
49
+ def make_request(req, uri, parse=true)
50
+ req.add_field("Accept", "text/json")
51
+ n = Net::HTTP.new(uri.host, uri.port)
52
+ n.use_ssl = true
53
+ res = n.start do |http|
54
+ http.request(req)
55
+ end
56
+ puts "BoxView::Http#make_request #{uri} response: #{res.body}#{" Parsing" if parse}"
57
+ parse_response(res, parse)
58
+ end
59
+
60
+ def parse_response(res, parse=true)
61
+ parse ? JSON.parse(res.body) : res.body
62
+ end
63
+
64
+ def convert_params(params)
65
+ params.each_pair do |key, val|
66
+ if [Date, Time, DateTime].include?(val.class)
67
+ params[key] = val.iso8601
68
+ end
69
+ end
70
+ params
71
+ end
72
+
73
+ private
74
+
75
+ def api_prefix()
76
+ "/1"
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,86 @@
1
+ module BoxView
2
+ module Models
3
+
4
+ class ReadOnlyAttribute < Exception; end
5
+ class ResourceNotSaved < Exception; end
6
+
7
+ class Base
8
+
9
+ require 'time'
10
+
11
+ attr_accessor :session
12
+
13
+ def initialize(fields = {}, session = nil)
14
+ self.session = session
15
+ fields.each_pair do |k, v|
16
+ self.send("#{k}=", v) if self.respond_to?("#{k}=") && !v.nil?
17
+ end
18
+ end
19
+
20
+ def write_attribute(name, value)
21
+ instance_variable_set("@#{name}", value)
22
+ end
23
+
24
+ def reload
25
+ raise ResourceNotSaved.new if self.id.nil?
26
+ api.find(self.id)
27
+ end
28
+
29
+ def save
30
+ if self.id.nil?
31
+ created_item = api.create(self.to_params)
32
+ self.id = created_item && created_item.id
33
+ self
34
+ else
35
+ api.update(self.id, self.to_params)
36
+ self
37
+ end
38
+ end
39
+
40
+ def destroy
41
+ raise ResourceNotSaved.new if self.id.nil?
42
+ api.destroy(self.id)
43
+ end
44
+
45
+ def api
46
+ raise NotImplementedError.new
47
+ end
48
+
49
+ def to_params
50
+ raise NotImplementedError.new
51
+ end
52
+
53
+ class << self
54
+ def has_attributes(attributes)
55
+ attributes.each_pair do |name, options|
56
+ attr_reader name
57
+ define_method "#{name}=" do |value|
58
+ if options[:readonly] && !instance_variable_get("@#{name}").nil?
59
+ raise ReadOnlyAttribute.new(name)
60
+ end
61
+ write_attribute(name, self.class.convert_attribute(value, options[:type]))
62
+ end
63
+ end
64
+ end
65
+
66
+ def convert_attribute(value, type)
67
+ case type
68
+ when :date
69
+ (value.is_a?(Time) || value.is_a?(DateTime)) ? value.to_date : Date.parse(value)
70
+ when :time
71
+ (value.is_a?(Date) || value.is_a?(DateTime)) ? value.to_time : Time.parse(value)
72
+ when :datetime
73
+ (value.is_a?(Date) || value.is_a?(Time)) ? value.to_datetime : DateTime.parse(value)
74
+ when :integer
75
+ value.to_i
76
+ when :string
77
+ value.to_s
78
+ else
79
+ value
80
+ end
81
+ end
82
+ end
83
+
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,36 @@
1
+ module BoxView
2
+ module Models
3
+ class Document < Base
4
+
5
+ has_attributes(
6
+ type: { type: :string },
7
+ id: { type: :string },
8
+ status: { type: :string },
9
+ name: { type: :name },
10
+ created_at: { type: :datetime, readonly: true },
11
+ modified_at: { type: :datetime, readonly: true }
12
+ )
13
+
14
+ def document_session
15
+ @document_session ||= BoxView::Api::DocumentSession.new(session).create(document_id: self.id)
16
+ end
17
+
18
+ def thumbnail(width, height)
19
+ self.api.thumbnail(self.id, width, height)
20
+ end
21
+
22
+ def content(extension=nil)
23
+ self.api.content(self.id, extension)
24
+ end
25
+
26
+ def to_params
27
+ { name: self.name }
28
+ end
29
+
30
+ def api
31
+ @api ||= BoxView::Api::Document.new(session)
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,26 @@
1
+ module BoxView
2
+ module Models
3
+ class DocumentSession < Base
4
+
5
+ has_attributes(
6
+ type: { type: :string },
7
+ id: { type: :string },
8
+ expires_at: { type: :datetime, readonly: true }
9
+ )
10
+
11
+ def view_url(theme = "dark")
12
+ return nil if self.id.nil?
13
+ "https://view-api.box.com/view/#{self.id}?theme=#{theme}"
14
+ end
15
+
16
+ def to_params
17
+ {}
18
+ end
19
+
20
+ def api
21
+ @api ||= BoxView::Api::DocumentSession.new(session)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ module BoxView
2
+ class Session
3
+
4
+ include Http
5
+
6
+ attr_accessor :token
7
+
8
+ def initialize(credentials={})
9
+ self.token = credentials[:token] || self.class.box_view_token
10
+ end
11
+
12
+ class << self
13
+ attr_accessor :box_view_token
14
+
15
+ def config
16
+ yield self
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module BoxView
2
+ VERSION = "0.0.1"
3
+ end
data/lib/box_view.rb ADDED
@@ -0,0 +1,43 @@
1
+ require "box_view/version"
2
+
3
+ require "net/http"
4
+ require "json"
5
+
6
+ module BoxView
7
+ {
8
+ Session: 'session',
9
+ Http: 'http'
10
+ }.each_pair do |klass, file|
11
+ autoload klass, "box_view/#{file}"
12
+ end
13
+
14
+ module Models
15
+ {
16
+ Base: 'base',
17
+ Document: 'document',
18
+ DocumentSession: 'document_session'
19
+ }.each_pair do |klass, file|
20
+ autoload klass, "box_view/models/#{file}"
21
+ end
22
+ end
23
+
24
+ module Api
25
+ {
26
+ Base: 'base',
27
+ Document: 'document',
28
+ DocumentSession: 'document_session'
29
+ }.each_pair do |klass, file|
30
+ autoload klass, "box_view/api/#{file}"
31
+ end
32
+
33
+ module Actions
34
+ {
35
+ Crudable: 'crudable',
36
+ Findable: 'findable',
37
+ Listable: 'listable'
38
+ }.each_pair do |klass, file|
39
+ autoload klass, "box_view/api/actions/#{file}"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe BoxView::Api::Actions::Crudable do
4
+ let(:session) { double("BoxView::Api::Actions::Crudable") }
5
+ let(:params) { { text: "1" } }
6
+ let(:subject) {
7
+ d = DummyApi.new(session)
8
+ d.extend(BoxView::Api::Actions::Crudable)
9
+ d
10
+ }
11
+ let(:response) { { id: 1, text: "1"} }
12
+ before { session.stub(:convert_params).and_return(params) }
13
+
14
+ describe "#create" do
15
+ it "should send a create request" do
16
+ session.stub(:post).with("dummies", params.to_json).and_return(response)
17
+ record = subject.create(params)
18
+ expect(record).to be_kind_of(DummyResource)
19
+ expect(record.id).to eql(1)
20
+ end
21
+ end
22
+
23
+ describe "#update" do
24
+ it "should send an update request" do
25
+ session.stub(:put).with("dummies/1", params.to_json).and_return(response)
26
+ record = subject.update(1, params)
27
+ expect(record).to be_kind_of(DummyResource)
28
+ expect(record.id).to eql(1)
29
+ end
30
+ end
31
+
32
+ describe "#destroy" do
33
+ it "should send a delete request" do
34
+ session.should_receive(:delete)
35
+ subject.destroy(1)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe BoxView::Api::Actions::Findable do
4
+ let(:session) { double("BoxView::Api::Actions::Findable") }
5
+ let(:subject) {
6
+ d = DummyApi.new(session)
7
+ d.extend(BoxView::Api::Actions::Findable)
8
+ d
9
+ }
10
+
11
+ describe "#find" do
12
+ let(:response) do
13
+ { id: 1 }
14
+ end
15
+
16
+ it "should return the correct data item" do
17
+ session.stub(:get).and_return(response)
18
+ record = subject.find(1)
19
+ expect(record).to be_kind_of(DummyResource)
20
+ expect(record.id).to eql(1)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe BoxView::Api::Actions::Listable do
4
+ let(:session) { double("BoxView::Api::Actions::Listable") }
5
+ let(:subject) {
6
+ d = DummyApi.new(session)
7
+ d.extend(BoxView::Api::Actions::Listable)
8
+ d
9
+ }
10
+
11
+ describe "#list" do
12
+ let(:response) do
13
+ { "document_collection" => { "entries" => [{ id: 1 }, { id: 2 }] } }
14
+ end
15
+
16
+ it "should return the correct data items" do
17
+ session.stub(:get).and_return(response)
18
+ records = subject.list
19
+ expect(records.count).to eql(2)
20
+ expect(records.first).to be_kind_of(DummyResource)
21
+ expect(records.first.id).to eql(1)
22
+ expect(records.last.id).to eql(2)
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe BoxView::Api::Base do
4
+ let(:api) { BoxView::Api::Base.new(session) }
5
+ let(:session) { nil }
6
+
7
+ it "should ues the configured session" do
8
+ expect(api.session).to_not be_nil
9
+ end
10
+
11
+ context "when a session is suppied" do
12
+ let(:session) { "the session" }
13
+
14
+ it "should use the supplied session" do
15
+ expect(api.session).to eql(session)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe BoxView::Api::Document do
4
+ let(:session) { double("BoxView::Api::Session") }
5
+ let(:url) { "http://www.example.com/1.pdf" }
6
+ let(:name) { "Doc 1" }
7
+ let(:params) { { url: url, name: name } }
8
+ let(:subject) { BoxView::Api::Document.new(session) }
9
+
10
+ describe "#upload" do
11
+ let(:response) { { id: "1" } }
12
+
13
+ it "should send a post request" do
14
+ session.stub(:post).with("documents", params.to_json).and_return(response)
15
+ record = subject.upload(url, name)
16
+ expect(record).to be_kind_of(BoxView::Models::Document)
17
+ expect(record.id).to eql("1")
18
+ end
19
+ end
20
+
21
+ describe "#content" do
22
+ context "filename has invalid extension" do
23
+ it "should raise an ArgumentError" do
24
+ expect{subject.content("1", "foo.bar")}.to raise_error(ArgumentError)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,206 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe BoxView::Models::Base do
4
+ let(:model) { BoxView::Models::Base.new(fields, session) }
5
+ let(:fields) { {} }
6
+ let(:session) { nil }
7
+
8
+ before {
9
+ model.stub(:api).and_return(BoxView::Api::Base.new)
10
+ model.stub(:to_params).and_return({})
11
+ model.stub(:id).and_return(1)
12
+ }
13
+
14
+ describe "#reload" do
15
+ context "when the resource is not saved" do
16
+ before { model.stub(:id) }
17
+ it "should raise ResourceNotSaved" do
18
+ expect{model.reload}.to raise_error(BoxView::Models::ResourceNotSaved)
19
+ end
20
+ end
21
+
22
+ it "should use the api's find method" do
23
+ model.api.should_receive(:find)
24
+ model.reload
25
+ end
26
+ end
27
+
28
+ describe "#save" do
29
+ context "when the resource is not saved" do
30
+ before {
31
+ model.stub(:id)
32
+ model.api.stub(:create).and_return(double("BoxView::Models::Base", id: 1))
33
+ }
34
+ it "should use the api's create method" do
35
+ model.api.should_receive(:create)
36
+ model.should_receive(:id=)
37
+ model.save
38
+ end
39
+ end
40
+
41
+ it "should use the api's update method" do
42
+ model.api.should_receive(:update)
43
+ model.save
44
+ end
45
+ end
46
+
47
+ describe "#destroy" do
48
+ context "when the resource is not saved" do
49
+ before { model.stub(:id) }
50
+ it "should raise ResourceNotSaved" do
51
+ expect{model.destroy}.to raise_error(BoxView::Models::ResourceNotSaved)
52
+ end
53
+ end
54
+
55
+ it "should use the api's destroy method" do
56
+ model.api.should_receive(:destroy)
57
+ model.destroy
58
+ end
59
+ end
60
+
61
+ describe ".has_attributes" do
62
+ before do
63
+ BoxView::Models::Base.has_attributes(
64
+ foo: { type: :string, readonly: true },
65
+ bar: { type: :string }
66
+ )
67
+ end
68
+ let(:model) { BoxView::Models::Base.new({foo: "foo"}) }
69
+
70
+ it "should define getter for the given attributes" do
71
+ model.should respond_to :foo
72
+ end
73
+
74
+ it "should define setter for the given attributes" do
75
+ model.should respond_to :foo=
76
+ end
77
+
78
+ context "when an attribute is readonly" do
79
+ it "should create setter that throws an exception" do
80
+ expect{model.foo = "bar"}.to raise_error(BoxView::Models::ReadOnlyAttribute)
81
+ end
82
+ end
83
+
84
+ it "should convert the attribute when setting it" do
85
+ BoxView::Models::Base.should_receive :convert_attribute
86
+ model.bar = "bar"
87
+ end
88
+ end
89
+
90
+ describe ".convert_attribute" do
91
+ let(:result) { BoxView::Models::Base.convert_attribute(value, type) }
92
+
93
+ context "when type is date" do
94
+ let(:type) { :date }
95
+ let(:value) { "2014-02-11" }
96
+
97
+ context "when value is a Time" do
98
+ let(:value) { Time.new }
99
+
100
+ it "should call to_date on the value" do
101
+ value.should_receive(:to_date)
102
+ result
103
+ end
104
+ end
105
+
106
+ context "when value is a DateTime" do
107
+ let(:value) { DateTime.new }
108
+
109
+ it "should call to_date on the value" do
110
+ value.should_receive(:to_date)
111
+ result
112
+ end
113
+ end
114
+
115
+ it "should parse the value" do
116
+ Date.should_receive(:parse).with(value)
117
+ result
118
+ end
119
+ end
120
+
121
+ context "when type is time" do
122
+ let(:type) { :time }
123
+ let(:value) { "15:00:00" }
124
+
125
+ context "when value is a Date" do
126
+ let(:value) { Date.new }
127
+
128
+ it "should call to_time on the value" do
129
+ value.should_receive(:to_time)
130
+ result
131
+ end
132
+ end
133
+
134
+ context "when value is a DateTime" do
135
+ let(:value) { DateTime.new }
136
+
137
+ it "should call to_time on the value" do
138
+ value.should_receive(:to_time)
139
+ result
140
+ end
141
+ end
142
+
143
+ it "should parse the value" do
144
+ Time.should_receive(:parse).with(value)
145
+ result
146
+ end
147
+ end
148
+
149
+ context "when type is datetime" do
150
+ let(:type) { :datetime }
151
+ let(:value) { "15:00:00" }
152
+
153
+ context "when value is a Date" do
154
+ let(:value) { Date.new }
155
+
156
+ it "should call to_datetime on the value" do
157
+ value.should_receive(:to_datetime)
158
+ result
159
+ end
160
+ end
161
+
162
+ context "when value is a DateTime" do
163
+ let(:value) { DateTime.new }
164
+
165
+ it "should call to_datetime on the value" do
166
+ value.should_receive(:to_datetime)
167
+ result
168
+ end
169
+ end
170
+
171
+ it "should parse the value" do
172
+ DateTime.should_receive(:parse).with(value)
173
+ result
174
+ end
175
+ end
176
+
177
+ context "when type is integer" do
178
+ let(:type) { :integer }
179
+ let(:value) { "42" }
180
+
181
+ it "should convert the value to an integer" do
182
+ expect(result).to eql(42)
183
+ end
184
+ end
185
+
186
+ context "when type is string" do
187
+ let(:type) { :string }
188
+ let(:value) { 42 }
189
+
190
+ it "should convert the value to a string" do
191
+ expect(result).to eql("42")
192
+ end
193
+ end
194
+
195
+ context "when type is anything else" do
196
+ let(:type) { :foo }
197
+ let(:value) { [1, 2, 3] }
198
+
199
+ it "should pass the value through" do
200
+ expect(result).to eql(value)
201
+ end
202
+
203
+ end
204
+ end
205
+
206
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe BoxView::Models::Document do
4
+ let(:document) { BoxView::Models::Document.new }
5
+ let(:api) { BoxView::Api::Document.new }
6
+ before { document.stub(:api).and_return(api) }
7
+
8
+ describe "#document_session" do
9
+ before do
10
+ BoxView::Api::DocumentSession.any_instance.stub(:create).and_return(BoxView::Models::DocumentSession.new)
11
+ end
12
+
13
+ context "when a document session has already been created" do
14
+ before do
15
+ document.instance_variable_set("@document_session", BoxView::Models::DocumentSession.new)
16
+ end
17
+
18
+ it "should not use DocumentSession api's create method" do
19
+ BoxView::Api::DocumentSession.any_instance.should_not_receive(:create)
20
+ document.document_session
21
+ end
22
+ end
23
+
24
+ it "should use DocumentSession api's create method" do
25
+ BoxView::Api::DocumentSession.any_instance.should_receive(:create)
26
+ document.document_session
27
+ end
28
+ end
29
+
30
+ describe "#thumbnail" do
31
+ before { document.api.stub(:thumbnail) }
32
+ it "should use the api's thumbnail method" do
33
+ document.api.should receive(:thumbnail)
34
+ document.thumbnail(100, 100)
35
+ end
36
+ end
37
+
38
+ describe "#content" do
39
+ before { document.api.stub(:content) }
40
+ it "should use the api's content method" do
41
+ document.api.should receive(:content)
42
+ document.content
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe BoxView::Session do
4
+ let(:session) { BoxView::Session.new(credentials) }
5
+ let(:credentials) { {} }
6
+ let(:config_token) { "ABC123" }
7
+ before { BoxView::Session.config { |config| config.box_view_token = config_token } }
8
+
9
+ it "should pick up the configured token" do
10
+ expect(session.token).to eql(config_token)
11
+ end
12
+
13
+ context "when credentials are supplied" do
14
+ let(:credentials) { { token: override_token } }
15
+ let(:override_token) { "overridden token" }
16
+
17
+ it "should use supplied token" do
18
+ expect(session.token).to eql(override_token)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ require 'box_view'
2
+
3
+ require 'support/dummy_api'
4
+ require 'support/dummy_resource'
@@ -0,0 +1,9 @@
1
+ class DummyApi < BoxView::Api::Base
2
+
3
+ def data_klass
4
+ DummyResource
5
+ end
6
+
7
+ def endpoint_url; "dummies"; end
8
+
9
+ end
@@ -0,0 +1,16 @@
1
+ class DummyResource < BoxView::Models::Base
2
+
3
+ has_attributes(
4
+ id: { type: :integer },
5
+ text: { type: :string }
6
+ )
7
+
8
+ def to_params
9
+ { text: self.text }
10
+ end
11
+
12
+ def api
13
+ @api ||= DummyApi.new(session)
14
+ end
15
+
16
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: box_view
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Reilly Forshaw
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: API client for Box View
42
+ email:
43
+ - reilly.forshaw@goclio.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - box_view.gemspec
54
+ - lib/box_view.rb
55
+ - lib/box_view/api/actions/crudable.rb
56
+ - lib/box_view/api/actions/findable.rb
57
+ - lib/box_view/api/actions/listable.rb
58
+ - lib/box_view/api/base.rb
59
+ - lib/box_view/api/document.rb
60
+ - lib/box_view/api/document_session.rb
61
+ - lib/box_view/http.rb
62
+ - lib/box_view/models/base.rb
63
+ - lib/box_view/models/document.rb
64
+ - lib/box_view/models/document_session.rb
65
+ - lib/box_view/session.rb
66
+ - lib/box_view/version.rb
67
+ - spec/api/actions/crudable_spec.rb
68
+ - spec/api/actions/findable_spec.rb
69
+ - spec/api/actions/listable_spec.rb
70
+ - spec/api/base_spec.rb
71
+ - spec/api/document_spec.rb
72
+ - spec/models/base_spec.rb
73
+ - spec/models/document_spec.rb
74
+ - spec/session_spec.rb
75
+ - spec/spec_helper.rb
76
+ - spec/support/dummy_api.rb
77
+ - spec/support/dummy_resource.rb
78
+ homepage: https://github.com/reillyforshaw/box_view
79
+ licenses:
80
+ - MIT
81
+ metadata: {}
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 2.0.3
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: A ruby library to interact with Box View
102
+ test_files:
103
+ - spec/api/actions/crudable_spec.rb
104
+ - spec/api/actions/findable_spec.rb
105
+ - spec/api/actions/listable_spec.rb
106
+ - spec/api/base_spec.rb
107
+ - spec/api/document_spec.rb
108
+ - spec/models/base_spec.rb
109
+ - spec/models/document_spec.rb
110
+ - spec/session_spec.rb
111
+ - spec/spec_helper.rb
112
+ - spec/support/dummy_api.rb
113
+ - spec/support/dummy_resource.rb