azuki-api 0.0.2

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.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.travis.yml +16 -0
  4. data/Gemfile +4 -0
  5. data/README.md +128 -0
  6. data/Rakefile +41 -0
  7. data/azuki-api.gemspec +23 -0
  8. data/changelog.txt +204 -0
  9. data/lib/azuki-api.rb +1 -0
  10. data/lib/azuki/api.rb +146 -0
  11. data/lib/azuki/api/addons.rb +48 -0
  12. data/lib/azuki/api/apps.rb +71 -0
  13. data/lib/azuki/api/attachments.rb +14 -0
  14. data/lib/azuki/api/collaborators.rb +33 -0
  15. data/lib/azuki/api/config_vars.rb +33 -0
  16. data/lib/azuki/api/domains.rb +42 -0
  17. data/lib/azuki/api/errors.rb +26 -0
  18. data/lib/azuki/api/features.rb +45 -0
  19. data/lib/azuki/api/keys.rb +42 -0
  20. data/lib/azuki/api/login.rb +14 -0
  21. data/lib/azuki/api/logs.rb +18 -0
  22. data/lib/azuki/api/mock.rb +179 -0
  23. data/lib/azuki/api/mock/addons.rb +153 -0
  24. data/lib/azuki/api/mock/apps.rb +205 -0
  25. data/lib/azuki/api/mock/attachments.rb +19 -0
  26. data/lib/azuki/api/mock/cache/get_addons.json +1 -0
  27. data/lib/azuki/api/mock/cache/get_features.json +1 -0
  28. data/lib/azuki/api/mock/cache/get_user.json +1 -0
  29. data/lib/azuki/api/mock/collaborators.rb +55 -0
  30. data/lib/azuki/api/mock/config_vars.rb +49 -0
  31. data/lib/azuki/api/mock/domains.rb +80 -0
  32. data/lib/azuki/api/mock/features.rb +120 -0
  33. data/lib/azuki/api/mock/keys.rb +46 -0
  34. data/lib/azuki/api/mock/login.rb +22 -0
  35. data/lib/azuki/api/mock/logs.rb +20 -0
  36. data/lib/azuki/api/mock/processes.rb +198 -0
  37. data/lib/azuki/api/mock/releases.rb +69 -0
  38. data/lib/azuki/api/mock/stacks.rb +83 -0
  39. data/lib/azuki/api/mock/user.rb +16 -0
  40. data/lib/azuki/api/processes.rb +77 -0
  41. data/lib/azuki/api/releases.rb +33 -0
  42. data/lib/azuki/api/ssl_endpoints.rb +62 -0
  43. data/lib/azuki/api/stacks.rb +22 -0
  44. data/lib/azuki/api/user.rb +14 -0
  45. data/lib/azuki/api/vendor/okjson.rb +600 -0
  46. data/lib/azuki/api/version.rb +5 -0
  47. data/test/data/site.crt +19 -0
  48. data/test/data/site.key +27 -0
  49. data/test/test_addons.rb +193 -0
  50. data/test/test_apps.rb +147 -0
  51. data/test/test_attachments.rb +23 -0
  52. data/test/test_collaborators.rb +73 -0
  53. data/test/test_config_vars.rb +54 -0
  54. data/test/test_domains.rb +65 -0
  55. data/test/test_error_conditions.rb +11 -0
  56. data/test/test_features.rb +87 -0
  57. data/test/test_helper.rb +48 -0
  58. data/test/test_keys.rb +39 -0
  59. data/test/test_login.rb +20 -0
  60. data/test/test_logs.rb +29 -0
  61. data/test/test_processes.rb +245 -0
  62. data/test/test_releases.rb +73 -0
  63. data/test/test_ssl_endpoints.rb +132 -0
  64. data/test/test_stacks.rb +49 -0
  65. data/test/test_user.rb +13 -0
  66. metadata +168 -0
