azuki-api 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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