-
-
Notifications
You must be signed in to change notification settings - Fork 372
test(account-dialog): add unit tests and 100% coverage for AccountDialogComponent #2871
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,10 +2,12 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
| import { describe, expect, it } from '@jest/globals'; | ||
| import { NO_ERRORS_SCHEMA } from '@angular/core'; | ||
| import { TranslateModule } from '@ngx-translate/core'; | ||
| import { mount, NgxTestWrapper } from '../../../../../testing'; | ||
| import { mock, mount, NgxTestWrapper } from '../../../../../testing'; | ||
| import { SharedModule } from '../../modules/shared/shared.module'; | ||
|
|
||
| import { AccountDialogComponent } from './account-dialog.component'; | ||
| import { apiClient } from '../../services/api/api.service'; | ||
| import * as externalUtils from '../../utils'; | ||
|
|
||
| describe('AccountDialogComponent', () => { | ||
| let wrapper: NgxTestWrapper<AccountDialogComponent>; | ||
|
|
@@ -25,15 +27,78 @@ describe('AccountDialogComponent', () => { | |
| fixture.detectChanges(); | ||
| }); | ||
|
|
||
| beforeEach(() => jest.clearAllMocks()); | ||
|
|
||
|
Comment on lines
+30
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix duplicate test hook (Biome: noDuplicateTestHooks). Two beforeEach hooks in the same describe block violate the linter. Move mock clearing to an afterEach or merge it into the first beforeEach. Apply this diff: - beforeEach(() => jest.clearAllMocks());
+ afterEach(() => {
+ jest.clearAllMocks();
+ });Additionally, consider avoiding a second component instantiation. Use the wrapper’s instance instead of TestBed.createComponent to reduce flakiness: // replace:
fixture = TestBed.createComponent(AccountDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
// with:
component = wrapper.component.componentInstance;🧰 Tools🪛 Biome (2.1.2)[error] 30-30: Disallow duplicate setup and teardown hooks. Disallow beforeEach duplicacy inside the describe function. (lint/suspicious/noDuplicateTestHooks) 🤖 Prompt for AI Agents |
||
| it('should create', () => { | ||
| expect(wrapper.component.nativeElement).toMatchSnapshot(); | ||
| }); | ||
|
|
||
| it ('should have default showDialog as true', () => { | ||
| expect(component.showDialog).toBe(true); | ||
| }); | ||
|
|
||
| it('should have undefined account by default', () => { | ||
| expect(component.account).toBeUndefined(); | ||
| }); | ||
|
|
||
| it('should emit "handleLoginChange" when login is clicked', () => { | ||
| const login = wrapper.find('.btn--primary'); | ||
|
|
||
| login.emit('click'); | ||
|
|
||
| expect(wrapper.emitted('handleLoginChange')).toBeTruthy(); | ||
| }); | ||
|
|
||
| it('should emit handleLoginChange on submitLogin', () => { | ||
| jest.spyOn(component.handleLoginChange, 'emit'); | ||
| component.submitLogin(); | ||
| expect(component.handleLoginChange.emit).toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it ('should open billing page with correct URL', async () => { | ||
| const mockUrl = 'https://billing.example.com'; | ||
| jest.spyOn(apiClient, 'getBillingUrl').mockResolvedValue({ url: mockUrl }); | ||
| const mockEvent = new MouseEvent('click'); | ||
| const externalSpy = jest.spyOn(externalUtils, 'externalLink').mockImplementation(() => {}); | ||
|
|
||
| await component.openBillingPage(mockEvent); | ||
|
|
||
| expect(apiClient.getBillingUrl).toHaveBeenCalledWith(); | ||
| expect(externalSpy).toHaveBeenCalledWith(mockUrl, mockEvent); | ||
| }); | ||
|
|
||
| it ('should call getUpgradeProUrl and open external link', async () => { | ||
| const mockUrl = 'https://upgrade.example.com'; | ||
| jest.spyOn(apiClient, 'getUpgradeProUrl').mockResolvedValue({ url: mockUrl }); | ||
| const mockEvent = new MouseEvent('click'); | ||
| const externalSpy = jest.spyOn(externalUtils, 'externalLink').mockImplementation(() => {}); | ||
|
|
||
| await component.openUpgradeProUrl(mockEvent); | ||
|
|
||
| expect(apiClient.getUpgradeProUrl).toHaveBeenCalledWith(); | ||
| expect(externalSpy).toHaveBeenCalledWith(mockUrl, mockEvent); | ||
| }); | ||
|
|
||
| it ('should call buyCredits and open external link if url exists', async () => { | ||
| const mockUrl = 'https://credits.example.com'; | ||
| jest.spyOn(apiClient, 'buyCredits').mockResolvedValue({ url: mockUrl }); | ||
| const mockEvent = new MouseEvent('click'); | ||
| const externalSpy = jest.spyOn(externalUtils, 'externalLink').mockImplementation(() => {}); | ||
|
|
||
| await component.buyCredits(mockEvent); | ||
|
|
||
| expect(apiClient.buyCredits).toHaveBeenCalledWith(); | ||
| expect(externalSpy).toHaveBeenCalledWith(mockUrl, mockEvent); | ||
| }); | ||
|
Comment on lines
+58
to
+92
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These three tests for it.each([
{ method: 'openBillingPage', api: 'getBillingUrl', url: 'https://billing.example.com' },
{ method: 'openUpgradeProUrl', api: 'getUpgradeProUrl', url: 'https://upgrade.example.com' },
{ method: 'buyCredits', api: 'buyCredits', url: 'https://credits.example.com' },
])('should call $api and open external link for $method', async ({ method, api, url }) => {
jest.spyOn(apiClient, api as keyof typeof apiClient).mockResolvedValue({ url });
const mockEvent = new MouseEvent('click');
const externalSpy = jest.spyOn(externalUtils, 'externalLink').mockImplementation(() => {});
await (component as any)[method](mockEvent);
expect(apiClient[api as keyof typeof apiClient]).toHaveBeenCalledWith();
expect(externalSpy).toHaveBeenCalledWith(url, mockEvent);
}); |
||
|
|
||
| it('should not call externalLink if buyCredits returns no url', async () => { | ||
| jest.spyOn(apiClient, 'buyCredits').mockResolvedValue({ url: '' }); | ||
| const mockEvent = new MouseEvent('click'); | ||
| const externalSpy = jest.spyOn(externalUtils, 'externalLink').mockImplementation(() => {}); | ||
|
|
||
| await component.buyCredits(mockEvent); | ||
|
|
||
| expect(apiClient.buyCredits).toHaveBeenCalledWith(); | ||
| expect(externalSpy).not.toHaveBeenCalled(); | ||
| }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
mockutility is imported but is not used within this file. It's good practice to remove unused imports to maintain code cleanliness.