discourse_api 0.3.0 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +5 -13
  2. data/CHANGELOG.md +16 -2
  3. data/README.md +2 -0
  4. data/examples/category.rb +12 -0
  5. data/lib/discourse_api/api/api_admin.rb +10 -0
  6. data/lib/discourse_api/api/backups.rb +10 -0
  7. data/lib/discourse_api/api/badges.rb +15 -0
  8. data/lib/discourse_api/api/categories.rb +13 -7
  9. data/lib/discourse_api/api/email.rb +15 -0
  10. data/lib/discourse_api/api/groups.rb +5 -6
  11. data/lib/discourse_api/api/params.rb +1 -1
  12. data/lib/discourse_api/api/posts.rb +15 -1
  13. data/lib/discourse_api/api/topics.rb +8 -8
  14. data/lib/discourse_api/api/users.rb +20 -14
  15. data/lib/discourse_api/client.rb +17 -5
  16. data/lib/discourse_api/version.rb +1 -1
  17. data/spec/discourse_api/api/api_admin_spec.rb +23 -0
  18. data/spec/discourse_api/api/backups_spec.rb +23 -0
  19. data/spec/discourse_api/api/badges_spec.rb +40 -0
  20. data/spec/discourse_api/api/categories_spec.rb +6 -0
  21. data/spec/discourse_api/api/email_spec.rb +39 -0
  22. data/spec/discourse_api/api/params_spec.rb +20 -0
  23. data/spec/discourse_api/api/posts_spec.rb +29 -0
  24. data/spec/discourse_api/api/topics_spec.rb +6 -0
  25. data/spec/discourse_api/api/users_spec.rb +78 -8
  26. data/spec/fixtures/api.json +12 -0
  27. data/spec/fixtures/backups.json +12 -0
  28. data/spec/fixtures/badges.json +569 -0
  29. data/spec/fixtures/email_list_all.json +749 -0
  30. data/spec/fixtures/email_settings.json +13 -0
  31. data/spec/fixtures/post.json +94 -0
  32. data/spec/fixtures/user_activate_success.json +3 -0
  33. data/spec/fixtures/user_badges.json +170 -0
  34. data/spec/fixtures/user_list.json +583 -0
  35. data/spec/fixtures/user_log_out_success.json +3 -0
  36. data/spec/fixtures/user_update_avatar_success.json +3 -0
  37. data/spec/fixtures/user_update_username.json +2 -1
  38. metadata +66 -28
@@ -18,6 +18,12 @@ describe DiscourseApi::API::Categories do
18
18
  expect(categories).to be_an Array
19
19
  expect(categories.first).to be_a Hash
20
20
  end
21
+
22
+ it "returns the requested categories with hash arg" do
23
+ categories = subject.categories({})
24
+ expect(categories).to be_an Array
25
+ expect(categories.first).to be_a Hash
26
+ end
21
27
  end
22
28
 
23
29
  describe '#category_latest_topics' do
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe DiscourseApi::API::Email do
4
+ subject { DiscourseApi::Client.new("http://localhost:3000", "test_d7fd0429940", "test_user" )}
5
+
6
+ describe "#email_settings" do
7
+ before do
8
+ stub_get("http://localhost:3000/admin/email.json?api_key=test_d7fd0429940&api_username=test_user").to_return(body: fixture("email_settings.json"), headers: { content_type: "application/json" })
9
+ end
10
+
11
+ it "requests the correct resource" do
12
+ subject.email_settings
13
+ expect(a_get("http://localhost:3000/admin/email.json?api_key=test_d7fd0429940&api_username=test_user")).to have_been_made
14
+ end
15
+
16
+ it "returns the requested settings" do
17
+ settings = subject.email_settings
18
+ expect(settings).to be_a Hash
19
+ expect(settings).to have_key('delivery_method')
20
+ expect(settings).to have_key('settings')
21
+ end
22
+ end
23
+
24
+ describe "#list_email_all" do
25
+ before do
26
+ stub_get("http://localhost:3000/admin/email/all.json?api_key=test_d7fd0429940&api_username=test_user").to_return(body: fixture("email_list_all.json"), headers: { content_type: "application/json" })
27
+ end
28
+
29
+ it "requests the correct resource" do
30
+ subject.list_email('all')
31
+ expect(a_get("http://localhost:3000/admin/email/all.json?api_key=test_d7fd0429940&api_username=test_user")).to have_been_made
32
+ end
33
+
34
+ it "returns all email" do
35
+ all_email = subject.list_email('all')
36
+ expect(all_email).to be_an Array
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe DiscourseApi::API::Params do
4
+ def params_for(h)
5
+ DiscourseApi::API::Params.new(h).required(:r1).optional(:o1, :o2)
6
+ end
7
+
8
+ it "should raise on missing required params" do
9
+ expect { params_for({o1: "test"}).to_h }.to raise_error(ArgumentError)
10
+ end
11
+
12
+ it "should not include optional params when not provided" do
13
+ expect(params_for({r1: "test"}).to_h).not_to include(:o1)
14
+ end
15
+
16
+ it "should include optional params if provided but blank" do
17
+ expect(params_for({r1: "test", o2: nil}).to_h).to include(:o2)
18
+ end
19
+
20
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe DiscourseApi::API::Posts do
4
+ let (:client) { DiscourseApi::Client.new("http://localhost:3000", "test_d7fd0429940", "test_user") }
5
+
6
+ describe "#get_post" do
7
+ before do
8
+ stub_get("http://localhost:3000/posts/11.json?api_key=test_d7fd0429940&api_username=test_user").to_return(body: fixture("post.json"), headers: { content_type: "application/json" })
9
+ end
10
+
11
+ it "fetches a post" do
12
+ the_post = client.get_post(11)
13
+ expect(the_post).to be_a Hash
14
+ expect(the_post['id']).to eq(11)
15
+ end
16
+ end
17
+
18
+ describe "#wikify_post" do
19
+ before do
20
+ stub_put("http://localhost:3000/posts/9999/wiki?api_key=test_d7fd0429940&api_username=test_user")
21
+ end
22
+
23
+ it "fails on unknown post" do
24
+ client.wikify_post(9999)
25
+ expect(a_put("http://localhost:3000/posts/9999/wiki?api_key=test_d7fd0429940&api_username=test_user")).to have_been_made
26
+ end
27
+ end
28
+
29
+ end
@@ -35,6 +35,12 @@ describe DiscourseApi::API::Topics do
35
35
  expect(topics).to be_an Array
