diff --git a/lib/apis/github.dart b/lib/apis/github.dart index 75e3f205..7a0719c0 100644 --- a/lib/apis/github.dart +++ b/lib/apis/github.dart @@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart' as foundation; import 'package:flutter/services.dart'; import 'package:http/http.dart' as http; +import 'package:meta/meta.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:gitjournal/utils.dart'; @@ -107,7 +108,7 @@ class GitHub implements GitHost { var repos = []; list.forEach((dynamic d) { var map = Map.from(d); - var repo = _repoFromJson(map); + var repo = repoFromJson(map); repos.add(repo); }); @@ -151,7 +152,7 @@ class GitHub implements GitHost { Log.d("GitHub createRepo: " + response.body); Map map = json.decode(response.body); - return _repoFromJson(map); + return repoFromJson(map); } @override @@ -180,7 +181,7 @@ class GitHub implements GitHost { Log.d("GitHub getRepo: " + response.body); Map map = json.decode(response.body); - return _repoFromJson(map); + return repoFromJson(map); } @override @@ -216,7 +217,8 @@ class GitHub implements GitHost { return json.decode(response.body); } - GitHostRepo _repoFromJson(Map parsedJson) { + @visibleForTesting + GitHostRepo repoFromJson(Map parsedJson) { DateTime updatedAt; try { updatedAt = DateTime.parse(parsedJson['updated_at'].toString()); diff --git a/lib/apis/gitlab.dart b/lib/apis/gitlab.dart index c7c98d8d..dbce66c0 100644 --- a/lib/apis/gitlab.dart +++ b/lib/apis/gitlab.dart @@ -7,6 +7,7 @@ import 'package:flutter/foundation.dart' as foundation; import 'package:flutter/services.dart'; import 'package:http/http.dart' as http; +import 'package:meta/meta.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:gitjournal/utils.dart'; @@ -94,7 +95,7 @@ class GitLab implements GitHost { var repos = []; list.forEach((dynamic d) { var map = Map.from(d); - var repo = _repoFromJson(map); + var repo = repoFromJson(map); repos.add(repo); }); @@ -137,7 +138,7 @@ class GitLab implements GitHost { Log.d("GitLab createRepo: " + response.body); Map map = json.decode(response.body); - return _repoFromJson(map); + return repoFromJson(map); } @override @@ -163,7 +164,7 @@ class GitLab implements GitHost { Log.d("GitLab getRepo: " + response.body); Map map = json.decode(response.body); - return _repoFromJson(map); + return repoFromJson(map); } @override @@ -200,7 +201,8 @@ class GitLab implements GitHost { return json.decode(response.body); } - GitHostRepo _repoFromJson(Map parsedJson) { + @visibleForTesting + GitHostRepo repoFromJson(Map parsedJson) { DateTime updatedAt; try { updatedAt = DateTime.parse(parsedJson['last_activity_at'].toString()); @@ -209,6 +211,12 @@ class GitLab implements GitHost { } var licenseMap = parsedJson['license']; + List tags = []; + var tagList = parsedJson['tag_list']; + if (tagList is List) { + tags = tagList.map((e) => e.toString()).toList(); + } + return GitHostRepo( fullName: parsedJson['path_with_namespace'], cloneUrl: parsedJson['ssh_url_to_repo'], @@ -219,7 +227,7 @@ class GitLab implements GitHost { issues: parsedJson['open_issues_count'], language: parsedJson['language'], private: parsedJson['visibility'] == 'private', - tags: parsedJson['tag_list'], + tags: tags, license: licenseMap != null ? licenseMap['nickname'] : null, ); } diff --git a/test/apis/data/github.json b/test/apis/data/github.json new file mode 100644 index 00000000..716e7b6f --- /dev/null +++ b/test/apis/data/github.json @@ -0,0 +1,212 @@ +[ + { + "id": 229985363, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjk5ODUzNjM=", + "name": "dart_git", + "full_name": "GitJournal/dart_git", + "private": false, + "owner": { + "login": "GitJournal", + "id": 46486395, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjQ2NDg2Mzk1", + "avatar_url": "https://avatars0.githubusercontent.com/u/46486395?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/GitJournal", + "html_url": "https://github.com/GitJournal", + "followers_url": "https://api.github.com/users/GitJournal/followers", + "following_url": "https://api.github.com/users/GitJournal/following{/other_user}", + "gists_url": "https://api.github.com/users/GitJournal/gists{/gist_id}", + "starred_url": "https://api.github.com/users/GitJournal/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/GitJournal/subscriptions", + "organizations_url": "https://api.github.com/users/GitJournal/orgs", + "repos_url": "https://api.github.com/users/GitJournal/repos", + "events_url": "https://api.github.com/users/GitJournal/events{/privacy}", + "received_events_url": "https://api.github.com/users/GitJournal/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/GitJournal/dart_git", + "description": "A Git implementation in pure Dart", + "fork": false, + "url": "https://api.github.com/repos/GitJournal/dart_git", + "forks_url": "https://api.github.com/repos/GitJournal/dart_git/forks", + "keys_url": "https://api.github.com/repos/GitJournal/dart_git/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/GitJournal/dart_git/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/GitJournal/dart_git/teams", + "hooks_url": "https://api.github.com/repos/GitJournal/dart_git/hooks", + "issue_events_url": "https://api.github.com/repos/GitJournal/dart_git/issues/events{/number}", + "events_url": "https://api.github.com/repos/GitJournal/dart_git/events", + "assignees_url": "https://api.github.com/repos/GitJournal/dart_git/assignees{/user}", + "branches_url": "https://api.github.com/repos/GitJournal/dart_git/branches{/branch}", + "tags_url": "https://api.github.com/repos/GitJournal/dart_git/tags", + "blobs_url": "https://api.github.com/repos/GitJournal/dart_git/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/GitJournal/dart_git/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/GitJournal/dart_git/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/GitJournal/dart_git/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/GitJournal/dart_git/statuses/{sha}", + "languages_url": "https://api.github.com/repos/GitJournal/dart_git/languages", + "stargazers_url": "https://api.github.com/repos/GitJournal/dart_git/stargazers", + "contributors_url": "https://api.github.com/repos/GitJournal/dart_git/contributors", + "subscribers_url": "https://api.github.com/repos/GitJournal/dart_git/subscribers", + "subscription_url": "https://api.github.com/repos/GitJournal/dart_git/subscription", + "commits_url": "https://api.github.com/repos/GitJournal/dart_git/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/GitJournal/dart_git/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/GitJournal/dart_git/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/GitJournal/dart_git/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/GitJournal/dart_git/contents/{+path}", + "compare_url": "https://api.github.com/repos/GitJournal/dart_git/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/GitJournal/dart_git/merges", + "archive_url": "https://api.github.com/repos/GitJournal/dart_git/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/GitJournal/dart_git/downloads", + "issues_url": "https://api.github.com/repos/GitJournal/dart_git/issues{/number}", + "pulls_url": "https://api.github.com/repos/GitJournal/dart_git/pulls{/number}", + "milestones_url": "https://api.github.com/repos/GitJournal/dart_git/milestones{/number}", + "notifications_url": "https://api.github.com/repos/GitJournal/dart_git/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/GitJournal/dart_git/labels{/name}", + "releases_url": "https://api.github.com/repos/GitJournal/dart_git/releases{/id}", + "deployments_url": "https://api.github.com/repos/GitJournal/dart_git/deployments", + "created_at": "2019-12-24T18:08:50Z", + "updated_at": "2020-08-02T10:59:13Z", + "pushed_at": "2020-08-02T10:59:11Z", + "git_url": "git://github.com/GitJournal/dart_git.git", + "ssh_url": "git@github.com:GitJournal/dart_git.git", + "clone_url": "https://github.com/GitJournal/dart_git.git", + "svn_url": "https://github.com/GitJournal/dart_git", + "homepage": null, + "size": 134, + "stargazers_count": 6, + "watchers_count": 6, + "language": "Dart", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 1, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "agpl-3.0", + "name": "GNU Affero General Public License v3.0", + "spdx_id": "AGPL-3.0", + "url": "https://api.github.com/licenses/agpl-3.0", + "node_id": "MDc6TGljZW5zZTE=" + }, + "forks": 1, + "open_issues": 2, + "watchers": 6, + "default_branch": "master", + "permissions": { + "admin": true, + "push": true, + "pull": true + } + }, + { + "id": 165047811, + "node_id": "MDEwOlJlcG9zaXRvcnkxNjUwNDc4MTE=", + "name": "GitJournal", + "full_name": "GitJournal/GitJournal", + "private": false, + "owner": { + "login": "GitJournal", + "id": 46486395, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjQ2NDg2Mzk1", + "avatar_url": "https://avatars0.githubusercontent.com/u/46486395?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/GitJournal", + "html_url": "https://github.com/GitJournal", + "followers_url": "https://api.github.com/users/GitJournal/followers", + "following_url": "https://api.github.com/users/GitJournal/following{/other_user}", + "gists_url": "https://api.github.com/users/GitJournal/gists{/gist_id}", + "starred_url": "https://api.github.com/users/GitJournal/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/GitJournal/subscriptions", + "organizations_url": "https://api.github.com/users/GitJournal/orgs", + "repos_url": "https://api.github.com/users/GitJournal/repos", + "events_url": "https://api.github.com/users/GitJournal/events{/privacy}", + "received_events_url": "https://api.github.com/users/GitJournal/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/GitJournal/GitJournal", + "description": "Store your Notes in any Git Repo", + "fork": false, + "url": "https://api.github.com/repos/GitJournal/GitJournal", + "forks_url": "https://api.github.com/repos/GitJournal/GitJournal/forks", + "keys_url": "https://api.github.com/repos/GitJournal/GitJournal/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/GitJournal/GitJournal/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/GitJournal/GitJournal/teams", + "hooks_url": "https://api.github.com/repos/GitJournal/GitJournal/hooks", + "issue_events_url": "https://api.github.com/repos/GitJournal/GitJournal/issues/events{/number}", + "events_url": "https://api.github.com/repos/GitJournal/GitJournal/events", + "assignees_url": "https://api.github.com/repos/GitJournal/GitJournal/assignees{/user}", + "branches_url": "https://api.github.com/repos/GitJournal/GitJournal/branches{/branch}", + "tags_url": "https://api.github.com/repos/GitJournal/GitJournal/tags", + "blobs_url": "https://api.github.com/repos/GitJournal/GitJournal/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/GitJournal/GitJournal/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/GitJournal/GitJournal/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/GitJournal/GitJournal/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/GitJournal/GitJournal/statuses/{sha}", + "languages_url": "https://api.github.com/repos/GitJournal/GitJournal/languages", + "stargazers_url": "https://api.github.com/repos/GitJournal/GitJournal/stargazers", + "contributors_url": "https://api.github.com/repos/GitJournal/GitJournal/contributors", + "subscribers_url": "https://api.github.com/repos/GitJournal/GitJournal/subscribers", + "subscription_url": "https://api.github.com/repos/GitJournal/GitJournal/subscription", + "commits_url": "https://api.github.com/repos/GitJournal/GitJournal/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/GitJournal/GitJournal/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/GitJournal/GitJournal/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/GitJournal/GitJournal/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/GitJournal/GitJournal/contents/{+path}", + "compare_url": "https://api.github.com/repos/GitJournal/GitJournal/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/GitJournal/GitJournal/merges", + "archive_url": "https://api.github.com/repos/GitJournal/GitJournal/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/GitJournal/GitJournal/downloads", + "issues_url": "https://api.github.com/repos/GitJournal/GitJournal/issues{/number}", + "pulls_url": "https://api.github.com/repos/GitJournal/GitJournal/pulls{/number}", + "milestones_url": "https://api.github.com/repos/GitJournal/GitJournal/milestones{/number}", + "notifications_url": "https://api.github.com/repos/GitJournal/GitJournal/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/GitJournal/GitJournal/labels{/name}", + "releases_url": "https://api.github.com/repos/GitJournal/GitJournal/releases{/id}", + "deployments_url": "https://api.github.com/repos/GitJournal/GitJournal/deployments", + "created_at": "2019-01-10T11:27:18Z", + "updated_at": "2020-09-04T21:15:16Z", + "pushed_at": "2020-09-04T21:15:14Z", + "git_url": "git://github.com/GitJournal/GitJournal.git", + "ssh_url": "git@github.com:GitJournal/GitJournal.git", + "clone_url": "https://github.com/GitJournal/GitJournal.git", + "svn_url": "https://github.com/GitJournal/GitJournal", + "homepage": "https://gitjournal.io", + "size": 9357, + "stargazers_count": 451, + "watchers_count": 451, + "language": "Dart", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 47, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 124, + "license": { + "key": "agpl-3.0", + "name": "GNU Affero General Public License v3.0", + "spdx_id": "AGPL-3.0", + "url": "https://api.github.com/licenses/agpl-3.0", + "node_id": "MDc6TGljZW5zZTE=" + }, + "forks": 47, + "open_issues": 124, + "watchers": 451, + "default_branch": "master", + "permissions": { + "admin": true, + "push": true, + "pull": true + } + } +] diff --git a/test/apis/data/gitlab.json b/test/apis/data/gitlab.json new file mode 100644 index 00000000..e752ae71 --- /dev/null +++ b/test/apis/data/gitlab.json @@ -0,0 +1,60 @@ +[ + { + "id": 20661519, + "description": "Source for https://about.gitlab.com/\r\n\r\nThis repo/project is for the public-facing marketing website of GitLab, including improvements to the docs and the handbook.\r\n\r\nPlease file product improvement suggestions at https://gitlab.com/gitlab-org/gitlab\r\n\r\n", + "name": "www-gitlab-com", + "name_with_namespace": "Vishesh Handa / www-gitlab-com", + "path": "www-gitlab-com", + "path_with_namespace": "vhanda/www-gitlab-com", + "created_at": "2020-08-21T10:50:34.730Z", + "default_branch": "master", + "tag_list": [], + "ssh_url_to_repo": "git@gitlab.com:vhanda/www-gitlab-com.git", + "http_url_to_repo": "https://gitlab.com/vhanda/www-gitlab-com.git", + "web_url": "https://gitlab.com/vhanda/www-gitlab-com", + "readme_url": "https://gitlab.com/vhanda/www-gitlab-com/-/blob/master/README.md", + "avatar_url": "https://assets.gitlab-static.net/uploads/-/system/project/avatar/20661519/about_logo.png", + "forks_count": 0, + "star_count": 0, + "last_activity_at": "2020-08-21T10:50:34.730Z", + "namespace": { + "id": 214434, + "name": "Vishesh Handa", + "path": "vhanda", + "kind": "user", + "full_path": "vhanda", + "parent_id": null, + "avatar_url": "https://secure.gravatar.com/avatar/f0ca65b41675e6aa42d6d8951d42c7bc?s=80&d=identicon", + "web_url": "https://gitlab.com/vhanda" + } + }, + { + "id": 19281306, + "description": null, + "name": "journal", + "name_with_namespace": "Vishesh Handa / journal", + "path": "journal", + "path_with_namespace": "vhanda/journal", + "created_at": "2020-06-09T14:19:41.472Z", + "default_branch": "master", + "tag_list": [], + "ssh_url_to_repo": "git@gitlab.com:vhanda/journal.git", + "http_url_to_repo": "https://gitlab.com/vhanda/journal.git", + "web_url": "https://gitlab.com/vhanda/journal", + "readme_url": null, + "avatar_url": null, + "forks_count": 0, + "star_count": 0, + "last_activity_at": "2020-06-09T14:19:41.472Z", + "namespace": { + "id": 214434, + "name": "Vishesh Handa", + "path": "vhanda", + "kind": "user", + "full_path": "vhanda", + "parent_id": null, + "avatar_url": "https://secure.gravatar.com/avatar/f0ca65b41675e6aa42d6d8951d42c7bc?s=80&d=identicon", + "web_url": "https://gitlab.com/vhanda" + } + } +] diff --git a/test/apis/github_test.dart b/test/apis/github_test.dart new file mode 100644 index 00000000..b65de04d --- /dev/null +++ b/test/apis/github_test.dart @@ -0,0 +1,25 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:test/test.dart'; + +import 'package:gitjournal/apis/githost_factory.dart'; +import 'package:gitjournal/apis/github.dart'; + +void main() { + test('Parse json', () async { + var jsonString = File('test/apis/data/github.json').readAsStringSync(); + + var api = GitHub(); + + List list = jsonDecode(jsonString); + var repos = []; + list.forEach((dynamic d) { + var map = Map.from(d); + var repo = api.repoFromJson(map); + repos.add(repo); + }); + + expect(repos.length, 2); + }); +} diff --git a/test/apis/gitlab_test.dart b/test/apis/gitlab_test.dart new file mode 100644 index 00000000..b2814ced --- /dev/null +++ b/test/apis/gitlab_test.dart @@ -0,0 +1,25 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:test/test.dart'; + +import 'package:gitjournal/apis/githost_factory.dart'; +import 'package:gitjournal/apis/gitlab.dart'; + +void main() { + test('Parse json', () async { + var jsonString = File('test/apis/data/gitlab.json').readAsStringSync(); + + var api = GitLab(); + + List list = jsonDecode(jsonString); + var repos = []; + list.forEach((dynamic d) { + var map = Map.from(d); + var repo = api.repoFromJson(map); + repos.add(repo); + }); + + expect(repos.length, 2); + }); +}