wordpress_client 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +124 -69
  3. data/Changelog.md +4 -0
  4. data/README.md +36 -13
  5. data/lib/wordpress_client.rb +0 -3
  6. data/lib/wordpress_client/client.rb +20 -74
  7. data/lib/wordpress_client/connection.rb +9 -10
  8. data/lib/wordpress_client/media.rb +15 -1
  9. data/lib/wordpress_client/media_parser.rb +1 -0
  10. data/lib/wordpress_client/post.rb +16 -36
  11. data/lib/wordpress_client/post_parser.rb +9 -37
  12. data/lib/wordpress_client/term.rb +1 -1
  13. data/lib/wordpress_client/version.rb +1 -1
  14. data/spec/client_spec.rb +17 -181
  15. data/spec/connection_spec.rb +8 -11
  16. data/spec/docker/Dockerfile +8 -8
  17. data/spec/docker/README.md +19 -9
  18. data/spec/docker/dbdump.sql.gz +0 -0
  19. data/spec/docker/restore-dbdump.sh +2 -2
  20. data/spec/fixtures/post-with-metadata.json +99 -1
  21. data/spec/fixtures/simple-post.json +324 -1
  22. data/spec/integration/attachments_crud_spec.rb +1 -1
  23. data/spec/integration/posts_crud_spec.rb +1 -1
  24. data/spec/integration/posts_finding_spec.rb +0 -69
  25. data/spec/integration/posts_metadata_spec.rb +11 -11
  26. data/spec/integration/posts_with_attachments_spec.rb +20 -6
  27. data/spec/media_spec.rb +13 -0
  28. data/spec/post_spec.rb +5 -31
  29. data/spec/support/docker_runner.rb +25 -10
  30. data/spec/support/wordpress_server.rb +15 -7
  31. data/wordpress_client.gemspec +11 -12
  32. metadata +5 -15
  33. data/lib/wordpress_client/replace_metadata.rb +0 -82
  34. data/lib/wordpress_client/replace_terms.rb +0 -63
  35. data/spec/fixtures/post-with-forbidden-metadata.json +0 -1
  36. data/spec/integration/category_assignment_spec.rb +0 -29
  37. data/spec/integration/tag_assignment_spec.rb +0 -29
  38. data/spec/replace_metadata_spec.rb +0 -56
  39. data/spec/replace_terms_spec.rb +0 -51
@@ -13,16 +13,13 @@ module WordpressClient
13
13
  end
14
14
 
15
15
  def to_post
16
- meta, meta_ids = parse_metadata
17
- post = Post.new(meta: meta, meta_ids: meta_ids)
18
-
16
+ post = Post.new
19
17
  assign_basic(post)
20
18
  assign_dates(post)
21
19
  assign_rendered(post)
22
20
  assign_categories(post)
23
21
  assign_tags(post)
24
- assign_featured_image(post)
25
-
22
+ assign_featured_media(post)
26
23
  post
27
24
  end
28
25
 
@@ -34,6 +31,10 @@ module WordpressClient
34
31
  post.slug = data["slug"]
35
32
  post.url = data["link"]
36
33
  post.status = data["status"]
34
+ post.meta = data["meta"]
35
+ post.category_ids = data["categories"]
36
+ post.tag_ids = data["tags"]
37
+ post.featured_media_id = data["featured_media"]
37
38
  end
38
39
 
39
40
  def assign_dates(post)
@@ -60,32 +61,17 @@ module WordpressClient
60
61
  end
61
62
  end
62
63
 
63
- def assign_featured_image(post)
64
- featured_id = data["featured_image"]
64
+ def assign_featured_media(post)
65
+ featured_id = data["featured_media"]
65
66
  if featured_id
66
67
  features = (embedded["wp:featuredmedia"] || []).flatten
67
68
  media = features.detect { |feature| feature["id"] == featured_id }
68
69
  if media
69
- post.featured_image = Media.parse(media)
70
+ post.featured_media = Media.parse(media)
70
71
  end
71
72
  end
72
73
  end
73
74
 
74
- def parse_metadata
75
- embedded_metadata = (embedded["wp:meta"] || []).flatten
76
- validate_embedded_metadata(embedded_metadata)
77
-
78
- meta = {}
79
- meta_ids = {}
80
-
81
- embedded_metadata.each do |entry|
82
- meta[entry.fetch("key")] = entry.fetch("value")
83
- meta_ids[entry.fetch("key")] = entry.fetch("id")
84
- end
85
-
86
- [meta, meta_ids]
87
- end
88
-
89
75
  def embedded_terms(type)