@@ -0,0 +1,5 @@
1
+ module Azuki
2
+ class API
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIC/jCCAeYCCQDqx6gBfaFHsjANBgkqhkiG9w0BAQUFADBBMQswCQYDVQQGEwJV
3
+ UzELMAkGA1UECBMCQ0ExDzANBgNVBAoTBkhlcm9rdTEUMBIGA1UEAxMLZXhhbXBs
4
+ ZS5jb20wHhcNMTIwODAxMjIzMjA5WhcNMTMwODAxMjIzMjA5WjBBMQswCQYDVQQG
5
+ EwJVUzELMAkGA1UECBMCQ0ExDzANBgNVBAoTBkhlcm9rdTEUMBIGA1UEAxMLZXhh
6
+ bXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/0Nhc36j5
7
+ CHgbEFYyExDR6PKLrhfJPGtYZTDlpy+d/vT+sFp1m81k/68/ylQwq7lJROvfrQ0M
8
+ vAZNO2axWOJnjSrEqQo96VLrFYp5dmkG7bWBjAa+aHzn3fvoKQ2NDrFLFRcuaw0Q
9
+ ra593EFry1VfbI4UeQPdy1V4fFm2A0l9S33Y9Fd/Qv/kUShKgjJXJISdg6PFruz9
10
+ XLqO3kjS1wDVCBrm+t3D6qxC99N3fW//9tCgjZHaiRRgs5B5DyJI3CIi1vmUR5IZ
11
+ 7vGFFtw84LcOh6PHWr/ZwRCDJa4dFtjI5fix6GLJZ7FhmezDyeqzqbVVEOIO9wbN
12
+ 0QXV1d8BBCw1AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAHsCtjR4qNfwtcBu95oR
13
+ jBnUReaxkYLA3Tbcy5bqusLnPvlgUhNn4XUWuPy0QVPP9TK/VGguqZrpJlfdWUJW
14
+ qrh5VX7ixieGWzHGw1bDzHA5ZNchyQyLyFHdXGw1dA85yVXZoAFkUxwY0qCRGWnt
15
+ /Kqct507tqsilFpliS9lzAY/E1GYSHRWuXB6I6tMZD0/jd9zPcg8Y/2aYuvuZ2SC
16
+ A3P04IhG9X9O8MGEPlxdlxmSHi6Vuj8iV+5N3zcodntOcLHlRm6grOC4y6xXaIfE
17
+ KDNGnoOsTJA+yPVtx8R2oZUHA52y09EjujzwMvXgKiq9R33zw6eQwrsD6Pp023Hj
18
+ 6CQ=
19
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEpAIBAAKCAQEAv9DYXN+o+Qh4GxBWMhMQ0ejyi64XyTxrWGUw5acvnf70/rBa
3
+ dZvNZP+vP8pUMKu5SUTr360NDLwGTTtmsVjiZ40qxKkKPelS6xWKeXZpBu21gYwG
4
+ vmh859376CkNjQ6xSxUXLmsNEK2ufdxBa8tVX2yOFHkD3ctVeHxZtgNJfUt92PRX
5
+ f0L/5FEoSoIyVySEnYOjxa7s/Vy6jt5I0tcA1Qga5vrdw+qsQvfTd31v//bQoI2R
6
+ 2okUYLOQeQ8iSNwiItb5lEeSGe7xhRbcPOC3Doejx1q/2cEQgyWuHRbYyOX4sehi
7
+ yWexYZnsw8nqs6m1VRDiDvcGzdEF1dXfAQQsNQIDAQABAoIBAQCt/ExUqZbGFHWE
8
+ 7uOQVhTaobZnFkmDAefIbTjWBji90gX9go76wJCkfPtEHE0TPKA7ImXlJD2DAIWi
9
+ xi+Wy63JCZXyffXJRHsuuwI4vDv1yeXqFM4FJhet5X9aDOq6uMn99apqMzXNnAx7
10
+ Iy7ADNZqULfrP/1Oz+G+AOUKoJ6nIyD6v1dGCfJhZhQyymhyOsEYjXl2RzSLHL1G
11
+ d6+404nnV7hP8zhQjREleYk/F1ZewJhtS7Tsv9YeeuckLQDBTfutuyS07QzRvnyf
12
+ XqXo9mhkl0OK27Jml82XFwquFBe/FoH8lKoXax3PT5xXQ6/UJQ4pOJi3D5ZnOLUk
13
+ Lsc9Fr89AoGBAOmbzXuF62MksVsk6bcV1UhmY+sGSNQwRa7GShczMgQE/GHDTayW
14
+ km2T1NLQt5oL0lnXMtuX6Wi0y2oNu+x3q5/O7DR+EQqsX4nbX34jynNsEmRv27pC
15
+ vACq7wRaaDoLWm14DX8Qp8KZmPTXsoRoswv6/hdvPMg3nNB+HxP10LknAoGBANIz
16
+ jAKi2XkaJRkSMBuqTjND3UkDIOwcd1v5V3Dy0bLlegBTxyIhlhicwO6JHZ8u5obx
17
+ 68eikKMc9gXf6hJTcNXbogf6t4+/v5oKgPVA6puPefZkt1Lswc1aR7NdC5tYmplc
18
+ C71WZISEONEQsTbp1c5QOJ69/gf325IE3sXb+vFDAoGAIy97WKKIHKu3JuI9bX0V
19
+ Xc1GOWz95S/MHxHwsOPeIaralKME/PzE20pL4ODc9o/XQ/7cwyRzXHj2tmeRKYGw
20
+ 0OYqv5FJYdEqpqnrDSW45X+emZAbiUdp57PXQlGXpz50hU5ywfOxQOc/mYkvczAN
21
+ 370TLlZr0kBGF0UXyzrYEDsCgYAlHm8qBAHtTb2hWMHgEMnwaZqJCyFkMH6vYi+b
22
+ xXVcZwONTT4L++xaekvjk5kEhC63Q79EKKPr+fBEB095Xvy89yT8zbxeiRjXpeUx
23
+ 6f3D7Kk35n8tCJwMnFWvCc5D53idflCgZcIoWIUD/jOdI9vaq/Xjql9SnuVKOsvw
24
+ GrGMqwKBgQCytS+qZdQ8/OoDSO+iLQr7prVxAfzVwuPggTIoRKcdU83o/2O89ipY
25
+ zkcS+NcCD78phRydu9G6dFhDThkQYGcouF1tYpNqbjqqMoudcP35yE2+h3pzmiuV
26
+ hZIQ2YjfaWARcNX+881gDb7m6835lCFyAZ75z9xsSWpYb+4EVH0gjg==
27
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,193 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/test_helper")
2
+
3
+ class TestAddons < MiniTest::Unit::TestCase
4
+
5
+ def test_delete_addon_addon_not_found
6
+ with_app do |app_data|
7
+ assert_raises(Azuki::API::Errors::RequestFailed) do
8
+ azuki.delete_addon(app_data['name'], random_name)
9
+ end
10
+ end
11
+ end
12
+
13
+ def test_delete_addon_addon_not_installed
14
+ with_app do |app_data|
15
+ assert_raises(Azuki::API::Errors::RequestFailed) do
16
+ azuki.delete_addon(app_data['name'], 'custom_domains:basic')
17
+ end
18
+ end
19
+ end
20
+
21
+ def test_delete_addon_app_not_found
22
+ assert_raises(Azuki::API::Errors::NotFound) do
23
+ azuki.delete_addon(random_name, 'logging:basic')
24
+ end
25
+ end
26
+
27
+ def test_delete_addon
28
+ with_app do |app_data|
29
+ azuki.post_addon(app_data['name'], 'deployhooks:http')
30
+ response = azuki.delete_addon(app_data['name'], 'deployhooks:http')
31
+
32
+ assert_equal(200, response.status)
33
+ assert_equal({
34
+ 'message' => nil,
35
+ 'price' => 'free',
36
+ 'status' => 'Uninstalled'
37
+ }, response.body)
38
+ end
39
+ end
40
+
41
+ def test_get_addons
42
+ response = azuki.get_addons
43
+ data = File.read("#{File.dirname(__FILE__)}/../lib/azuki/api/mock/cache/get_addons.json")
44
+
45
+ assert_equal(200, response.status)
46
+ assert_equal(Azuki::API::OkJson.decode(data), response.body)
47
+ end
48
+
49
+ def test_get_addons_with_app
50
+ with_app do |app_data|
51
+ response = azuki.get_addons(app_data['name'])
52
+
53
+ assert_equal(200, response.status)
54
+ assert_equal([{
55
+ 'attachable' => false,
56
+ 'beta' => false,
57
+ 'configured' => true,
58
+ 'consumes_dyno_hours' => false,
59
+ 'description' => 'Shared Database 5MB',
60
+ 'group_description' => 'Shared Database',
61
+ 'name' => 'shared-database:5mb',
62
+ 'plan_description' => '5mb',
63
+ 'price' => { 'cents' => 0, 'unit' => 'month' },
64
+ 'slug' => '5mb',
65
+ 'state' => 'public',
66
+ 'terms_of_service' => false,
67
+ 'url' => nil
68
+ }], response.body)
69
+ end
70
+ end
71
+
72
+ def test_get_addons_with_app_app_not_found
73
+ assert_raises(Azuki::API::Errors::NotFound) do
74
+ azuki.get_addons(random_name)
75
+ end
76
+ end
77
+
78
+ def test_post_addon
79
+ with_app do |app_data|
80
+ response = azuki.post_addon(app_data['name'], 'deployhooks:http')
81
+
82
+ assert_equal(200, response.status)
83
+ assert_equal({
84
+ 'message' => nil,
85
+ 'price' => 'free',
86
+ 'status' => 'Installed'
87
+ }, response.body)
88
+ end
89
+ end
90
+
91
+ def test_post_addon_with_config
92
+ with_app do |app_data|
93
+ response = azuki.post_addon(app_data['name'], 'deployhooks:http', {"url"=>"http://example.com"})
94
+
95
+ assert_equal(200, response.status)
96
+ assert_equal({
97
+ 'message' => nil,
98
+ 'price' => 'free',
99
+ 'status' => 'Installed'
100
+ }, response.body)
101
+ end
102
+ end
103
+
104
+ def test_post_add_on_with_config_parses_config_correctly
105
+ with_app do |app_data|
106
+ addon_post_path = "/apps/#{app_data['name']}/addons/deployhooks:http"
107
+ Excon.stub({:method => :post, :path => addon_post_path}) do |params|
108
+ {:body => params[:query], :status => 200}
109
+ end
110
+ response = azuki.post_addon(app_data['name'], 'deployhooks:http', {"url"=>"http://example.com"})
111
+ assert_equal({ "config[url]" => "http://example.com"}, response.body)
112
+ end
113
+ Excon.stubs.shift
114
+ end
115
+
116
+ def test_post_addon_addon_already_installed
117
+ with_app do |app_data|
118
+ assert_raises(Azuki::API::Errors::RequestFailed) do
119
+ azuki.post_addon(app_data['name'], 'logging:basic')
120
+ azuki.post_addon(app_data['name'], 'logging:basic')
121
+ end
122
+ end
123
+ end
124
+
125
+ def test_post_addon_addon_type_already_installed
126
+ with_app do |app_data|
127
+ assert_raises(Azuki::API::Errors::RequestFailed) do
128
+ azuki.post_addon(app_data['name'], 'logging:basic')
129
+ azuki.post_addon(app_data['name'], 'logging:expanded')
130
+ end
131
+ end
132
+ end
133
+
134
+ def test_post_addon_addon_not_found
135
+ with_app do |app_data|
136
+ assert_raises(Azuki::API::Errors::NotFound) do
137
+ azuki.post_addon(app_data['name'], random_name)
138
+ end
139
+ end
140
+ end
141
+
142
+ def test_post_addon_app_not_found
143
+ assert_raises(Azuki::API::Errors::NotFound) do
144
+ azuki.post_addon(random_name, 'shared-database:5mb')
145
+ end
146
+ end
147
+
148
+ def test_put_addon
149
+ with_app do |app_data|
150
+ response = azuki.post_addon(app_data['name'], 'pgbackups:basic')
151
+ response = azuki.put_addon(app_data['name'], 'pgbackups:plus')
152
+
153
+ assert_equal(200, response.status)
154
+ assert_equal({
155
+ 'message' => 'Plan upgraded',
156
+ 'price' => 'free',
157
+ 'status' => 'Updated'
158
+ }, response.body)
159
+ end
160
+ end
161
+
162
+ def test_put_addon_addon_already_installed
163
+ with_app do |app_data|
164
+ assert_raises(Azuki::API::Errors::RequestFailed) do
165
+ azuki.post_addon(app_data['name'], 'logging:basic')
166
+ azuki.put_addon(app_data['name'], 'logging:basic')
167
+ end
168
+ end
169
+ end
170
+
171
+ def test_put_addon_addon_not_found
172
+ with_app do |app_data|
173
+ assert_raises(Azuki::API::Errors::NotFound) do
174
+ azuki.put_addon(app_data['name'], random_name)
175
+ end
176
+ end
177
+ end
178
+
179
+ def test_put_addon_addon_type_not_installed
180
+ with_app do |app_data|
181
+ assert_raises(Azuki::API::Errors::RequestFailed) do
182
+ azuki.put_addon(app_data['name'], 'releases:basic')
183
+ end
184
+ end
185
+ end
186
+
187
+ def test_put_addon_app_not_found
188
+ assert_raises(Azuki::API::Errors::NotFound) do
189
+ azuki.put_addon(random_name, 'logging:basic')
190
+ end
191
+ end
192
+
193
+ end
@@ -0,0 +1,147 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/test_helper")
2
+
3
+ class TestApps < MiniTest::Unit::TestCase
4
+
5
+ def test_delete_app
6
+ with_app do |app_data|
7
+ response = azuki.delete_app(app_data['name'])
8
+ assert_equal({}, response.body)
9
+ assert_equal(200, response.status)
10
+ end
11
+ end
12
+
13
+ def test_delete_app_not_found
14
+ assert_raises(Azuki::API::Errors::NotFound) do
15
+ azuki.delete_app(random_name)
16
+ end
17
+ end
18
+
19
+ def test_get_apps
20
+ with_app do |app_data|
21
+ response = azuki.get_apps
22
+ assert_equal(200, response.status)
23
+ assert(response.body.detect {|app| app['name'] == app_data['name']})
24
+ end
25
+ end
26
+
27
+ def test_get_app
28
+ with_app do |app_data|
29
+ response = azuki.get_app(app_data['name'])
30
+ assert_equal(200, response.status)
31
+ assert_equal(app_data['name'], response.body['name'])
32
+ end
33
+ end
34
+
35
+ def test_get_app_not_found
36
+ assert_raises(Azuki::API::Errors::NotFound) do
37
+ azuki.get_app(random_name)
38
+ end
39
+ end
40
+
41
+ def test_get_app_maintenance
42
+ with_app do |app_data|
43
+ response = azuki.get_app_maintenance(app_data['name'])
44
+
45
+ assert_equal(200, response.status)
46
+ assert_equal({'maintenance' => false}, response.body)
47
+
48
+ azuki.post_app_maintenance(app_data['name'], '1')
49
+ response = azuki.get_app_maintenance(app_data['name'])
50
+
51
+ assert_equal(200, response.status)
52
+ assert_equal({'maintenance' => true}, response.body)
53
+ end
54
+ end
55
+
56
+ def test_post_app
57
+ response = azuki.post_app
58
+
59
+ assert_equal(202, response.status)
60
+
61
+ azuki.delete_app(response.body['name'])
62
+ end
63
+
64
+ def test_post_app_with_name
65
+ name = random_name
66
+ response = azuki.post_app('name' => name)
67
+
68
+ assert_equal(202, response.status)
69
+ assert_equal(name, response.body['name'])
70
+
71
+ azuki.delete_app(name)
72
+ end
73
+
74
+ def test_post_app_with_duplicate_name
75
+ name = random_name
76
+ response = azuki.post_app('name' => name)
77
+
78
+ assert_raises(Azuki::API::Errors::RequestFailed) do
79
+ azuki.post_app('name' => name)
80
+ end
81
+
82
+ azuki.delete_app(name)
83
+ end
84
+
85
+ def test_post_app_with_stack
86
+ response = azuki.post_app('stack' => 'cedar')
87
+
88
+ assert_equal(202, response.status)
89
+ assert_equal('cedar', response.body['stack'])
90
+
91
+ azuki.delete_app(response.body['name'])
92
+ end
93
+
94
+ def test_put_app_not_found
95
+ name = random_name
96
+ assert_raises(Azuki::API::Errors::NotFound) do
97
+ azuki.put_app(name, 'name' => random_name)
98
+ end
99
+ end
100
+
101
+ def test_put_app_with_name
102
+ with_app do |app_data|
103
+ new_name = random_name
104
+ response = azuki.put_app(app_data['name'], 'name' => new_name)
105
+
106
+ assert_equal(200, response.status)
107
+ assert_equal({'name' => new_name}, response.body)
108
+
109
+ azuki.delete_app(new_name)
110
+ end
111
+ end
112
+
113
+ def test_put_app_with_transfer_owner_non_collaborator
114
+ with_app do |app_data|
115
+ assert_raises(Azuki::API::Errors::RequestFailed) do
116
+ azuki.put_app(app_data['name'], 'transfer_owner' => 'wesley@azukiapp.com')
117
+ end
118
+ end
119
+ end
120
+
121
+ def test_put_app_with_transfer_owner
122
+ with_app do |app_data|
123
+ email_address = 'wesley@azukiapp.com'
124
+ azuki.post_collaborator(app_data['name'], email_address)
125
+ response = azuki.put_app(app_data['name'], 'transfer_owner' => email_address)
126
+
127
+ assert_equal(200, response.status)
128
+ assert_equal({'name' => app_data['name']}, response.body)
129
+
130
+ azuki.delete_collaborator(app_data['name'], email_address)
131
+ end
132
+ end
133
+
134
+ def test_post_app_maintenance
135
+ with_app do |app_data|
136
+ response = azuki.post_app_maintenance(app_data['name'], '1')
137
+
138
+ assert_equal(200, response.status)
139
+ assert_equal("", response.body)
140
+
141
+ response = azuki.post_app_maintenance(app_data['name'], '0')
142
+
143
+ assert_equal(200, response.status)
144
+ assert_equal("", response.body)
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/test_helper")
2
+
3
+ class TestAttachments < MiniTest::Unit::TestCase
4
+
5
+ def test_get_attachments
6
+ with_app do |app_data|
7
+ response = azuki.get_attachments(app_data['name'])
8
+
9
+ assert_equal(200, response.status)
10
+ assert_equal(
11
+ [],
12
+ response.body
13
+ )
14
+ end
15
+ end
16
+
17
+ def test_get_attachments_app_not_found
18
+ assert_raises(Azuki::API::Errors::NotFound) do
19
+ azuki.get_attachments(random_name)
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,73 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/test_helper")
2
+
3
+ class TestCollaborators < MiniTest::Unit::TestCase
4
+
5
+ def test_delete_collaborator
6
+ with_app do |app_data|
7
+ email_address = 'wesley@azukiapp.com'
8
+ azuki.post_collaborator(app_data['name'], email_address)
9
+
10
+ response = azuki.delete_collaborator(app_data['name'], email_address)
11
+
12
+ assert_equal(200, response.status)
13
+ assert_equal(
14
+ "#{email_address} has been removed as collaborator on #{app_data['name']}",
15
+ response.body
16
+ )
17
+ end
18
+ end
19
+
20
+ def test_delete_collaborator_app_not_found
21
+ assert_raises(Azuki::API::Errors::NotFound) do
22
+ azuki.delete_collaborator(random_name, random_email_address)
23
+ end
24
+ end
25
+
26
+ def test_delete_collaborator_user_not_found
27
+ with_app do |app_data|
28
+ assert_raises(Azuki::API::Errors::NotFound) do
29
+ azuki.delete_collaborator(app_data['name'], random_email_address)
30
+ end
31
+ end
32
+ end
33
+
34
+ def test_get_collaborators
35
+ with_app do |app_data|
36
+ response = azuki.get_collaborators(app_data['name'])
37
+
38
+ assert_equal(200, response.status)
39
+ assert_equal(
40
+ [{'access' => 'edit', 'email' => app_data['owner_email'], 'name' => nil}],
41
+ response.body
42
+ )
43
+ end
44
+ end
45
+
46
+ def test_get_collaborators_app_not_found
47
+ assert_raises(Azuki::API::Errors::NotFound) do
48
+ azuki.get_collaborators(random_name)
49
+ end
50
+ end
51
+
52
+ def test_post_collaborator
53
+ with_app do |app_data|
54
+ email_address = 'wesley@azukiapp.com'
55
+ response = azuki.post_collaborator(app_data['name'], email_address)
56
+
57
+ assert_equal(201, response.status)
58
+ assert_equal(
59
+ "#{email_address} added as a collaborator on #{app_data['name']}.",
60
+ response.body
61
+ )
62
+
63
+ azuki.delete_collaborator(app_data['name'], email_address)
64
+ end
65
+ end
66
+
67
+ def test_post_collaborator_app_not_found
68
+ assert_raises(Azuki::API::Errors::NotFound) do
69
+ azuki.post_collaborator(random_name, random_email_address)
70
+ end
71
+ end
72
+
73
+ end