wordpress_client 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.hound.yml +2 -0
- data/.rubocop.yml +1065 -0
- data/.ruby-version +1 -0
- data/Gemfile +11 -0
- data/Guardfile +29 -0
- data/LICENSE +21 -0
- data/README.md +63 -0
- data/Rakefile +1 -0
- data/circle.yml +3 -0
- data/lib/wordpress_client.rb +25 -0
- data/lib/wordpress_client/category.rb +4 -0
- data/lib/wordpress_client/client.rb +142 -0
- data/lib/wordpress_client/connection.rb +186 -0
- data/lib/wordpress_client/errors.rb +10 -0
- data/lib/wordpress_client/media.rb +37 -0
- data/lib/wordpress_client/media_parser.rb +48 -0
- data/lib/wordpress_client/paginated_collection.rb +53 -0
- data/lib/wordpress_client/post.rb +62 -0
- data/lib/wordpress_client/post_parser.rb +113 -0
- data/lib/wordpress_client/replace_metadata.rb +81 -0
- data/lib/wordpress_client/replace_terms.rb +62 -0
- data/lib/wordpress_client/rest_parser.rb +17 -0
- data/lib/wordpress_client/tag.rb +4 -0
- data/lib/wordpress_client/term.rb +34 -0
- data/lib/wordpress_client/version.rb +3 -0
- data/spec/category_spec.rb +8 -0
- data/spec/client_spec.rb +411 -0
- data/spec/connection_spec.rb +270 -0
- data/spec/docker/Dockerfile +40 -0
- data/spec/docker/README.md +37 -0
- data/spec/docker/dbdump.sql.gz +0 -0
- data/spec/docker/htaccess +10 -0
- data/spec/docker/restore-dbdump.sh +13 -0
- data/spec/fixtures/category.json +1 -0
- data/spec/fixtures/image-media.json +1 -0
- data/spec/fixtures/invalid-post-id.json +1 -0
- data/spec/fixtures/post-with-forbidden-metadata.json +1 -0
- data/spec/fixtures/post-with-metadata.json +1 -0
- data/spec/fixtures/simple-post.json +1 -0
- data/spec/fixtures/tag.json +1 -0
- data/spec/fixtures/thoughtful.jpg +0 -0
- data/spec/fixtures/validation-error.json +1 -0
- data/spec/integration/attachments_crud_spec.rb +51 -0
- data/spec/integration/categories_spec.rb +60 -0
- data/spec/integration/category_assignment_spec.rb +29 -0
- data/spec/integration/posts_crud_spec.rb +118 -0
- data/spec/integration/posts_finding_spec.rb +86 -0
- data/spec/integration/posts_metadata_spec.rb +27 -0
- data/spec/integration/posts_with_attachments_spec.rb +21 -0
- data/spec/integration/tag_assignment_spec.rb +29 -0
- data/spec/integration/tags_spec.rb +36 -0
- data/spec/media_spec.rb +63 -0
- data/spec/paginated_collection_spec.rb +64 -0
- data/spec/post_spec.rb +114 -0
- data/spec/replace_metadata_spec.rb +56 -0
- data/spec/replace_terms_spec.rb +51 -0
- data/spec/shared_examples/term_examples.rb +37 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/support/docker_runner.rb +49 -0
- data/spec/support/fixtures.rb +19 -0
- data/spec/support/integration_macros.rb +10 -0
- data/spec/support/wordpress_server.rb +103 -0
- data/spec/tag_spec.rb +8 -0
- data/wordpress_client.gemspec +27 -0
- metadata +219 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module WordpressClient
|
4
|
+
describe PaginatedCollection do
|
5
|
+
it "wraps an array" do
|
6
|
+
list = ["one"]
|
7
|
+
pagination = PaginatedCollection.new(list, total: 1, per_page: 1, current_page: 1)
|
8
|
+
|
9
|
+
expect(pagination.each.to_a).to eq list
|
10
|
+
expect(pagination.to_a).to eq list
|
11
|
+
expect(pagination.size).to eq 1
|
12
|
+
|
13
|
+
expect(pagination.total).to eq 1
|
14
|
+
expect(pagination.per_page).to eq 1
|
15
|
+
expect(pagination.current_page).to eq 1
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "pagination attributes" do
|
19
|
+
def collection(total: 1, per_page: 1, current_page: 1)
|
20
|
+
PaginatedCollection.new([], total: total, per_page: per_page, current_page: current_page)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "includes total pages" do
|
24
|
+
expect(collection(total: 10, per_page: 5).total_pages).to eq 2
|
25
|
+
expect(collection(total: 11, per_page: 5).total_pages).to eq 3
|
26
|
+
expect(collection(total: 0, per_page: 5).total_pages).to eq 0
|
27
|
+
expect(collection(total: 10, per_page: 0).total_pages).to eq 0
|
28
|
+
expect(collection(total: 2, per_page: 9).total_pages).to eq 1
|
29
|
+
end
|
30
|
+
|
31
|
+
it "includes next page number" do
|
32
|
+
expect(collection(total: 10, per_page: 1, current_page: 1).next_page).to eq 2
|
33
|
+
expect(collection(total: 10, per_page: 1, current_page: 9).next_page).to eq 10
|
34
|
+
expect(collection(total: 10, per_page: 1, current_page: 10).next_page).to eq nil
|
35
|
+
|
36
|
+
expect(collection(total: 10, per_page: 0, current_page: 1).next_page).to eq nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it "includes previous page number" do
|
40
|
+
expect(collection(total: 10, per_page: 1, current_page: 10).previous_page).to eq 9
|
41
|
+
expect(collection(total: 10, per_page: 1, current_page: 2).previous_page).to eq 1
|
42
|
+
expect(collection(total: 10, per_page: 1, current_page: 1).previous_page).to eq nil
|
43
|
+
end
|
44
|
+
|
45
|
+
it "is out of bounds if current page is after last page" do
|
46
|
+
expect(collection(total: 2, per_page: 1, current_page: 1)).to_not be_out_of_bounds
|
47
|
+
expect(collection(total: 2, per_page: 1, current_page: 2)).to_not be_out_of_bounds
|
48
|
+
|
49
|
+
expect(collection(total: 2, per_page: 1, current_page: 3)).to be_out_of_bounds
|
50
|
+
expect(collection(total: 2, per_page: 1, current_page: 0)).to be_out_of_bounds
|
51
|
+
end
|
52
|
+
|
53
|
+
# Only to be compatible with will_paginate < 3.0
|
54
|
+
it "has an offset" do
|
55
|
+
expect(collection(per_page: 5, current_page: 1).offset).to eq 0
|
56
|
+
expect(collection(per_page: 5, current_page: 2).offset).to eq 5
|
57
|
+
expect(collection(per_page: 50, current_page: 3).offset).to eq 100
|
58
|
+
|
59
|
+
expect(collection(per_page: 50, current_page: 0).offset).to eq 0
|
60
|
+
expect(collection(per_page: 0, current_page: 0).offset).to eq 0
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/spec/post_spec.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module WordpressClient
|
4
|
+
describe Post do
|
5
|
+
let(:fixture) { json_fixture("simple-post.json") }
|
6
|
+
|
7
|
+
it "can be parsed from JSON data" do
|
8
|
+
post = Post.parse(fixture)
|
9
|
+
|
10
|
+
expect(post.id).to eq 1
|
11
|
+
expect(post.title_html).to eq "Hello world!"
|
12
|
+
expect(post.slug).to eq "hello-world"
|
13
|
+
|
14
|
+
expect(post.url).to eq "http://example.com/2015/11/03/hello-world/"
|
15
|
+
expect(post.guid).to eq "http://example.com/?p=1"
|
16
|
+
|
17
|
+
expect(post.excerpt_html).to eq(
|
18
|
+
"<p>Welcome to WordPress. This is your first post. Edit or delete it, then start " \
|
19
|
+
"writing!</p>\n"
|
20
|
+
)
|
21
|
+
|
22
|
+
expect(post.content_html).to eq(
|
23
|
+
"<p>Welcome to WordPress. This is your first post. Edit or delete it, then start " \
|
24
|
+
"writing!</p>\n"
|
25
|
+
)
|
26
|
+
|
27
|
+
expect(post.date).to_not be nil
|
28
|
+
expect(post.updated_at).to_not be nil
|
29
|
+
end
|
30
|
+
|
31
|
+
it "parses categories" do
|
32
|
+
post = Post.parse(fixture)
|
33
|
+
|
34
|
+
expect(post.categories).to eq [
|
35
|
+
Category.new(
|
36
|
+
id: 1, name_html: "Uncategorized", slug: "uncategorized"
|
37
|
+
)
|
38
|
+
]
|
39
|
+
|
40
|
+
expect(post.category_ids).to eq [1]
|
41
|
+
end
|
42
|
+
|
43
|
+
it "parses tags" do
|
44
|
+
post = Post.parse(fixture)
|
45
|
+
|
46
|
+
expect(post.tags).to eq [
|
47
|
+
Tag.new(
|
48
|
+
id: 2, name_html: "Foo", slug: "foo"
|
49
|
+
)
|
50
|
+
]
|
51
|
+
|
52
|
+
expect(post.tag_ids).to eq [2]
|
53
|
+
end
|
54
|
+
|
55
|
+
it "can have a Media as featured image" do
|
56
|
+
media = instance_double(Media, id: 12)
|
57
|
+
post = Post.new(featured_image: media)
|
58
|
+
|
59
|
+
expect(post.featured_image).to eq media
|
60
|
+
expect(post.featured_image_id).to eq 12
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "dates" do
|
64
|
+
it "uses GMT times if available" do
|
65
|
+
post = Post.parse(fixture.merge(
|
66
|
+
"date_gmt" => "2001-01-01T15:00:00",
|
67
|
+
"date" => "2001-01-01T12:00:00",
|
68
|
+
"modified_gmt" => "2001-01-01T15:00:00",
|
69
|
+
"modified" => "2001-01-01T12:00:00",
|
70
|
+
))
|
71
|
+
|
72
|
+
expect(post.date).to eq Time.utc(2001, 1, 1, 15, 0, 0)
|
73
|
+
expect(post.updated_at).to eq Time.utc(2001, 1, 1, 15, 0, 0)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "falls back to local time if no GMT date is provided" do
|
77
|
+
post = Post.parse(fixture.merge(
|
78
|
+
"date_gmt" => nil,
|
79
|
+
"date" => "2001-01-01T12:00:00",
|
80
|
+
"modified_gmt" => nil,
|
81
|
+
"modified" => "2001-01-01T12:00:00",
|
82
|
+
))
|
83
|
+
|
84
|
+
expect(post.date).to eq Time.local(2001, 1, 1, 12, 0, 0)
|
85
|
+
expect(post.updated_at).to eq Time.local(2001, 1, 1, 12, 0, 0)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "metadata" do
|
90
|
+
it "is parsed into a hash" do
|
91
|
+
post = Post.parse(json_fixture("post-with-metadata.json"))
|
92
|
+
expect(post.meta).to eq "foo" => "bar"
|
93
|
+
end
|
94
|
+
|
95
|
+
it "raises UnauthorizedError when post it is forbidden" do
|
96
|
+
expect {
|
97
|
+
Post.parse(json_fixture("post-with-forbidden-metadata.json"))
|
98
|
+
}.to raise_error(UnauthorizedError)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "keeps track of the ID of each metadata key" do
|
102
|
+
post = Post.parse(json_fixture("post-with-metadata.json"))
|
103
|
+
expect(post.meta_id_for("foo")).to eq 2
|
104
|
+
end
|
105
|
+
|
106
|
+
it "raises ArgumentError when asked for the meta ID of a meta key not present" do
|
107
|
+
post = Post.parse(json_fixture("post-with-metadata.json"))
|
108
|
+
expect {
|
109
|
+
post.meta_id_for("clearly unreal")
|
110
|
+
}.to raise_error(ArgumentError, /clearly unreal/)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module WordpressClient
|
4
|
+
describe ReplaceMetadata do
|
5
|
+
it "does nothing if the new metadata is equal to the existing one" do
|
6
|
+
post = instance_double(Post, id: 5, meta: {"existing" => "1"})
|
7
|
+
|
8
|
+
# Note: connection double does not accept any message.
|
9
|
+
connection = instance_double(Connection)
|
10
|
+
|
11
|
+
ReplaceMetadata.apply(connection, post, existing: "1")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "adds missing metadata" do
|
15
|
+
connection = instance_double(Connection)
|
16
|
+
post = instance_double(Post, id: 5, meta: {"existing" => "1"})
|
17
|
+
|
18
|
+
expect(connection).to receive(:create_without_response).with(
|
19
|
+
"posts/5/meta", key: "new", value: "2"
|
20
|
+
)
|
21
|
+
|
22
|
+
ReplaceMetadata.apply(connection, post, existing: "1", new: "2")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "replaces changed metadata" do
|
26
|
+
connection = instance_double(Connection)
|
27
|
+
post = instance_double(Post, id: 5, meta: {"change_me" => "1"})
|
28
|
+
|
29
|
+
expect(post).to receive(:meta_id_for).with("change_me").and_return(13)
|
30
|
+
|
31
|
+
expect(connection).to receive(:patch_without_response).with(
|
32
|
+
"posts/5/meta/13", key: "change_me", value: "2"
|
33
|
+
)
|
34
|
+
|
35
|
+
ReplaceMetadata.apply(connection, post, change_me: "2")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "removes extra metadata" do
|
39
|
+
connection = instance_double(Connection)
|
40
|
+
post = instance_double(Post, id: 5, meta: {"old" => "1", "new" => "2"})
|
41
|
+
|
42
|
+
expect(post).to receive(:meta_id_for).with("old").and_return(45)
|
43
|
+
expect(connection).to receive(:delete).with("posts/5/meta/45", force: true)
|
44
|
+
|
45
|
+
ReplaceMetadata.apply(connection, post, new: "2")
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns the number of changes" do
|
49
|
+
connection = instance_double(Connection).as_null_object
|
50
|
+
post = instance_double(Post, id: 5, meta: {"old" => "1", "change" => "2"}).as_null_object
|
51
|
+
|
52
|
+
result = ReplaceMetadata.apply(connection, post, change: "3", extra: "4")
|
53
|
+
expect(result).to eq 3
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module WordpressClient
|
4
|
+
describe ReplaceTerms do
|
5
|
+
it "adds missing categories" do
|
6
|
+
connection = double(Connection)
|
7
|
+
post = double(Post, id: 40, category_ids: [1])
|
8
|
+
|
9
|
+
expect(connection).to receive(:create_without_response).with("posts/40/terms/category/5", {})
|
10
|
+
|
11
|
+
ReplaceTerms.apply_categories(connection, post, [1, 5])
|
12
|
+
end
|
13
|
+
|
14
|
+
it "removes extra categories" do
|
15
|
+
connection = double(Connection)
|
16
|
+
post = double(Post, id: 40, category_ids: [8, 9, 10])
|
17
|
+
|
18
|
+
expect(connection).to receive(:delete).with("posts/40/terms/category/8", force: true)
|
19
|
+
expect(connection).to receive(:delete).with("posts/40/terms/category/9", force: true)
|
20
|
+
|
21
|
+
ReplaceTerms.apply_categories(connection, post, [10])
|
22
|
+
end
|
23
|
+
|
24
|
+
it "adds missing tags" do
|
25
|
+
connection = double(Connection)
|
26
|
+
post = double(Post, id: 40, tag_ids: [1])
|
27
|
+
|
28
|
+
expect(connection).to receive(:create_without_response).with("posts/40/terms/tag/5", {})
|
29
|
+
|
30
|
+
ReplaceTerms.apply_tags(connection, post, [1, 5])
|
31
|
+
end
|
32
|
+
|
33
|
+
it "removes extra tags" do
|
34
|
+
connection = double(Connection)
|
35
|
+
post = double(Post, id: 40, tag_ids: [8, 9, 10])
|
36
|
+
|
37
|
+
expect(connection).to receive(:delete).with("posts/40/terms/tag/8", force: true)
|
38
|
+
expect(connection).to receive(:delete).with("posts/40/terms/tag/9", force: true)
|
39
|
+
|
40
|
+
ReplaceTerms.apply_tags(connection, post, [10])
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns the amount of changes made" do
|
44
|
+
connection = double(Connection).as_null_object
|
45
|
+
post = double(Post, id: 40, tag_ids: [8, 9, 10])
|
46
|
+
|
47
|
+
result = ReplaceTerms.apply_tags(connection, post, [10, 11])
|
48
|
+
expect(result).to eq 3
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
shared_examples_for(WordpressClient::Term) do |fixture_name:|
|
2
|
+
it "has an id, name_html and slug" do
|
3
|
+
term = described_class.new(id: 5, name_html: "Heyho", slug: "heyho")
|
4
|
+
expect(term.id).to eq 5
|
5
|
+
expect(term.name_html).to eq "Heyho"
|
6
|
+
expect(term.slug).to eq "heyho"
|
7
|
+
end
|
8
|
+
|
9
|
+
it "can be parsed" do
|
10
|
+
term = described_class.parse(json_fixture(fixture_name))
|
11
|
+
expect(term.id).to be_kind_of Integer
|
12
|
+
|
13
|
+
expect(term.name_html).to be_kind_of String
|
14
|
+
expect(term.slug).to be_kind_of String
|
15
|
+
expect(term.name_html).to_not be_empty
|
16
|
+
expect(term.slug).to_not be_empty
|
17
|
+
end
|
18
|
+
|
19
|
+
it "is equal to other instances with the same id, name_html and slug" do
|
20
|
+
instance = described_class.new(id: 1, name_html: "One", slug: "one")
|
21
|
+
copy = described_class.new(id: 1, name_html: "One", slug: "one")
|
22
|
+
|
23
|
+
expect(instance).to eq instance
|
24
|
+
expect(instance).to eq copy
|
25
|
+
|
26
|
+
expect(instance).to_not eq described_class.new(id: 2, name_html: "One", slug: "one")
|
27
|
+
expect(instance).to_not eq described_class.new(id: 1, name_html: "Two", slug: "one")
|
28
|
+
expect(instance).to_not eq described_class.new(id: 1, name_html: "One", slug: "two")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "it not equal on other Term subclasses with the same id, name_html and slug" do
|
32
|
+
other_subclass = Class.new(WordpressClient::Tag)
|
33
|
+
|
34
|
+
term = described_class.new(id: 1, name_html: "One", slug: "one")
|
35
|
+
expect(term).to_not eq other_subclass.new(id: 1, name_html: "One", slug: "one")
|
36
|
+
end
|
37
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
if ENV['CODECLIMATE_REPO_TOKEN']
|
2
|
+
require "codeclimate-test-reporter"
|
3
|
+
CodeClimate::TestReporter.start
|
4
|
+
end
|
5
|
+
|
6
|
+
require "webmock/rspec"
|
7
|
+
|
8
|
+
require_relative "support/wordpress_server"
|
9
|
+
require_relative "support/fixtures"
|
10
|
+
require_relative "support/integration_macros"
|
11
|
+
|
12
|
+
$LOAD_PATH << File.expand_path("../../lib", __FILE__)
|
13
|
+
require "wordpress_client"
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.extend IntegrationMacros
|
17
|
+
config.include Fixtures
|
18
|
+
|
19
|
+
config.run_all_when_everything_filtered = true
|
20
|
+
|
21
|
+
config.before do
|
22
|
+
WebMock.disable_net_connect!(allow_localhost: false)
|
23
|
+
end
|
24
|
+
|
25
|
+
config.after do
|
26
|
+
WebMock.allow_net_connect!
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "shellwords"
|
2
|
+
require "uri"
|
3
|
+
|
4
|
+
module DockerRunner
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def docker_installed?
|
8
|
+
system("hash docker > /dev/null 2> /dev/null")
|
9
|
+
end
|
10
|
+
|
11
|
+
def image_exists?(name)
|
12
|
+
system("docker images | grep -q '^#{name.shellescape} '")
|
13
|
+
end
|
14
|
+
|
15
|
+
def build_image(name, path: Dir.pwd)
|
16
|
+
system("cd #{path.shellescape} && docker build -t #{name.shellescape} .")
|
17
|
+
end
|
18
|
+
|
19
|
+
def run_container(name, port:, environment: {})
|
20
|
+
environment_flags = environment.map { |key, value|
|
21
|
+
"-e #{key.to_s.upcase.shellescape}=#{value.shellescape}"
|
22
|
+
}
|
23
|
+
|
24
|
+
output = `
|
25
|
+
docker run \
|
26
|
+
-dit -p #{port.to_i}:80 \
|
27
|
+
#{environment_flags.join(" ")} \
|
28
|
+
#{name.shellescape}
|
29
|
+
`
|
30
|
+
if $?.success?
|
31
|
+
output.chomp
|
32
|
+
else
|
33
|
+
fail "Failed to start container. Maybe it's already running? Output: #{output}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def purge_container(id)
|
38
|
+
output = `docker kill #{id.shellescape}; docker rm #{id.shellescape} `
|
39
|
+
|
40
|
+
unless $?.success?
|
41
|
+
message = "Could not clean up docker image #{id}. Output was:\n#{output}.\n"
|
42
|
+
if ENV["CIRCLECI"]
|
43
|
+
puts message
|
44
|
+
else
|
45
|
+
raise message
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Fixtures
|
2
|
+
FixtureRoot = Pathname.new(File.expand_path("../../fixtures", __FILE__))
|
3
|
+
|
4
|
+
def fixture_path(name)
|
5
|
+
FixtureRoot.join(name)
|
6
|
+
end
|
7
|
+
|
8
|
+
def fixture_contents(name)
|
9
|
+
fixture_path(name).read
|
10
|
+
end
|
11
|
+
|
12
|
+
def json_fixture(name)
|
13
|
+
JSON.parse(fixture_contents(name))
|
14
|
+
end
|
15
|
+
|
16
|
+
def open_fixture(name)
|
17
|
+
fixture_path(name).open('r') { |file| yield file }
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require_relative "docker_runner"
|
2
|
+
|
3
|
+
class WordpressServer
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
attr_reader :container_id, :port, :host
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@host = docker_host
|
10
|
+
@port = 8181
|
11
|
+
|
12
|
+
start_docker_container
|
13
|
+
at_exit { purge_container }
|
14
|
+
end
|
15
|
+
|
16
|
+
def url
|
17
|
+
"http://#{host_with_port}/wp-json"
|
18
|
+
end
|
19
|
+
|
20
|
+
# Defined in the dbdump in spec/docker/dbdump.sql.gz
|
21
|
+
def username() "test" end
|
22
|
+
|
23
|
+
# Defined in the dbdump in spec/docker/dbdump.sql.gz
|
24
|
+
def password() "test" end
|
25
|
+
|
26
|
+
private
|
27
|
+
def host_with_port
|
28
|
+
"#{host}:#{port}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def docker_host
|
32
|
+
if ENV['DOCKER_HOST']
|
33
|
+
URI.parse(ENV['DOCKER_HOST']).host
|
34
|
+
else
|
35
|
+
"localhost"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def start_docker_container
|
40
|
+
fail_if_docker_missing
|
41
|
+
build_container_if_missing
|
42
|
+
|
43
|
+
@container_id = start_container
|
44
|
+
@running = true
|
45
|
+
|
46
|
+
begin
|
47
|
+
wait_for_container_to_start
|
48
|
+
rescue
|
49
|
+
purge_container
|
50
|
+
raise $!
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def fail_if_docker_missing
|
55
|
+
unless DockerRunner.docker_installed?
|
56
|
+
STDERR.puts(
|
57
|
+
"It does not look like you have docker installed. " \
|
58
|
+
"Please install docker so you can run integration tests."
|
59
|
+
)
|
60
|
+
fail "No docker installed"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def build_container_if_missing
|
65
|
+
unless DockerRunner.image_exists?("wpclient-test")
|
66
|
+
DockerRunner.build_image("wpclient-test", path: "spec/docker")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def start_container
|
71
|
+
DockerRunner.run_container(
|
72
|
+
"wpclient-test",
|
73
|
+
port: port,
|
74
|
+
environment: {wordpress_host: host_with_port}
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
def purge_container
|
79
|
+
if @running
|
80
|
+
DockerRunner.purge_container(container_id)
|
81
|
+
@running = true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def wait_for_container_to_start
|
86
|
+
# Try to connect to the webserver in a loop until we successfully connect,
|
87
|
+
# the container process dies, or the timeout is reached.
|
88
|
+
timeout = 60
|
89
|
+
start = Time.now
|
90
|
+
|
91
|
+
loop do
|
92
|
+
fail "Timed out while waiting for the container to start" if Time.now - start > timeout
|
93
|
+
|
94
|
+
begin
|
95
|
+
response = Faraday.get(url)
|
96
|
+
return if response.status == 200
|
97
|
+
rescue Faraday::ConnectionFailed
|
98
|
+
# Server not yet started. Just wait it out...
|
99
|
+
end
|
100
|
+
sleep 0.5
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|