jsonapi-materializer 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2f61a86bda571eb041aa543a16338d80c82b742708f90be0c321e45f27eb97e
4
- data.tar.gz: fb22fbb7a3998c2ca6563c85a65b12980fae019feb96972523850c8074160485
3
+ metadata.gz: 9556e194a2e69b081bad43a8ddfbab23c55b9707a2250598222854943118b50c
4
+ data.tar.gz: 14653444ae546e3f3ecb4a4611b9739e247538b82d032a475b7931fe8a97f2ef
5
5
  SHA512:
6
- metadata.gz: 1a27fc6d325e69296ae5ce9e73a21caf13194eba084b71f127a81574c63fe839cba0be3701b2be43f812efa7e9d22428f20891d46703eb30fe7d2cba73d2f3b8
7
- data.tar.gz: 7c661026d63ac185e4f7d01db31b83547945d3903c14775273dbe06b05455a57209286efc5237c764b26853c3a8bfe733c4064aa3b081e1fd38e287a675a36c3
6
+ metadata.gz: a0985c0cfcbdab3e5c6d6115838a3f30699e40a819cd4c00c2a58b9bf27181e5d5bce12d4da230e6d2c3ba9564df9e04a777a5086e5074c1bf6b757ff7b8d456
7
+ data.tar.gz: 82e6d60d6806c0d37c043bbe16783dacb9601eb9651c200decf078efc012292d87d36a605b55697e8c6ef8afeb0bc03bf300eca8104b1e707aadc4f18438e0d9
@@ -13,47 +13,18 @@ module JSONAPI
13
13
  attr_writer(:includes)
14
14
  attr_writer(:pagination)
15
15
 
16
- delegate(:first_page?, to: :object)
17
- delegate(:prev_page, to: :object)
18
- delegate(:total_pages, to: :object)
19
- delegate(:next_page, to: :object)
20
- delegate(:last_page?, to: :object)
21
- delegate(:limit_value, to: :object)
22
-
23
16
  def as_json(*)
24
17
  {
25
- links: if pagination
26
- {
27
- first: (links_pagination.expand(offset: 1, limit: limit_value).to_s unless total_pages.zero? || first_page?),
28
- prev: (links_pagination.expand(offset: prev_page, limit: limit_value).to_s unless total_pages.zero? || first_page?),
29
- self: (links_self unless total_pages.zero?),
30
- next: (links_pagination.expand(offset: next_page, limit: limit_value).to_s unless total_pages.zero? || last_page?),
31
- last: (links_pagination.expand(offset: total_pages, limit: limit_value).to_s unless total_pages.zero? || last_page?)
32
- }.compact
33
- else
34
- {}
35
- end,
36
- data: resources,
37
- included:
38
- }.transform_values(&:presence).compact
18
+ links: pagination,
19
+ included:,
20
+ meta:
21
+ }.transform_values(&:presence).compact.merge(data: resources)
39
22
  end
40
23
 
41
24
  private def materializers
42
25
  @materializers ||= object.map { |subobject| self.class.module_parent.new(object: subobject, selects:, includes:) }
43
26
  end
44
27
 
45
- private def links_pagination
46
- Addressable::Template.new(
47
- "#{origin}/#{type}?page[offset]={offset}&page[limit]={limit}"
48
- )
49
- end
50
-
51
- private def links_self
52
- Addressable::Template.new(
53
- "#{origin}/#{type}"
54
- ).pattern
55
- end
56
-
57
28
  private def origin
58
29
  self.class.module_parent.instance_variable_get(:@origin)
59
30
  end
@@ -74,6 +45,36 @@ module JSONAPI
74
45
  @includes || []
75
46
  end
76
47
 
48
+ private def pagination
49
+ if @pagination
50
+ {
51
+ first: (pagination_link_template.expand(offset: 1, limit: @pagination.in).to_s unless @pagination.pages.zero? || @pagination.prev.nil?),
52
+ prev: (pagination_link_template.expand(offset: @pagination.prev, limit: @pagination.in).to_s unless @pagination.pages.zero? || @pagination.prev.nil?),
53
+ self: (pagination_link_template.expand(offset: @pagination.page, limit: @pagination.in).to_s unless @pagination.pages.zero?),
54
+ next: (pagination_link_template.expand(offset: @pagination.next, limit: @pagination.in).to_s unless @pagination.pages.zero? || @pagination.next.nil?),
55
+ last: (pagination_link_template.expand(offset: @pagination.pages, limit: @pagination.in).to_s unless @pagination.pages.zero? || @pagination.next.nil?)
56
+ }.compact
57
+ else
58
+ {}
59
+ end
60
+ end
61
+
62
+ private def pagination_link_template
63
+ Addressable::Template.new(
64
+ "#{origin}/#{type}?page[offset]={offset}&page[limit]={limit}"
65
+ )
66
+ end
67
+
68
+ private def self_link_template
69
+ Addressable::Template.new(
70
+ "#{origin}/#{type}"
71
+ ).pattern
72
+ end
73
+
74
+ private def meta
75
+ {}
76
+ end
77
+
77
78
  private def included
78
79
  @included ||= materializers.flat_map do |materializer|
79
80
  includes.flat_map do |path|
@@ -85,9 +86,8 @@ module JSONAPI
85
86
  end
86
87
  end
87
88
  end
88
- end.uniq.map(&:as_data)
89
+ end.uniq.compact.map(&:as_data)
89
90
  end
90
- # rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
91
91
  end
92
92
  end
