-
-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cart): add cart retrieval action support (#2557)
- Loading branch information
Showing
6 changed files
with
170 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { TestBed } from '@angular/core/testing'; | ||
import { Action } from '@ngrx/store'; | ||
|
||
import { DaffCart } from '@daffodil/cart'; | ||
import { | ||
DaffCartRetrievalAction, | ||
DaffCartRetrievalActionInjection, | ||
} from '@daffodil/cart/state'; | ||
import { DaffCartFactory } from '@daffodil/cart/testing'; | ||
|
||
import { daffCartRetrievalGetResponse } from './get-response'; | ||
|
||
class DirectAction implements DaffCartRetrievalAction { | ||
type = 'direct'; | ||
constructor(public payload: DaffCart) {} | ||
} | ||
|
||
class TransformAction implements Action { | ||
type = 'transform'; | ||
constructor(public response: DaffCart) {} | ||
} | ||
|
||
describe('@daffodil/cart/state | daffCartRetrievalGetResponse', () => { | ||
let result: Partial<DaffCart> | null; | ||
let actions: DaffCartRetrievalActionInjection[]; | ||
let cartFactory: DaffCartFactory; | ||
let mockCart: DaffCart; | ||
|
||
beforeEach(() => { | ||
cartFactory = TestBed.inject(DaffCartFactory); | ||
|
||
mockCart = cartFactory.create(); | ||
actions = [ | ||
{ type: 'direct' }, | ||
{ type: 'transform', transform: <any>((action: TransformAction) => action.response) }, | ||
]; | ||
}); | ||
|
||
describe('when the action is not a recognized retrieval action', () => { | ||
beforeEach(() => { | ||
result = daffCartRetrievalGetResponse( | ||
{ type: 'unknown' }, | ||
actions, | ||
); | ||
}); | ||
|
||
it('should return null', () => { | ||
expect(result).toBeNull(); | ||
}); | ||
}); | ||
|
||
describe('when the action is direct', () => { | ||
beforeEach(() => { | ||
result = daffCartRetrievalGetResponse( | ||
new DirectAction(mockCart), | ||
actions, | ||
); | ||
}); | ||
|
||
it('should return the cart', () => { | ||
expect(result).toEqual(mockCart); | ||
}); | ||
}); | ||
|
||
describe('when the action is transform', () => { | ||
beforeEach(() => { | ||
result = daffCartRetrievalGetResponse( | ||
new TransformAction(mockCart), | ||
actions, | ||
); | ||
}); | ||
|
||
it('should return the cart', () => { | ||
expect(result).toEqual(mockCart); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { Action } from '@ngrx/store'; | ||
|
||
import { DaffCart } from '@daffodil/cart'; | ||
|
||
import { | ||
DaffCartRetrievalAction, | ||
DaffCartRetrievalActionInjection, | ||
DaffCartRetrievalActionTransformedInjection, | ||
} from './type'; | ||
|
||
/** | ||
* Gets the cart from the passed action if it is a recognized retrieval action and applying the transformation if needed. | ||
*/ | ||
export function daffCartRetrievalGetResponse<T extends DaffCart = DaffCart>(action: Action, retrievalActions: DaffCartRetrievalActionInjection[]): Partial<T> | null { | ||
const actionInjection = retrievalActions.find(({ type }) => type === action.type); | ||
|
||
if (actionInjection) { | ||
return (<DaffCartRetrievalActionTransformedInjection>actionInjection).transform?.<T>(action) || (<DaffCartRetrievalAction<T>>action).payload; | ||
} | ||
|
||
return null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './token'; | ||
export * from './type'; | ||
export * from './get-response'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { | ||
InjectionToken, | ||
ValueProvider, | ||
} from '@angular/core'; | ||
|
||
import { DaffCartRetrievalActionInjection } from './type'; | ||
|
||
/** | ||
* A token to hold {@link DaffCartRetrievalActionInjection}s. | ||
*/ | ||
export const DAFF_CART_RETRIEVAL_ACTIONS = new InjectionToken<DaffCartRetrievalActionInjection[]>('DAFF_CART_RETRIEVAL_ACTIONS', { factory: () => []}); | ||
|
||
/** | ||
* A provider function for {@link DAFF_CART_RETRIEVAL_ACTIONS}. | ||
*/ | ||
export const daffCartProvideRetrievalActions = (...actions: DaffCartRetrievalActionInjection[]): ValueProvider[] => | ||
actions.map((action) => ({ | ||
provide: DAFF_CART_RETRIEVAL_ACTIONS, | ||
useValue: action, | ||
multi: true, | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { Action } from '@ngrx/store'; | ||
|
||
import { DaffCart } from '@daffodil/cart'; | ||
|
||
/** | ||
* Represents an action that loads a portion of the cart. | ||
*/ | ||
export interface DaffCartRetrievalAction<T extends DaffCart = DaffCart> extends Action { | ||
readonly payload: Partial<T>; | ||
} | ||
|
||
/** | ||
* Represents an injection of a retrieval action that implements the {@link DaffCartRetrievalAction} interface | ||
* and therefore does not need transformation. | ||
* If the injected action needs transformation, use {@link DaffCartRetrievalActionTransformedInjection} | ||
*/ | ||
export interface DaffCartRetrievalActionDirectInjection<T extends DaffCartRetrievalAction = DaffCartRetrievalAction> { | ||
/** | ||
* The action type. | ||
*/ | ||
type: T['type']; | ||
} | ||
|
||
/** | ||
* Represents an injection of a retrieval action that doesn't implement the {@link DaffCartRetrievalAction} interface. | ||
* Contains a way to get the cart from the action. | ||
*/ | ||
export interface DaffCartRetrievalActionTransformedInjection<T extends Action = Action> { | ||
/** | ||
* The action type. | ||
*/ | ||
type: T['type']; | ||
|
||
/** | ||
* A function that gets the retrieved cart from the action. | ||
*/ | ||
transform: <TCart extends DaffCart = DaffCart>(action: T) => Partial<TCart>; | ||
} | ||
|
||
/** | ||
* Represents an injection of a cart retrieval action. | ||
* These actions are typically dispatched when an operation that mutates or loads the cart completes. | ||
* Actions provided to {@link DAFF_CART_RETRIEVAL_ACTIONS} are natively understood by Daffodil reducers and will automatically | ||
* populate the appropriate pieces of state when they are dispatched. | ||
*/ | ||
export type DaffCartRetrievalActionInjection = DaffCartRetrievalActionDirectInjection | DaffCartRetrievalActionTransformedInjection; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters