@umituz/react-native-subscription 2.14.98 → 2.14.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +211 -395
- package/package.json +1 -1
- package/src/application/README.md +46 -225
- package/src/application/ports/README.md +42 -97
- package/src/domain/README.md +36 -384
- package/src/domain/constants/README.md +0 -56
- package/src/domain/entities/README.md +43 -169
- package/src/domain/errors/README.md +33 -287
- package/src/domain/value-objects/README.md +43 -179
- package/src/domains/README.md +52 -0
- package/src/domains/README.md.bak +274 -0
- package/src/domains/config/README.md +93 -383
- package/src/domains/config/domain/README.md +37 -0
- package/src/domains/config/domain/entities/README.md +41 -0
- package/src/domains/paywall/README.md +99 -369
- package/src/domains/paywall/components/README.md +34 -178
- package/src/domains/paywall/entities/README.md +34 -193
- package/src/domains/paywall/hooks/README.md +34 -122
- package/src/domains/wallet/README.md +34 -275
- package/src/domains/wallet/README.md.bak +209 -0
- package/src/domains/wallet/domain/README.md +34 -101
- package/src/domains/wallet/domain/entities/README.md +34 -115
- package/src/domains/wallet/domain/errors/README.md +34 -151
- package/src/domains/wallet/infrastructure/README.md +34 -89
- package/src/domains/wallet/presentation/components/README.md +34 -224
- package/src/domains/wallet/presentation/hooks/README.md +34 -248
- package/src/infrastructure/README.md +37 -496
- package/src/infrastructure/mappers/README.md +0 -13
- package/src/infrastructure/repositories/README.md +74 -360
- package/src/infrastructure/services/README.md +95 -370
- package/src/presentation/README.md +123 -408
- package/src/presentation/README.md.bak +172 -0
- package/src/presentation/components/README.md +151 -179
- package/src/presentation/components/README.md.bak +217 -0
- package/src/presentation/components/details/CreditRow.md +65 -310
- package/src/presentation/components/details/DetailRow.md +63 -255
- package/src/presentation/components/details/PremiumDetailsCard.md +65 -238
- package/src/presentation/components/details/PremiumStatusBadge.md +64 -239
- package/src/presentation/components/details/README.md +97 -447
- package/src/presentation/components/feedback/PaywallFeedbackModal.md +63 -287
- package/src/presentation/components/feedback/README.md +97 -445
- package/src/presentation/components/paywall/PaywallModal.md +66 -416
- package/src/presentation/components/paywall/README.md +50 -186
- package/src/presentation/components/sections/README.md +97 -466
- package/src/presentation/components/sections/SubscriptionSection.md +92 -244
- package/src/presentation/hooks/README.md +154 -741
- package/src/presentation/hooks/useAuthAwarePurchase.md +58 -325
- package/src/presentation/hooks/useAuthGate.md +61 -375
- package/src/presentation/hooks/useAuthSubscriptionSync.md +66 -370
- package/src/presentation/hooks/useCreditChecker.md +73 -378
- package/src/presentation/hooks/useCredits.md +74 -313
- package/src/presentation/hooks/useCredits.md.bak +231 -0
- package/src/presentation/hooks/useCreditsGate.md +66 -318
- package/src/presentation/hooks/useDeductCredit.md +96 -156
- package/src/presentation/hooks/useDevTestCallbacks.md +63 -394
- package/src/presentation/hooks/useFeatureGate.md +105 -150
- package/src/presentation/hooks/useFeatureGate.md.bak +284 -0
- package/src/presentation/hooks/useInitializeCredits.md +64 -430
- package/src/presentation/hooks/usePaywall.md +61 -306
- package/src/presentation/hooks/usePaywallOperations.md +64 -458
- package/src/presentation/hooks/usePaywallVisibility.md +67 -316
- package/src/presentation/hooks/usePremium.md +84 -226
- package/src/presentation/hooks/usePremiumGate.md +60 -395
- package/src/presentation/hooks/usePremiumWithCredits.md +64 -401
- package/src/presentation/hooks/useSubscription.md +66 -422
- package/src/presentation/hooks/useSubscriptionDetails.md +65 -410
- package/src/presentation/hooks/useSubscriptionGate.md +80 -164
- package/src/presentation/hooks/useSubscriptionSettingsConfig.md +66 -346
- package/src/presentation/hooks/useSubscriptionStatus.md +66 -396
- package/src/presentation/hooks/useUserTier.md +63 -328
- package/src/presentation/hooks/useUserTierWithRepository.md +64 -424
- package/src/presentation/screens/README.md +48 -190
- package/src/presentation/types/README.md +0 -16
- package/src/presentation/utils/README.md +0 -21
- package/src/revenuecat/README.md +99 -518
- package/src/revenuecat/application/README.md +43 -0
- package/src/revenuecat/application/ports/README.md +41 -0
- package/src/revenuecat/domain/README.md +42 -141
- package/src/revenuecat/domain/constants/README.md +41 -0
- package/src/revenuecat/domain/entities/README.md +42 -0
- package/src/revenuecat/domain/errors/README.md +47 -191
- package/src/revenuecat/domain/types/README.md +41 -0
- package/src/revenuecat/domain/value-objects/README.md +41 -0
- package/src/revenuecat/infrastructure/README.md +41 -0
- package/src/revenuecat/infrastructure/config/README.md +32 -23
- package/src/revenuecat/infrastructure/handlers/README.md +41 -0
- package/src/revenuecat/infrastructure/managers/README.md +34 -42
- package/src/revenuecat/infrastructure/services/README.md +42 -0
- package/src/revenuecat/infrastructure/utils/README.md +41 -0
- package/src/revenuecat/presentation/README.md +42 -0
- package/src/revenuecat/presentation/hooks/README.md +29 -35
- package/src/utils/README.md +38 -525
|
@@ -2,402 +2,88 @@
|
|
|
2
2
|
|
|
3
3
|
Hook for combining authentication and subscription gating.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Location
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
import { useAuthGate } from '@umituz/react-native-subscription';
|
|
9
|
-
```
|
|
7
|
+
**Import Path**: `@umituz/react-native-subscription`
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
**File**: `src/presentation/hooks/useAuthGate.ts`
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
function useAuthGate(config?: {
|
|
15
|
-
requireAuth?: boolean;
|
|
16
|
-
requireSubscription?: boolean;
|
|
17
|
-
}): {
|
|
18
|
-
isAuthenticated: boolean;
|
|
19
|
-
isAuthorized: boolean;
|
|
20
|
-
user: User | null;
|
|
21
|
-
subscription: SubscriptionStatus | null;
|
|
22
|
-
signIn: () => void;
|
|
23
|
-
signOut: () => void;
|
|
24
|
-
isLoading: boolean;
|
|
25
|
-
}
|
|
26
|
-
```
|
|
11
|
+
**Type**: Hook
|
|
27
12
|
|
|
28
|
-
##
|
|
13
|
+
## Strategy
|
|
29
14
|
|
|
30
|
-
|
|
31
|
-
|-----------|------|---------|-------------|
|
|
32
|
-
| `requireAuth` | `boolean` | `false` | Require user to be logged in |
|
|
33
|
-
| `requireSubscription` | `boolean` | `false` | Require premium subscription |
|
|
15
|
+
### Auth Gate Flow
|
|
34
16
|
|
|
35
|
-
|
|
17
|
+
1. **Authentication Check**: Verify if user is authenticated
|
|
18
|
+
2. **Subscription Check**: Verify if user has required subscription
|
|
19
|
+
3. **Authorization Evaluation**: Combine auth + subscription status
|
|
20
|
+
4. **Gate Actions**: Provide functions to gate features
|
|
21
|
+
5. **Sign In Flow**: Trigger authentication when required
|
|
22
|
+
6. **Upgrade Flow**: Trigger subscription when required
|
|
36
23
|
|
|
37
|
-
|
|
38
|
-
|----------|------|-------------|
|
|
39
|
-
| `isAuthenticated` | `boolean` | User is logged in |
|
|
40
|
-
| `isAuthorized` | `boolean` | User meets all requirements |
|
|
41
|
-
| `user` | `User \| null` | Current user object |
|
|
42
|
-
| `subscription` | `SubscriptionStatus \| null` | Subscription status |
|
|
43
|
-
| `signIn` | `() => void` | Trigger sign in |
|
|
44
|
-
| `signOut` | `() => void` | Trigger sign out |
|
|
45
|
-
| `isLoading` | `boolean` | Loading state |
|
|
24
|
+
### Integration Points
|
|
46
25
|
|
|
47
|
-
|
|
26
|
+
- **Auth Context**: User authentication state
|
|
27
|
+
- **Subscription Repository**: `src/infrastructure/repositories/SubscriptionRepository.ts`
|
|
28
|
+
- **Paywall Domain**: For subscription upgrade flow
|
|
29
|
+
- **Auth UI**: For sign-in/sign-up flows
|
|
48
30
|
|
|
49
|
-
|
|
50
|
-
function ProtectedFeature() {
|
|
51
|
-
const { isAuthorized, signIn, isLoading } = useAuthGate({
|
|
52
|
-
requireAuth: true,
|
|
53
|
-
requireSubscription: true,
|
|
54
|
-
});
|
|
31
|
+
## Restrictions
|
|
55
32
|
|
|
56
|
-
|
|
33
|
+
### REQUIRED
|
|
57
34
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<Text>This feature requires Premium</Text>
|
|
62
|
-
<Button onPress={signIn} title="Sign In / Subscribe" />
|
|
63
|
-
</View>
|
|
64
|
-
);
|
|
65
|
-
}
|
|
35
|
+
- **Loading State**: MUST handle loading state
|
|
36
|
+
- **Authorization Check**: MUST verify isAuthorized before showing protected content
|
|
37
|
+
- **Callback Implementation**: MUST implement onAuthRequired/onSubscriptionRequired callbacks
|
|
66
38
|
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
```
|
|
39
|
+
### PROHIBITED
|
|
70
40
|
|
|
71
|
-
|
|
41
|
+
- **NEVER** show protected content without checking isAuthorized
|
|
42
|
+
- **NEVER** use for security decisions without server validation
|
|
43
|
+
- **DO NOT** assume user is authenticated or subscribed
|
|
72
44
|
|
|
73
|
-
###
|
|
45
|
+
### CRITICAL SAFETY
|
|
74
46
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
requireSubscription: false,
|
|
80
|
-
});
|
|
47
|
+
- **ALWAYS** check isAuthorized before showing protected features
|
|
48
|
+
- **NEVER** trust client-side state for security
|
|
49
|
+
- **MUST** implement proper auth flow
|
|
50
|
+
- **ALWAYS** handle all states (loading, authorized, unauthorized)
|
|
81
51
|
|
|
82
|
-
|
|
83
|
-
return (
|
|
84
|
-
<View>
|
|
85
|
-
<Text>Please sign in to continue</Text>
|
|
86
|
-
<Button onPress={signIn} title="Sign In" />
|
|
87
|
-
</View>
|
|
88
|
-
);
|
|
89
|
-
}
|
|
52
|
+
## AI Agent Guidelines
|
|
90
53
|
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
```
|
|
54
|
+
### When Implementing Auth Gates
|
|
94
55
|
|
|
95
|
-
|
|
56
|
+
1. **Always** check loading state first
|
|
57
|
+
2. **Always** verify isAuthorized before showing content
|
|
58
|
+
3. **Always** provide sign-in option for unauthenticated users
|
|
59
|
+
4. **Always** provide upgrade option for non-subscribed users
|
|
60
|
+
5. **Never** bypass auth checks for convenience
|
|
96
61
|
|
|
97
|
-
|
|
98
|
-
function SubscriptionRequiredComponent() {
|
|
99
|
-
const { isAuthorized, user, subscription } = useAuthGate({
|
|
100
|
-
requireAuth: false, // Auto-handles auth internally
|
|
101
|
-
requireSubscription: true,
|
|
102
|
-
});
|
|
62
|
+
### Integration Checklist
|
|
103
63
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
64
|
+
- [ ] Import from correct path: `@umituz/react-native-subscription`
|
|
65
|
+
- [ ] Configure requireAuth and requireSubscription
|
|
66
|
+
- [ ] Handle loading state
|
|
67
|
+
- [ ] Check isAuthorized before showing content
|
|
68
|
+
- [ ] Implement sign-in callback
|
|
69
|
+
- [ ] Implement subscription upgrade callback
|
|
70
|
+
- [ ] Test with unauthenticated user
|
|
71
|
+
- [ ] Test with authenticated non-subscribed user
|
|
72
|
+
- [ ] Test with authenticated subscribed user
|
|
73
|
+
- [ ] Test loading states
|
|
115
74
|
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
```
|
|
75
|
+
### Common Patterns
|
|
119
76
|
|
|
120
|
-
|
|
77
|
+
1. **Auth Only**: Require authentication only
|
|
78
|
+
2. **Subscription Only**: Require subscription only (auth handled internally)
|
|
79
|
+
3. **Both**: Require both auth and subscription
|
|
80
|
+
4. **Conditional Gates**: Different requirements per feature
|
|
81
|
+
5. **Nested Gates**: Layer multiple gate conditions
|
|
121
82
|
|
|
122
|
-
|
|
123
|
-
function FullyProtectedFeature() {
|
|
124
|
-
const {
|
|
125
|
-
isAuthorized,
|
|
126
|
-
user,
|
|
127
|
-
subscription,
|
|
128
|
-
signIn,
|
|
129
|
-
isLoading
|
|
130
|
-
} = useAuthGate({
|
|
131
|
-
requireAuth: true,
|
|
132
|
-
requireSubscription: true,
|
|
133
|
-
});
|
|
83
|
+
## Related Documentation
|
|
134
84
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (!subscription?.isPremium) {
|
|
143
|
-
return <UpgradePrompt onUpgrade={() => navigation.navigate('Paywall')} />;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return <PremiumContent />;
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
## Advanced Usage
|
|
152
|
-
|
|
153
|
-
### Progressive Gating
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
function ProgressiveAccess() {
|
|
157
|
-
const { isAuthorized, user, subscription } = useAuthGate({
|
|
158
|
-
requireAuth: true,
|
|
159
|
-
requireSubscription: true,
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// Determine access level
|
|
163
|
-
const accessLevel = !user
|
|
164
|
-
? 'public'
|
|
165
|
-
: !subscription?.isPremium
|
|
166
|
-
? 'authenticated'
|
|
167
|
-
: 'premium';
|
|
168
|
-
|
|
169
|
-
const features = {
|
|
170
|
-
public: ['Basic Browse'],
|
|
171
|
-
authenticated: ['Save Favorites', 'View History'],
|
|
172
|
-
premium: ['Advanced Filters', 'AI Features', 'Priority Support'],
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
return (
|
|
176
|
-
<FeatureList
|
|
177
|
-
availableFeatures={features[accessLevel]}
|
|
178
|
-
onFeatureLocked={(feature) => showUpgradePrompt(feature, accessLevel)}
|
|
179
|
-
/>
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### With Graceful Degradation
|
|
185
|
-
|
|
186
|
-
```typescript
|
|
187
|
-
function GracefulDegradationComponent() {
|
|
188
|
-
const { isAuthorized, user, subscription } = useAuthGate({
|
|
189
|
-
requireAuth: true,
|
|
190
|
-
requireSubscription: true,
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
if (!isAuthorized) {
|
|
194
|
-
// Show limited version with upgrade prompt
|
|
195
|
-
return (
|
|
196
|
-
<View>
|
|
197
|
-
<FeatureFreeVersion />
|
|
198
|
-
|
|
199
|
-
<View style={styles.upgradeBanner}>
|
|
200
|
-
<Text>Upgrade to unlock all features</Text>
|
|
201
|
-
<Button onPress={() => user ? showPaywall() : signIn()} />
|
|
202
|
-
</View>
|
|
203
|
-
</View>
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return <FullVersion />;
|
|
208
|
-
}
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
### With Custom Auth Flow
|
|
212
|
-
|
|
213
|
-
```typescript
|
|
214
|
-
function CustomAuthFlow() {
|
|
215
|
-
const { isAuthorized, signIn } = useAuthGate({
|
|
216
|
-
requireAuth: true,
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
const handleSignIn = () => {
|
|
220
|
-
// Navigate to custom auth flow
|
|
221
|
-
navigation.navigate('CustomAuth', {
|
|
222
|
-
onSuccess: () => {
|
|
223
|
-
// Auth success, callback will trigger re-render
|
|
224
|
-
},
|
|
225
|
-
});
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
if (!isAuthorized) {
|
|
229
|
-
return (
|
|
230
|
-
<View>
|
|
231
|
-
<Text>Sign in to access this feature</Text>
|
|
232
|
-
<Button onPress={handleSignIn} title="Sign In" />
|
|
233
|
-
</View>
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return <ProtectedContent />;
|
|
238
|
-
}
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
## Integration Examples
|
|
242
|
-
|
|
243
|
-
### Navigation Guard
|
|
244
|
-
|
|
245
|
-
```typescript
|
|
246
|
-
function ProtectedScreen() {
|
|
247
|
-
const { isAuthorized, signIn } = useAuthGate({
|
|
248
|
-
requireAuth: true,
|
|
249
|
-
requireSubscription: true,
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
useEffect(() => {
|
|
253
|
-
if (!isAuthorized) {
|
|
254
|
-
// Replace navigation instead of just showing UI
|
|
255
|
-
navigation.replace('AuthGate', {
|
|
256
|
-
requireAuth: true,
|
|
257
|
-
requireSubscription: true,
|
|
258
|
-
returnTo: 'ProtectedScreen',
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
}, [isAuthorized]);
|
|
262
|
-
|
|
263
|
-
if (!isAuthorized) return null;
|
|
264
|
-
|
|
265
|
-
return <ScreenContent />;
|
|
266
|
-
}
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
### Settings Screen
|
|
270
|
-
|
|
271
|
-
```typescript
|
|
272
|
-
function SettingsScreen() {
|
|
273
|
-
const { user, subscription, signIn, signOut } = useAuthGate({
|
|
274
|
-
requireAuth: true,
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
return (
|
|
278
|
-
<ScrollView>
|
|
279
|
-
<Section title="Account">
|
|
280
|
-
<InfoRow label="Email" value={user?.email} />
|
|
281
|
-
<InfoRow
|
|
282
|
-
label="Subscription"
|
|
283
|
-
value={subscription?.type || 'Free'}
|
|
284
|
-
/>
|
|
285
|
-
</Section>
|
|
286
|
-
|
|
287
|
-
<Section title="Actions">
|
|
288
|
-
<Button
|
|
289
|
-
onPress={signIn}
|
|
290
|
-
title="Sign In"
|
|
291
|
-
/>
|
|
292
|
-
<Button
|
|
293
|
-
onPress={signOut}
|
|
294
|
-
title="Sign Out"
|
|
295
|
-
/>
|
|
296
|
-
</Section>
|
|
297
|
-
</ScrollView>
|
|
298
|
-
);
|
|
299
|
-
}
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
### Content Based on Access Level
|
|
303
|
-
|
|
304
|
-
```typescript
|
|
305
|
-
function DynamicContent() {
|
|
306
|
-
const { isAuthorized, user, subscription } = useAuthGate({
|
|
307
|
-
requireAuth: true,
|
|
308
|
-
requireSubscription: false,
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
return (
|
|
312
|
-
<View>
|
|
313
|
-
{/* Always visible */}
|
|
314
|
-
<PublicContent />
|
|
315
|
-
|
|
316
|
-
{/* Authenticated users */}
|
|
317
|
-
{user && <AuthenticatedContent />}
|
|
318
|
-
|
|
319
|
-
{/* Premium users */}
|
|
320
|
-
{subscription?.isPremium && <PremiumContent />}
|
|
321
|
-
</View>
|
|
322
|
-
);
|
|
323
|
-
}
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
## Best Practices
|
|
327
|
-
|
|
328
|
-
1. **Check authorization first** - Before rendering content
|
|
329
|
-
2. **Provide clear messaging** - Tell users what's required
|
|
330
|
-
3. **Easy sign-in flow** - Make authentication simple
|
|
331
|
-
4. **Show upgrade path** - Guide users to subscription
|
|
332
|
-
5. **Handle loading** - Show loading states appropriately
|
|
333
|
-
6. **Cache auth state** - Avoid unnecessary re-authentication
|
|
334
|
-
7. **Sign out cleanup** - Clear sensitive data on sign out
|
|
335
|
-
|
|
336
|
-
## Testing
|
|
337
|
-
|
|
338
|
-
```typescript
|
|
339
|
-
describe('useAuthGate', () => {
|
|
340
|
-
it('should authorize authenticated user', () => {
|
|
341
|
-
const { result } = renderHook(() =>
|
|
342
|
-
useAuthGate({ requireAuth: true }),
|
|
343
|
-
{
|
|
344
|
-
wrapper: ({ children }) => (
|
|
345
|
-
<AuthProvider value={{ user: { uid: '123' }}}>
|
|
346
|
-
{children}
|
|
347
|
-
</AuthProvider>
|
|
348
|
-
),
|
|
349
|
-
}
|
|
350
|
-
);
|
|
351
|
-
|
|
352
|
-
expect(result.current.isAuthorized).toBe(true);
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
it('should not authorize unauthenticated user', () => {
|
|
356
|
-
const { result } = renderHook(() =>
|
|
357
|
-
useAuthGate({ requireAuth: true }),
|
|
358
|
-
{
|
|
359
|
-
wrapper: ({ children }) => (
|
|
360
|
-
<AuthProvider value={{ user: null }}>
|
|
361
|
-
{children}
|
|
362
|
-
</AuthProvider>
|
|
363
|
-
),
|
|
364
|
-
}
|
|
365
|
-
);
|
|
366
|
-
|
|
367
|
-
expect(result.current.isAuthorized).toBe(false);
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
it('should authorize premium user', () => {
|
|
371
|
-
const { result } = renderHook(() =>
|
|
372
|
-
useAuthGate({ requireSubscription: true }),
|
|
373
|
-
{
|
|
374
|
-
wrapper: ({ children }) => (
|
|
375
|
-
<AuthProvider
|
|
376
|
-
value={{
|
|
377
|
-
user: { uid: '123' },
|
|
378
|
-
subscription: { type: 'premium', isActive: true },
|
|
379
|
-
}}
|
|
380
|
-
>
|
|
381
|
-
{children}
|
|
382
|
-
</AuthProvider>
|
|
383
|
-
),
|
|
384
|
-
}
|
|
385
|
-
);
|
|
386
|
-
|
|
387
|
-
expect(result.current.isAuthorized).toBe(true);
|
|
388
|
-
});
|
|
389
|
-
});
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
## Related Hooks
|
|
393
|
-
|
|
394
|
-
- **useAuth** - Authentication only
|
|
395
|
-
- **usePremium** - Premium check only
|
|
396
|
-
- **useSubscriptionGate** - Subscription gating
|
|
397
|
-
- **useUserTier** - Tier information
|
|
398
|
-
|
|
399
|
-
## See Also
|
|
400
|
-
|
|
401
|
-
- [Auth Integration](../../hooks/useAuthSubscriptionSync.md)
|
|
402
|
-
- [usePremium](./usePremium.md)
|
|
403
|
-
- [useUserTier](./useUserTier.md)
|
|
85
|
+
- **useAuth**: Authentication state
|
|
86
|
+
- **usePremiumGate**: Premium-only gating
|
|
87
|
+
- **useSubscriptionGate**: Subscription-only gating
|
|
88
|
+
- **useFeatureGate**: Unified feature gating
|
|
89
|
+
- **Auth Domain**: `src/domains/config/README.md`
|