jsonapi-materializer 1.2.0 → 3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b51f422840742a6b80b48de2c10d75b2530a630d13e0caecb0c598f79089081e
4
- data.tar.gz: ffbf502f4377b1814cb6ba7c8f7d5b3cd01d792ccc4fa047ccd1e2c448f83f19
3
+ metadata.gz: c287ea52f8d9f995a5c91f7e50f6cba792bc4ca365e8ef812d7a469a1a61d194
4
+ data.tar.gz: 72cc3904868b56e90520245a839c269115a6dc506f8f06314f9315eac328657f
5
5
  SHA512:
6
- metadata.gz: 6bb8dc1d59f884f503c4e6f993c331a69d41b7e7619f34fa2296f5cb0597e82cf128d55f27b15f2523e6d7ea1c603ed4cb8abb87c65da3d78dd2197484e4348e
7
- data.tar.gz: 7689dec65ec8f3a81751c054345ae19e51d5ef1dd64245ce7bccc6226b373f168f69eeb1c51254f635a69d89e5ae70ea176eb708d98f7e234ef013a507c57756
6
+ metadata.gz: 544c4346e3d48c094efae3c518fcf3cb7dbd692b37b876a1e2cfc77d2af256ce07441999f207b9ca336e19621a44a5fdfe02358f88907b17c5949e613358f041
7
+ data.tar.gz: 34f5d566e30b8ac81fff03976c4a16a48cffdeaa858295553d12a051e936e79b273c4d42c77272c4d76b5f02009fa78987255f2b83422a793c2978fa0011ec77
@@ -13,13 +13,6 @@ 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
18
  links: pagination,
@@ -55,11 +48,11 @@ module JSONAPI
55
48
  private def pagination
56
49
  if @pagination
57
50
  {
58
- first: (pagination_link_template.expand(offset: 1, limit: limit_value).to_s unless total_pages.zero? || first_page?),
59
- prev: (pagination_link_template.expand(offset: prev_page, limit: limit_value).to_s unless total_pages.zero? || first_page?),
60
- self: (self_link_template unless total_pages.zero?),
61
- next: (pagination_link_template.expand(offset: next_page, limit: limit_value).to_s unless total_pages.zero? || last_page?),
62
- last: (pagination_link_template.expand(offset: total_pages, limit: limit_value).to_s unless total_pages.zero? || last_page?)
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?)
63
56
  }.compact
64
57
  else
65
58
  {}
@@ -93,9 +86,8 @@ module JSONAPI
93
86
  end
94
87
  end
95
88
  end
96
- end.uniq.map(&:as_data)
89
+ end.uniq.compact.map(&:as_data)
97
90
  end
98
- # rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
99
91
  end
100
92
  end
101
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
@@ -37,15 +37,14 @@ module JSONAPI
37
37
  )
38
38
  end
39
39
  when :one
40
- if fetch_relation(subject).present?
41
- materializer_class.new(
42
- **subject.raw,
43
- object: fetch_relation(subject)
44
- )
45
- end
40
+ raise StandardError, "couldn't find a relationship by the name #{from} on #{subject.class}" unless fetch_relation(subject).present?
41
+
42
+ materializer_class.new(
43
+ **subject.raw,
44
+ object: fetch_relation(subject)
45
+ )
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:)
@@ -60,8 +59,8 @@ module JSONAPI
60
59
  end
61
60
 
62
61
  private def fetch_relation(subject)
63
- @fetch_relationship ||= {}
64
- @fetch_relationship[checksum(subject)] ||= subject.object.public_send(from)
62
+ @fetch_relationships ||= {}
63
+ @fetch_relationships[checksum(subject)] ||= subject.object.public_send(from)
65
64
  end
66
65
 
67
66
  private def materializer_class
@@ -44,27 +44,31 @@ module JSONAPI
44
44
 
45
45
  def as_data
46
46
  {
47
- id:,
48
- type:,
49
47
  attributes: exposed(attributes.except(:id))
50
48
  .transform_values { |attribute| object.public_send(attribute.from) },
51
- relationships: exposed(relations)
52
- .transform_values { |relation| relation.using(self).as_json },
49
+ relationships: relations
50
+ .transform_values { |relation| relation.using(self).as_json }
51
+ }.transform_values(&:presence).compact.merge(
52
+ id:,
53
+ type:,
53
54
  links: {
54
55
  self: links_self
56
+ # TODO: Add more links
55
57
  }
56
- }.transform_values(&:presence).compact
58
+ )
57
59
  end
58
60
  # rubocop:enable Metrics/AbcSize
59
61
 
60
62
  def as_json(*)
61
63
  {
64
+ included:
65
+ }.transform_values(&:presence).compact.merge(
66
+ data: as_data,
62
67
  links: {
63
68
  self: links_self
64
- },
65
- data: as_data,
66
- included:
67
- }.transform_values(&:presence).compact
69
+ # TODO: Add more links
70
+ }
71
+ )
68
72
  end
69
73
 
70
74
  def type
@@ -204,7 +208,7 @@ module JSONAPI
204
208
  subject.relation(key).for(subject)
205
209
  end
206
210
  end
207
- end.map(&:as_data)
211
+ end.compact.map(&:as_data)
208
212
  end
209
213
  end
210
214
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module JSONAPI
4
4
  module Materializer
5
- VERSION = "1.2.0"
5
+ VERSION = "3.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.2.0
4
+ version: 3.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-18 00:00:00.000000000 Z
11
+ date: 2023-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport