Skip to content

Commit

Permalink
Updated unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
colemancda committed Aug 19, 2023
1 parent 854bed1 commit ef5f33a
Show file tree
Hide file tree
Showing 2 changed files with 361 additions and 1 deletion.
39 changes: 38 additions & 1 deletion Tests/CoreModelMongoDBTests/MongoDBModelTests.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Foundation
import XCTest
import NIO
@testable import CoreModel
@testable import MongoDBModel

final class MongoDBModelTests: XCTestCase {
Expand All @@ -20,7 +21,7 @@ final class MongoDBModelTests: XCTestCase {
try? elg.syncShutdownGracefully()
}

let model = Model(entities: Person.self, Event.self)
let model = Model(entities: Person.self, Event.self, Campground.self, Campground.RentalUnit.self)
let store = MongoModelStorage(
database: database,
model: model
Expand All @@ -36,6 +37,7 @@ final class MongoDBModelTests: XCTestCase {
date: Date(timeIntervalSinceNow: 60 * 60 * 24 * 10)
)

// set relationship
event1.people.append(person1.id)
person1.events.append(event1.id)

Expand All @@ -45,5 +47,40 @@ final class MongoDBModelTests: XCTestCase {
XCTAssertEqual(person1.events, [event1.id])
event1 = try await store.fetch(Event.self, for: event1.id)!
XCTAssertEqual(event1.people, [person1.id])

var campground = Campground(
name: "Fair Play RV Park",
address: """
243 Fisher Cove Rd,
Fair Play, SC
""",
location: .init(latitude: 34.51446212994721, longitude: -83.01371101951648),
descriptionText: """
At Fair Play RV Park, we are committed to providing a clean, safe and fun environment for all of our guests, including your fur-babies! We look forward to meeting you and having you stay with us!
""",
officeHours: Campground.Schedule(start: 60 * 8, end: 60 * 18)
)

let rentalUnit = Campground.RentalUnit(
campground: campground.id,
name: "A1",
amenities: [.amp50, .water, .mail, .river, .laundry],
checkout: campground.officeHours
)

// set relationship
campground.units = [rentalUnit.id]

var campgroundData = try campground.encode(log: { print("Encoder:", $0) })
try await store.insert(campgroundData)
let rentalUnitData = try rentalUnit.encode(log: { print("Encoder:", $0) })
XCTAssertEqual(rentalUnitData.relationships[PropertyKey(Campground.RentalUnit.CodingKeys.campground)], .toOne(ObjectID(campground.id)))
try await store.insert(rentalUnitData)
campgroundData = try await store.fetch(Campground.entityName, for: ObjectID(campground.id))!
campground = try .init(from: campgroundData, log: { print("Decoder:", $0) })
XCTAssertEqual(campground.units, [rentalUnit.id])
XCTAssertEqual(campgroundData.relationships[PropertyKey(Campground.CodingKeys.units)], .toMany([ObjectID(rentalUnit.id)]))
let fetchedRentalUnit = try await store.fetch(Campground.RentalUnit.self, for: rentalUnit.id)
XCTAssertEqual(fetchedRentalUnit, rentalUnit)
}
}
323 changes: 323 additions & 0 deletions Tests/CoreModelMongoDBTests/TestModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,326 @@ extension Event: Entity {
]
}
}

/// Campground Location
public struct Campground: Equatable, Hashable, Codable, Identifiable {

public let id: UUID

public let created: Date

public let updated: Date

public var name: String

public var address: String

public var location: LocationCoordinates

public var amenities: [Amenity]

public var phoneNumber: String?

public var descriptionText: String

/// The number of seconds from GMT.
public var timeZone: Int

public var notes: String?

public var directions: String?

public var units: [RentalUnit.ID]

public var officeHours: Schedule

public init(
id: UUID = UUID(),
created: Date = Date(),
updated: Date = Date(),
name: String,
address: String,
location: LocationCoordinates,
amenities: [Amenity] = [],
phoneNumber: String? = nil,
descriptionText: String,
notes: String? = nil,
directions: String? = nil,
units: [RentalUnit.ID] = [],
timeZone: Int = 0,
officeHours: Schedule
) {
self.id = id
self.created = created
self.updated = updated
self.name = name
self.address = address
self.location = location
self.amenities = amenities
self.phoneNumber = phoneNumber
self.descriptionText = descriptionText
self.notes = notes
self.directions = directions
self.units = units
self.timeZone = timeZone
self.officeHours = officeHours
}

public enum CodingKeys: CodingKey {
case id
case created
case updated
case name
case address
case location
case amenities
case phoneNumber
case descriptionText
case timeZone
case notes
case directions
case units
case officeHours
}
}