93
93
  end
@@ -2,9 +2,26 @@
2
2
 
3
3
  require("spec_helper")
4
4
 
5
+ PaginationAdapter = Struct.new(:in, :page, :pages, :prev, :next)
6
+
5
7
  RSpec.describe(JSONAPI::Materializer::Collection) do
6
8
  let(:described_class) { ArticleMaterializer::Collection }
7
- let(:collection) { described_class.new(object:, includes: [["comments"], ["author"]]) }
9
+ let(:collection) do
10
+ described_class.new(
11
+ object:,
12
+ includes: [["comments"], ["author"]],
13
+ pagination:
14
+ )
15
+ end
16
+ let(:pagination) do
17
+ PaginationAdapter.new(
18
+ 10, # items in page
19
+ 9, # current page
20
+ 10, # total pages
21
+ 100, # previous page
22
+ 80 # next page
23
+ )
24
+ end
8
25
 
9
26
  describe("#as_json") do
10
27
  subject { collection.as_json.deep_stringify_keys }
@@ -54,12 +71,84 @@ RSpec.describe(JSONAPI::Materializer::Collection) do
54
71
  }]))
55
72
  end
56
73
 
57
- it("has a links key at root with pagination") do
58
- expect(subject.fetch("links")).to(eq(
59
- "self" => "http://example.com/articles",
60
- "next" => "http://example.com/articles?page[offset]=2&page[limit]=1",
61
- "last" => "http://example.com/articles?page[offset]=3&page[limit]=1"
62
- ))
74
+ context("when on the first page") do
75
+ let(:pagination) do
76
+ PaginationAdapter.new(
77
+ 10, # items in page
78
+ 1, # current page
79
+ 10, # total pages
80
+ nil, # previous page
81
+ 2 # next page
82
+ )
83
+ end
84
+
85
+ it("has a links key at root with pagination") do
86
+ expect(subject.fetch("links")).to(eq(
87
+ "last" => "http://example.com/articles?page[offset]=10&page[limit]=10",
88
+ "next" => "http://example.com/articles?page[offset]=2&page[limit]=10",
89
+ "self" => "http://example.com/articles?page[offset]=1&page[limit]=10"
90
+ ))
91
+ end
92
+ end
93
+
94
+ context("when on the last page") do
95
+ let(:pagination) do
96
+ PaginationAdapter.new(
97
+ 10, # items in page
98
+ 10, # current page
99
+ 10, # total pages
100
+ 9, # previous page
101
+ nil # next page
102
+ )
103
+ end
104
+
105
+ it("has a links key at root with pagination") do
106
+ expect(subject.fetch("links")).to(eq(
107
+ "first" => "http://example.com/articles?page[offset]=1&page[limit]=10",
108
+ "prev" => "http://example.com/articles?page[offset]=9&page[limit]=10",
109
+ "self" => "http://example.com/articles?page[offset]=10&page[limit]=10"
110
+ ))
111
+ end
112
+ end
113
+
114
+ context("when on the middle page") do
115
+ let(:pagination) do
116
+ PaginationAdapter.new(
117
+ 10, # items in page
118
+ 5, # current page
119
+ 10, # total pages
120
+ 4, # previous page
121
+ 6 # next page
122
+ )
123
+ end
124
+
125
+ it("has a links key at root with pagination") do
126
+ expect(subject.fetch("links")).to(eq(
127
+ "first" => "http://example.com/articles?page[offset]=1&page[limit]=10",
128
+ "last" => "http://example.com/articles?page[offset]=10&page[limit]=10",
129
+ "next" => "http://example.com/articles?page[offset]=6&page[limit]=10",
130
+ "prev" => "http://example.com/articles?page[offset]=4&page[limit]=10",
131
+ "self" => "http://example.com/articles?page[offset]=5&page[limit]=10"
132
+ ))
133
+ end
134
+ end
135
+
136
+ context("when on the only page") do
137
+ let(:pagination) do
138
+ PaginationAdapter.new(
139
+ 10, # items in page
140
+ 1, # current page
141
+ 1, # total pages
142
+ nil, # previous page
143
+ nil # next page
144
+ )
145
+ end
146
+
147
+ it("has a links key at root with pagination") do
148
+ expect(subject.fetch("links")).to(eq(
149
+ "self" => "http://example.com/articles?page[offset]=1&page[limit]=10"
150
+ ))
151
+ end
63
152
  end
64
153
 
65
154
  it("has a included key at root with included models") do
@@ -45,7 +45,6 @@ module JSONAPI
45
45
  end
46
46
  end
47
47
  end
48
- # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
49
48
 
50
49
  def using(parent)
51
50
  Resource::Relationship.new(related: self, parent:)
@@ -24,8 +24,7 @@ module JSONAPI
24
24
  links: {
25
25
  self: links_self,
26
26
  related: links_related
27
- },
28
- meta: {}
27
+ }
29
28
  }.transform_values(&:presence).compact
30
29
  end
31
30
 
@@ -204,7 +204,7 @@ module JSONAPI
204
204
  subject.relation(key).for(subject)
205
205
  end
206
206
  end
207
- end.map(&:as_data)
207
+ end.compact.map(&:as_data)
208
208
  end
209
209
  end
210
210
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module JSONAPI
4
4
  module Materializer
5
- VERSION = "1.1.0"
5
+ VERSION = "2.0.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi-materializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kurtis Rainbolt-Greene
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-08 00:00:00.000000000 Z
11
+ date: 2023-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport