play_time 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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 60d15a35b3f4ffbbd717a6fa5b016c6fb11687e6
4
+ data.tar.gz: 769b7ccfefa8e113eee1bd5c146443d447e768c9
5
+ SHA512:
6
+ metadata.gz: f52451c21ce608888a99c804432d2f87fa63386830683929fd38f3ac83b83acd0bfdb69f302e7b4ce0889fbb3fae92efe9fce891a90ade92524f41193e89a513
7
+ data.tar.gz: 4ca0b9a8df26418ffed5a48184d475297b59ccba43d9f85141d9ad416b55396334d40b7de3b7666296a5a68797d048113bf6e1e77b4ece27250c4d12f46f262e
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in play_time.gemspec
4
+ gemspec
5
+
6
+ gem 'pry'
7
+ gem 'did_you_mean'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Yuki Nishijima
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,31 @@
1
+ # PlayTime
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'play_time'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install play_time
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/play_time/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: 'spec:default'
9
+
10
+ namespace :spec do
11
+ %w(
12
+ default
13
+ ).each do |config_file|
14
+ desc "Run Tests against config: #{config_file}.yml"
15
+ task config_file do
16
+ sh "PLAY_TIME_CONFIG_PATH=spec/support/config/#{config_file}.yml bundle exec rake spec"
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'google/api_client'
2
+
3
+ module PlayTime
4
+ class Apk
5
+ MIME_TYPE = 'application/vnd.android.package-archive'.freeze
6
+
7
+ class << self
8
+ def load
9
+ Google::APIClient::UploadIO.new(path, MIME_TYPE)
10
+ end
11
+
12
+ private
13
+
14
+ def path
15
+ PlayTime.configuration.apk_path
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,77 @@
1
+ require 'google/api_client'
2
+
3
+ require 'play_time/runner'
4
+ require 'play_time/apk'
5
+
6
+ module PlayTime
7
+ class Client
8
+ TOKEN_URI = 'https://accounts.google.com/o/oauth2/token'.freeze
9
+ SCOPE = 'https://www.googleapis.com/auth/androidpublisher'.freeze
10
+ API = 'androidpublisher'.freeze
11
+ API_VERSION = 'v2'.freeze
12
+
13
+ def authorize!
14
+ client.authorization = oauth2_client
15
+ client.authorization.fetch_access_token!
16
+ end
17
+
18
+ def commit(track)
19
+ create_insert
20
+ upload_apk
21
+ update_track(track)
22
+ save
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :edit_id
28
+
29
+ def create_insert
30
+ @edit_id = Runner.run!(client, api_method: service.edits.insert, parameters: parameters).data.id
31
+ end
32
+
33
+ def upload_apk
34
+ upload_params = parameters.merge(editId: edit_id, uploadType: 'media')
35
+ Runner.run! client, api_method: service.edits.apks.upload, parameters: upload_params, media: Apk.load
36
+ end
37
+
38
+ def update_track(track)
39
+ update_params = parameters.merge(editId: edit_id, track: track)
40
+ Runner.run! client, api_method: service.edits.tracks.update, parameters: update_params
41
+ end
42
+
43
+ def save
44
+ commit_params = parameters.merge(editId: edit_id)
45
+ Runner.run! client, api_method: service.edits.commit, parameters: commit_params
46
+ end
47
+
48
+ def parameters
49
+ {package_name: PlayTime.configuration.package_name}
50
+ end
51
+
52
+ def client
53
+ @client ||= Google::APIClient.new(
54
+ application_name: PlayTime.configuration.client_name,
55
+ application_version: PlayTime.configuration.client_version
56
+ )
57
+ end
58
+
59
+ def service
60
+ @service ||= client.discovered_api(API, API_VERSION)
61
+ end
62
+
63
+ def oauth2_client
64
+ @oauth2_client ||= Signet::OAuth2::Client.new(
65
+ token_credential_uri: TOKEN_URI,
66
+ audience: TOKEN_URI,
67
+ scope: SCOPE,
68
+ issuer: PlayTime.configuration.issuer,
69
+ signing_key: openssl_key
70
+ )
71
+ end
72
+
73
+ def openssl_key
74
+ @openssl_key ||= Google::APIClient::KeyUtils.load_from_pkcs12(PlayTime.configuration.secret_path, PlayTime.configuration.secret_passphrase)
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,30 @@
1
+ module PlayTime
2
+ class Configuration
3
+ DEFAULT_CONFIG = 'config/play_time.yml'.freeze
4
+ OPTIONS = %w(
5
+ apk_path
6
+ client_name
7
+ client_version
8
+ secret_path
9
+ secret_passphrase
10
+ issuer
11
+ package_name
12
+ ).freeze
13
+
14
+ def initialize(config)
15
+ @config = config
16
+ end
17
+
18
+ OPTIONS.each do |config_name|
19
+ eval <<-RUBY
20
+ def #{config_name} # def config_option
21
+ config["#{config_name}"] # config['config_option']
22
+ end # end
23
+ RUBY
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :config
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ module PlayTime
2
+ class Runner
3
+ class IOError < StandardError; end
4
+ class ResponseError < StandardError; end
5
+
6
+ class << self
7
+ def run!(client, options = {})
8
+ response = client.execute(options)
9
+
10
+ if error?(response)
11
+ raise error_for(response)
12
+ else
13
+ response
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def has_data?(response)
20
+ response && response.data
21
+ end
22
+
23
+ def error?(response)
24
+ !has_data?(response) || response.data['error']
25
+ end
26
+
27
+ def error_message(response)
28
+ response.data['error'] if has_data?(response)
29
+ end
30
+
31
+ def error_for(response)
32
+ if error_message = error_message(response)
33
+ ResponseError.new(error_message)
34
+ else
35
+ IOError
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,20 @@
1
+ module PlayTime
2
+ class Track
3
+ class InvalidTrack < StandardError; end
4
+
5
+ ALPHA = 'alpha'.freeze
6
+ BETA = 'beta'.freeze
7
+ ROLLOUT = 'rollout'.freeze
8
+ PRODUCTION = 'production'.freeze
9
+
10
+ def self.validate!(track)
11
+ raise InvalidTrack.new("#{track} is an invalid track") unless valid?(track)
12
+ end
13
+
14
+ private
15
+
16
+ def self.valid?(track)
17
+ [ALPHA, BETA, ROLLOUT, PRODUCTION].include?(track)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ require 'play_time/client'
2
+
3
+ module PlayTime
4
+ class Upload
5
+ def self.upload(track)
6
+ upload = Upload.new(Client.new)
7
+ upload.upload(track)
8
+ end
9
+
10
+ attr_reader :client
11
+
12
+ def initialize(client)
13
+ @client = client
14
+ end
15
+
16
+ def upload(track)
17
+ client.authorize!
18
+
19
+ client.commit(track)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module PlayTime
2
+ VERSION = "0.0.1"
3
+ end
data/lib/play_time.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'yaml'
2
+ require 'play_time/version'
3
+ require 'play_time/track'
4
+ require 'play_time/configuration'
5
+ require 'play_time/upload'
6
+
7
+ module PlayTime
8
+ def self.config_path
9
+ ENV['PLAY_TIME_CONFIG_PATH'] || Configuration::DEFAULT_CONFIG
10
+ end
11
+
12
+ def self.configuration
13
+ @configuration ||= Configuration.new(YAML.load(open(config_path).read))
14
+ end
15
+
16
+ def self.upload(track)
17
+ Upload.upload(track)
18
+ end
19
+ end
data/play_time.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'play_time/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "play_time"
8
+ spec.version = PlayTime::VERSION
9
+ spec.authors = ["Yuki Nishijima and Trevor John"]
10
+ spec.email = ["pair+tjohn+ynishijima@pivotal.io"]
11
+ spec.summary = %q{PlayTime is a gem for uploading apks to the Google Play Store}
12
+ spec.description = %q{More to come}
13
+ spec.homepage = "https://github.com/is-devteam/play_time"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'google-api-client', '~> 0.7'
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.7"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec", "~> 3.1"
26
+ end
data/spec/apk_spec.rb ADDED
@@ -0,0 +1,19 @@
1
+ describe PlayTime::Apk do
2
+ describe '#load' do
3
+ let(:path) { 'path/to/apk' }
4
+
5
+ subject { PlayTime::Apk.load }
6
+
7
+ before do
8
+ allow(PlayTime.configuration).to receive(:apk_path).and_return(path)
9
+ end
10
+
11
+ it 'returns a Google::APIClient::UploadIO with the path and MIME_TYPE' do
12
+ allow(Google::APIClient::UploadIO).to receive(:new)
13
+
14
+ subject
15
+
16
+ expect(Google::APIClient::UploadIO).to have_received(:new).with(path, PlayTime::Apk::MIME_TYPE)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,131 @@
1
+ require 'play_time/client'
2
+
3
+ describe PlayTime::Client do
4
+ let(:api_client) { instance_double(Google::APIClient) }
5
+ let(:oauth2_client) { instance_double(Signet::OAuth2::Client) }
6
+
7
+ before do
8
+ allow(PlayTime.configuration).to receive(:client_name).and_return('client_name')
9
+ allow(PlayTime.configuration).to receive(:client_version).and_return('client_version')
10
+ allow(PlayTime.configuration).to receive(:secret_path).and_return('/path/secret.p12')
11
+ allow(PlayTime.configuration).to receive(:secret_passphrase).and_return('p12 secret')
12
+ allow(PlayTime.configuration).to receive(:issuer).and_return('issuer@developer.gserviceaccount.com')
13
+
14
+ allow(Google::APIClient).to receive(:new).and_return(api_client)
15
+ allow(Signet::OAuth2::Client).to receive(:new).and_return(oauth2_client)
16
+ allow(api_client).to receive(:authorization=)
17
+ allow(api_client).to receive(:authorization).and_return(oauth2_client)
18
+ end
19
+
20
+ describe '#authorize!' do
21
+ let(:key_utils) { instance_double(OpenSSL::PKey) }
22
+
23
+ subject { PlayTime::Client.new.authorize! }
24
+
25
+ before do
26
+ allow(Google::APIClient::KeyUtils).to receive(:load_from_pkcs12).and_return(key_utils)
27
+ allow(oauth2_client).to receive(:fetch_access_token!)
28
+ end
29
+
30
+ it "creates a client" do
31
+ subject
32
+
33
+ expect(Google::APIClient).to have_received(:new).with(application_name: 'client_name', application_version: 'client_version')
34
+ end
35
+
36
+ it 'creates authorization object' do
37
+ subject
38
+
39
+ expect(Google::APIClient::KeyUtils).to have_received(:load_from_pkcs12).with('/path/secret.p12', 'p12 secret')
40
+ end
41
+
42
+ it "initializes the oauth client" do
43
+ subject
44
+
45
+ expect(Signet::OAuth2::Client).to have_received(:new).with(
46
+ token_credential_uri: PlayTime::Client::TOKEN_URI,
47
+ audience: PlayTime::Client::TOKEN_URI,
48
+ scope: PlayTime::Client::SCOPE,
49
+ issuer: 'issuer@developer.gserviceaccount.com',
50
+ signing_key: key_utils
51
+ )
52
+ end
53
+
54
+ it "sets the oauth client on the google client" do
55
+ subject
56
+
57
+ expect(api_client).to have_received(:authorization=).with(oauth2_client)
58
+ end
59
+
60
+ it "authorizes the oauth client" do
61
+ subject
62
+
63
+ expect(oauth2_client).to have_received(:fetch_access_token!)
64
+ end
65
+ end
66
+
67
+ describe '#commit' do
68
+ let(:track) { 'alpha' }
69
+ let(:service) { double(Google::APIClient::API) }
70
+ let(:response) { double(:response, data: double(:data, id: 'id')) }
71
+ let(:apk_file) { instance_double(Google::APIClient::UploadIO) }
72
+
73
+ subject { PlayTime::Client.new.commit(track) }
74
+
75
+ before do
76
+ allow(PlayTime.configuration).to receive(:package_name).and_return('com.package.name')
77
+
78
+ allow(PlayTime::Runner).to receive(:run!).and_return(response)
79
+ allow(PlayTime::Apk).to receive(:load).and_return(apk_file)
80
+ allow(api_client).to receive(:discovered_api).and_return(service)
81
+ allow(service).to receive_message_chain('edits.insert').and_return('insert')
82
+ allow(service).to receive_message_chain('edits.apks.upload').and_return('upload')
83
+ allow(service).to receive_message_chain('edits.tracks.update').and_return('track update')
84
+ allow(service).to receive_message_chain('edits.commit').and_return('commit')
85
+ end
86
+
87
+ it 'creates a service' do
88
+ subject
89
+
90
+ expect(api_client).to have_received(:discovered_api).with('androidpublisher', 'v2')
91
+ end
92
+
93
+ it 'creates an edit' do
94
+ subject
95
+
96
+ expect(PlayTime::Runner).to have_received(:run!).with(
97
+ api_client, api_method: 'insert', parameters: { package_name: 'com.package.name' })
98
+ end
99
+
100
+ it 'uploads an apk file' do
101
+ subject
102
+
103
+ expect(PlayTime::Runner).to have_received(:run!).with(
104
+ api_client,
105
+ api_method: 'upload',
106
+ parameters: { package_name: 'com.package.name', editId: 'id', uploadType: 'media' },
107
+ media: apk_file
108
+ )
109
+ end
110
+
111
+ it 'updates a track' do
112
+ subject
113
+
114
+ expect(PlayTime::Runner).to have_received(:run!).with(
115
+ api_client,
116
+ api_method: 'track update',
117
+ parameters: { package_name: 'com.package.name', editId: 'id', track: track }
118
+ )
119
+ end
120
+
121
+ it 'commits the changes' do
122
+ subject
123
+
124
+ expect(PlayTime::Runner).to have_received(:run!).with(
125
+ api_client,
126
+ api_method: 'commit',
127
+ parameters: { package_name: 'com.package.name', editId: 'id' }
128
+ )
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,19 @@
1
+ describe PlayTime::Configuration do
2
+ shared_examples_for 'configuration option' do
3
+ let(:configuration) { PlayTime::Configuration.new({option.to_s => option, 'foo' => 'bar'}) }
4
+
5
+ subject { configuration.send(option) }
6
+
7
+ it "fetchings the option from the config" do
8
+ expect(subject).to eq option
9
+ end
10
+ end
11
+
12
+ PlayTime::Configuration::OPTIONS.each do |option|
13
+ describe "##{option}" do
14
+ let(:option) { option }
15
+
16
+ it_behaves_like 'configuration option'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ describe PlayTime, if: PlayTime.config_path.end_with?('default.yml') do
2
+ describe '.configuration' do
3
+ subject { PlayTime.configuration }
4
+
5
+ it 'returns a PlayTime::Configuration object' do
6
+ expect(subject).to be_a PlayTime::Configuration
7
+ end
8
+ end
9
+
10
+ describe '.upload' do
11
+ let(:apk_path) { '/path/to/app.apk' }
12
+ let(:track) { PlayTime::Track::ALPHA }
13
+
14
+ subject { PlayTime.upload(track) }
15
+
16
+ it 'uploads the apk with the track' do
17
+ allow(PlayTime::Upload).to receive(:upload)
18
+
19
+ subject
20
+
21
+ expect(PlayTime::Upload).to have_received(:upload).with(track)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,53 @@
1
+ describe PlayTime::Runner do
2
+ describe '.run!' do
3
+ let(:response) { double(:response, data: {success: true}) }
4
+ let(:client) { double(:client, execute: response) }
5
+ let(:options) { {foo: :bar} }
6
+
7
+ subject { PlayTime::Runner.run!(client, options) }
8
+
9
+ it 'executes an api' do
10
+ subject
11
+
12
+ expect(client).to have_received(:execute).with(options)
13
+ end
14
+
15
+ context 'when success' do
16
+ it 'returns a response' do
17
+ expect(subject).to eq response
18
+ end
19
+ end
20
+
21
+ context 'when failure' do
22
+ context 'when no response' do
23
+ let(:response) { nil }
24
+
25
+ it 'raises an error' do
26
+ expect {
27
+ subject
28
+ }.to raise_error PlayTime::Runner::IOError
29
+ end
30
+ end
31
+
32
+ context 'when data is nil' do
33
+ let(:response) { double(:response, data: nil) }
34
+
35
+ it 'raises an error' do
36
+ expect {
37
+ subject
38
+ }.to raise_error PlayTime::Runner::IOError
39
+ end
40
+ end
41
+
42
+ context 'when data has an error' do
43
+ let(:response) { double(:response, data: {'error' => 'Something went wrong'}) }
44
+
45
+ it 'raises an error' do
46
+ expect {
47
+ subject
48
+ }.to raise_error PlayTime::Runner::ResponseError, 'Something went wrong'
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,93 @@
1
+ require 'pry'
2
+ require 'play_time'
3
+ require 'did_you_mean'
4
+
5
+ # This file was generated by the `rspec --init` command. Conventionally, all
6
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
7
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
8
+ # file to always be loaded, without a need to explicitly require it in any files.
9
+ #
10
+ # Given that it is always loaded, you are encouraged to keep this file as
11
+ # light-weight as possible. Requiring heavyweight dependencies from this file
12
+ # will add to the boot time of your test suite on EVERY test run, even for an
13
+ # individual file that may not need all of that loaded. Instead, consider making
14
+ # a separate helper file that requires the additional dependencies and performs
15
+ # the additional setup, and require it from the spec files that actually need it.
16
+ #
17
+ # The `.rspec` file also contains a few flags that are not defaults but that
18
+ # users commonly want.
19
+ #
20
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
21
+ RSpec.configure do |config|
22
+ # rspec-expectations config goes here. You can use an alternate
23
+ # assertion/expectation library such as wrong or the stdlib/minitest
24
+ # assertions if you prefer.
25
+ config.expect_with :rspec do |expectations|
26
+ # This option will default to `true` in RSpec 4. It makes the `description`
27
+ # and `failure_message` of custom matchers include text for helper methods
28
+ # defined using `chain`, e.g.:
29
+ # be_bigger_than(2).and_smaller_than(4).description
30
+ # # => "be bigger than 2 and smaller than 4"
31
+ # ...rather than:
32
+ # # => "be bigger than 2"
33
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
34
+ end
35
+
36
+ # rspec-mocks config goes here. You can use an alternate test double
37
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
38
+ config.mock_with :rspec do |mocks|
39
+ # Prevents you from mocking or stubbing a method that does not exist on
40
+ # a real object. This is generally recommended, and will default to
41
+ # `true` in RSpec 4.
42
+ mocks.verify_partial_doubles = true
43
+ end
44
+
45
+ # The settings below are suggested to provide a good initial experience
46
+ # with RSpec, but feel free to customize to your heart's content.
47
+ =begin
48
+ # These two settings work together to allow you to limit a spec run
49
+ # to individual examples or groups you care about by tagging them with
50
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
51
+ # get run.
52
+ config.filter_run :focus
53
+ config.run_all_when_everything_filtered = true
54
+
55
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
56
+ # For more details, see:
57
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
58
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
59
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
60
+ config.disable_monkey_patching!
61
+
62
+ # This setting enables warnings. It's recommended, but in some cases may
63
+ # be too noisy due to issues in dependencies.
64
+ config.warnings = true
65
+
66
+ # Many RSpec users commonly either run the entire suite or an individual
67
+ # file, and it's useful to allow more verbose output when running an
68
+ # individual spec file.
69
+ if config.files_to_run.one?
70
+ # Use the documentation formatter for detailed output,
71
+ # unless a formatter has already been configured
72
+ # (e.g. via a command-line flag).
73
+ config.default_formatter = 'doc'
74
+ end
75
+
76
+ # Print the 10 slowest examples and example groups at the
77
+ # end of the spec run, to help surface which specs are running
78
+ # particularly slow.
79
+ config.profile_examples = 10
80
+
81
+ # Run specs in random order to surface order dependencies. If you find an
82
+ # order dependency and want to debug it, you can fix the order by providing
83
+ # the seed, which is printed after each run.
84
+ # --seed 1234
85
+ config.order = :random
86
+
87
+ # Seed global randomization in this process using the `--seed` CLI option.
88
+ # Setting this allows you to use `--seed` to deterministically reproduce
89
+ # test failures related to randomization by passing the same `--seed` value
90
+ # as the one that triggered the failure.
91
+ Kernel.srand config.seed
92
+ =end
93
+ end
@@ -0,0 +1,5 @@
1
+ package_name: com.example.app
2
+ secret_path: /path/to/secret/secret.p12
3
+ apk_path: /path/to/alpha/app.apk
4
+ client_name: 'Google API Client Name'
5
+ client_version: '1.0.0'
@@ -0,0 +1,55 @@
1
+ describe PlayTime::Track do
2
+ describe '.validate!' do
3
+ subject { PlayTime::Track.validate!(track) }
4
+
5
+ context 'when alpha' do
6
+ let(:track) { 'alpha' }
7
+
8
+ it "is true" do
9
+ expect {
10
+ subject
11
+ }.not_to raise_error
12
+ end
13
+ end
14
+
15
+ context 'when beta' do
16
+ let(:track) { 'beta' }
17
+
18
+ it "is true" do
19
+ expect {
20
+ subject
21
+ }.not_to raise_error
22
+ end
23
+ end
24
+
25
+ context 'when rollout' do
26
+ let(:track) { 'rollout' }
27
+
28
+ it "is true" do
29
+ expect {
30
+ subject
31
+ }.not_to raise_error
32
+ end
33
+ end
34
+
35
+ context 'when production' do
36
+ let(:track) { 'production' }
37
+
38
+ it "is true" do
39
+ expect {
40
+ subject
41
+ }.not_to raise_error
42
+ end
43
+ end
44
+
45
+ context 'when invalid' do
46
+ let(:track) { 'something else' }
47
+
48
+ it "is false" do
49
+ expect {
50
+ subject
51
+ }.to raise_error PlayTime::Track::InvalidTrack
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,52 @@
1
+
2
+ describe PlayTime::Upload do
3
+ describe '.upload' do
4
+ let(:upload) { instance_double(PlayTime::Upload) }
5
+ let(:client) { instance_double(PlayTime::Client) }
6
+
7
+ subject { PlayTime::Upload.upload('track') }
8
+
9
+ before do
10
+ allow(upload).to receive(:upload)
11
+ allow(PlayTime::Client).to receive(:new).and_return(client)
12
+ allow(PlayTime::Upload).to receive(:new).and_return(upload)
13
+ end
14
+
15
+ it 'uploads the track' do
16
+ subject
17
+
18
+ expect(upload).to have_received(:upload).with('track')
19
+ end
20
+
21
+ it 'instantiates upload with new authorization and client' do
22
+ subject
23
+
24
+ expect(PlayTime::Upload).to have_received(:new).with(client)
25
+ end
26
+ end
27
+
28
+ describe '#upload' do
29
+ let(:client) { instance_double(PlayTime::Client) }
30
+ let(:upload) { PlayTime::Upload.new(client) }
31
+
32
+ subject { upload.upload('track') }
33
+
34
+ before do
35
+ allow(client).to receive(:authorize!)
36
+ allow(client).to receive(:commit)
37
+ end
38
+
39
+ it 'authroizes the client' do
40
+ subject
41
+
42
+ expect(client).to have_received(:authorize!)
43
+ end
44
+
45
+ it 'commits the track' do
46
+ subject
47
+
48
+ expect(client).to have_received(:commit).with('track')
49
+ end
50
+ end
51
+ end
52
+
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: play_time
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Yuki Nishijima and Trevor John
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: google-api-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.1'
69
+ description: More to come
70
+ email:
71
+ - pair+tjohn+ynishijima@pivotal.io
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - lib/play_time.rb
83
+ - lib/play_time/apk.rb
84
+ - lib/play_time/client.rb
85
+ - lib/play_time/configuration.rb
86
+ - lib/play_time/runner.rb
87
+ - lib/play_time/track.rb
88
+ - lib/play_time/upload.rb
89
+ - lib/play_time/version.rb
90
+ - play_time.gemspec
91
+ - spec/apk_spec.rb
92
+ - spec/client_spec.rb
93
+ - spec/configuration_spec.rb
94
+ - spec/play_time_spec.rb
95
+ - spec/runner_spec.rb
96
+ - spec/spec_helper.rb
97
+ - spec/support/config/default.yml
98
+ - spec/track_spec.rb
99
+ - spec/upload_spec.rb
100
+ homepage: https://github.com/is-devteam/play_time
101
+ licenses:
102
+ - MIT
103
+ metadata: {}
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 2.2.2
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: PlayTime is a gem for uploading apks to the Google Play Store
124
+ test_files:
125
+ - spec/apk_spec.rb
126
+ - spec/client_spec.rb
127
+ - spec/configuration_spec.rb
128
+ - spec/play_time_spec.rb
129
+ - spec/runner_spec.rb
130
+ - spec/spec_helper.rb
131
+ - spec/support/config/default.yml
132
+ - spec/track_spec.rb
133
+ - spec/upload_spec.rb