Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(shorebird_code_push_api_client): add createRelease #5

Merged
merged 2 commits into from
Mar 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/shorebird_code_push_api_client/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
.dart_tool/
.packages
build/
pubspec.lock
pubspec.lock
coverage/
28 changes: 25 additions & 3 deletions packages/shorebird_code_push_api_client/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
## shorebird_code_push_api_client
## Shorebird CodePush API Client

The Shorebird CodePush API Client
The Shorebird CodePush API Client is a Dart library which allows Dart applications to interact with the ShoreBird CodePush API.

🚧 Under construction... 🚧
### Installing

To get started, add the library to your `pubspec.yaml`:

```yaml
dependencies:
shorebird_code_push_api_client:
git:
url: https://github.com/shorebirdtech/shorebird
path: packages/shorebird_code_push_api_client
```

### Usage

```dart
void main() async {
// Create an instance of the client.
final client = ShorebirdCodePushApiClient();

// Publish a new release.
await client.createRelease('path/to/release');
}
```
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
import 'dart:io';

import 'package:http/http.dart' as http;

/// {@template shorebird_code_push_api_client}
/// The Shorebird CodePush API Client
/// {@endtemplate}
class ShorebirdCodePushApiClient {
/// {@macro shorebird_code_push_api_client}
const ShorebirdCodePushApiClient();
ShorebirdCodePushApiClient({http.Client? httpClient, Uri? hostedUri})
: _httpClient = httpClient ?? http.Client(),
_hostedUri = hostedUri ??
Uri.https('shorebird-code-push-api-cypqazu4da-uc.a.run.app');

final http.Client _httpClient;
final Uri _hostedUri;

/// Upload the artifact at [path] to the
/// Shorebird CodePush API as a new release.
Future<void> createRelease(String path) async {
final request = http.MultipartRequest(
'POST',
Uri.parse('$_hostedUri/api/v1/releases'),
);
final file = await http.MultipartFile.fromPath('file', path);
request.files.add(file);
final response = await _httpClient.send(request);

if (response.statusCode != HttpStatus.created) {
throw Exception('${response.statusCode} ${response.reasonPhrase}');
}
}
}
4 changes: 4 additions & 0 deletions packages/shorebird_code_push_api_client/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ publish_to: none
environment:
sdk: ">=2.19.0 <3.0.0"

dependencies:
http: ^0.13.5

dev_dependencies:
mocktail: ^0.3.0
path: ^1.8.3
test: ^1.19.2
very_good_analysis: ^4.0.0
Empty file.
Original file line number Diff line number Diff line change
@@ -1,11 +1,75 @@
// ignore_for_file: prefer_const_constructors
import 'dart:io';

import 'package:http/http.dart' as http;
import 'package:mocktail/mocktail.dart';
import 'package:path/path.dart' as path;
import 'package:shorebird_code_push_api_client/shorebird_code_push_api_client.dart';
import 'package:test/test.dart';

class _MockHttpClient extends Mock implements http.Client {}

class _FakeBaseRequest extends Fake implements http.BaseRequest {}

void main() {
group('ShorebirdCodePushApiClient', () {
late http.Client httpClient;
late ShorebirdCodePushApiClient shorebirdCodePushApiClient;

setUpAll(() {
registerFallbackValue(_FakeBaseRequest());
});

setUp(() {
httpClient = _MockHttpClient();
shorebirdCodePushApiClient = ShorebirdCodePushApiClient(
httpClient: httpClient,
);
});

test('can be instantiated', () {
expect(ShorebirdCodePushApiClient(), isNotNull);
});

group('createRelease', () {
test('throws an exception if the http request fails', () async {
when(() => httpClient.send(any())).thenAnswer((_) async {
return http.StreamedResponse(
Stream.empty(),
400,
);
});

expect(
shorebirdCodePushApiClient.createRelease(
path.join('test', 'fixtures', 'release.txt'),
),
throwsA(isA<Exception>()),
);
});

test('sends a multipart request to the correct url', () async {
when(() => httpClient.send(any())).thenAnswer((_) async {
return http.StreamedResponse(
Stream.empty(),
HttpStatus.created,
);
});

await shorebirdCodePushApiClient.createRelease(
path.join('test', 'fixtures', 'release.txt'),
);

final request = verify(() => httpClient.send(captureAny()))
.captured
.single as http.MultipartRequest;
expect(
request.url,
Uri.parse(
'https://shorebird-code-push-api-cypqazu4da-uc.a.run.app/api/v1/releases',
),
);
});
});
});
}