Skip to content
This repository was archived by the owner on Sep 20, 2023. It is now read-only.

Commit de801c5

Browse files
authored
Merge pull request #1780 from GitHawkApp/vulnerability-support
Add support for vulnerability alerts
2 parents 9c0062e + b61324b commit de801c5

File tree

10 files changed

+140
-19
lines changed

10 files changed

+140
-19
lines changed

Classes/Bookmark/BookmarkViewModel.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,17 @@ final class BookmarkViewModel: ListDiffable {
2424
style: Styles.Text.body.with(foreground: Styles.Colors.Gray.dark.color)
2525
))
2626
switch bookmark.type {
27-
case .issue, .pullRequest:
27+
case .securityVulnerability:
28+
assertionFailure("Type \(bookmark.type) is not expected to be bookmarkable.")
29+
fallthrough
30+
case .issue, .pullRequest, .release:
2831
builder.add(text: bookmark.title)
29-
case .commit, .repo:
32+
case .commit:
33+
assertionFailure("Type \(bookmark.type) is not expected to be bookmarkable.")
34+
fallthrough
35+
case .repo:
3036
builder.add(text: "\(bookmark.owner)/")
3137
.add(text: bookmark.name, traits: .traitBold)
32-
case .release:
33-
builder.add(text: bookmark.title)
3438
}
3539

