8000 BIT-2362 - Maximum Access Count Field Cannot Have A Value Entered In Manually by phil-livefront · Pull Request #714 · bitwarden/ios · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

BIT-2362 - Maximum Access Count Field Cannot Have A Value Entered In Manually #714

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

Merged
merged 6 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ enum AddEditSendItemAction: Equatable {
/// The options button was pressed.
case optionsPressed

/// maximum access count stepper was changed.
case maximumAccessCountChanged(Int)
/// maximum access count was changed via the stepper.
case maximumAccessCountStepperChanged(Int)

/// maximum access count was changed via the TextField.
case maximumAccessCountTextFieldChanged(String)

/// The name text field was changed.
case nameChanged(String)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,12 @@ class AddEditSendItemProcessor:
state.isPasswordVisible = newValue
case let .profileSwitcher(profileAction):
handle(profileAction)
case let .maximumAccessCountChanged(newValue):
case let .maximumAccessCountStepperChanged(newValue):
state.maximumAccessCount = newValue
state.maximumAccessCountText = "\(state.maximumAccessCount)"
case let .maximumAccessCountTextFieldChanged(newValue):
state.maximumAccessCount = Int(newValue) ?? 0
state.maximumAccessCountText = newValue.isEmpty ? "" : "\(state.maximumAccessCount)"
case let .nameChanged(newValue):
state.name = newValue
case let .notesChanged(newValue):
Expand Down Expand Up @@ -168,6 +172,10 @@ class AddEditSendItemProcessor:
state.isSendDisabled = await services.policyService.policyAppliesToUser(.disableSend)
state.isSendHideEmailDisabled = await services.policyService.isSendHideEmailDisabledByPolicy()
await refreshProfileState()

if state.maximumAccessCount != 0 {
state.maximumAccessCountText = "\(state.maximumAccessCount)"
}
}

/// A method to respond to a `ProfileSwitcherAction`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,17 @@ class AddEditSendItemProcessorTests: BitwardenTestCase { // swiftlint:disable:th
XCTAssertTrue(subject.state.isSendHideEmailDisabled)
}

/// `perform(_:)` with `loadData` loads the correct maximum access count in the TextField.
func test_perform_loadData_maximumAccessCountUpdates() async {
subject.state.maximumAccessCount = 42
await subject.perform(.loadData)
subject.state.maximumAccessCountText = "42"

subject.state.maximumAccessCount = 0
await subject.perform(.loadData)
subject.state.maximumAccessCountText = ""
}

