diff --git a/README.md b/README.md index 1bba241..df8d8d8 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,17 @@ import DogAPI let dogAPI = DogAPI() ``` -### Fetch All Breeds +### Fetch Breeds & Sub-Breeds ```swift do { - // fetch list of all breeds and sub-breeds + // fetch list of all breeds let breeds = try await dogAPI.fetchAllBreeds() print(breeds) + // fetch list of all sub-breeds of a breed + let subBreeds = try await dogAPI.fetchAllSubBreeds(breed: "retriever") + print(subBreeds) } catch { - print("Error fetching breeds: \(error)") + print("Error fetching breeds & sub-breeds: \(error)") } ``` diff --git a/Sources/DogAPI/DogAPI.swift b/Sources/DogAPI/DogAPI.swift index de2a853..fad32be 100644 --- a/Sources/DogAPI/DogAPI.swift +++ b/Sources/DogAPI/DogAPI.swift @@ -20,6 +20,13 @@ public struct DogAPI { try await client.fetch(.allBreeds) } + /// Fetch list of all sub-breeds for a breed + /// - Parameter breed: breed to fetch sub-breeds for + /// - Returns: list of sub-breeds for the breed + public func fetchAllSubBreeds(breed: DogBreed) async throws -> [DogSubBreed] { + try await client.fetch(.allSubBreeds(breed)) + } + /// Fetch single random image from all dogs collection /// - Returns: URL of random dog image public func fetchRandomImage() async throws -> DogURL { diff --git a/Sources/DogAPI/DogAPIEndpoint.swift b/Sources/DogAPI/DogAPIEndpoint.swift index 8043d4c..1fd4738 100644 --- a/Sources/DogAPI/DogAPIEndpoint.swift +++ b/Sources/DogAPI/DogAPIEndpoint.swift @@ -24,7 +24,7 @@ enum DogAPIEndpoint { case .allBreeds: "breeds/list/all" case .allSubBreeds(let breed): - "breeds/\(breed)/list" + "breed/\(breed)/list" case .randomImage: "breeds/image/random" case .randomImages(let count): diff --git a/Tests/DogAPITests/DogAPITests.swift b/Tests/DogAPITests/DogAPITests.swift index 69efb2f..907a4b5 100644 --- a/Tests/DogAPITests/DogAPITests.swift +++ b/Tests/DogAPITests/DogAPITests.swift @@ -25,6 +25,18 @@ final class DogAPITests: XCTestCase { XCTAssertEqual(breeds, ["affenpinscher":[],"african":[],"airedale":[],"akita":[],"appenzeller":[],"australian":["kelpie","shepherd"]]) } + func test_fetchAllSubBreeds_success_allSubBreeds() async throws { + // given the all sub-breeds request will succeed + let url = URL(string: "https://dog.ceo/api/breed/hound/list")! + let expectedResponse = HTTPURLResponse(url: url, statusCode: 200, httpVersion: nil, headerFields: nil) + let expectedData = #"{"message":["afghan","basset","blood","english","ibizan","plott","walker"],"status":"success"}"#.data(using: .utf8)! + MockURLProtocol.expect(.init(data: expectedData, response: expectedResponse), for: url) + // when user requests all sub-breeds for a breed + let subBreeds = try await api.fetchAllSubBreeds(breed: "hound") + // then all sub-breeds are returned + XCTAssertEqual(subBreeds, ["afghan","basset","blood","english","ibizan","plott","walker"]) + } + func test_fetchRandomImage_success_randomImage() async throws { // given random image request will succeed let url = URL(string: "https://dog.ceo/api/breeds/image/random")!