extension Campground: Entity {

public static var entityName: EntityName { "Campground" }

public static var attributes: [CodingKeys: AttributeType] {
[
.name : .string,
.created : .date,
.updated : .date,
.address : .string,
.location: .string,
.amenities: .string,
.phoneNumber: .string,
.descriptionText: .string,
.timeZone: .int32,
.notes: .string,
.directions: .string,
.officeHours: .string
]
}

public static var relationships: [CodingKeys: Relationship] {
[
.units : Relationship(
id: PropertyKey(CodingKeys.units),
type: .toMany,
destinationEntity: RentalUnit.entityName,
inverseRelationship: PropertyKey(RentalUnit.CodingKeys.campground)
)
]
}
}

public extension Campground {

/// Campground Amenities
enum Amenity: String, Codable, CaseIterable {

case water
case amp30
case amp50
case wifi
case laundry
case mail
case dumpStation
case picnicArea
case storage
case cabins
case showers
case restrooms
case pool
case fishing
case beach
case lake
case river
case rv
case tent
case pets
}
}

extension Array: AttributeEncodable where Self.Element == Campground.Amenity {

public var attributeValue: AttributeValue {
let string = self.reduce("", { $0 + ($0.isEmpty ? "" : ",") + $1.rawValue })
return .string(string)
}
}

extension Array: AttributeDecodable where Self.Element == Campground.Amenity {

public init?(attributeValue: AttributeValue) {
guard let string = String(attributeValue: attributeValue) else {
return nil
}
let components = string
.components(separatedBy: ",")
.filter { $0.isEmpty == false }
var values = [Campground.Amenity]()
values.reserveCapacity(components.count)
for element in components {
guard let value = Self.Element(rawValue: element) else {
return nil
}
values.append(value)
}
self = values
}
}

public extension Campground {

/// Location Coordinates
struct LocationCoordinates: Equatable, Hashable, Codable {

/// Latitude
public var latitude: Double

/// Longitude
public var longitude: Double

public init(latitude: Double, longitude: Double) {
self.latitude = latitude
self.longitude = longitude
}
}
}

extension Campground.LocationCoordinates: AttributeEncodable {

public var attributeValue: AttributeValue {
return .string("\(latitude),\(longitude)")
}
}

extension Campground.LocationCoordinates: AttributeDecodable {

public init?(attributeValue: AttributeValue) {
guard let string = String(attributeValue: attributeValue) else {
return nil
}
let components = string.components(separatedBy: ",")
guard components.count == 2,
let latitude = Double(components[0]),
let longitude = Double(components[1]) else {
return nil
}
self.init(latitude: latitude, longitude: longitude)
}
}

public extension Campground {

/// Schedule (e.g. Check in, Check Out)
struct Schedule: Equatable, Hashable, Codable {

public var start: UInt

public var end: UInt

public init(start: UInt, end: UInt) {
assert(start < end)
self.start = start
self.end = end
}
}
}

extension Campground.Schedule: AttributeEncodable {

public var attributeValue: AttributeValue {
return .string("\(start),\(end)")
}
}

extension Campground.Schedule: AttributeDecodable {

public init?(attributeValue: AttributeValue) {
guard let string = String(attributeValue: attributeValue) else {
return nil
}
let components = string.components(separatedBy: ",")
guard components.count == 2,
let start = UInt(components[0]),
let end = UInt(components[1]) else {
return nil
}
self.init(start: start, end: end)
}
}

public extension Campground {

/// Campground Rental Unit
struct RentalUnit: Equatable, Hashable, Codable, Identifiable {

public let id: UUID

public let campground: Campground.ID

public var name: String

public var notes: String?

public var amenities: [Amenity]

public var checkout: Schedule

public init(
id: UUID = UUID(),
campground: Campground.ID,
name: String,
notes: String? = nil,
amenities: [Amenity] = [],
checkout: Schedule
) {
self.id = id
self.campground = campground
self.name = name
self.notes = notes
self.amenities = amenities
self.checkout = checkout
}

public enum CodingKeys: CodingKey {

case id
case campground
case name
case notes
case amenities
case checkout
}
}
}

extension Campground.RentalUnit: Entity {

public static var entityName: EntityName { "RentalUnit" }

public static var attributes: [CodingKeys: AttributeType] {
[
.name : .string,
.notes : .string,
.amenities : .string,
.checkout : .string
]
}

public static var relationships: [CodingKeys: Relationship] {
[
.campground : Relationship(
id: PropertyKey(CodingKeys.campground),
type: .toOne,
destinationEntity: Campground.entityName,
inverseRelationship: PropertyKey(Campground.CodingKeys.units)
)
]
}
}

0 comments on commit ef5f33a

Please sign in to comment.