Skip to content

Commit 9d5aa4c

Browse files
committed
feat(*): Align styling and button tests
1 parent bcf07ba commit 9d5aa4c

21 files changed

+1056
-121
lines changed

examples/react/src/firebase/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ export const firebaseConfig = {
2020
projectId: "fir-ui-rework",
2121
storageBucket: "fir-ui-rework.firebasestorage.app",
2222
messagingSenderId: "200312857118",
23-
appId: "1:200312857118:web:94e3f69b0e0a4a863f040f"
23+
appId: "1:200312857118:web:94e3f69b0e0a4a863f040f",
2424
};

examples/react/src/screens/oauth-screen.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,25 @@
1616

1717
"use client";
1818

19-
import { GoogleSignInButton, OAuthScreen } from "@firebase-ui/react";
19+
import {
20+
FacebookSignInButton,
21+
AppleSignInButton,
22+
GitHubSignInButton,
23+
GoogleSignInButton,
24+
MicrosoftSignInButton,
25+
OAuthScreen,
26+
TwitterSignInButton,
27+
} from "@firebase-ui/react";
2028

2129
export default function OAuthScreenPage() {
2230
return (
2331
<OAuthScreen>
24-
<GoogleSignInButton />
32+
<GoogleSignInButton themed="neutral" />
33+
<FacebookSignInButton themed />
34+
<AppleSignInButton themed />
35+
<GitHubSignInButton themed />
36+
<MicrosoftSignInButton themed />
37+
<TwitterSignInButton themed />
2538
</OAuthScreen>
2639
);
2740
}

examples/react/src/screens/sign-in-auth-screen-w-oauth.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
"use client";
1818

