Skip to content

Commit a6e3af3

Browse files
authoredMar 17, 2025
fix(offline_first_with_rest): restore RestRequest url #553 (#567)
1 parent d29727e commit a6e3af3

File tree

5 files changed

+85
-17
lines changed

5 files changed

+85
-17
lines changed
 

‎packages/brick_offline_first_with_rest/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 4.0.1
2+
3+
- Fixes a bug where `get` with `.awaitRemote` and a non-empty `Query` overrides the initial query and disregards the URL when being passed to the remote provider via `RestRequest`. Hat tip to @hortigado and @devj3ns #553
4+
15
## 4.0.0
26

37
- **BREAKING CHANGE** `Query(providerArgs:)` is no longer supported. See #510 for migration steps.

‎packages/brick_offline_first_with_rest/lib/src/offline_first_with_rest_repository.dart

+12-14
Original file line numberDiff line numberDiff line change
@@ -84,25 +84,23 @@ abstract class OfflineFirstWithRestRepository<TRepositoryModel extends OfflineFi
8484
OfflineFirstUpsertPolicy? upsert,
8585
}) {
8686
// The header value must be stringified because of how `http.Client` accepts the `headers` Map
87-
final headerValue = delete?.toString().split('.').last ??
88-
get?.toString().split('.').last ??
89-
upsert?.toString().split('.').last;
90-
final existingProviderQuery =
91-
query?.providerQueries[RestProvider] as RestProviderQuery? ?? const RestProviderQuery();
92-
final existingProviderQueryRequest = existingProviderQuery.request ?? const RestRequest();
87+
final headerValue = delete?.name ?? get?.name ?? upsert?.name;
88+
final existingProviderQuery = query?.providerQueries[RestProvider] as RestProviderQuery?;
89+
final existingProviderQueryRequest = existingProviderQuery?.request;
9390

9491
return query?.copyWith(
9592
forProviders: [
9693
...query.forProviders,
97-
existingProviderQuery.copyWith(
98-
request: existingProviderQueryRequest.copyWith(
99-
headers: {
100-
// This header is removed by the [RestOfflineQueueClient]
101-
if (headerValue != null) RestOfflineQueueClient.policyHeader: headerValue,
102-
...?existingProviderQueryRequest.headers,
103-
},
94+
if (existingProviderQuery != null)
95+
existingProviderQuery.copyWith(
96+
request: existingProviderQueryRequest?.copyWith(
97+
headers: {
98+
// This header is removed by the [RestOfflineQueueClient]
99+
if (headerValue != null) RestOfflineQueueClient.policyHeader: headerValue,
100+
...?existingProviderQueryRequest.headers,
101+
},
102+
),
104103
),
105-
),
106104
],
107105
);
108106
}

‎packages/brick_offline_first_with_rest/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ homepage: https://github.com/GetDutchie/brick/tree/main/packages/brick_offline_f
55
issue_tracker: https://github.com/GetDutchie/brick/issues
66
repository: https://github.com/GetDutchie/brick
77

8-
version: 4.0.0
8+
version: 4.0.1
99

1010
environment:
1111
sdk: ">=3.4.0 <4.0.0"

‎packages/brick_offline_first_with_rest/test/helpers/__mocks__.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class TestRepository extends OfflineFirstWithRestRepository {
7979
client: client,
8080
),
8181
SqliteProvider(
82-
'$inMemoryDatabasePath/repository',
82+
'$inMemoryDatabasePath/repository${DateTime.now().microsecondsSinceEpoch}',
8383
databaseFactory: databaseFactoryFfi,
8484
modelDictionary: sqliteDictionary,
8585
),

‎packages/brick_offline_first_with_rest/test/offline_first_with_rest_repository_test.dart

+67-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import 'package:brick_offline_first/brick_offline_first.dart';
22
import 'package:brick_offline_first_with_rest/testing.dart';
3+
import 'package:http/http.dart' as http;
4+
import 'package:http/testing.dart';
35
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
46
import 'package:test/test.dart';
57

@@ -11,7 +13,7 @@ void main() {
1113
group('OfflineFirstRepository', () {
1214
const baseUrl = 'http://0.0.0.0:3000';
1315

14-
setUpAll(() async {
16+
setUp(() async {
1517
TestRepository.configure(
1618
baseUrl: baseUrl,
1719
restDictionary: restModelDictionary,
@@ -63,6 +65,70 @@ void main() {
6365

6466
expect(findByName.first.name, horse.name);
6567
});
68+
69+
test('delivers data from HTTP when using awaitRemote policy', () async {
70+
// Configure test repository with a client that returns a specific response
71+
const customResponse = '[{"name": "RemoteName"}]';
72+
final client = StubOfflineFirstWithRest(
73+
baseEndpoint: baseUrl,
74+
responses: [
75+
StubOfflineFirstRestResponse(
76+
customResponse,
77+
endpoint: 'mounties',
78+
method: StubHttpMethod.get,
79+
),
80+
],
81+
).client;
82+
83+
TestRepository.configure(
84+
baseUrl: baseUrl,
85+
restDictionary: restModelDictionary,
86+
sqliteDictionary: sqliteModelDictionary,
87+
client: client,
88+
);
89+
await TestRepository().initialize();
90+
91+
// Get data with awaitRemote policy
92+
final results = await TestRepository().get<Mounty>(
93+
query: Query(
94+
where: [
95+
const Where('name').isExactly('RemoteName'),
96+
],
97+
),
98+
policy: OfflineFirstGetPolicy.awaitRemote,
99+
);
100+
101+
// Verify data came from HTTP
102+
expect(results, hasLength(1));
103+
expect(results.first.name, 'RemoteName');
104+
});
105+
106+
test('handles tunnel not found response with non-awaitRemote policy', () async {
107+
// Configure test repository with a client that returns a tunnel not found response
108+
const tunnelNotFoundResponse = 'Tunnel 12345 not found';
109+
final client = MockClient((req) async {
110+
if (req.url.toString().contains('mounties')) {
111+
return http.Response(tunnelNotFoundResponse, 404);
112+
}
113+
return http.Response('Not found', 404);
114+
});
115+
116+
TestRepository.configure(
117+
baseUrl: baseUrl,
118+
restDictionary: restModelDictionary,
119+
sqliteDictionary: sqliteModelDictionary,
120+
client: client,
121+
);
122+
await TestRepository().initialize();
123+
124+
// Get data with non-awaitRemote policy
125+
final results = await TestRepository().get<Mounty>(
126+
policy: OfflineFirstGetPolicy.localOnly,
127+
);
128+
129+
// Should return empty list without throwing
130+
expect(results, isEmpty);
131+
});
66132
});
67133

68134
test('#getBatched', () async {

0 commit comments

Comments
 (0)
Please sign in to comment.