Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f9c87ea
Create the .addOrderNote action. Create the addOrderNote network requ…
mindgraffiti Jul 23, 2018
3800738
addOrderNote: original note line should be a `String` not an `OrderNo…
mindgraffiti Jul 23, 2018
ac7ee88
Add `new-order-note.json` file for unit tests
mindgraffiti Jul 23, 2018
069bfd7
Write first addOrderNote network unit test
mindgraffiti Jul 23, 2018
6a3944b
Add JSON to Networking project
mindgraffiti Jul 24, 2018
1db3761
Remove unused JSON response from Yosemite. Rename variable in a unit …
mindgraffiti Jul 24, 2018
2248841
Add initial `AddaNoteViewController`
mindgraffiti Jul 24, 2018
effc64a
Add tableview data source
mindgraffiti Jul 24, 2018
96567e2
Add "Email note to customer" cell
mindgraffiti Jul 24, 2018
9bfd55a
Rename `AddaNoteVC` to `AddANoteVC`
mindgraffiti Jul 25, 2018
106ed79
Autolayout for note writing cell. Add note icon, `.aside`
mindgraffiti Jul 25, 2018
229ea51
toggling the "email note to customer?" control changes the note icon …
mindgraffiti Jul 25, 2018
a4afa45
Add dispatch action to "Add" button
mindgraffiti Jul 25, 2018
e6a10f1
Add single note mapper
mindgraffiti Jul 25, 2018
27bc94b
Fix mapper
mindgraffiti Jul 25, 2018
5778f9a
Merge branch 'develop' into feature/75-add-note
mindgraffiti Jul 25, 2018
eb5bb56
Fix unit test networking response
mindgraffiti Jul 26, 2018
4af8c6b
Merge branch 'develop' into feature/75-add-note
mindgraffiti Jul 26, 2018
03295aa
Code review - rename table view cells, create public new variables, c…
mindgraffiti Jul 26, 2018
5596d4a
Add textview's delegate
mindgraffiti Jul 27, 2018
f9243d7
SwitchTableViewCell: selectionStyle = .none
jleandroperez Jul 27, 2018
37c9736
TextViewTableViewCell: selectionStyle = .none
jleandroperez Jul 27, 2018
53339fb
AddANoteViewController: becomeFirstResponder on viewDidAppear / resig…
jleandroperez Jul 27, 2018
bb6933f
SwitchTableViewCell: Tap Support
jleandroperez Jul 27, 2018
42886ac
AddANoteViewController: Preventing firstResponder dismissal upon switch
jleandroperez Jul 27, 2018
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
8 changes: 8 additions & 0 deletions Networking/Networking.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
B5C6FCD420A373BB00A4F8E4 /* OrderMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C6FCD320A373BA00A4F8E4 /* OrderMapper.swift */; };
B5C6FCD620A3768900A4F8E4 /* order.json in Resources */ = {isa = PBXBuildFile; fileRef = B5C6FCD520A3768900A4F8E4 /* order.json */; };
CE20179320E3EFA7005B4C18 /* broken-orders.json in Resources */ = {isa = PBXBuildFile; fileRef = CE20179220E3EFA7005B4C18 /* broken-orders.json */; };
CE21B3E72106811000A259D5 /* new-order-note.json in Resources */ = {isa = PBXBuildFile; fileRef = CE21B3E62106811000A259D5 /* new-order-note.json */; };
CE583A0E2109154500D73C1C /* OrderNoteMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE583A0D2109154500D73C1C /* OrderNoteMapper.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -133,6 +135,8 @@
BD9439D9B8F2C1ED2EADAA51 /* Pods-NetworkingTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NetworkingTests.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-NetworkingTests/Pods-NetworkingTests.debug.xcconfig"; sourceTree = "<group>"; };
C8F9A8CC6F90A8C9B5EF2EE2 /* Pods-Networking.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Networking.release.xcconfig"; path = "../Pods/Target Support Files/Pods-Networking/Pods-Networking.release.xcconfig"; sourceTree = "<group>"; };
CE20179220E3EFA7005B4C18 /* broken-orders.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "broken-orders.json"; sourceTree = "<group>"; };
CE21B3E62106811000A259D5 /* new-order-note.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "new-order-note.json"; sourceTree = "<group>"; };
CE583A0D2109154500D73C1C /* OrderNoteMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderNoteMapper.swift; sourceTree = "<group>"; };
F3F25DC15EC1D7C631169CB5 /* Pods_Networking.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Networking.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F6CEE1CA2AD376C0C28AE9F6 /* Pods-NetworkingTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NetworkingTests.release.xcconfig"; path = "../Pods/Target Support Files/Pods-NetworkingTests/Pods-NetworkingTests.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -314,6 +318,7 @@
B559EBA820A0B5B100836CD4 /* Responses */ = {
isa = PBXGroup;
children = (
CE21B3E62106811000A259D5 /* new-order-note.json */,
B505F6D420BEE4E600BB1B69 /* me.json */,
B559EBA920A0B5CD00836CD4 /* orders-load-all.json */,
B5C6FCD520A3768900A4F8E4 /* order.json */,
Expand All @@ -335,6 +340,7 @@
B567AF2A20A0FA4200AB6C62 /* OrderListMapper.swift */,
B56C1EB520EA757B00D749F9 /* SiteListMapper.swift */,
74C8F06720EEB7BC00B6EDC9 /* OrderNotesMapper.swift */,
CE583A0D2109154500D73C1C /* OrderNoteMapper.swift */,
);
path = Mapper;
sourceTree = "<group>";
Expand Down Expand Up @@ -482,6 +488,7 @@
files = (
74C8F06620EEB76400B6EDC9 /* order-notes.json in Resources */,
74C8F06C20EEBD5D00B6EDC9 /* broken-order.json in Resources */,
CE21B3E72106811000A259D5 /* new-order-note.json in Resources */,
B505F6D520BEE4E700BB1B69 /* me.json in Resources */,
B5C6FCD620A3768900A4F8E4 /* order.json in Resources */,
B559EBAA20A0B5CD00836CD4 /* orders-load-all.json in Resources */,
Expand Down Expand Up @@ -575,6 +582,7 @@
B518662220A097C200037A38 /* Network.swift in Sources */,
B518662420A099BF00037A38 /* AlamofireNetwork.swift in Sources */,
B557DA1820979D51005962F4 /* Credentials.swift in Sources */,
CE583A0E2109154500D73C1C /* OrderNoteMapper.swift in Sources */,
B5C6FCCF20A3592900A4F8E4 /* OrderItem.swift in Sources */,
B505F6EC20BEFDC200BB1B69 /* Loader.swift in Sources */,
B5BB1D1220A255EC00112D92 /* OrderStatus.swift in Sources */,
Expand Down
29 changes: 29 additions & 0 deletions Networking/Networking/Mapper/OrderNoteMapper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Foundation


/// Mapper: OrderNote (Singular)
///
class OrderNoteMapper: Mapper {

/// (Attempts) to convert a dictionary into a single OrderNote
///
func map(response: Data) throws -> OrderNote {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(DateFormatter.Defaults.dateTimeFormatter)

return try decoder.decode(OrderNoteEnvelope.self, from: response).orderNote
}
}


/// OrderNote Disposable Entity:
/// `Add Order Note` endpoint the single added note within the `data` key. This entity
/// allows us to parse all the things with JSONDecoder.
///
private struct OrderNoteEnvelope: Decodable {
let orderNote: OrderNote

private enum CodingKeys: String, CodingKey {
case orderNote = "data"
}
}
28 changes: 25 additions & 3 deletions Networking/Networking/Remote/OrdersRemote.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,26 @@ public class OrdersRemote: Remote {
let request = JetpackRequest(wooApiVersion: .mark2, method: .post, siteID: siteID, path: path, parameters: parameters)
enqueue(request, mapper: mapper, completion: completion)
}

/// Adds an order note to a specific Order.
///
/// - Parameters:
/// - siteID: Site which hosts the Order.
/// - orderID: Identifier of the Order to be updated.
/// - isCustomerNote: if true, the note will be shown to customers and they will be notified.
/// if false, the note will be for admin reference only. Default is false.
/// - note: The note to be posted.
/// - completion: Closure to be executed upon completion.
///
public func addOrderNote(for siteID: Int, orderID: Int, isCustomerNote: Bool, with note: String, completion: @escaping (OrderNote?, Error?) -> Void) {
let path = "\(Constants.ordersPath)/" + String(orderID) + "/" + "\(Constants.notesPath)"
let parameters = [ParameterKeys.note: note,
ParameterKeys.customerNote: String(isCustomerNote)]
let mapper = OrderNoteMapper()

let request = JetpackRequest(wooApiVersion: .mark2, method: .post, siteID: siteID, path: path, parameters: parameters)
enqueue(request, mapper: mapper, completion: completion)
}
}


Expand All @@ -81,8 +101,10 @@ private extension OrdersRemote {
}

enum ParameterKeys {
static let status: String = "status"
static let page: String = "page"
static let perPage: String = "per_page"
static let customerNote: String = "customer_note"
static let note: String = "note"
static let page: String = "page"
static let perPage: String = "per_page"
static let status: String = "status"
}
}
17 changes: 17 additions & 0 deletions Networking/NetworkingTests/Remote/OrdersRemoteTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,21 @@ class OrdersRemoteTests: XCTestCase {

wait(for: [expectation], timeout: Constants.expectationTimeout)
}

/// Verifies that addOrderNote properly parses the `new-order-note` sample response.
///
func testLoadAddOrderNoteProperlyReturnsParsedOrderNote() {
let remote = OrdersRemote(network: network)
let expectation = self.expectation(description: "Add Order Note")
let noteData = "This order would be so much better with ketchup."

network.simulateResponse(requestUrlSuffix: "orders/\(sampleOrderID)/notes", filename: "new-order-note")

remote.addOrderNote(for: sampleSiteID, orderID: sampleOrderID, isCustomerNote: true, with: noteData) { (orderNote, error) in
XCTAssertNil(error)
XCTAssertNotNil(orderNote)
expectation.fulfill()
}
wait(for: [expectation], timeout: Constants.expectationTimeout)
}
}
26 changes: 26 additions & 0 deletions Networking/NetworkingTests/Responses/new-order-note.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"data": {
"id": 2235,
"date_created": "2018-06-22T11:36:20",
"date_created_gmt": "2018-06-22T15:36:20",
"note": "This order would be so much better with ketchup.",
"customer_note": true,
"_links": {
"self": [
{
"href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/orders/1179/notes/2235"
}
],
"collection": [
{
"href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/orders/1179/notes"
}
],
"up": [
{
"href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/orders/1179"
}
]
}
}
}
22 changes: 21 additions & 1 deletion WooCommerce/Classes/Extensions/UIView+Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Foundation
import UIKit


/// UIView Helper Methods
/// UIView Class Methods
///
extension UIView {

Expand All @@ -19,3 +19,23 @@ extension UIView {
return loadNib().instantiate(withOwner: nil, options: nil).first as! T
}
}


/// UIView Extension Methods
///
extension UIView {

/// Returns the first Subview of the specified Type (if any).
///
func firstSubview<T: UIView>(ofType type: T.Type) -> T? {
for subview in subviews {
guard let target = (subview as? T) ?? subview.firstSubview(ofType: type) else {
continue
}

return target
}

return nil
}
}
Loading