wordpress_client 1.0.1 → 2.0.0

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 (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,