1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-25 10:43:13 +02:00

chore(mobile): Run dart analyze in CI (#1425)

* Run dart analyze in CI

* Add pub get

* Fix linter errors in mobile code
This commit is contained in:
Matthias Rupp 2023-01-26 15:40:19 +01:00 committed by GitHub
parent b1311547b2
commit bcb0056b55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 87 additions and 44 deletions

31
.github/workflows/static_analysis.yml vendored Normal file
View File

@ -0,0 +1,31 @@
name: Static Code Analysis
on:
workflow_dispatch:
pull_request:
push:
branches: [main]
jobs:
mobile-dart-analyze:
name: Run Dart Code Analysis
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Flutter SDK
uses: subosito/flutter-action@v2
with:
channel: 'stable'
flutter-version: '3.3.10'
- name: Install dependencies
run: dart pub get
working-directory: ./mobile
- name: Run dart analyze
run: dart analyze --fatal-infos
working-directory: ./mobile

View File

@ -2,7 +2,6 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_test/flutter_test.dart';
import '../test_utils/general_helper.dart';
import '../test_utils/login_helper.dart';
void main() async {
await ImmichTestHelper.initialize();
@ -13,7 +12,7 @@ void main() async {
await helper.loginHelper.acknowledgeNewServerVersion();
await helper.loginHelper.enterCredentials(
email: " demo@immich.app"
email: " demo@immich.app",
);
await tester.pump(const Duration(milliseconds: 300));
@ -21,7 +20,7 @@ void main() async {
expect(find.text("login_form_err_leading_whitespace".tr()), findsOneWidget);
await helper.loginHelper.enterCredentials(
email: "demo@immich.app "
email: "demo@immich.app ",
);
await tester.pump(const Duration(milliseconds: 300));
@ -34,7 +33,7 @@ void main() async {
await helper.loginHelper.acknowledgeNewServerVersion();
await helper.loginHelper.enterCredentials(
email: "demo.immich.app"
email: "demo.immich.app",
);
await tester.pump(const Duration(milliseconds: 300));

View File

@ -1,5 +1,3 @@
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import '../test_utils/general_helper.dart';
@ -12,8 +10,9 @@ void main() async {
immichWidgetTest("Test correct credentials", (tester, helper) async {
await helper.loginHelper.waitForLoginScreen();
await helper.loginHelper.acknowledgeNewServerVersion();
await helper.loginHelper
.enterCredentialsOf(LoginCredentials.testInstance);
await helper.loginHelper.enterCredentialsOf(
LoginCredentials.testInstance,
);
await helper.loginHelper.pressLoginButton();
await helper.loginHelper.assertLoginSuccess();
});
@ -22,16 +21,19 @@ void main() async {
await helper.loginHelper.waitForLoginScreen();
await helper.loginHelper.acknowledgeNewServerVersion();
await helper.loginHelper.enterCredentialsOf(
LoginCredentials.testInstanceButWithWrongPassword);
LoginCredentials.testInstanceButWithWrongPassword,
);
await helper.loginHelper.pressLoginButton();
await helper.loginHelper.assertLoginFailed();
});
immichWidgetTest("Test login with wrong server URL", (tester, helper) async {
immichWidgetTest("Test login with wrong server URL",
(tester, helper) async {
await helper.loginHelper.waitForLoginScreen();
await helper.loginHelper.acknowledgeNewServerVersion();
await helper.loginHelper.enterCredentialsOf(
LoginCredentials.wrongInstanceUrl);
LoginCredentials.wrongInstanceUrl,
);
await helper.loginHelper.pressLoginButton();
await helper.loginHelper.assertLoginFailed();
});

View File

@ -1,17 +1,14 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hive/hive.dart';
import 'package:immich_mobile/main.dart';
import 'package:integration_test/integration_test.dart';
// ignore: depend_on_referenced_packages
import 'package:meta/meta.dart';
import 'package:immich_mobile/main.dart' as app;
import 'login_helper.dart';
class ImmichTestHelper {
final WidgetTester tester;
ImmichTestHelper(this.tester);
@ -43,15 +40,19 @@ class ImmichTestHelper {
await tester.pumpAndSettle();
await EasyLocalization.ensureInitialized();
}
}
@isTest
void immichWidgetTest(String description, Future<void> Function(WidgetTester, ImmichTestHelper) test) {
testWidgets(description, (widgetTester) async {
void immichWidgetTest(
String description,
Future<void> Function(WidgetTester, ImmichTestHelper) test,
) {
testWidgets(
description,
(widgetTester) async {
await ImmichTestHelper.loadApp(widgetTester);
await test(widgetTester, ImmichTestHelper(widgetTester));
}, semanticsEnabled: false);
},
semanticsEnabled: false,
);
}

View File

@ -1,8 +1,6 @@
import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
class ImmichTestLoginHelper {
final WidgetTester tester;

View File

@ -96,7 +96,7 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
if (isSuccess) {
Navigator.pop(context);
ref.watch(assetSelectionProvider.notifier).disableMultiselection();
ref.refresh(sharedAlbumDetailProvider(albumId));
ref.invalidate(sharedAlbumDetailProvider(albumId));
} else {
Navigator.pop(context);
ImmichToast.show(

View File

@ -62,7 +62,7 @@ class AlbumViewerPage extends HookConsumerWidget {
if (addAssetsResult != null &&
addAssetsResult.successfullyAdded > 0) {
ref.refresh(sharedAlbumDetailProvider(albumId));
ref.invalidate(sharedAlbumDetailProvider(albumId));
}
ImmichLoadingOverlayController.appLoader.hide();
@ -88,7 +88,7 @@ class AlbumViewerPage extends HookConsumerWidget {
.addAdditionalUserToAlbum(sharedUserIds, albumId);
if (isSuccess) {
ref.refresh(sharedAlbumDetailProvider(albumId));
ref.invalidate(sharedAlbumDetailProvider(albumId));
}
ImmichLoadingOverlayController.appLoader.hide();

View File

@ -22,7 +22,7 @@ class LibraryPage extends HookConsumerWidget {
[],
);
Widget _buildAppBar() {
Widget buildAppBar() {
return const SliverAppBar(
centerTitle: true,
floating: true,
@ -40,7 +40,7 @@ class LibraryPage extends HookConsumerWidget {
);
}
Widget _buildCreateAlbumButton() {
Widget buildCreateAlbumButton() {
return GestureDetector(
onTap: () {
AutoRouter.of(context).push(CreateAlbumRoute(isSharedAlbum: false));
@ -83,7 +83,7 @@ class LibraryPage extends HookConsumerWidget {
return Scaffold(
body: CustomScrollView(
slivers: [
_buildAppBar(),
buildAppBar(),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(12.0),
@ -99,7 +99,7 @@ class LibraryPage extends HookConsumerWidget {
child: Wrap(
spacing: 12,
children: [
_buildCreateAlbumButton(),
buildCreateAlbumButton(),
for (var album in albums)
AlbumThumbnailCard(
album: album,

View File

@ -8,7 +8,8 @@ class AssetCacheService extends JsonCache<List<Asset>> {
AssetCacheService() : super("asset_cache");
static Future<List<Map<String, dynamic>>> _computeSerialize(
List<Asset> assets) async {
List<Asset> assets,
) async {
return assets.map((e) => e.toJson()).toList();
}

View File

@ -42,8 +42,13 @@ class _AssetGroupsToRenderListComputeParameters {
final Map<String, List<Asset>> groups;
final int perRow;
_AssetGroupsToRenderListComputeParameters(this.monthFormat, this.dayFormat,
this.dayFormatYear, this.groups, this.perRow);
_AssetGroupsToRenderListComputeParameters(
this.monthFormat,
this.dayFormat,
this.dayFormatYear,
this.groups,
this.perRow,
);
}
class RenderList {
@ -52,7 +57,8 @@ class RenderList {
RenderList(this.elements);
static Future<RenderList> _processAssetGroupData(
_AssetGroupsToRenderListComputeParameters data) async {
_AssetGroupsToRenderListComputeParameters data,
) async {
final monthFormat = DateFormat(data.monthFormat);
final dayFormatSameYear = DateFormat(data.dayFormat);
final dayFormatOtherYear = DateFormat(data.dayFormatYear);

View File

@ -1,4 +1,3 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

View File

@ -235,7 +235,7 @@ class ServerEndpointInput extends StatelessWidget {
labelText: 'login_form_endpoint_url'.tr(),
border: const OutlineInputBorder(),
hintText: 'login_form_endpoint_hint'.tr(),
errorMaxLines: 4
errorMaxLines: 4,
),
validator: _validateInput,
autovalidateMode: AutovalidateMode.always,

View File

@ -30,8 +30,8 @@ class TabNavigationObserver extends AutoRouterObserver {
// Perform tasks on re-visit to SearchRoute
if (route.name == 'SearchRoute') {
// Refresh Location State
ref.refresh(getCuratedLocationProvider);
ref.refresh(getCuratedObjectProvider);
ref.invalidate(getCuratedLocationProvider);
ref.invalidate(getCuratedObjectProvider);
}
if (route.name == 'SharingRoute') {

View File

@ -83,6 +83,7 @@ class ImmichLogger {
}
// Share file
// ignore: deprecated_member_use
await Share.shareFiles(
[filePath],
subject: "Immich logs $dateTime",

View File

@ -40,6 +40,7 @@ class ShareService {
}
});
// ignore: deprecated_member_use
Share.shareFiles(
await Future.wait(downloadedFilePaths),
sharePositionOrigin: Rect.zero,

View File

@ -10,8 +10,10 @@ String getThumbnailUrl(
return _getThumbnailUrl(asset.id, type: type);
}
String getThumbnailCacheKey(final AssetResponseDto asset,
{ThumbnailFormat type = ThumbnailFormat.WEBP}) {
String getThumbnailCacheKey(
final AssetResponseDto asset, {
ThumbnailFormat type = ThumbnailFormat.WEBP,
}) {
return _getThumbnailCacheKey(asset.id, type);
}

View File

@ -31,7 +31,9 @@ extension WithETag on AssetApi {
final responseBody = await _decodeBodyBytes(response);
final etag = response.headers[HttpHeaders.etagHeader];
final data = (await apiClient.deserializeAsync(
responseBody, 'List<AssetResponseDto>') as List)
responseBody,
'List<AssetResponseDto>',
) as List)
.cast<AssetResponseDto>()
.toList();
return Pair(data, etag);