Skip to content

Commit 7003c3c

Browse files
committed
Add spec for N+1
1 parent 3b8a7a6 commit 7003c3c

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

spec/requests/graphql_spec.rb

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
require 'rails_helper'
2+
3+
RSpec.describe 'FragmentCache + Dataloader N+1 Investigation', type: :request do
4+
before do
5+
user1 = User.create!(name: "Alice")
6+
user2 = User.create!(name: "Bob")
7+
5.times do |i|
8+
user1.posts.create!(title: "Alice Post #{i}")
9+
user2.posts.create!(title: "Bob Post #{i}")
10+
end
11+
end
12+
13+
let(:query) do
14+
<<~GRAPHQL
15+
query($useCache: Boolean!) {
16+
users {
17+
id
18+
name
19+
posts(useCache: $useCache) {
20+
id
21+
title
22+
}
23+
}
24+
}
25+
GRAPHQL
26+
end
27+
28+
context 'when cache_fragment is disabled' do
29+
it 'should have minimal query count with effective batching' do
30+
queries_count = 0
31+
queries = []
32+
33+
counter = ->(_name, _started, _finished, _unique_id, payload) do
34+
sql = payload[:sql].to_s
35+
if sql.start_with?("SELECT")
36+
queries_count += 1
37+
queries << sql
38+
end
39+
end
40+
41+
ActiveSupport::Notifications.subscribed(counter, "sql.active_record") do
42+
post '/graphql', params: {
43+
query: query,
44+
variables: { useCache: false }.to_json
45+
}
46+
end
47+
48+
puts "\n=== Queries without cache ==="
49+
queries.each.with_index(1) do |sql, i|
50+
puts "\n#{i}. #{sql}"
51+
end
52+
53+
expect(response).to have_http_status(:success)
54+
json_response = JSON.parse(response.body)
55+
expect(json_response["errors"]).to be_nil
56+
expect(json_response["data"]["users"]).to be_present
57+
expect(queries_count).to be 2
58+
end
59+
end
60+
61+
context 'when cache_fragment is enabled' do
62+
it 'should show increased query count due to N+1' do
63+
GraphQL::FragmentCache.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
64+
65+
queries_count = 0
66+
queries = []
67+
68+
counter = ->(_name, _started, _finished, _unique_id, payload) do
69+
sql = payload[:sql].to_s
70+
if sql.start_with?("SELECT")
71+
queries_count += 1
72+
queries << sql
73+
end
74+
end
75+
76+
77+
ActiveSupport::Notifications.subscribed(counter, "sql.active_record") do
78+
post '/graphql', params: {
79+
query: query,
80+
variables: { useCache: true }.to_json
81+
}
82+
end
83+
84+
puts "\n=== Queries with cache ==="
85+
queries.each.with_index(1) do |sql, i|
86+
puts "\n#{i}. #{sql}"
87+
end
88+
89+
90+
expect(response).to have_http_status(:success)
91+
json_response = JSON.parse(response.body)
92+
expect(json_response["errors"]).to be_nil
93+
expect(json_response["data"]["users"]).to be_present
94+
expect(queries_count).to be 3
95+
end
96+
end
97+
end

0 commit comments

Comments
 (0)