hq-graphql 0.0.2 → 1.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 +4 -4
- data/README.md +93 -7
- data/lib/hq/graphql/active_record_extensions.rb +125 -0
- data/lib/hq/graphql/input_extensions.rb +56 -0
- data/lib/hq/graphql/input_object.rb +17 -0
- data/lib/hq/graphql/inputs.rb +32 -0
- data/lib/hq/graphql/mutation.rb +13 -0
- data/lib/hq/graphql/object.rb +11 -77
- data/lib/hq/graphql/resource/mutation.rb +32 -0
- data/lib/hq/graphql/resource.rb +199 -0
- data/lib/hq/graphql/root_mutation.rb +20 -0
- data/lib/hq/graphql/root_query.rb +29 -0
- data/lib/hq/graphql/scalars.rb +9 -0
- data/lib/hq/graphql/types/uuid.rb +3 -3
- data/lib/hq/graphql/types.rb +14 -22
- data/lib/hq/graphql/version.rb +1 -1
- data/lib/hq/graphql.rb +27 -11
- data/spec/internal/db/schema.rb +2 -2
- data/spec/lib/graphql/active_record_extensions_spec.rb +63 -0
- data/spec/lib/graphql/inputs_spec.rb +40 -0
- data/spec/lib/graphql/mutation_spec.rb +173 -0
- data/spec/lib/graphql/object_spec.rb +173 -0
- data/spec/lib/graphql/resource_spec.rb +374 -0
- data/spec/lib/graphql/types/uuid_spec.rb +65 -0
- data/spec/lib/graphql/types_spec.rb +40 -0
- data/spec/rails_helper.rb +2 -0
- metadata +28 -14
- data/spec/internal/app/graphql/query.rb +0 -18
- data/spec/internal/app/graphql/schema.rb +0 -3
- data/spec/internal/app/graphql/user_type.rb +0 -3
- data/spec/lib/object_spec.rb +0 -198
- data/spec/lib/types_spec.rb +0 -60
data/spec/lib/object_spec.rb
DELETED
@@ -1,198 +0,0 @@
|
|
1
|
-
require 'rails_helper'
|
2
|
-
|
3
|
-
describe ::HQ::GraphQL::Object do
|
4
|
-
|
5
|
-
describe ".lazy_load" do
|
6
|
-
let(:lazy_load_class) do
|
7
|
-
Class.new(described_class) do
|
8
|
-
graphql_name "LazyLoadQuery"
|
9
|
-
|
10
|
-
@counter = 0
|
11
|
-
|
12
|
-
lazy_load do
|
13
|
-
@counter += 1
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.counter
|
17
|
-
@counter
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
it "lazy loads once" do
|
23
|
-
# First time it works
|
24
|
-
expect { lazy_load_class.to_graphql }.to change { lazy_load_class.counter }.by(1)
|
25
|
-
# Second time it does nothing
|
26
|
-
expect { lazy_load_class.to_graphql }.to change { lazy_load_class.counter }.by(0)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe ".with_model" do
|
31
|
-
let(:hql_object_klass) do
|
32
|
-
Class.new(described_class) do
|
33
|
-
graphql_name "TestQuery"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
it "adds everything by default" do
|
38
|
-
hql_object_klass.class_eval do
|
39
|
-
with_model "Advisor"
|
40
|
-
end
|
41
|
-
|
42
|
-
expect(hql_object_klass.fields.keys).to be_empty
|
43
|
-
hql_object_klass.to_graphql
|
44
|
-
expected = ["createdAt", "id", "name", "organization", "organizationId", "updatedAt"]
|
45
|
-
expect(hql_object_klass.fields.keys).to contain_exactly(*expected)
|
46
|
-
end
|
47
|
-
|
48
|
-
it "removes an attribute" do
|
49
|
-
hql_object_klass.class_eval do
|
50
|
-
remove_attrs :created_at, :id, :organization_id
|
51
|
-
with_model "Advisor"
|
52
|
-
end
|
53
|
-
|
54
|
-
expect(hql_object_klass.fields.keys).to be_empty
|
55
|
-
hql_object_klass.to_graphql
|
56
|
-
expected = ["name", "organization", "updatedAt"]
|
57
|
-
expect(hql_object_klass.fields.keys).to contain_exactly(*expected)
|
58
|
-
end
|
59
|
-
|
60
|
-
it "removes an association" do
|
61
|
-
hql_object_klass.class_eval do
|
62
|
-
remove_associations :organization, :doesntexist
|
63
|
-
with_model "Advisor"
|
64
|
-
end
|
65
|
-
|
66
|
-
expect(hql_object_klass.fields.keys).to be_empty
|
67
|
-
hql_object_klass.to_graphql
|
68
|
-
expected = ["createdAt", "id", "name", "organizationId", "updatedAt"]
|
69
|
-
expect(hql_object_klass.fields.keys).to contain_exactly(*expected)
|
70
|
-
end
|
71
|
-
|
72
|
-
context "with attributes and associations turned off" do
|
73
|
-
it "doesn't have any fields by default" do
|
74
|
-
hql_object_klass.to_graphql
|
75
|
-
expect(hql_object_klass.fields.keys).to be_empty
|
76
|
-
end
|
77
|
-
|
78
|
-
it "doesn't have any fields when disabling model attrs/associations" do
|
79
|
-
hql_object_klass.class_eval do
|
80
|
-
with_model "Advisor", attributes: false, associations: false
|
81
|
-
end
|
82
|
-
hql_object_klass.to_graphql
|
83
|
-
expect(hql_object_klass.fields.keys).to be_empty
|
84
|
-
end
|
85
|
-
|
86
|
-
it "blows up when adding an attribute to an object without a model" do
|
87
|
-
hql_object_klass.class_eval do
|
88
|
-
add_attr :name
|
89
|
-
end
|
90
|
-
|
91
|
-
expect { hql_object_klass.to_graphql }.to raise_error(described_class::Error)
|
92
|
-
end
|
93
|
-
|
94
|
-
it "blows up when adding an attribute that doesn't exist" do
|
95
|
-
hql_object_klass.class_eval do
|
96
|
-
add_attr :doesnt_exist
|
97
|
-
|
98
|
-
with_model "Advisor", attributes: false, associations: false
|
99
|
-
end
|
100
|
-
|
101
|
-
expect { hql_object_klass.to_graphql }.to raise_error(described_class::Error)
|
102
|
-
end
|
103
|
-
|
104
|
-
it "adds attributes once connected to a model" do
|
105
|
-
hql_object_klass.class_eval do
|
106
|
-
# Order shouldn't matter....but let's test it anyway
|
107
|
-
|
108
|
-
# First
|
109
|
-
add_attr :name
|
110
|
-
|
111
|
-
# Second
|
112
|
-
with_model "Advisor", attributes: false, associations: false
|
113
|
-
end
|
114
|
-
|
115
|
-
expect(hql_object_klass.fields.keys).to be_empty
|
116
|
-
hql_object_klass.to_graphql
|
117
|
-
expect(hql_object_klass.fields.keys).to contain_exactly("name")
|
118
|
-
end
|
119
|
-
|
120
|
-
it "blows up when adding an association to an object without a model" do
|
121
|
-
hql_object_klass.class_eval do
|
122
|
-
add_association :organization
|
123
|
-
end
|
124
|
-
|
125
|
-
expect { hql_object_klass.to_graphql }.to raise_error(described_class::Error)
|
126
|
-
end
|
127
|
-
|
128
|
-
it "blows up when adding an association that doesn't exist" do
|
129
|
-
hql_object_klass.class_eval do
|
130
|
-
add_association :doesnt_exist
|
131
|
-
|
132
|
-
with_model "Advisor", attributes: false, associations: false
|
133
|
-
end
|
134
|
-
|
135
|
-
expect { hql_object_klass.to_graphql }.to raise_error(described_class::Error)
|
136
|
-
end
|
137
|
-
|
138
|
-
it "adds associations once connected to a model" do
|
139
|
-
hql_object_klass.class_eval do
|
140
|
-
# Order shouldn't matter....but let's test it anyway
|
141
|
-
|
142
|
-
# First
|
143
|
-
add_association :organization
|
144
|
-
|
145
|
-
# Second
|
146
|
-
with_model "Advisor", attributes: false, associations: false
|
147
|
-
end
|
148
|
-
|
149
|
-
expect(hql_object_klass.fields.keys).to be_empty
|
150
|
-
hql_object_klass.to_graphql
|
151
|
-
expect(hql_object_klass.fields.keys).to contain_exactly("organization")
|
152
|
-
end
|
153
|
-
|
154
|
-
end
|
155
|
-
|
156
|
-
context "with a schema" do
|
157
|
-
let(:user_1) { FactoryBot.create(:user) }
|
158
|
-
let(:user_2) { FactoryBot.create(:user, organization: user_1.organization) }
|
159
|
-
|
160
|
-
before(:each) do
|
161
|
-
user_1
|
162
|
-
user_2
|
163
|
-
end
|
164
|
-
|
165
|
-
it "executes graphql" do
|
166
|
-
query_str = <<-GRAPHQ
|
167
|
-
query {
|
168
|
-
users {
|
169
|
-
name
|
170
|
-
organizationId
|
171
|
-
|
172
|
-
organization {
|
173
|
-
name
|
174
|
-
}
|
175
|
-
}
|
176
|
-
}
|
177
|
-
GRAPHQ
|
178
|
-
|
179
|
-
result = ::Schema.execute(query_str)
|
180
|
-
|
181
|
-
aggregate_failures do
|
182
|
-
user_1_data, user_2_data = result["data"]["users"]
|
183
|
-
# User 1
|
184
|
-
expect(user_1_data["name"]).to eql(user_1.name)
|
185
|
-
expect(user_1_data["organizationId"]).to eql(user_1.organization_id)
|
186
|
-
expect(user_1_data["organization"]["name"]).to eql(user_1.organization.name)
|
187
|
-
|
188
|
-
# User 2
|
189
|
-
expect(user_2_data["name"]).to eql(user_2.name)
|
190
|
-
expect(user_2_data["organizationId"]).to eql(user_2.organization_id)
|
191
|
-
expect(user_2_data["organization"]["name"]).to eql(user_2.organization.name)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
end
|
197
|
-
|
198
|
-
end
|
data/spec/lib/types_spec.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'rails_helper'
|
2
|
-
|
3
|
-
describe ::HQ::GraphQL::Types do
|
4
|
-
|
5
|
-
describe ".[]" do
|
6
|
-
before(:each) do
|
7
|
-
described_class.reset!
|
8
|
-
end
|
9
|
-
|
10
|
-
after(:each) do
|
11
|
-
described_class.reset!
|
12
|
-
end
|
13
|
-
|
14
|
-
it "generates a new class with columns & associations" do
|
15
|
-
# Unique Classes
|
16
|
-
allow(::HQ::GraphQL).to receive(:model_to_graphql_type) { -> (model_class) { "#{model_class.name.demodulize}TypeTest" } }
|
17
|
-
|
18
|
-
advisor_klass = described_class[Advisor]
|
19
|
-
user_klass = described_class[User]
|
20
|
-
advisor_user_fields = ["id", "organizationId", "name", "createdAt", "updatedAt", "organization"]
|
21
|
-
|
22
|
-
#### Advisor Schema ####
|
23
|
-
expect(advisor_klass.name).to eql(::HQ::GraphQL.graphql_type_from_model(Advisor))
|
24
|
-
expect(advisor_klass.fields.keys).to be_empty
|
25
|
-
### Build GraphQL schema
|
26
|
-
advisor_klass.to_graphql
|
27
|
-
expect(advisor_klass.fields.keys).to contain_exactly(*advisor_user_fields)
|
28
|
-
|
29
|
-
#### User Schema ####
|
30
|
-
expect(user_klass.name).to eql(::HQ::GraphQL.graphql_type_from_model(User))
|
31
|
-
expect(user_klass.fields.keys).to be_empty
|
32
|
-
user_klass.to_graphql
|
33
|
-
expect(user_klass.fields.keys).to contain_exactly(*advisor_user_fields)
|
34
|
-
|
35
|
-
organization_klass = ::HQ::GraphQL.graphql_type_from_model(Organization).constantize
|
36
|
-
expect(organization_klass.fields.keys).to be_empty
|
37
|
-
organization_klass.to_graphql
|
38
|
-
organization_fields = ["id", "name", "createdAt", "updatedAt", "users"]
|
39
|
-
expect(organization_klass.fields.keys).to contain_exactly(*organization_fields)
|
40
|
-
end
|
41
|
-
|
42
|
-
it "users the existing class if one exists" do
|
43
|
-
allow(::HQ::GraphQL).to receive(:model_to_graphql_type) { -> (model_class) { "#{model_class.name.demodulize}TypeTestTwo" } }
|
44
|
-
|
45
|
-
klass = Class.new(::HQ::GraphQL::Object) do
|
46
|
-
graphql_name "TestQuery"
|
47
|
-
|
48
|
-
field :custom_field, String, null: false
|
49
|
-
end
|
50
|
-
advisor_klass = stub_const(::HQ::GraphQL.graphql_type_from_model(Advisor), klass)
|
51
|
-
|
52
|
-
expect(advisor_klass).to eql(described_class[Advisor])
|
53
|
-
expect(advisor_klass.fields.keys).to contain_exactly("customField")
|
54
|
-
advisor_klass.to_graphql
|
55
|
-
expect(advisor_klass.fields.keys).to contain_exactly("customField")
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|