Skip to content

Commit 5333447

Browse files
committed
fix: Add missing PropertyPath types double and int (#2689)
* chore: enable lazy loading integration tests * update branches for GH workflows * fix: test UserPostComment schema * add lazy load tests * add schema with Double field, fix PropertyPath
1 parent c123890 commit 5333447

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+3318
-2
lines changed

Amplify/Categories/DataStore/Model/PropertyPath.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,12 @@ open class ModelPath<ModelType: Model> : PropertyContainerPath {
123123
public func time(_ name: String) -> FieldPath<Temporal.Time> {
124124
FieldPath(name: name, parent: self)
125125
}
126+
127+
public func int(_ name: String) -> FieldPath<Int> {
128+
FieldPath(name: name, parent: self)
129+
}
130+
131+
public func double(_ name: String) -> FieldPath<Double> {
132+
FieldPath(name: name, parent: self)
133+
}
126134
}

AmplifyPlugins/API/Tests/APIHostApp/APIHostApp.xcodeproj/project.pbxproj

Lines changed: 108 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// swiftlint:disable all
2+
import Amplify
3+
import Foundation
4+
5+
extension Comment14 {
6+
// MARK: - CodingKeys
7+
public enum CodingKeys: String, ModelKey {
8+
case id
9+
case content
10+
case post
11+
case author
12+
case createdAt
13+
case updatedAt
14+
}
15+
16+
public static let keys = CodingKeys.self
17+
// MARK: - ModelSchema
18+
19+
public static let schema = defineSchema { model in
20+
let comment14 = Comment14.keys
21+
22+
model.authRules = [
23+
rule(allow: .public, operations: [.create, .update, .delete, .read])
24+
]
25+
26+
model.pluralName = "Comment14s"
27+
28+
model.attributes(
29+
.primaryKey(fields: [comment14.id])
30+
)
31+
32+
model.fields(
33+
.field(comment14.id, is: .required, ofType: .string),
34+
.field(comment14.content, is: .optional, ofType: .string),
35+
.belongsTo(comment14.post, is: .optional, ofType: Post14.self, targetNames: ["post14CommentsId"]),
36+
.belongsTo(comment14.author, is: .required, ofType: User14.self, targetNames: ["user14CommentsId"]),
37+
.field(comment14.createdAt, is: .optional, isReadOnly: true, ofType: .dateTime),
38+
.field(comment14.updatedAt, is: .optional, isReadOnly: true, ofType: .dateTime)
39+
)
40+
}
41+
public class Path: ModelPath<Comment14> { }
42+
43+
public static var rootPath: PropertyContainerPath? { Path() }
44+
}
45+
46+
extension Comment14: ModelIdentifiable {
47+
public typealias IdentifierFormat = ModelIdentifierFormat.Default
48+
public typealias IdentifierProtocol = DefaultModelIdentifier<Self>
49+
}
50+
extension ModelPath where ModelType == Comment14 {
51+
public var id: FieldPath<String> {
52+
string("id")
53+
}
54+
public var content: FieldPath<String> {
55+
string("content")
56+
}
57+
public var post: ModelPath<Post14> {
58+
Post14.Path(name: "post", parent: self)
59+
}
60+
public var author: ModelPath<User14> {
61+
User14.Path(name: "author", parent: self)
62+
}
63+
public var createdAt: FieldPath<Temporal.DateTime> {
64+
datetime("createdAt")
65+
}
66+
public var updatedAt: FieldPath<Temporal.DateTime> {
67+
datetime("updatedAt")
68+
}
69+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// swiftlint:disable all
2+
import Amplify
3+
import Foundation
4+
5+
public struct Comment14: Model {
6+
public let id: String
7+
public var content: String?
8+
internal var _post: LazyReference<Post14>
9+
public var post: Post14? {
10+
get async throws {
11+
try await _post.get()
12+
}
13+
}
14+
internal var _author: LazyReference<User14>
15+
public var author: User14 {
16+
get async throws {
17+
try await _author.require()
18+
}
19+
}
20+
public var createdAt: Temporal.DateTime?
21+
public var updatedAt: Temporal.DateTime?
22+
23+
public init(id: String = UUID().uuidString,
24+
content: String? = nil,
25+
post: Post14? = nil,
26+
author: User14) {
27+
self.init(id: id,
28+
content: content,
29+
post: post,
30+
author: author,
31+
createdAt: nil,
32+
updatedAt: nil)
33+
}
34+
internal init(id: String = UUID().uuidString,
35+
content: String? = nil,
36+
post: Post14? = nil,
37+
author: User14,
38+
createdAt: Temporal.DateTime? = nil,
39+
updatedAt: Temporal.DateTime? = nil) {
40+
self.id = id
41+
self.content = content
42+
self._post = LazyReference(post)
43+
self._author = LazyReference(author)
44+
self.createdAt = createdAt
45+
self.updatedAt = updatedAt
46+
}
47+
public mutating func setPost(_ post: Post14? = nil) {
48+
self._post = LazyReference(post)
49+
}
50+
public mutating func setAuthor(_ author: User14) {
51+
self._author = LazyReference(author)
52+
}
53+
public init(from decoder: Decoder) throws {
54+
let values = try decoder.container(keyedBy: CodingKeys.self)
55+
id = try values.decode(String.self, forKey: .id)
56+
content = try? values.decode(String?.self, forKey: .content)
57+
_post = try values.decodeIfPresent(LazyReference<Post14>.self, forKey: .post) ?? LazyReference(identifiers: nil)
58+
_author = try values.decodeIfPresent(LazyReference<User14>.self, forKey: .author) ?? LazyReference(identifiers: nil)
59+
createdAt = try? values.decode(Temporal.DateTime?.self, forKey: .createdAt)
60+
updatedAt = try? values.decode(Temporal.DateTime?.self, forKey: .updatedAt)
61+
}
62+
public func encode(to encoder: Encoder) throws {
63+
var container = encoder.container(keyedBy: CodingKeys.self)
64+
try container.encode(id, forKey: .id)
65+
try container.encode(content, forKey: .content)
66+
try container.encode(_post, forKey: .post)
67+
try container.encode(_author, forKey: .author)
68+
try container.encode(createdAt, forKey: .createdAt)
69+
try container.encode(updatedAt, forKey: .updatedAt)
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
//
2+
// Copyright Amazon.com Inc. or its affiliates.
3+
// All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import Foundation
9+
import Combine
10+
import XCTest
11+
12+
@testable import Amplify
13+
14+
final class GraphQLLazyLoadUserPostCommentTests: GraphQLLazyLoadBaseTest {
15+
16+
func testConfigure() async throws {
17+
await setup(withModels: UserPostCommentModels(), logLevel: .verbose)
18+
}
19+
20+
func testSaveUser() async throws {
21+
await setup(withModels: UserPostCommentModels())
22+
let user = User(username: "name")
23+
try await mutate(.create(user))
24+
}
25+
26+
func testSaveUserSettings() async throws {
27+
await setup(withModels: UserPostCommentModels())
28+
let user = User(username: "name")
29+
let savedUser = try await mutate(.create(user))
30+
31+
let userSettings = UserSettings(language: "en-us", user: savedUser)
32+
try await mutate(.create(userSettings))
33+
}
34+
35+
func testSavePost() async throws {
36+
await setup(withModels: UserPostCommentModels())
37+
let user = User(username: "name")
38+
let savedUser = try await mutate(.create(user))
39+
let post = Post(title: "title", rating: 1, status: .active, author: savedUser)
40+
try await mutate(.create(post))
41+
}
42+
43+
func testSaveComment() async throws {
44+
await setup(withModels: UserPostCommentModels())
45+
let user = User(username: "name")
46+
let savedUser = try await mutate(.create(user))
47+
let post = Post(title: "title", rating: 1, status: .active, author: savedUser)
48+
let savedPost = try await mutate(.create(post))
49+
50+
let comment = Comment(content: "content", post: savedPost, author: savedUser)
51+
try await mutate(.create(comment))
52+
}
53+
54+
/// LazyLoad from queried models
55+
///
56+
/// - Given: Created models
57+
/// - When:
58+
/// - Querying for models
59+
/// - Then:
60+
/// - Traversing from the models to its connected models are successful
61+
///
62+
func testLazyLoad() async throws {
63+
await setup(withModels: UserPostCommentModels())
64+
let user = User(username: "name")
65+
let savedUser = try await mutate(.create(user))
66+
let userSettings = UserSettings(language: "en-us", user: savedUser)
67+
try await mutate(.create(userSettings))
68+
let post = Post(title: "title", rating: 1, status: .active, author: savedUser)
69+
let savedPost = try await mutate(.create(post))
70+
let comment = Comment(content: "content", post: savedPost, author: savedUser)
71+
try await mutate(.create(comment))
72+
73+
// Traverse from User
74+
let queriedUser = try await query(for: user)!
75+
try await queriedUser.posts?.fetch()
76+
XCTAssertEqual(queriedUser.posts?.count, 1)
77+
try await queriedUser.comments?.fetch()
78+
XCTAssertEqual(queriedUser.comments?.count, 1)
79+
// Cannot traverse from User to settings
80+
//let queriedUserSettings = try await queriedUser.settings
81+
//XCTAssertNotNil(queriedUserSettings)
82+
83+
// Traverse from UserSettings
84+
let queriedSettings = try await query(for: userSettings)!
85+
let queriedSettingsUser = try await queriedSettings.user
86+
XCTAssertEqual(queriedSettingsUser.id, user.id)
87+
88+
// Traverse from Post
89+
let queriedPost = try await query(for: post)!
90+
try await queriedPost.comments?.fetch()
91+
XCTAssertEqual(queriedPost.comments?.count, 1)
92+
let queriedPostUser = try await queriedPost.author
93+
XCTAssertEqual(queriedPostUser.id, user.id)
94+
95+
// Traverse from Comment
96+
let queriedComment = try await query(for: comment)!
97+
let queriedCommentPost = try await queriedComment.post
98+
XCTAssertEqual(queriedCommentPost?.id, post.id)
99+
let queriedCommentUser = try await queriedComment.author
100+
XCTAssertEqual(queriedCommentUser.id, user.id)
101+
102+
// Clean up - delete the saved models
103+
try await mutate(.delete(comment))
104+
try await assertModelDoesNotExist(comment)
105+
try await mutate(.delete(post))
106+
try await assertModelDoesNotExist(post)
107+
try await mutate(.delete(userSettings))
108+
try await assertModelDoesNotExist(userSettings)
109+
try await mutate(.delete(user))
110+
try await assertModelDoesNotExist(user)
111+
}
112+
}
113+
114+
extension GraphQLLazyLoadUserPostCommentTests {
115+
typealias User = User14
116+
typealias Post = Post14
117+
typealias Comment = Comment14
118+
typealias UserSettings = UserSettings14
119+
120+
struct UserPostCommentModels: AmplifyModelRegistration {
121+
public let version: String = "version"
122+
func registerModels(registry: ModelRegistry.Type) {
123+
ModelRegistry.register(modelType: User14.self)
124+
ModelRegistry.register(modelType: Post14.self)
125+
ModelRegistry.register(modelType: Comment14.self)
126+
ModelRegistry.register(modelType: UserSettings14.self)
127+
}
128+
}
129+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// swiftlint:disable all
2+
import Amplify
3+
import Foundation
4+
5+
extension Post14 {
6+
// MARK: - CodingKeys
7+
public enum CodingKeys: String, ModelKey {
8+
case id
9+
case title
10+
case rating
11+
case status
12+
case comments
13+
case author
14+
case createdAt
15+
case updatedAt
16+
}
17+
18+
public static let keys = CodingKeys.self
19+
// MARK: - ModelSchema
20+
21+
public static let schema = defineSchema { model in
22+
let post14 = Post14.keys
23+
24+
model.authRules = [
25+
rule(allow: .public, operations: [.create, .update, .delete, .read])
26+
]
27+
28+
model.pluralName = "Post14s"
29+
30+
model.attributes(
31+
.primaryKey(fields: [post14.id])
32+
)
33+
34+
model.fields(
35+
.field(post14.id, is: .required, ofType: .string),
36+
.field(post14.title, is: .required, ofType: .string),
37+
.field(post14.rating, is: .required, ofType: .int),
38+
.field(post14.status, is: .required, ofType: .enum(type: PostStatus.self)),
39+
.hasMany(post14.comments, is: .optional, ofType: Comment14.self, associatedWith: Comment14.keys.post),
40+
.belongsTo(post14.author, is: .required, ofType: User14.self, targetNames: ["user14PostsId"]),
41+
.field(post14.createdAt, is: .optional, isReadOnly: true, ofType: .dateTime),
42+
.field(post14.updatedAt, is: .optional, isReadOnly: true, ofType: .dateTime)
43+
)
44+
}
45+
public class Path: ModelPath<Post14> { }
46+
47+
public static var rootPath: PropertyContainerPath? { Path() }
48+
}
49+
50+
extension Post14: ModelIdentifiable {
51+
public typealias IdentifierFormat = ModelIdentifierFormat.Default
52+
public typealias IdentifierProtocol = DefaultModelIdentifier<Self>
53+
}
54+
extension ModelPath where ModelType == Post14 {
55+
public var id: FieldPath<String> {
56+
string("id")
57+
}
58+
public var title: FieldPath<String> {
59+
string("title")
60+
}
61+
public var rating: FieldPath<Int> {
62+
int("rating")
63+
}
64+
public var comments: ModelPath<Comment14> {
65+
Comment14.Path(name: "comments", isCollection: true, parent: self)
66+
}
67+
public var author: ModelPath<User14> {
68+
User14.Path(name: "author", parent: self)
69+
}
70+
public var createdAt: FieldPath<Temporal.DateTime> {
71+
datetime("createdAt")
72+
}
73+
public var updatedAt: FieldPath<Temporal.DateTime> {
74+
datetime("updatedAt")
75+
}
76+
}

0 commit comments

Comments
 (0)