3640
text = StyledTextRenderer(

Classes/Notifications/NotificationType+Icon.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ extension NotificationType {
1818
case .issue: image = #imageLiteral(resourceName: "issue-opened")
1919
case .pullRequest: image = #imageLiteral(resourceName: "git-pull-request")
2020
case .release: image = #imageLiteral(resourceName: "tag")
21+
case .securityVulnerability: image = #imageLiteral(resourceName: "alert")
2122
}
2223

2324
return image

Classes/Notifications/NotificationType.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ enum NotificationType: String {
1515
case commit = "Commit"
1616
case repo = "Repository"
1717
case release = "Release"
18+
case securityVulnerability = "RepositoryVulnerabilityAlert"
1819

1920
var localizedString: String {
2021
switch self {
@@ -23,6 +24,7 @@ enum NotificationType: String {
2324
case .repo: return NSLocalizedString("Repository", comment: "")
2425
case .release: return NSLocalizedString("Release", comment: "")
2526
case .pullRequest: return Constants.Strings.pullRequest
27+
case .securityVulnerability: return NSLocalizedString("Security Vulnerability", comment: "")
2628
}
2729
}
2830
}

FreetimeTests/Bookmark Tests/BookmarkViewModelTests.swift

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,25 @@ import XCTest
1212
@testable import Freetime
1313
class BookmarkViewModelTests: XCTestCase {
1414

15-
var issue: Bookmark!
16-
var other: Bookmark!
15+
var bookmark: Bookmark!
16+
var bookmarkViewModel: BookmarkViewModel!
1717

18-
var issueModel: BookmarkViewModel!
19-
var otherModel: BookmarkViewModel!
20-
21-
override func setUp() {
22-
super.setUp()
23-
24-
issue = Bookmark(type: .issue, name: "IGListKit on Bookmarks", owner: "rizwankce", title: "Bookmarks view controller not using IGLK")
25-
issueModel = BookmarkViewModel(bookmark: issue, contentSizeCategory: .large, width: 0)
18+
func test_bookmarkText_issue() {
19+
bookmark = Bookmark(type: .issue, name: "IGListKit on Bookmarks", owner: "rizwankce", title: "Bookmarks view controller not using IGLK")
20+
bookmarkViewModel = BookmarkViewModel(bookmark: bookmark, contentSizeCategory: .large, width: 0)
21+
XCTAssertEqual(bookmark.title, bookmarkViewModel.text.string.allText)
22+
}
2623

27-
other = Bookmark(type: .commit, name: "Implemented Bookmark ViewModel", owner: "heshamsalman")
28-
otherModel = BookmarkViewModel(bookmark: other, contentSizeCategory: .large, width: 0)
24+
func test_bookmarkText_pullRequest() {
25+
bookmark = Bookmark(type: .pullRequest, name: "Implemented Bookmark ViewModel", owner: "heshamsalman")
26+
bookmarkViewModel = BookmarkViewModel(bookmark: bookmark, contentSizeCategory: .large, width: 0)
27+
XCTAssertEqual(bookmark.title, bookmarkViewModel.text.string.allText)
2928
}
3029

31-
func test_bookmarkText_other() {
32-
XCTAssertEqual("\(other.owner)/\(other.name)", otherModel.text.string.allText)
30+
func test_bookmarkText_repository() {
31+
bookmark = Bookmark(type: .repo, name: "GitHawk", owner: "GitHawkApp")
32+
bookmarkViewModel = BookmarkViewModel(bookmark: bookmark, contentSizeCategory: .large, width: 0)
33+
XCTAssertEqual("\(bookmark.owner)/\(bookmark.name)", bookmarkViewModel.text.string.allText)
3334
}
3435

3536
}

Local Pods/GitHubAPI/GitHubAPI.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
29F8BAC0204B577800E5CA32 /* V3NotificationSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29F8BABF204B577800E5CA32 /* V3NotificationSubject.swift */; };
6262
29F8BAC2204B57EC00E5CA32 /* V3Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29F8BAC1204B57EC00E5CA32 /* V3Notification.swift */; };
6363
4906A18D206ADECE0031F6F5 /* invitation_notification.json in Resources */ = {isa = PBXBuildFile; fileRef = 4906A18C206ADECE0031F6F5 /* invitation_notification.json */; };
64+
496C9CE620965F2800F13F09 /* security_vulnerability.json in Resources */ = {isa = PBXBuildFile; fileRef = 496C9CE520965F2800F13F09 /* security_vulnerability.json */; };
6465
985AD904C6ABF3E0A1F46079 /* Pods_GitHubAPI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAB687054FAA1CE0478BE468 /* Pods_GitHubAPI.framework */; };
6566
D4D67C0931ACEE218D81A041 /* Pods_GitHubAPITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AD96096F323FEE96EB3F8D0D /* Pods_GitHubAPITests.framework */; };
6667
/* End PBXBuildFile section */
@@ -135,6 +136,7 @@
135136
29F8BAC1204B57EC00E5CA32 /* V3Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = V3Notification.swift; sourceTree = "<group>"; };
136137
33E0718D024CC4F81EBF7364 /* Pods-GitHubAPITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GitHubAPITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-GitHubAPITests/Pods-GitHubAPITests.release.xcconfig"; sourceTree = "<group>"; };
137138
4906A18C206ADECE0031F6F5 /* invitation_notification.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = invitation_notification.json; sourceTree = "<group>"; };
139+
496C9CE520965F2800F13F09 /* security_vulnerability.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = security_vulnerability.json; sourceTree = "<group>"; };
138140
8FAA1C36CB3C11579EF5BE54 /* Pods-GitHubAPI.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GitHubAPI.release.xcconfig"; path = "Pods/Target Support Files/Pods-GitHubAPI/Pods-GitHubAPI.release.xcconfig"; sourceTree = "<group>"; };
139141
AAB687054FAA1CE0478BE468 /* Pods_GitHubAPI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GitHubAPI.framework; sourceTree = BUILT_PRODUCTS_DIR; };
140142
AD96096F323FEE96EB3F8D0D /* Pods_GitHubAPITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GitHubAPITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -247,6 +249,7 @@
247249
29C1A9EF204B22A200CB6995 /* Info.plist */,
248250
2958050A204B5A68009CFD51 /* notifications.json */,
249251
4906A18C206ADECE0031F6F5 /* invitation_notification.json */,
252+
496C9CE520965F2800F13F09 /* security_vulnerability.json */,
250253
);
251254
path = GitHubAPITests;
252255
sourceTree = "<group>";
@@ -377,6 +380,7 @@
377380
isa = PBXResourcesBuildPhase;
378381
buildActionMask = 2147483647;
379382
files = (
383+
496C9CE620965F2800F13F09 /* security_vulnerability.json in Resources */,
380384
2958050B204B5A68009CFD51 /* notifications.json in Resources */,
381385
4906A18D206ADECE0031F6F5 /* invitation_notification.json in Resources */,
382386
);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>IDEDidComputeMac32BitWarning</key>
6+
<true/>
7+
</dict>
8+
</plist>

