-
1st time start testing on my project
from this To fix, inspect any effects the reducer returns for this action and ensure that all of them complete by the end of the test. There are a few reasons why an effect may not have completed: • If an effect uses a scheduler (via "receive(on:)", "delay", "debounce", etc.), make sure that you wait enough time for the scheduler to perform the effect. If you are using a test scheduler, advance the scheduler so that the effects may complete, or consider using an immediate scheduler to immediately perform the effect instead. • If you are returning a long-living effect (timers, notifications, subjects, etc.), then make sure those effects are torn down by marking the effect ".cancellable" and returning a corresponding cancellation effect ("Effect.cancel") from another action, or, if your effect is driven by a Combine subject, send it a completion. class EventFormViewTests: XCTestCase {
let scheduler = DispatchQueue.test
func testCreatEvent() {
let now = Date()
let attachments = [
Attachment(
id: "5fb6736c1432f950f8ea2d33",
type: .image,
userId: "5fabb05d2470c17919b3c0e2",
imageUrlString: "https://adda.nyc3.digitaloceanspaces.com/uploads/images/5fabb05d2470c17919b3c0e2/1605796266916.jpeg",
createdAt: now,
updatedAt: now
),
Attachment(
id: "5fb6736c1432f950f8ea2d36",
type: .image,
userId: "5fabb05d2470c17919b3c0e2",
imageUrlString: "https://adda.nyc3.digitaloceanspaces.com/uploads/images/5fabb05d2470c17919b3c0e2/5fabb05d2470c17919b3c0e2_1605792619988.jpeg",
createdAt: now,
updatedAt: now
),
Attachment(
id: "5fb6bc48d63734254b0eb777",
type: .image,
userId: "5fabb05d2470c17919b3c0e2",
imageUrlString: "https://adda.nyc3.digitaloceanspaces.com/uploads/images/5fabb05d2470c17919b3c0e2/1605811270871.jpeg",
createdAt: now,
updatedAt: now
)
]
let cuser = User(
id: "5fabb05d2470c17919b3c0e2",
phoneNumber: "+79218821217",
attachments: attachments,
createdAt: now,
updatedAt: now
)
let postAddress = CNMutablePostalAddress()
postAddress.street = "улица Вавиловых, 8 к1,"
postAddress.city = "Saint Petersburg"
postAddress.subAdministrativeArea = "Saint Petersburg"
postAddress.state = "Leningrad Oblast"
postAddress.postalCode = "195257"
postAddress.country = "Russia"
postAddress.isoCountryCode = "ru"
let placeMark = MKPlacemark(
location: CLLocation(latitude: +60.02020100, longitude: +30.38803500),
name: "улица Вавиловых, 8 к1",
postalAddress: postAddress
)
let location = placeMark.location?.coordinate
let eventAddress = "\(placeMark.postalAddress)"
let state = EventFormState(
placeMark: placeMark,
eventAddress: eventAddress,
eventCoordinate: location,
currentUser: cuser
)
let environment = EventFormEnvironment(
eventClient: .happyPath,
mainQueue: self.scheduler.eraseToAnyScheduler()
)
let store = TestStore(
initialState: state,
reducer: eventFormReducer,
environment: environment
)
store.send(.titleChanged("Walk Around")) {
$0.title = "Walk Around"
}
store.send(.selectedDurations(.FourHours)) {
let duration = DurationButtons.self
$0.durationRawValue = duration.FourHours.rawValue
$0.selectedDutaionButtons = duration.FourHours
$0.durationIntValue = duration.FourHours.value
}
store.send(.liveLocationToggleChanged(true)) {
$0.liveLocationToggleisOn.toggle()
}
store.send(.isSearchSheet(isPresented: false)) {
$0.locationSearchState = nil
}
store.send(.selectedDurationIndex(2)) {
$0.selectedCateforyIndex = 2
}
store.send(.submitButtonTapped) {
$0.isPostRequestOnFly = true
}
scheduler.advance(by: 4)
store.receive(.eventsResponse(
.success(
.init(
name: "", duration: 3600, categories: "",
isActive: true, addressName: "", coordinates: [0.0, 0.0]
)
)
)
)
}
// Reducer
public let eventFormReducer = Reducer<
EventFormState, EventFormAction, EventFormEnvironment
> { state, action, environment in
switch action {
case .didAppear:
guard let currentUSER: User = KeychainService.loadCodable(for: .user) else {
assertionFailure("current user is missing")
return .none
}
state.currentUser = currentUSER
return .none
case .didDisappear:
return .none
case let .titleChanged(string):
state.title = string
return .none
case let .selectedDurations(duration):
// duration.value -> 3600
state.durationRawValue = duration.rawValue
state.selectedDutaionButtons = duration
state.durationIntValue = duration.value
return .none
case let .showCategorySheet(isPresent):
return .none
case let .liveLocationToggleChanged(liveLocationEnabled):
state.liveLocationToggleisOn.toggle()
return .none
case let .isSearchSheet(isPresented: isPresented):
state.locationSearchState = isPresented ? LocationSearchState() : nil
return .none
case let .selectedDurationIndex(int):
state.selectedCateforyIndex = int
return .none
case .backToPVAfterCreatedEventSuccessfully:
return .none
case .successFullMsg:
state.isEventCreatedSuccessfully = true
state.isPostRequestOnFly = false
return Effect(value: EventFormAction.backToPVAfterCreatedEventSuccessfully)
.delay(for: 3, scheduler: environment.mainQueue)
.eraseToEffect()
case let .eventsResponse(.success(event)):
return Effect(value: EventFormAction.successFullMsg)
.receive(on: environment.mainQueue)
.eraseToEffect()
case let .eventsResponse(.failure(error)):
state.isPostRequestOnFly = false
return .none
case .submitButtonTapped:
guard let coordinate = state.eventCoordinate else {
// alert action for valid form notification
state.alert = .init(title: TextState("Invalid address please valid address please"))
return .none
}
let event = Event(
name: state.title,
details: "",
imageUrl: state.currentUser.attachments?.last?.imageUrlString,
duration: state.durationIntValue,
categories: state.categoryRawValue,
isActive: true,
addressName: state.eventAddress,
type: .Point,
sponsored: false,
overlay: false,
coordinates: [coordinate.longitude, coordinate.latitude]
// mongoDB coordicate have to long then lat
// selectedPlace.coordinatesMongoDouble
)
state.isPostRequestOnFly = true
return environment.eventClient.create(event, "")
.retry(3)
.receive(on: environment.mainQueue)
.catchToEffect(EventFormAction.eventsResponse)
case .actionSheetButtonTapped:
let cancel = ActionSheetState<EventFormAction>.Button.cancel()
var alertButtons: [ActionSheetState<EventFormAction>.Button] = Categories.allCases.enumerated().map { _, item in
return .default(
.init("\(item.rawValue)"),
send: .selectedCategories(item)
)
}
alertButtons.append(cancel)
state.actionSheet = .init(
title: .init("Action sheet"),
message: .init("This is an action sheet."),
buttons: alertButtons
)
return .none
case .actionSheetCancelTapped:
return .none
case .actionSheetDismissed:
state.actionSheet = nil
return .none
case .alertButtonTapped:
return .none
case .alertCancelTapped:
state.alert = nil
return .none
case .alertDismissed:
state.alert = nil
return .none
case let .selectedCategories(categories):
state.categoryRawValue = categories.rawValue
return .none
case let .textFieldHeightChanged(height):
let minHeight: CGFloat = 30
let maxHeight: CGFloat = 70
if height < minHeight {
state.textFieldHeight = minHeight
return .none
}
if height > maxHeight {
state.textFieldHeight = maxHeight
return .none
}
state.textFieldHeight = height
return .none
case let .locationSearch(.didSelect(address: results)):
state.eventAddress = results.title + " " + results.subtitle
return .none
case let .locationSearch(.eventCoordinate(.success(placemark))):
if let location = placemark.location {
state.locationSearchState = nil
state.eventCoordinate = location.coordinate
}
return .none
case let .locationSearch(action):
return .none
}
}
.presents(
locationSearchReducer,
state: \.locationSearchState,
action: /EventFormAction.locationSearch,
environment: { _ in
LocationEnvironment(localSearch: .live, mainQueue: .immediate)
}
)
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 7 replies
-
Hi @saroar, are there any test failures on the |
Beta Was this translation helpful? Give feedback.
-
Ok, since you are getting a test failure on the return environment.eventClient.create(event, "")
.retry(3)
.receive(on: environment.mainQueue)
.catchToEffect(EventFormAction.eventsResponse) Can you show what your |
Beta Was this translation helpful? Give feedback.
Hi @saroar, are there any test failures on the
store.receive(.eventsResponse(...))
line? Or is it just onstore.send(.submitButtonTapped)
?