Signal-iOS/SignalServiceKit/tests/Network/OWSHttpHeadersTest.swift
Evan Hahn bf8fd72fba
Improve Accept-Language header value, fixing registration bug
Some users [are unable to register][1] because the server [returns a 400
error][2] if passed an invalid `Accept-Language` header.

This commit helps prevent two possible error modes:

- Filters out invalid language tags. Some users reported a "Workshopx"
  language, which the server would reject because it's syntactically
  invalid. Deleting this language (at the OS level) let them register.
- If no languages are valid, we should send `*` instead of the empty
  string. There's no evidence that this happened in practice.

In addition, this commit:

- Adds tests.
- Sends a maximum of 10 languages instead of 6.
- Omits the `q` value when it's 1 because [that's the default][3].
- Marginally improves performance by iterating lazily.

[1]: https://github.com/signalapp/Signal-iOS/issues/5261
[2]: bf6d3aa324/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java (L271-L275)
[3]: https://www.rfc-editor.org/rfc/rfc9110.html#section-12.4.2

Co-authored-by: Nora Trapp <nora@signal.org>
2022-07-11 12:20:24 -05:00

48 lines
1.8 KiB
Swift

//
// Copyright (c) 2022 Open Whisper Systems. All rights reserved.
//
import XCTest
@testable import SignalServiceKit
class OWSHttpHeadersTest: XCTestCase {
func testFormatAcceptLanguageHeader() throws {
func chars(_ str: String) -> [String] {
str.map { String($0) }
}
let testCases: [[String]: String] = [
[]: "*",
["invalid!"]: "*",
["bad1", "bad2", "no_unders", "itstoolong", "en--", "en--us", "en-*stars*", "en-**"]: "*",
["en-US"]: "en-US",
["en-*"]: "en-*",
["*-US"]: "*-US",
["*-*"]: "*-*",
["a-b-c2-d"]: "a-b-c2-d",
["bad1", "ok", "bad2"]: "ok",
// This was an actual string sent from someone's device, so we test that it's ignored.
["en-US@attribute=isk", "de"]: "de",
["a", "b", "c"]: "a, b;q=0.9, c;q=0.8",
["a", "b", "bad123", "c"]: "a, b;q=0.9, c;q=0.8",
chars("abcdefghij"): "a, b;q=0.9, c;q=0.8, d;q=0.7, e;q=0.6, f;q=0.5, g;q=0.4, h;q=0.3, i;q=0.2, j;q=0.1",
chars("abcdefghijklmnopqrst"): "a, b;q=0.9, c;q=0.8, d;q=0.7, e;q=0.6, f;q=0.5, g;q=0.4, h;q=0.3, i;q=0.2, j;q=0.1",
chars("a!b@c#d$e%f^g&h(i)j_"): "a, b;q=0.9, c;q=0.8, d;q=0.7, e;q=0.6, f;q=0.5, g;q=0.4, h;q=0.3, i;q=0.2, j;q=0.1"
]
for (languages, expected) in testCases {
let actual = OWSHttpHeaders.formatAcceptLanguageHeader(languages)
XCTAssertEqual(actual, expected, "Input: \(languages)")
}
}
func testAcceptLanguageHeaderValue() throws {
let expected = OWSHttpHeaders.formatAcceptLanguageHeader(Locale.preferredLanguages)
let actual = OWSHttpHeaders.acceptLanguageHeaderValue
XCTAssertEqual(actual, expected)
}
}