90
76
  term_collections = embedded["wp:term"] || embedded["https://api.w.org/term"] || []
91
77
 
@@ -96,19 +82,5 @@ module WordpressClient
96
82
  } || []
97
83
  end
98
84
 
99
- def validate_embedded_metadata(embedded_metadata)
100
- if embedded_metadata.size == 1 && embedded_metadata.first["code"]
101
- error = embedded_metadata.first
102
- case error["code"]
103
- when "rest_forbidden"
104
- raise UnauthorizedError, error.fetch(
105
- "message", "You are not authorized to see meta for this post."
106
- )
107
- else
108
- raise Error, "Could not retreive meta for this post: " \
109
- "#{error["code"]} – #{error["message"]}"
110
- end
111
- end
112
- end
113
85
  end
114
86
  end
@@ -14,7 +14,7 @@ module WordpressClient
14
14
  # @!attribute [r] name_html
15
15
  # @return [String] The name of the resource, HTML encoded.
16
16
  # @example
17
- # term.name_html #=> "Father & Daughter stuff"
17
+ # term.name_html #=> "Father & Daughter stuff"
18
18
 
19
19
  # @!attribute [r] slug
20
20
  # @return [String] The slug of the resource in Wordpress.
@@ -3,5 +3,5 @@ module WordpressClient
3
3
  #
4
4
  # @note This only applies if using a released version. A development build
5
5
  # would not correspond to this constant.
6
- VERSION = "1.0.1"
6
+ VERSION = "2.0.0".freeze
7
7
  end
@@ -22,30 +22,6 @@ module WordpressClient
22
22
 
23
23
  expect(client.posts).to eq []
24
24
  end
25
-
26
- it "can filter on category slugs" do
27
- expect(connection).to receive(:get_multiple).with(
28
- Post, "posts", hash_including(filter: {category_name: "my-cat"})
29
- ).and_return []
30
-
31
- expect(client.posts(category_slug: "my-cat")).to eq []
32
- end
33
-
34
- it "can filter on tag slugs" do
35
- expect(connection).to receive(:get_multiple).with(
36
- Post, "posts", hash_including(filter: {tag: "my-cat"})
37
- ).and_return []
38
-
39
- expect(client.posts(tag_slug: "my-cat")).to eq []
40
- end
41
-
42
- it "can filter on tag and category slugs" do
43
- expect(connection).to receive(:get_multiple).with(
44
- Post, "posts", hash_including(filter: {tag: "my-cat", category_name: "my-dog"})
45
- ).and_return []
46
-
47
- expect(client.posts(tag_slug: "my-cat", category_slug: "my-dog")).to eq []
48
- end
49
25
  end
50
26
 
51
27
  describe "fetching a single post" do
@@ -53,31 +29,12 @@ module WordpressClient
53
29
  post = instance_double(Post)
54
30
 
55
31
  expect(connection).to receive(:get).with(
56
- Post, "posts/5", _embed: nil, context: "edit"
32
+ Post, "posts/5", _embed: nil
57
33
  ).and_return post
58
34
 
59
35
  expect(client.find_post(5)).to eq post
60
36
  end
61
37
 
62
- it "can find using a slug" do
63
- post = instance_double(Post)
64
-
65
- expect(connection).to receive(:get_multiple).with(
66
- Post, "posts", hash_including(filter: {name: "my-slug"})
67
- ).and_return [post]
68
-
69
- expect(client.find_post_by_slug("my-slug")).to eq post
70
- end
71
-
72
- it "raises NotFoundError when trying to find by slug yields no posts" do
73
- expect(connection).to receive(:get_multiple).with(
74
- Post, "posts", hash_including(filter: {name: "my-slug"}, per_page: 1)
75
- ).and_return []
76
-
77
- expect {
78
- client.find_post_by_slug("my-slug")
79
- }.to raise_error(NotFoundError, /my-slug/)
80
- end
81
38
  end
82
39
 
83
40
  describe "creating a post" do
@@ -93,147 +50,26 @@ module WordpressClient
93
50
  # it's also very possible that we need to fetch the post again after
94
51
  # doing other things to it.
95
52
  allow(connection).to receive(:get).with(
96
- Post, "posts/5", hash_including(_embed: nil)
53
+ Post, "posts/5"
97
54
  ).and_return(post)
