Await store.putFile so cache info is persisted #492 by AzazelSensei · Pull Request #518 · Baseflow/flutter_cache_manager · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions flutter_cache_manager/CHANGELOG.md
4 changes: 2 additions & 2 deletions flutter_cache_manager/lib/src/cache_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ class CacheManager implements BaseCacheManager {

final file = await _config.fileSystem.createFile(cacheObject.relativePath);
await file.writeAsBytes(fileBytes);
_store.putFile(cacheObject);
await _store.putFile(cacheObject);
return file;
}

Expand Down Expand Up @@ -287,7 +287,7 @@ class CacheManager implements BaseCacheManager {
.map((event) => event)
.pipe(sink);

_store.putFile(cacheObject);
await _store.putFile(cacheObject);
return file;
}

Expand Down
18 changes: 11 additions & 7 deletions flutter_cache_manager/lib/src/web/web_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,10 @@ class WebHelper {
newCacheObject = newCacheObject.copyWith(length: savedBytes);
}

_store.putFile(newCacheObject).then((_) {
if (newCacheObject.relativePath != oldCacheObject.relativePath) {
_removeOldFile(oldCacheObject.relativePath);
}
});
await _store.putFile(newCacheObject);
if (newCacheObject.relativePath != oldCacheObject.relativePath) {
await _removeOldFile(oldCacheObject.relativePath);
}

final file = await _store.fileSystem.createFile(
newCacheObject.relativePath,
Expand Down Expand Up @@ -232,8 +231,13 @@ class WebHelper {
Future<void> _removeOldFile(String? relativePath) async {
if (relativePath == null) return;
final file = await _store.fileSystem.createFile(relativePath);
if (await file.exists()) {
await file.delete();
try {
if (await file.exists()) {
await file.delete();
}
} on FileSystemException {
// Already deleted (see #184) or not deletable. The cache info no longer
// points at this path, so there is nothing to recover here.
}
}
}
Expand Down
61 changes: 61 additions & 0 deletions flutter_cache_manager/test/cache_manager_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ import 'package:flutter_cache_manager/src/web/web_helper.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';

import 'package:flutter_cache_manager/src/config/config.dart';

import 'helpers/config_extensions.dart';
import 'helpers/json_repo_helpers.dart';
import 'helpers/mock_cache_store.dart';
import 'helpers/mock_file_fetcher_response.dart';
import 'helpers/mock_file_service.dart';
import 'helpers/test_configuration.dart';
import 'mock.mocks.dart';

Expand Down Expand Up @@ -424,6 +428,40 @@ void main() {
expect(arg.key, fileKey);
expect(arg.url, fileUrl);
});

test('putFile waits for store persist before returning', () async {
final persisted = Completer<void>();
final store = MockCacheStore();
when(store.putFile(any)).thenAnswer((_) => persisted.future);
final cacheManager = TestCacheManager(createTestConfig(), store: store);
var returned = false;
final put = cacheManager.putFile('baseflow.com/test', Uint8List(8))
..whenComplete(() => returned = true);
await pumpEventQueue();
expect(returned, isFalse, reason: 'putFile returned before the store persisted');
persisted.complete();
await put;
});

test('putFileStream waits for store persist before returning', () async {
final persisted = Completer<void>();
final store = MockCacheStore();
when(store.putFile(any)).thenAnswer((_) => persisted.future);
final cacheManager = TestCacheManager(createTestConfig(), store: store);
var returned = false;
final put = cacheManager.putFileStream(
'baseflow.com/test',
Stream<List<int>>.value([1, 2, 3]),
)..whenComplete(() => returned = true);
await pumpEventQueue();
expect(
returned,
isFalse,
reason: 'putFileStream returned before the store persisted',
);
persisted.complete();
await put;
});
});

group('Testing remove files from cache', () {
Expand Down Expand Up @@ -462,6 +500,29 @@ void main() {
verifyNever(store.removeCachedFile(any));
});

test('removeFile deletes the entry right after putFile', () async {
final repo = JsonCacheInfoRepository.withFile(
await JsonRepoHelpers.createDatabaseFile(),
);
final config = Config(
'test',
fileSystem: TestFileSystem(),
repo: repo,
fileService: MockFileService(),
);
final cacheManager = TestCacheManager(config);
const url = 'baseflow.com/test';
final file = await cacheManager.putFile(
url,
Uint8List(8),
fileExtension: 'jpg',
);
await cacheManager.removeFile(url);
await pumpEventQueue();
expect(await repo.get(url), isNull);
expect(await file.exists(), isFalse);
});

test("Don't crash if the cached object doesn't have an id", () async {
var fileUrl = 'baseflow.com/test';

Expand Down
40 changes: 40 additions & 0 deletions flutter_cache_manager/test/web_helper_test.dart