mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
even simplier tests
This commit is contained in:
parent
50b6351b39
commit
97c365cb05
5 changed files with 48 additions and 108 deletions
|
|
@ -27,7 +27,7 @@ class SharedLink {
|
||||||
required this.expiresAt,
|
required this.expiresAt,
|
||||||
required this.key,
|
required this.key,
|
||||||
required this.showMetadata,
|
required this.showMetadata,
|
||||||
required this.slug,
|
this.slug,
|
||||||
required this.type,
|
required this.type,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,5 +98,6 @@ String? punycodeDecodeUrl(String? serverUrl) {
|
||||||
/// - If slug is present: 's/${sharedLink.slug}'
|
/// - If slug is present: 's/${sharedLink.slug}'
|
||||||
/// - Otherwise: 'share/${sharedLink.key}'
|
/// - Otherwise: 'share/${sharedLink.key}'
|
||||||
String getShareUrlPath(SharedLink sharedLink) {
|
String getShareUrlPath(SharedLink sharedLink) {
|
||||||
return sharedLink.slug != null ? 's/${sharedLink.slug}' : 'share/${sharedLink.key}';
|
final slug = sharedLink.slug?.trim();
|
||||||
|
return slug?.isNotEmpty == true ? 's/$slug' : 'share/${sharedLink.key}';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ void main() {
|
||||||
clipboardCapturer = ClipboardCapturer();
|
clipboardCapturer = ClipboardCapturer();
|
||||||
setupClipboardMock(clipboardCapturer);
|
setupClipboardMock(clipboardCapturer);
|
||||||
|
|
||||||
setupDefaultMockResponses(mockSharedLinkService);
|
setupMockResponse(mockSharedLinkService, 'new-slug');
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
|
|
@ -90,53 +90,45 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
group('SharedLinkEditPage Tests', () {
|
group('SharedLinkEditPage Tests', () {
|
||||||
testWidgets('copies URL with slug to clipboard after link creation', (tester) async {
|
testWidgets('copies correct URL for links with slug', (tester) async {
|
||||||
await pumpSharedLinkEditPage(tester, container, albumId: 'album-1');
|
await pumpSharedLinkEditPage(tester, container, albumId: 'album-1');
|
||||||
await createSharedLink(tester);
|
await createSharedLink(tester);
|
||||||
|
|
||||||
final copyButton = find.byIcon(Icons.copy);
|
await tester.tap(find.byIcon(Icons.copy));
|
||||||
await tester.tap(copyButton);
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(clipboardCapturer.text, 'https://demo.immich.app/s/new-slug');
|
expect(clipboardCapturer.text, 'https://demo.immich.app/s/new-slug');
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('copies URL without slug to clipboard after link creation', (tester) async {
|
testWidgets('copies correct URL for links without slug', (tester) async {
|
||||||
setupMockResponseForLinkWithoutSlug(mockSharedLinkService);
|
setupMockResponse(mockSharedLinkService, '');
|
||||||
|
|
||||||
await pumpSharedLinkEditPage(tester, container, albumId: 'album-1');
|
await pumpSharedLinkEditPage(tester, container, albumId: 'album-1');
|
||||||
await createSharedLink(tester);
|
await createSharedLink(tester);
|
||||||
|
|
||||||
final copyButton = find.byIcon(Icons.copy);
|
await tester.tap(find.byIcon(Icons.copy));
|
||||||
await tester.tap(copyButton);
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(clipboardCapturer.text, 'https://demo.immich.app/share/new-key');
|
expect(clipboardCapturer.text, 'https://demo.immich.app/share/new-key');
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('handles empty external domain by using server endpoint', (tester) async {
|
testWidgets('uses server endpoint when external domain is empty', (tester) async {
|
||||||
setupEmptyExternalDomain(mockServerInfoNotifier);
|
setupServerInfo(mockServerInfoNotifier, '');
|
||||||
|
|
||||||
await pumpSharedLinkEditPage(tester, container, albumId: 'album-1');
|
await pumpSharedLinkEditPage(tester, container, albumId: 'album-1');
|
||||||
await createSharedLink(tester);
|
await createSharedLink(tester);
|
||||||
|
|
||||||
final copyButton = find.byIcon(Icons.copy);
|
await tester.tap(find.byIcon(Icons.copy));
|
||||||
await tester.tap(copyButton);
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(clipboardCapturer.text, 'https://demo.immich.app/s/new-slug');
|
expect(clipboardCapturer.text, 'https://demo.immich.app/s/new-slug');
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('uses custom domain when external domain is set', (tester) async {
|
testWidgets('uses custom external domain when set', (tester) async {
|
||||||
final mockServerInfoWithCustomDomain = createMockServerInfo(externalDomain: 'https://custom-immich.com');
|
setupServerInfo(mockServerInfoNotifier, 'https://custom-immich.com');
|
||||||
mockServerInfoNotifier.state = mockServerInfoWithCustomDomain;
|
|
||||||
|
|
||||||
await pumpSharedLinkEditPage(tester, container, albumId: 'album-1');
|
await pumpSharedLinkEditPage(tester, container, albumId: 'album-1');
|
||||||
await createSharedLink(tester);
|
await createSharedLink(tester);
|
||||||
|
|
||||||
final copyButton = find.byIcon(Icons.copy);
|
await tester.tap(find.byIcon(Icons.copy));
|
||||||
await tester.tap(copyButton);
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(clipboardCapturer.text, 'https://custom-immich.com/s/new-slug');
|
expect(clipboardCapturer.text, 'https://custom-immich.com/s/new-slug');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ void main() {
|
||||||
mockSharedLinksNotifier = MockSharedLinksNotifier();
|
mockSharedLinksNotifier = MockSharedLinksNotifier();
|
||||||
clipboardCapturer = ClipboardCapturer();
|
clipboardCapturer = ClipboardCapturer();
|
||||||
|
|
||||||
setupDefaultServerInfo(mockServerInfoNotifier);
|
setupServerInfo(mockServerInfoNotifier, 'https://example.com');
|
||||||
mockSharedLinksNotifier.state = const AsyncValue.data([]);
|
mockSharedLinksNotifier.state = const AsyncValue.data([]);
|
||||||
|
|
||||||
overrides = [
|
overrides = [
|
||||||
|
|
@ -68,62 +68,51 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
group('SharedLinkItem Tests', () {
|
group('SharedLinkItem Tests', () {
|
||||||
testWidgets('copies URL with slug to clipboard', (tester) async {
|
testWidgets('copies URL with slug', (tester) async {
|
||||||
await tester.pumpConsumerWidget(Scaffold(body: SharedLinkItem(sharedLinkWithSlug)), overrides: overrides);
|
await tester.pumpConsumerWidget(Scaffold(body: SharedLinkItem(sharedLinkWithSlug)), overrides: overrides);
|
||||||
|
|
||||||
final copyButton = find.byIcon(Icons.copy_outlined);
|
await tester.tap(find.byIcon(Icons.copy_outlined));
|
||||||
await tester.tap(copyButton);
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(clipboardCapturer.text, 'https://example.com/s/test-slug');
|
expect(clipboardCapturer.text, 'https://example.com/s/test-slug');
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('copies URL without slug to clipboard', (tester) async {
|
testWidgets('copies URL without slug', (tester) async {
|
||||||
await tester.pumpConsumerWidget(Scaffold(body: SharedLinkItem(sharedLinkWithoutSlug)), overrides: overrides);
|
await tester.pumpConsumerWidget(Scaffold(body: SharedLinkItem(sharedLinkWithoutSlug)), overrides: overrides);
|
||||||
|
|
||||||
final copyButton = find.byIcon(Icons.copy_outlined);
|
await tester.tap(find.byIcon(Icons.copy_outlined));
|
||||||
await tester.tap(copyButton);
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(clipboardCapturer.text, 'https://example.com/share/test-key-2');
|
expect(clipboardCapturer.text, 'https://example.com/share/test-key-2');
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('handles empty external domain by using server URL', (tester) async {
|
testWidgets('falls back to server URL when external domain is empty', (tester) async {
|
||||||
setupEmptyExternalDomain(mockServerInfoNotifier);
|
setupServerInfo(mockServerInfoNotifier, '');
|
||||||
await Store.put(StoreKey.serverEndpoint, 'http://example.com');
|
await Store.put(StoreKey.serverEndpoint, 'http://example.com');
|
||||||
|
|
||||||
await tester.pumpConsumerWidget(Scaffold(body: SharedLinkItem(sharedLinkWithSlug)), overrides: overrides);
|
await tester.pumpConsumerWidget(Scaffold(body: SharedLinkItem(sharedLinkWithSlug)), overrides: overrides);
|
||||||
|
|
||||||
final copyButton = find.byIcon(Icons.copy_outlined);
|
await tester.tap(find.byIcon(Icons.copy_outlined));
|
||||||
await tester.tap(copyButton);
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(clipboardCapturer.text, 'http://example.com/s/test-slug');
|
expect(clipboardCapturer.text, 'http://example.com/s/test-slug');
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('shows snackbar on successful copy', (tester) async {
|
testWidgets('shows success message on copy', (tester) async {
|
||||||
await tester.pumpConsumerWidget(Scaffold(body: SharedLinkItem(sharedLinkWithSlug)), overrides: overrides);
|
await tester.pumpConsumerWidget(Scaffold(body: SharedLinkItem(sharedLinkWithSlug)), overrides: overrides);
|
||||||
|
|
||||||
final copyButton = find.byIcon(Icons.copy_outlined);
|
await tester.tap(find.byIcon(Icons.copy_outlined));
|
||||||
await tester.tap(copyButton);
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(find.textContaining('copied'), findsOneWidget);
|
expect(find.textContaining('copied'), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('works with different shared links', (tester) async {
|
testWidgets('handles different link types correctly', (tester) async {
|
||||||
await tester.pumpConsumerWidget(Scaffold(body: SharedLinkItem(sharedLinkWithSlug)), overrides: overrides);
|
await tester.pumpConsumerWidget(Scaffold(body: SharedLinkItem(sharedLinkWithSlug)), overrides: overrides);
|
||||||
|
|
||||||
final copyButton = find.byIcon(Icons.copy_outlined);
|
await tester.tap(find.byIcon(Icons.copy_outlined));
|
||||||
await tester.tap(copyButton);
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(clipboardCapturer.text, 'https://example.com/s/test-slug');
|
expect(clipboardCapturer.text, 'https://example.com/s/test-slug');
|
||||||
|
|
||||||
await tester.pumpConsumerWidget(Scaffold(body: SharedLinkItem(sharedLinkWithoutSlug)), overrides: overrides);
|
await tester.pumpConsumerWidget(Scaffold(body: SharedLinkItem(sharedLinkWithoutSlug)), overrides: overrides);
|
||||||
await tester.tap(copyButton);
|
await tester.tap(find.byIcon(Icons.copy_outlined));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(clipboardCapturer.text, 'https://example.com/share/test-key-2');
|
expect(clipboardCapturer.text, 'https://example.com/share/test-key-2');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,10 @@ class MockSharedLinksNotifier extends StateNotifier<AsyncValue<List<SharedLink>>
|
||||||
MockSharedLinksNotifier() : super(const AsyncValue.loading());
|
MockSharedLinksNotifier() : super(const AsyncValue.loading());
|
||||||
}
|
}
|
||||||
|
|
||||||
final mockServerInfoNotifierProvider = Provider<ServerInfoNotifier>((ref) => MockServerInfoNotifier());
|
|
||||||
|
|
||||||
/// Creates a mock ServerInfo with customizable parameters for testing
|
/// Creates a mock ServerInfo for testing
|
||||||
ServerInfo createMockServerInfo({
|
ServerInfo createMockServerInfo({
|
||||||
String externalDomain = 'https://demo.immich.app',
|
String externalDomain = 'https://demo.immich.app',
|
||||||
String serverEndpoint = 'https://demo.immich.app',
|
|
||||||
}) {
|
}) {
|
||||||
return ServerInfo(
|
return ServerInfo(
|
||||||
serverVersion: const ServerVersion(major: 1, minor: 0, patch: 0),
|
serverVersion: const ServerVersion(major: 1, minor: 0, patch: 0),
|
||||||
|
|
@ -57,34 +55,6 @@ ServerInfo createMockServerInfo({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a mock album shared link with customizable parameters for testing
|
|
||||||
SharedLink createAlbumSharedLink({
|
|
||||||
String id = '1',
|
|
||||||
String title = 'Test Album',
|
|
||||||
String description = 'Test Description',
|
|
||||||
String key = 'test-key',
|
|
||||||
String? slug = 'test-slug',
|
|
||||||
bool allowUpload = true,
|
|
||||||
bool allowDownload = true,
|
|
||||||
bool showMetadata = true,
|
|
||||||
String? password,
|
|
||||||
}) {
|
|
||||||
return SharedLink(
|
|
||||||
id: id,
|
|
||||||
title: title,
|
|
||||||
description: description,
|
|
||||||
key: key,
|
|
||||||
slug: slug,
|
|
||||||
expiresAt: DateTime.now().add(const Duration(days: 1)),
|
|
||||||
allowUpload: allowUpload,
|
|
||||||
allowDownload: allowDownload,
|
|
||||||
showMetadata: showMetadata,
|
|
||||||
thumbAssetId: null,
|
|
||||||
password: password,
|
|
||||||
type: SharedLinkSource.album,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a shared link with slug for testing
|
/// Creates a shared link with slug for testing
|
||||||
SharedLink createSharedLinkWithSlug() {
|
SharedLink createSharedLinkWithSlug() {
|
||||||
return SharedLink(
|
return SharedLink(
|
||||||
|
|
@ -121,20 +91,13 @@ SharedLink createSharedLinkWithoutSlug() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets up default server info with external domain for testing
|
/// Sets up server info with external domain for testing
|
||||||
void setupDefaultServerInfo(MockServerInfoNotifier mockServerInfoNotifier) {
|
void setupServerInfo(MockServerInfoNotifier mockServerInfoNotifier, String domain) {
|
||||||
final mockServerInfo = createMockServerInfo(externalDomain: 'https://example.com');
|
mockServerInfoNotifier.state = createMockServerInfo(externalDomain: domain);
|
||||||
mockServerInfoNotifier.state = mockServerInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets up empty external domain for testing
|
/// Sets up mock response for shared link service
|
||||||
void setupEmptyExternalDomain(ServerInfoNotifier mockServerInfoNotifier) {
|
void setupMockResponse(MockSharedLinkService mockSharedLinkService, String slug) {
|
||||||
final mockServerInfoWithEmptyDomain = createMockServerInfo(externalDomain: '');
|
|
||||||
mockServerInfoNotifier.state = mockServerInfoWithEmptyDomain;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets up default mock responses for shared link service
|
|
||||||
void setupDefaultMockResponses(MockSharedLinkService mockSharedLinkService) {
|
|
||||||
when(
|
when(
|
||||||
() => mockSharedLinkService.createSharedLink(
|
() => mockSharedLinkService.createSharedLink(
|
||||||
albumId: any(named: 'albumId'),
|
albumId: any(named: 'albumId'),
|
||||||
|
|
@ -146,25 +109,20 @@ void setupDefaultMockResponses(MockSharedLinkService mockSharedLinkService) {
|
||||||
password: any(named: 'password'),
|
password: any(named: 'password'),
|
||||||
expiresAt: any(named: 'expiresAt'),
|
expiresAt: any(named: 'expiresAt'),
|
||||||
),
|
),
|
||||||
).thenAnswer(
|
).thenAnswer((_) async => SharedLink(
|
||||||
(_) async => createAlbumSharedLink(id: 'new-link-id', title: 'New Link', key: 'new-key', slug: 'new-slug'),
|
id: 'new-link-id',
|
||||||
);
|
title: 'New Link',
|
||||||
}
|
description: 'Test Description',
|
||||||
|
key: 'new-key',
|
||||||
/// Sets up mock response for link without slug
|
slug: slug.isEmpty ? null : slug,
|
||||||
void setupMockResponseForLinkWithoutSlug(MockSharedLinkService mockSharedLinkService) {
|
expiresAt: DateTime.now().add(const Duration(days: 1)),
|
||||||
when(
|
allowUpload: true,
|
||||||
() => mockSharedLinkService.createSharedLink(
|
allowDownload: true,
|
||||||
albumId: any(named: 'albumId'),
|
showMetadata: true,
|
||||||
assetIds: any(named: 'assetIds'),
|
thumbAssetId: null,
|
||||||
showMeta: any(named: 'showMeta'),
|
password: null,
|
||||||
allowDownload: any(named: 'allowDownload'),
|
type: SharedLinkSource.album,
|
||||||
allowUpload: any(named: 'allowUpload'),
|
));
|
||||||
description: any(named: 'description'),
|
|
||||||
password: any(named: 'password'),
|
|
||||||
expiresAt: any(named: 'expiresAt'),
|
|
||||||
),
|
|
||||||
).thenAnswer((_) async => createAlbumSharedLink(id: 'new-link-id', title: 'New Link', key: 'new-key', slug: null));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test utility to capture clipboard operations for verification
|
/// Test utility to capture clipboard operations for verification
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue