Skip to content
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
31 changes: 30 additions & 1 deletion Sources/MeiliSearch/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,36 @@ public struct MeiliSearch {
For a partial update of the document see `updateDocument`.

- parameter UID: The unique identifier for the Document's index to be found.
- parameter documents: The documents data (JSON) to be processed.
- parameter documents: The documents to be processed.
- parameter completion: The completion closure used to notify when the server
completes the update request, it returns a `Result` object that contains `Update`
value. If the request was sucessful or `Error` if a failure occured.
*/
public func addDocuments<T>(
UID: String,
documents: [T],
encoder: JSONEncoder? = nil,
primaryKey: String?,
_ completion: @escaping (Result<Update, Swift.Error>) -> Void) where T: Encodable {
self.documents.add(
UID,
documents,
encoder,
primaryKey,
completion)
}

/**
Add a list of documents as data or replace them if they already exist.

If you send an already existing document (same id) the whole existing document will
be overwritten by the new document. Fields previously in the document not present in
the new document are removed.

For a partial update of the document see `updateDocument`.

- parameter UID: The unique identifier for the Document's index to be found.
- parameter documents: The data to be processed.
- parameter completion: The completion closure used to notify when the server
completes the update request, it returns a `Result` object that contains `Update`
value. If the request was sucessful or `Error` if a failure occured.
Expand Down
7 changes: 7 additions & 0 deletions Sources/MeiliSearch/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,11 @@ struct Constants {
decoder.dateDecodingStrategy = .formatted(Formatter.iso8601)
return decoder
}()

static let customJSONEecoder: JSONEncoder = {
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .formatted(Formatter.iso8601)
return encoder
}()

}
49 changes: 49 additions & 0 deletions Sources/MeiliSearch/Documents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct Documents {
_ document: Data,
_ primaryKey: String?,
_ completion: @escaping (Result<Update, Swift.Error>) -> Void) {

var query: String = "/indexes/\(UID)/documents"
if let primaryKey: String = primaryKey {
query += "?primaryKey=\(primaryKey)"
Expand All @@ -94,6 +95,42 @@ struct Documents {
}
}

func add<T>(
_ UID: String,
_ documents: [T],
_ encoder: JSONEncoder? = nil,
_ primaryKey: String?,
_ completion: @escaping (Result<Update, Swift.Error>) -> Void) where T: Encodable {

var query: String = "/indexes/\(UID)/documents"
if let primaryKey: String = primaryKey {
query += "?primaryKey=\(primaryKey)"
}

let data: Data!

switch encodeJSON(documents, encoder) {
case .success(let documentData):
data = documentData
case .failure(let error):
completion(.failure(error))
return
}

request.post(api: query, data) { result in

switch result {
case .success(let data):

Documents.decodeJSON(data, completion: completion)

case .failure(let error):
completion(.failure(error))
}

}
}

func update(
_ UID: String,
_ document: Data,
Expand Down Expand Up @@ -217,4 +254,16 @@ struct Documents {
}
}

private func encodeJSON<T: Encodable>(
_ documents: [T],
_ encoder: JSONEncoder?) -> Result<Data, Swift.Error> {
do {
let data: Data = try (encoder ?? Constants.customJSONEecoder)
.encode(documents)
return .success(data)
} catch {
return .failure(error)
}
}

}
78 changes: 63 additions & 15 deletions Tests/MeiliSearchIntegrationTests/DocumentsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,12 @@ class DocumentsTests: XCTestCase {
}

func testAddAndGetDocuments() {
let documents: Data = try! JSONEncoder().encode(movies)

let expectation = XCTestExpectation(description: "Add or replace Movies document")

self.client.addDocuments(
UID: self.uid,
documents: documents,
documents: movies,
primaryKey: nil
) { result in

Expand Down Expand Up @@ -112,6 +111,53 @@ class DocumentsTests: XCTestCase {

}

func testAddDataAndGetDocuments() {
let documents: Data = try! JSONEncoder().encode(movies)

let expectation = XCTestExpectation(description: "Add or replace Movies document")

self.client.addDocuments(
UID: self.uid,
documents: documents,
primaryKey: nil
) { result in

switch result {
case .success(let update):

XCTAssertEqual(Update(updateId: 0), update)

Thread.sleep(forTimeInterval: 1.0)

self.client.getDocuments(
UID: self.uid,
limit: 20
) { (result: Result<[Movie], Swift.Error>) in

switch result {
case .success(let returnedMovies):

movies.forEach { (movie: Movie) in
XCTAssertTrue(returnedMovies.contains(movie))
}

case .failure(let error):
print(error)
XCTFail()
}

expectation.fulfill()
}

case .failure(let error):
print(error)
XCTFail()
}
}
self.wait(for: [expectation], timeout: 5.0)

}

func testGetOneDocumentAndFail() {

let getExpectation = XCTestExpectation(description: "Get one document and fail")
Expand Down Expand Up @@ -146,25 +192,26 @@ class DocumentsTests: XCTestCase {

case .success(let update):


XCTAssertEqual(Update(updateId: 0), update)

Thread.sleep(forTimeInterval: 1.0)

self.client.getDocument(
UID: self.uid,
identifier: "10"
) { (result: Result<Movie, Swift.Error>) in
self.client.getDocument(
UID: self.uid,
identifier: "10"
) { (result: Result<Movie, Swift.Error>) in

switch result {
case .success(let returnedMovie):
XCTAssertEqual(movie, returnedMovie)
case .failure(let error):
print(error)
XCTFail()
}
expectation.fulfill()
switch result {
case .success(let returnedMovie):
XCTAssertEqual(movie, returnedMovie)
case .failure(let error):
print(error)
XCTFail()
}
expectation.fulfill()

}
}

case .failure(let error):
print(error)
Expand Down Expand Up @@ -391,6 +438,7 @@ class DocumentsTests: XCTestCase {

static var allTests = [
("testAddAndGetDocuments", testAddAndGetDocuments),
("testAddDataAndGetDocuments", testAddDataAndGetDocuments),
("testGetOneDocumentAndFail", testGetOneDocumentAndFail),
("testAddAndGetOneDocuments", testAddAndGetOneDocuments),
("testUpdateAndGetDocuments", testUpdateAndGetDocuments),
Expand Down
5 changes: 4 additions & 1 deletion Tests/MeiliSearchUnitTests/ClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import XCTest

class ClientTests: XCTestCase {

private let session = MockURLSession()

func testValidHostURL() {
XCTAssertNotNil(try? MeiliSearch(Config(hostURL: "http://localhost:7700", apiKey: "masterKey")))
session.pushEmpty(code: 200)
XCTAssertNotNil(try? MeiliSearch(Config.default(apiKey: "masterKey", session: session)))
}

func testEmptyHostURL() {
Expand Down
46 changes: 46 additions & 0 deletions Tests/MeiliSearchUnitTests/DocumentsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,51 @@ class DocumentsTests: XCTestCase {

let uid: String = "Movies"

let movie = Movie(
id: 287947,
title: "Shazam",
overview: "A boy is given the ability to become an adult superhero in times of need with a single magic word.",
releaseDate: Date(timeIntervalSince1970: TimeInterval(1553299200)))

let expectation = XCTestExpectation(description: "Add or replace Movies document")

self.client.addDocuments(
UID: uid,
documents: [movie],
primaryKey: "") { result in

switch result {
case .success(let update):
XCTAssertEqual(stubUpdate, update)
expectation.fulfill()
case .failure:
XCTFail("Failed to add or replace Movies document")
}

}

self.wait(for: [expectation], timeout: 1.0)

}

func testAddDataDocuments() {

//Prepare the mock server

let jsonString = """
{"updateId":0}
"""

let decoder: JSONDecoder = JSONDecoder()
let jsonData = jsonString.data(using: .utf8)!
let stubUpdate: Update = try! decoder.decode(Update.self, from: jsonData)

session.pushData(jsonString, code: 202)

// Start the test with the mocked server

let uid: String = "Movies"

let documentJsonString = """
[{
"id": 287947,
Expand Down Expand Up @@ -358,6 +403,7 @@ class DocumentsTests: XCTestCase {

static var allTests = [
("testAddDocuments", testAddDocuments),
("testAddDataDocuments", testAddDataDocuments),
("testUpdateDocuments", testUpdateDocuments),
("testGetDocument", testGetDocument),
("testGetDocuments", testGetDocuments),
Expand Down