diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index cf84703..6fd75fc 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -5,6 +5,9 @@ concurrency: cancel-in-progress: true on: + push: + branches: + - main pull_request: branches: - main diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..30e3106 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +* feat: initial release of `url_launcher_service` 🎉 \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..9308375 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,37 @@ +# Contributing to Url Launcher Service + +First off, thanks for taking the time to contribute! + +The following is a set of guidelines for contributing to the library and related packages. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. + +## Proposing a Change + +We recommend filing an issue if you intend to change the public API or make any non-trivial changes to the implementation. It lets us reach an agreement on your proposal before you put significant effort into it. + +If you’re only fixing a bug, it’s fine to submit a pull request right away, but we still recommend filing an issue detailing what you’re fixing. It is helpful if we don’t accept that specific fix but want to keep track of the issue. + +## Creating a Pull Request + +Before creating a pull request please: + +1. Fork the repository and create your branch from `main`. +1. Install all dependencies (`flutter packages get` or `pub get`). +1. Squash your commits and ensure you have a meaningful commit message. +1. If you’ve fixed a bug or added code that should be tested, add tests! + Pull Requests without 100% test coverage will not be approved. +1. Ensure the test suite passes. +1. If you've changed the public API, make sure to update/add documentation. +1. Format your code (`dart format .`). +1. Analyze your code (`dart analyze --fatal-infos --fatal-warnings .`). +1. Create the Pull Request. +1. Verify that all status checks are passing. + +While the prerequisites above must be satisfied before having your pull request reviewed, the reviewer(s) may ask you to complete additional design work, tests, or other changes before your pull request can be ultimately accepted. + +## Getting in Touch + +If you want to just ask a question or get feedback on an idea, you can post it as a GitHub issue. + +## License + +By contributing to animated_svg, you agree that your contributions will be licensed under its [license](LICENSE). \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..aef5e2e --- /dev/null +++ b/LICENSE @@ -0,0 +1,28 @@ +BSD 3-Clause License + +Copyright (c) 2023, BBK Development + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/README.md b/README.md index cce57e6..9807c83 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,16 @@ -# Url Launcher Service +#

Url Launcher Service

+
+ +[![url_launcher_service][build_status_badge]][workflow_link] +![coverage][coverage_badge] [![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] [![Powered by Mason](https://img.shields.io/endpoint?url=https%3A%2F%2Ftinyurl.com%2Fmason-badge)](https://github.com/felangel/mason) -[![License: MIT][license_badge]][license_link] +[![License: BSD-3-Clause][license_badge]][license_link] + +
-A Very Good Project created by Very Good CLI. +This service wraps the [url_launcher][url_launcher_link] and provides secure usage of the plugin by handling exceptions. ## Installation 💻 @@ -15,6 +21,9 @@ Add `url_launcher_service` to your `pubspec.yaml`: ```yaml dependencies: url_launcher_service: + git: + url: https://github.com/BBKDevelopment/Url-Launcher-Service.git + ref: v1.0.0 ``` Install it: @@ -57,10 +66,14 @@ genhtml coverage/lcov.info -o coverage/ open coverage/index.html ``` +[url_launcher_link]: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher +[workflow_link]: https://github.com/BBKDevelopment/Url-Launcher-Service/actions/workflows/main.yaml +[build_status_badge]: https://github.com/BBKDevelopment/Url-Launcher-Service/actions/workflows/main.yaml/badge.svg +[coverage_badge]: coverage_badge.svg [flutter_install_link]: https://docs.flutter.dev/get-started/install [github_actions_link]: https://docs.github.com/en/actions/learn-github-actions -[license_badge]: https://img.shields.io/badge/license-MIT-blue.svg -[license_link]: https://opensource.org/licenses/MIT +[license_badge]: https://img.shields.io/badge/license-BSD%203%E2%80%93Clause-blue.svg +[license_link]: https://opensource.org/licenses/bsd-3-clause [logo_black]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_black.png#gh-light-mode-only [logo_white]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_white.png#gh-dark-mode-only [mason_link]: https://github.com/felangel/mason diff --git a/lib/src/url_launcher_service.dart b/lib/src/url_launcher_service.dart index 9369936..85ed078 100644 --- a/lib/src/url_launcher_service.dart +++ b/lib/src/url_launcher_service.dart @@ -1,5 +1,6 @@ import 'dart:developer'; +import 'package:flutter/foundation.dart'; import 'package:url_launcher/url_launcher.dart'; /// An exception thrown when the email could not be sent. @@ -19,7 +20,21 @@ class UrlLaunchException implements Exception {} /// {@endtemplate} class UrlLauncherService { /// {@macro url_launcher_service} - const UrlLauncherService(); + const UrlLauncherService() : _urlLauncherResponse = null; + + /// A named constructor of the [UrlLauncherService] for testing purposes in + /// which it is possible to predefine some variables. + /// + /// ```dart + /// final urlLauncherService = UrlLauncherService.test( + /// urlLauncherResponse: true, + /// ); + /// ``` + @visibleForTesting + const UrlLauncherService.test({required bool urlLauncherResponse}) + : _urlLauncherResponse = urlLauncherResponse; + + final bool? _urlLauncherResponse; /// Sends an email to the given [emailUri]. /// @@ -28,7 +43,7 @@ class UrlLauncherService { try { if (!emailUri.isScheme('mailto')) throw Exception(); - final isSuccess = await launchUrl(emailUri); + final isSuccess = _urlLauncherResponse ?? await launchUrl(emailUri); if (!isSuccess) throw Exception(); } catch (_) { @@ -44,7 +59,7 @@ class UrlLauncherService { try { if (!url.isScheme('http') && !url.isScheme('https')) throw Exception(); - final isSuccess = await launchUrl(url); + final isSuccess = _urlLauncherResponse ?? await launchUrl(url); if (!isSuccess) throw Exception(); } catch (_) { diff --git a/pubspec.yaml b/pubspec.yaml index 5ef063c..96a427f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: url_launcher_service -description: A Very Good Project created by Very Good CLI. -version: 0.1.0+1 +description: Url Launcher Service +version: 1.0.0 publish_to: none environment: diff --git a/test/src/url_launcher_service_test.dart b/test/src/url_launcher_service_test.dart index 4eab974..f1d3f79 100644 --- a/test/src/url_launcher_service_test.dart +++ b/test/src/url_launcher_service_test.dart @@ -4,9 +4,47 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:url_launcher_service/url_launcher_service.dart'; void main() { + late UrlLauncherService sut; + group('UrlLauncherService', () { test('can be instantiated', () { expect(UrlLauncherService(), isNotNull); }); + + test('can send email', () async { + sut = UrlLauncherService.test(urlLauncherResponse: true); + + expect( + () => sut.sendEmail(emailUri: Uri(scheme: 'mailto')), + isA(), + ); + }); + + test('can throw SendEmailException when could not send email', () async { + sut = UrlLauncherService.test(urlLauncherResponse: false); + + expect( + () => sut.sendEmail(emailUri: Uri(scheme: 'mailto')), + throwsA(isA()), + ); + }); + + test('can launch url', () async { + sut = UrlLauncherService.test(urlLauncherResponse: true); + + expect( + () => sut.launch(url: Uri(scheme: 'https')), + isA(), + ); + }); + + test('can throw UrlLaunchException when could not launch url', () async { + sut = UrlLauncherService.test(urlLauncherResponse: false); + + expect( + () => sut.launch(url: Uri(scheme: 'https')), + throwsA(isA()), + ); + }); }); }