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

Filename validator #92

Merged
merged 23 commits into from
Aug 23, 2024
Merged
24 changes: 15 additions & 9 deletions Sources/NextcloudKit/Utils/FileNameValidator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,47 +28,48 @@ public class FileNameValidator {
return instance
}()

public var forbiddenFileNames: [String] = [] {
public private(set) var forbiddenFileNames: [String] = [] {
didSet {
forbiddenFileNames = forbiddenFileNames.map({$0.uppercased()})
}
}
public var forbiddenFileNameBasenames: [String] = [] {

public private(set) var forbiddenFileNameBasenames: [String] = [] {
didSet {
forbiddenFileNameBasenames = forbiddenFileNameBasenames.map({$0.uppercased()})
}
}

private var forbiddenFileNameCharactersRegex: NSRegularExpression?

public var forbiddenFileNameCharacters: [String] = [] {
public private(set) var forbiddenFileNameCharacters: [String] = [] {
didSet {
forbiddenFileNameCharactersRegex = try? NSRegularExpression(pattern: "[\(forbiddenFileNameCharacters.joined())]")
}
}

public var forbiddenFileNameExtensions: [String] = [] {
public private(set) var forbiddenFileNameExtensions: [String] = [] {
didSet {
forbiddenFileNameExtensions = forbiddenFileNameExtensions.map({$0.uppercased()})
}
}

public let fileEndsWithSpacePeriodError = NKError(errorCode: NSURLErrorCannotCreateFile, errorDescription: NSLocalizedString("_file_name_validator_error_ends_with_space_period_", value: "File name ends with a space or a period", comment: ""))
public let fileEndsWithSpacePeriodError = NKError(errorCode: NSURLErrorCannotCreateFile, errorDescription: NSLocalizedString("_file_name_validator_error_ends_with_space_period_", value: "File name ends with a space or a period.", comment: ""))

public var fileReservedNameError: NKError {
let errorMessageTemplate = NSLocalizedString("_file_name_validator_error_reserved_name_", value: "%@ is a reserved name", comment: "")
let errorMessageTemplate = NSLocalizedString("_file_name_validator_error_reserved_name_", value: "\"%@\" is a forbidden name.", comment: "")
let errorMessage = String(format: errorMessageTemplate, templateString)
return NKError(errorCode: NSURLErrorCannotCreateFile, errorDescription: errorMessage)
}

public var fileForbiddenFileExtensionError: NKError {
let errorMessageTemplate = NSLocalizedString("_file_name_validator_error_forbidden_file_extension_", value: ".%@ is a forbidden file extension", comment: "")
let errorMessageTemplate = NSLocalizedString("_file_name_validator_error_forbidden_file_extension_", value: ".\"%@\" is a forbidden file extension.", comment: "")
let errorMessage = String(format: errorMessageTemplate, templateString)
return NKError(errorCode: NSURLErrorCannotCreateFile, errorDescription: errorMessage)
}

public var fileInvalidCharacterError: NKError {
let errorMessageTemplate = NSLocalizedString("file_name_validator_error_invalid_character_", value: "File name contains an invalid character: %@", comment: "")
let errorMessageTemplate = NSLocalizedString("_file_name_validator_error_invalid_character_", value: "Name contains an invalid character: \"%@\".", comment: "")
let errorMessage = String(format: errorMessageTemplate, templateString)
return NKError(errorCode: NSURLErrorCannotCreateFile, errorDescription: errorMessage)
}
Expand All @@ -84,7 +85,7 @@ public class FileNameValidator {
self.forbiddenFileNameExtensions = forbiddenFileNameExtensions
}

public func checkFileName(_ filename: String, existedFileNames: Set<String>? = nil) -> NKError? {
public func checkFileName(_ filename: String) -> NKError? {
if filename.hasSuffix(" ") || filename.hasSuffix(".") {
return fileEndsWithSpacePeriodError
}
Expand All @@ -107,6 +108,11 @@ public class FileNameValidator {
return nil
}

public func checkFolderPath(folderPath: String) -> Bool {
return folderPath.split { $0 == "/" || $0 == "\\" }
.allSatisfy { checkFileName(String($0)) == nil }
}

private func checkInvalidCharacters(string: String) -> NKError? {
for char in string {
let charAsString = String(char)
Expand Down
46 changes: 44 additions & 2 deletions Tests/NextcloudKitUnitTests/FileNameValidatorTests.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// fileNameValidatorTests.swift
//
//
//
//
// Created by Milen Pivchev on 12.07.24.
// Copyright © 2024 Milen Pivchev. All rights reserved.
//
Expand Down Expand Up @@ -66,4 +66,46 @@ class FileNameValidatorTests: XCTestCase {
let result = fileNameValidator.checkFileName("validFileName")
XCTAssertNil(result?.errorDescription)
}

func testValidFolderAndFilePaths() {
let folderPath = "validFolder"

let result = fileNameValidator.checkFolderPath(folderPath: folderPath)
XCTAssertTrue(result)
}

func testFolderPathWithReservedName() {
let folderPath = "CON"

let result = fileNameValidator.checkFolderPath(folderPath: folderPath)
XCTAssertFalse(result)
}

func testFolderPathWithInvalidCharacter() {
let folderPath = "invalid<Folder"

let result = fileNameValidator.checkFolderPath(folderPath: folderPath)
XCTAssertFalse(result)
}

func testFolderPathEndingWithSpace() {
let folderPath = "folderWithSpace "

let result = fileNameValidator.checkFolderPath(folderPath: folderPath)
XCTAssertFalse(result)
}

func testFolderPathEndingWithPeriod() {
let folderPath = "validFolder."

let result = fileNameValidator.checkFolderPath(folderPath: folderPath)
XCTAssertFalse(result)
}

func testFilePathWithNestedFolder() {
let folderPath = "validFolder/secondValidFolder/CON"

let result = fileNameValidator.checkFolderPath(folderPath: folderPath)
XCTAssertFalse(result)
}
}
Loading