Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download schema relative to root url #2609

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 33 additions & 18 deletions Sources/ApolloCodegenLib/ApolloSchemaDownloader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public struct ApolloSchemaDownloader {
introspection: endpointURL,
httpMethod: httpMethod,
includeDeprecatedInputValues: includeDeprecatedInputValues,
configuration: configuration
configuration: configuration,
withRootURL: rootURL
)

case .apolloRegistry(let settings):
Expand Down Expand Up @@ -93,6 +94,27 @@ public struct ApolloSchemaDownloader {
return request
}

static func write(
_ string: String,
path: String,
rootURL: URL?,
fileManager: ApolloFileManager = .default
) throws {

let outputURL: URL
if let rootURL = rootURL {
outputURL = URL(fileURLWithPath: path, relativeTo: rootURL)
} else {
outputURL = URL(fileURLWithPath: path).standardizedFileURL
}

guard let data = string.data(using: .utf8) else {
throw SchemaDownloadError.couldNotCreateSDLDataToWrite(schema: string)
}

try fileManager.createFile(atPath: outputURL.path, data: data, overwrite: true)
}

// MARK: - Schema Registry

static let RegistryEndpoint = URL(string: "https://graphql.api.apollographql.com/api/graphql")!
Expand Down Expand Up @@ -206,12 +228,7 @@ public struct ApolloSchemaDownloader {
throw SchemaDownloadError.couldNotExtractSDLFromRegistryJSON
}

guard let sdlData = sdlSchema.data(using: .utf8) else {
throw SchemaDownloadError.couldNotCreateSDLDataToWrite(schema: sdlSchema)
}

let outputURL = URL(fileURLWithPath: configuration.outputPath, relativeTo: rootURL)
try sdlData.write(to: outputURL)
try write(sdlSchema, path: configuration.outputPath, rootURL: rootURL)
}

