Skip to content

Commit c65905c

Browse files
yndajasGweaton
andcommitted
Implement GraphQL Edition type withdrawn_notice
Currently content items for non-withdrawn editions will include an empty object for the `withdrawn_notice`. We opted to return `nil` instead, which feels more conventional (for APIs in general) and is also the [recommended way of doing things in GraphQL][1]. Implementing an empty object in GraphQL requires some fairly [hacky code][2]. We'll need to ensure that consumers can handle this field being `nil` before any move to use the GraphQL endpoint in production [1]: https://spec.graphql.org/draft/#sel-HAHZhCFBABPBT5pS [2]: graphql/graphql-spec#568 (comment) Co-authored-by: George <[email protected]>
1 parent 0d57f2c commit c65905c

File tree

3 files changed

+91
-5
lines changed

3 files changed

+91
-5
lines changed

app/graphql/types/edition_type.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
module Types
44
class EditionType < Types::BaseObject
5+
class WithdrawnNotice < Types::BaseObject
6+
field :explanation, String
7+
field :withdrawn_at, GraphQL::Types::ISO8601DateTime
8+
end
9+
510
field :analytics_identifier, String
611
field :base_path, String
712
field :content_id, ID
@@ -20,7 +25,16 @@ class EditionType < Types::BaseObject
2025
field :schema_name, String
2126
field :title, String, null: false
2227
field :updated_at, GraphQL::Types::ISO8601DateTime
23-
field :withdrawn_notice, String
28+
field :withdrawn_notice, WithdrawnNotice
29+
30+
def withdrawn_notice
31+
return nil unless object.unpublishing&.withdrawal?
32+
33+
Presenters::EditionPresenter
34+
.new(object)
35+
.present
36+
.fetch(:withdrawn_notice)
37+
end
2438

2539
# Aliased by field methods for fields that are currently presented in the
2640
# content item, but come from Content Store, so we can't provide them here
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
RSpec.describe "Types::EditionType" do
2+
include GraphQL::Testing::Helpers.for(PublishingApiSchema)
3+
4+
describe "#withdrawn_notice" do
5+
context "when the edition is withdrawn" do
6+
it "returns a withdrawal notice" do
7+
edition = create(:withdrawn_unpublished_edition, explanation: "for testing", unpublished_at: "2024-10-28 17:00:00.000000000 +0000")
8+
expected = {
9+
explanation: "for testing",
10+
withdrawn_at: "2024-10-28T17:00:00Z",
11+
}
12+
13+
expect(
14+
run_graphql_field(
15+
"Edition.withdrawnNotice",
16+
edition,
17+
),
18+
).to eq(expected)
19+
end
20+
end
21+
22+
context "when the edition is not withdrawn" do
23+
it "returns nil" do
24+
expect(
25+
run_graphql_field(
26+
"Edition.withdrawnNotice",
27+
create(:edition),
28+
),
29+
).to be_nil
30+
end
31+
end
32+
end
33+
end

spec/integration/graphql_spec.rb

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,7 @@
5959
"schemaName": @edition.schema_name,
6060
"title": @edition.title,
6161
"updatedAt": @edition.updated_at.iso8601,
62-
"withdrawnNotice": {
63-
"explanation": nil,
64-
"withdrawnAt": nil,
65-
},
62+
"withdrawnNotice": nil,
6663
},
6764
},
6865
}
@@ -72,6 +69,48 @@
7269
expect(parsed_response).to eq(expected)
7370
end
7471

72+
context "when there is a withdrawn notice" do
73+
before do
74+
create(
75+
:withdrawn_unpublished_edition,
76+
base_path: "/my/withdrawn/edition",
77+
explanation: "for integration testing",
78+
unpublished_at: "2024-10-27 17:00:00.000000000 +0000",
79+
)
80+
end
81+
82+
it "populates the withdrawn notice" do
83+
post "/graphql", params: {
84+
query:
85+
"{
86+
edition(basePath: \"/my/withdrawn/edition\") {
87+
... on Edition {
88+
withdrawnNotice {
89+
explanation
90+
withdrawnAt
91+
}
92+
}
93+
}
94+
}",
95+
}
96+
97+
expected = {
98+
"data": {
99+
"edition": {
100+
"withdrawnNotice": {
101+
"explanation": "for integration testing",
102+
"withdrawnAt": "2024-10-27T17:00:00Z",
103+
},
104+
},
105+
},
106+
}
107+
108+
parsed_response = JSON.parse(response.body).deep_symbolize_keys
109+
110+
expect(parsed_response).to eq(expected)
111+
end
112+
end
113+
75114
it "does not expose non-generic edition fields" do
76115
post "/graphql", params: {
77116
query:

0 commit comments

Comments
 (0)