From 52889ad0c1f9ed3a83b02de2ff2246e07af55da9 Mon Sep 17 00:00:00 2001 From: "yusuf.ozgul" Date: Mon, 3 Jun 2024 12:46:11 +0300 Subject: [PATCH 1/3] Fix searchbar main thread warning --- .../Sources/CommonViewsKit/CustomSearchbar.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Core/CommonViewsKit/Sources/CommonViewsKit/CustomSearchbar.swift b/Core/CommonViewsKit/Sources/CommonViewsKit/CustomSearchbar.swift index ee7f7ae78c..223ca7bc1b 100644 --- a/Core/CommonViewsKit/Sources/CommonViewsKit/CustomSearchbar.swift +++ b/Core/CommonViewsKit/Sources/CommonViewsKit/CustomSearchbar.swift @@ -27,8 +27,11 @@ public struct CustomSearchbar: NSViewRepresentable { return textField } - @MainActor public func updateNSView(_ nsView: NSTextField, context: Context) { + guard Thread.isMainThread else { + return DispatchQueue.main.async { self.updateNSView(nsView, context: context) } + } + nsView.stringValue = text if placeholderCount != 0 { From fa1a32209342682289df2a9070761309bf8d5303 Mon Sep 17 00:00:00 2001 From: "yusuf.ozgul" Date: Mon, 3 Jun 2024 12:46:37 +0300 Subject: [PATCH 2/3] Fix render failed mock detail inspector --- .../MockDetailInspectorView.swift | 99 +++++++++++++------ 1 file changed, 71 insertions(+), 28 deletions(-) diff --git a/Features/MockDetail/Sources/MockDetail/Views/MockDetailInspector/MockDetailInspectorView.swift b/Features/MockDetail/Sources/MockDetail/Views/MockDetailInspector/MockDetailInspectorView.swift index fc7aad39d1..5c19e4e298 100644 --- a/Features/MockDetail/Sources/MockDetail/Views/MockDetailInspector/MockDetailInspectorView.swift +++ b/Features/MockDetail/Sources/MockDetail/Views/MockDetailInspector/MockDetailInspectorView.swift @@ -14,48 +14,91 @@ struct MockDetailInspectorView: View { @Bindable var viewModel: MockDetailInspectorViewModel var body: some View { - Form { - Section("Overview") { - LabeledContent("URL", value: viewModel.mockModel.metaData.url.absoluteString) - LabeledContent("Path", value: viewModel.mockModel.metaData.url.path()) - LabeledContent("Query", value: viewModel.mockModel.metaData.url.query() ?? "") + List { + GroupBox { + VStack { + LabeledContent("URL", value: viewModel.mockModel.metaData.url.absoluteString) + Divider() + LabeledContent("Path", value: viewModel.mockModel.metaData.url.path()) + Divider() + LabeledContent("Query", value: viewModel.mockModel.metaData.url.query() ?? "") + } + .padding(6) + } label: { + Label("Overview", systemImage: "book.pages") + .labelStyle(.titleOnly) + .font(.title3) } + .listRowSeparator(.hidden) - Section("Mock State") { - LabeledContent("Is Modified", value: viewModel.mockModel.metaData.appendTime == viewModel.mockModel.metaData.updateTime ? "No" : "Yes") + GroupBox { + VStack { + LabeledContent("Is Modified", value: viewModel.mockModel.metaData.appendTime == viewModel.mockModel.metaData.updateTime ? "No" : "Yes") + Divider() - TextField("Mock Scenario", text: $viewModel.scenario, prompt: Text("Enter a scenario"), axis: .vertical) - .lineLimit(1...10) - TextField("HTTP Status", value: $viewModel.httpStatus, format: .httpStatus(), prompt: Text("HTTP Status Code")) + LabeledContent("Mock Scenario") { + TextField("Mock Scenario", text: $viewModel.scenario, prompt: Text("Enter a scenario"), axis: .vertical) + .lineLimit(1...10) + .multilineTextAlignment(.trailing) + } - LabeledContent("Append Date", value: viewModel.mockModel.metaData.appendTime, format: .dateTime) + Divider() - if viewModel.mockModel.metaData.appendTime != viewModel.mockModel.metaData.updateTime { - LabeledContent("Update Date", value: viewModel.mockModel.metaData.updateTime, format: .dateTime) - } + LabeledContent("HTTP Status") { + TextField("HTTP Status", value: $viewModel.httpStatus, format: .httpStatus(), prompt: Text("HTTP Status Code")) + .multilineTextAlignment(.trailing) + } - VStack(alignment: .leading) { - Text("Response Time") - Slider(value: $viewModel.responseTime, in: 0.0...30.0) { - TextField(String(), value: $viewModel.responseTime, format: .number.precision(.fractionLength(2)), prompt: Text("Response Time (Second)")) + Divider() + + LabeledContent("Append Date", value: viewModel.mockModel.metaData.appendTime, format: .dateTime) + Divider() + + if viewModel.mockModel.metaData.appendTime != viewModel.mockModel.metaData.updateTime { + LabeledContent("Update Date", value: viewModel.mockModel.metaData.updateTime, format: .dateTime) + Divider() + } + + VStack(alignment: .leading) { + Text("Response Time") + Slider(value: $viewModel.responseTime, in: 0.0...30.0) { + TextField(String(), value: $viewModel.responseTime, format: .number.precision(.fractionLength(2)), prompt: Text("Response Time (Second)")) + } } } + .padding(6) + } label: { + Label("Mock State", systemImage: "book.pages") + .labelStyle(.titleOnly) + .font(.title3) } + .listRowSeparator(.hidden) - Section("Plugin") { - ForEach(viewModel.pluginMessages, id: \.self) { message in - Text(LocalizedStringKey(message)) - .textSelection(.enabled) - } + GroupBox { + VStack { + ForEach(viewModel.pluginMessages, id: \.self) { message in + Text(LocalizedStringKey(message)) + .textSelection(.enabled) - Button("Load async Plugin") { - Task { @MainActor in - await viewModel.loadPluginMessage(shouldLoadAsync: true) + Divider() + .padding(.vertical, 6) } - } - TipView(PluginsDocumentTip()) + Button("Load async Plugin") { + Task { @MainActor in + await viewModel.loadPluginMessage(shouldLoadAsync: true) + } + } + + TipView(PluginsDocumentTip()) + } + .padding(6) + } label: { + Label("Plugin", systemImage: "book.pages") + .labelStyle(.titleOnly) + .font(.title3) } + .listRowSeparator(.hidden) } .inspectorColumnWidth(min: 300, ideal: 400) .task(id: viewModel.httpStatus) { viewModel.sync() } From 05d56634e721924bd360b6d27ef35b5d3392a83d Mon Sep 17 00:00:00 2001 From: "yusuf.ozgul" Date: Mon, 3 Jun 2024 12:46:55 +0300 Subject: [PATCH 3/3] Fix empty body save bug --- .../Sources/MockingStarCore/MockingStar.swift | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Core/MockingStarCore/Sources/MockingStarCore/MockingStar.swift b/Core/MockingStarCore/Sources/MockingStarCore/MockingStar.swift index e109a41a5b..61393f8406 100644 --- a/Core/MockingStarCore/Sources/MockingStarCore/MockingStar.swift +++ b/Core/MockingStarCore/Sources/MockingStarCore/MockingStar.swift @@ -130,6 +130,7 @@ public final class MockingStarCore { private func saveFileIfNeeded(request: URLRequest, flags: MockServerFlags, status: Int, body: Data, headers: [String: String], decider: MockDeciderInterface) { logger.debug("Checking mock should save") + var request = request var shouldSave = decider.mockFilters.contains(where: { filter in let filterableItems: [String] = switch filter.selectedLocation { @@ -174,21 +175,25 @@ public final class MockingStarCore { return } - guard (try? JSONSerialization.jsonObject(with: body)) != nil else { + guard body == "".data(using: .utf8) || (try? JSONSerialization.jsonObject(with: body)) != nil else { logger.warning("Mock won't save due to response body is not json, path: \(request.url?.path() ?? "-")") return } - if let requestBody = request.httpBody, - (try? JSONSerialization.jsonObject(with: requestBody)) == nil { - logger.warning("Mock won't save due to request body is not json, path: \(request.url?.path() ?? "-")") - return + if let requestBody = request.httpBody { + if requestBody == "".data(using: .utf8) { + request.httpBody = nil + } else if (try? JSONSerialization.jsonObject(with: requestBody)) == nil { + logger.warning("Mock won't save due to request body is not json, path: \(request.url?.path() ?? "-")") + return + } } + let saveRequest = request Task { do { logger.debug("Saving file") - try await saveFile(request: request, flags: flags, status: status, body: body, headers: headers) + try await saveFile(request: saveRequest, flags: flags, status: status, body: body, headers: headers) } catch { logger.critical("File saving failed. Error: \(error)") }