36
36
  expect(topics.first).to be_a Hash
37
37
  end
38
+
39
+ it "can take a hash param" do
40
+ topics = subject.latest_topics({})
41
+ expect(topics).to be_an Array
42
+ expect(topics.first).to be_a Hash
43
+ end
38
44
  end
39
45
 
40
46
  describe "#new_topics" do
@@ -17,10 +17,25 @@ describe DiscourseApi::API::Users do
17
17
  user = subject.user("test")
18
18
  expect(user).to be_a Hash
19
19
  end
20
+
21
+ it "works with optional params" do
22
+ user = subject.user("test", {})
23
+ expect(user).to be_a Hash
24
+ end
20
25
  end
21
26
 
22
27
  describe "#update_avatar" do
23
- it "needs to have a test written for it"
28
+ before do
29
+ stub_post("http://localhost:3000/users/test_user/preferences/user_image?api_key=test_d7fd0429940&api_username=test_user").to_return(body: fixture("user_update_avatar_success.json"), headers: { content_type: "application/json" })
30
+ stub_put("http://localhost:3000/users/test_user/preferences/avatar/pick?api_key=test_d7fd0429940&api_username=test_user").to_return(body: fixture("user_update_avatar_success.json"), headers: { content_type: "application/json" })
31
+ end
32
+
33
+ it "uploads an image" do
34
+ sam = "https://meta-discourse.global.ssl.fastly.net/user_avatar/meta.discourse.org/sam/120/5243.png"
35
+ args = { username: 'test_user', file: sam }
36
+ response = subject.update_avatar(args)
37
+ expect(response[:body]['success']).to eq('OK')
38
+ end
24
39
  end
25
40
 
26
41
  describe "#update_email" do
@@ -65,24 +80,19 @@ describe DiscourseApi::API::Users do
65
80
  end
66
81
 
67
82
  it "makes the put request" do
68
- subject.api_key = 'test_d7fd0429940'
69
- subject.api_username = 'test_user'
70
83
  subject.update_username("fake_user", "fake_user_2")
71
84
  expect(a_put("http://localhost:3000/users/fake_user/preferences/username?api_key=test_d7fd0429940&api_username=test_user")).to have_been_made
72
85
  end
73
86
 
74
- it "returns success" do
75
- subject.api_key = 'test_d7fd0429940'
76
- subject.api_username = 'test_user'
87
+ it "returns the updated username" do
77
88
  response = subject.update_username("fake_user", "fake_user_2")
78
- expect(response[:body]['success']).to be_truthy
89
+ expect(response[:body]['username']).to eq('fake_user_2')
79
90
  end
80
91
  end
81
92
 
82
93
  describe "#create_user" do
83
94
  before do
84
95
  stub_post("http://localhost:3000/users?api_key=test_d7fd0429940&api_username=test_user").to_return(body: fixture("user_create_success.json"), headers: { content_type: "application/json" })
