Skip to content

Commit

Permalink
Add unit tests AvatarPickerViewModel
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewdmontgomery committed Dec 10, 2024
1 parent 18701f3 commit 5cd6c41
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 5 deletions.
10 changes: 5 additions & 5 deletions Sources/TestHelpers/Resources/avatarSetRatingResponse.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"image_id": "6f3eac1c67f970f2a0c2ea8",
"image_url": "https://2.gravatar.com/userimage/133992/9862792c5653946c?size=512",
"rating": "G",
"updated_date": "2024-09-19T11:46:04Z",
"alt_text": "John Appleseed's avatar"
"image_id": "991a7b71cf9f34...",
"image_url": "https://2.gravatar.com/userimage/1/991a7b71cf934ea2...?size=512",
"rating": "PG",
"updated_date": "2024-09-18T10:17:53Z",
"alt_text": "John Appleseed's avatar"
}
74 changes: 74 additions & 0 deletions Tests/GravatarUITests/AvatarPickerViewModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,59 @@ final class AvatarPickerViewModelTests {
#expect(model.grid.avatars.count == 1)
}
}

@Test("Handle avatar rating change: Success")
func changeAvatarRatingSucceeds() async throws {
let testAvatarID = "991a7b71cf9f34..."

await model.refresh()
let avatar = try #require(model.grid.avatars.first(where: { $0.id == testAvatarID }), "No avatar found")
try #require(avatar.rating == .g)

await confirmation { confirmation in
model.toastManager.$toasts.sink { toasts in
#expect(toasts.count <= 1)
if toasts.count == 1 {
#expect(toasts.first?.message == AvatarPickerViewModel.Localized.avatarRatingUpdateSuccess)
#expect(toasts.first?.type == .info)
confirmation.confirm()
}
}.store(in: &cancellables)

await model.setRating(.pg, for: avatar)
}
let resultAvatar = try #require(model.grid.avatars.first(where: { $0.id == testAvatarID }))
#expect(resultAvatar.rating == .pg)
}

@Test(
"Handle avatar rating change: Failure",
arguments: [HTTPStatus.unauthorized, .forbidden]
)
func changeAvatarRatingReturnsError(httpStatus: HTTPStatus) async throws {
let testAvatarID = "991a7b71cf9f34..."
model = Self.createModel(session: .init(returnErrorCode: httpStatus.rawValue))

await model.refresh()
let avatar = try #require(model.grid.avatars.first(where: { $0.id == testAvatarID }), "No avatar found")
try #require(avatar.rating == .g)

await confirmation { confirmation in
model.toastManager.$toasts.sink { toasts in
#expect(toasts.count <= 1)
if toasts.count == 1 {
#expect(toasts.first?.message == AvatarPickerViewModel.Localized.avatarRatingError)
#expect(toasts.first?.type == .error)
confirmation.confirm()
}
}.store(in: &cancellables)

await model.setRating(.pg, for: avatar)
}

let resultAvatar = try #require(model.grid.avatars.first(where: { $0.id == testAvatarID }))
#expect(resultAvatar.rating == .g, "The rating should not be changed")
}
}

final class URLSessionAvatarPickerMock: URLSessionProtocol {
Expand All @@ -221,6 +274,10 @@ final class URLSessionAvatarPickerMock: URLSessionProtocol {
case avatars
}

enum QueryType: String {
case rating
}

init(returnErrorCode: Int? = nil) {
self.returnErrorCode = returnErrorCode
}
Expand All @@ -231,6 +288,13 @@ final class URLSessionAvatarPickerMock: URLSessionProtocol {
return (Bundle.postAvatarSelectedJsonData, HTTPURLResponse.successResponse()) // Avatars data
}
}
if isSetAvatarRatingRequest(request) {
if let returnErrorCode {
return (Data("".utf8), HTTPURLResponse.errorResponse(code: returnErrorCode))
} else {
return (Bundle.setRatingJsonData, HTTPURLResponse.successResponse())
}
}
if request.url?.absoluteString.contains(RequestType.profiles.rawValue) == true {
return (Bundle.fullProfileJsonData, HTTPURLResponse.successResponse()) // Profile data
} else if request.url?.absoluteString.contains(RequestType.avatars.rawValue) == true {
Expand All @@ -245,4 +309,14 @@ final class URLSessionAvatarPickerMock: URLSessionProtocol {
}
return (Bundle.postAvatarUploadJsonData, HTTPURLResponse.successResponse())
}

private func isSetAvatarRatingRequest(_ request: URLRequest) -> Bool {
guard request.httpMethod == "PATCH",
request.url?.absoluteString.contains(RequestType.avatars.rawValue) == true,
request.url?.query?.contains(QueryType.rating.rawValue) == true
else {
return false
}
return true
}
}

0 comments on commit 5cd6c41

Please sign in to comment.