/// `perform(_:)` with `sendListItemRow(removePassword())` uses the send repository to remove
/// the password from a send.
func test_perform_removePassword_success() async throws {
Expand Down Expand Up @@ -535,9 +546,37 @@ class AddEditSendItemProcessorTests: BitwardenTestCase { // swiftlint:disable:th
/// `receive(_:)` with `.maximumAccessCountChanged` updates the maximum access count.
func test_receive_maximumAccessCountChanged() {
subject.state.maximumAccessCount = 0
subject.receive(.maximumAccessCountChanged(42))
subject.receive(.maximumAccessCountStepperChanged(42))

XCTAssertEqual(subject.state.maximumAccessCount, 42)
XCTAssertEqual(subject.state.maximumAccessCountText, "42")
}

/// `receive(_:)` with `.maximumAccessCountTextChanged` updates the maximum access count.
func test_receive_maximumAccessCountTextChanged() {
subject.state.maximumAccessCountText = "0"
subject.receive(.maximumAccessCountTextFieldChanged("32"))

XCTAssertEqual(subject.state.maximumAccessCount, 32)
XCTAssertEqual(subject.state.maximumAccessCountText, "32")
}

/// `receive(_:)` with `.maximumAccessCountTextChanged` updates the maximum access count.
func test_receive_maximumAccessCountTextChanged_zeroToEmptyState() {
subject.state.maximumAccessCountText = "0"
subject.receive(.maximumAccessCountTextFieldChanged(""))

XCTAssertEqual(subject.state.maximumAccessCount, 0)
XCTAssertEqual(subject.state.maximumAccessCountText, "")
}

/// `receive(_:)` with `.maximumAccessCountTextChanged` updates the maximum access count.
func test_receive_maximumAccessCountTextChanged_emptyToZeroState() {
subject.state.maximumAccessCountText = ""
subject.receive(.maximumAccessCountTextFieldChanged("0"))

XCTAssertEqual(subject.state.maximumAccessCount, 0)
XCTAssertEqual(subject.state.maximumAccessCountText, "0")
}

/// `receive(_:)` with `.nameChanged` updates the name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ struct AddEditSendItemState: Equatable {
/// The maximum number of times this share can be accessed before being deactivated.
var maximumAccessCount: Int = 0

/// The text representation of the maximum access count.
var maximumAccessCountText: String = ""

/// The mode for this view.
var mode: Mode = .add

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
/// The `Store` for this view.
@ObservedObject var store: Store<AddEditSendItemState, AddEditSendItemAction, AddEditSendItemEffect>

/// A state variable to track whether the TextField is focused
@FocusState private var isMaxAccessCountFocused: Bool

var body: some View {
ZStack {
ScrollView {
Expand Down Expand Up @@ -53,9 +56,6 @@
title: store.state.mode.navigationTitle,
titleDisplayMode: .inline
)
.task {
await store.perform(.loadData)
}
.toolbar {
ToolbarItem(placement: .topBarLeading) {
switch store.state.mode {
Expand Down Expand Up @@ -130,22 +130,40 @@
Stepper(
value: store.binding(
get: \.maximumAccessCount,
send: AddEditSendItemAction.maximumAccessCountChanged
send: AddEditSendItemAction.maximumAccessCountStepperChanged
),
in: 0 ... Int.max
) {
HStack(spacing: 8) {
Text(Localizations.maximumAccessCount)
.styleGuide(.body)
.foregroundStyle(Asset.Colors.textPrimary.swiftUIColor)
.layoutPriority(1)

Spacer()

if store.state.maximumAccessCount > 0 {
Text("\(store.state.maximumAccessCount)")
.styleGuide(.body, monoSpacedDigit: true)
.foregroundStyle(Asset.Colors.textSecondary.swiftUIColor)
TextField(
"",
text: store.binding(
get: \.maximumAccessCountText,
send: AddEditSendItemAction.maximumAccessCountTextFieldChanged
)
)
.focused($isMaxAccessCountFocused)
.keyboardType(.numberPad)
.styleGuide(.body)
.foregroundStyle(Asset.Colors.textSecondary.swiftUIColor)
.multilineTextAlignment(.trailing)
.textFieldStyle(.plain)
.toolbar {
ToolbarItemGroup(placement: .keyboard) {
Spacer()
Button(Localizations.save) {
isMaxAccessCountFocused = false

Check warning on line 162 in BitwardenShared/UI/Tools/Send/SendItem/AddEditSendItem/AddEditSendItemView.swift

View check run for this annotation

Codecov / codecov/patch

BitwardenShared/UI/Tools/Send/SendItem/AddEditSendItem/AddEditSendItemView.swift#L162

Added line #L162 was not covered by tests
}
}
}
.accessibilityIdentifier("MaxAccessCountTextField")
}
}
.accessibilityIdentifier("SendMaxAccessCountEntry")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ class AddEditSendItemViewTests: BitwardenTestCase {
let stepper = try subject.inspect().find(ViewType.Stepper.self, containing: Localizations.maximumAccessCount)

try stepper.increment()
XCTAssertEqual(processor.dispatchedActions.last, .maximumAccessCountChanged(43))
XCTAssertEqual(processor.dispatchedActions.last, .maximumAccessCountStepperChanged(43))

try stepper.decrement()
XCTAssertEqual(processor.dispatchedActions.last, .maximumAccessCountChanged(41))
XCTAssertEqual(processor.dispatchedActions.last, .maximumAccessCountStepperChanged(41))
}

/// Updating the name textfield sends the `.nameChanged` action.
Expand All @@ -99,6 +99,16 @@ class AddEditSendItemViewTests: BitwardenTestCase {
XCTAssertEqual(process F438 or.dispatchedActions.last, .notesChanged("Notes"))
}

/// Updating the max access count textfield sends the `.maximumAccessCountChanged` action.
func test_maxAccessCountTextField_updated() throws {
processor.state.isOptionsExpanded = true
let textField = try subject.inspect()
.find(viewWithAccessibilityIdentifier: "MaxAccessCountTextField")
.textField()
try textField.setInput("42")
XCTAssertEqual(processor.dispatchedActions.last, .maximumAccessCountTextFieldChanged("42"))
}

/// Tapping the options button sends the `.optionsPressed` action.
func test_optionsButton_tap() throws {
let button = try subject.inspect().find(button: Localizations.options)
Expand Down Expand Up @@ -192,6 +202,7 @@ class AddEditSendItemViewTests: BitwardenTestCase {
processor.state.expirationDate = .custom
processor.state.customExpirationDate = Date(year: 2023, month: 11, day: 5, hour: 9, minute: 41)
processor.state.maximumAccessCount = 42
processor.state.maximumAccessCountText = "42"
processor.state.password = "pa$$w0rd"
processor.state.notes = "Notes"
processor.state.isHideMyEmailOn = true
Expand All @@ -211,6 +222,7 @@ class AddEditSendItemViewTests: BitwardenTestCase {
processor.state.expirationDate = .custom
processor.state.customExpirationDate = nil
processor.state.maximumAccessCount = 420
processor.state.maximumAccessCountText = "420"
processor.state.currentAccessCount = 42
processor.state.password = "pa$$w0rd"
processor.state.notes = "Notes"
Expand Down Expand Up @@ -255,6 +267,7 @@ class AddEditSendItemViewTests: BitwardenTestCase {
processor.state.expirationDate = .custom
processor.state.customExpirationDate = Date(year: 2023, month: 11, day: 5, hour: 9, minute: 41)
processor.state.maximumAccessCount = 42
processor.state.maximumAccessCountText = "42"
processor.state.password = "pa$$w0rd"
processor.state.notes = "Notes with lots of text that wraps to new lines when displayed."
processor.state.isHideMyEmailOn = true
Expand All @@ -273,6 +286,7 @@ class AddEditSendItemViewTests: BitwardenTestCase {
processor.state.expirationDate = .custom
processor.state.customExpirationDate = nil
processor.state.maximumAccessCount = 420
processor.state.maximumAccessCountText = "420"
processor.state.currentAccessCount = 42
processor.state.password = "pa$$w0rd"
processor.state.notes = "Notes"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
0