98
55
 
99
56
  expect(client.create_post(attributes)).to eq post
100
57
  end
101
58
 
102
- it "adds metadata to the post" do
103
- post = instance_double(Post, id: 5)
104
- allow(connection).to receive(:create).and_return(post)
105
-
106
- expect(ReplaceMetadata).to receive(:apply).with(
107
- connection, post, {"hello" => "world"}
108
- ).and_return(0)
109
-
110
- client.create_post(title: "Foo", meta: {"hello" => "world"})
111
- end
112
-
113
- it "sets categories of the post" do
114
- post = instance_double(Post, id: 5)
115
- allow(connection).to receive(:create).and_return(post)
116
-
117
- expect(ReplaceTerms).to receive(:apply_categories).with(
118
- connection, post, [1, 3, 7]
119
- ).and_return(0)
120
-
121
- client.create_post(title: "Foo", category_ids: [1, 3, 7])
122
- end
123
-
124
- it "sets tags of the post" do
125
- post = instance_double(Post, id: 5)
126
- allow(connection).to receive(:create).and_return(post)
127
-
128
- expect(ReplaceTerms).to receive(:apply_tags).with(
129
- connection, post, [1, 3, 7]
130
- ).and_return(0)
131
-
132
- client.create_post(title: "Foo", tag_ids: [1, 3, 7])
133
- end
134
-
135
- it "refreshes the post if terms or categories changed" do
136
- post = instance_double(Post, id: 5)
137
- allow(connection).to receive(:create).and_return(post)
138
-
139
- expect(ReplaceTerms).to receive(:apply_tags).and_return(1)
140
- expect(ReplaceTerms).to receive(:apply_categories).and_return(1)
141
- expect(ReplaceMetadata).to receive(:apply).and_return(1)
142
-
143
- expect(connection).to receive(:get).with(
144
- Post, "posts/5", hash_including(_embed: nil)
145
- ).and_return(post)
146
-
147
- client.create_post(title: "Foo", tag_ids: [], category_ids: [], meta: {})
148
- end
149
-
150
- it "does not refresh the post if neither terms nor categories changed" do
151
- post = instance_double(Post, id: 5)
152
- allow(connection).to receive(:create).and_return(post)
153
-
154
- expect(ReplaceTerms).to receive(:apply_tags).and_return(0)
155
- expect(ReplaceTerms).to receive(:apply_categories).and_return(0)
156
- expect(ReplaceMetadata).to receive(:apply).and_return(0)
157
-
158
- expect(connection).to_not receive(:get)
159
-
160
- client.create_post(title: "Foo", tag_ids: [], category_ids: [], meta: {})
161
- end
162
59
  end
163
60
 
164
61
  describe "updating a post" do
165
62
  it "embeds linked resources" do
166
63
  post = instance_double(Post)
167
64
 