Local Pods/GitHubAPI/GitHubAPI/V3Notification.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public struct V3Notification: Codable {
2121
case subscribed = "subscribed"
2222
case teamMention = "team_mention"
2323
case reviewRequested = "review_requested"
24+
case securityAlert = "security_alert"
2425
}
2526

2627
public let id: String

Local Pods/GitHubAPI/GitHubAPI/V3NotificationSubject.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public struct V3NotificationSubject: Codable {
1717
case repo = "Repository"
1818
case release = "Release"
1919
case invitation = "RepositoryInvitation"
20+
case vulnerabilityAlert = "RepositoryVulnerabilityAlert"
2021
}
2122

2223
public let title: String

Local Pods/GitHubAPI/GitHubAPITests/GitHubAPITests.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class GitHubAPITests: XCTestCase {
125125
let data = try! Data(contentsOf: Bundle(for: type(of: self)).url(forResource: "invitation_notification", withExtension: "json")!)
126126
let result = processResponse(request: V3NotificationRequest(), input: data)
127127
switch result {
128-
case .failure: XCTFail()
128+
case .failure(let error): XCTFail(error?.localizedDescription ?? "Failed without error")
129129
case .success(let response):
130130
XCTAssertEqual(response.data.count, 1)
131131

@@ -138,5 +138,22 @@ class GitHubAPITests: XCTestCase {
138138
XCTAssertEqual(first.subject.title, "Invitation to join \(repo) from \(first.repository.owner.login)")
139139
}
140140
}
141+
142+
func test_securityVulnerabilityJSON() {
143+
let data = try! Data(contentsOf: Bundle(for: type(of: self)).url(forResource: "security_vulnerability", withExtension: "json")!)
144+
let result = processResponse(request: V3NotificationRequest(), input: data)
145+
switch result {
146+
case .failure(let error): XCTFail(error?.localizedDescription ?? "Failed without error")
147+
case .success(let response):
148+
XCTAssertEqual(response.data.count, 1)
149+
150+
let first = response.data.first!
151+
XCTAssertEqual(first.id, "328706116")
152+
XCTAssertEqual(first.reason, .securityAlert)
153+
XCTAssertEqual(first.repository.name, "eslint-docs")
154+
XCTAssertEqual(first.repository.owner.login, "j-f1")
155+
XCTAssertEqual(first.subject.title, "Potential security vulnerability found in the hoek dependency")
156+
}
157+
}
141158

142159
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
[
2+
{
3+
"id": "328706116",
4+
"unread": false,
5+
"reason": "security_alert",
6+
"updated_at": "2018-04-26T15:25:17Z",
7+
"last_read_at": "2018-04-27T00:34:20Z",
8+
"subject": {
9+
"title": "Potential security vulnerability found in the hoek dependency",
10+
"url": "https://api.github.com/repos/j-f1/eslint-docs",
11+
"latest_comment_url": "https://api.github.com/repos/j-f1/eslint-docs",
12+
"type": "RepositoryVulnerabilityAlert"
13+
},
14+
"repository": {
15+
"id": 100884355,
16+
"name": "eslint-docs",
17+
"full_name": "j-f1/eslint-docs",
18+
"owner": {
19+
"login": "j-f1",
20+
"id": 25517624,
21+
"avatar_url": "https://avatars2.githubusercontent.com/u/25517624?v=4",
22+
"gravatar_id": "",
23+
"url": "https://api.github.com/users/j-f1",
24+
"html_url": "https://github.com/j-f1",
25+
"followers_url": "https://api.github.com/users/j-f1/followers",
26+
"following_url": "https://api.github.com/users/j-f1/following{/other_user}",
27+
"gists_url": "https://api.github.com/users/j-f1/gists{/gist_id}",
28+
"starred_url": "https://api.github.com/users/j-f1/starred{/owner}{/repo}",
29+
"subscriptions_url": "https://api.github.com/users/j-f1/subscriptions",
30+
"organizations_url": "https://api.github.com/users/j-f1/orgs",
31+
"repos_url": "https://api.github.com/users/j-f1/repos",
32+
"events_url": "https://api.github.com/users/j-f1/events{/privacy}",
33+
"received_events_url": "https://api.github.com/users/j-f1/received_events",
34+
"type": "User",
35+
"site_admin": false
36+
},
37+
"private": false,
38+
"html_url": "https://github.com/j-f1/eslint-docs",
39+
"description": "Keep your rule names and descriptions up-to-date across your repo",
40+
"fork": false,
41+
"url": "https://api.github.com/repos/j-f1/eslint-docs",
42+
"forks_url": "https://api.github.com/repos/j-f1/eslint-docs/forks",
43+
"keys_url": "https://api.github.com/repos/j-f1/eslint-docs/keys{/key_id}",
44+
"collaborators_url": "https://api.github.com/repos/j-f1/eslint-docs/collaborators{/collaborator}",
45+
"teams_url": "https://api.github.com/repos/j-f1/eslint-docs/teams",
46+
"hooks_url": "https://api.github.com/repos/j-f1/eslint-docs/hooks",
47+
"issue_events_url": "https://api.github.com/repos/j-f1/eslint-docs/issues/events{/number}",
48+
"events_url": "https://api.github.com/repos/j-f1/eslint-docs/events",
49+
"assignees_url": "https://api.github.com/repos/j-f1/eslint-docs/assignees{/user}",
50+
"branches_url": "https://api.github.com/repos/j-f1/eslint-docs/branches{/branch}",
51+
"tags_url": "https://api.github.com/repos/j-f1/eslint-docs/tags",
52+
"blobs_url": "https://api.github.com/repos/j-f1/eslint-docs/git/blobs{/sha}",
53+
"git_tags_url": "https://api.github.com/repos/j-f1/eslint-docs/git/tags{/sha}",
54+
"git_refs_url": "https://api.github.com/repos/j-f1/eslint-docs/git/refs{/sha}",
55+
"trees_url": "https://api.github.com/repos/j-f1/eslint-docs/git/trees{/sha}",
56+
"statuses_url": "https://api.github.com/repos/j-f1/eslint-docs/statuses/{sha}",
57+
"languages_url": "https://api.github.com/repos/j-f1/eslint-docs/languages",
58+
"stargazers_url": "https://api.github.com/repos/j-f1/eslint-docs/stargazers",
59+
"contributors_url": "https://api.github.com/repos/j-f1/eslint-docs/contributors",
60+
"subscribers_url": "https://api.github.com/repos/j-f1/eslint-docs/subscribers",
61+
"subscription_url": "https://api.github.com/repos/j-f1/eslint-docs/subscription",
62+
"commits_url": "https://api.github.com/repos/j-f1/eslint-docs/commits{/sha}",
63+
"git_commits_url": "https://api.github.com/repos/j-f1/eslint-docs/git/commits{/sha}",
64+
"comments_url": "https://api.github.com/repos/j-f1/eslint-docs/comments{/number}",
65+
"issue_comment_url": "https://api.github.com/repos/j-f1/eslint-docs/issues/comments{/number}",
66+
"contents_url": "https://api.github.com/repos/j-f1/eslint-docs/contents/{+path}",
67+
"compare_url": "https://api.github.com/repos/j-f1/eslint-docs/compare/{base}...{head}",
68+
"merges_url": "https://api.github.com/repos/j-f1/eslint-docs/merges",
69+
"archive_url": "https://api.github.com/repos/j-f1/eslint-docs/{archive_format}{/ref}",
70+
"downloads_url": "https://api.github.com/repos/j-f1/eslint-docs/downloads",
71+
"issues_url": "https://api.github.com/repos/j-f1/eslint-docs/issues{/number}",
72+
"pulls_url": "https://api.github.com/repos/j-f1/eslint-docs/pulls{/number}",
73+
"milestones_url": "https://api.github.com/repos/j-f1/eslint-docs/milestones{/number}",
74+
"notifications_url": "https://api.github.com/repos/j-f1/eslint-docs/notifications{?since,all,participating}",
75+
"labels_url": "https://api.github.com/repos/j-f1/eslint-docs/labels{/name}",
76+
"releases_url": "https://api.github.com/repos/j-f1/eslint-docs/releases{/id}",
77+
"deployments_url": "https://api.github.com/repos/j-f1/eslint-docs/deployments"
78+
},
79+
"url": "https://api.github.com/notifications/threads/328706116",
80+
"subscription_url": "https://api.github.com/notifications/threads/328706116/subscription"
81+
}
82+
]

0 commit comments

Comments
 (0)