19-
import { OAuthButton } from "@firebase-ui/react";
2019
import {
2120
AppleSignInButton,
2221
GoogleSignInButton,
@@ -26,14 +25,11 @@ import {
2625
MicrosoftSignInButton,
2726
TwitterSignInButton,
2827
} from "@firebase-ui/react";
29-
import { OAuthProvider } from "firebase/auth";
3028
import { useNavigate } from "react-router";
3129

3230
export default function SignInAuthScreenWithOAuthPage() {
3331
const navigate = useNavigate();
3432

35-
const p = new OAuthProvider('oidc.foobar')
36-
3733
return (
3834
<SignInAuthScreen
3935
onForgotPasswordClick={() => navigate("/password-reset-screen")}

packages/react/src/auth/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ export { AppleSignInButton, AppleLogo, type AppleSignInButtonProps } from "./oau
5757
export { FacebookSignInButton, FacebookLogo, type FacebookSignInButtonProps } from "./oauth/facebook-sign-in-button";
5858
export { GitHubSignInButton, GitHubLogo, type GitHubSignInButtonProps } from "./oauth/github-sign-in-button";
5959
export { GoogleSignInButton, GoogleLogo, type GoogleSignInButtonProps } from "./oauth/google-sign-in-button";
60-
export { MicrosoftSignInButton, MicrosoftLogo, type MicrosoftSignInButtonProps } from "./oauth/microsoft-sign-in-button";
60+
export {
61+
MicrosoftSignInButton,
62+
MicrosoftLogo,
63+
type MicrosoftSignInButtonProps,
64+
} from "./oauth/microsoft-sign-in-button";
6165
export { TwitterSignInButton, TwitterLogo, type TwitterSignInButtonProps } from "./oauth/twitter-sign-in-button";
6266
export { OAuthButton, type OAuthButtonProps } from "./oauth/oauth-button";
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/**
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
import { describe, it, expect, vi, afterEach, beforeEach } from "vitest";
17+
import { render, screen, cleanup } from "@testing-library/react";
18+
import { AppleLogo, AppleSignInButton } from "./apple-sign-in-button";
19+
import { CreateFirebaseUIProvider, createMockUI } from "~/tests/utils";
20+
import { registerLocale } from "@firebase-ui/translations";
21+
import { OAuthProvider } from "firebase/auth";
22+
23+
vi.mock("firebase/auth", () => ({
24+
OAuthProvider: class OAuthProvider {
25+
constructor(providerId: string) {
26+
this.providerId = providerId;
27+
}
28+
providerId: string;
29+
},
30+
}));
31+
32+
afterEach(() => {
33+
cleanup();
34+
});
35+
36+
describe("<AppleSignInButton />", () => {
37+
beforeEach(() => {
38+
vi.clearAllMocks();
39+
});
40+
41+
it("renders with the correct provider", () => {
42+
const ui = createMockUI({
43+
locale: registerLocale("test", {
44+
labels: {
45+
signInWithApple: "Sign in with Apple",
46+
},
47+
}),
48+
});
49+
50+
render(
51+
<CreateFirebaseUIProvider ui={ui}>
52+
<AppleSignInButton />
53+
</CreateFirebaseUIProvider>
54+
);
55+
56+
const button = screen.getByRole("button");
57+
expect(button).toBeDefined();
58+
expect(button.getAttribute("data-provider")).toBe("apple.com");
59+
});
60+
61+
it("renders with custom provider when provided", () => {
62+
const ui = createMockUI({
63+
locale: registerLocale("test", {
64+
labels: {
65+
signInWithApple: "Sign in with Apple",
66+
},
67+
}),
68+
});
69+
70+
const customProvider = new OAuthProvider("custom.apple.com");
71+
72+
render(
73+
<CreateFirebaseUIProvider ui={ui}>
74+
<AppleSignInButton provider={customProvider} />
75+
</CreateFirebaseUIProvider>
76+
);
77+
78+
const button = screen.getByRole("button");
79+
expect(button).toBeDefined();
80+
expect(button.getAttribute("data-provider")).toBe("custom.apple.com");
81+
});
82+
83+
it("renders with the Apple icon", () => {
84+
const ui = createMockUI({
85+
locale: registerLocale("test", {
86+
labels: {
87+
signInWithApple: "Sign in with Apple",
88+
},
89+
}),
90+
});
91+
92+
render(
93+
<CreateFirebaseUIProvider ui={ui}>
94+
<AppleSignInButton />
95+
</CreateFirebaseUIProvider>
96+
);
97+
98+
const svg = document.querySelector(".fui-provider__icon");
99+
expect(svg).toBeDefined();
100+
expect(svg).toHaveClass("fui-provider__icon");
101+
expect(svg?.tagName.toLowerCase()).toBe("svg");
102+
});
103+
104+
it("renders with the correct translated text", () => {
105+
const ui = createMockUI({
106+
locale: registerLocale("test", {
107+
labels: {
108+
signInWithApple: "Sign in with Apple",
109+
},
110+
}),
111+
});
112+
113+
render(
114+
<CreateFirebaseUIProvider ui={ui}>
115+
<AppleSignInButton />
116+
</CreateFirebaseUIProvider>
117+
);
118+
119+
expect(screen.getByText("Sign in with Apple")).toBeDefined();
120+
});
121+
122+
it("renders with different translated text for different locales", () => {
123+
const ui = createMockUI({
124+
locale: registerLocale("test", {
125+
labels: {
126+
signInWithApple: "Iniciar sesión con Apple",
127+
},
128+
}),
129+
});
130+
131+
render(
132+
<CreateFirebaseUIProvider ui={ui}>
133+
<AppleSignInButton />
134+
</CreateFirebaseUIProvider>
135+
);
136+
137+
expect(screen.getByText("Iniciar sesión con Apple")).toBeDefined();
138+
});
139+
140+
it("renders as a button with correct classes", () => {
141+
const ui = createMockUI({
142+
locale: registerLocale("test", {
143+
labels: {
144+
signInWithApple: "Sign in with Apple",
145+
},
146+
}),
147+
});
148+
149+
render(
150+
<CreateFirebaseUIProvider ui={ui}>
151+
<AppleSignInButton />
152+
</CreateFirebaseUIProvider>
153+
);
154+
155+
const button = screen.getByRole("button");
156+
expect(button).toHaveClass("fui-provider__button");
157+
expect(button.getAttribute("type")).toBe("button");
158+
});
159+
});
160+
161+
describe("<AppleLogo />", () => {
162+
it("renders as an SVG element", () => {
163+
const { container } = render(<AppleLogo />);
164+
const svg = container.querySelector("svg");
165+
166+
expect(svg).toBeDefined();
167+
expect(svg?.tagName.toLowerCase()).toBe("svg");
168+
});
169+
170+
it("has the correct CSS class", () => {
171+
const { container } = render(<AppleLogo />);
172+
const svg = container.querySelector("svg");
173+
174+
expect(svg).toHaveClass("fui-provider__icon");
175+
});
176+
177+
it("forwards custom SVG props", () => {
178+
const { container } = render(<AppleLogo data-testid="custom-svg" className="foo" width={32} />);
179+
const svg = container.querySelector('svg[data-testid="custom-svg"]');
180+
181+
expect(svg).toBeDefined();
182+
expect(svg!.getAttribute("width")).toBe("32");
183+
expect(svg).toHaveClass("fui-provider__icon");
184+
expect(svg).toHaveClass("foo");
185+
});
186+
});

packages/react/src/auth/oauth/apple-sign-in-button.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { OAuthProvider } from "firebase/auth";
2121
import { useUI } from "~/hooks";
2222
import { OAuthButton } from "./oauth-button";
2323
import AppleSvgLogo from "~/components/logos/apple/Logo";
24+
import { cn } from "~/utils/cn";
2425

2526
export type AppleSignInButtonProps = {
2627
provider?: OAuthProvider;
@@ -38,6 +39,6 @@ export function AppleSignInButton({ provider, themed }: AppleSignInButtonProps)
3839
);
3940
}
4041

41-
export function AppleLogo() {
42-
return <AppleSvgLogo className="fui-provider__icon" />;
42+
export function AppleLogo({ className, ...props }: React.SVGProps<SVGSVGElement>) {
43+
return <AppleSvgLogo className={cn("fui-provider__icon", className)} {...props} />;
4344
}

0 commit comments

Comments
 (0)