Browse Source

refactor(nextcloud): Rework version checks

Signed-off-by: jld3103 <jld3103yt@gmail.com>
pull/1157/head
jld3103 1 year ago
parent
commit
7f1e84d00f
No known key found for this signature in database
GPG Key ID: 9062417B9E8EB7B3
  1. 44
      packages/nextcloud/lib/src/helpers/common.dart
  2. 36
      packages/nextcloud/lib/src/helpers/core.dart
  3. 17
      packages/nextcloud/lib/src/helpers/news.dart
  4. 25
      packages/nextcloud/lib/src/helpers/notes.dart
  5. 15
      packages/nextcloud/lib/src/helpers/spreed.dart
  6. 10
      packages/nextcloud/test/core_test.dart
  7. 2
      packages/nextcloud/test/news_test.dart
  8. 2
      packages/nextcloud/test/notes_test.dart
  9. 2
      packages/nextcloud/test/spreed_test.dart
  10. 100
      packages/nextcloud/test/version_check_test.dart

44
packages/nextcloud/lib/src/helpers/common.dart

@ -1,2 +1,42 @@
/// The result of a version check.
typedef VersionSupported<T> = ({bool isSupported, T minimumVersion});
import 'package:meta/meta.dart';
import 'package:version/version.dart';
/// Holds the [versions], [minimumVersion] and [maximumMajor] of an app.
@immutable
class VersionCheck {
/// Creates a new [VersionCheck].
///
/// If the [maximumMajor] is `null` the compatibility of the major of the [minimumVersion] is checked.
VersionCheck({
required this.versions,
required this.minimumVersion,
required final int? maximumMajor,
}) : maximumMajor = maximumMajor ?? minimumVersion.major;
/// Current version of the app.
final List<Version>? versions;
/// Minimum version of the app.
final Version minimumVersion;
/// Maximum major version of the app.
late final int maximumMajor;
/// Whether the [versions] is allowed by the [minimumVersion] and [maximumMajor].
///
/// If [versions] is `null` or empty it is assumed that the app is supported.
/// Only one of the [versions] has to be supported to return `true`.
bool get isSupported {
if (versions == null || versions!.isEmpty) {
return true;
}
for (final version in versions!) {
if (version >= minimumVersion && version.major <= maximumMajor) {
return true;
}
}
return false;
}
}

36
packages/nextcloud/lib/src/helpers/core.dart