// MARK: - Schema Introspection
Expand Down Expand Up @@ -321,7 +338,8 @@ public struct ApolloSchemaDownloader {
introspection endpoint: URL,
httpMethod: ApolloSchemaDownloadConfiguration.DownloadMethod.HTTPMethod,
includeDeprecatedInputValues: Bool,
configuration: ApolloSchemaDownloadConfiguration
configuration: ApolloSchemaDownloadConfiguration,
withRootURL: URL?
) throws {

CodegenLogger.log("Downloading schema via introspection from \(endpoint)", logLevel: .debug)
Expand All @@ -335,11 +353,11 @@ public struct ApolloSchemaDownloader {

let jsonOutputURL: URL = {
switch configuration.outputFormat {
case .SDL: return URL(fileURLWithPath: configuration.outputPath)
case .SDL: return URL(fileURLWithPath: configuration.outputPath, relativeTo: withRootURL)
.parentFolderURL()
.appendingPathComponent("introspection_response.json")

case .JSON: return URL(fileURLWithPath: configuration.outputPath)
case .JSON: return URL(fileURLWithPath: configuration.outputPath, relativeTo: withRootURL)
}
}()

Expand All @@ -353,7 +371,8 @@ public struct ApolloSchemaDownloader {
if configuration.outputFormat == .SDL {
try convertFromIntrospectionJSONToSDLFile(
jsonFileURL: jsonOutputURL,
configuration: configuration
configuration: configuration,
withRootURL: withRootURL
)
}

Expand Down Expand Up @@ -403,7 +422,8 @@ public struct ApolloSchemaDownloader {

static func convertFromIntrospectionJSONToSDLFile(
jsonFileURL: URL,
configuration: ApolloSchemaDownloadConfiguration
configuration: ApolloSchemaDownloadConfiguration,
withRootURL rootURL: URL?
) throws {

defer {
Expand All @@ -427,12 +447,7 @@ public struct ApolloSchemaDownloader {
throw SchemaDownloadError.couldNotConvertIntrospectionJSONToSDL(underlying: error)
}

let outputURL = URL(fileURLWithPath: configuration.outputPath)
try sdlSchema.write(
to: outputURL,
atomically: true,
encoding: .utf8
)
try write(sdlSchema, path: configuration.outputPath, rootURL: rootURL)
}
}
#endif
108 changes: 107 additions & 1 deletion Tests/ApolloCodegenTests/ApolloSchemaInternalTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import ApolloCodegenInternalTestHelpers
@testable import ApolloCodegenLib

class ApolloSchemaInternalTests: XCTestCase {
let mockFileManager = MockApolloFileManager(strict: true)

// MARK: Conversion Tests

func testFormatConversion_givenIntrospectionJSON_shouldOutputValidSDL() throws {
let bundle = Bundle(for: type(of: self))
guard let jsonURL = bundle.url(forResource: "introspection_response", withExtension: "json") else {
Expand All @@ -16,7 +20,11 @@ class ApolloSchemaInternalTests: XCTestCase {
outputPath: CodegenTestHelper.schemaOutputURL().path
)

try ApolloSchemaDownloader.convertFromIntrospectionJSONToSDLFile(jsonFileURL: jsonURL, configuration: configuration)
try ApolloSchemaDownloader.convertFromIntrospectionJSONToSDLFile(
jsonFileURL: jsonURL,
configuration: configuration,
withRootURL: nil
)
XCTAssertTrue(ApolloFileManager.default.doesFileExist(atPath: configuration.outputPath))

let frontend = try GraphQLJSFrontend()
Expand All @@ -30,6 +38,8 @@ class ApolloSchemaInternalTests: XCTestCase {
XCTAssertEqual(postType?.name, "Post")
}

// MARK: Request Tests

func testRequest_givenIntrospectionGETDownload_shouldOutputGETRequest() throws {
let url = ApolloInternalTestHelpers.TestURL.mockServer.url
let queryParameterName = "customParam"
Expand Down Expand Up @@ -145,4 +155,100 @@ class ApolloSchemaInternalTests: XCTestCase {

XCTAssertEqual(request.httpBody, bodyData)
}

// MARK: Path Tests

func test__write__givenRelativePath_noRootURL_shouldUseRelativePath() throws {
// given
let path = "./subfolder/output.test"

mockFileManager.base.changeCurrentDirectoryPath(CodegenTestHelper.outputFolderURL().path)

mockFileManager.mock(closure: .fileExists({ path, isDirectory in
return false
}))

mockFileManager.mock(closure: .createDirectory({ path, intermediateDirectories, attributes in
// no-op
}))

mockFileManager.mock(closure: .createFile({ path, data, attributes in
let expected = CodegenTestHelper.outputFolderURL()
.appendingPathComponent("subfolder/output.test").path

// then
XCTAssertEqual(path, expected)

return true
}))

// when
try ApolloSchemaDownloader.write(
"Test File",
path: path,
rootURL: nil,
fileManager: mockFileManager)
}

func test__write__givenAbsolutePath_noRootURL_shouldUseAbsolutePath() throws {
// given
let path = "/absolute/path/subfolder/output.test"

mockFileManager.base.changeCurrentDirectoryPath(CodegenTestHelper.outputFolderURL().path)

mockFileManager.mock(closure: .fileExists({ path, isDirectory in
return false
}))

mockFileManager.mock(closure: .createDirectory({ path, intermediateDirectories, attributes in
// no-op
}))

mockFileManager.mock(closure: .createFile({ path, data, attributes in
let expected = "/absolute/path/subfolder/output.test"

// then
XCTAssertEqual(path, expected)

return true
}))

// when
try ApolloSchemaDownloader.write(
"Test File",
path: path,
rootURL: nil,
fileManager: mockFileManager)
}

func test__write__givenPath_withRootURL_shouldExtendRootURL() throws {
// given
let path = "output.test"

mockFileManager.base.changeCurrentDirectoryPath(CodegenTestHelper.outputFolderURL().path)

mockFileManager.mock(closure: .fileExists({ path, isDirectory in
return false
}))

mockFileManager.mock(closure: .createDirectory({ path, intermediateDirectories, attributes in
// no-op
}))

mockFileManager.mock(closure: .createFile({ path, data, attributes in
let expected = "/rootURL/path/output.test"

// then
XCTAssertEqual(path, expected)

return true
}))

// when
try ApolloSchemaDownloader.write(
"Test File",
path: path,
rootURL: URL(fileURLWithPath: "/rootURL/path/"),
fileManager: mockFileManager)
}
}