middleman-dato 0.0.1.rc12 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +7 -0
- data/.rspec +2 -0
- data/.rubocop.yml +9 -1070
- data/Gemfile +8 -8
- data/Rakefile +14 -5
- data/foo.rb +12 -0
- data/lib/dato/client.rb +14 -9
- data/lib/dato/entities_repo.rb +43 -0
- data/lib/dato/field_type/boolean.rb +9 -0
- data/lib/dato/field_type/date.rb +9 -0
- data/lib/dato/field_type/date_time.rb +9 -0
- data/lib/dato/field_type/file.rb +30 -0
- data/lib/dato/field_type/float.rb +9 -0
- data/lib/dato/field_type/image.rb +23 -0
- data/lib/dato/field_type/integer.rb +9 -0
- data/lib/dato/field_type/lat_lon.rb +16 -0
- data/lib/dato/field_type/link.rb +9 -0
- data/lib/dato/field_type/links.rb +9 -0
- data/lib/dato/field_type/seo.rb +21 -0
- data/lib/dato/field_type/string.rb +9 -0
- data/lib/dato/field_type/text.rb +9 -0
- data/lib/dato/field_type/video.rb +48 -0
- data/lib/dato/json_api_entity.rb +75 -0
- data/lib/dato/meta_tags/article_modified_time.rb +3 -3
- data/lib/dato/meta_tags/article_publisher.rb +3 -3
- data/lib/dato/meta_tags/base.rb +12 -19
- data/lib/dato/meta_tags/description.rb +4 -4
- data/lib/dato/meta_tags/image.rb +5 -8
- data/lib/dato/meta_tags/og_locale.rb +2 -2
- data/lib/dato/meta_tags/og_meta_tag.rb +2 -4
- data/lib/dato/meta_tags/og_site_name.rb +2 -2
- data/lib/dato/meta_tags/og_type.rb +5 -5
- data/lib/dato/meta_tags/robots.rb +2 -4
- data/lib/dato/meta_tags/title.rb +5 -4
- data/lib/dato/meta_tags/twitter_card.rb +3 -3
- data/lib/dato/meta_tags/twitter_meta_tag.rb +2 -4
- data/lib/dato/meta_tags/twitter_site.rb +2 -2
- data/lib/dato/meta_tags/url.rb +4 -4
- data/lib/dato/meta_tags_builder.rb +13 -13
- data/lib/dato/middleman_extension.rb +15 -23
- data/lib/dato/record.rb +77 -46
- data/lib/dato/records_repo.rb +106 -0
- data/lib/dato/space.rb +36 -0
- data/lib/middleman-dato.rb +5 -2
- data/middleman-dato.gemspec +14 -13
- data/spec/dato/entities_repo_spec.rb +41 -0
- data/spec/dato/field_type/file_spec.rb +20 -0
- data/spec/dato/field_type/image_spec.rb +24 -0
- data/spec/dato/field_type/lat_lon_spec.rb +18 -0
- data/spec/dato/field_type/seo_spec.rb +31 -0
- data/spec/dato/field_type/video_spec.rb +32 -0
- data/spec/dato/json_api_entity_spec.rb +123 -0
- data/spec/dato/meta_tags/article_modified_time_spec.rb +16 -14
- data/spec/dato/meta_tags/image_spec.rb +39 -0
- data/spec/dato/meta_tags/og_locale_spec.rb +14 -12
- data/spec/dato/record_spec.rb +137 -78
- data/spec/dato/records_repo_spec.rb +125 -0
- data/spec/spec_helper.rb +14 -12
- metadata +58 -13
- data/lib/dato/field.rb +0 -43
- data/lib/dato/fields/belongs_to.rb +0 -21
- data/lib/dato/fields/file.rb +0 -22
- data/lib/dato/fields/seo.rb +0 -37
- data/lib/dato/repo.rb +0 -111
- data/lib/middleman_extension.rb +0 -1
- data/spec/dato/field_spec.rb +0 -110
@@ -0,0 +1,31 @@
|
|
1
|
+
module Dato
|
2
|
+
module FieldType
|
3
|
+
RSpec.describe Seo do
|
4
|
+
subject(:seo) { described_class.parse(attributes, nil) }
|
5
|
+
let(:attributes) do
|
6
|
+
{
|
7
|
+
title: 'title',
|
8
|
+
description: 'description',
|
9
|
+
image: {
|
10
|
+
path: '/foo.png',
|
11
|
+
format: 'jpg',
|
12
|
+
size: 4000,
|
13
|
+
width: 20,
|
14
|
+
height: 20
|
15
|
+
}
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'responds to title, description and image methods' do
|
20
|
+
expect(seo.title).to eq 'title'
|
21
|
+
expect(seo.description).to eq 'description'
|
22
|
+
expect(seo.image).to be_a Dato::FieldType::Image
|
23
|
+
expect(seo.image.path).to eq '/foo.png'
|
24
|
+
expect(seo.image.format).to eq 'jpg'
|
25
|
+
expect(seo.image.size).to eq 4000
|
26
|
+
expect(seo.image.width).to eq 20
|
27
|
+
expect(seo.image.height).to eq 20
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Dato
|
2
|
+
module FieldType
|
3
|
+
RSpec.describe Video do
|
4
|
+
subject(:video) { described_class.parse(attributes, nil) }
|
5
|
+
let(:attributes) do
|
6
|
+
{
|
7
|
+
url: 'https://www.youtube.com/watch?v=oHg5SJYRHA0',
|
8
|
+
provider_url: 'https://www.youtube.com',
|
9
|
+
thumbnail_url: 'http://i3.ytimg.com/vi/oHg5SJYRHA0/hqdefault.jpg',
|
10
|
+
title: "RickRoll'D",
|
11
|
+
width: 640,
|
12
|
+
height: 480
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'responds to path, format, size, width and height' do
|
17
|
+
expect(video.url).to eq 'https://www.youtube.com/watch?v=oHg5SJYRHA0'
|
18
|
+
expect(video.provider_url).to eq 'https://www.youtube.com'
|
19
|
+
expect(video.thumbnail_url).to eq 'http://i3.ytimg.com/vi/oHg5SJYRHA0/hqdefault.jpg'
|
20
|
+
expect(video.title).to eq "RickRoll'D"
|
21
|
+
expect(video.width).to eq 640
|
22
|
+
expect(video.height).to eq 480
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'iframe_embed' do
|
26
|
+
it 'returns a iframe embed HTML fragment' do
|
27
|
+
expect(video.iframe_embed).to eq '<iframe width="560" height="315" src="http://www.youtube.com/embed/oHg5SJYRHA0?rel=0" frameborder="0" allowfullscreen></iframe>'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'dato/json_api_entity'
|
2
|
+
|
3
|
+
module Dato
|
4
|
+
RSpec.describe JsonApiEntity do
|
5
|
+
subject(:object) { described_class.new(payload, data_source) }
|
6
|
+
let(:payload) do
|
7
|
+
{
|
8
|
+
id: 'peter',
|
9
|
+
type: 'person',
|
10
|
+
attributes: {
|
11
|
+
first_name: 'Peter',
|
12
|
+
last_name: 'Griffin'
|
13
|
+
},
|
14
|
+
relationships: {
|
15
|
+
children: {
|
16
|
+
data: [
|
17
|
+
{ type: 'person', id: 'stewie' }
|
18
|
+
]
|
19
|
+
},
|
20
|
+
mother: {
|
21
|
+
data: { type: 'person', id: 'thelma' }
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:data_source) do
|
28
|
+
instance_double('Dato::DataSource')
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#id' do
|
32
|
+
it 'returns the object ID' do
|
33
|
+
expect(object.id).to eq 'peter'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#type' do
|
38
|
+
it 'returns the object type' do
|
39
|
+
expect(object.type).to eq 'person'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'attributes' do
|
44
|
+
it 'returns the attribute if it exists' do
|
45
|
+
expect(object.respond_to?(:first_name)).to be_truthy
|
46
|
+
expect(object.first_name).to eq 'Peter'
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns NoMethodError if it doesnt' do
|
50
|
+
expect(object.respond_to?(:foo_bar)).to be_falsy
|
51
|
+
expect { object.foo_bar }.to raise_error NoMethodError
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '[]' do
|
56
|
+
it 'returns the attribute if it exists' do
|
57
|
+
expect(object[:first_name]).to eq 'Peter'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'returns nil if it doesnt' do
|
61
|
+
expect(object[:foo_bar]).to be_nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '==' do
|
66
|
+
context 'same id and type' do
|
67
|
+
let(:other) do
|
68
|
+
described_class.new({ id: 'peter', type: 'person' }, data_source)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'returns true' do
|
72
|
+
expect(object == other).to be_truthy
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'different id and type' do
|
77
|
+
let(:other) do
|
78
|
+
described_class.new({ id: 'stewie', type: 'person' }, data_source)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'returns false' do
|
82
|
+
expect(object == other).to be_falsy
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'different class' do
|
87
|
+
let(:other) do
|
88
|
+
12
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'returns false' do
|
92
|
+
expect(object == other).to be_falsy
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe 'links' do
|
98
|
+
let(:stewie) { instance_double('Dato::JsonApiObject') }
|
99
|
+
let(:thelma) { instance_double('Dato::JsonApiObject') }
|
100
|
+
|
101
|
+
before do
|
102
|
+
allow(data_source).to receive(:find_entity).with('person', 'stewie') { stewie }
|
103
|
+
allow(data_source).to receive(:find_entity).with('person', 'thelma') { thelma }
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'multiple linkages' do
|
107
|
+
it 'returns the array of JsonApiObjects' do
|
108
|
+
expect(object.children).to eq [stewie]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'single linkage' do
|
113
|
+
it 'returns the JsonApiObject' do
|
114
|
+
expect(object.mother).to eq thelma
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'returns NoMethodError if it does not exist' do
|
119
|
+
expect { object.father }.to raise_error NoMethodError
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -1,19 +1,21 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
module Dato
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
module Dato
|
4
|
+
module MetaTags
|
5
|
+
RSpec.describe ArticleModifiedTime do
|
6
|
+
subject(:meta_tag) { described_class.new(builder, base_url, space, record) }
|
7
|
+
let(:builder) { ::MockBuilder.new }
|
8
|
+
let(:base_url) { nil }
|
9
|
+
let(:space) { nil }
|
10
|
+
let(:record) do
|
11
|
+
double('Record', updated_at: Time.now, singleton?: false)
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
describe '.value' do
|
15
|
+
context 'if record is not singleton' do
|
16
|
+
it 'returns an ISO 8601 time representation' do
|
17
|
+
expect(meta_tag.value).not_to be_nil
|
18
|
+
end
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dato
|
4
|
+
module MetaTags
|
5
|
+
RSpec.describe Image do
|
6
|
+
subject(:meta_tag) { described_class.new(builder, base_url, space, record) }
|
7
|
+
let(:builder) { ::MockBuilder.new }
|
8
|
+
let(:base_url) { nil }
|
9
|
+
let(:space) { nil }
|
10
|
+
let(:record) do
|
11
|
+
double(
|
12
|
+
'Dato::Record',
|
13
|
+
fields: [double('Dato::JsonApiEntity', api_key: 'foo', field_type: 'image')],
|
14
|
+
foo: image,
|
15
|
+
singleton?: false
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:field) do
|
20
|
+
{ field_type: 'image' }
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:image) do
|
24
|
+
double(
|
25
|
+
'Dato::JsonApiEntity',
|
26
|
+
width: 300,
|
27
|
+
height: 300,
|
28
|
+
file: double('File', format: double('Imgix', to_url: 'http://google.com'))
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '.value' do
|
33
|
+
it 'returns the current locale' do
|
34
|
+
expect(meta_tag.image).to eq 'http://google.com'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,17 +1,19 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
module Dato
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
module Dato
|
4
|
+
module MetaTags
|
5
|
+
RSpec.describe OgLocale do
|
6
|
+
subject(:meta_tag) { described_class.new(builder, base_url, space, record) }
|
7
|
+
let(:builder) { ::MockBuilder.new }
|
8
|
+
let(:base_url) { nil }
|
9
|
+
let(:space) { nil }
|
10
|
+
let(:record) { nil }
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
describe '#value' do
|
13
|
+
it 'returns the current locale' do
|
14
|
+
I18n.with_locale(:it) do
|
15
|
+
expect(meta_tag.value).to eq 'it_IT'
|
16
|
+
end
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
data/spec/dato/record_spec.rb
CHANGED
@@ -1,103 +1,162 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
1
|
+
module Dato
|
2
|
+
RSpec.describe Record do
|
3
|
+
subject(:record) { described_class.new(entity, repo) }
|
4
|
+
let(:entity) do
|
5
|
+
double(
|
6
|
+
'Dato::JsonApiEntity(Record)',
|
7
|
+
id: '14',
|
8
|
+
content_type: content_type,
|
9
|
+
title: "My titlè with àccents",
|
10
|
+
body: 'Hi there',
|
11
|
+
position: 2,
|
12
|
+
updated_at: '2010-01-01T00:00'
|
13
|
+
)
|
14
|
+
end
|
15
|
+
let(:repo) do
|
16
|
+
instance_double('Dato::RecordsRepo')
|
17
|
+
end
|
18
|
+
let(:content_type) do
|
19
|
+
double(
|
20
|
+
'Dato::JsonApiEntity(Content Type)',
|
21
|
+
singleton: is_singleton,
|
22
|
+
api_key: 'work_item',
|
23
|
+
fields: fields
|
24
|
+
)
|
25
|
+
end
|
26
|
+
let(:is_singleton) { false }
|
27
|
+
let(:fields) do
|
28
|
+
[
|
29
|
+
double(
|
30
|
+
'Dato::JsonApiEntity(Field)',
|
31
|
+
position: 1,
|
32
|
+
api_key: 'title',
|
33
|
+
localized: false,
|
34
|
+
field_type: 'string',
|
35
|
+
appeareance: { type: 'title' }
|
36
|
+
),
|
37
|
+
double(
|
38
|
+
'Dato::JsonApiEntity(Field)',
|
39
|
+
position: 1,
|
40
|
+
api_key: 'body',
|
41
|
+
localized: false,
|
42
|
+
field_type: 'text',
|
43
|
+
appeareance: { type: 'plain' }
|
44
|
+
)
|
45
|
+
]
|
19
46
|
end
|
20
47
|
|
21
|
-
|
22
|
-
|
48
|
+
describe '#slug' do
|
49
|
+
context 'singleton' do
|
50
|
+
let(:is_singleton) { true }
|
23
51
|
|
24
|
-
|
25
|
-
|
52
|
+
it 'returns the parameterized content type api key' do
|
53
|
+
expect(record.slug).to eq 'work-item'
|
54
|
+
end
|
26
55
|
end
|
27
|
-
end
|
28
|
-
end
|
29
56
|
|
30
|
-
|
31
|
-
|
57
|
+
context 'non singleton, no title field' do
|
58
|
+
let(:fields) { [] }
|
32
59
|
|
33
|
-
|
34
|
-
|
35
|
-
|
60
|
+
it 'returns the ID' do
|
61
|
+
expect(record.slug).to eq '14'
|
62
|
+
end
|
36
63
|
end
|
37
|
-
end
|
38
64
|
|
39
|
-
|
40
|
-
|
41
|
-
|
65
|
+
context 'non singleton, title field' do
|
66
|
+
it 'returns the ID + title' do
|
67
|
+
expect(record.slug).to eq '14-my-title-with-accents'
|
68
|
+
end
|
42
69
|
end
|
43
70
|
end
|
44
|
-
end
|
45
|
-
|
46
|
-
describe "#id" do
|
47
|
-
let(:attributes) { { id: 123 } }
|
48
71
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
describe "#updated_at" do
|
55
|
-
let(:attributes) { { updated_at: "2015-06-09T12:47" } }
|
56
|
-
|
57
|
-
it "parses the field and returns a Time object" do
|
58
|
-
expect(record.updated_at).to eq(Time.new(2015, 6, 9, 12, 47))
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe "#slug" do
|
63
|
-
let(:attributes) { { id: 1, title: "Foo Bar" } }
|
64
|
-
|
65
|
-
context 'if there is a "title" field' do
|
66
|
-
let(:content_type) { { fields: { title: { field_type: "title" } } } }
|
67
|
-
|
68
|
-
it "retuns the slug of the record" do
|
69
|
-
expect(record.slug).to eq("1-foo-bar")
|
72
|
+
describe '#attributes' do
|
73
|
+
it 'returns an hash of the field values' do
|
74
|
+
expected_attributes = { title: "My titlè with àccents", body: 'Hi there' }
|
75
|
+
expect(record.attributes).to eq expected_attributes
|
70
76
|
end
|
71
77
|
end
|
72
78
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
it "returns nil" do
|
77
|
-
expect(record.slug).to be_nil
|
79
|
+
describe 'position' do
|
80
|
+
it 'returns the entity position field' do
|
81
|
+
expect(record.position).to eq 2
|
78
82
|
end
|
79
83
|
end
|
80
|
-
end
|
81
|
-
|
82
|
-
describe "#method_missing" do
|
83
|
-
let(:content_type) { { fields: { foo: { field_type: "text" } } } }
|
84
|
-
let(:attributes) { { foo: "bar" } }
|
85
84
|
|
86
|
-
|
87
|
-
|
85
|
+
describe 'updated_at' do
|
86
|
+
it 'returns the entity updated_at field' do
|
87
|
+
expect(record.updated_at).to be_a Time
|
88
|
+
end
|
88
89
|
end
|
89
90
|
|
90
|
-
|
91
|
-
|
91
|
+
describe 'dynamic methods' do
|
92
|
+
context 'existing field' do
|
93
|
+
it 'returns the field value' do
|
94
|
+
expect(record.respond_to?(:body)).to be_truthy
|
95
|
+
expect(record.body).to eq 'Hi there'
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'localized field' do
|
99
|
+
let(:entity) do
|
100
|
+
double(
|
101
|
+
'Dato::JsonApiEntity(Record)',
|
102
|
+
id: '14',
|
103
|
+
content_type: content_type,
|
104
|
+
title: { it: 'Foo', en: 'Bar' }
|
105
|
+
)
|
106
|
+
end
|
107
|
+
|
108
|
+
let(:fields) do
|
109
|
+
[
|
110
|
+
double(
|
111
|
+
'Dato::JsonApiEntity(Field)',
|
112
|
+
position: 1,
|
113
|
+
api_key: 'title',
|
114
|
+
localized: true,
|
115
|
+
field_type: 'string',
|
116
|
+
appeareance: { type: 'plain' }
|
117
|
+
)
|
118
|
+
]
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'returns the value for the current locale' do
|
122
|
+
I18n.with_locale(:it) do
|
123
|
+
expect(record.title).to eq 'Foo'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'non existing value' do
|
128
|
+
it 'raises nil' do
|
129
|
+
I18n.with_locale(:ru) do
|
130
|
+
expect(record.title).to eq nil
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
92
136
|
|
93
|
-
|
94
|
-
|
137
|
+
context 'non existing field' do
|
138
|
+
it 'raises NoMethodError' do
|
139
|
+
expect(record.respond_to?(:qux)).to be_falsy
|
140
|
+
expect { record.qux }.to raise_error NoMethodError
|
141
|
+
end
|
95
142
|
end
|
96
|
-
end
|
97
143
|
|
98
|
-
|
99
|
-
|
100
|
-
|
144
|
+
context 'non existing field type' do
|
145
|
+
let(:fields) do
|
146
|
+
[
|
147
|
+
double(
|
148
|
+
'Dato::JsonApiEntity(Field)',
|
149
|
+
position: 1,
|
150
|
+
api_key: 'title',
|
151
|
+
localized: true,
|
152
|
+
field_type: 'rotfl'
|
153
|
+
)
|
154
|
+
]
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'raises RuntimeError' do
|
158
|
+
expect { record.title }.to raise_error RuntimeError
|
159
|
+
end
|
101
160
|
end
|
102
161
|
end
|
103
162
|
end
|