85
- stub_get("http://localhost:3000/users/hp.json?api_key=test_d7fd0429940&api_username=test_user").to_return(body: {"value"=>"foo", "challenge"=>"bar"}.to_json, headers: { content_type: "application/json" })
86
96
  end
87
97
 
88
98
  it "makes the post request" do
@@ -96,4 +106,64 @@ describe DiscourseApi::API::Users do
96
106
  expect(response['success']).to be_truthy
97
107
  end
98
108
  end
109
+
110
+ describe "#activate_user" do
111
+ before do
112
+ stub_put("http://localhost:3000/admin/users/15/activate?api_key=test_d7fd0429940&api_username=test_user").to_return(body: fixture("user_activate_success.json"), headers: { content_type: "application/json" })
113
+ end
114
+
115
+ it "makes the put request" do
116
+ subject.activate(15)
117
+ expect(a_put("http://localhost:3000/admin/users/15/activate?api_key=test_d7fd0429940&api_username=test_user")).to have_been_made
118
+ end
119
+
120
+ it "returns success" do
121
+ response = subject.activate(15)
122
+ expect(response[:body]['success']).to eq('OK')
123
+ end
124
+ end
125
+
126
+ describe "#log_out_success" do
127
+ before do
128
+ stub_post("http://localhost:3000/admin/users/4/log_out?api_key=test_d7fd0429940&api_username=test_user").to_return(body: fixture("user_log_out_success.json"), headers: { content_type: "application/json" })
129
+ end
130
+
131
+ it "makes a post request" do
132
+ subject.log_out(4)
133
+ expect(a_post("http://localhost:3000/admin/users/4/log_out?api_key=test_d7fd0429940&api_username=test_user")).to have_been_made
134
+ end
135
+
136
+ it "returns success" do
137
+ response = subject.log_out(4)
138
+ expect(response).to be_a Hash
139
+ expect(response['success']).to eq('OK')
140
+ end
141
+ end
142
+
143
+ describe "#log_out_unsuccessful" do
144
+ before do
145
+ stub_post("http://localhost:3000/admin/users/90/log_out?api_key=test_d7fd0429940&api_username=test_user").to_return(status: 404, headers: { content_type: "application/json" })
146
+ end
147
+
148
+ it "Raises API Error" do
149
+ expect{subject.log_out(90)}.to raise_error DiscourseApi::Error
150
+ end
151
+ end
152
+
153
+ describe "#list_users" do
154
+ before do
155
+ stub_get("http://localhost:3000/admin/users/list/active.json?api_key=test_d7fd0429940&api_username=test_user").to_return(body: fixture("user_list.json"), headers: { content_type: "application/json" })
156
+ end
157
+
158
+ it "requests the correct resource" do
159
+ subject.list_users('active')
160
+ expect(a_get("http://localhost:3000/admin/users/list/active.json?api_key=test_d7fd0429940&api_username=test_user")).to have_been_made
161
+ end
162
+
163
+ it "returns the requested users" do
164
+ users = subject.list_users('active')
165
+ expect(users).to be_an Array
166
+ expect(users.first).to be_a Hash
167
+ end
168
+ end
99
169
  end
