【问题标题】:Authenticated Vapor session not preserved inside an XCTestXCTest 中未保留经过身份验证的 Vapor 会话
【发布时间】:2020-05-29 10:43:44
【问题描述】:

应用程序本身运行良好,但我无法进行确认这一点的测试。

在下面的第 1 部分中,测试检查使用电子邮件和(正确的)密码登录是否成功,并返回正确的 URL 重定向。在重定向返回测试之前的代码中,调试显示对request.auth.require(User.self) 的调用成功。

在第 2a 部分和第 2b 部分中,XCTAssertEqual 失败,并且日志显示调用 request.auth.require(User.self) 的结果引发了错误,提示用户未获得授权。

第 3 部分再次检查第 1 部分是否正常工作,因为它也为不成功的登录返回正确的 URL 重定向。

因此,似乎会话数据在调用.test(...) 之后没有被保留。有没有办法解决这个问题?

@testable import App
import XCTVapor
final class AppTests: XCTestCase
{
    func test011UserLoginLogout() throws
    {
        func attemptLogin(withPassword password:String, completion:(XCTHTTPResponse) throws -> ()) throws -> Void
        {
            var body = ByteBufferAllocator().buffer(capacity: 0)
            body.writeString(#"{"email":"me@example.com","password":"\#(password)"}"#)
            var headers = HTTPHeaders()
            headers.replaceOrAdd(name: .contentLength, value: body.readableBytes.description)
            headers.contentType = .json
            try app.test(.POST, "/login", headers:headers, body:body) { response in try completion( response ) }
        }

        var app = Application(.testing)
        app.databases.use(.mysql(hostname:DBHost, username:DBAccount, password:DBPassword, database:DBDatabase, tlsConfiguration:.none), as:.mysql)
        app.databases.default(to:.mysql)
        do { try configure(app!) }
        catch { XCTFail("configure(app) failed") }
        //  Part 1 succeeds
        try attemptLogin(withPassword:"goodPassword")
        {
            res in
            XCTAssertEqual(res.status, HTTPResponseStatus.seeOther)
            XCTAssertEqual(res.headers["location"].first,"success")
            try app!.test(.GET, "/success")
            {
                response in
                XCTAssertEqual(response.status, .ok) // <--- Part 2(a) fails
            }
        }

        try app.test(.GET, "/success")
        {
            response in
            XCTAssertEqual(response.status, .ok) // <-- Part 2(b) fails
        }

        // Part 3 succeeds
        try attemptLogin(withPassword:"badPassword")
        {
            response in
            XCTAssertEqual(response.status, .seeOther)
            XCTAssertEqual(response.headers["location"].first,"failed")
        }
    }
}

【问题讨论】:

    标签: swift xctest vapor


    【解决方案1】:

    我认为您在失败的请求中缺少身份验证。如果使用会话,则需要将会话 cookie 传递给失败的请求,如果使用承载身份验证,则需要将令牌传递给失败的请求。

    【讨论】:

    • 谢谢,@0xTim。有意思,我去看看。我也许可以从对登录后测试的响应中捕获 cookie,然后手动传递它。
    • 一路走来,@0xTim!我现在将会话 cookie 传递到请求标头中,但它仍然失败,因为 XCTHTTPRequest 中没有会话属性。
    • 是的,这就是要走的路,从登录响应中获取登录 cookie(通常在 vapor-session 下,并将其添加到未来的请求中。否则,您尝试发送的请求与未经身份验证的请求。Here's an example 这样做(但不使用 XCTVapor)
    • 切换到不和谐,@OxTim?我可以设置厨师,没问题,但它会使用它来查找会话数据中的 _UserSession 值。
    猜你喜欢
    • 2018-03-11
    • 2015-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 2019-09-25
    相关资源
    最近更新 更多