168
- expect(connection).to receive(:patch).with(
169
- Post, "posts/5?_embed", hash_including(title: "Foo")
65
+ expect(connection).to receive(:put).with(
66
+ Post, "posts/5", hash_including(title: "Foo")
170
67
  ).and_return(post)
171
68
 
172
69
  expect(client.update_post(5, title: "Foo")).to eq post
173
70
  end
174
71
 
175
- it "adds metadata to the post" do
176
- post = instance_double(Post, id: 5)
177
- allow(connection).to receive(:patch).and_return(post)
178
-
179
- expect(ReplaceMetadata).to receive(:apply).with(
180
- connection, post, {"hello" => "world"}
181
- ).and_return(0)
182
-
183
- client.update_post(5, title: "Foo", meta: {"hello" => "world"})
184
- end
185
-
186
- it "changes categories of the post" do
187
- post = instance_double(Post, id: 5)
188
- allow(connection).to receive(:patch).and_return(post)
189
-
190
- expect(ReplaceTerms).to receive(:apply_categories).with(
191
- connection, post, [1, 3, 7]
192
- ).and_return(0)
193
-
194
- client.update_post(5, title: "Foo", category_ids: [1, 3, 7])
195
- end
196
-
197
- it "changes tags of the post" do
198
- post = instance_double(Post, id: 5)
199
- allow(connection).to receive(:patch).and_return(post)
200
-
201
- expect(ReplaceTerms).to receive(:apply_tags).with(
202
- connection, post, [1, 3, 7]
203
- ).and_return(0)
204
-
205
- client.update_post(5, title: "Foo", tag_ids: [1, 3, 7])
206
- end
207
-
208
- it "refreshes the post if terms or categories changed" do
209
- post = instance_double(Post, id: 5)
210
- allow(connection).to receive(:patch).and_return(post)
211
-
212
- expect(ReplaceTerms).to receive(:apply_tags).and_return(1)
213
- expect(ReplaceTerms).to receive(:apply_categories).and_return(1)
214
- expect(ReplaceMetadata).to receive(:apply).and_return(1)
215
-
216
- expect(connection).to receive(:get).with(
217
- Post, "posts/5", hash_including(_embed: nil)
218
- ).and_return(post)
219
-
220
- client.update_post(5, title: "Foo", tag_ids: [], category_ids: [], meta: {})
221
- end
222
-
223
- it "does not refresh the post if neither terms nor categories changed" do
224
- post = instance_double(Post, id: 5)
225
- allow(connection).to receive(:patch).and_return(post)
226
-
227
- expect(ReplaceTerms).to receive(:apply_tags).and_return(0)
228
- expect(ReplaceTerms).to receive(:apply_categories).and_return(0)
229
- expect(ReplaceMetadata).to receive(:apply).and_return(0)
230
-
231
- expect(connection).to_not receive(:get)
232
-
233
- client.update_post(5, title: "Foo", tag_ids: [], category_ids: [], meta: {})
234
- end
235
72
  end
236
-
237
73
  describe "deleting posts" do
238
74
  it "deletes a post without force by default" do
239
75
  expect(connection).to receive(:delete).with(
@@ -263,12 +99,12 @@ module WordpressClient
263
99
  describe "categories" do
264
100
  it "can be listed" do
265
101
  expect(connection).to receive(:get_multiple).with(
266
- Category, "terms/category", hash_including(page: 1, per_page: 10)
102
+ Category, "categories", hash_including(page: 1, per_page: 10)
267
103
  )
268
104
  client.categories
269
105
 
270
106
  expect(connection).to receive(:get_multiple).with(
271
- Category, "terms/category", hash_including(page: 2, per_page: 60)
107
+ Category, "categories", hash_including(page: 2, per_page: 60)
272
108
  )
273
109
  client.categories(page: 2, per_page: 60)
274
110
  end
@@ -277,7 +113,7 @@ module WordpressClient
277
113
  category = instance_double(Category)
278
114
 
279
115
  expect(connection).to receive(:get).with(
280
- Category, "terms/category/12"
116
+ Category, "categories/12"
281
117
  ).and_return category
282
118
 
283
119
  expect(client.find_category(12)).to eq category
@@ -287,7 +123,7 @@ module WordpressClient
287
123
  category = instance_double(Category)
288
124
 
289
125
  expect(connection).to receive(:create).with(
290
- Category, "terms/category", name: "Foo"
126
+ Category, "categories", name: "Foo"
291
127
  ).and_return category
292
128
 
293
129
  expect(client.create_category(name: "Foo")).to eq category
@@ -296,8 +132,8 @@ module WordpressClient
296
132
  it "can be updated" do
297
133
  category = instance_double(Category)
298
134
 
299
- expect(connection).to receive(:patch).with(
300
- Category, "terms/category/45", name: "New"
135
+ expect(connection).to receive(:put).with(
136
+ Category, "categories/45", name: "New"
301
137
  ).and_return category
302
138
 
303
139
  expect(client.update_category(45, name: "New")).to eq category
@@ -307,12 +143,12 @@ module WordpressClient
307
143
  describe "tags" do
308
144
  it "can be listed" do
309
145
  expect(connection).to receive(:get_multiple).with(
310
- Tag, "terms/tag", hash_including(page: 1, per_page: 10)
146
+ Tag, "tags", hash_including(page: 1, per_page: 10)
311
147
  )
312
148
  client.tags
313
149
 
314
150
  expect(connection).to receive(:get_multiple).with(
315
- Tag, "terms/tag", hash_including(page: 2, per_page: 60)
151
+ Tag, "tags", hash_including(page: 2, per_page: 60)
316
152
  )
317
153
  client.tags(page: 2, per_page: 60)
318
154
  end
@@ -321,7 +157,7 @@ module WordpressClient
321
157
  tag = instance_double(Tag)
322
158
 
323
159
  expect(connection).to receive(:get).with(
324
- Tag, "terms/tag/12"
160
+ Tag, "tags/12"
325
161
  ).and_return tag
326
162
 
327
163
  expect(client.find_tag(12)).to eq tag
@@ -331,7 +167,7 @@ module WordpressClient
331
167
  tag = instance_double(Tag)
332
168
 
333
169
  expect(connection).to receive(:create).with(
334
- Tag, "terms/tag", name: "Foo"
170
+ Tag, "tags", name: "Foo"
335
171
  ).and_return tag
336
172
 
337
173
  expect(client.create_tag(name: "Foo")).to eq tag
@@ -340,8 +176,8 @@ module WordpressClient
340
176
  it "can be updated" do
341
177
  tag = instance_double(Tag)
342
178
 
343
- expect(connection).to receive(:patch).with(
344
- Tag, "terms/tag/45", name: "New"
179
+ expect(connection).to receive(:put).with(
180
+ Tag, "tags/45", name: "New"
345
181
  ).and_return tag
346
182
 
347
183
  expect(client.update_tag(45, name: "New")).to eq tag
@@ -400,7 +236,7 @@ module WordpressClient
400
236
  it "can be updated" do
401
237
  media = instance_double(Media)
402
238
 
403
- expect(connection).to receive(:patch).with(
239
+ expect(connection).to receive(:put).with(
404
240
  Media, "media/7", title: "New"
405
241
  ).and_return(media)
406
242
 
@@ -135,31 +135,31 @@ module WordpressClient
135
135
  "id" => 1, "title" => "Bar"
136
136
  ).and_return(model_instance)
137
137
 
138
- response = connection.patch(model, "foos/1", title: "Bar")
138
+ response = connection.put(model, "foos/1", title: "Bar")
139
139
  expect(response).to eq model_instance
140
140
  end
141
141
 
142
142
  it "can ignore responses" do
143
143
  stub_patch("#{base_url}/foos/1", {title: "Bar"}, returns: {id: 1, title: "Bar"})
144
- response = connection.patch_without_response("foos/1", title: "Bar")
144
+ response = connection.put_without_response("foos/1", title: "Bar")
145
145
  expect(response).to be true
146
146
  end
147
147
 
148
148
  it "raises NotFoundError if response is 400 with rest_post_invalid_id as error code" do
149
149
  stub_patch(/./, {}, returns: json_fixture("invalid-post-id.json"), status: 400)
150
- expect { connection.patch(model, "foo", {}) }.to raise_error(NotFoundError, /post id/i)
151
- expect { connection.patch_without_response("foo", {}) }.to raise_error(NotFoundError)
150
+ expect { connection.put(model, "foo", {}) }.to raise_error(NotFoundError, /post id/i)
151
+ expect { connection.put_without_response("foo", {}) }.to raise_error(NotFoundError)
152
152
  end
153
153
 
154
154
  it "raises ValidationError on any other 400 responses" do
155
155
  stub_patch(/./, {}, returns: json_fixture("validation-error.json"), status: 400)
156
156
 
157
157
  expect {
158
- connection.patch(model, "foo", {})
158
+ connection.put(model, "foo", {})
159
159
  }.to raise_error(ValidationError, /status is not one of/)
160
160
 
161
161
  expect {
162
- connection.patch_without_response("foo", {})
162
+ connection.put_without_response("foo", {})
163
163
  }.to raise_error(ValidationError, /status is not one of/)
164
164
  end
165
165
  end
@@ -199,10 +199,7 @@ module WordpressClient
199
199
  headers: {
200
200
  "content-length" => "11",
201
201
  "content-type" => "text/plain",
202
- # WP API does not parse normal Content-Disposition and instead ops
203
- # to using their own format:
204
- # https://github.com/WP-API/WP-API/issues/1744
205
- "content-disposition" => 'filename=foo.txt',
202
+ "content-disposition" => 'attachment; filename="foo.txt"',
206
203
  },
207
204
  body: "hello world",
208
205
  ).to_return(
@@ -260,7 +257,7 @@ module WordpressClient
260
257
  end
261
258
 
262
259
  def stub_patch(path, data, returns:, status: 200)
263
- stub_request(:patch, path).with(
260
+ stub_request(:put, path).with(
264
261
  basic_auth: ['jane', 'doe'],
265
262
  headers: {"content-type" => "application/json; charset=#{"".encoding}"},
266
263
  body: data.to_json,