rainforest 1.0.7 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -6
- data/.travis.yml +13 -1
- data/Gemfile +6 -0
- data/README.md +72 -21
- data/Rakefile +6 -13
- data/VERSION +1 -1
- data/bin/rainforest-console +1 -1
- data/gemfiles/default-with-activesupport.gemfile +8 -1
- data/gemfiles/json.gemfile +10 -2
- data/gemfiles/yajl.gemfile +10 -2
- data/lib/rainforest.rb +61 -240
- data/lib/rainforest/apibits/api_client.rb +28 -0
- data/lib/rainforest/apibits/api_endpoint.rb +11 -0
- data/lib/rainforest/apibits/api_list.rb +88 -0
- data/lib/rainforest/apibits/api_method.rb +95 -0
- data/lib/rainforest/apibits/api_object.rb +52 -0
- data/lib/rainforest/apibits/api_resource.rb +153 -0
- data/lib/rainforest/apibits/headers_builder.rb +47 -0
- data/lib/rainforest/apibits/params_builder.rb +27 -0
- data/lib/rainforest/apibits/path_builder.rb +38 -0
- data/lib/rainforest/apibits/requester.rb +104 -0
- data/lib/rainforest/apibits/util.rb +51 -0
- data/lib/rainforest/clients/default_client.rb +59 -0
- data/lib/rainforest/endpoints/client_stats_endpoint.rb +11 -0
- data/lib/rainforest/endpoints/environment_runs_endpoint.rb +11 -0
- data/lib/rainforest/endpoints/environments_endpoint.rb +48 -0
- data/lib/rainforest/endpoints/generator_rows_endpoint.rb +17 -0
- data/lib/rainforest/endpoints/generators_endpoint.rb +48 -0
- data/lib/rainforest/endpoints/integrations_endpoint.rb +33 -0
- data/lib/rainforest/endpoints/run_tests_endpoint.rb +20 -0
- data/lib/rainforest/endpoints/runs_endpoint.rb +48 -0
- data/lib/rainforest/endpoints/schedules_endpoint.rb +48 -0
- data/lib/rainforest/endpoints/site_environments_endpoint.rb +24 -0
- data/lib/rainforest/endpoints/sites_endpoint.rb +39 -0
- data/lib/rainforest/endpoints/tests_endpoint.rb +57 -0
- data/lib/rainforest/endpoints/users_endpoint.rb +48 -0
- data/lib/rainforest/errors/api_connection_error.rb +1 -1
- data/lib/rainforest/errors/api_error.rb +32 -1
- data/lib/rainforest/errors/authentication_error.rb +1 -1
- data/lib/rainforest/errors/rainforest_error.rb +2 -9
- data/lib/rainforest/resources/client_stats.rb +31 -0
- data/lib/rainforest/resources/environment.rb +73 -0
- data/lib/rainforest/resources/generator.rb +73 -0
- data/lib/rainforest/resources/integration.rb +52 -0
- data/lib/rainforest/resources/run.rb +93 -0
- data/lib/rainforest/resources/schedule.rb +63 -0
- data/lib/rainforest/resources/site.rb +53 -0
- data/lib/rainforest/resources/site_environment.rb +40 -0
- data/lib/rainforest/resources/test.rb +98 -0
- data/lib/rainforest/resources/user.rb +75 -0
- data/rainforest.gemspec +8 -6
- data/test/rainforest/api_client_test.rb +51 -0
- data/test/rainforest/api_endpoint_test.rb +13 -0
- data/test/rainforest/api_list_test.rb +49 -0
- data/test/rainforest/api_method_test.rb +78 -0
- data/test/rainforest/headers_builder_test.rb +28 -0
- data/test/rainforest/params_builder_test.rb +57 -0
- data/test/rainforest/path_builder_test.rb +50 -0
- data/test/rainforest/requester_test.rb +86 -0
- data/test/rainforest/util_test.rb +41 -19
- data/test/test_data.rb +72 -0
- data/test/test_helper.rb +17 -134
- metadata +99 -59
- data/CONTRIBUTORS +0 -2
- data/History.txt +0 -4
- data/LICENSE +0 -21
- data/lib/data/ca-certificates.crt +0 -3918
- data/lib/rainforest/api_operations/create.rb +0 -16
- data/lib/rainforest/api_operations/delete.rb +0 -11
- data/lib/rainforest/api_operations/list.rb +0 -16
- data/lib/rainforest/api_operations/update.rb +0 -61
- data/lib/rainforest/api_resource.rb +0 -33
- data/lib/rainforest/errors/invalid_request_error.rb +0 -10
- data/lib/rainforest/json.rb +0 -21
- data/lib/rainforest/list_object.rb +0 -35
- data/lib/rainforest/rainforest_object.rb +0 -165
- data/lib/rainforest/run.rb +0 -8
- data/lib/rainforest/singleton_api_resource.rb +0 -20
- data/lib/rainforest/util.rb +0 -100
- data/test/rainforest/api_resource_test.rb +0 -11
- data/test/rainforest/auth_test.rb +0 -24
- data/test/rainforest/list_object_test.rb +0 -7
- data/test/rainforest/metadata_test.rb +0 -7
- data/test/rainforest/run_test.rb +0 -36
@@ -0,0 +1,20 @@
|
|
1
|
+
module Rainforest
|
2
|
+
class RunTestsEndpoint < ApiEndpoint
|
3
|
+
|
4
|
+
def all(params={}, headers={})
|
5
|
+
method = ApiMethod.new(:get, "/runs/:id/tests", params, headers, @parent)
|
6
|
+
json = @client.execute(method)
|
7
|
+
ApiList.new(:Test, json, method)
|
8
|
+
end
|
9
|
+
|
10
|
+
def retrieve(test_id, params={}, headers={})
|
11
|
+
params = ParamsBuilder.merge({
|
12
|
+
:test_id => test_id,
|
13
|
+
}, params)
|
14
|
+
method = ApiMethod.new(:get, "/runs/:id/tests/:test_id", params, headers, @parent)
|
15
|
+
json = @client.execute(method)
|
16
|
+
Test.new(json, method)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Rainforest
|
2
|
+
class RunsEndpoint < ApiEndpoint
|
3
|
+
|
4
|
+
def new(id)
|
5
|
+
Run.new({:id => id}, nil, @client)
|
6
|
+
end
|
7
|
+
|
8
|
+
def all(params={}, headers={})
|
9
|
+
method = ApiMethod.new(:get, "/runs", params, headers, @parent)
|
10
|
+
json = @client.execute(method)
|
11
|
+
ApiList.new(:Run, json, method)
|
12
|
+
end
|
13
|
+
|
14
|
+
def retrieve(run_id, params={}, headers={})
|
15
|
+
params = ParamsBuilder.merge({
|
16
|
+
:run_id => run_id,
|
17
|
+
}, params)
|
18
|
+
method = ApiMethod.new(:get, "/runs/:run_id", params, headers, @parent)
|
19
|
+
json = @client.execute(method)
|
20
|
+
Run.new(json, method)
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete(run_id, params={}, headers={})
|
24
|
+
params = ParamsBuilder.merge({
|
25
|
+
:run_id => run_id,
|
26
|
+
}, params)
|
27
|
+
method = ApiMethod.new(:delete, "/runs/:run_id", params, headers, @parent)
|
28
|
+
json = @client.execute(method)
|
29
|
+
Run.new(json, method)
|
30
|
+
end
|
31
|
+
|
32
|
+
def abort(run_id, params={}, headers={})
|
33
|
+
params = ParamsBuilder.merge({
|
34
|
+
:run_id => run_id,
|
35
|
+
}, params)
|
36
|
+
method = ApiMethod.new(:delete, "/runs/:run_id", params, headers, @parent)
|
37
|
+
json = @client.execute(method)
|
38
|
+
Run.new(json, method)
|
39
|
+
end
|
40
|
+
|
41
|
+
def create(params={}, headers={})
|
42
|
+
method = ApiMethod.new(:post, "/runs", params, headers, @parent)
|
43
|
+
json = @client.execute(method)
|
44
|
+
Run.new(json, method)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Rainforest
|
2
|
+
class SchedulesEndpoint < ApiEndpoint
|
3
|
+
|
4
|
+
def new(id)
|
5
|
+
Schedule.new({:id => id}, nil, @client)
|
6
|
+
end
|
7
|
+
|
8
|
+
def all(params={}, headers={})
|
9
|
+
method = ApiMethod.new(:get, "/schedules", params, headers, @parent)
|
10
|
+
json = @client.execute(method)
|
11
|
+
ApiList.new(:Schedule, json, method)
|
12
|
+
end
|
13
|
+
|
14
|
+
def retrieve(schedule_id, params={}, headers={})
|
15
|
+
params = ParamsBuilder.merge({
|
16
|
+
:schedule_id => schedule_id,
|
17
|
+
}, params)
|
18
|
+
method = ApiMethod.new(:get, "/schedules/:schedule_id", params, headers, @parent)
|
19
|
+
json = @client.execute(method)
|
20
|
+
Schedule.new(json, method)
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete(schedule_id, params={}, headers={})
|
24
|
+
params = ParamsBuilder.merge({
|
25
|
+
:schedule_id => schedule_id,
|
26
|
+
}, params)
|
27
|
+
method = ApiMethod.new(:delete, "/schedules/:schedule_id", params, headers, @parent)
|
28
|
+
json = @client.execute(method)
|
29
|
+
Schedule.new(json, method)
|
30
|
+
end
|
31
|
+
|
32
|
+
def update(schedule_id, params={}, headers={})
|
33
|
+
params = ParamsBuilder.merge({
|
34
|
+
:schedule_id => schedule_id,
|
35
|
+
}, params)
|
36
|
+
method = ApiMethod.new(:put, "/schedules/:schedule_id", params, headers, @parent)
|
37
|
+
json = @client.execute(method)
|
38
|
+
Schedule.new(json, method)
|
39
|
+
end
|
40
|
+
|
41
|
+
def create(params={}, headers={})
|
42
|
+
method = ApiMethod.new(:post, "/schedules", params, headers, @parent)
|
43
|
+
json = @client.execute(method)
|
44
|
+
Schedule.new(json, method)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Rainforest
|
2
|
+
class SiteEnvironmentsEndpoint < ApiEndpoint
|
3
|
+
|
4
|
+
def new(id)
|
5
|
+
SiteEnvironment.new({:id => id}, nil, @client)
|
6
|
+
end
|
7
|
+
|
8
|
+
def all(params={}, headers={})
|
9
|
+
method = ApiMethod.new(:get, "/site_environments", params, headers, @parent)
|
10
|
+
json = @client.execute(method)
|
11
|
+
ApiList.new(:SiteEnvironment, json, method)
|
12
|
+
end
|
13
|
+
|
14
|
+
def update(site_environment_id, params={}, headers={})
|
15
|
+
params = ParamsBuilder.merge({
|
16
|
+
:site_environment_id => site_environment_id,
|
17
|
+
}, params)
|
18
|
+
method = ApiMethod.new(:put, "/site_environments/:site_environment_id", params, headers, @parent)
|
19
|
+
json = @client.execute(method)
|
20
|
+
SiteEnvironment.new(json, method)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Rainforest
|
2
|
+
class SitesEndpoint < ApiEndpoint
|
3
|
+
|
4
|
+
def new(id)
|
5
|
+
Site.new({:id => id}, nil, @client)
|
6
|
+
end
|
7
|
+
|
8
|
+
def all(params={}, headers={})
|
9
|
+
method = ApiMethod.new(:get, "/sites", params, headers, @parent)
|
10
|
+
json = @client.execute(method)
|
11
|
+
ApiList.new(:Site, json, method)
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete(site_id, params={}, headers={})
|
15
|
+
params = ParamsBuilder.merge({
|
16
|
+
:site_id => site_id,
|
17
|
+
}, params)
|
18
|
+
method = ApiMethod.new(:delete, "/sites/:site_id", params, headers, @parent)
|
19
|
+
json = @client.execute(method)
|
20
|
+
Site.new(json, method)
|
21
|
+
end
|
22
|
+
|
23
|
+
def update(site_id, params={}, headers={})
|
24
|
+
params = ParamsBuilder.merge({
|
25
|
+
:site_id => site_id,
|
26
|
+
}, params)
|
27
|
+
method = ApiMethod.new(:put, "/sites/:site_id", params, headers, @parent)
|
28
|
+
json = @client.execute(method)
|
29
|
+
Site.new(json, method)
|
30
|
+
end
|
31
|
+
|
32
|
+
def create(params={}, headers={})
|
33
|
+
method = ApiMethod.new(:post, "/sites", params, headers, @parent)
|
34
|
+
json = @client.execute(method)
|
35
|
+
Site.new(json, method)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Rainforest
|
2
|
+
class TestsEndpoint < ApiEndpoint
|
3
|
+
|
4
|
+
def new(id)
|
5
|
+
Test.new({:id => id}, nil, @client)
|
6
|
+
end
|
7
|
+
|
8
|
+
def all(params={}, headers={})
|
9
|
+
method = ApiMethod.new(:get, "/tests", params, headers, @parent)
|
10
|
+
json = @client.execute(method)
|
11
|
+
ApiList.new(:Test, json, method)
|
12
|
+
end
|
13
|
+
|
14
|
+
def retrieve(test_id, params={}, headers={})
|
15
|
+
params = ParamsBuilder.merge({
|
16
|
+
:test_id => test_id,
|
17
|
+
}, params)
|
18
|
+
method = ApiMethod.new(:get, "/tests/:test_id", params, headers, @parent)
|
19
|
+
json = @client.execute(method)
|
20
|
+
Test.new(json, method)
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete(test_id, params={}, headers={})
|
24
|
+
params = ParamsBuilder.merge({
|
25
|
+
:test_id => test_id,
|
26
|
+
}, params)
|
27
|
+
method = ApiMethod.new(:delete, "/tests/:test_id", params, headers, @parent)
|
28
|
+
json = @client.execute(method)
|
29
|
+
Test.new(json, method)
|
30
|
+
end
|
31
|
+
|
32
|
+
def update(test_id, params={}, headers={})
|
33
|
+
params = ParamsBuilder.merge({
|
34
|
+
:test_id => test_id,
|
35
|
+
}, params)
|
36
|
+
method = ApiMethod.new(:put, "/tests/:test_id", params, headers, @parent)
|
37
|
+
json = @client.execute(method)
|
38
|
+
Test.new(json, method)
|
39
|
+
end
|
40
|
+
|
41
|
+
def create(params={}, headers={})
|
42
|
+
method = ApiMethod.new(:post, "/tests", params, headers, @parent)
|
43
|
+
json = @client.execute(method)
|
44
|
+
Test.new(json, method)
|
45
|
+
end
|
46
|
+
|
47
|
+
def history(test_id, params={}, headers={})
|
48
|
+
params = ParamsBuilder.merge({
|
49
|
+
:test_id => test_id,
|
50
|
+
}, params)
|
51
|
+
method = ApiMethod.new(:get, "/tests/:test_id/history", params, headers, @parent)
|
52
|
+
json = @client.execute(method)
|
53
|
+
ApiList.new(:Run, json, method)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Rainforest
|
2
|
+
class UsersEndpoint < ApiEndpoint
|
3
|
+
|
4
|
+
def new(id)
|
5
|
+
User.new({:id => id}, nil, @client)
|
6
|
+
end
|
7
|
+
|
8
|
+
def all(params={}, headers={})
|
9
|
+
method = ApiMethod.new(:get, "/users", params, headers, @parent)
|
10
|
+
json = @client.execute(method)
|
11
|
+
ApiList.new(:User, json, method)
|
12
|
+
end
|
13
|
+
|
14
|
+
def retrieve(user_id, params={}, headers={})
|
15
|
+
params = ParamsBuilder.merge({
|
16
|
+
:user_id => user_id,
|
17
|
+
}, params)
|
18
|
+
method = ApiMethod.new(:get, "/users/:user_id", params, headers, @parent)
|
19
|
+
json = @client.execute(method)
|
20
|
+
User.new(json, method)
|
21
|
+
end
|
22
|
+
|
23
|
+
def update(user_id, params={}, headers={})
|
24
|
+
params = ParamsBuilder.merge({
|
25
|
+
:user_id => user_id,
|
26
|
+
}, params)
|
27
|
+
method = ApiMethod.new(:put, "/users/:user_id", params, headers, @parent)
|
28
|
+
json = @client.execute(method)
|
29
|
+
User.new(json, method)
|
30
|
+
end
|
31
|
+
|
32
|
+
def create(params={}, headers={})
|
33
|
+
method = ApiMethod.new(:post, "/users", params, headers, @parent)
|
34
|
+
json = @client.execute(method)
|
35
|
+
User.new(json, method)
|
36
|
+
end
|
37
|
+
|
38
|
+
def reset_password(email, params={}, headers={})
|
39
|
+
params = ParamsBuilder.merge({
|
40
|
+
:email => email,
|
41
|
+
}, params)
|
42
|
+
method = ApiMethod.new(:post, "/users/reset_password", params, headers, @parent)
|
43
|
+
json = @client.execute(method)
|
44
|
+
json
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -1,4 +1,35 @@
|
|
1
1
|
module Rainforest
|
2
|
-
class
|
2
|
+
class ApiError < RainforestError
|
3
|
+
attr_reader :api_method
|
4
|
+
|
5
|
+
def initialize(message=nil, api_method=nil)
|
6
|
+
@message = message
|
7
|
+
@api_method = api_method
|
8
|
+
end
|
9
|
+
|
10
|
+
def code
|
11
|
+
@api_method.response_code if @api_method
|
12
|
+
end
|
13
|
+
|
14
|
+
def body
|
15
|
+
@api_method.response_body if @api_method
|
16
|
+
end
|
17
|
+
|
18
|
+
def json
|
19
|
+
begin
|
20
|
+
if @api_method
|
21
|
+
hash = @api_method.response_json
|
22
|
+
return ApiObject.construct(hash)
|
23
|
+
end
|
24
|
+
rescue ApiError
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
prefix = code.nil? ? "" : "(Status #{code}) "
|
31
|
+
"#{prefix}#{@message}"
|
32
|
+
end
|
3
33
|
end
|
4
34
|
end
|
35
|
+
|
@@ -1,20 +1,13 @@
|
|
1
1
|
module Rainforest
|
2
2
|
class RainforestError < StandardError
|
3
3
|
attr_reader :message
|
4
|
-
attr_reader :http_status
|
5
|
-
attr_reader :http_body
|
6
|
-
attr_reader :json_body
|
7
4
|
|
8
|
-
def initialize(message=nil
|
5
|
+
def initialize(message=nil)
|
9
6
|
@message = message
|
10
|
-
@http_status = http_status
|
11
|
-
@http_body = http_body
|
12
|
-
@json_body = json_body
|
13
7
|
end
|
14
8
|
|
15
9
|
def to_s
|
16
|
-
|
17
|
-
"#{status_string}#{@message}"
|
10
|
+
"#{@message}"
|
18
11
|
end
|
19
12
|
end
|
20
13
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Rainforest
|
2
|
+
class ClientStats < ApiResource
|
3
|
+
attr_accessor :has_runs
|
4
|
+
attr_accessor :has_schedules
|
5
|
+
attr_accessor :has_step_variables
|
6
|
+
attr_accessor :has_steps
|
7
|
+
attr_accessor :has_test_steps
|
8
|
+
attr_accessor :has_tests
|
9
|
+
|
10
|
+
def self.retrieve(params={}, headers={})
|
11
|
+
res = client.client_stats.retrieve(params, headers)
|
12
|
+
res
|
13
|
+
end
|
14
|
+
|
15
|
+
def refresh(params={}, headers={})
|
16
|
+
res = client.client_stats.retrieve(params, headers)
|
17
|
+
self.refresh_from(res.json, res.api_method, res.client)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Everything below here is used behind the scenes.
|
21
|
+
ApiResource.register_api_subclass(self, "client_stats")
|
22
|
+
@api_attributes = {
|
23
|
+
:has_runs => {},
|
24
|
+
:has_schedules => {},
|
25
|
+
:has_step_variables => {},
|
26
|
+
:has_steps => {},
|
27
|
+
:has_test_steps => {},
|
28
|
+
:has_tests => {},
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Rainforest
|
2
|
+
class Environment < ApiResource
|
3
|
+
attr_accessor :created_at
|
4
|
+
attr_accessor :default
|
5
|
+
attr_accessor :id
|
6
|
+
attr_accessor :name
|
7
|
+
attr_accessor :site_environments
|
8
|
+
attr_accessor :webhook
|
9
|
+
attr_accessor :webhook_enabled
|
10
|
+
|
11
|
+
def self.all(params={}, headers={})
|
12
|
+
res = client.environments.all(params, headers)
|
13
|
+
res
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.retrieve(environment_id, params={}, headers={})
|
17
|
+
res = client.environments.retrieve(environment_id, params, headers)
|
18
|
+
res
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.update(environment_id, params={}, headers={})
|
22
|
+
res = client.environments.update(environment_id, params, headers)
|
23
|
+
res
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.delete(environment_id, params={}, headers={})
|
27
|
+
res = client.environments.delete(environment_id, params, headers)
|
28
|
+
res
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.create(params={}, headers={})
|
32
|
+
res = client.environments.create(params, headers)
|
33
|
+
res
|
34
|
+
end
|
35
|
+
|
36
|
+
def refresh(params={}, headers={})
|
37
|
+
res = client.environments.retrieve(id, params, headers)
|
38
|
+
self.refresh_from(res.json, res.api_method, res.client)
|
39
|
+
end
|
40
|
+
|
41
|
+
def update(params={}, headers={})
|
42
|
+
res = client.environments.update(id, params, headers)
|
43
|
+
self.refresh_from(res.json, res.api_method, res.client)
|
44
|
+
end
|
45
|
+
|
46
|
+
def save(params={}, headers={})
|
47
|
+
params = ParamsBuilder.merge(api_attributes, params)
|
48
|
+
res = client.environments.update(id, params, headers)
|
49
|
+
self.refresh_from(res.json, res.api_method, res.client)
|
50
|
+
end
|
51
|
+
|
52
|
+
def delete(params={}, headers={})
|
53
|
+
res = client.environments.delete(id, params, headers)
|
54
|
+
res
|
55
|
+
end
|
56
|
+
|
57
|
+
def runs()
|
58
|
+
EnvironmentRunsEndpoint.new(client, self)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Everything below here is used behind the scenes.
|
62
|
+
ApiResource.register_api_subclass(self, "environment")
|
63
|
+
@api_attributes = {
|
64
|
+
:created_at => {},
|
65
|
+
:default => { :editable => true },
|
66
|
+
:id => {},
|
67
|
+
:name => { :editable => true },
|
68
|
+
:site_environments => { :editable => true },
|
69
|
+
:webhook => { :editable => true },
|
70
|
+
:webhook_enabled => { :editable => true },
|
71
|
+
}
|
72
|
+
end
|
73
|
+
end
|