refactor(shorebird_code_push_protocol): include patch check request/response (#3031)
This commit is contained in:
@@ -13,6 +13,7 @@ export 'get_organizations/get_organizations.dart';
|
||||
export 'get_release_artifacts/get_release_artifacts.dart';
|
||||
export 'get_release_patches/get_release_patches.dart';
|
||||
export 'get_releases/get_releases.dart';
|
||||
export 'patch_check/patch_check.dart';
|
||||
export 'promote_patch/promote_patch.dart';
|
||||
export 'update_app_collaborator/update_app_collaborator.dart';
|
||||
export 'update_patch/update_patch.dart';
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export 'patch_check_request.dart';
|
||||
export 'patch_check_response.dart';
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:shorebird_code_push_protocol/shorebird_code_push_protocol.dart';
|
||||
|
||||
part 'patch_check_request.g.dart';
|
||||
|
||||
/// {@template patch_check_request}
|
||||
/// The request body for POST /api/v1/patches/check
|
||||
/// {@endtemplate}
|
||||
@JsonSerializable()
|
||||
class PatchCheckRequest {
|
||||
/// {@macro patch_check_request}
|
||||
const PatchCheckRequest({
|
||||
required this.releaseVersion,
|
||||
required this.patchNumber,
|
||||
required this.patchHash,
|
||||
required this.platform,
|
||||
required this.arch,
|
||||
required this.appId,
|
||||
required this.channel,
|
||||
});
|
||||
|
||||
/// Converts a `Map<String, dynamic>` to a [PatchCheckRequest]
|
||||
factory PatchCheckRequest.fromJson(Map<String, dynamic> json) =>
|
||||
_$PatchCheckRequestFromJson(json);
|
||||
|
||||
/// Converts a [PatchCheckRequest] to a `Map<String, dynamic>`
|
||||
Map<String, dynamic> toJson() => _$PatchCheckRequestToJson(this);
|
||||
|
||||
/// The release version of the app.
|
||||
final String releaseVersion;
|
||||
|
||||
/// The highest patch number that the client has downloaded.
|
||||
/// If provided, the server will only return patches with a higher patch
|
||||
/// number.
|
||||
/// If not provided, the server will provide the latest available patch.
|
||||
final int? patchNumber;
|
||||
|
||||
/// The current patch hash of the app.
|
||||
final String? patchHash;
|
||||
|
||||
/// The platform of the app.
|
||||
final ReleasePlatform platform;
|
||||
|
||||
/// The architecture of the app.
|
||||
final String arch;
|
||||
|
||||
/// The ID of the app.
|
||||
final String appId;
|
||||
|
||||
/// The channel of the app.
|
||||
final String channel;
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
// ignore_for_file: implicit_dynamic_parameter, require_trailing_commas, cast_nullable_to_non_nullable, lines_longer_than_80_chars, unnecessary_lambdas
|
||||
|
||||
part of 'patch_check_request.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
PatchCheckRequest _$PatchCheckRequestFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => $checkedCreate(
|
||||
'PatchCheckRequest',
|
||||
json,
|
||||
($checkedConvert) {
|
||||
final val = PatchCheckRequest(
|
||||
releaseVersion: $checkedConvert('release_version', (v) => v as String),
|
||||
patchNumber: $checkedConvert('patch_number', (v) => (v as num?)?.toInt()),
|
||||
patchHash: $checkedConvert('patch_hash', (v) => v as String?),
|
||||
platform: $checkedConvert(
|
||||
'platform',
|
||||
(v) => $enumDecode(_$ReleasePlatformEnumMap, v),
|
||||
),
|
||||
arch: $checkedConvert('arch', (v) => v as String),
|
||||
appId: $checkedConvert('app_id', (v) => v as String),
|
||||
channel: $checkedConvert('channel', (v) => v as String),
|
||||
);
|
||||
return val;
|
||||
},
|
||||
fieldKeyMap: const {
|
||||
'releaseVersion': 'release_version',
|
||||
'patchNumber': 'patch_number',
|
||||
'patchHash': 'patch_hash',
|
||||
'appId': 'app_id',
|
||||
},
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$PatchCheckRequestToJson(PatchCheckRequest instance) =>
|
||||
<String, dynamic>{
|
||||
'release_version': instance.releaseVersion,
|
||||
'patch_number': instance.patchNumber,
|
||||
'patch_hash': instance.patchHash,
|
||||
'platform': _$ReleasePlatformEnumMap[instance.platform]!,
|
||||
'arch': instance.arch,
|
||||
'app_id': instance.appId,
|
||||
'channel': instance.channel,
|
||||
};
|
||||
|
||||
const _$ReleasePlatformEnumMap = {
|
||||
ReleasePlatform.android: 'android',
|
||||
ReleasePlatform.ios: 'ios',
|
||||
ReleasePlatform.linux: 'linux',
|
||||
ReleasePlatform.macos: 'macos',
|
||||
ReleasePlatform.windows: 'windows',
|
||||
};
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'patch_check_response.g.dart';
|
||||
|
||||
/// {@template patch_check_response}
|
||||
/// The response body for POST /api/v1/patches/check
|
||||
/// {@endtemplate}
|
||||
@JsonSerializable()
|
||||
class PatchCheckResponse extends Equatable {
|
||||
/// {@macro patch_check_response}
|
||||
const PatchCheckResponse({
|
||||
required this.patchAvailable,
|
||||
this.patch,
|
||||
this.rolledBackPatchNumbers,
|
||||
});
|
||||
|
||||
/// Converts a `Map<String, dynamic>` to a [PatchCheckResponse]
|
||||
factory PatchCheckResponse.fromJson(Map<String, dynamic> json) =>
|
||||
_$PatchCheckResponseFromJson(json);
|
||||
|
||||
/// Converts a [PatchCheckResponse] to a `Map<String, dynamic>`
|
||||
Map<String, dynamic> toJson() => _$PatchCheckResponseToJson(this);
|
||||
|
||||
/// Whether a patch is available.
|
||||
final bool patchAvailable;
|
||||
|
||||
/// The patch metadata.
|
||||
final PatchCheckMetadata? patch;
|
||||
|
||||
/// The numbers of all patches that have been rolled back for the current
|
||||
/// release.
|
||||
final List<int>? rolledBackPatchNumbers;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [patchAvailable, patch, rolledBackPatchNumbers];
|
||||
}
|
||||
|
||||
/// {@template patch_check_metadata}
|
||||
/// Patch metadata represents the contents of an update (patch) for a specific
|
||||
/// platform and architecture.
|
||||
/// {@endtemplate}
|
||||
@JsonSerializable()
|
||||
class PatchCheckMetadata extends Equatable {
|
||||
/// {@macro patch_check_metadata}
|
||||
const PatchCheckMetadata({
|
||||
required this.number,
|
||||
required this.downloadUrl,
|
||||
required this.hash,
|
||||
required this.hashSignature,
|
||||
});
|
||||
|
||||
/// Converts a `Map<String, dynamic>` to an [PatchCheckMetadata]
|
||||
factory PatchCheckMetadata.fromJson(Map<String, dynamic> json) =>
|
||||
_$PatchCheckMetadataFromJson(json);
|
||||
|
||||
/// Converts an [PatchCheckMetadata] to a `Map<String, dynamic>`
|
||||
Map<String, dynamic> toJson() => _$PatchCheckMetadataToJson(this);
|
||||
|
||||
/// The patch number associated with the artifact.
|
||||
final int number;
|
||||
|
||||
/// The URL of the artifact.
|
||||
final String downloadUrl;
|
||||
|
||||
/// The hash of the artifact.
|
||||
final String hash;
|
||||
|
||||
/// The signature of the [hash].
|
||||
@JsonKey(includeIfNull: false)
|
||||
final String? hashSignature;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [number, downloadUrl, hash, hashSignature];
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
// ignore_for_file: implicit_dynamic_parameter, require_trailing_commas, cast_nullable_to_non_nullable, lines_longer_than_80_chars, unnecessary_lambdas
|
||||
|
||||
part of 'patch_check_response.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
PatchCheckResponse _$PatchCheckResponseFromJson(Map<String, dynamic> json) =>
|
||||
$checkedCreate(
|
||||
'PatchCheckResponse',
|
||||
json,
|
||||
($checkedConvert) {
|
||||
final val = PatchCheckResponse(
|
||||
patchAvailable: $checkedConvert('patch_available', (v) => v as bool),
|
||||
patch: $checkedConvert(
|
||||
'patch',
|
||||
(v) =>
|
||||
v == null
|
||||
? null
|
||||
: PatchCheckMetadata.fromJson(v as Map<String, dynamic>),
|
||||
),
|
||||
rolledBackPatchNumbers: $checkedConvert(
|
||||
'rolled_back_patch_numbers',
|
||||
(v) =>
|
||||
(v as List<dynamic>?)?.map((e) => (e as num).toInt()).toList(),
|
||||
),
|
||||
);
|
||||
return val;
|
||||
},
|
||||
fieldKeyMap: const {
|
||||
'patchAvailable': 'patch_available',
|
||||
'rolledBackPatchNumbers': 'rolled_back_patch_numbers',
|
||||
},
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$PatchCheckResponseToJson(PatchCheckResponse instance) =>
|
||||
<String, dynamic>{
|
||||
'patch_available': instance.patchAvailable,
|
||||
'patch': instance.patch?.toJson(),
|
||||
'rolled_back_patch_numbers': instance.rolledBackPatchNumbers,
|
||||
};
|
||||
|
||||
PatchCheckMetadata _$PatchCheckMetadataFromJson(Map<String, dynamic> json) =>
|
||||
$checkedCreate(
|
||||
'PatchCheckMetadata',
|
||||
json,
|
||||
($checkedConvert) {
|
||||
final val = PatchCheckMetadata(
|
||||
number: $checkedConvert('number', (v) => (v as num).toInt()),
|
||||
downloadUrl: $checkedConvert('download_url', (v) => v as String),
|
||||
hash: $checkedConvert('hash', (v) => v as String),
|
||||
hashSignature: $checkedConvert('hash_signature', (v) => v as String?),
|
||||
);
|
||||
return val;
|
||||
},
|
||||
fieldKeyMap: const {
|
||||
'downloadUrl': 'download_url',
|
||||
'hashSignature': 'hash_signature',
|
||||
},
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$PatchCheckMetadataToJson(PatchCheckMetadata instance) =>
|
||||
<String, dynamic>{
|
||||
'number': instance.number,
|
||||
'download_url': instance.downloadUrl,
|
||||
'hash': instance.hash,
|
||||
if (instance.hashSignature case final value?) 'hash_signature': value,
|
||||
};
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import 'package:shorebird_code_push_protocol/shorebird_code_push_protocol.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group(PatchCheckRequest, () {
|
||||
test('can be (de)serialized', () {
|
||||
const request = PatchCheckRequest(
|
||||
releaseVersion: '1',
|
||||
patchNumber: 2,
|
||||
patchHash: '3',
|
||||
platform: ReleasePlatform.android,
|
||||
arch: 'arm64',
|
||||
appId: 'app_123',
|
||||
channel: 'channel_123',
|
||||
);
|
||||
expect(
|
||||
PatchCheckRequest.fromJson(request.toJson()).toJson(),
|
||||
equals(request.toJson()),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
import 'package:shorebird_code_push_protocol/shorebird_code_push_protocol.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group(PatchCheckResponse, () {
|
||||
test('uses value equality', () {
|
||||
expect(
|
||||
// Ignoring for value quality testing.
|
||||
// ignore: prefer_const_constructors
|
||||
PatchCheckResponse(patchAvailable: true),
|
||||
// Ignoring for value quality testing.
|
||||
// ignore: prefer_const_constructors
|
||||
equals(PatchCheckResponse(patchAvailable: true)),
|
||||
);
|
||||
});
|
||||
|
||||
test('can be (de)serialized', () {
|
||||
const response = PatchCheckResponse(patchAvailable: true);
|
||||
expect(
|
||||
PatchCheckResponse.fromJson(response.toJson()).toJson(),
|
||||
equals(response.toJson()),
|
||||
);
|
||||
});
|
||||
|
||||
test('can be serialized to json without patch metadata', () {
|
||||
const response = PatchCheckResponse(patchAvailable: true);
|
||||
expect(response.toJson(), {
|
||||
'patch_available': true,
|
||||
'patch': null,
|
||||
'rolled_back_patch_numbers': null,
|
||||
});
|
||||
});
|
||||
|
||||
test('PatchCheckMetadata uses value equality', () {
|
||||
expect(
|
||||
// Ignoring for value quality testing.
|
||||
// ignore: prefer_const_constructors
|
||||
PatchCheckMetadata(
|
||||
number: 1,
|
||||
downloadUrl: 'https://download.com',
|
||||
hash: '1234',
|
||||
hashSignature: null,
|
||||
),
|
||||
equals(
|
||||
// Ignoring for value quality testing.
|
||||
// ignore: prefer_const_constructors
|
||||
PatchCheckMetadata(
|
||||
number: 1,
|
||||
downloadUrl: 'https://download.com',
|
||||
hash: '1234',
|
||||
hashSignature: null,
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('PatchCheckMetadata can be (de)serialized', () {
|
||||
const metadata = PatchCheckMetadata(
|
||||
number: 1,
|
||||
downloadUrl: 'https://download.com',
|
||||
hash: '1234',
|
||||
hashSignature: null,
|
||||
);
|
||||
expect(
|
||||
PatchCheckMetadata.fromJson(metadata.toJson()).toJson(),
|
||||
equals(metadata.toJson()),
|
||||
);
|
||||
});
|
||||
|
||||
test('can be serialized to json with patch metadata', () {
|
||||
const response = PatchCheckResponse(
|
||||
patchAvailable: true,
|
||||
patch: PatchCheckMetadata(
|
||||
number: 1,
|
||||
downloadUrl: 'https://download.com',
|
||||
hash: '1234',
|
||||
hashSignature: null,
|
||||
),
|
||||
);
|
||||
expect(response.toJson(), {
|
||||
'patch_available': true,
|
||||
'patch': {
|
||||
'number': 1,
|
||||
'download_url': 'https://download.com',
|
||||
'hash': '1234',
|
||||
},
|
||||
'rolled_back_patch_numbers': null,
|
||||
});
|
||||
});
|
||||
|
||||
group('when there is a hash signature', () {
|
||||
test('includes the signature', () {
|
||||
const response = PatchCheckResponse(
|
||||
patchAvailable: true,
|
||||
patch: PatchCheckMetadata(
|
||||
number: 1,
|
||||
downloadUrl: 'https://download.com',
|
||||
hash: '1234',
|
||||
hashSignature: 'signature',
|
||||
),
|
||||
);
|
||||
expect(response.toJson(), {
|
||||
'patch_available': true,
|
||||
'patch': {
|
||||
'number': 1,
|
||||
'download_url': 'https://download.com',
|
||||
'hash': '1234',
|
||||
'hash_signature': 'signature',
|
||||
},
|
||||
'rolled_back_patch_numbers': null,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
group('when rolled back patch numbers are provided', () {
|
||||
test('includes the rolled back patch numbers', () {
|
||||
const response = PatchCheckResponse(
|
||||
patchAvailable: true,
|
||||
rolledBackPatchNumbers: [1, 2, 3],
|
||||
);
|
||||
expect(response.toJson(), {
|
||||
'patch_available': true,
|
||||
'patch': null,
|
||||
'rolled_back_patch_numbers': [1, 2, 3],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user