Skip to content

Commit 4b6ecba

Browse files
authored
Merge pull request #11146 from neinteractiveliterature/nbudin/issue11125
Make sure that the React Router context and useApolloClient return the same ApolloClient instance
2 parents c0b8cb9 + 75496da commit 4b6ecba

59 files changed

Lines changed: 831 additions & 196 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ concurrency:
1212

1313
jobs:
1414
typescript:
15-
name: typescript
15+
name: TypeScript check
1616
runs-on: ubuntu-latest
1717
steps:
1818
- uses: actions/checkout@v5
@@ -31,7 +31,7 @@ jobs:
3131
- name: tsc on resulting generated files
3232
run: yarn run tsc --noEmit
3333
vitest:
34-
name: vitest
34+
name: Vitest
3535
runs-on: ubuntu-latest
3636
steps:
3737
- uses: actions/checkout@v5
@@ -69,7 +69,7 @@ jobs:
6969
path: coverage/*
7070
minitest:
7171
permissions: write-all
72-
name: minitest
72+
name: Minitest
7373
runs-on: ubuntu-latest
7474
env:
7575
TEST_DATABASE_URL: postgres://postgres:postgres@localhost/intercode_test
@@ -124,8 +124,78 @@ jobs:
124124
with:
125125
name: minitest-coverage
126126
path: coverage/*
127+
minitest-system:
128+
permissions: write-all
129+
name: Minitest system tests
130+
runs-on: ubuntu-latest
131+
env:
132+
TEST_DATABASE_URL: postgres://postgres:postgres@localhost/intercode_test
133+
RAILS_ENV: test
134+
services:
135+
postgres:
136+
image: postgres:18
137+
env:
138+
POSTGRES_PASSWORD: postgres
139+
options: >-
140+
--health-cmd pg_isready
141+
--health-interval 10s
142+
--health-timeout 5s
143+
--health-retries 5
144+
ports:
145+
- 5432:5432
146+
steps:
147+
- uses: actions/checkout@v5
148+
- name: Install libvips42
149+
run: sudo apt-get update && sudo apt-get install libvips42
150+
- name: Upgrade postgres client utilities
151+
run: |
152+
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
153+
wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo tee /etc/apt/trusted.gpg.d/pgdg.asc &>/dev/null
154+
sudo apt-get update
155+
sudo apt-get install postgresql-client-18 -y
156+
- name: Set up Ruby
157+
uses: ruby/setup-ruby@v1
158+
with:
159+
bundler-cache: true
160+
- name: Read .node-version
161+
id: node-version
162+
run: echo "node-version=$(cat .node-version)" >> $GITHUB_OUTPUT
163+
- name: install node
164+
uses: actions/setup-node@v6
165+
with:
166+
cache: yarn
167+
node-version: ${{ steps.node-version.outputs.node-version }}
168+
- name: yarn install
169+
run: yarn install
170+
- name: build
171+
run: yarn run build
172+
- name: Database setup
173+
run: bundle exec rails db:create db:migrate
174+
- name: Run tests
175+
run: TERM=xterm-color bundle exec rails test:system
176+
- name: Publish Test Report
177+
uses: mikepenz/action-junit-report@v6
178+
if: always() # always run even if the previous step fails
179+
with:
180+
check_name: "Minitest System Test Report"
181+
report_paths: "test/reports/TEST-*.xml"
182+
detailed_summary: true
183+
skip_success_summary: true
184+
- name: Archive HTML test reports
185+
uses: actions/upload-artifact@v5
186+
if: always()
187+
with:
188+
name: minitest-system-reports
189+
path: test/html_reports/*
190+
- name: Archive coverage report
191+
uses: actions/upload-artifact@v5
192+
if: always()
193+
with:
194+
name: minitest-system-coverage
195+
path: coverage/*
127196
docker-build:
128197
runs-on: ubuntu-latest
198+
name: Build containers
129199
steps:
130200
- uses: actions/checkout@v5
131201
- name: Read .node-version
@@ -231,23 +301,30 @@ jobs:
231301
path: doc-site.tar.gz
232302
coverage-report:
233303
runs-on: ubuntu-latest
304+
name: Test coverage report
234305
if: github.actor != 'dependabot[bot]'
235306
needs:
236307
- vitest
237308
- minitest
309+
- minitest-system
238310
steps:
239311
- name: Download Minitest coverage
240312
uses: actions/download-artifact@v6
241313
with:
242314
name: minitest-coverage
243315
path: minitest-coverage
316+
- name: Download Minitest system test coverage
317+
uses: actions/download-artifact@v6
318+
with:
319+
name: minitest-system-coverage
320+
path: minitest-system-coverage
244321
- name: Download Vitest coverage
245322
uses: actions/download-artifact@v6
246323
with:
247324
name: vitest-coverage
248325
path: vitest-coverage
249326
- name: Merge coverage reports
250-
run: npx cobertura-merge -o merged-coverage.xml package1=minitest-coverage/coverage.xml package2=vitest-coverage/cobertura-coverage.xml
327+
run: npx cobertura-merge -o merged-coverage.xml package1=minitest-coverage/coverage.xml package2=vitest-coverage/cobertura-coverage.xml package3=minitest-system-coverage/coverage.xml
251328
- name: Generate Coverage Report
252329
uses: clearlyip/code-coverage-report-action@v6
253330
id: code_coverage_report_action
@@ -264,11 +341,13 @@ jobs:
264341
path: code-coverage-results.md
265342
update-release-draft:
266343
runs-on: ubuntu-latest
344+
name: Update release draft
267345
if: github.event_name == 'push' && github.event.ref == 'refs/heads/main'
268346
needs:
269347
- typescript
270348
- vitest
271349
- minitest
350+
- minitest-system
272351
- docker-build
273352
- doc-site
274353
outputs:

.rubocop.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
inherit_from: .rubocop_todo.yml
22

3-
require:
3+
plugins:
44
- rubocop-performance
55
- rubocop-rails
66
- rubocop-sequel
77
- rubocop-factory_bot
88
- rubocop-graphql
9+
- rubocop-capybara
910

1011
inherit_gem:
1112
prettier: rubocop.yml

.rubocop_todo.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ Naming/MethodParameterName:
175175
# ForbiddenPrefixes: is_, has_, have_
176176
# AllowedMethods: is_a?
177177
# MethodDefinitionMacros: define_method, define_singleton_method
178-
Naming/PredicateName:
178+
Naming/PredicatePrefix:
179179
Exclude:
180180
- 'app/models/registration_policy/bucket.rb'
181181
- 'app/models/run.rb'

Gemfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ group :development do
144144
gem "rubocop-factory_bot", require: false
145145
gem "rubocop-graphql", require: false
146146
gem "rubocop-rspec", require: false
147+
gem "rubocop-capybara", require: false
147148
gem "prettier", "4.0.4"
148149
gem "prettier_print"
149150
gem "syntax_tree"
@@ -171,6 +172,9 @@ group :intercode1_import do
171172
end
172173

173174
group :test do
175+
gem "capybara"
176+
gem "cuprite"
177+
gem "database_cleaner-active_record"
174178
gem "minitest-spec-rails"
175179
gem "minitest-reporters"
176180
gem "minitest-focus"

Gemfile.lock

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ GEM
112112
uri (>= 0.13.1)
113113
acts_as_list (0.9.16)
114114
activerecord (>= 3.0)
115+
addressable (2.8.8)
116+
public_suffix (>= 2.0.2, < 8.0)
115117
ahoy_matey (5.4.1)
116118
activesupport (>= 7.1)
117119
device_detector (>= 1)
@@ -180,13 +182,29 @@ GEM
180182
acts_as_list
181183
cadmus
182184
rails (>= 5.0.0)
185+
capybara (3.40.0)
186+
addressable
187+
matrix
188+
mini_mime (>= 0.1.3)
189+
nokogiri (~> 1.11)
190+
rack (>= 1.6.0)
191+
rack-test (>= 0.6.3)
192+
regexp_parser (>= 1.5, < 3.0)
193+
xpath (~> 3.2)
183194
cgi (0.4.2)
184195
coderay (1.1.3)
185196
concurrent-ruby (1.3.5)
186197
connection_pool (2.5.4)
187198
crass (1.0.6)
188199
csv (3.3.5)
200+
cuprite (0.17)
201+
capybara (~> 3.0)
202+
ferrum (~> 0.17.0)
189203
dalli (3.2.8)
204+
database_cleaner-active_record (2.2.2)
205+
activerecord (>= 5.a)
206+
database_cleaner-core (~> 2.0)
207+
database_cleaner-core (2.0.1)
190208
date (3.5.0)
191209
dead_end (4.0.0)
192210
debug (1.11.0)
@@ -260,6 +278,12 @@ GEM
260278
logger
261279
faraday-net_http (3.4.2)
262280
net-http (~> 0.5)
281+
ferrum (0.17.1)
282+
addressable (~> 2.5)
283+
base64 (~> 0.2)
284+
concurrent-ruby (~> 1.1)
285+
webrick (~> 1.7)
286+
websocket-driver (~> 0.7)
263287
ffi (1.17.2-arm64-darwin)
264288
ffi (1.17.2-x86_64-linux-gnu)
265289
flamegraph (0.9.5)
@@ -338,6 +362,7 @@ GEM
338362
net-pop
339363
net-smtp
340364
marcel (1.1.0)
365+
matrix (0.4.3)
341366
memory_profiler (1.1.0)
342367
method_source (1.0.0)
343368
mini_histogram (0.3.1)
@@ -432,6 +457,7 @@ GEM
432457
psych (5.2.6)
433458
date
434459
stringio
460+
public_suffix (7.0.0)
435461
puma (7.1.0)
436462
nio4r (~> 2.0)
437463
pundit (2.5.2)
@@ -527,6 +553,9 @@ GEM
527553
rubocop-ast (1.48.0)
528554
parser (>= 3.3.7.2)
529555
prism (~> 1.4)
556+
rubocop-capybara (2.22.1)
557+
lint_roller (~> 1.1)
558+
rubocop (~> 1.72, >= 1.72.1)
530559
rubocop-factory_bot (2.28.0)
531560
lint_roller (~> 1.1)
532561
rubocop (~> 1.72, >= 1.72.1)
@@ -647,6 +676,8 @@ GEM
647676
with_advisory_lock (7.0.2)
648677
activerecord (>= 7.2)
649678
zeitwerk (>= 2.7)
679+
xpath (3.2.0)
680+
nokogiri (~> 1.8)
650681
yard (0.9.37)
651682
zeitwerk (2.7.3)
652683

@@ -672,10 +703,13 @@ DEPENDENCIES
672703
business_time
673704
cadmus!
674705
cadmus_navbar (~> 0.1.0)
706+
capybara
675707
civil_service!
676708
cloudwatch_scheduler!
677709
csv
710+
cuprite
678711
dalli
712+
database_cleaner-active_record
679713
dead_end
680714
debug
681715
derailed_benchmarks
@@ -732,6 +766,7 @@ DEPENDENCIES
732766
reverse_markdown
733767
rollbar
734768
rubocop (= 1.81.7)
769+
rubocop-capybara
735770
rubocop-factory_bot
736771
rubocop-graphql
737772
rubocop-performance

app/javascript/EventsApp/EventPage/EventPageRunCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ function EventPageRunCard({
141141
return response.data?.createMySignup.signup;
142142
}
143143
},
144-
[event, run, revalidator],
144+
[event, run, revalidator, client],
145145
);
146146

147147
const createSignup = (signupOption: SignupOption) => {

app/javascript/packs/application.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ import 'regenerator-runtime/runtime';
22

33
import mountReactComponents from '../mountReactComponents';
44
import { StrictMode, use, useMemo } from 'react';
5-
import AuthenticityTokensManager, {
6-
AuthenticityTokensContext,
7-
getAuthenticityTokensURL,
8-
} from 'AuthenticityTokensContext';
5+
import AuthenticityTokensManager, { getAuthenticityTokensURL } from 'AuthenticityTokensContext';
96
import { createBrowserRouter, RouterContextProvider, RouterProvider } from 'react-router';
107
import { buildBrowserApolloClient } from 'useIntercodeApolloClient';
118
import {
@@ -16,7 +13,6 @@ import {
1613
sessionContext,
1714
} from 'AppContexts';
1815
import { ClientConfigurationQueryData } from 'serverQueries.generated';
19-
import { ApolloProvider } from '@apollo/client/react';
2016
import { appRootRoutes } from 'AppRouter';
2117

2218
const manager = new AuthenticityTokensManager(fetch, undefined, getAuthenticityTokensURL());
@@ -76,11 +72,7 @@ function DataModeApplicationEntry({
7672

7773
return (
7874
<StrictMode>
79-
<AuthenticityTokensContext.Provider value={manager}>
80-
<ApolloProvider client={client}>
81-
<RouterProvider router={router} />
82-
</ApolloProvider>
83-
</AuthenticityTokensContext.Provider>
75+
<RouterProvider router={router} />
8476
</StrictMode>
8577
);
8678
}

app/javascript/root.tsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
1+
import { ApolloClient } from '@apollo/client';
12
import { ApolloProvider } from '@apollo/client/react';
2-
import { authenticityTokensManagerContext, clientConfigurationDataContext } from 'AppContexts';
3+
import { apolloClientContext, authenticityTokensManagerContext, clientConfigurationDataContext } from 'AppContexts';
34
import { ProviderStack } from 'AppWrapper';
45
import AuthenticityTokensManager, { AuthenticityTokensContext } from 'AuthenticityTokensContext';
56
import { ClientConfiguration } from 'graphqlTypes.generated';
6-
import { StrictMode, useMemo } from 'react';
7+
import { StrictMode } from 'react';
78
import { LoaderFunction, useLoaderData } from 'react-router';
89
import { ClientConfigurationQueryData } from 'serverQueries.generated';
9-
import { buildBrowserApolloClient } from 'useIntercodeApolloClient';
1010

1111
type RootLoaderData = {
1212
clientConfigurationData: ClientConfigurationQueryData;
1313
authenticityTokensManager: AuthenticityTokensManager;
14+
client: ApolloClient;
1415
};
1516

1617
export const loader: LoaderFunction = ({ context }) => {
1718
const clientConfigurationData = context.get(clientConfigurationDataContext);
1819
const authenticityTokensManager = context.get(authenticityTokensManagerContext);
19-
return { clientConfigurationData, authenticityTokensManager } satisfies RootLoaderData;
20+
const client = context.get(apolloClientContext);
21+
return { clientConfigurationData, client, authenticityTokensManager } satisfies RootLoaderData;
2022
};
2123

2224
function RootProviderStack({ clientConfiguration }: { clientConfiguration: ClientConfiguration }) {
@@ -31,15 +33,11 @@ function RootProviderStack({ clientConfiguration }: { clientConfiguration: Clien
3133

3234
export default function Root() {
3335
const loaderData = useLoaderData() as RootLoaderData;
34-
const client = useMemo(
35-
() => buildBrowserApolloClient(loaderData.authenticityTokensManager),
36-
[loaderData.authenticityTokensManager],
37-
);
3836

3937
return (
4038
<StrictMode>
4139
<AuthenticityTokensContext.Provider value={loaderData.authenticityTokensManager}>
42-
<ApolloProvider client={client}>
40+
<ApolloProvider client={loaderData.client}>
4341
<RootProviderStack clientConfiguration={loaderData.clientConfigurationData.clientConfiguration} />
4442
</ApolloProvider>
4543
</AuthenticityTokensContext.Provider>

app/models/registration_policy.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def ==(other)
142142
end
143143

144144
def as_json(*)
145-
super.merge(buckets: buckets.as_json(*))
145+
super.merge("buckets" => buckets.as_json(*))
146146
end
147147

148148
def blank?

0 commit comments

Comments
 (0)