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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +7 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +9 -1070
  5. data/Gemfile +8 -8
  6. data/Rakefile +14 -5
  7. data/foo.rb +12 -0
  8. data/lib/dato/client.rb +14 -9
  9. data/lib/dato/entities_repo.rb +43 -0
  10. data/lib/dato/field_type/boolean.rb +9 -0
  11. data/lib/dato/field_type/date.rb +9 -0
  12. data/lib/dato/field_type/date_time.rb +9 -0
  13. data/lib/dato/field_type/file.rb +30 -0
  14. data/lib/dato/field_type/float.rb +9 -0
  15. data/lib/dato/field_type/image.rb +23 -0
  16. data/lib/dato/field_type/integer.rb +9 -0
  17. data/lib/dato/field_type/lat_lon.rb +16 -0
  18. data/lib/dato/field_type/link.rb +9 -0
  19. data/lib/dato/field_type/links.rb +9 -0
  20. data/lib/dato/field_type/seo.rb +21 -0
  21. data/lib/dato/field_type/string.rb +9 -0
  22. data/lib/dato/field_type/text.rb +9 -0
  23. data/lib/dato/field_type/video.rb +48 -0
  24. data/lib/dato/json_api_entity.rb +75 -0
  25. data/lib/dato/meta_tags/article_modified_time.rb +3 -3
  26. data/lib/dato/meta_tags/article_publisher.rb +3 -3
  27. data/lib/dato/meta_tags/base.rb +12 -19
  28. data/lib/dato/meta_tags/description.rb +4 -4
  29. data/lib/dato/meta_tags/image.rb +5 -8
  30. data/lib/dato/meta_tags/og_locale.rb +2 -2
  31. data/lib/dato/meta_tags/og_meta_tag.rb +2 -4
  32. data/lib/dato/meta_tags/og_site_name.rb +2 -2
  33. data/lib/dato/meta_tags/og_type.rb +5 -5
  34. data/lib/dato/meta_tags/robots.rb +2 -4
  35. data/lib/dato/meta_tags/title.rb +5 -4
  36. data/lib/dato/meta_tags/twitter_card.rb +3 -3
  37. data/lib/dato/meta_tags/twitter_meta_tag.rb +2 -4
  38. data/lib/dato/meta_tags/twitter_site.rb +2 -2
  39. data/lib/dato/meta_tags/url.rb +4 -4
  40. data/lib/dato/meta_tags_builder.rb +13 -13
  41. data/lib/dato/middleman_extension.rb +15 -23
  42. data/lib/dato/record.rb +77 -46
  43. data/lib/dato/records_repo.rb +106 -0
  44. data/lib/dato/space.rb +36 -0
  45. data/lib/middleman-dato.rb +5 -2
  46. data/middleman-dato.gemspec +14 -13
  47. data/spec/dato/entities_repo_spec.rb +41 -0
  48. data/spec/dato/field_type/file_spec.rb +20 -0
  49. data/spec/dato/field_type/image_spec.rb +24 -0
  50. data/spec/dato/field_type/lat_lon_spec.rb +18 -0
  51. data/spec/dato/field_type/seo_spec.rb +31 -0
  52. data/spec/dato/field_type/video_spec.rb +32 -0
  53. data/spec/dato/json_api_entity_spec.rb +123 -0
  54. data/spec/dato/meta_tags/article_modified_time_spec.rb +16 -14
  55. data/spec/dato/meta_tags/image_spec.rb +39 -0
  56. data/spec/dato/meta_tags/og_locale_spec.rb +14 -12
  57. data/spec/dato/record_spec.rb +137 -78
  58. data/spec/dato/records_repo_spec.rb +125 -0
  59. data/spec/spec_helper.rb +14 -12
  60. metadata +58 -13
  61. data/lib/dato/field.rb +0 -43
  62. data/lib/dato/fields/belongs_to.rb +0 -21
  63. data/lib/dato/fields/file.rb +0 -22
  64. data/lib/dato/fields/seo.rb +0 -37
  65. data/lib/dato/repo.rb +0 -111
  66. data/lib/middleman_extension.rb +0 -1
  67. 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 "spec_helper"
1
+ require 'spec_helper'
2
2
 
3
- module Dato::MetaTags
4
- RSpec.describe ArticleModifiedTime do
5
- subject(:meta_tag) { described_class.new(builder, base_url, space, record) }
6
- let(:builder) { MockBuilder.new }
7
- let(:base_url) { nil }
8
- let(:space) { nil }
9
- let(:record) do
10
- double("Record", updated_at: Time.now, singleton?: false)
11
- end
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
- describe ".value" do
14
- context "if record is not singleton" do
15
- it "returns an ISO 8601 time representation" do
16
- expect(meta_tag.value).not_to be_nil
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 "spec_helper"
1
+ require 'spec_helper'
2
2
 
3
- module Dato::MetaTags
4
- RSpec.describe OgLocale do
5
- subject(:meta_tag) { described_class.new(builder, base_url, space, record) }
6
- let(:builder) { MockBuilder.new }
7
- let(:base_url) { nil }
8
- let(:space) { nil }
9
- let(:record) { nil }
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
- describe ".value" do
12
- it "returns the current locale" do
13
- I18n.with_locale(:it) do
14
- expect(meta_tag.value).to eq "it_IT"
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
@@ -1,103 +1,162 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe Dato::Record do
4
- subject(:record) { described_class.new(attributes, content_type) }
5
- let(:attributes) { {} }
6
- let(:content_type) { { fields: {} } }
7
-
8
- it "gets attributes and content type as constructor parameters" do
9
- record
10
- end
11
-
12
- describe "#singleton?" do
13
- context "if the record is a singleton" do
14
- let(:content_type) { { fields: {}, singleton: true } }
15
-
16
- it "returns true" do
17
- expect(record.singleton?).to eq(true)
18
- end
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
- context "else" do
22
- let(:content_type) { { fields: {}, singleton: false } }
48
+ describe '#slug' do
49
+ context 'singleton' do
50
+ let(:is_singleton) { true }
23
51
 
24
- it "returns false" do
25
- expect(record.singleton?).to eq(false)
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
- describe "#respond_to?" do
31
- let(:attributes) { { foo: "bar" } }
57
+ context 'non singleton, no title field' do
58
+ let(:fields) { [] }
32
59
 
33
- context "if the record contains the requested field" do
34
- it "returns true" do
35
- expect(record.respond_to?(:foo)).to eq(true)
60
+ it 'returns the ID' do
61
+ expect(record.slug).to eq '14'
62
+ end
36
63
  end
37
- end
38
64
 
39
- context "else" do
40
- it "returns true" do
41
- expect(record.respond_to?(:bar)).to eq(false)
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
- it "returns the id of the record" do
50
- expect(record.id).to eq(123)
51
- end
52
- end
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
- context "else" do
74
- let(:content_type) { { fields: { title: { field_type: "text" } } } }
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
- before do
87
- allow(Dato::Field).to receive(:value).and_return("bar")
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
- context "if the requested method matches one attribute" do
91
- before { record.foo }
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
- it 'calls the ".value" method of "Field" class' do
94
- expect(Dato::Field).to have_received(:value).with(attributes[:foo], content_type[:fields][:foo])
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
- context "if the same attribute is requested multiple times" do
99
- it "returns the same object" do
100
- expect(record.foo.object_id).to eq(record.foo.object_id)
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