Skip to content

Commit 68e3df8

Browse files
committed
refactor(core): Remove state managament from behaviors
1 parent 5db38b0 commit 68e3df8

File tree

7 files changed

+29
-52
lines changed

7 files changed

+29
-52
lines changed

packages/core/src/auth.test.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ describe("signInWithEmailAndPassword", () => {
112112
expect(mockBehavior).toHaveBeenCalledWith(mockUI, credential);
113113
expect(result.providerId).toBe("password");
114114

115-
// Only the `finally` block is called here.
116-
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["idle"]]);
115+
// Auth method sets pending at start, then idle in finally block.
116+
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["pending"], ["idle"]]);
117117
});
118118

119119
it("should call the autoUpgradeAnonymousCredential behavior if enabled and handle no result from the behavior", async () => {
@@ -205,8 +205,8 @@ describe("createUserWithEmailAndPassword", () => {
205205
expect(mockBehavior).toHaveBeenCalledWith(mockUI, credential);
206206
expect(result.providerId).toBe("password");
207207

208-
// Only the `finally` block is called here.
209-
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["idle"]]);
208+
// Auth method sets pending at start, then idle in finally block.
209+
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["pending"], ["idle"]]);
210210
});
211211

212212
it("should call the autoUpgradeAnonymousCredential behavior if enabled and handle no result from the behavior", async () => {
@@ -368,8 +368,8 @@ describe("confirmPhoneNumber", () => {
368368
expect(mockBehavior).toHaveBeenCalledWith(mockUI, credential);
369369
expect(result.providerId).toBe("phone");
370370

371-
// Only the `finally` block is called here.
372-
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["idle"]]);
371+
// Auth method sets pending at start, then idle in finally block.
372+
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["pending"], ["idle"]]);
373373
});
374374

375375
it("should not call behavior when user is not anonymous", async () => {
@@ -641,8 +641,8 @@ describe("signInWithEmailLink", () => {
641641
expect(mockBehavior).toHaveBeenCalledWith(mockUI, credential);
642642
expect(result.providerId).toBe("emailLink");
643643

644-
// Only the `finally` block is called here.
645-
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["idle"]]);
644+
// Auth method sets pending at start, then idle in finally block.
645+
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["pending"], ["idle"]]);
646646
});
647647

648648
it("should call the autoUpgradeAnonymousCredential behavior if enabled and handle no result from the behavior", async () => {
@@ -739,8 +739,8 @@ describe("signInWithCredential", () => {
739739
expect(mockBehavior).toHaveBeenCalledWith(mockUI, credential);
740740
expect(result.providerId).toBe("password");
741741

742-
// Only the `finally` block is called here.
743-
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["idle"]]);
742+
// Auth method sets pending at start, then idle in finally block.
743+
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["pending"], ["idle"]]);
744744
});
745745

746746
it("should call the autoUpgradeAnonymousCredential behavior if enabled and handle no result from the behavior", async () => {
@@ -794,7 +794,7 @@ describe("signInWithCredential", () => {
794794

795795
expect(handleFirebaseError).toHaveBeenCalledWith(mockUI, error);
796796

797-
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["idle"]]);
797+
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["pending"], ["idle"]]);
798798

799799
expect(_signInWithCredential).not.toHaveBeenCalled();
800800
});
@@ -921,6 +921,6 @@ describe("signInWithProvider", () => {
921921
await signInWithProvider(mockUI, provider);
922922

923923
expect(handleFirebaseError).toHaveBeenCalledWith(mockUI, error);
924-
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["idle"]]);
924+
expect(vi.mocked(mockUI.setState).mock.calls).toEqual([["pending"], ["idle"]]);
925925
});
926926
});

packages/core/src/auth.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,13 @@ import { FirebaseUIConfiguration } from "./config";
3636
import { handleFirebaseError } from "./errors";
3737
import { hasBehavior, getBehavior } from "./behaviors/index";
3838