@ -2,26 +2,36 @@
import 'package:nextcloud/src/api/core.openapi.dart' as core;
import 'package:nextcloud/src/helpers/common.dart';
import 'package:version/version.dart';
/// Version of core/Server supported
const supportedVersion = 27;
/// Minimum version of core/Server supported
final minVersion = Version(27, 0, 0);
extension CoreVersionSupported on core.Client {
extension CoreVersionCheck on core.Client {
/// Check if the core/Server version is supported by this client
///
/// Also returns the supported version number
VersionSupported<int> isSupported(
final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities,
) =>
(
isSupported: capabilities.version.major == supportedVersion,
minimumVersion: supportedVersion,
);
/// Also returns the minimum supported version
VersionCheck getVersionCheck(final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities) {
final version = Version(
capabilities.version.major,
capabilities.version.minor,
capabilities.version.micro,
);
return VersionCheck(
versions: [version],
minimumVersion: minVersion,
maximumMajor: null,
);
}
}
extension CoreStatusVersionSupported on core.Status {
extension CoreStatusVersionCheck on core.Status {
/// Check if the core/Server version is supported
bool get isSupported => version.startsWith('$supportedVersion.');
VersionCheck get versionCheck => VersionCheck(
versions: [Version.parse(version)],
minimumVersion: minVersion,
maximumMajor: null,
);
}
enum ShareType {

17
packages/nextcloud/lib/src/helpers/news.dart

@ -2,19 +2,22 @@
import 'package:nextcloud/src/api/news.openapi.dart' as news;
import 'package:nextcloud/src/helpers/common.dart';
import 'package:version/version.dart';
/// API version of the news app supported
const supportedVersion = 'v1-3';
/// Minimum API version of the news app supported
final minVersion = Version(1, 3, 0);
extension NewsVersionSupported on news.Client {
extension NewsVersionCheck on news.Client {
/// Check if the news app version is supported by this client
///
/// Also returns the supported API version number
Future<VersionSupported<String>> isSupported() async {
Future<VersionCheck> getVersionCheck() async {
final response = await getSupportedApiVersions();
return (
isSupported: response.body.apiLevels!.contains(supportedVersion),
minimumVersion: supportedVersion,
final versions = response.body.apiLevels;
return VersionCheck(
versions: versions?.map((final version) => Version.parse(version.substring(1).replaceAll('-', '.'))).toList(),
minimumVersion: minVersion,
maximumMajor: null,
);
}
}

25
packages/nextcloud/lib/src/helpers/notes.dart

@ -1,25 +1,22 @@
import 'package:collection/collection.dart';
import 'package:nextcloud/src/api/core.openapi.dart' as core;
import 'package:nextcloud/src/api/notes.openapi.dart' as notes;
import 'package:nextcloud/src/helpers/common.dart';
import 'package:version/version.dart';
/// API version of the notes app supported
const supportedVersion = 1;
/// Minimum API version of the notes app supported
final minVersion = Version(1, 3, 0);
// ignore: public_member_api_docs
extension NotesVersionSupported on notes.Client {
extension NotesVersionCheck on notes.Client {
/// Check if the notes app version is supported by this client
///
/// Also returns the supported API version number
VersionSupported<int> isSupported(
final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities,
) =>
(
isSupported: capabilities.capabilities.notesCapabilities?.notes.apiVersion
?.map(Version.parse)
.firstWhereOrNull((final version) => version.major == supportedVersion) !=
null,
minimumVersion: supportedVersion,
);
VersionCheck getVersionCheck(final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities) {
final versions = capabilities.capabilities.notesCapabilities?.notes.apiVersion;
return VersionCheck(
versions: versions?.map(Version.parse).toList(),
minimumVersion: minVersion,
maximumMajor: null,
);
}
}

15
packages/nextcloud/lib/src/helpers/spreed.dart

@ -3,19 +3,20 @@ import 'package:nextcloud/src/api/core.openapi.dart' as core;
import 'package:nextcloud/src/api/spreed.openapi.dart' as spreed;
import 'package:version/version.dart';
/// The version of the spreed app that is supported.
const supportedVersion = 17;
/// The minimum version of the spreed app that is supported.
final minVersion = Version(17, 0, 0);
/// Extension for checking whether spreed is supported.
extension SpreedVersionSupported on spreed.Client {
extension SpreedVersionCheck on spreed.Client {
/// Checks whether the spreed app installed on the server is supported by this client.
///
/// Also returns the supported version number.
VersionSupported<int> isSupported(final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities) {
VersionCheck getVersionCheck(final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities) {
final version = capabilities.capabilities.spreedPublicCapabilities?.spreedPublicCapabilities0?.spreed.version;
return (
isSupported: version != null && Version.parse(version).major == supportedVersion,
minimumVersion: supportedVersion,
return VersionCheck(
versions: version != null ? [Version.parse(version)] : null,
minimumVersion: minVersion,
maximumMajor: null,
);
}
}

10
packages/nextcloud/test/core_test.dart

@ -22,7 +22,7 @@ void main() {
expect(response.statusCode, 200);
expect(() => response.headers, isA<void>());
final result = client.core.isSupported(response.body.ocs.data);
final result = client.core.getVersionCheck(response.body.ocs.data);
expect(result.isSupported, isTrue);
});
@ -31,7 +31,7 @@ void main() {
expect(response.statusCode, 200);
expect(() => response.headers, isA<void>());
expect(response.body.isSupported, isTrue);
expect(response.body.versionCheck.isSupported, isTrue);
});
test('Get status', () async {
@ -42,8 +42,8 @@ void main() {
expect(response.body.installed, isTrue);
expect(response.body.maintenance, isFalse);
expect(response.body.needsDbUpgrade, isFalse);
expect(response.body.version, startsWith('${core.supportedVersion}.'));
expect(response.body.versionstring, startsWith('${core.supportedVersion}.'));
expect(response.body.version, isNotEmpty);
expect(response.body.versionstring, isNotEmpty);
expect(response.body.edition, '');
expect(response.body.productname, 'Nextcloud');
expect(response.body.extendedSupport, isFalse);
@ -55,8 +55,6 @@ void main() {
expect(response.statusCode, 200);
expect(() => response.headers, isA<void>());
expect(response.body.ocs.data.version.major, core.supportedVersion);
expect(response.body.ocs.data.version.string, startsWith('${core.supportedVersion}.'));
expect(response.body.ocs.data.capabilities.commentsCapabilities, isNotNull);
expect(response.body.ocs.data.capabilities.davCapabilities, isNotNull);
expect(response.body.ocs.data.capabilities.filesCapabilities, isNotNull);

2
packages/nextcloud/test/news_test.dart

@ -29,7 +29,7 @@ void main() {
);
test('Is supported', () async {
final result = await client.news.isSupported();
final result = await client.news.getVersionCheck();
expect(result.isSupported, isTrue);
});

2
packages/nextcloud/test/notes_test.dart

@ -22,7 +22,7 @@ void main() {
expect(response.statusCode, 200);
expect(() => response.headers, isA<void>());
final result = client.notes.isSupported(response.body.ocs.data);
final result = client.notes.getVersionCheck(response.body.ocs.data);
expect(result.isSupported, isTrue);
});

2
packages/nextcloud/test/spreed_test.dart

@ -34,7 +34,7 @@ void main() {
expect(response.statusCode, 200);
expect(() => response.headers, isA<void>());
final result = client1.spreed.isSupported(response.body.ocs.data);
final result = client1.spreed.getVersionCheck(response.body.ocs.data);
expect(result.isSupported, isTrue);
});

100
packages/nextcloud/test/version_check_test.dart

@ -0,0 +1,100 @@
import 'package:nextcloud/nextcloud.dart';
import 'package:test/test.dart';
import 'package:version/version.dart';
void main() {
group('Version check', () {
test('Null versions', () {
final check = VersionCheck(
versions: null,
// Invalid constraints to avoid accidental validation
minimumVersion: Version(2, 0, 0),
maximumMajor: 1,
);
expect(check.isSupported, isTrue);
});
test('Empty versions', () {
final check = VersionCheck(
versions: const [],
// Invalid constraints to avoid accidental validation
minimumVersion: Version(2, 0, 0),
maximumMajor: 1,
);
expect(check.isSupported, isTrue);
});
test('Multiple versions', () {
final check = VersionCheck(
versions: [
Version(0, 9, 9),
Version(1, 5, 0),
Version(2, 0, 0),
],
minimumVersion: Version(1, 0, 0),
maximumMajor: 1,
);
expect(check.isSupported, isTrue);
});
test('With maximumMajor', () {
var check = VersionCheck(
versions: [Version(0, 9, 9)],
minimumVersion: Version(1, 0, 0),
maximumMajor: 1,
);
expect(check.isSupported, isFalse);
check = VersionCheck(
versions: [Version(1, 0, 0)],
minimumVersion: Version(1, 0, 0),
maximumMajor: 1,
);
expect(check.isSupported, isTrue);
check = VersionCheck(
versions: [Version(1, 5, 0)],
minimumVersion: Version(1, 0, 0),
maximumMajor: 1,
);
expect(check.isSupported, isTrue);
check = VersionCheck(
versions: [Version(1, 9, 9)],
minimumVersion: Version(1, 0, 0),
maximumMajor: 1,
);
expect(check.isSupported, isTrue);
check = VersionCheck(
versions: [Version(2, 0, 0)],
minimumVersion: Version(1, 0, 0),
maximumMajor: 1,
);
expect(check.isSupported, isFalse);
});
test('Without maximumMajor', () {
var check = VersionCheck(
versions: [Version(0, 9, 9)],
minimumVersion: Version(1, 0, 0),
maximumMajor: null,
);
expect(check.isSupported, isFalse);
check = VersionCheck(
versions: [Version(1, 5, 0)],
minimumVersion: Version(1, 0, 0),
maximumMajor: null,
);
expect(check.isSupported, isTrue);
check = VersionCheck(
versions: [Version(2, 0, 0)],
minimumVersion: Version(1, 0, 0),
maximumMajor: null,
);
expect(check.isSupported, isFalse);
});
});
}
Loading…
Cancel
Save