1
- import { MockProvider } from 'ng-mocks' ;
1
+ import { MockComponents , MockProvider } from 'ng-mocks' ;
2
2
3
3
import { BehaviorSubject } from 'rxjs' ;
4
4
5
5
import { ComponentFixture , TestBed } from '@angular/core/testing' ;
6
6
import { ActivatedRoute , Router } from '@angular/router' ;
7
7
8
8
import { IS_MEDIUM } from '@osf/shared/helpers' ;
9
+ import { SelectComponent , SubHeaderComponent } from '@shared/components' ;
10
+
11
+ import { CollectionModerationTab } from '../../enums' ;
9
12
10
13
import { CollectionModerationComponent } from './collection-moderation.component' ;
11
14
12
15
import { OSFTestingStoreModule } from '@testing/osf.testing.module' ;
16
+ import { ActivatedRouteMockBuilder } from '@testing/providers/route-provider.mock' ;
17
+ import { RouterMockBuilder } from '@testing/providers/router-provider.mock' ;
13
18
14
19
describe ( 'Component: Collection Moderation' , ( ) => {
15
20
let component : CollectionModerationComponent ;
16
21
let fixture : ComponentFixture < CollectionModerationComponent > ;
17
22
let isMediumSubject : BehaviorSubject < boolean > ;
18
-
19
- const mockActivatedRoute = {
20
- snapshot : {
21
- firstChild : {
22
- data : {
23
- tab : null ,
24
- } ,
25
- } ,
26
- params : { providerId : 'osf' } ,
27
- } ,
28
- } ;
29
-
30
- const mockRouter = {
31
- navigate : jest . fn ( ) ,
32
- } ;
23
+ let mockRouter : ReturnType < RouterMockBuilder [ 'build' ] > ;
24
+ let mockActivatedRoute : ReturnType < ActivatedRouteMockBuilder [ 'build' ] > ;
33
25
34
26
beforeEach ( async ( ) => {
35
27
isMediumSubject = new BehaviorSubject < boolean > ( true ) ;
28
+ mockRouter = RouterMockBuilder . create ( ) . build ( ) ;
29
+ mockActivatedRoute = ActivatedRouteMockBuilder . create ( )
30
+ . withParams ( { providerId : 'test-provider-id' } )
31
+ . withData ( { tab : CollectionModerationTab . AllItems } )
32
+ . build ( ) ;
36
33
37
34
await TestBed . configureTestingModule ( {
38
- imports : [ CollectionModerationComponent , OSFTestingStoreModule ] ,
35
+ imports : [
36
+ CollectionModerationComponent ,
37
+ OSFTestingStoreModule ,
38
+ ...MockComponents ( SubHeaderComponent , SelectComponent ) ,
39
+ ] ,
39
40
providers : [
40
- { provide : ActivatedRoute , useValue : mockActivatedRoute } ,
41
- { provide : Router , useValue : mockRouter } ,
41
+ MockProvider ( ActivatedRoute , mockActivatedRoute ) ,
42
+ MockProvider ( Router , mockRouter ) ,
42
43
MockProvider ( IS_MEDIUM , isMediumSubject ) ,
43
44
] ,
44
45
} ) . compileComponents ( ) ;
@@ -51,4 +52,144 @@ describe('Component: Collection Moderation', () => {
51
52
it ( 'should create' , ( ) => {
52
53
expect ( component ) . toBeTruthy ( ) ;
53
54
} ) ;
55
+
56
+ it ( 'should initialize with default values' , ( ) => {
57
+ expect ( component . selectedTab ) . toBeUndefined ( ) ;
58
+ expect ( component . tabOptions ) . toBeDefined ( ) ;
59
+ expect ( component . isMedium ) . toBeDefined ( ) ;
60
+ } ) ;
61
+
62
+ it ( 'should initialize selected tab from route data' , async ( ) => {
63
+ const mockFirstChild = {
64
+ data : { tab : CollectionModerationTab . Moderators } ,
65
+ } ;
66
+
67
+ const routeWithFirstChild = ActivatedRouteMockBuilder . create ( )
68
+ . withParams ( { providerId : 'test-provider-id' } )
69
+ . build ( ) ;
70
+
71
+ Object . defineProperty ( routeWithFirstChild . snapshot , 'firstChild' , {
72
+ value : mockFirstChild ,
73
+ writable : true ,
74
+ } ) ;
75
+
76
+ await TestBed . configureTestingModule ( {
77
+ imports : [
78
+ CollectionModerationComponent ,
79
+ OSFTestingStoreModule ,
80
+ ...MockComponents ( SubHeaderComponent , SelectComponent ) ,
81
+ ] ,
82
+ providers : [
83
+ MockProvider ( ActivatedRoute , routeWithFirstChild ) ,
84
+ MockProvider ( Router , mockRouter ) ,
85
+ MockProvider ( IS_MEDIUM , isMediumSubject ) ,
86
+ ] ,
87
+ } ) . compileComponents ( ) ;
88
+
89
+ const testFixture = TestBed . createComponent ( CollectionModerationComponent ) ;
90
+ const testComponent = testFixture . componentInstance ;
91
+
92
+ testComponent . ngOnInit ( ) ;
93
+
94
+ expect ( testComponent . selectedTab ) . toBe ( CollectionModerationTab . Moderators ) ;
95
+ } ) ;
96
+
97
+ it ( 'should navigate to not-found when providerId is missing' , async ( ) => {
98
+ const routeWithoutProviderId = ActivatedRouteMockBuilder . create ( ) . withParams ( { } ) . build ( ) ;
99
+
100
+ await TestBed . configureTestingModule ( {
101
+ imports : [
102
+ CollectionModerationComponent ,
103
+ OSFTestingStoreModule ,
104
+ ...MockComponents ( SubHeaderComponent , SelectComponent ) ,
105
+ ] ,
106
+ providers : [
107
+ MockProvider ( ActivatedRoute , routeWithoutProviderId ) ,
108
+ MockProvider ( Router , mockRouter ) ,
109
+ MockProvider ( IS_MEDIUM , isMediumSubject ) ,
110
+ ] ,
111
+ } ) . compileComponents ( ) ;
112
+
113
+ const testFixture = TestBed . createComponent ( CollectionModerationComponent ) ;
114
+ const testComponent = testFixture . componentInstance ;
115
+
116
+ testComponent . ngOnInit ( ) ;
117
+
118
+ expect ( mockRouter . navigate ) . toHaveBeenCalledWith ( [ '/not-found' ] ) ;
119
+ } ) ;
120
+
121
+ it ( 'should call getCollectionProvider action on init when providerId exists' , ( ) => {
122
+ const getCollectionProviderSpy = jest . fn ( ) ;
123
+ component . actions = {
124
+ ...component . actions ,
125
+ getCollectionProvider : getCollectionProviderSpy ,
126
+ } ;
127
+
128
+ component . ngOnInit ( ) ;
129
+
130
+ expect ( getCollectionProviderSpy ) . toHaveBeenCalledWith ( 'test-provider-id' ) ;
131
+ } ) ;
132
+
133
+ it ( 'should handle tab change and navigate to new tab' , ( ) => {
134
+ const newTab = CollectionModerationTab . Moderators ;
135
+
136
+ component . onTabChange ( newTab ) ;
137
+
138
+ expect ( component . selectedTab ) . toBe ( newTab ) ;
139
+ expect ( mockRouter . navigate ) . toHaveBeenCalledWith ( [ newTab ] , { relativeTo : expect . any ( Object ) } ) ;
140
+ } ) ;
141
+
142
+ it ( 'should call clearCurrentProvider on destroy' , ( ) => {
143
+ const clearCurrentProviderSpy = jest . fn ( ) ;
144
+ component . actions = {
145
+ ...component . actions ,
146
+ clearCurrentProvider : clearCurrentProviderSpy ,
147
+ } ;
148
+
149
+ component . ngOnDestroy ( ) ;
150
+
151
+ expect ( clearCurrentProviderSpy ) . toHaveBeenCalled ( ) ;
152
+ } ) ;
153
+
154
+ it ( 'should have actions defined' , ( ) => {
155
+ expect ( component . actions ) . toBeDefined ( ) ;
156
+ expect ( component . actions . getCollectionProvider ) . toBeDefined ( ) ;
157
+ expect ( component . actions . clearCurrentProvider ) . toBeDefined ( ) ;
158
+ } ) ;
159
+
160
+ it ( 'should have tab options defined' , ( ) => {
161
+ expect ( component . tabOptions ) . toBeDefined ( ) ;
162
+ expect ( component . tabOptions . length ) . toBeGreaterThan ( 0 ) ;
163
+ } ) ;
164
+
165
+ it ( 'should handle isMedium observable' , ( ) => {
166
+ expect ( component . isMedium ( ) ) . toBe ( true ) ;
167
+
168
+ isMediumSubject . next ( false ) ;
169
+ fixture . detectChanges ( ) ;
170
+
171
+ expect ( component . isMedium ( ) ) . toBe ( false ) ;
172
+ } ) ;
173
+
174
+ it ( 'should handle tab change with different tab values' , ( ) => {
175
+ const tabs = [
176
+ CollectionModerationTab . AllItems ,
177
+ CollectionModerationTab . Moderators ,
178
+ CollectionModerationTab . Settings ,
179
+ ] ;
180
+
181
+ tabs . forEach ( ( tab ) => {
182
+ component . onTabChange ( tab ) ;
183
+ expect ( component . selectedTab ) . toBe ( tab ) ;
184
+ expect ( mockRouter . navigate ) . toHaveBeenCalledWith ( [ tab ] , { relativeTo : expect . any ( Object ) } ) ;
185
+ } ) ;
186
+ } ) ;
187
+
188
+ it ( 'should not navigate when providerId is present' , ( ) => {
189
+ mockActivatedRoute = ActivatedRouteMockBuilder . create ( ) . withParams ( { providerId : 'valid-id' } ) . build ( ) ;
190
+
191
+ component . ngOnInit ( ) ;
192
+
193
+ expect ( mockRouter . navigate ) . not . toHaveBeenCalledWith ( [ '/not-found' ] ) ;
194
+ } ) ;
54
195
} ) ;
0 commit comments