hockeyapp 0.0.15

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.
@@ -0,0 +1,30 @@
1
+ module HockeyApp
2
+ class AndroidAppUrls
3
+ def initialize app
4
+ @app=app
5
+ end
6
+
7
+ def direct_download_url
8
+ "https://rink.hockeyapp.net/api/2/apps/#{@app.public_identifier}?format=apk"
9
+ end
10
+
11
+ def install_url
12
+ direct_download_url
13
+ end
14
+
15
+ end
16
+
17
+ class AndroidVersionUrls
18
+ def initialize version
19
+ @version=version
20
+ end
21
+
22
+ def direct_download_url
23
+ "https://rink.hockeyapp.net/api/2/apps/#{@version.app.public_identifier}/app_versions/#{@version.id.to_s}?format=apk"
24
+ end
25
+
26
+ def install_url
27
+ direct_download_url
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,35 @@
1
+ module HockeyApp
2
+ class IOSAppUrls
3
+ def initialize app
4
+ @app=app
5
+ end
6
+ def download_url
7
+ "https://rink.hockeyapp.net/apps/#{@app.public_identifier}"
8
+ end
9
+
10
+ def direct_download_url
11
+ @app.last_version.direct_download_url
12
+ end
13
+
14
+ def install_url
15
+ @app.last_version.install_url
16
+ end
17
+
18
+ end
19
+
20
+ class IOSVersionUrls
21
+
22
+ def initialize version
23
+ @version = version
24
+ end
25
+
26
+ def direct_download_url
27
+ "https://rink.hockeyapp.net/api/2/apps/#{@version.app.public_identifier}/app_versions/#{@version.id.to_s}?format=ipa"
28
+ end
29
+
30
+ def install_url
31
+ location = "https://rink.hockeyapp.net/api/2/apps/#{@version.app.public_identifier}/app_versions/#{@version.id.to_s}?format=plist"
32
+ "itms-services://?action=download-manifest&url=#{CGI::escape(location)}"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,72 @@
1
+ module HockeyApp
2
+ class Client
3
+
4
+ def initialize ws
5
+ @ws = ws
6
+ end
7
+
8
+ def get_apps
9
+ apps_hash = ws.get_apps
10
+ assert_success apps_hash
11
+ apps_hash["apps"].map{|app_hash|App.from_hash(app_hash, self)}
12
+ end
13
+
14
+ def get_crashes app
15
+ crashes_hash = ws.get_crashes app.public_identifier
16
+ assert_success crashes_hash
17
+ crashes_hash["crashes"].map{|crash_hash|Crash.from_hash(crash_hash, app, self)}
18
+ end
19
+
20
+ def get_crash_groups app
21
+ crash_groups_hash = ws.get_crash_groups app.public_identifier
22
+ assert_success crash_groups_hash
23
+ crash_groups_hash["crash_reasons"].map{|reason_hash|CrashGroup.from_hash(reason_hash, app, self)}
24
+ end
25
+
26
+ def get_crash_log crash
27
+ ws.get_crash_log crash.app.public_identifier, crash.id
28
+ end
29
+
30
+ def get_crash_description crash
31
+ ws.get_crash_description crash.app.public_identifier, crash.id
32
+ end
33
+
34
+ def get_versions app
35
+ versions_hash = ws.get_versions app.public_identifier
36
+ versions_hash["app_versions"].map{|version_hash|Version.from_hash(version_hash, app, self)}
37
+ end
38
+
39
+ def post_new_version version
40
+ app_id = version.app.public_identifier
41
+ ipa = version.ipa
42
+ raise "There must be an executable file" if ipa.nil?
43
+ version_hash = ws.post_new_version(app_id, ipa, version.dsym, version.notes, version.notes_type, version.notify, version.status)
44
+ raise version_hash['errors'].map{|e|e.to_s}.join("\n") unless version_hash['errors'].nil?
45
+ Version.from_hash(version_hash, version.app, self)
46
+ end
47
+
48
+ def remove_app app
49
+ resp = ws.remove_app app.public_identifier
50
+ raise "unexpected response" if resp.code != 200
51
+ resp.code == 200
52
+ end
53
+
54
+ def create_app file_ipa
55
+ resp = ws.post_new_app(file_ipa)
56
+ raise resp['errors'].map{|e|e.to_s}.join("\n") unless resp['errors'].nil?
57
+ App.from_hash(resp, self)
58
+ end
59
+
60
+
61
+
62
+ private
63
+
64
+ attr_reader :ws
65
+
66
+ def assert_success hash
67
+ status = hash["status"]
68
+ raise "Bad Status : #{status}" unless status == "success"
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,96 @@
1
+ require 'httmultiparty'
2
+
3
+ module HockeyApp
4
+ class WS
5
+ include HTTMultiParty
6
+ base_uri 'https://rink.hockeyapp.net/api/2'
7
+ headers 'Accept' => 'application/json'
8
+ format :json
9
+
10
+
11
+ def initialize (options = {})
12
+ @options = Config.to_h.merge(options)
13
+ raise "No API Token Given" if (@options[:token].nil?)
14
+ self.class.headers 'X-HockeyAppToken' => @options[:token]
15
+ self.class.base_uri @options[:base_uri] if @options[:base_uri].present?
16
+ end
17
+
18
+
19
+ def get_apps
20
+ self.class.get '/apps'
21
+ end
22
+
23
+
24
+ def get_crashes app_id, options = {}
25
+ self.class.get "/apps/#{app_id}/crashes", options
26
+ end
27
+
28
+ def get_crash_groups app_id, options = {}
29
+ self.class.get "/apps/#{app_id}/crash_reasons", options
30
+ end
31
+
32
+ # this is damn not thread safe !
33
+ def get_crash_log app_id, crash_id, options = {}
34
+ self.class.format :plain
35
+ log = self.class.get "/apps/#{app_id}/crashes/#{crash_id}?format=log", options
36
+ self.class.format :json
37
+ log
38
+ end
39
+
40
+ # this is damn not thread safe !
41
+ def get_crash_description app_id, crash_id, options = {}
42
+ self.class.format :plain
43
+ description = self.class.get "/apps/#{app_id}/crashes/#{crash_id}?format=text", options
44
+ self.class.format :json
45
+ description
46
+ end
47
+
48
+ def get_versions app_id, options = {}
49
+ self.class.get "/apps/#{app_id}/app_versions", options
50
+ end
51
+
52
+ def post_new_version(
53
+ app_id,
54
+ ipa,
55
+ dsym=nil,
56
+ notes="New version",
57
+ notes_type=Version::NOTES_TYPES_TO_SYM.invert[:textile],
58
+ notify=Version::NOTIFY_TO_BOOL.invert[false],
59
+ status=Version::STATUS_TO_SYM.invert[:allow]
60
+ )
61
+ params = {
62
+ :ipa => ipa ,
63
+ :dsym => dsym ,
64
+ :notes => notes,
65
+ :notes_type => notes_type,
66
+ :notify => notify,
67
+ :status => status
68
+ }
69
+ params.reject!{|_,v|v.nil?}
70
+ self.class.post "/apps/#{app_id}/app_versions", :body => params
71
+ end
72
+
73
+
74
+ def remove_app app_id
75
+ self.class.format :plain
76
+ response = self.class.delete "/apps/#{app_id}"
77
+ self.class.format :json
78
+ response
79
+ end
80
+
81
+ def post_new_app(file_ipa,
82
+ notes="New app",
83
+ notes_type=App::NOTES_TYPES_TO_SYM.invert[:textile],
84
+ notify=App::NOTIFY_TO_BOOL.invert[false],
85
+ status=App::STATUS_TO_SYM.invert[:allow])
86
+ params = {
87
+ :ipa => file_ipa,
88
+ :notes => notes,
89
+ :notes_type => notes_type,
90
+ :notify => notify,
91
+ :status => status
92
+ }
93
+ self.class.post "/apps", :body => params
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'support/rspec_helper'
2
+
3
+ describe HockeyApp::Config do
4
+
5
+ it "can be set throug configure method" do
6
+ HockeyApp::Config.configure do |config|
7
+ config.token = "ABCDEF"
8
+ end
9
+
10
+ HockeyApp::Config.token.should == "ABCDEF"
11
+ end
12
+
13
+ it "can store a token" do
14
+ HockeyApp::Config.token = "ABCDEF"
15
+ HockeyApp::Config.token.should == "ABCDEF"
16
+ end
17
+
18
+ it "can store a base_uri" do
19
+ HockeyApp::Config.base_uri = "foo"
20
+ HockeyApp::Config.base_uri.should == "foo"
21
+ end
22
+
23
+ it "can transform into a hash" do
24
+ HockeyApp::Config.configure do |config|
25
+ config.token = "ABCDEF"
26
+ config.base_uri = "foobar"
27
+ end
28
+ hash = HockeyApp::Config.to_h
29
+ hash.should == {
30
+ :token => "ABCDEF",
31
+ :base_uri => "foobar"
32
+ }
33
+ end
34
+
35
+ end
@@ -0,0 +1,13 @@
1
+ require 'support/rspec_helper'
2
+
3
+ describe HockeyApp do
4
+ before :each do
5
+ HockeyApp::Config.configure do |config|
6
+ config.token = "ABCDEF"
7
+ end
8
+ end
9
+ it "can build a ws client" do
10
+ client = HockeyApp.build_client
11
+ client.should be_a HockeyApp::Client
12
+ end
13
+ end
@@ -0,0 +1,143 @@
1
+ require_relative '../support/rspec_helper'
2
+
3
+ describe HockeyApp::App do
4
+
5
+ before :each do
6
+ h = {
7
+ "bundle_identifier" => "de.codenauts.hockeytest.beta",
8
+ "device_family" => "iPhone/iPod",
9
+ "public_identifier" => "1234567890abcdef1234567890abcdef",
10
+ "company" => "some company",
11
+ "release_type" => 0,
12
+ "platform" => "iOS",
13
+ "title" => "Hockey Test",
14
+ "role" => 0,
15
+ "status" => 2,
16
+ "minimum_os_version" => "4.0",
17
+ "owner" => "John Doe"
18
+ }
19
+ @client = HockeyApp::Client.new(HockeyApp::FakeWS.new)
20
+ @app = HockeyApp::App.from_hash h, @client
21
+ @model = @app
22
+ end
23
+
24
+ it_behaves_like "ActiveModel"
25
+
26
+ it "can give me info about my application" do
27
+ @app.bundle_identifier.should == "de.codenauts.hockeytest.beta"
28
+ @app.device_family.should == "iPhone/iPod"
29
+ @app.public_identifier.should == "1234567890abcdef1234567890abcdef"
30
+ @app.company.should == "some company"
31
+ @app.release_type.should == 0
32
+ @app.platform.should == "iOS"
33
+ @app.title.should == "Hockey Test"
34
+ @app.role.should == 0
35
+ @app.status.should == 2
36
+ @app.minimum_os_version.should == "4.0"
37
+ @app.owner.should == "John Doe"
38
+ end
39
+
40
+
41
+ it "will call client once when asked for crashes" do
42
+ @client.should_receive(:get_crashes).with(@app).and_return([])
43
+ @app.crashes
44
+ @client.should_not_receive(:get_crashes).with(@app)
45
+ @app.crashes
46
+ end
47
+
48
+ it "will call client once when asked for crash reasons" do
49
+ @client.should_receive(:get_crash_groups).with(@app).and_return([])
50
+ @app.crash_reasons
51
+ @client.should_not_receive(:get_crash_groups).with(@app)
52
+ @app.crash_reasons
53
+ end
54
+
55
+ it "will call client once when asked for versions" do
56
+ @client.should_receive(:get_versions).with(@app).and_return([])
57
+ @app.versions
58
+ @client.should_not_receive(:get_versions).with(@app)
59
+ @app.versions
60
+ end
61
+
62
+ it "can generate a download url" do
63
+ @app.download_url.should == "https://rink.hockeyapp.net/apps/0873e2b98ad046a92c170a243a8515f6/app_versions/208"
64
+ end
65
+
66
+
67
+
68
+ it "can generate a direct download url for Android" do
69
+ @app.platform = "Android"
70
+ @app.direct_download_url.should == "https://rink.hockeyapp.net/api/2/apps/1234567890abcdef1234567890abcdef?format=apk"
71
+ end
72
+
73
+ it "can generate a direct download url for iOS" do
74
+ @app.platform = "iOS"
75
+ @app.direct_download_url.should == "https://rink.hockeyapp.net/api/2/apps/1234567890abcdef1234567890abcdef/app_versions/208?format=ipa"
76
+ end
77
+
78
+ it "can generate an install url for iOS" do
79
+ @app.install_url.should == "itms-services://?action=download-manifest&url=https%3A%2F%2Frink.hockeyapp.net%2Fapi%2F2%2Fapps%2F1234567890abcdef1234567890abcdef%2Fapp_versions%2F208%3Fformat%3Dplist"
80
+ end
81
+
82
+ it "can generate an icon url for iOS" do
83
+ @app.icon.should == "https://rink.hockeyapp.net/api/2/apps/1234567890abcdef1234567890abcdef?format=png"
84
+ end
85
+
86
+ it "can generate an icon url for Android" do
87
+ @app.platform = "Android"
88
+ @app.icon.should == "https://rink.hockeyapp.net/api/2/apps/1234567890abcdef1234567890abcdef?format=png"
89
+ end
90
+
91
+ it "can generate an install url for Android" do
92
+ @app.platform = "Android"
93
+ @app.install_url.should == @app.direct_download_url
94
+ end
95
+
96
+
97
+ describe "#create_version" do
98
+ it "will create a new version instance and pass it to the webservice" do
99
+ release_notes = "New version from automated test"
100
+ binary_file = double('file')
101
+ fake_version = double('version')
102
+ HockeyApp::Version.should_receive(:new).with(@app, @client).and_return(fake_version)
103
+ fake_version.should_receive(:ipa=).with(binary_file)
104
+ fake_version.should_receive(:notes=).with(release_notes)
105
+ @client.should_receive(:post_new_version).with(fake_version)
106
+ @app.create_version(binary_file, release_notes)
107
+ end
108
+
109
+ end
110
+
111
+ describe "#remove_app", :js => true do
112
+ it "will remove an app from hockeyapp", :driver => :webkit do
113
+ @client.should_receive(:remove_app).with(@app).and_return(true)
114
+ @app.remove
115
+ end
116
+ end
117
+
118
+ describe "#last_version" do
119
+
120
+ it "sorts the versions" do
121
+ versions = double("versions")
122
+ @app.should_receive(:versions).and_return(versions)
123
+ versions.should_receive(:sort_by).and_return([])
124
+ @app.last_version
125
+ end
126
+
127
+ context "there are 3 versions for this app" do
128
+ before :each do
129
+ @version1 = double("Version1", :version => "5")
130
+ @version2 = double("Version2", :version => "10")
131
+ @version3 = double("Version3", :version => "6")
132
+ @versions = [@version1, @version2, @version3]
133
+
134
+ end
135
+ it "returns the last version" do
136
+ @app.should_receive(:versions).and_return(@versions)
137
+ @app.last_version.version.should == "10"
138
+ end
139
+ end
140
+
141
+
142
+ end
143
+ end
@@ -0,0 +1,53 @@
1
+ require_relative '../support/rspec_helper'
2
+
3
+ describe HockeyApp::CrashGroup do
4
+
5
+ before :each do
6
+ h = {
7
+ "file" => "AbstractParser.java",
8
+ "reason" => "java.lang.RuntimeException: An error occured while executing doInBackground()",
9
+ "status" => 1,
10
+ "id" => 135837,
11
+ "class" => "com.tapptic.common.parser.AbstractParser",
12
+ "bundle_version" => "2",
13
+ "last_crash_at" => "2011-12-15T20:07:11Z",
14
+ "app_version_id" => 2,
15
+ "line" => "48",
16
+ "updated_at" => "2012-01-03T13:22:01Z",
17
+ "bundle_short_version" => "0.2",
18
+ "method" => "parse",
19
+ "number_of_crashes" => 2,
20
+ "fixed" => true,
21
+ "created_at" => "2011-12-15T20:06:49Z",
22
+ "app_id" => 9999
23
+ }
24
+ @client = HockeyApp::Client.new(HockeyApp::FakeWS.new)
25
+ @app = HockeyApp::App.from_hash( {"public_identifier" => "91423bc5519dd2462513abbb54598959"}, @client)
26
+ @crash_group = HockeyApp::CrashGroup.from_hash h, @app, @client
27
+ @model = @crash_group
28
+ end
29
+
30
+ it_behaves_like "ActiveModel"
31
+
32
+ it "can give me info about the crash group" do
33
+ @crash_group.file.should == "AbstractParser.java"
34
+ @crash_group.reason.should == "java.lang.RuntimeException: An error occured while executing doInBackground()"
35
+ @crash_group.status.should == 1
36
+ @crash_group.id.should == 135837
37
+ @crash_group.crash_class.should == "com.tapptic.common.parser.AbstractParser"
38
+ @crash_group.bundle_version.should == "2"
39
+ @crash_group.last_crash_at.should == "2011-12-15T20:07:11Z"
40
+ @crash_group.app_version_id.should == 2
41
+ @crash_group.updated_at.should == "2012-01-03T13:22:01Z"
42
+ @crash_group.bundle_short_version.should == "0.2"
43
+ @crash_group.method.should == "parse"
44
+ @crash_group.number_of_crashes.should == 2
45
+ @crash_group.fixed.should == true
46
+ @crash_group.created_at.should == "2011-12-15T20:06:49Z"
47
+ @crash_group.app_id.should == 9999
48
+ end
49
+
50
+
51
+
52
+ end
53
+