From 91387dda3895607dd919e4ae4492534418bbee2e Mon Sep 17 00:00:00 2001 From: odanylewycz Date: Wed, 1 Jul 2020 13:26:22 -0400 Subject: [PATCH 1/5] Added validate(_ uri: URI) method to Validations struct and Validatable protocol for validating decoded query parameters. --- Sources/Vapor/Validation/Validatable.swift | 4 ++++ Sources/Vapor/Validation/Validations.swift | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/Sources/Vapor/Validation/Validatable.swift b/Sources/Vapor/Validation/Validatable.swift index e174ace389..59566a07ac 100644 --- a/Sources/Vapor/Validation/Validatable.swift +++ b/Sources/Vapor/Validation/Validatable.swift @@ -17,6 +17,10 @@ extension Validatable { try self.validations().validate(request).assert() } + public static func validate(_ uri: URI) throws { + try self.validations().validate(uri).assert() + } + public static func validate(json: String) throws { try self.validations().validate(json: json).assert() } diff --git a/Sources/Vapor/Validation/Validations.swift b/Sources/Vapor/Validation/Validations.swift index d231ed1c35..d9a4ff6447 100644 --- a/Sources/Vapor/Validation/Validations.swift +++ b/Sources/Vapor/Validation/Validations.swift @@ -46,6 +46,14 @@ public struct Validations { return try self.validate(decoder.decoder) } + public func validate(_ uri: URI) throws -> ValidationsResult { + + let urlDecoder = try ContentConfiguration.global.requireURLDecoder() + let decoder = try urlDecoder.decode(DecoderUnwrapper.self, from: uri) + return try self.validate(decoder.decoder) + + } + public func validate(json: String) throws -> ValidationsResult { let decoder = try JSONDecoder().decode(DecoderUnwrapper.self, from: Data(json.utf8)) return try self.validate(decoder.decoder) From cebe0eefdaf1ce59a5c0a306459277af73f9834d Mon Sep 17 00:00:00 2001 From: odanylewycz Date: Thu, 2 Jul 2020 12:46:28 -0400 Subject: [PATCH 2/5] Added tests for decodning query parameters to ValidationTests.swift --- Tests/VaporTests/ValidationTests.swift | 42 ++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/Tests/VaporTests/ValidationTests.swift b/Tests/VaporTests/ValidationTests.swift index 4c00f63175..c9d77fa832 100644 --- a/Tests/VaporTests/ValidationTests.swift +++ b/Tests/VaporTests/ValidationTests.swift @@ -20,7 +20,10 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ + let validUrl: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&isAdmin=true" XCTAssertNoThrow(try User.validate(json: valid)) + XCTAssertNoThrow(try User.validate(validUrl)) + let invalidUser = """ { "name": "Tan!ner", @@ -37,10 +40,16 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ + let invalidUserUrl: URI = "https://tanner.xyz/user?name=Tan!ner&age=24&gender=other&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&isAdmin=true" XCTAssertThrowsError(try User.validate(json: invalidUser)) { error in XCTAssertEqual("\(error)", "name contains '!' (allowed: A-Z, a-z, 0-9)") } + XCTAssertThrowsError(try User.validate(invalidUserUrl)) { error in + XCTAssertEqual("\(error)", + "name contains '!' (allowed: A-Z, a-z, 0-9)") + } + let invalidPet = """ { "name": "Tanner", @@ -57,10 +66,16 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ + let invalidPetURL: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zi!ek&pet[age]=3&isAdmin=true" XCTAssertThrowsError(try User.validate(json: invalidPet)) { error in XCTAssertEqual("\(error)", "pet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") } + XCTAssertThrowsError(try User.validate(invalidPetURL)) { error in + XCTAssertEqual("\(error)", + "pet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") + } + let invalidBool = """ { "name": "Tanner", @@ -77,10 +92,15 @@ class ValidationTests: XCTestCase { "isAdmin": "true" } """ + let invalidPetBool: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&isAdmin='true'" XCTAssertThrowsError(try User.validate(json: invalidBool)) { error in XCTAssertEqual("\(error)", "isAdmin is not a(n) Bool") } + XCTAssertThrowsError(try User.validate(invalidPetBool)) { error in + XCTAssertEqual("\(error)", + "isAdmin is not a(n) Bool") + } let validOptionalFavoritePet = """ { @@ -102,7 +122,9 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ + let validOptionalFavoritePetUrl: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&favoritePet[name]=Zizek&favoritePet[age]=3&&isAdmin=true" XCTAssertNoThrow(try User.validate(json: validOptionalFavoritePet)) + XCTAssertNoThrow(try User.validate(validOptionalFavoritePetUrl)) let invalidOptionalFavoritePet = """ { @@ -124,10 +146,15 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ + let invalidOptionalFavoritePetUrl: URI = "https://tanner.xyz/model?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&favoritePet[name]=Zi!ek&favoritePet[age]=3&&isAdmin=true" XCTAssertThrowsError(try User.validate(json: invalidOptionalFavoritePet)) { error in XCTAssertEqual("\(error)", "favoritePet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") } + XCTAssertThrowsError(try User.validate(invalidOptionalFavoritePetUrl)) { error in + XCTAssertEqual("\(error)", + "favoritePet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") + } } func testCatchError() throws { @@ -147,6 +174,7 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ + let invalidUserUrl: URI = "https://tanner.xyz/user?name=Tan!ner&age=24&gender=other&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&isAdmin=true" do { try User.validate(json: invalidUser) } catch let error as ValidationsError { @@ -161,6 +189,20 @@ class ValidationTests: XCTestCase { let character = and.right as! ValidatorResults.CharacterSet XCTAssertEqual(character.invalidSlice, "!") } + do { + try User.validate(invalidUserUrl) + } catch let error as ValidationsError { + XCTAssertEqual(error.failures.count, 1) + let name = error.failures[0] + XCTAssertEqual(name.key.stringValue, "name") + XCTAssertEqual(name.result.isFailure, true) + XCTAssertEqual(name.result.failureDescription, "contains '!' (allowed: A-Z, a-z, 0-9)") + let and = name.result as! ValidatorResults.And + let count = and.left as! ValidatorResults.Range + XCTAssertEqual(count.result, .greaterThanOrEqualToMin(5)) + let character = and.right as! ValidatorResults.CharacterSet + XCTAssertEqual(character.invalidSlice, "!") + } } func testNotReadability() { From 3bd53606bdca3f045d8e6385b6052f825f2111b2 Mon Sep 17 00:00:00 2001 From: odanylewycz Date: Thu, 2 Jul 2020 12:59:28 -0400 Subject: [PATCH 3/5] Revert "Added tests for decodning query parameters to ValidationTests.swift" This reverts commit cebe0eefdaf1ce59a5c0a306459277af73f9834d. --- Tests/VaporTests/ValidationTests.swift | 42 -------------------------- 1 file changed, 42 deletions(-) diff --git a/Tests/VaporTests/ValidationTests.swift b/Tests/VaporTests/ValidationTests.swift index c9d77fa832..4c00f63175 100644 --- a/Tests/VaporTests/ValidationTests.swift +++ b/Tests/VaporTests/ValidationTests.swift @@ -20,10 +20,7 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ - let validUrl: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&isAdmin=true" XCTAssertNoThrow(try User.validate(json: valid)) - XCTAssertNoThrow(try User.validate(validUrl)) - let invalidUser = """ { "name": "Tan!ner", @@ -40,16 +37,10 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ - let invalidUserUrl: URI = "https://tanner.xyz/user?name=Tan!ner&age=24&gender=other&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&isAdmin=true" XCTAssertThrowsError(try User.validate(json: invalidUser)) { error in XCTAssertEqual("\(error)", "name contains '!' (allowed: A-Z, a-z, 0-9)") } - XCTAssertThrowsError(try User.validate(invalidUserUrl)) { error in - XCTAssertEqual("\(error)", - "name contains '!' (allowed: A-Z, a-z, 0-9)") - } - let invalidPet = """ { "name": "Tanner", @@ -66,16 +57,10 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ - let invalidPetURL: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zi!ek&pet[age]=3&isAdmin=true" XCTAssertThrowsError(try User.validate(json: invalidPet)) { error in XCTAssertEqual("\(error)", "pet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") } - XCTAssertThrowsError(try User.validate(invalidPetURL)) { error in - XCTAssertEqual("\(error)", - "pet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") - } - let invalidBool = """ { "name": "Tanner", @@ -92,15 +77,10 @@ class ValidationTests: XCTestCase { "isAdmin": "true" } """ - let invalidPetBool: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&isAdmin='true'" XCTAssertThrowsError(try User.validate(json: invalidBool)) { error in XCTAssertEqual("\(error)", "isAdmin is not a(n) Bool") } - XCTAssertThrowsError(try User.validate(invalidPetBool)) { error in - XCTAssertEqual("\(error)", - "isAdmin is not a(n) Bool") - } let validOptionalFavoritePet = """ { @@ -122,9 +102,7 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ - let validOptionalFavoritePetUrl: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&favoritePet[name]=Zizek&favoritePet[age]=3&&isAdmin=true" XCTAssertNoThrow(try User.validate(json: validOptionalFavoritePet)) - XCTAssertNoThrow(try User.validate(validOptionalFavoritePetUrl)) let invalidOptionalFavoritePet = """ { @@ -146,15 +124,10 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ - let invalidOptionalFavoritePetUrl: URI = "https://tanner.xyz/model?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&favoritePet[name]=Zi!ek&favoritePet[age]=3&&isAdmin=true" XCTAssertThrowsError(try User.validate(json: invalidOptionalFavoritePet)) { error in XCTAssertEqual("\(error)", "favoritePet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") } - XCTAssertThrowsError(try User.validate(invalidOptionalFavoritePetUrl)) { error in - XCTAssertEqual("\(error)", - "favoritePet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") - } } func testCatchError() throws { @@ -174,7 +147,6 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ - let invalidUserUrl: URI = "https://tanner.xyz/user?name=Tan!ner&age=24&gender=other&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&isAdmin=true" do { try User.validate(json: invalidUser) } catch let error as ValidationsError { @@ -189,20 +161,6 @@ class ValidationTests: XCTestCase { let character = and.right as! ValidatorResults.CharacterSet XCTAssertEqual(character.invalidSlice, "!") } - do { - try User.validate(invalidUserUrl) - } catch let error as ValidationsError { - XCTAssertEqual(error.failures.count, 1) - let name = error.failures[0] - XCTAssertEqual(name.key.stringValue, "name") - XCTAssertEqual(name.result.isFailure, true) - XCTAssertEqual(name.result.failureDescription, "contains '!' (allowed: A-Z, a-z, 0-9)") - let and = name.result as! ValidatorResults.And - let count = and.left as! ValidatorResults.Range - XCTAssertEqual(count.result, .greaterThanOrEqualToMin(5)) - let character = and.right as! ValidatorResults.CharacterSet - XCTAssertEqual(character.invalidSlice, "!") - } } func testNotReadability() { From 29f0c2aa607ae0812513f8dcd1e3a6e54953df39 Mon Sep 17 00:00:00 2001 From: odanylewycz Date: Thu, 2 Jul 2020 13:05:26 -0400 Subject: [PATCH 4/5] Added tests for decoding query parameters to ValidationTests.swift --- Tests/VaporTests/ValidationTests.swift | 42 ++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/Tests/VaporTests/ValidationTests.swift b/Tests/VaporTests/ValidationTests.swift index 4c00f63175..2d002b8b5e 100644 --- a/Tests/VaporTests/ValidationTests.swift +++ b/Tests/VaporTests/ValidationTests.swift @@ -20,7 +20,9 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ + let validUrl: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&isAdmin=true" XCTAssertNoThrow(try User.validate(json: valid)) + XCTAssertNoThrow(try User.validate(validUrl)) let invalidUser = """ { "name": "Tan!ner", @@ -37,9 +39,15 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ + let invalidUserUrl: URI = "https://tanner.xyz/user?name=Tan!ner&age=24&gender=other&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&isAdmin=true" XCTAssertThrowsError(try User.validate(json: invalidUser)) { error in XCTAssertEqual("\(error)", "name contains '!' (allowed: A-Z, a-z, 0-9)") + + } + XCTAssertThrowsError(try User.validate(invalidUserUrl)) { error in + XCTAssertEqual("\(error)", + "name contains '!' (allowed: A-Z, a-z, 0-9)") } let invalidPet = """ { @@ -57,10 +65,15 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ + let invalidPetURL: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zi!ek&pet[age]=3&isAdmin=true" XCTAssertThrowsError(try User.validate(json: invalidPet)) { error in XCTAssertEqual("\(error)", "pet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") } + XCTAssertThrowsError(try User.validate(invalidPetURL)) { error in + XCTAssertEqual("\(error)", + "pet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") + } let invalidBool = """ { "name": "Tanner", @@ -77,11 +90,15 @@ class ValidationTests: XCTestCase { "isAdmin": "true" } """ + let invalidPetBool: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&isAdmin='true'" XCTAssertThrowsError(try User.validate(json: invalidBool)) { error in XCTAssertEqual("\(error)", "isAdmin is not a(n) Bool") } - + XCTAssertThrowsError(try User.validate(invalidPetBool)) { error in + XCTAssertEqual("\(error)", + "isAdmin is not a(n) Bool") + } let validOptionalFavoritePet = """ { "name": "Tanner", @@ -102,8 +119,9 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ + let validOptionalFavoritePetUrl: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&favoritePet[name]=Zizek&favoritePet[age]=3&&isAdmin=true" XCTAssertNoThrow(try User.validate(json: validOptionalFavoritePet)) - + XCTAssertNoThrow(try User.validate(validOptionalFavoritePetUrl)) let invalidOptionalFavoritePet = """ { "name": "Tanner", @@ -124,10 +142,15 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ + let invalidOptionalFavoritePetUrl: URI = "https://tanner.xyz/model?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&favoritePet[name]=Zi!ek&favoritePet[age]=3&&isAdmin=true" XCTAssertThrowsError(try User.validate(json: invalidOptionalFavoritePet)) { error in XCTAssertEqual("\(error)", "favoritePet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") } + XCTAssertThrowsError(try User.validate(invalidOptionalFavoritePetUrl)) { error in + XCTAssertEqual("\(error)", + "favoritePet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") + } } func testCatchError() throws { @@ -147,6 +170,7 @@ class ValidationTests: XCTestCase { "isAdmin": true } """ + let invalidUserUrl: URI = "https://tanner.xyz/user?name=Tan!ner&age=24&gender=other&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&isAdmin=true" do { try User.validate(json: invalidUser) } catch let error as ValidationsError { @@ -161,6 +185,20 @@ class ValidationTests: XCTestCase { let character = and.right as! ValidatorResults.CharacterSet XCTAssertEqual(character.invalidSlice, "!") } + do { + try User.validate(invalidUserUrl) + } catch let error as ValidationsError { + XCTAssertEqual(error.failures.count, 1) + let name = error.failures[0] + XCTAssertEqual(name.key.stringValue, "name") + XCTAssertEqual(name.result.isFailure, true) + XCTAssertEqual(name.result.failureDescription, "contains '!' (allowed: A-Z, a-z, 0-9)") + let and = name.result as! ValidatorResults.And + let count = and.left as! ValidatorResults.Range + XCTAssertEqual(count.result, .greaterThanOrEqualToMin(5)) + let character = and.right as! ValidatorResults.CharacterSet + XCTAssertEqual(character.invalidSlice, "!") + } } func testNotReadability() { From d4a02a00834d8986bf70e684604aa62d1b61757d Mon Sep 17 00:00:00 2001 From: odanylewycz Date: Thu, 16 Jul 2020 11:39:52 -0400 Subject: [PATCH 5/5] Updated Validatble Protocol validate methods for better readablility. Added old method to Deprecations. --- .../Vapor/Deprecations/Validatable+validate.swift | 6 ++++++ Sources/Vapor/Validation/Validatable.swift | 12 ++++++++---- Sources/Vapor/Validation/Validations.swift | 8 +++----- Tests/VaporTests/RouteTests.swift | 2 +- Tests/VaporTests/ValidationTests.swift | 14 +++++++------- 5 files changed, 25 insertions(+), 17 deletions(-) create mode 100644 Sources/Vapor/Deprecations/Validatable+validate.swift diff --git a/Sources/Vapor/Deprecations/Validatable+validate.swift b/Sources/Vapor/Deprecations/Validatable+validate.swift new file mode 100644 index 0000000000..56055a795a --- /dev/null +++ b/Sources/Vapor/Deprecations/Validatable+validate.swift @@ -0,0 +1,6 @@ +extension Validatable { + @available(*, deprecated, renamed: "validate(content:)") + public static func validate(_ request: Request) throws { + try self.validations().validate(request: request).assert() + } +} diff --git a/Sources/Vapor/Validation/Validatable.swift b/Sources/Vapor/Validation/Validatable.swift index 59566a07ac..0e93128c4c 100644 --- a/Sources/Vapor/Validation/Validatable.swift +++ b/Sources/Vapor/Validation/Validatable.swift @@ -13,18 +13,22 @@ public protocol Validatable { } extension Validatable { - public static func validate(_ request: Request) throws { - try self.validations().validate(request).assert() + public static func validate(content request: Request) throws { + try self.validations().validate(request: request).assert() } - public static func validate(_ uri: URI) throws { - try self.validations().validate(uri).assert() + public static func validate(query request: Request) throws { + try self.validations().validate(query: request.url).assert() } public static func validate(json: String) throws { try self.validations().validate(json: json).assert() } + public static func validate(query: URI) throws { + try self.validations().validate(query: query).assert() + } + public static func validate(_ decoder: Decoder) throws { try self.validations().validate(decoder).assert() } diff --git a/Sources/Vapor/Validation/Validations.swift b/Sources/Vapor/Validation/Validations.swift index d9a4ff6447..0eba04bc8f 100644 --- a/Sources/Vapor/Validation/Validations.swift +++ b/Sources/Vapor/Validation/Validations.swift @@ -34,7 +34,7 @@ public struct Validations { self.storage.append(validation) } - public func validate(_ request: Request) throws -> ValidationsResult { + public func validate(request: Request) throws -> ValidationsResult { guard let contentType = request.headers.contentType else { throw Abort(.unprocessableEntity) } @@ -46,12 +46,10 @@ public struct Validations { return try self.validate(decoder.decoder) } - public func validate(_ uri: URI) throws -> ValidationsResult { - + public func validate(query: URI) throws -> ValidationsResult { let urlDecoder = try ContentConfiguration.global.requireURLDecoder() - let decoder = try urlDecoder.decode(DecoderUnwrapper.self, from: uri) + let decoder = try urlDecoder.decode(DecoderUnwrapper.self, from: query) return try self.validate(decoder.decoder) - } public func validate(json: String) throws -> ValidationsResult { diff --git a/Tests/VaporTests/RouteTests.swift b/Tests/VaporTests/RouteTests.swift index 2b8c67a8f0..0aea0a4a8f 100644 --- a/Tests/VaporTests/RouteTests.swift +++ b/Tests/VaporTests/RouteTests.swift @@ -150,7 +150,7 @@ final class RouteTests: XCTestCase { defer { app.shutdown() } app.post("users") { req -> User in - try User.validate(req) + try User.validate(content: req) return try req.content.decode(User.self) } diff --git a/Tests/VaporTests/ValidationTests.swift b/Tests/VaporTests/ValidationTests.swift index 2d002b8b5e..fdf7cbf8dd 100644 --- a/Tests/VaporTests/ValidationTests.swift +++ b/Tests/VaporTests/ValidationTests.swift @@ -22,7 +22,7 @@ class ValidationTests: XCTestCase { """ let validUrl: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&isAdmin=true" XCTAssertNoThrow(try User.validate(json: valid)) - XCTAssertNoThrow(try User.validate(validUrl)) + XCTAssertNoThrow(try User.validate(query: validUrl)) let invalidUser = """ { "name": "Tan!ner", @@ -45,7 +45,7 @@ class ValidationTests: XCTestCase { "name contains '!' (allowed: A-Z, a-z, 0-9)") } - XCTAssertThrowsError(try User.validate(invalidUserUrl)) { error in + XCTAssertThrowsError(try User.validate(query: invalidUserUrl)) { error in XCTAssertEqual("\(error)", "name contains '!' (allowed: A-Z, a-z, 0-9)") } @@ -70,7 +70,7 @@ class ValidationTests: XCTestCase { XCTAssertEqual("\(error)", "pet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") } - XCTAssertThrowsError(try User.validate(invalidPetURL)) { error in + XCTAssertThrowsError(try User.validate(query: invalidPetURL)) { error in XCTAssertEqual("\(error)", "pet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") } @@ -95,7 +95,7 @@ class ValidationTests: XCTestCase { XCTAssertEqual("\(error)", "isAdmin is not a(n) Bool") } - XCTAssertThrowsError(try User.validate(invalidPetBool)) { error in + XCTAssertThrowsError(try User.validate(query: invalidPetBool)) { error in XCTAssertEqual("\(error)", "isAdmin is not a(n) Bool") } @@ -121,7 +121,7 @@ class ValidationTests: XCTestCase { """ let validOptionalFavoritePetUrl: URI = "https://tanner.xyz/user?name=Tanner&age=24&gender=male&email=me@tanner.xyz&luckyNumber=5&profilePictureURL=https://foo.jpg&preferredColors=[blue]&pet[name]=Zizek&pet[age]=3&favoritePet[name]=Zizek&favoritePet[age]=3&&isAdmin=true" XCTAssertNoThrow(try User.validate(json: validOptionalFavoritePet)) - XCTAssertNoThrow(try User.validate(validOptionalFavoritePetUrl)) + XCTAssertNoThrow(try User.validate(query: validOptionalFavoritePetUrl)) let invalidOptionalFavoritePet = """ { "name": "Tanner", @@ -147,7 +147,7 @@ class ValidationTests: XCTestCase { XCTAssertEqual("\(error)", "favoritePet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") } - XCTAssertThrowsError(try User.validate(invalidOptionalFavoritePetUrl)) { error in + XCTAssertThrowsError(try User.validate(query: invalidOptionalFavoritePetUrl)) { error in XCTAssertEqual("\(error)", "favoritePet name contains '!' (allowed: whitespace, A-Z, a-z, 0-9)") } @@ -186,7 +186,7 @@ class ValidationTests: XCTestCase { XCTAssertEqual(character.invalidSlice, "!") } do { - try User.validate(invalidUserUrl) + try User.validate(query: invalidUserUrl) } catch let error as ValidationsError { XCTAssertEqual(error.failures.count, 1) let name = error.failures[0]