39-
async function handlePendingCredential(ui: FirebaseUIConfiguration, user: UserCredential): Promise<UserCredential> {
39+
async function handlePendingCredential(_ui: FirebaseUIConfiguration, user: UserCredential): Promise<UserCredential> {
4040
const pendingCredString = window.sessionStorage.getItem("pendingCred");
4141
if (!pendingCredString) return user;
4242

4343
try {
4444
const pendingCred = JSON.parse(pendingCredString);
45-
ui.setState("pending");
4645
const result = await linkWithCredential(user.user, pendingCred);
47-
ui.setState("idle");
4846
window.sessionStorage.removeItem("pendingCred");
4947
return result;
5048
} catch {
@@ -59,6 +57,7 @@ export async function signInWithEmailAndPassword(
5957
password: string
6058
): Promise<UserCredential> {
6159
try {
60+
ui.setState("pending");
6261
const credential = EmailAuthProvider.credential(email, password);
6362

6463
if (hasBehavior(ui, "autoUpgradeAnonymousCredential")) {
@@ -69,7 +68,6 @@ export async function signInWithEmailAndPassword(
6968
}
7069
}
7170

72-
ui.setState("pending");
7371
const result = await _signInWithCredential(ui.auth, credential);
7472
return handlePendingCredential(ui, result);
7573
} catch (error) {
@@ -85,6 +83,7 @@ export async function createUserWithEmailAndPassword(
8583
password: string
8684
): Promise<UserCredential> {
8785
try {
86+
ui.setState("pending");
8887
const credential = EmailAuthProvider.credential(email, password);
8988

9089
if (hasBehavior(ui, "autoUpgradeAnonymousCredential")) {
@@ -95,7 +94,6 @@ export async function createUserWithEmailAndPassword(
9594
}
9695
}
9796

98-
ui.setState("pending");
9997
const result = await _createUserWithEmailAndPassword(ui.auth, email, password);
10098
return handlePendingCredential(ui, result);
10199
} catch (error) {
@@ -126,6 +124,7 @@ export async function confirmPhoneNumber(
126124
verificationCode: string
127125
): Promise<UserCredential> {
128126
try {
127+
ui.setState("pending");
129128
const currentUser = ui.auth.currentUser;
130129
const credential = PhoneAuthProvider.credential(confirmationResult.verificationId, verificationCode);
131130

@@ -137,7 +136,6 @@ export async function confirmPhoneNumber(
137136
}
138137
}
139138

140-
ui.setState("pending");
141139
const result = await _signInWithCredential(ui.auth, credential);
142140
return handlePendingCredential(ui, result);
143141
} catch (error) {
@@ -160,13 +158,13 @@ export async function sendPasswordResetEmail(ui: FirebaseUIConfiguration, email:
160158

161159
export async function sendSignInLinkToEmail(ui: FirebaseUIConfiguration, email: string): Promise<void> {
162160
try {
161+
ui.setState("pending");
163162
const actionCodeSettings = {
164163
url: window.location.href,
165164
// TODO(ehesp): Check this...
166165
handleCodeInApp: true,
167166
} satisfies ActionCodeSettings;
168167

169-
ui.setState("pending");
170168
await _sendSignInLinkToEmail(ui.auth, email, actionCodeSettings);
171169
// TODO: Should this be a behavior ("storageStrategy")?
172170
window.localStorage.setItem("emailForSignIn", email);
@@ -191,6 +189,7 @@ export async function signInWithCredential(
191189
credential: AuthCredential
192190
): Promise<UserCredential> {
193191
try {
192+
ui.setState("pending");
194193
if (hasBehavior(ui, "autoUpgradeAnonymousCredential")) {
195194
const userCredential = await getBehavior(ui, "autoUpgradeAnonymousCredential")(ui, credential);
196195

@@ -201,7 +200,6 @@ export async function signInWithCredential(
201200
}
202201
}
203202

204-
ui.setState("pending");
205203
const result = await _signInWithCredential(ui.auth, credential);
206204
return handlePendingCredential(ui, result);
207205
} catch (error) {
@@ -228,6 +226,7 @@ export async function signInWithProvider(
228226
provider: AuthProvider
229227
): Promise<UserCredential | never> {
230228
try {
229+
ui.setState("pending");
231230
if (hasBehavior(ui, "autoUpgradeAnonymousProvider")) {
232231
const credential = await getBehavior(ui, "autoUpgradeAnonymousProvider")(ui, provider);
233232

@@ -265,7 +264,6 @@ export async function completeEmailLinkSignIn(
265264

266265
ui.setState("pending");
267266
const result = await signInWithEmailLink(ui, email, currentUrl);
268-
ui.setState("idle"); // TODO(ehesp): Do we need this here?
269267
return handlePendingCredential(ui, result);
270268
} catch (error) {
271269
handleFirebaseError(ui, error);

packages/core/src/behaviors/anonymous-upgrade.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ describe("autoUpgradeAnonymousCredentialHandler", () => {
4343
const result = await autoUpgradeAnonymousCredentialHandler(mockUI, mockCredential);
4444

4545
expect(linkWithCredential).toHaveBeenCalledWith(mockUser, mockCredential);
46-
expect(mockUI.setState).toHaveBeenCalledWith("pending");
47-
expect(mockUI.setState).toHaveBeenCalledWith("idle");
4846
expect(result).toBe(mockResult);
4947
});
5048

packages/core/src/behaviors/anonymous-upgrade.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,12 @@ export const autoUpgradeAnonymousCredentialHandler = async (
2121

2222
const oldUserId = currentUser.uid;
2323

24-
ui.setState("pending");
2524
const result = await linkWithCredential(currentUser, credential);
2625

2726
if (onUpgrade) {
2827
await onUpgrade(ui, oldUserId, result);
2928
}
3029

31-
ui.setState("idle");
3230
return result;
3331
};
3432

packages/core/src/behaviors/auto-anonymous-login.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { InitHandler } from "./utils";
33

44
export const autoAnonymousLoginHandler: InitHandler = async (ui) => {
55
const auth = ui.auth;
6+
67
if (!auth.currentUser) {
78
await signInAnonymously(auth);
89
}

packages/core/src/behaviors/provider-strategy.test.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,12 @@ describe("signInWithRediectHandler", () => {
3838

3939
await signInWithRediectHandler(mockUI, mockProvider);
4040

41-
expect(mockUI.setState).toHaveBeenCalledWith("pending");
4241
expect(signInWithRedirect).toHaveBeenCalledWith(mockAuth, mockProvider);
4342
});
4443
});
4544

4645
describe("signInWithPopupHandler", () => {
47-
it("should set state to pending, call signInWithPopup, set state to idle, and return result", async () => {
46+
it("should call signInWithPopup and return result", async () => {
4847
const mockAuth = {} as Auth;
4948
const mockUI = createMockUI({ auth: mockAuth });
5049
const mockProvider = { providerId: "google.com" } as AuthProvider;
@@ -54,13 +53,11 @@ describe("signInWithPopupHandler", () => {
5453

5554
const result = await signInWithPopupHandler(mockUI, mockProvider);
5655

57-
expect(mockUI.setState).toHaveBeenCalledWith("pending");
5856
expect(signInWithPopup).toHaveBeenCalledWith(mockAuth, mockProvider);
59-
expect(mockUI.setState).toHaveBeenCalledWith("idle");
6057
expect(result).toBe(mockResult);
6158
});
6259

63-
it("should not set state to idle when signInWithPopup fails", async () => {
60+
it("should throw error when signInWithPopup fails", async () => {
6461
const mockAuth = {} as Auth;
6562
const mockUI = createMockUI({ auth: mockAuth });
6663
const mockProvider = { providerId: "google.com" } as AuthProvider;
@@ -69,13 +66,11 @@ describe("signInWithPopupHandler", () => {
6966
vi.mocked(signInWithPopup).mockRejectedValue(mockError);
7067

7168
await expect(signInWithPopupHandler(mockUI, mockProvider)).rejects.toThrow("Popup sign in failed");
72-
expect(mockUI.setState).toHaveBeenCalledWith("pending");
73-
expect(mockUI.setState).not.toHaveBeenCalledWith("idle");
7469
});
7570
});
7671

7772
describe("linkWithRedirectHandler", () => {
78-
it("should set state to pending and call linkWithRedirect", async () => {
73+
it("should call linkWithRedirect", async () => {
7974
const mockAuth = {} as Auth;
8075
const mockUI = createMockUI({ auth: mockAuth });
8176
const mockUser = { uid: "test-user" } as User;
@@ -85,13 +80,12 @@ describe("linkWithRedirectHandler", () => {
8580

8681
await linkWithRedirectHandler(mockUI, mockUser, mockProvider);
8782

88-
expect(mockUI.setState).toHaveBeenCalledWith("pending");
8983
expect(linkWithRedirect).toHaveBeenCalledWith(mockUser, mockProvider);
9084
});
9185
});
9286

9387
describe("linkWithPopupHandler", () => {
94-
it("should set state to pending, call linkWithPopup, set state to idle, and return result", async () => {
88+
it("should call linkWithPopup and return result", async () => {
9589
const mockAuth = {} as Auth;
9690
const mockUI = createMockUI({ auth: mockAuth });
9791
const mockUser = { uid: "test-user" } as User;
@@ -102,13 +96,11 @@ describe("linkWithPopupHandler", () => {
10296

10397
const result = await linkWithPopupHandler(mockUI, mockUser, mockProvider);
10498

105-
expect(mockUI.setState).toHaveBeenCalledWith("pending");
10699
expect(linkWithPopup).toHaveBeenCalledWith(mockUser, mockProvider);
107-
expect(mockUI.setState).toHaveBeenCalledWith("idle");
108100
expect(result).toBe(mockResult);
109101
});
110102

111-
it("should not set state to idle when linkWithPopup fails", async () => {
103+
it("should throw error when linkWithPopup fails", async () => {
112104
const mockAuth = {} as Auth;
113105
const mockUI = createMockUI({ auth: mockAuth });
114106
const mockUser = { uid: "test-user" } as User;
@@ -118,7 +110,5 @@ describe("linkWithPopupHandler", () => {
118110
vi.mocked(linkWithPopup).mockRejectedValue(mockError);
119111

120112
await expect(linkWithPopupHandler(mockUI, mockUser, mockProvider)).rejects.toThrow("Popup link failed");
121-
expect(mockUI.setState).toHaveBeenCalledWith("pending");
122-
expect(mockUI.setState).not.toHaveBeenCalledWith("idle");
123113
});
124114
});

packages/core/src/behaviors/provider-strategy.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,17 @@ export type ProviderLinkStrategyHandler = (
2020
) => Promise<never | UserCredential>;
2121

2222
export const signInWithRediectHandler: ProviderSignInStrategyHandler = async (ui, provider) => {
23-
ui.setState("pending");
2423
return signInWithRedirect(ui.auth, provider);
2524
};
2625

2726
export const signInWithPopupHandler: ProviderSignInStrategyHandler = async (ui, provider) => {
28-
ui.setState("pending");
29-
const result = await signInWithPopup(ui.auth, provider);
30-
ui.setState("idle");
31-
return result;
27+
return signInWithPopup(ui.auth, provider);
3228
};
3329

34-
export const linkWithRedirectHandler: ProviderLinkStrategyHandler = async (ui, user, provider) => {
35-
ui.setState("pending");
30+
export const linkWithRedirectHandler: ProviderLinkStrategyHandler = async (_ui, user, provider) => {
3631
return linkWithRedirect(user, provider);
3732
};
3833

39-
export const linkWithPopupHandler: ProviderLinkStrategyHandler = async (ui, user, provider) => {
40-
ui.setState("pending");
41-
const result = await linkWithPopup(user, provider);
42-
ui.setState("idle");
43-
return result;
34+
export const linkWithPopupHandler: ProviderLinkStrategyHandler = async (_ui, user, provider) => {
35+
return linkWithPopup(user, provider);
4436
};

0 commit comments

Comments
 (0)