Skip to content

Commit

Permalink
[file_selector] Fix unknown extensions on macOS (#4946)
Browse files Browse the repository at this point in the history
Fixes a bug in the type lookup that would cause the dynamic `UTType` created for unknown extensions to not work as a save/open panel filter.

As incidental cleanup, removes test timeouts that shouldn't exist per Flutter policy.

Fixes flutter/flutter#134963
  • Loading branch information
stuartmorgan authored Sep 18, 2023
1 parent 09df102 commit 98659b7
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 19 deletions.
4 changes: 4 additions & 0 deletions packages/file_selector/file_selector_macos/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.9.3+3

* Fixes handling of unknown file extensions on macOS 11+.

## 0.9.3+2

* Adds pub topics to package metadata.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class exampleTests: XCTestCase {
called.fulfill()
}

wait(for: [called], timeout: 0.5)
wait(for: [called])
XCTAssertNotNil(panelController.openPanel)
if let panel = panelController.openPanel {
XCTAssertTrue(panel.canChooseFiles)
Expand Down Expand Up @@ -104,7 +104,7 @@ class exampleTests: XCTestCase {
called.fulfill()
}

wait(for: [called], timeout: 0.5)
wait(for: [called])
XCTAssertNotNil(panelController.openPanel)
if let panel = panelController.openPanel {
XCTAssertEqual(panel.directoryURL?.path, "/some/dir")
Expand Down Expand Up @@ -140,7 +140,7 @@ class exampleTests: XCTestCase {
called.fulfill()
}

wait(for: [called], timeout: 0.5)
wait(for: [called])
XCTAssertNotNil(panelController.openPanel)
}

Expand Down Expand Up @@ -173,7 +173,7 @@ class exampleTests: XCTestCase {
called.fulfill()
}

wait(for: [called], timeout: 0.5)
wait(for: [called])
XCTAssertNotNil(panelController.openPanel)
if let panel = panelController.openPanel {
if #available(macOS 11.0, *) {
Expand All @@ -188,6 +188,51 @@ class exampleTests: XCTestCase {
}
}

func testFilterUnknownFileExtension() throws {
let panelController = TestPanelController()
let plugin = FileSelectorPlugin(
viewProvider: TestViewProvider(),
panelController: panelController)

let unknownExtension = "somenewextension"
let returnPath = "/foo/bar"
panelController.openURLs = [URL(fileURLWithPath: returnPath)]

let called = XCTestExpectation()
let options = OpenPanelOptions(
allowsMultipleSelection: true,
canChooseDirectories: false,
canChooseFiles: true,
baseOptions: SavePanelOptions(
allowedFileTypes: AllowedTypes(
extensions: [unknownExtension],
mimeTypes: [],
utis: [])))
plugin.displayOpenPanel(options: options) { result in
switch result {
case .success(let paths):
XCTAssertEqual(paths[0], returnPath)
case .failure(let error):
XCTFail("\(error)")
}
called.fulfill()
}

wait(for: [called])
XCTAssertNotNil(panelController.openPanel)
if let panel = panelController.openPanel {
if #available(macOS 11.0, *) {
XCTAssertEqual(panel.allowedContentTypes.count, 1)
XCTAssertEqual(panel.allowedContentTypes[0].preferredFilenameExtension, unknownExtension)
// If this isn't true, the dynamic type created for the extension won't work as a file
// extension filter.
XCTAssertTrue(panel.allowedContentTypes[0].conforms(to: UTType.data))
} else {
XCTAssertEqual(panel.allowedFileTypes, [unknownExtension])
}
}
}

func testOpenWithFilterLegacy() throws {
let panelController = TestPanelController()
let plugin = FileSelectorPlugin(
Expand Down Expand Up @@ -218,7 +263,7 @@ class exampleTests: XCTestCase {
called.fulfill()
}

wait(for: [called], timeout: 0.5)
wait(for: [called])
XCTAssertNotNil(panelController.openPanel)
if let panel = panelController.openPanel {
// On the legacy path, the allowedFileTypes should be set directly.
Expand Down Expand Up @@ -257,7 +302,7 @@ class exampleTests: XCTestCase {
called.fulfill()
}

wait(for: [called], timeout: 0.5)
wait(for: [called])
XCTAssertNotNil(panelController.openPanel)
}

Expand All @@ -282,7 +327,7 @@ class exampleTests: XCTestCase {
called.fulfill()
}

wait(for: [called], timeout: 0.5)
wait(for: [called])
XCTAssertNotNil(panelController.savePanel)
}

Expand All @@ -309,7 +354,7 @@ class exampleTests: XCTestCase {
called.fulfill()
}

wait(for: [called], timeout: 0.5)
wait(for: [called])
XCTAssertNotNil(panelController.savePanel)
if let panel = panelController.savePanel {
XCTAssertEqual(panel.directoryURL?.path, "/some/dir")
Expand All @@ -335,7 +380,7 @@ class exampleTests: XCTestCase {
called.fulfill()
}

wait(for: [called], timeout: 0.5)
wait(for: [called])
XCTAssertNotNil(panelController.savePanel)
}

Expand Down Expand Up @@ -364,7 +409,7 @@ class exampleTests: XCTestCase {
called.fulfill()
}

wait(for: [called], timeout: 0.5)
wait(for: [called])
XCTAssertNotNil(panelController.openPanel)
if let panel = panelController.openPanel {
XCTAssertTrue(panel.canChooseDirectories)
Expand Down Expand Up @@ -398,7 +443,7 @@ class exampleTests: XCTestCase {
called.fulfill()
}

wait(for: [called], timeout: 0.5)
wait(for: [called])
XCTAssertNotNil(panelController.openPanel)
}

Expand All @@ -408,7 +453,7 @@ class exampleTests: XCTestCase {
viewProvider: TestViewProvider(),
panelController: panelController)

let returnPaths = ["/foo/bar", "/foo/test"];
let returnPaths = ["/foo/bar", "/foo/test"]
panelController.openURLs = returnPaths.map({ path in URL(fileURLWithPath: path) })

let called = XCTestExpectation()
Expand All @@ -427,7 +472,7 @@ class exampleTests: XCTestCase {
called.fulfill()
}

wait(for: [called], timeout: 0.5)
wait(for: [called])
XCTAssertNotNil(panelController.openPanel)
if let panel = panelController.openPanel {
XCTAssertTrue(panel.canChooseDirectories)
Expand Down Expand Up @@ -459,7 +504,7 @@ class exampleTests: XCTestCase {
called.fulfill()
}

wait(for: [called], timeout: 0.5)
wait(for: [called])
XCTAssertNotNil(panelController.openPanel)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@ public class FileSelectorPlugin: NSObject, FlutterPlugin, FileSelectorApi {
// that via the types; see messages.dart and https://github.com/flutter/flutter/issues/97848
allowedTypes.append(contentsOf: acceptedTypes.utis.compactMap({ UTType($0!) }))
allowedTypes.append(
contentsOf: acceptedTypes.extensions.flatMap({
UTType.types(tag: $0!, tagClass: UTTagClass.filenameExtension, conformingTo: nil)
contentsOf: acceptedTypes.extensions.compactMap({
UTType.init(filenameExtension: $0!)
}))
allowedTypes.append(
contentsOf: acceptedTypes.mimeTypes.flatMap({
UTType.types(tag: $0!, tagClass: UTTagClass.mimeType, conformingTo: nil)
contentsOf: acceptedTypes.mimeTypes.compactMap({
UTType.init(mimeType: $0!)
}))
if !allowedTypes.isEmpty {
panel.allowedContentTypes = allowedTypes
Expand Down
2 changes: 1 addition & 1 deletion packages/file_selector/file_selector_macos/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: file_selector_macos
description: macOS implementation of the file_selector plugin.
repository: https://github.com/flutter/packages/tree/main/packages/file_selector/file_selector_macos
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22
version: 0.9.3+2
version: 0.9.3+3

environment:
sdk: ">=2.19.0 <4.0.0"
Expand Down

0 comments on commit 98659b7

Please sign in to comment.