Skip to content

Commit

Permalink
Merge pull request #110 from duhnnie/develop
Browse files Browse the repository at this point in the history
Develop to Main
  • Loading branch information
duhnnie committed Jan 19, 2024
2 parents 7d835f6 + f8516ec commit fdd7ecc
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 12 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ lastFM.User.getRecentTracks(params: recentTrackParams) { result in
print("No data was returned.")
case .OtherError(let error):
print("An error ocurred: \(error)")
case .NoSessionKey:
print("No session key provided.")
}
case .success(let obj):
for track in obj.items {
Expand Down Expand Up @@ -178,4 +176,4 @@ So that's why some test running in GitHub Actions. Anyway, you can run the tests
## License

LastFM.swift is available under the MIT license. See [the LICENSE
file](./LICENSE.txt) for more information.
file](./LICENSE.txt) for more information.
3 changes: 0 additions & 3 deletions Sources/LastFM/Models/LastFMError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public enum LastFMServiceErrorType: Int {

public enum LastFMError: Error {
case LastFMServiceError(LastFMServiceErrorType, String)
case NoSessionKey
case NoData
case OtherError(Error)
}
Expand All @@ -39,8 +38,6 @@ extension LastFMError: LocalizedError {
switch (self) {
case .LastFMServiceError(_, let message):
detail = "\(message)"
case .NoSessionKey:
detail = "No session key."
case .NoData:
detail = "No data was returned."
case .OtherError(let error):
Expand Down
37 changes: 35 additions & 2 deletions Sources/LastFM/Models/LastFMImages.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

public struct LastFMImages: Decodable {
public enum LastFMImageSize: String, Decodable {
public struct LastFMImages: Codable {
public enum LastFMImageSize: String, Decodable, CaseIterable {
case S = "small"
case M = "medium"
case L = "large"
Expand Down Expand Up @@ -60,4 +60,37 @@ public struct LastFMImages: Decodable {
}
}
}

private func encodeItem(
container: inout UnkeyedEncodingContainer,
url: URL?,
size: LastFMImageSize
) throws {
if let url = url {
var subcontainer = container.nestedContainer(keyedBy: CodingKeys.self)

try subcontainer.encode(size.rawValue, forKey: .size)
try subcontainer.encode(url, forKey: .url)
}
}

public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()

for size in LastFMImageSize.allCases {
switch size {
case .S:
try encodeItem(container: &container, url: small, size: size)
case .M:
try encodeItem(container: &container, url: medium, size: size)
case .L:
try encodeItem(container: &container, url: large, size: size)
case .XL:
try encodeItem(container: &container, url: extraLarge, size: size)
case .MG:
try encodeItem(container: &container, url: mega, size: size)
}
}

}
}
36 changes: 33 additions & 3 deletions Sources/LastFM/Models/UserInfo.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import Foundation

public struct UserInfo: Decodable {
public struct UserInfo: Codable {

public let name: String
public let age: UInt
public let subscriber: Bool
public let realname: String
public let bootsrap: Bool
public let bootstrap: Bool
public let playcount: UInt
public let artistCount: UInt
public let playlists: UInt
Expand Down Expand Up @@ -64,7 +64,7 @@ public struct UserInfo: Decodable {

self.age = try container.decode(UInt.self, forKey: .age)
self.subscriber = try container.decode(Bool.self, forKey: .subscriber)
self.bootsrap = try container.decode(Bool.self, forKey: .bootstrap)
self.bootstrap = try container.decode(Bool.self, forKey: .bootstrap)
self.playcount = try container.decode(UInt.self, forKey: .playcount)
self.artistCount = try container.decode(UInt.self, forKey: .artistCount)
self.playlists = try container.decode(UInt.self, forKey: .playlists)
Expand All @@ -76,5 +76,35 @@ public struct UserInfo: Decodable {

self.registered = Date(timeIntervalSince1970: registeredDouble)
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: OuterCodingKeys.self)
var subcontainer = container.nestedContainer(keyedBy: CodingKeys.self, forKey: .user)

var subsubcontainer = subcontainer.nestedContainer(
keyedBy: CodingKeys.RegisteredKeys.self,
forKey: .registered
)

try subcontainer.encode(name, forKey: .name)
try subcontainer.encode(age, forKey: .age)
try subcontainer.encode(subscriber, forKey: .subscriber)
try subcontainer.encode(name, forKey: .name)
try subcontainer.encode(age, forKey: .age)
try subcontainer.encode(subscriber, forKey: .subscriber)
try subcontainer.encode(realname, forKey: .realname)
try subcontainer.encode(bootstrap, forKey: .bootstrap)
try subcontainer.encode(playcount, forKey: .playcount)
try subcontainer.encode(artistCount, forKey: .artistCount)
try subcontainer.encode(playlists, forKey: .playlists)
try subcontainer.encode(trackCount, forKey: .trackCount)
try subcontainer.encode(albumCount, forKey: .albumCount)
try subcontainer.encode(image, forKey: .image)
try subcontainer.encode(country, forKey: .country)
try subcontainer.encode(gender, forKey: .gender)
try subcontainer.encode(url, forKey: .url)
try subcontainer.encode(type, forKey: .type)
try subsubcontainer.encode(registered, forKey: .text)
}

}
6 changes: 6 additions & 0 deletions Sources/LastFM/Modules/UserModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ public struct UserModule {

requester.getDataAndParse(params: params, secure: false, onCompletion: onCompletion)
}

public func getInfo(sessionKey: String, onCompletion: @escaping LastFM.OnCompletion<UserInfo>) throws {
let params = parent.normalizeParams(params: [:], method: APIMethod.getInfo, sessionKey: sessionKey)

try requester.postFormURLEncodedAndParse(payload: params, secure: false, onCompletion: onCompletion)
}

public func getFriends(
params: SearchParams,
Expand Down
97 changes: 96 additions & 1 deletion Tests/LastFMTests/Modules/UserModuleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1093,7 +1093,7 @@ class UserTests: XCTestCase {
XCTAssertEqual(userInfo.age, 0)
XCTAssertEqual(userInfo.subscriber, false)
XCTAssertEqual(userInfo.realname, "Jose")
XCTAssertEqual(userInfo.bootsrap, false)
XCTAssertEqual(userInfo.bootstrap, false)
XCTAssertEqual(userInfo.playcount, 347575)
XCTAssertEqual(userInfo.artistCount, 14264)
XCTAssertEqual(userInfo.playlists, 0)
Expand Down Expand Up @@ -1150,6 +1150,101 @@ class UserTests: XCTestCase {
)
)
}

func test_getInfoBySessionKey() throws {
let jsonURL = Bundle.module.url(
forResource: "Resources/user.getInfo",
withExtension: "json"
)!

let fakeData = try Data(contentsOf: jsonURL)
let expectation = expectation(description: "Waiting for getInfo")

apiClientMock.data = fakeData
apiClientMock.response = Constants.RESPONSE_200_OK

try instance.getInfo(sessionKey: "someSessionKey") { result in
switch (result) {
case .success(let userInfo):
XCTAssertEqual(userInfo.name, "pepito")
XCTAssertEqual(userInfo.age, 0)
XCTAssertEqual(userInfo.subscriber, false)
XCTAssertEqual(userInfo.realname, "Jose")
XCTAssertEqual(userInfo.bootstrap, false)
XCTAssertEqual(userInfo.playcount, 347575)
XCTAssertEqual(userInfo.artistCount, 14264)
XCTAssertEqual(userInfo.playlists, 0)
XCTAssertEqual(userInfo.trackCount, 55279)
XCTAssertEqual(userInfo.albumCount, 30492)

XCTAssertEqual(
userInfo.image.small?.absoluteString,
"https://images.com/pepito-small.png"
)

XCTAssertEqual(
userInfo.image.medium?.absoluteString,
"https://images.com/pepito-medium.png"
)

XCTAssertEqual(
userInfo.image.large?.absoluteString,
"https://images.com/pepito-large.png"
)

XCTAssertEqual(
userInfo.image.extraLarge?.absoluteString,
"https://images.com/pepito-extralarge.png"
)

XCTAssertNil(userInfo.image.mega)

var dateComponents = DateComponents()
dateComponents.year = 2011
dateComponents.month = 8
dateComponents.day = 17
dateComponents.hour = 18
dateComponents.minute = 28
dateComponents.second = 10
dateComponents.timeZone = TimeZone(secondsFromGMT: -4 * 60 * 60)

XCTAssertEqual(userInfo.registered, Calendar.current.date(from: dateComponents))
XCTAssertEqual(userInfo.country, "Bolivia")
XCTAssertEqual(userInfo.gender, "n")
XCTAssertEqual(userInfo.url.absoluteString, "https://pepito.profile")
XCTAssertEqual(userInfo.type, "user")
case .failure(let error):
XCTFail("It was supposed to succeed, but it failed with error \(error.localizedDescription)")
}

expectation.fulfill()
}

waitForExpectations(timeout: 3)
XCTAssertEqual(apiClientMock.postCalls.count, 1)

let actualBody = String(data: apiClientMock.postCalls[0].body!, encoding: .utf8)!
let expectedBody = "sk=someSessionKey&method=user.getinfo&api_key=someAPIKey"

XCTAssertTrue(
Util.areSameURL(
"http://somedomain.com/?\(actualBody)",
"http://somedomain.com/?\(expectedBody)"
)
)

XCTAssertEqual(
apiClientMock.postCalls[0].headers,
["Content-Type": "application/x-www-formurlencoded"]
)

XCTAssertTrue(
Util.areSameURL(
"http://ws.audioscrobbler.com/2.0?format=json",
apiClientMock.postCalls[0].url.absoluteString
)
)
}

func test_getFriends_success() throws {
let jsonURL = Bundle.module.url(
Expand Down

0 comments on commit fdd7ecc

Please sign in to comment.