fieldview 0.0.0 → 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 +4 -4
- data/Gemfile.lock +0 -4
- data/README.md +29 -2
- data/fieldview.gemspec +4 -4
- data/lib/fieldview/auth_token.rb +26 -8
- data/lib/fieldview/errors.rb +13 -1
- data/lib/fieldview/field.rb +2 -3
- data/lib/fieldview/fieldview_response.rb +7 -3
- data/lib/fieldview/list_object.rb +3 -3
- data/lib/fieldview/requestable.rb +9 -0
- data/lib/fieldview/upload.rb +62 -0
- data/lib/fieldview/util.rb +7 -0
- data/lib/fieldview/version.rb +3 -0
- data/lib/fieldview.rb +5 -0
- data/test/test_auth_token.rb +2 -2
- data/test/test_helper.rb +3 -0
- data/test/test_upload.rb +89 -0
- metadata +10 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05858ad578d5fc9f1a42d4f15c8d9ee0b7299f01
|
4
|
+
data.tar.gz: be48bc245a2c2a38c6b850b51f735ca4d8db193a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d1893ef1af5bdcc6a9ca2790e9806d58828d24a859ad944109b611a1af556688a45761290f0694821a5690c44c3b3e86d59a69135178eec56bcad0598890997c
|
7
|
+
data.tar.gz: cad12cb23d33a5569cdd3583429bab951ede0d58c5fcc4ca6ea80e27266fff1554717d49edc4b28c76a4c5dfbaf2c7fc72507c5585e380d18e832f3f43866341
|
data/Gemfile.lock
CHANGED
@@ -2,7 +2,6 @@ PATH
|
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
4
|
fieldview (0.0.0)
|
5
|
-
faraday (~> 0.9)
|
6
5
|
|
7
6
|
GEM
|
8
7
|
remote: https://rubygems.org/
|
@@ -12,11 +11,8 @@ GEM
|
|
12
11
|
byebug (9.0.6)
|
13
12
|
crack (0.4.3)
|
14
13
|
safe_yaml (~> 1.0.0)
|
15
|
-
faraday (0.12.0.1)
|
16
|
-
multipart-post (>= 1.2, < 3)
|
17
14
|
hashdiff (0.3.2)
|
18
15
|
minitest (5.8.4)
|
19
|
-
multipart-post (2.0.0)
|
20
16
|
public_suffix (2.0.5)
|
21
17
|
rake (11.3.0)
|
22
18
|
safe_yaml (1.0.4)
|
data/README.md
CHANGED
@@ -2,6 +2,16 @@
|
|
2
2
|
|
3
3
|
The FieldView Ruby library provides convenient access to the FieldView API from applications written in the Ruby language. It includes a pre-defined set of classes for API resources that are available currently from the API. You will need to get access from a Climate Corporation representative and the interface utilize OAUTH 2.0.
|
4
4
|
|
5
|
+
OAuth token refreshing is handled for your if for some reason the token expires in the middle of requests (this requires that you provide the `refresh_token` with the creation of the `AuthToken`).
|
6
|
+
|
7
|
+
## Listable Objects
|
8
|
+
|
9
|
+
FieldView returns pages of objects that are tracked via the headers, you cannot go back in pages easily (perhaps we could be tracking the next-token?). Use `more_pages?` on the listable object to see if there are more pages to be acquired by using `next_page!`. The `next_token` on listable objects can also be preserved when reaching the end of a list to see if there are any additional changes since the `next_token` was saved.
|
10
|
+
|
11
|
+
The raw data can be acquired by using `.data` on a listable object.
|
12
|
+
|
13
|
+
When finished you will want to store information of the `AuthToken` somewhere as it may have changed with requests.
|
14
|
+
|
5
15
|
## Usage
|
6
16
|
|
7
17
|
The library needs to be configured with your FieldView account's client secret,
|
@@ -25,9 +35,10 @@ auth_token = FieldView::AuthToken.new_auth_token_with_code_from_redirect_code(<C
|
|
25
35
|
# Or initialize with previous information
|
26
36
|
auth_token = FieldView::AuthToken.new(
|
27
37
|
access_token: <ATOKEN>,
|
28
|
-
expiration_at: <DATETIME>,
|
38
|
+
expiration_at: <DATETIME>, # not required, but should be known
|
29
39
|
refresh_token: <RTOKEN>,
|
30
|
-
refresh_token_expiration_at: <DATETIME>
|
40
|
+
refresh_token_expiration_at: <DATETIME> # Not required, but should be known
|
41
|
+
)
|
31
42
|
|
32
43
|
# Or with just auth_token (assuming it hasn't expired)
|
33
44
|
auth_token = FieldView::AuthToken.new(access_token: <ATOKEN>)
|
@@ -35,6 +46,15 @@ auth_token = FieldView::AuthToken.new(access_token: <ATOKEN>)
|
|
35
46
|
# refresh token and a new access/refresh token will be associated with the object
|
36
47
|
auth_token = FieldView::AuthToken.new(refresh_token: <RTOKEN>)
|
37
48
|
|
49
|
+
# Then you can do something like this:
|
50
|
+
|
51
|
+
fields = FieldView::Fields.list(auth_token)
|
52
|
+
|
53
|
+
fields.each do |field|
|
54
|
+
puts field.boundary
|
55
|
+
end
|
56
|
+
|
57
|
+
fields.has_more?
|
38
58
|
|
39
59
|
```
|
40
60
|
|
@@ -52,6 +72,13 @@ Run a single test:
|
|
52
72
|
|
53
73
|
bundle exec ruby -Ilib/ test/field_view_test.rb -n /client.id/
|
54
74
|
|
75
|
+
## TODOs
|
76
|
+
|
77
|
+
- [ ] Thread safety of the auth token object since it's passed to all created objects
|
78
|
+
- [ ] Probably add configurable behavior for auto-refresh
|
79
|
+
- [ ] Change the configuration to non-static variables (at least the items that are required)
|
80
|
+
- [ ] Use faraday so that we are middleware agnostic
|
81
|
+
|
55
82
|
## Disclaimer
|
56
83
|
|
57
84
|
This Gem is in no way associated with The Climate Corporation, and they are in no way associated with it's support, maintenance, or updates.
|
data/fieldview.gemspec
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
$:.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
2
2
|
|
3
|
+
require 'fieldview/version'
|
4
|
+
|
3
5
|
spec = Gem::Specification.new do |s|
|
4
6
|
s.name = 'fieldview'
|
5
|
-
s.version =
|
7
|
+
s.version = FieldView::VERSION
|
6
8
|
s.required_ruby_version = '>= 1.9.3'
|
7
9
|
s.summary = 'Ruby bindings for the FieldView API'
|
8
|
-
s.description = ' FieldView is used make data-driven decisions to maximize your return on every acre.'
|
10
|
+
s.description = ' FieldView is used to make data-driven decisions to maximize your return on every acre. This Ruby Gem is provided as a convenient way to access their API.'
|
9
11
|
s.author = 'Paul Susmarski'
|
10
12
|
s.email = 'paul@susmarski.com'
|
11
13
|
s.homepage = 'http://rubygems.org/gems/fielview'
|
12
14
|
s.license = 'MIT'
|
13
15
|
|
14
|
-
s.add_dependency('faraday', '~> 0.9')
|
15
|
-
|
16
16
|
s.files = Dir['lib/**/*.rb']
|
17
17
|
s.files = `git ls-files`.split("\n")
|
18
18
|
s.test_files = `git ls-files -- test/*`.split("\n")
|
data/lib/fieldview/auth_token.rb
CHANGED
@@ -12,14 +12,13 @@ module FieldView
|
|
12
12
|
# When the access token expires we'll need to refresh,
|
13
13
|
# can be specified as part of the object, 14399 is what is being
|
14
14
|
# returned at the time of writing this (2017-04-11)
|
15
|
-
self.access_token_expiration_at = params[:access_token_expiration_at] || (now + (params[:expires_in]||14399)
|
15
|
+
self.access_token_expiration_at = params[:access_token_expiration_at] || (now + (params[:expires_in]||14399))
|
16
16
|
|
17
17
|
# Refresh token isn't required, but can be initialized with this
|
18
18
|
self.refresh_token = params[:refresh_token]
|
19
19
|
|
20
|
-
# Refresh token technically expires in 30 days
|
21
|
-
|
22
|
-
self.refresh_token_expiration_at = params[:access_token_expiration_at] || (now + (30-1)*24*60*60)
|
20
|
+
# Refresh token technically expires in 30 days
|
21
|
+
self.refresh_token_expiration_at = params[:access_token_expiration_at] || (now + (30)*24*60*60)
|
23
22
|
end
|
24
23
|
|
25
24
|
def access_token_expired?
|
@@ -61,15 +60,27 @@ module FieldView
|
|
61
60
|
http = Net::HTTP.new(uri.host, uri.port)
|
62
61
|
http.use_ssl = FieldView.api_base.start_with?("https")
|
63
62
|
request = Net::HTTP.class_eval(method.to_s.capitalize).new(uri.request_uri)
|
63
|
+
if method == :get then
|
64
|
+
new_query_ar = URI.decode_www_form(uri.query || '')
|
65
|
+
params.each do |key,value|
|
66
|
+
new_query_ar << [key.to_s, value.to_s]
|
67
|
+
end
|
68
|
+
uri.query = URI.encode_www_form(new_query_ar)
|
69
|
+
request = Net::HTTP.class_eval(method.to_s.capitalize).new(uri.request_uri)
|
70
|
+
else
|
71
|
+
if params.is_a?(Hash)
|
72
|
+
request.body = params.to_json()
|
73
|
+
else
|
74
|
+
request.body = params
|
75
|
+
end
|
76
|
+
end
|
64
77
|
request["Accept"] = "*/*"
|
65
78
|
request["Authorization"] = "Bearer #{self.access_token}"
|
66
79
|
request["X-Api-Key"] = FieldView.x_api_key
|
67
80
|
request["Content-Type"] = "application/json"
|
68
|
-
|
69
81
|
headers.each do |header,value|
|
70
82
|
request[header] = value.to_s
|
71
83
|
end
|
72
|
-
|
73
84
|
response = http.request(request)
|
74
85
|
FieldView.handle_response_error_codes(response)
|
75
86
|
return FieldViewResponse.new(response)
|
@@ -92,10 +103,10 @@ module FieldView
|
|
92
103
|
end
|
93
104
|
|
94
105
|
# Code will be collected from the redirect to your server
|
95
|
-
def self.new_auth_token_with_code_from_redirect_code(code)
|
106
|
+
def self.new_auth_token_with_code_from_redirect_code(code, redirect_uri: nil)
|
96
107
|
http, request = build_token_request([
|
97
108
|
["grant_type", "authorization_code"],
|
98
|
-
["redirect_uri", FieldView.redirect_uri],
|
109
|
+
["redirect_uri", FieldView.redirect_uri || redirect_uri],
|
99
110
|
["code", code]
|
100
111
|
])
|
101
112
|
response = http.request(request)
|
@@ -107,5 +118,12 @@ module FieldView
|
|
107
118
|
return AuthToken.new(json)
|
108
119
|
end
|
109
120
|
end
|
121
|
+
|
122
|
+
def to_s()
|
123
|
+
[
|
124
|
+
"AccessToken: #{self.access_token}, Expiration: #{self.access_token_expiration_at}",
|
125
|
+
"RefreshToken: #{self.refresh_token}, Expiration: #{self.refresh_token_expiration_at}"
|
126
|
+
].join('\n')
|
127
|
+
end
|
110
128
|
end
|
111
129
|
end
|
data/lib/fieldview/errors.rb
CHANGED
@@ -14,8 +14,14 @@ module FieldView
|
|
14
14
|
attr_accessor :response
|
15
15
|
# Initializes a FieldViewError.
|
16
16
|
def initialize(message=nil, http_status: nil, http_body: nil,
|
17
|
-
http_headers: nil)
|
17
|
+
http_headers: nil, fieldview_response: nil)
|
18
18
|
@message = message
|
19
|
+
if fieldview_response then
|
20
|
+
self.response = fieldview_response
|
21
|
+
http_status = fieldview_response.http_status
|
22
|
+
http_body = fieldview_response.http_body
|
23
|
+
http_headers = fieldview_response.http_headers
|
24
|
+
end
|
19
25
|
@http_status = http_status
|
20
26
|
@http_body = http_body
|
21
27
|
@http_headers = http_headers || {}
|
@@ -61,4 +67,10 @@ module FieldView
|
|
61
67
|
# Raised when the server is busy
|
62
68
|
class ServerBusyError < FieldViewError
|
63
69
|
end
|
70
|
+
|
71
|
+
# Raised when a response code that is non-breaking is outside
|
72
|
+
# API specifications, ex: We expect a 201 when creating an upload, but it
|
73
|
+
# returns a 200
|
74
|
+
class UnexpectedResponseError < FieldViewError
|
75
|
+
end
|
64
76
|
end
|
data/lib/fieldview/field.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
module FieldView
|
2
|
-
class Field
|
2
|
+
class Field < Requestable
|
3
3
|
attr_accessor :id
|
4
4
|
attr_accessor :name
|
5
5
|
attr_accessor :boundary_id
|
6
|
-
attr_accessor :auth_token
|
7
6
|
def initialize(json_object, auth_token = nil)
|
8
7
|
self.id = json_object[:id]
|
9
8
|
self.name = json_object[:name]
|
10
9
|
self.boundary_id = json_object[:boundaryId]
|
11
|
-
|
10
|
+
super(auth_token)
|
12
11
|
end
|
13
12
|
|
14
13
|
def boundary
|
@@ -12,9 +12,13 @@ module FieldView
|
|
12
12
|
end
|
13
13
|
|
14
14
|
self.http_body = response.body
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
if response.body then
|
16
|
+
begin
|
17
|
+
self.data = JSON.parse(response.body, symbolize_names: true)
|
18
|
+
rescue JSON::ParserError
|
19
|
+
self.data = nil
|
20
|
+
end
|
21
|
+
else
|
18
22
|
self.data = nil
|
19
23
|
end
|
20
24
|
self.http_status = response.code.to_i
|
@@ -1,16 +1,16 @@
|
|
1
1
|
module FieldView
|
2
|
-
class ListObject
|
2
|
+
class ListObject < Requestable
|
3
3
|
attr_accessor :limit
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :data, :last_http_status, :next_token, :listable
|
5
5
|
include Enumerable
|
6
6
|
|
7
7
|
def initialize(listable, auth_token, data, http_status, next_token: nil, limit: 100)
|
8
8
|
@listable = listable
|
9
|
-
@auth_token = auth_token
|
10
9
|
@data = data
|
11
10
|
@last_http_status = http_status
|
12
11
|
@next_token = next_token
|
13
12
|
@limit = 100
|
13
|
+
super(auth_token)
|
14
14
|
end
|
15
15
|
|
16
16
|
def each(&blk)
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module FieldView
|
2
|
+
class Upload < Requestable
|
3
|
+
# 5 Megabytes is the current chunk size
|
4
|
+
REQUIRED_CHUNK_SIZE = 5*1024*1024
|
5
|
+
CHUNK_CONTENT_TYPE = "application/octet-stream"
|
6
|
+
|
7
|
+
PATH = "uploads"
|
8
|
+
attr_accessor :id, :content_length, :content_type
|
9
|
+
|
10
|
+
# Creates an upload with the specified items, all required.
|
11
|
+
# will return an a new upload object that has it's ID which can be
|
12
|
+
# used to upload. The following are known content types:
|
13
|
+
# image/vnd.climate.thermal.geotiff, image/vnd.climate.ndvi.geotiff,
|
14
|
+
# image/vnd.climate.chlorophyll.geotiff, image/vnd.climate.cci.geotiff,
|
15
|
+
# image/vnd.climate.waterstress.geotiff, image/vnd.climate.infrared.geotiff
|
16
|
+
def self.create(auth_token, md5, content_length, content_type)
|
17
|
+
response = auth_token.execute_request!(:post, PATH,
|
18
|
+
params: {
|
19
|
+
"md5" => md5,
|
20
|
+
"length" => content_length,
|
21
|
+
"content-type" => content_type
|
22
|
+
})
|
23
|
+
|
24
|
+
Util.verify_response_with_code("Upload creation", response, 201)
|
25
|
+
|
26
|
+
return new(response.http_body.gsub('"', ''), content_length, auth_token)
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize(id, content_length, auth_token = nil)
|
30
|
+
self.id = id
|
31
|
+
self.content_length = content_length.to_i
|
32
|
+
if self.content_length <= 0 then
|
33
|
+
raise ArgumentError.new("You must set content_length to a non-zero value")
|
34
|
+
end
|
35
|
+
super(auth_token)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Upload a chunk of a file, specify the range of the bytes, 0 based, for the bytes
|
39
|
+
# you're passing, for example, the first 256 bytes would be start_bytes = 0 and
|
40
|
+
# end_bytes = 255, with bytes = 256 byte size object
|
41
|
+
def upload_chunk(start_bytes, end_bytes, bytes)
|
42
|
+
if (end_bytes.to_i - start_bytes.to_i + 1) != bytes.bytesize ||
|
43
|
+
bytes.bytesize > REQUIRED_CHUNK_SIZE then
|
44
|
+
raise ArgumentError.new("End bytes (#{end_bytes}) - Start bytes (#{start_bytes})" \
|
45
|
+
" must be equal to bytes (#{bytes}) and no greater than #{REQUIRED_CHUNK_SIZE}")
|
46
|
+
end
|
47
|
+
response = auth_token.execute_request!(:put, "#{PATH}/#{self.id}",
|
48
|
+
headers: {
|
49
|
+
"Content-Range" => "bytes #{start_bytes}-#{end_bytes}/#{self.content_length}",
|
50
|
+
"Content-Length" => bytes.bytesize,
|
51
|
+
"Content-Type" => CHUNK_CONTENT_TYPE,
|
52
|
+
"Transfer-Encoding" => "chunked"
|
53
|
+
},
|
54
|
+
params: bytes)
|
55
|
+
|
56
|
+
# We expect a 204
|
57
|
+
Util.verify_response_with_code("Chunk upload", response, 204)
|
58
|
+
|
59
|
+
return response
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/fieldview/util.rb
CHANGED
@@ -3,5 +3,12 @@ module FieldView
|
|
3
3
|
def self.http_status_is_more_in_list?(http_status)
|
4
4
|
return http_status.to_i == 206
|
5
5
|
end
|
6
|
+
|
7
|
+
def self.verify_response_with_code(message, fieldview_response, *acceptable_response_codes)
|
8
|
+
if not acceptable_response_codes.include?(fieldview_response.http_status) then
|
9
|
+
raise UnexpectedResponseError.new("#{message} expects #{acceptable_response_codes}",
|
10
|
+
fieldview_response: fieldview_response)
|
11
|
+
end
|
12
|
+
end
|
6
13
|
end
|
7
14
|
end
|
data/lib/fieldview.rb
CHANGED
@@ -3,13 +3,18 @@ require 'json'
|
|
3
3
|
require 'rbconfig'
|
4
4
|
require 'base64'
|
5
5
|
|
6
|
+
# Version
|
7
|
+
require 'fieldview/version'
|
8
|
+
|
6
9
|
# API Support Classes
|
7
10
|
require 'fieldview/errors'
|
11
|
+
require 'fieldview/requestable'
|
8
12
|
require 'fieldview/auth_token'
|
9
13
|
require 'fieldview/fields'
|
10
14
|
require 'fieldview/util'
|
11
15
|
require 'fieldview/fieldview_response'
|
12
16
|
require 'fieldview/field'
|
17
|
+
require 'fieldview/upload'
|
13
18
|
require 'fieldview/list_object'
|
14
19
|
require 'fieldview/boundary'
|
15
20
|
|
data/test/test_auth_token.rb
CHANGED
@@ -9,8 +9,8 @@ class TestAuthToken < Minitest::Test
|
|
9
9
|
def check_token_matches_fixture(token)
|
10
10
|
assert_equal FIXTURE[:access_token], token.access_token
|
11
11
|
assert_equal FIXTURE[:refresh_token], token.refresh_token
|
12
|
-
assert_equal FieldView.now + FIXTURE[:expires_in] -
|
13
|
-
assert_equal FieldView.now
|
12
|
+
assert_equal FieldView.now + FIXTURE[:expires_in] - 5, token.access_token_expiration_at
|
13
|
+
assert_equal FieldView.now + 30*24*60*60 - 5, token.refresh_token_expiration_at, "Should be 30 days in the future"
|
14
14
|
end
|
15
15
|
|
16
16
|
def setup
|
data/test/test_helper.rb
CHANGED
data/test/test_upload.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
class TestUpload < Minitest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
setup_for_api_requests
|
7
|
+
end
|
8
|
+
|
9
|
+
def teardown
|
10
|
+
teardown_for_api_request
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_expects_certain_status_code
|
14
|
+
stub_request(:post, /uploads/).
|
15
|
+
to_return(status: 200)
|
16
|
+
|
17
|
+
assert_raises(FieldView::UnexpectedResponseError) do
|
18
|
+
FieldView::Upload.create(new_auth_token, "dontcare", 5, "dontcare")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_create()
|
23
|
+
md5 = "eb782356d6011dab2b112bdcb098ec7d"
|
24
|
+
uuid = "1a2623b3-d2a7-4e52-ba21-a3eb521a3208"
|
25
|
+
content_length = 275
|
26
|
+
content_type = "image/vnd.climate.thermal.geotiff"
|
27
|
+
stub_request(:post, /uploads/).
|
28
|
+
with(body: {
|
29
|
+
"md5" => md5,
|
30
|
+
"length" => content_length,
|
31
|
+
"content-type" => content_type
|
32
|
+
}).
|
33
|
+
to_return(status: 201, body: %Q!"#{uuid}"!)
|
34
|
+
|
35
|
+
auth_token = new_auth_token
|
36
|
+
|
37
|
+
upload = FieldView::Upload.create(auth_token, md5, content_length, content_type)
|
38
|
+
|
39
|
+
assert_equal uuid, upload.id
|
40
|
+
assert_equal content_length, upload.content_length
|
41
|
+
assert_equal auth_token, upload.auth_token
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_checks_content_length
|
45
|
+
assert_raises(ArgumentError) do
|
46
|
+
# nil is going to result in 0 when converting to integer
|
47
|
+
FieldView::Upload.new(1,nil,new_auth_token)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_uploading_wrong_chunk_size
|
52
|
+
upload = FieldView::Upload.new("dontcare",
|
53
|
+
50000000, new_auth_token)
|
54
|
+
|
55
|
+
bytes = "12345678"
|
56
|
+
start_bytes = 0
|
57
|
+
end_bytes = 5
|
58
|
+
assert_raises(ArgumentError, "Wrong byte start/end") do
|
59
|
+
upload.upload_chunk(start_bytes, end_bytes, bytes)
|
60
|
+
end
|
61
|
+
|
62
|
+
bytes = "A" * (FieldView::Upload::REQUIRED_CHUNK_SIZE + 1)
|
63
|
+
end_bytes = bytes.bytesize - 1
|
64
|
+
assert_raises(ArgumentError, "Larger than the accepted chunk size") do
|
65
|
+
upload.upload_chunk(start_bytes, end_bytes, bytes)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_can_upload_chunk
|
70
|
+
uuid = "1a2623b3-d2a7-4e52-ba21-a3eb521a3208"
|
71
|
+
total_content_length = FieldView::Upload::REQUIRED_CHUNK_SIZE * 2
|
72
|
+
upload = FieldView::Upload.new(uuid,
|
73
|
+
total_content_length, new_auth_token)
|
74
|
+
|
75
|
+
chunk = "A"
|
76
|
+
start_bytes = 0
|
77
|
+
end_bytes = chunk.bytesize - 1
|
78
|
+
|
79
|
+
stub_request(:put, /uploads\/#{uuid}/).
|
80
|
+
with(headers: {
|
81
|
+
content_range: "bytes #{start_bytes}-#{end_bytes}/#{total_content_length}",
|
82
|
+
content_length: chunk.bytesize.to_s,
|
83
|
+
content_type: "application/octet-stream",
|
84
|
+
transfer_encoding: "chunked"
|
85
|
+
}).
|
86
|
+
to_return(status: 204, body: nil)
|
87
|
+
assert upload.upload_chunk(start_bytes, end_bytes, chunk)
|
88
|
+
end
|
89
|
+
end
|
metadata
CHANGED
@@ -1,31 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fieldview
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Susmarski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
12
|
-
dependencies:
|
13
|
-
-
|
14
|
-
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ~>
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.9'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ~>
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0.9'
|
27
|
-
description: ' FieldView is used make data-driven decisions to maximize your return
|
28
|
-
on every acre.'
|
11
|
+
date: 2017-04-19 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: ' FieldView is used to make data-driven decisions to maximize your return
|
14
|
+
on every acre. This Ruby Gem is provided as a convenient way to access their API.'
|
29
15
|
email: paul@susmarski.com
|
30
16
|
executables: []
|
31
17
|
extensions: []
|
@@ -46,7 +32,10 @@ files:
|
|
46
32
|
- lib/fieldview/fields.rb
|
47
33
|
- lib/fieldview/fieldview_response.rb
|
48
34
|
- lib/fieldview/list_object.rb
|
35
|
+
- lib/fieldview/requestable.rb
|
36
|
+
- lib/fieldview/upload.rb
|
49
37
|
- lib/fieldview/util.rb
|
38
|
+
- lib/fieldview/version.rb
|
50
39
|
- spec/fixtures.json
|
51
40
|
- test/api_fixtures.rb
|
52
41
|
- test/test_auth_token.rb
|
@@ -56,6 +45,7 @@ files:
|
|
56
45
|
- test/test_fieldview.rb
|
57
46
|
- test/test_helper.rb
|
58
47
|
- test/test_list_object.rb
|
48
|
+
- test/test_upload.rb
|
59
49
|
homepage: http://rubygems.org/gems/fielview
|
60
50
|
licenses:
|
61
51
|
- MIT
|
@@ -89,3 +79,4 @@ test_files:
|
|
89
79
|
- test/test_fieldview.rb
|
90
80
|
- test/test_helper.rb
|
91
81
|
- test/test_list_object.rb
|
82
|
+
- test/test_upload.rb
|