box_view 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.
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