|
1 | 1 | import { describe, expect, it } from 'vitest'
|
2 | 2 |
|
3 | 3 | import { Model, useRepo } from '../../../src'
|
4 |
| -import { Attr, HasManyThrough, Str } from '../../../src/decorators' |
| 4 | +import { Attr, HasMany, HasManyThrough, Str } from '../../../src/decorators' |
5 | 5 | import { assertInstanceOf, assertModel, fillState } from '../../helpers'
|
6 | 6 |
|
7 | 7 | describe('feature/relations/has_many_through_retrieve', () => {
|
@@ -115,4 +115,72 @@ describe('feature/relations/has_many_through_retrieve', () => {
|
115 | 115 | expect(country.posts[0].id).toBe(2)
|
116 | 116 | expect(country.posts[1].id).toBe(1)
|
117 | 117 | })
|
| 118 | + |
| 119 | + it('can retrieve multi-level "has many through" relations with manual comparison', () => { |
| 120 | + // Extend the Country model with a direct relationship to users to manifest the difference |
| 121 | + class ExtendedCountry extends Country { |
| 122 | + @HasMany(() => User, 'countryId') |
| 123 | + declare users: User[] |
| 124 | + } |
| 125 | + |
| 126 | + // Extend the User model with a direct relationship to posts to manifest the difference |
| 127 | + class ExtendedUser extends User { |
| 128 | + @HasMany(() => Post, 'userId') |
| 129 | + declare posts: Post[] |
| 130 | + } |
| 131 | + |
| 132 | + const countryRepo = useRepo(ExtendedCountry) |
| 133 | + |
| 134 | + // Set up test data with: |
| 135 | + // - 2 countries |
| 136 | + // - 3 users (2 in country 1, 1 in country 2) |
| 137 | + // - 5 posts (3 from user 1, 1 from user 2, 1 from user 3) |
| 138 | + fillState({ |
| 139 | + users: { |
| 140 | + 1: { id: 1, name: 'John Doe', countryId: 1 }, |
| 141 | + 2: { id: 2, name: 'Jane Doe', countryId: 1 }, |
| 142 | + 3: { id: 3, name: 'Johnny Doe', countryId: 2 }, |
| 143 | + }, |
| 144 | + countries: { |
| 145 | + 1: { id: 1 }, |
| 146 | + 2: { id: 2 }, |
| 147 | + }, |
| 148 | + posts: { |
| 149 | + 1: { id: 1, userId: 1, title: 'Title 01' }, |
| 150 | + 2: { id: 2, userId: 1, title: 'Title 02' }, |
| 151 | + 3: { id: 3, userId: 1, title: 'Title 03' }, |
| 152 | + 4: { id: 4, userId: 2, title: 'Title 04' }, |
| 153 | + 5: { id: 5, userId: 3, title: 'Title 05' }, |
| 154 | + }, |
| 155 | + }) |
| 156 | + |
| 157 | + // Register the extended user model to make posts accessible |
| 158 | + useRepo(ExtendedUser) |
| 159 | + |
| 160 | + // Retrieve country with all related data |
| 161 | + const country = countryRepo.withAllRecursive().first()! |
| 162 | + |
| 163 | + // Verify the country is retrieved correctly |
| 164 | + expect(country.id).toBe(1) |
| 165 | + |
| 166 | + // Verify users are retrieved correctly |
| 167 | + expect(country.users.length).toBe(2) |
| 168 | + |
| 169 | + // Verify posts are retrieved correctly through HasManyThrough |
| 170 | + expect(country.posts.length).toBe(4) // Should include all posts from all users in country 1 |
| 171 | + |
| 172 | + // Manually retrieve all posts through users to compare |
| 173 | + const manualPosts = country.users.flatMap((user) => { |
| 174 | + // Cast user to ExtendedUser to access posts |
| 175 | + return (user as unknown as ExtendedUser).posts |
| 176 | + }) |
| 177 | + |
| 178 | + // Compare the manual retrieval with the HasManyThrough relationship |
| 179 | + // This tests that HasManyThrough correctly retrieves all related models |
| 180 | + expect(country.posts.length).toEqual(manualPosts.length) |
| 181 | + |
| 182 | + // Verify all expected post IDs are present |
| 183 | + const postIds = country.posts.map(post => post.id).sort() |
| 184 | + expect(postIds).toEqual([1, 2, 3, 4]) |
| 185 | + }) |
118 | 186 | })
|
0 commit comments