feat(code_push_client): adjust create artifact APIs to use uploadUrl (#586)
This commit is contained in:
@@ -29,7 +29,7 @@ Future<void> main() async {
|
||||
);
|
||||
|
||||
// Create a release artifact.
|
||||
final releaseArtifact = await client.createReleaseArtifact(
|
||||
await client.createReleaseArtifact(
|
||||
releaseId: release.id,
|
||||
artifactPath: '<PATH TO ARTIFACT>', // e.g. 'libapp.so'
|
||||
platform: '<PLATFORM>', // e.g. 'android'
|
||||
@@ -41,7 +41,7 @@ Future<void> main() async {
|
||||
final patch = await client.createPatch(releaseId: release.id);
|
||||
|
||||
// Create a patch artifact.
|
||||
final patchArtifact = await client.createPatchArtifact(
|
||||
await client.createPatchArtifact(
|
||||
patchId: patch.id,
|
||||
artifactPath: '<PATH TO ARTIFACT>', // e.g. 'libapp.so'
|
||||
platform: '<PLATFORM>', // e.g. 'android'
|
||||
|
||||
@@ -82,7 +82,7 @@ class CodePushClient {
|
||||
}
|
||||
|
||||
/// Create a new artifact for a specific [patchId].
|
||||
Future<PatchArtifact> createPatchArtifact({
|
||||
Future<void> createPatchArtifact({
|
||||
required String artifactPath,
|
||||
required int patchId,
|
||||
required String arch,
|
||||
@@ -94,7 +94,6 @@ class CodePushClient {
|
||||
Uri.parse('$_v1/patches/$patchId/artifacts'),
|
||||
);
|
||||
final file = await http.MultipartFile.fromPath('file', artifactPath);
|
||||
request.files.add(file);
|
||||
request.fields.addAll({
|
||||
'arch': arch,
|
||||
'platform': platform,
|
||||
@@ -108,7 +107,20 @@ class CodePushClient {
|
||||
throw _parseErrorResponse(response.statusCode, body);
|
||||
}
|
||||
|
||||
return PatchArtifact.fromJson(json.decode(body) as Map<String, dynamic>);
|
||||
final decoded = CreatePatchArtifactResponse.fromJson(
|
||||
json.decode(body) as Map<String, dynamic>,
|
||||
);
|
||||
|
||||
final uploadResponse = await _httpClient.put(
|
||||
Uri.parse(decoded.uploadUrl),
|
||||
body: File(artifactPath).readAsBytesSync(),
|
||||
);
|
||||
if (uploadResponse.statusCode != HttpStatus.ok) {
|
||||
throw CodePushException(
|
||||
message:
|
||||
'''Failed to upload artifact (${uploadResponse.reasonPhrase} '${uploadResponse.statusCode})''',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates a Stripe payment link for the current user.
|
||||
@@ -127,7 +139,7 @@ class CodePushClient {
|
||||
}
|
||||
|
||||
/// Create a new artifact for a specific [releaseId].
|
||||
Future<ReleaseArtifact> createReleaseArtifact({
|
||||
Future<void> createReleaseArtifact({
|
||||
required String artifactPath,
|
||||
required int releaseId,
|
||||
required String arch,
|
||||
@@ -139,7 +151,6 @@ class CodePushClient {
|
||||
Uri.parse('$_v1/releases/$releaseId/artifacts'),
|
||||
);
|
||||
final file = await http.MultipartFile.fromPath('file', artifactPath);
|
||||
request.files.add(file);
|
||||
request.fields.addAll({
|
||||
'arch': arch,
|
||||
'platform': platform,
|
||||
@@ -153,7 +164,20 @@ class CodePushClient {
|
||||
throw _parseErrorResponse(response.statusCode, body);
|
||||
}
|
||||
|
||||
return ReleaseArtifact.fromJson(json.decode(body) as Map<String, dynamic>);
|
||||
final decoded = CreateReleaseArtifactResponse.fromJson(
|
||||
json.decode(body) as Map<String, dynamic>,
|
||||
);
|
||||
|
||||
final uploadResponse = await _httpClient.put(
|
||||
Uri.parse(decoded.uploadUrl),
|
||||
body: File(artifactPath).readAsBytesSync(),
|
||||
);
|
||||
if (uploadResponse.statusCode != HttpStatus.ok) {
|
||||
throw CodePushException(
|
||||
message:
|
||||
'''Failed to upload artifact (${uploadResponse.reasonPhrase} '${uploadResponse.statusCode})''',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new app with the provided [displayName].
|
||||
|
||||
@@ -244,22 +244,19 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
test('completes when request succeeds', () async {
|
||||
const artifactId = 0;
|
||||
const artifactUrl = 'https://example.com/artifact.zip';
|
||||
test('throws an exception if the upload fails', () async {
|
||||
const uploadUrl = 'https://example.com/artifact.zip';
|
||||
when(() => httpClient.send(any())).thenAnswer((_) async {
|
||||
return http.StreamedResponse(
|
||||
Stream.value(
|
||||
utf8.encode(
|
||||
json.encode(
|
||||
PatchArtifact(
|
||||
id: artifactId,
|
||||
url: artifactUrl,
|
||||
patchId: patchId,
|
||||
CreatePatchArtifactResponse(
|
||||
arch: arch,
|
||||
platform: platform,
|
||||
hash: hash,
|
||||
size: size,
|
||||
uploadUrl: uploadUrl,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -268,6 +265,10 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
when(
|
||||
() => httpClient.put(any(), body: any(named: 'body')),
|
||||
).thenAnswer((_) async => http.Response('', HttpStatus.badRequest));
|
||||
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
final fixture = File(path.join(tempDir.path, 'release.txt'))
|
||||
..createSync();
|
||||
@@ -280,18 +281,61 @@ void main() {
|
||||
platform: platform,
|
||||
hash: hash,
|
||||
),
|
||||
completion(
|
||||
equals(
|
||||
isA<PatchArtifact>()
|
||||
.having((a) => a.id, 'id', artifactId)
|
||||
.having((a) => a.patchId, 'patchId', patchId)
|
||||
.having((a) => a.arch, 'arch', arch)
|
||||
.having((a) => a.platform, 'platform', platform)
|
||||
.having((a) => a.hash, 'hash', hash)
|
||||
.having((a) => a.url, 'artifactUrl', artifactUrl),
|
||||
throwsA(
|
||||
isA<CodePushException>().having(
|
||||
(e) => e.message,
|
||||
'message',
|
||||
contains('Failed to upload artifact'),
|
||||
),
|
||||
),
|
||||
);
|
||||
verify(
|
||||
() => httpClient.put(
|
||||
Uri.parse(uploadUrl),
|
||||
body: fixture.readAsBytesSync(),
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('completes when request succeeds', () async {
|
||||
const uploadUrl = 'https://example.com/artifact.zip';
|
||||
when(() => httpClient.send(any())).thenAnswer((_) async {
|
||||
return http.StreamedResponse(
|
||||
Stream.value(
|
||||
utf8.encode(
|
||||
json.encode(
|
||||
CreatePatchArtifactResponse(
|
||||
arch: arch,
|
||||
platform: platform,
|
||||
hash: hash,
|
||||
size: size,
|
||||
uploadUrl: uploadUrl,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
HttpStatus.ok,
|
||||
);
|
||||
});
|
||||
|
||||
when(
|
||||
() => httpClient.put(any(), body: any(named: 'body')),
|
||||
).thenAnswer((_) async => http.Response('', HttpStatus.ok));
|
||||
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
final fixture = File(path.join(tempDir.path, 'release.txt'))
|
||||
..createSync();
|
||||
|
||||
await expectLater(
|
||||
codePushClient.createPatchArtifact(
|
||||
artifactPath: fixture.path,
|
||||
patchId: patchId,
|
||||
arch: arch,
|
||||
platform: platform,
|
||||
hash: hash,
|
||||
),
|
||||
completes,
|
||||
);
|
||||
|
||||
final request = verify(() => httpClient.send(captureAny()))
|
||||
.captured
|
||||
@@ -442,22 +486,19 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
test('completes when request succeeds', () async {
|
||||
const artifactId = 0;
|
||||
const artifactUrl = 'https://example.com/artifact.zip';
|
||||
test('throws an exception if the upload fails', () async {
|
||||
const uploadUrl = 'https://example.com/artifact.zip';
|
||||
when(() => httpClient.send(any())).thenAnswer((_) async {
|
||||
return http.StreamedResponse(
|
||||
Stream.value(
|
||||
utf8.encode(
|
||||
json.encode(
|
||||
ReleaseArtifact(
|
||||
id: artifactId,
|
||||
url: artifactUrl,
|
||||
releaseId: releaseId,
|
||||
CreateReleaseArtifactResponse(
|
||||
arch: arch,
|
||||
platform: platform,
|
||||
hash: hash,
|
||||
size: size,
|
||||
uploadUrl: uploadUrl,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -466,6 +507,10 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
when(
|
||||
() => httpClient.put(any(), body: any(named: 'body')),
|
||||
).thenAnswer((_) async => http.Response('', HttpStatus.badRequest));
|
||||
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
final fixture = File(path.join(tempDir.path, 'release.txt'))
|
||||
..createSync();
|
||||
@@ -478,18 +523,61 @@ void main() {
|
||||
platform: platform,
|
||||
hash: hash,
|
||||
),
|
||||
completion(
|
||||
equals(
|
||||
isA<ReleaseArtifact>()
|
||||
.having((a) => a.id, 'id', artifactId)
|
||||
.having((a) => a.releaseId, 'releaseId', releaseId)
|
||||
.having((a) => a.arch, 'arch', arch)
|
||||
.having((a) => a.platform, 'platform', platform)
|
||||
.having((a) => a.hash, 'hash', hash)
|
||||
.having((a) => a.url, 'artifactUrl', artifactUrl),
|
||||
throwsA(
|
||||
isA<CodePushException>().having(
|
||||
(e) => e.message,
|
||||
'message',
|
||||
contains('Failed to upload artifact'),
|
||||
),
|
||||
),
|
||||
);
|
||||
verify(
|
||||
() => httpClient.put(
|
||||
Uri.parse(uploadUrl),
|
||||
body: fixture.readAsBytesSync(),
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('completes when request succeeds', () async {
|
||||
const uploadUrl = 'https://example.com/artifact.zip';
|
||||
when(() => httpClient.send(any())).thenAnswer((_) async {
|
||||
return http.StreamedResponse(
|
||||
Stream.value(
|
||||
utf8.encode(
|
||||
json.encode(
|
||||
CreateReleaseArtifactResponse(
|
||||
arch: arch,
|
||||
platform: platform,
|
||||
hash: hash,
|
||||
size: size,
|
||||
uploadUrl: uploadUrl,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
HttpStatus.ok,
|
||||
);
|
||||
});
|
||||
|
||||
when(
|
||||
() => httpClient.put(any(), body: any(named: 'body')),
|
||||
).thenAnswer((_) async => http.Response('', HttpStatus.ok));
|
||||
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
final fixture = File(path.join(tempDir.path, 'release.txt'))
|
||||
..createSync();
|
||||
|
||||
await expectLater(
|
||||
codePushClient.createReleaseArtifact(
|
||||
artifactPath: fixture.path,
|
||||
releaseId: releaseId,
|
||||
arch: arch,
|
||||
platform: platform,
|
||||
hash: hash,
|
||||
),
|
||||
completes,
|
||||
);
|
||||
|
||||
final request = verify(() => httpClient.send(captureAny()))
|
||||
.captured
|
||||
|
||||
@@ -2,9 +2,9 @@ export 'cancel_subscription/cancel_subscription_response.dart';
|
||||
export 'check_for_patches/check_for_patches.dart';
|
||||
export 'create_app/create_app.dart';
|
||||
export 'create_app_collaborator/create_app_collaborator.dart';
|
||||
export 'create_patch_artifact/create_patch_artifact.dart';
|
||||
export 'create_channel/create_channel.dart';
|
||||
export 'create_patch/create_patch.dart';
|
||||
export 'create_patch_artifact/create_patch_artifact.dart';
|
||||
export 'create_payment_link/create_payment_link.dart';
|
||||
export 'create_release/create_release.dart';
|
||||
export 'create_release_artifact/create_release_artifact.dart';
|
||||
|
||||
Reference in New Issue
Block a user