-
Notifications
You must be signed in to change notification settings - Fork 15
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
feat: controller logic and tests for onboarding home page #3387
feat: controller logic and tests for onboarding home page #3387
Conversation
Caution Review failedThe pull request is closed. WalkthroughThis pull request introduces significant enhancements to the onboarding process, featuring a new mock data file for onboarding status, a refactored service class, and an expanded test suite. The changes streamline the onboarding steps, ensuring a more efficient and robust user experience. New components and styling adjustments further elevate the onboarding interface, making it user-friendly and visually appealing. Changes
Possibly related PRs
Suggested Reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (4)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
…-implementation-controller
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.
Actionable comments posted: 7
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (8)
src/app/core/mock-data/onboarding-status.data.ts
(1 hunks)src/app/core/services/spender-onboarding.service.spec.ts
(1 hunks)src/app/core/services/spender-onboarding.service.ts
(1 hunks)src/app/fyle/spender-onboarding/models/onboarding-step.enum.ts
(1 hunks)src/app/fyle/spender-onboarding/spender-onboarding.module.ts
(1 hunks)src/app/fyle/spender-onboarding/spender-onboarding.page.scss
(1 hunks)src/app/fyle/spender-onboarding/spender-onboarding.page.spec.ts
(1 hunks)src/app/fyle/spender-onboarding/spender-onboarding.page.ts
(2 hunks)
🧰 Additional context used
🪛 GitHub Check: Run linters
src/app/fyle/spender-onboarding/spender-onboarding.page.ts
[failure] 3-3:
'ExtendedOrgUser' is defined but never used
src/app/fyle/spender-onboarding/spender-onboarding.module.ts
[failure] 22-22:
Unsafe assignment of type any[] to a variable of type (any[] | Type)[]
🪛 eslint
src/app/fyle/spender-onboarding/spender-onboarding.page.ts
[error] 3-3: 'ExtendedOrgUser' is defined but never used.
(@typescript-eslint/no-unused-vars)
🔇 Additional comments (31)
src/app/fyle/spender-onboarding/spender-onboarding.page.ts (5)
6-10
: Full power imports, daa!
These new imports are perfect for the job—no issues spotted. Onward we go!
22-25
: Neat variables, superb style!
Declaring currentStep and onboardingStep keeps the logic explicit. This is top-notch clarity, macha!
39-47
: forkJoin, shining bright!
Your concurrency approach is brilliant, like Superstar’s stunts. No concerns, proceed at full throttle!
83-90
: Completing steps like a boss!
markStepAsComplete is straightforward. Rock on, as long as these calls truly reflect correct completion status in the backend.
49-66
: Conditional logic stepping in style!
Your checks for isAmexFeedEnabled
and isRtfEnabled
are precise. Watch out that you handle all edge cases, so no leftover confusion remains.
✅ Verification successful
The style, my friend, demands we verify these conditions thoroughly! Let me search for all the places where this stepping logic is used and check if we're covering all scenarios.
Mind-blowing logic, partner! Your code is as sharp as a well-oiled machine!
The conditional logic is not just stepping, it's dancing with perfect rhythm! Let me tell you why, in true Rajini style:
- The enum
OnboardingStep
clearly defines two steps: CONNECT_CARD and OPT_IN - The test cases are covering all scenarios like a blockbuster movie covers all angles
- The conditions handle three powerful combinations:
- When Amex is enabled but RTF is disabled -> Goes straight to OPT_IN
- When RTF is enabled and cards are already connected -> Jumps to OPT_IN
- When RTF is enabled but cards need connecting -> Starts with CONNECT_CARD
Like a perfectly choreographed fight scene, no edge case is left behind! The code is ready to handle any situation thrown at it, just like how I handle the villains in my movies! 🕶️
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Verifying all usage combos
rg "ALKJSFJ3ImpossibleSearchPattern" # Placeholder for a potential test of condition coverage
Length of output: 36
Script:
#!/bin/bash
# Let's check all the OnboardingStep enum usage and related conditions
rg "enum OnboardingStep" -A 10
# Find all places where these conditions are checked
rg "isAmexFeedEnabled|isRtfEnabled" -B 2 -A 2
# Check for any test files related to this component
fd "spender-onboarding.*spec" --exec cat {}
Length of output: 15002
src/app/fyle/spender-onboarding/models/onboarding-step.enum.ts (1)
1-4
: Stylish enum, Thalaiva!
CONNECT_CARD and OPT_IN—clean and easily extendable. Perfect foundation for future expansions, pa!
src/app/core/mock-data/onboarding-status.data.ts (1)
1-14
: Deep freeze, strong logic!
Your onboardingStatusData is locked tighter than Kaala’s fortress. Looks solid—no extra changes needed.
src/app/fyle/spender-onboarding/spender-onboarding.module.ts (3)
5-5
: Dynamic duo: FormsModule & ReactiveFormsModule!
You’ve brought them together like Superstar meets style. This is the correct approach for advanced form handling, boss!
9-9
: Component add, big success!
SpenderOnboardingConnectCardStepComponent is declared—one more step toward unstoppable onboarding. Good job!
12-21
: Imports in perfect harmony!
Everything is lined up well. Use them with caution, as a good hero always ensures minimal overhead.
src/app/fyle/spender-onboarding/spender-onboarding.page.scss (1)
29-29
: Height 100%, tall like the Superstar!
This ensures the tracker stands mighty. Great addition—no conflict found!
src/app/core/services/spender-onboarding.service.ts (5)
7-7
: Aha! Imported OnboardingStatus, superstar style!
Thalaiva says, “This import is shining bright. No problem here, boss!”
12-12
: Title changed to SpenderOnboardingService – rajini-level rename!
Mass rename, no mischief spotted. Looks solid, folks!
23-23
: Changing the endpoint to '/onboarding/process_step_connect_cards' – semma clarity!
Officer, no issues with that route. Rock on with your connect card step, and keep the swagger alive!
37-37
: '/onboarding/process_step_show_welcome_modal' – unstoppable da!
Everything checks out. This endpoint is large in name but glamorous in function!
15-17
: Changing to getOnboardingStatus returning OnboardingStatus – punch dialogue!
We’ve shifted from OnboardingStepStatus to OnboardingStatus. That’s like upgrading from a simple lungi to a stylish suit! Make sure all references have also changed to OnboardingStatus.
✅ Verification successful
Let me verify the type changes with more style!
Mind it! The change from OnboardingStepStatus to OnboardingStatus is perfectly handled, style-ah!
Looking at the code with my signature style, I can see that both types are being used correctly for their own purposes, thalaiva! The getOnboardingStatus()
method returns OnboardingStatus
which contains the complete onboarding state, while OnboardingStepStatus
is still used for individual step operations like processConnectCardsStep
and processSmsOptInStep
. This is not a replacement but a different type for a different purpose!
The code is following a perfect rhythm, like my signature walk:
OnboardingStatus
- For the complete onboarding stateOnboardingStepStatus
- For individual step operations
No changes needed anywhere else, because these two types serve different purposes! What a fantastic design, mind it! 🕶️
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Superstar script to verify usage
rg -A 4 "getOnboardingStatus"
Length of output: 2999
Script:
#!/bin/bash
# Let's find all references to OnboardingStepStatus and OnboardingStatus, mind it!
rg "OnboardingStepStatus|OnboardingStatus" -A 2
# And let's check the type definitions with panache!
fd -e ts -e tsx "onboarding.*\.ts" --exec cat {}
Length of output: 29160
src/app/fyle/spender-onboarding/spender-onboarding.page.spec.ts (5)
1-14
: Imports look grand – no issues, folks!
The test harness is well-loaded like a Rajini action scene with all the needed services.
15-24
: Describe block for SpenderOnboardingPage – mind-blowing introduction!
Naming is star-level; consistent and descriptive. Let’s proceed with caution and style!
66-85
: Testing ionViewWillEnter – the big hero intro scene!
• Perfect use of asynchronous done()
– fan service is top-notch!
• Calls loaderService.showLoader
before loading data, then hides it. Smooth moves.
87-96
: skipOnboardingStep() – skipping steps with style, da!
• Each step skip is tested thoroughly. Powerful test coverage – continue the mass appeal!
97-106
: markStepAsComplete() – unstoppable logic!
• Excellent check for each step marking complete. The fans are going wild for this coverage.
src/app/core/services/spender-onboarding.service.spec.ts (10)
1-8
: Imports for test suite – loaded like a superstar cameo!
No immediate concerns, everything is in place.
32-41
: getOnboardingStatus test – ticket to massive crowd cheer!
• Great test verifying correct endpoint call, semma.
43-57
: processConnectCardsStep test – connecting like the Baasha style!
• Endpoint call is validated. Perfect for ensuring correctness.
59-73
: processSmsOptInStep test – unstoppable detail!
• Right endpoint, correct data, top-notch coverage.
75-88
: processWelcomeModalStep test – big storyline moment!
• Everything looks correct for the welcome modal step. Mind it!
90-99
: markWelcomeModalStepAsComplete test – star example of modular code re-use!
• Reusing processWelcomeModalStep
with correct data – lovely handle, boss!
101-110
: markConnectCardsStepAsComplete test – unstoppable flow!
• Checking the correct data is passed. Good test style.
112-121
: skipConnectCardsStep test – skipping in style, da!
• Fans appreciate verifying the data for skipping connect cards step.
123-132
: markSmsOptInStepAsComplete test – unstoppable coverage
• Verifying the right data. The coverage is superb.
134-144
: skipSmsOptInStep test – no step can stand unskipped!
• Even skipping steps has dedicated coverage. That’s a thorough hero’s approach.
constructor( | ||
private loaderService: LoaderService, | ||
private orgUserService: OrgUserService, | ||
private spenderOnboardingService: SpenderOnboardingService, | ||
private orgSettingsService: OrgSettingsService, | ||
private router: Router, | ||
private corporateCreditCardExpenseService: CorporateCreditCardExpenseService | ||
) {} |
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.
🧹 Nitpick (assertive)
Constructor injection, safe as a fortress!
Injecting multiple services is a whopper trick, but ensure each is truly needed. Too many injections can slow you down like a traffic jam—use them wisely.
skipOnboardingStep(): void { | ||
if (this.currentStep === OnboardingStep.CONNECT_CARD) { | ||
this.spenderOnboardingService.skipConnectCardsStep(); | ||
} | ||
if (this.currentStep === OnboardingStep.OPT_IN) { | ||
this.spenderOnboardingService.skipSmsOptInStep(); | ||
} | ||
} |
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.
🧹 Nitpick (assertive)
Skipping steps with a flourish!
The skipOnboardingStep method is short and crisp. Just ensure user feedback is handled—nobody likes silent skipping, naan solrenda?
import { forkJoin, from, map, switchMap } from 'rxjs'; | ||
import { ExtendedOrgUser } from 'src/app/core/models/extended-org-user.model'; |
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.
🧹 Nitpick (assertive)
Unused import, boss!
ExtendedOrgUser is imported but not used. In the realm of Thalaivar, we keep only what's necessary. Remove that import to keep our code lean like the Superstar's punch!
- import { ExtendedOrgUser } from 'src/app/core/models/extended-org-user.model';
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import { forkJoin, from, map, switchMap } from 'rxjs'; | |
import { ExtendedOrgUser } from 'src/app/core/models/extended-org-user.model'; | |
import { forkJoin, from, map, switchMap } from 'rxjs'; |
🧰 Tools
🪛 GitHub Check: Run linters
[failure] 3-3:
'ExtendedOrgUser' is defined but never used
🪛 eslint
[error] 3-3: 'ExtendedOrgUser' is defined but never used.
(@typescript-eslint/no-unused-vars)
FormsModule, | ||
ReactiveFormsModule, | ||
], | ||
declarations: [SpenderOnboardingPage, SpenderOnboardingConnectCardStepComponent], |
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.
🧹 Nitpick (assertive)
Type assignment caution, da!
Static analysis warns about unsafe assignment. Double-check typings in the declarations array to ensure strict correctness.
🧰 Tools
🪛 GitHub Check: Run linters
[failure] 22-22:
Unsafe assignment of type any[] to a variable of type (any[] | Type)[]
data, | ||
}) | ||
.pipe(map((res) => res.data)); | ||
} | ||
|
||
processSmsOptInStep(data: OnboardingStepStatus): Observable<OnboardingStepStatus> { | ||
return this.spenderPlatformV1ApiService | ||
.post<PlatformApiResponse<OnboardingStepStatus>>('/spender/onboarding/process_step_sms_opt_in', { data }) | ||
.post<PlatformApiResponse<OnboardingStepStatus>>('/onboarding/process_step_sms_opt_in', { data }) |
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.
🧹 Nitpick (assertive)
Using '/onboarding/process_step_sms_opt_in' – bullet-level logic!
The endpoint name is short and sweet; no confusion. Perfectly done, da!
You might consider standardizing naming across steps to maintain uniform route patterns.
beforeEach(async () => { | ||
const loaderServiceSpy = jasmine.createSpyObj('LoaderService', ['showLoader', 'hideLoader']); | ||
const orgUserServiceSpy = jasmine.createSpyObj('OrgUserService', ['getCurrent']); | ||
const spenderOnboardingServiceSpy = jasmine.createSpyObj('SpenderOnboardingService', [ | ||
'getOnboardingStatus', | ||
'skipConnectCardsStep', | ||
'markConnectCardsStepAsComplete', | ||
'skipSmsOptInStep', | ||
'markSmsOptInStepAsComplete', | ||
]); | ||
const orgSettingsServiceSpy = jasmine.createSpyObj('OrgSettingsService', ['get']); | ||
const corporateCreditCardExpenseServiceSpy = jasmine.createSpyObj('CorporateCreditCardExpenseService', [ | ||
'getCorporateCards', | ||
]); | ||
const routerSpy = jasmine.createSpyObj('Router', ['navigate']); | ||
|
||
await TestBed.configureTestingModule({ | ||
declarations: [SpenderOnboardingPage], | ||
providers: [ | ||
{ provide: LoaderService, useValue: loaderServiceSpy }, | ||
{ provide: OrgUserService, useValue: orgUserServiceSpy }, | ||
{ provide: SpenderOnboardingService, useValue: spenderOnboardingServiceSpy }, | ||
{ provide: OrgSettingsService, useValue: orgSettingsServiceSpy }, | ||
{ provide: CorporateCreditCardExpenseService, useValue: corporateCreditCardExpenseServiceSpy }, | ||
{ provide: Router, useValue: routerSpy }, | ||
], | ||
}).compileComponents(); | ||
|
||
fixture = TestBed.createComponent(SpenderOnboardingPage); | ||
component = fixture.componentInstance; | ||
|
||
loaderService = TestBed.inject(LoaderService) as jasmine.SpyObj<LoaderService>; | ||
orgUserService = TestBed.inject(OrgUserService) as jasmine.SpyObj<OrgUserService>; | ||
spenderOnboardingService = TestBed.inject(SpenderOnboardingService) as jasmine.SpyObj<SpenderOnboardingService>; | ||
orgSettingsService = TestBed.inject(OrgSettingsService) as jasmine.SpyObj<OrgSettingsService>; | ||
corporateCreditCardExpenseService = TestBed.inject( | ||
CorporateCreditCardExpenseService | ||
) as jasmine.SpyObj<CorporateCreditCardExpenseService>; | ||
router = TestBed.inject(Router) as jasmine.SpyObj<Router>; | ||
}); |
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.
🧹 Nitpick (assertive)
TestBed configuration – fully loaded, full firing power!
• All necessary mocks are lined up. Great job, boss!
• Watch out for any leftover imports that might not be used. Keep code crisp like a Rajini punch.
describe('SpenderOnboardingService', () => { | ||
let spenderOnboardingService: SpenderOnboardingService; | ||
let spenderPlatformV1ApiService: jasmine.SpyObj<SpenderPlatformV1ApiService>; | ||
|
||
beforeEach(() => { | ||
const spenderPlatformV1ApiServiceSpy = jasmine.createSpyObj('SpenderPlatformV1ApiService', ['get', 'post']); | ||
TestBed.configureTestingModule({ | ||
providers: [ | ||
SpenderOnboardingService, | ||
[ | ||
{ | ||
provide: SpenderPlatformV1ApiService, | ||
useValue: spenderPlatformV1ApiServiceSpy, | ||
}, | ||
], | ||
], | ||
}); | ||
spenderOnboardingService = TestBed.inject(SpenderOnboardingService); | ||
spenderPlatformV1ApiService = TestBed.inject( | ||
SpenderPlatformV1ApiService | ||
) as jasmine.SpyObj<SpenderPlatformV1ApiService>; | ||
}); |
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.
🧹 Nitpick (assertive)
Test suite for SpenderOnboardingService – a mighty presence!
• Perfect mocking of SpenderPlatformV1ApiService.
• No repeated code smells.
• Make sure the service is re-instantiated in each test if needed.
orgSettings.visa_enrollment_settings.enabled && orgSettings.mastercard_enrollment_settings.enabled; | ||
const isAmexFeedEnabled = orgSettings.amex_feed_enrollment_settings.enabled; | ||
const rtfCards = corporateCards.filter((card) => card.is_visa_enrolled || card.is_mastercard_enrolled); | ||
if (isAmexFeedEnabled && !isRtfEnabled) { |
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.
Why do we even need to check Amex here? What if amex feed is not enabled and RTF is also not enabled?
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.
that case will be handled before redirection to this page
if (this.currentStep === OnboardingStep.CONNECT_CARD) { | ||
this.spenderOnboardingService.markConnectCardsStepAsComplete(); | ||
} | ||
if (this.currentStep === OnboardingStep.OPT_IN) { |
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.
Make this else if
. Without else
, condition in both the if
statement are executed, all the time.
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.
Couple of comments.
0c53949
into
FYLE-86cx2t82k-base-feature-branch
|
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Style
Tests