@@ -0,0 +1,12 @@
1
+ [
2
+ {
3
+ "id": 1,
4
+ "key": "test_d7fd0429940",
5
+ "user": {
6
+ "id": 1,
7
+ "username": "test_user",
8
+ "uploaded_avatar_id": 7,
9
+ "avatar_template": "/user_avatar/localhost/test_user/{size}/7.png"
10
+ }
11
+ }
12
+ ]
@@ -0,0 +1,12 @@
1
+ [
2
+ {
3
+ "filename": "discourse-2015-01-10-065015.tar.gz",
4
+ "size": 557075,
5
+ "link": "//localhost:3000/admin/backups/discourse-2015-01-10-065015.tar.gz"
6
+ },
7
+ {
8
+ "filename": "2014-02-10-065935.tar.gz",
9
+ "size": 5,
10
+ "link": "//localhost:3000/admin/backups/2014-02-10-065935.tar.gz"
11
+ }
12
+ ]
@@ -0,0 +1,569 @@
1
+ {
2
+ "badges": [
3
+ {
4
+ "id": 9,
5
+ "name": "Autobiographer",
6
+ "description": null,
7
+ "grant_count": 0,
8
+ "allow_title": false,
9
+ "multiple_grant": false,
10
+ "icon": "fa-certificate",
11
+ "image": null,
12
+ "listable": true,
13
+ "enabled": true,
14
+ "badge_grouping_id": 1,
15
+ "system": true,
16
+ "query": " SELECT u.id user_id, current_timestamp granted_at\n FROM users u\n JOIN user_profiles up on u.id = up.user_id\n WHERE bio_raw IS NOT NULL AND LENGTH(TRIM(bio_raw)) > 10 AND\n uploaded_avatar_id IS NOT NULL AND\n (:backfill OR u.id IN (:user_ids) )\n",
17
+ "trigger": 8,
18
+ "target_posts": false,
19
+ "auto_revoke": true,
20
+ "show_posts": false,
21
+ "badge_type_id": 3
22
+ },
23
+ {
24
+ "id": 11,
25
+ "name": "First Like",
26
+ "description": null,
27
+ "grant_count": 1,
28
+ "allow_title": false,
29
+ "multiple_grant": false,
30
+ "icon": "fa-certificate",
31
+ "image": null,
32
+ "listable": true,
33
+ "enabled": true,
34
+ "badge_grouping_id": 1,
35
+ "system": true,
36
+ "query": " SELECT pa1.user_id, pa1.created_at granted_at, pa1.post_id\n FROM (\n SELECT pa.user_id, min(pa.id) id\n FROM post_actions pa\n JOIN badge_posts p on p.id = pa.post_id\n WHERE post_action_type_id = 2 AND\n (:backfill OR pa.post_id IN (:post_ids) )\n GROUP BY pa.user_id\n ) x\n JOIN post_actions pa1 on pa1.id = x.id\n",
37
+ "trigger": 1,
38
+ "target_posts": true,
39
+ "auto_revoke": true,
40
+ "show_posts": true,
41
+ "badge_type_id": 3
42
+ },
43
+ {
44
+ "id": 14,
45
+ "name": "First Link",
46
+ "description": null,
47
+ "grant_count": 0,
48
+ "allow_title": false,
49
+ "multiple_grant": false,
50
+ "icon": "fa-certificate",
51
+ "image": null,
52
+ "listable": true,
53
+ "enabled": true,
54
+ "badge_grouping_id": 1,
55
+ "system": true,
56
+ "query": " SELECT l.user_id, l.post_id, l.created_at granted_at\n FROM\n (\n SELECT MIN(l1.id) id\n FROM topic_links l1\n JOIN badge_posts p1 ON p1.id = l1.post_id\n JOIN badge_posts p2 ON p2.id = l1.link_post_id\n WHERE NOT reflection AND p1.topic_id <> p2.topic_id AND not quote AND\n (:backfill OR ( p1.id in (:post_ids) ))\n GROUP BY l1.user_id\n ) ids\n JOIN topic_links l ON l.id = ids.id\n",
57
+ "trigger": 2,
58
+ "target_posts": true,
59
+ "auto_revoke": true,
60
+ "show_posts": true,
61
+ "badge_type_id": 3
62
+ },
63
+ {
64
+ "id": 15,
65
+ "name": "First Quote",
66
+ "description": null,
67
+ "grant_count": 0,
68
+ "allow_title": false,
69
+ "multiple_grant": false,
70
+ "icon": "fa-certificate",
71
+ "image": null,
72
+ "listable": true,
73
+ "enabled": true,
74
+ "badge_grouping_id": 1,
75
+ "system": true,
76
+ "query": " SELECT ids.user_id, q.post_id, q.created_at granted_at\n FROM\n (\n SELECT p1.user_id, MIN(q1.id) id\n FROM quoted_posts q1\n JOIN badge_posts p1 ON p1.id = q1.post_id\n JOIN badge_posts p2 ON p2.id = q1.quoted_post_id\n WHERE (:backfill OR ( p1.id IN (:post_ids) ))\n GROUP BY p1.user_id\n ) ids\n JOIN quoted_posts q ON q.id = ids.id\n",
77
+ "trigger": 2,
78
+ "target_posts": true,
79
+ "auto_revoke": true,
80
+ "show_posts": true,
81
+ "badge_type_id": 3
82
+ },
83
+ {
84
+ "id": 12,
85
+ "name": "First Share",
86
+ "description": null,
87
+ "grant_count": 0,
88
+ "allow_title": false,
89
+ "multiple_grant": false,
90
+ "icon": "fa-certificate",
91
+ "image": null,
92
+ "listable": true,
93
+ "enabled": true,
94
+ "badge_grouping_id": 1,
95
+ "system": true,
96
+ "query": " SELECT views.user_id, i2.post_id, i2.created_at granted_at\n FROM\n (\n SELECT i.user_id, MIN(i.id) i_id\n FROM incoming_links i\n JOIN badge_posts p on p.id = i.post_id\n WHERE i.user_id IS NOT NULL\n GROUP BY i.user_id\n ) as views\n JOIN incoming_links i2 ON i2.id = views.i_id\n",
97
+ "trigger": 0,
98
+ "target_posts": true,
99
+ "auto_revoke": true,
100
+ "show_posts": true,
101
+ "badge_type_id": 3
102
+ },
103
+ {
104
+ "id": 16,
105
+ "name": "Read Guidelines",
106
+ "description": null,
107
+ "grant_count": 0,
108
+ "allow_title": false,
109
+ "multiple_grant": false,
110
+ "icon": "fa-certificate",
111
+ "image": null,
112
+ "listable": true,
113
+ "enabled": true,
114
+ "badge_grouping_id": 1,
115
+ "system": true,
116
+ "query": " SELECT user_id, read_faq granted_at\n FROM user_stats\n WHERE read_faq IS NOT NULL AND (user_id IN (:user_ids) OR :backfill)\n",
117
+ "trigger": 8,
118
+ "target_posts": false,
119
+ "auto_revoke": true,
120
+ "show_posts": false,
121
+ "badge_type_id": 3
122
+ },
123
+ {
124
+ "id": 17,
125
+ "name": "Reader",
126
+ "description": null,
127
+ "grant_count": 0,
128
+ "allow_title": false,
129
+ "multiple_grant": false,
130
+ "icon": "fa-certificate",
131
+ "image": null,
132
+ "listable": true,
133
+ "enabled": true,
134
+ "badge_grouping_id": 1,
135
+ "system": true,
136
+ "query": " SELECT id user_id, current_timestamp granted_at\n FROM users\n WHERE id IN\n (\n SELECT pt.user_id\n FROM post_timings pt\n JOIN badge_posts b ON b.post_number = pt.post_number AND\n b.topic_id = pt.topic_id\n JOIN topics t ON t.id = pt.topic_id\n LEFT JOIN user_badges ub ON ub.badge_id = 17 AND ub.user_id = pt.user_id\n WHERE ub.id IS NULL AND t.posts_count > 100\n GROUP BY pt.user_id, pt.topic_id, t.posts_count\n HAVING count(*) >= t.posts_count\n )\n",
137
+ "trigger": null,
138
+ "target_posts": false,
139
+ "auto_revoke": false,
140
+ "show_posts": false,
141
+ "badge_type_id": 3
142
+ },
143
+ {
144
+ "id": 23,
145
+ "name": "Great Share",
146
+ "description": null,
147
+ "grant_count": 0,
148
+ "allow_title": false,
149
+ "multiple_grant": true,
150
+ "icon": "fa-certificate",
151
+ "image": null,
152
+ "listable": true,
153
+ "enabled": true,
154
+ "badge_grouping_id": 2,
155
+ "system": true,
156
+ "query": " SELECT views.user_id, i2.post_id, i2.created_at granted_at\n FROM\n (\n SELECT i.user_id, MIN(i.id) i_id\n FROM incoming_links i\n JOIN badge_posts p on p.id = i.post_id\n WHERE i.user_id IS NOT NULL\n GROUP BY i.user_id,i.post_id\n HAVING COUNT(*) > 1000\n ) as views\n JOIN incoming_links i2 ON i2.id = views.i_id\n",
157
+ "trigger": 0,
158
+ "target_posts": true,
159
+ "auto_revoke": true,
160
+ "show_posts": true,
161
+ "badge_type_id": 1
162
+ },
163
+ {
164
+ "id": 22,
165
+ "name": "Good Share",
166
+ "description": null,
167
+ "grant_count": 0,
168
+ "allow_title": false,
169
+ "multiple_grant": true,
170
+ "icon": "fa-certificate",
171
+ "image": null,
172
+ "listable": true,
173
+ "enabled": true,
174
+ "badge_grouping_id": 2,
175
+ "system": true,
176
+ "query": " SELECT views.user_id, i2.post_id, i2.created_at granted_at\n FROM\n (\n SELECT i.user_id, MIN(i.id) i_id\n FROM incoming_links i\n JOIN badge_posts p on p.id = i.post_id\n WHERE i.user_id IS NOT NULL\n GROUP BY i.user_id,i.post_id\n HAVING COUNT(*) > 300\n ) as views\n JOIN incoming_links i2 ON i2.id = views.i_id\n",
177
+ "trigger": 0,
178
+ "target_posts": true,
179
+ "auto_revoke": true,
180
+ "show_posts": true,
181
+ "badge_type_id": 2
182
+ },
183
+ {
184
+ "id": 10,
185
+ "name": "Editor",
186
+ "description": null,
187
+ "grant_count": 1,
188
+ "allow_title": false,
189
+ "multiple_grant": false,
190
+ "icon": "fa-certificate",
191
+ "image": null,
192
+ "listable": true,
193
+ "enabled": true,
194
+ "badge_grouping_id": 2,
195
+ "system": true,
196
+ "query": " SELECT p.user_id, min(p.id) post_id, min(p.created_at) granted_at\n FROM badge_posts p\n WHERE p.self_edits > 0 AND\n (:backfill OR p.id IN (:post_ids) )\n GROUP BY p.user_id\n",
197
+ "trigger": 2,
198
+ "target_posts": false,
199
+ "auto_revoke": true,
200
+ "show_posts": false,
201
+ "badge_type_id": 3
202
+ },
203
+ {
204
+ "id": 13,
205
+ "name": "First Flag",
206
+ "description": null,
207
+ "grant_count": 0,
208
+ "allow_title": false,
209
+ "multiple_grant": false,
210
+ "icon": "fa-certificate",
211
+ "image": null,
212
+ "listable": true,
213
+ "enabled": true,
214
+ "badge_grouping_id": 2,
215
+ "system": true,
216
+ "query": " SELECT pa1.user_id, pa1.created_at granted_at, pa1.post_id\n FROM (\n SELECT pa.user_id, min(pa.id) id\n FROM post_actions pa\n JOIN badge_posts p on p.id = pa.post_id\n WHERE post_action_type_id IN (3,4,7,8) AND\n (:backfill OR pa.post_id IN (:post_ids) )\n GROUP BY pa.user_id\n ) x\n JOIN post_actions pa1 on pa1.id = x.id\n",
217
+ "trigger": 1,
218
+ "target_posts": true,
219
+ "auto_revoke": false,
220
+ "show_posts": false,
221
+ "badge_type_id": 3
222
+ },
223
+ {
224
+ "id": 21,
225
+ "name": "Nice Share",
226
+ "description": null,
227
+ "grant_count": 0,
228
+ "allow_title": false,
229
+ "multiple_grant": true,
230
+ "icon": "fa-certificate",
231
+ "image": null,
232
+ "listable": true,
233
+ "enabled": true,
234
+ "badge_grouping_id": 2,
235
+ "system": true,
236
+ "query": " SELECT views.user_id, i2.post_id, i2.created_at granted_at\n FROM\n (\n SELECT i.user_id, MIN(i.id) i_id\n FROM incoming_links i\n JOIN badge_posts p on p.id = i.post_id\n WHERE i.user_id IS NOT NULL\n GROUP BY i.user_id,i.post_id\n HAVING COUNT(*) > 25\n ) as views\n JOIN incoming_links i2 ON i2.id = views.i_id\n",
237
+ "trigger": 0,
238
+ "target_posts": true,
239
+ "auto_revoke": true,
240
+ "show_posts": true,
241
+ "badge_type_id": 3
242
+ },
243
+ {
244
+ "id": 5,
245
+ "name": "Welcome",
246
+ "description": null,
247
+ "grant_count": 1,
248
+ "allow_title": false,
249
+ "multiple_grant": false,
250
+ "icon": "fa-certificate",
251
+ "image": null,
252
+ "listable": true,
253
+ "enabled": true,
254
+ "badge_grouping_id": 2,
255
+ "system": true,
256
+ "query": " SELECT p.user_id, min(post_id) post_id, min(pa.created_at) granted_at\n FROM post_actions pa\n JOIN badge_posts p on p.id = pa.post_id\n WHERE post_action_type_id = 2 AND\n (:backfill OR pa.post_id IN (:post_ids) )\n GROUP BY p.user_id\n",
257
+ "trigger": 1,
258
+ "target_posts": true,
259
+ "auto_revoke": true,
260
+ "show_posts": true,
261
+ "badge_type_id": 3
262
+ },
263
+ {
264
+ "id": 8,
265
+ "name": "Great Post",
266
+ "description": null,
267
+ "grant_count": 0,
268
+ "allow_title": false,
269
+ "multiple_grant": true,
270
+ "icon": "fa-certificate",
271
+ "image": null,
272
+ "listable": true,
273
+ "enabled": true,
274
+ "badge_grouping_id": 3,
275
+ "system": true,
276
+ "query": "\n SELECT p.user_id, p.id post_id, p.updated_at granted_at\n FROM badge_posts p\n WHERE p.post_number > 1 AND p.like_count >= 50 AND\n (:backfill OR p.id IN (:post_ids) )\n",
277
+ "trigger": 1,
278
+ "target_posts": true,
279
+ "auto_revoke": true,
280
+ "show_posts": true,
281
+ "badge_type_id": 1
282
+ },
283
+ {
284
+ "id": 20,
285
+ "name": "Great Topic",
286
+ "description": null,
287
+ "grant_count": 0,
288
+ "allow_title": false,
289
+ "multiple_grant": true,
290
+ "icon": "fa-certificate",
291
+ "image": null,
292
+ "listable": true,
293
+ "enabled": true,
294
+ "badge_grouping_id": 3,
295
+ "system": true,
296
+ "query": "\n SELECT p.user_id, p.id post_id, p.updated_at granted_at\n FROM badge_posts p\n WHERE p.post_number = 1 AND p.like_count >= 50 AND\n (:backfill OR p.id IN (:post_ids) )\n",
297
+ "trigger": 1,
298
+ "target_posts": true,
299
+ "auto_revoke": true,
300
+ "show_posts": true,
301
+ "badge_type_id": 1
302
+ },
303
+ {
304
+ "id": 7,
305
+ "name": "Good Post",
306
+ "description": null,
307
+ "grant_count": 0,
308
+ "allow_title": false,
309
+ "multiple_grant": true,
310
+ "icon": "fa-certificate",
311
+ "image": null,
312
+ "listable": true,
313
+ "enabled": true,
314
+ "badge_grouping_id": 3,
315
+ "system": true,
316
+ "query": "\n SELECT p.user_id, p.id post_id, p.updated_at granted_at\n FROM badge_posts p\n WHERE p.post_number > 1 AND p.like_count >= 25 AND\n (:backfill OR p.id IN (:post_ids) )\n",
317
+ "trigger": 1,
318
+ "target_posts": true,
319
+ "auto_revoke": true,
320
+ "show_posts": true,
321
+ "badge_type_id": 2
322
+ },
323
+ {
324
+ "id": 19,
325
+ "name": "Good Topic",
326
+ "description": null,
327
+ "grant_count": 0,
328
+ "allow_title": false,
329
+ "multiple_grant": true,
330
+ "icon": "fa-certificate",
331
+ "image": null,
332
+ "listable": true,
333
+ "enabled": true,
334
+ "badge_grouping_id": 3,
335
+ "system": true,
336
+ "query": "\n SELECT p.user_id, p.id post_id, p.updated_at granted_at\n FROM badge_posts p\n WHERE p.post_number = 1 AND p.like_count >= 25 AND\n (:backfill OR p.id IN (:post_ids) )\n",
337
+ "trigger": 1,
338
+ "target_posts": true,
339
+ "auto_revoke": true,
340
+ "show_posts": true,
341
+ "badge_type_id": 2
342
+ },
343
+ {
344
+ "id": 6,
345
+ "name": "Nice Post",
346
+ "description": null,
347
+ "grant_count": 0,
348
+ "allow_title": false,
349
+ "multiple_grant": true,
350
+ "icon": "fa-certificate",
351
+ "image": null,
352
+ "listable": true,
353
+ "enabled": true,
354
+ "badge_grouping_id": 3,
355
+ "system": true,
356
+ "query": "\n SELECT p.user_id, p.id post_id, p.updated_at granted_at\n FROM badge_posts p\n WHERE p.post_number > 1 AND p.like_count >= 10 AND\n (:backfill OR p.id IN (:post_ids) )\n",
357
+ "trigger": 1,
358
+ "target_posts": true,
359
+ "auto_revoke": true,
360
+ "show_posts": true,
361
+ "badge_type_id": 3
362
+ },
363
+ {
364
+ "id": 18,
365
+ "name": "Nice Topic",
366
+ "description": null,
367
+ "grant_count": 0,
368
+ "allow_title": false,
369
+ "multiple_grant": true,
370
+ "icon": "fa-certificate",
371
+ "image": null,
372
+ "listable": true,
373
+ "enabled": true,
374
+ "badge_grouping_id": 3,
375
+ "system": true,
376
+ "query": "\n SELECT p.user_id, p.id post_id, p.updated_at granted_at\n FROM badge_posts p\n WHERE p.post_number = 1 AND p.like_count >= 10 AND\n (:backfill OR p.id IN (:post_ids) )\n",
377
+ "trigger": 1,
378
+ "target_posts": true,
379
+ "auto_revoke": true,
380
+ "show_posts": true,
381
+ "badge_type_id": 3
382
+ },
383
+ {
384
+ "id": 4,
385
+ "name": "Leader",
386
+ "description": null,
387
+ "grant_count": 0,
388
+ "allow_title": true,
389
+ "multiple_grant": false,
390
+ "icon": "fa-user",
391
+ "image": null,
392
+ "listable": true,
393
+ "enabled": true,
394
+ "badge_grouping_id": 4,
395
+ "system": true,
396
+ "query": "\n SELECT u.id user_id, current_timestamp granted_at FROM users u\n WHERE trust_level >= 4 AND (\n :backfill OR u.id IN (:user_ids)\n )\n",
397
+ "trigger": 4,
398
+ "target_posts": false,
399
+ "auto_revoke": true,
400
+ "show_posts": false,
401
+ "badge_type_id": 1
402
+ },
403
+ {
404
+ "id": 3,
405
+ "name": "Regular",
406
+ "description": null,
407
+ "grant_count": 0,
408
+ "allow_title": true,
409
+ "multiple_grant": false,
410
+ "icon": "fa-user",
411
+ "image": null,
412
+ "listable": true,
413
+ "enabled": true,
414
+ "badge_grouping_id": 4,
415
+ "system": true,
416
+ "query": "\n SELECT u.id user_id, current_timestamp granted_at FROM users u\n WHERE trust_level >= 3 AND (\n :backfill OR u.id IN (:user_ids)\n )\n",
417
+ "trigger": 4,
418
+ "target_posts": false,
419
+ "auto_revoke": true,
420
+ "show_posts": false,
421
+ "badge_type_id": 2
422
+ },
423
+ {
424
+ "id": 1,
425
+ "name": "Basic User",
426
+ "description": null,
427
+ "grant_count": 0,
428
+ "allow_title": false,
429
+ "multiple_grant": false,
430
+ "icon": "fa-user",
431
+ "image": null,
432
+ "listable": true,
433
+ "enabled": true,
434
+ "badge_grouping_id": 4,
435
+ "system": true,
436
+ "query": "\n SELECT u.id user_id, current_timestamp granted_at FROM users u\n WHERE trust_level >= 1 AND (\n :backfill OR u.id IN (:user_ids)\n )\n",
437
+ "trigger": 4,
438
+ "target_posts": false,
439
+ "auto_revoke": true,
440
+ "show_posts": false,
441
+ "badge_type_id": 3
442
+ },
443
+ {
444
+ "id": 2,
445
+ "name": "Member",
446
+ "description": null,
447
+ "grant_count": 0,
448
+ "allow_title": false,
449
+ "multiple_grant": false,
450
+ "icon": "fa-user",
451
+ "image": null,
452
+ "listable": true,
453
+ "enabled": true,
454
+ "badge_grouping_id": 4,
455
+ "system": true,
456
+ "query": "\n SELECT u.id user_id, current_timestamp granted_at FROM users u\n WHERE trust_level >= 2 AND (\n :backfill OR u.id IN (:user_ids)\n )\n",
457
+ "trigger": 4,
458
+ "target_posts": false,
459
+ "auto_revoke": true,
460
+ "show_posts": false,
461
+ "badge_type_id": 3
462
+ }
463
+ ],
464
+ "badge_types": [
465
+ {
466
+ "id": 3,
467
+ "name": "Bronze",
468
+ "sort_order": 7
469
+ },
470
+ {
471
+ "id": 1,
472
+ "name": "Gold",
473
+ "sort_order": 9
474
+ },
475
+ {
476
+ "id": 2,
477
+ "name": "Silver",
478
+ "sort_order": 8
479
+ }
480
+ ],
481
+ "badge_groupings": [
482
+ {
483
+ "id": 1,
484
+ "name": "Getting Started",
485
+ "description": null,
486
+ "position": 10
487
+ },
488
+ {
489
+ "id": 2,
490
+ "name": "Community",
491
+ "description": null,
492
+ "position": 11
493
+ },
494
+ {
495
+ "id": 3,
496
+ "name": "Posting",
497
+ "description": null,
498
+ "position": 12
499
+ },
500
+ {
501
+ "id": 4,
502
+ "name": "Trust Level",
503
+ "description": null,
504
+ "position": 13
505
+ },
506
+ {
507
+ "id": 5,
508
+ "name": "Other",
509
+ "description": null,
510
+ "position": 14
511
+ }
512
+ ],
513
+ "admin_badges": {
514
+ "protected_system_fields": [
515
+ "badge_type_id",
516
+ "multiple_grant",
517
+ "target_posts",
518
+ "show_posts",
519
+ "query",
520
+ "trigger",
521
+ "auto_revoke",
522
+ "listable"
523
+ ],
524
+ "triggers": {
525
+ "none": 0,
526
+ "post_action": 1,
527
+ "post_revision": 2,
528
+ "trust_level_change": 4,
529
+ "user_change": 8
530
+ },
531
+ "badge_ids": [
532
+ 9,
533
+ 11,
534
+ 14,
535
+ 15,
536
+ 12,
537
+ 16,
538
+ 17,
539
+ 23,
540
+ 22,
541
+ 10,
542
+ 13,
543
+ 21,
544
+ 5,
545
+ 8,
546
+ 20,
547
+ 7,
548
+ 19,
549
+ 6,
550
+ 18,
551
+ 4,
552
+ 3,
553
+ 1,
554
+ 2
555
+ ],
556
+ "badge_grouping_ids": [
557
+ 1,
558
+ 2,
559
+ 3,
560
+ 4,
561
+ 5
562
+ ],
563
+ "badge_type_ids": [
564
+ 1,
565
+ 2,
566
+ 3
567
+ ]
568
+ }
569
+ }