Skip to content

Commit

Permalink
Merge branch 'update-radio-stations' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
wrandall22 committed Dec 11, 2024
2 parents c9716f6 + c11174c commit e2a7f3f
Show file tree
Hide file tree
Showing 12 changed files with 54 additions and 56 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ Add the following code to your page where appropriate. See the [Branded checkout
on-order-completed="$event.$window.onOrderCompleted($event.purchase)"
on-order-failed="$event.$window.onOrderFailed($event.donorDetails)"
radio-station-api-url="https://api.domain.com/getStations"
radio-station-radius="100"
premium-code="BOOKS01"
premium-name="Books"
premium-image-url="https://api.images.com/img.png"
Expand Down Expand Up @@ -140,7 +139,6 @@ The `<branded-checkout>` element is where the branded checkout Angular app will
- `$event.$window` - Provides access to the browser's global `window` object. This allows you to call a custom callback function like `onOrderCompleted` in the example.
- `$event.purchase` - contains the order's details that are loaded for the thank you page
- `radio-station-api-url` - Provides a URL path for fetching a list of radio stations in the donor's vicinity. If you plan to use this feature, contact Cru's Digital Products and Services (DPS) department ([help@cru.org](mailto:help@cru.org)) to have your URL domain whitelisted to interact with our API - *Optional*
- `radio-station-radius` - Provides a radius (in miles) for fetching a list of radio stations in the donor's vicinity - *Optional*
- `hide-spouse-details` - Hides the spouse detail line initially, and adds a link to toggle the spouse details. If you don't want this feature, do not add this attribute at all. - *Optional*
- `hide-annual` - Hides the annual frequency option. If you don't want this feature, do not add this attribute at all. - *Optional*
- `hide-quarterly` - Hides the quarterly frequency option. If you don't want this feature, do not add this attribute at all. - *Optional*
Expand Down
1 change: 0 additions & 1 deletion src/app/branded/branded-checkout.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ export default angular
day: '@',
apiUrl: '@',
radioStationApiUrl: '@',
radioStationRadius: '@',
premiumCode: '@',
premiumName: '@',
premiumImageUrl: '@',
Expand Down
1 change: 0 additions & 1 deletion src/app/branded/branded-checkout.tpl.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
next="$ctrl.next()"
on-payment-failed="$ctrl.onPaymentFailed($event.donorDetails)"
radio-station-api-url="$ctrl.radioStationApiUrl"
radio-station-radius="$ctrl.radioStationRadius"
premium-code="$ctrl.premiumCode"
premium-name="$ctrl.premiumName"
premium-image-url="$ctrl.premiumImageUrl"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ export default angular
next: '&',
onPaymentFailed: '&',
radioStationApiUrl: '<',
radioStationRadius: '<',
premiumCode: '<',
premiumName: '<',
premiumImageUrl: '<',
Expand Down
1 change: 0 additions & 1 deletion src/app/branded/step-1/branded-checkout-step-1.tpl.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ <h3 class="panel-name" translate>{{'YOUR_INFORMATION'}}</h3>
on-submit="$ctrl.onContactInfoSubmit(success)"
donor-details="$ctrl.donorDetails"
radio-station-api-url="$ctrl.radioStationApiUrl"
radio-station-radius="$ctrl.radioStationRadius"
hide-spouse-details="$ctrl.hideSpouseDetails">
</contact-info>
</div>
Expand Down
16 changes: 7 additions & 9 deletions src/common/components/contactInfo/contactInfo.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,9 @@ class Step1Controller {
}
this.showSpouseFields = false

this.requestRadioStation = !!(this.radioStationApiUrl && this.radioStationRadius)
this.requestRadioStation = !!(this.radioStationApiUrl)

this.loadDonorDetails(donorDetailsDefaults)
this.loadRadioStations()
this.waitForFormInitialization()

this.$scope.$on(SignInEvent, () => {
Expand Down Expand Up @@ -121,6 +120,7 @@ class Step1Controller {
this.spouseFieldsDisabled = false
}
}
this.loadRadioStations()
},
error => {
this.loadingDonorDetails = false
Expand All @@ -135,13 +135,10 @@ class Step1Controller {
if (this.requestRadioStation && postalCode) {
this.loadingRadioStationsError = false

this.radioStationsService.getRadioStations(
this.radioStationApiUrl,
postalCode,
this.radioStationRadius
)
this.radioStationsService.getRadioStations(this.radioStationApiUrl, postalCode)
.subscribe((data) => {
this.radioStations = data
this.radioStationName = this.orderService.retrieveRadioStationName()
},
error => {
this.loadingRadioStationsError = true
Expand All @@ -151,7 +148,9 @@ class Step1Controller {
}

onSelectRadioStation () {
this.radioStationData = this.radioStations.filter((station) => station.Description === this.radioStationName)[0]
this.radioStationData = Object.fromEntries(
Object.entries(this.radioStations).filter(([stationCallLetters, stationName]) => stationName === this.radioStationName)
)
}

submitDetails () {
Expand Down Expand Up @@ -217,7 +216,6 @@ export default angular
donorDetails: '=?',
onSubmit: '&',
radioStationApiUrl: '<',
radioStationRadius: '<',
hideSpouseDetails: '<',
compactAddress: '<'
}
Expand Down
64 changes: 35 additions & 29 deletions src/common/components/contactInfo/contactInfo.component.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ describe('contactInfo', function () {
describe('$onInit', () => {
it('should load the necessary data', () => {
jest.spyOn(self.controller, 'loadDonorDetails').mockImplementation(() => {})
jest.spyOn(self.controller, 'loadRadioStations').mockImplementation(() => {})
jest.spyOn(self.controller, 'waitForFormInitialization').mockImplementation(() => {})
self.controller.$onInit()

expect(self.controller.loadDonorDetails).toHaveBeenCalled()
expect(self.controller.loadRadioStations).toHaveBeenCalled()
expect(self.controller.waitForFormInitialization).toHaveBeenCalled()
})

Expand Down Expand Up @@ -93,6 +91,10 @@ describe('contactInfo', function () {
})

describe('loadDonorDetails', () => {
beforeEach(() => {
jest.spyOn(self.controller, 'loadRadioStations').mockImplementation(() => {})
})

it('should get the donor\'s details', () => {
jest.spyOn(self.controller.orderService, 'getDonorDetails').mockImplementation(() => Observable.of({ 'donor-type': 'Organization', 'spouse-name': {}, staff: false }))
self.controller.loadDonorDetails()
Expand Down Expand Up @@ -130,6 +132,7 @@ describe('contactInfo', function () {
expect(self.controller.nameFieldsDisabled).toEqual(true)
expect(self.controller.spouseFieldsDisabled).toEqual(true)
expect(self.controller.orderService.spouseEditableForOrder).toHaveBeenCalledWith(donorDetails)
expect(self.controller.loadRadioStations).toHaveBeenCalled()
})

it('should set the donor type if it is an empty string', () => {
Expand Down Expand Up @@ -285,13 +288,12 @@ describe('contactInfo', function () {
email: '[email protected]',
'registration-state': 'COMPLETED'
}

beforeEach(() => {
jest.spyOn(self.controller.orderService, 'getDonorDetails').mockImplementation(() => Observable.of(cloneDeep(initDonorDetails)))
jest.spyOn(self.controller, 'loadRadioStations').mockImplementation(() => {})
jest.spyOn(self.controller, 'waitForFormInitialization').mockImplementation(() => {})
})

it('should overwrite donorDetails with overrideDonorDetails on intital load', () => {
self.controller.$window.sessionStorage.removeItem('initialLoadComplete')
self.controller.donorDetails = overrideDonorDetails
Expand All @@ -318,12 +320,12 @@ describe('contactInfo', function () {

expect(self.controller.$window.sessionStorage.getItem('initialLoadComplete')).toEqual('true')
})

it('should not use overrideDonorDetails if initialLoadComplete is set', () => {
self.controller.$window.sessionStorage.setItem('initialLoadComplete', 'true')
self.controller.donorDetails = overrideDonorDetails
self.controller.$onInit()

expect(self.controller.donorDetails.name['title']).toEqual('')
expect(self.controller.donorDetails.name['given-name']).toEqual('Joe')
expect(self.controller.donorDetails.name['middle-initial']).toEqual('')
Expand Down Expand Up @@ -351,7 +353,7 @@ describe('contactInfo', function () {
}
}
self.controller.loadDonorDetails()

expect(self.controller.donorDetails.name['title']).toEqual('')
expect(self.controller.donorDetails.name['given-name']).toEqual('Joe')
expect(self.controller.donorDetails.name['middle-initial']).toEqual('')
Expand Down Expand Up @@ -422,12 +424,15 @@ describe('contactInfo', function () {
describe('loadRadioStations', () => {
const postalCode = '33333';
const radioStationApiUrl = 'https://api.domain.com/getStations'
const radioStationRadius = '100'
const radioStations = [{ Description: 'Radio Station', MediaId: 'WXYZ' }]
const radioStations = { WXYZ: 'Radio Station' }

beforeEach(() => {
self.controller.radioStationApiUrl = radioStationApiUrl
self.controller.requestRadioStation = true
})

it('should not load if not requesting radio station', () => {
self.controller.radioStationApiUrl = undefined
self.controller.radioStationRadius = undefined
self.controller.requestRadioStation = false
self.controller.donorDetails = { mailingAddress: { postalCode } }

Expand All @@ -439,9 +444,6 @@ describe('contactInfo', function () {
})

it('should not load if no postal code selected', () => {
self.controller.radioStationApiUrl = radioStationApiUrl
self.controller.radioStationRadius = radioStationRadius
self.controller.requestRadioStation = true
self.controller.donorDetails = { mailingAddress: { } }

jest.spyOn(self.controller.radioStationsService, 'getRadioStations').mockImplementation(() => Observable.of([]))
Expand All @@ -452,51 +454,55 @@ describe('contactInfo', function () {
})

it('should load if requesting radio station and postal code selected', () => {
self.controller.radioStationApiUrl = radioStationApiUrl
self.controller.radioStationRadius = radioStationRadius
self.controller.requestRadioStation = true
self.controller.donorDetails = { mailingAddress: { postalCode } }

jest.spyOn(self.controller.radioStationsService, 'getRadioStations').mockImplementation(() => Observable.of(radioStations))
self.controller.loadRadioStations()

expect(self.controller.radioStationsService.getRadioStations).toHaveBeenCalledWith(radioStationApiUrl, postalCode, radioStationRadius)
expect(self.controller.radioStationsService.getRadioStations).toHaveBeenCalledWith(radioStationApiUrl, postalCode)
expect(self.controller.radioStations).toEqual(radioStations)
})

it('should log error on failure', () => {
self.controller.radioStationApiUrl = radioStationApiUrl
self.controller.radioStationRadius = radioStationRadius
self.controller.requestRadioStation = true
self.controller.donorDetails = { mailingAddress: { postalCode } }

jest.spyOn(self.controller.radioStationsService, 'getRadioStations').mockImplementation(() => Observable.throw('some error'))
self.controller.loadRadioStations()

expect(self.controller.radioStationsService.getRadioStations).toHaveBeenCalledWith(radioStationApiUrl, postalCode, radioStationRadius)
expect(self.controller.radioStationsService.getRadioStations).toHaveBeenCalledWith(radioStationApiUrl, postalCode)
expect(self.controller.radioStations).toBeUndefined()
expect(self.controller.$log.error.logs[0]).toEqual(['Error loading radio stations.', 'some error'])
})

it('should prepopulate the radio station name previously selected', () => {
self.controller.donorDetails = { mailingAddress: { postalCode } }

jest.spyOn(self.controller.radioStationsService, 'getRadioStations').mockImplementation(() => Observable.of(radioStations))
jest.spyOn(self.controller.orderService, 'retrieveRadioStationName').mockReturnValue('Radio Station')
self.controller.loadRadioStations()

expect(self.controller.radioStationName).toEqual('Radio Station')
})
})

describe('onSelectRadioStation', () => {
const radioStations = [{ Description: 'Radio Station', MediaId: 'WXYZ' }, { Description: 'Another Station', MediaId: 'ZYXW' }]
const radioStations = { WXYZ: 'Radio Station', ZYXW: 'Another Station' }

it('should find selected radio station in list', () => {
self.controller.radioStations = radioStations
self.controller.radioStationName = radioStations[0].Description
self.controller.radioStationName = Object.values(radioStations)[0]

self.controller.onSelectRadioStation()

expect(self.controller.radioStationData).toEqual(radioStations[0])
expect(self.controller.radioStationData).toEqual({ WXYZ: 'Radio Station' })
})
})

describe('submitDetails', () => {
const radioStationData = { Description: 'Radio Station', MediaId: 'WXYZ' }
const radioStationData = { WXYZ: 'Radio Station' }

it('should call onSubmit binding if there are errors', () => {
self.controller.detailsForm.$valid = false
self.controller.detailsForm.$valid = false
jest.spyOn(self.controller.orderService, 'updateDonorDetails').mockImplementation(() => {})
jest.spyOn(self.controller.orderService, 'addEmail').mockImplementation(() => {})
jest.spyOn(self.controller.orderService, 'storeRadioStationData').mockImplementation(() => {})
Expand Down Expand Up @@ -549,7 +555,7 @@ describe('contactInfo', function () {
jest.spyOn(self.controller.orderService, 'storeRadioStationData').mockImplementation(() => {})
self.controller.submitDetails()

expect(self.controller.orderService.storeRadioStationData).toHaveBeenCalledWith(radioStationData)
expect(self.controller.orderService.storeRadioStationData).toHaveBeenCalledWith(radioStationData)
})

it('should handle an error saving donor details', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/common/components/contactInfo/contactInfo.tpl.html
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ <h4 class="panel-title border-bottom-small visible" translate>{{'RADIO_STATION
name="radioStation"
ng-model="$ctrl.radioStationName"
ng-change="$ctrl.onSelectRadioStation()"
ng-options="v.Description as v['Description'] for v in $ctrl.radioStations | orderBy:Description"
ng-options="value for (key, value) in $ctrl.radioStations"
>
</select>
<div role="alert" ng-if="$ctrl.loadingRadioStationsError">
Expand Down
4 changes: 2 additions & 2 deletions src/common/services/api/order.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,8 @@ class Order {
}

storeRadioStationData (radioStationData) {
this.sessionStorage.setItem('radioStationName', radioStationData.Description)
this.sessionStorage.setItem('radioStationCallLetters', radioStationData.MediaId)
this.sessionStorage.setItem('radioStationName', Object.values(radioStationData)[0])
this.sessionStorage.setItem('radioStationCallLetters', Object.keys(radioStationData)[0])
}

retrieveRadioStationName () {
Expand Down
2 changes: 1 addition & 1 deletion src/common/services/api/order.service.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1125,7 +1125,7 @@ describe('order service', () => {

describe('storeRadioStationData', () => {
it('should save the choice of radio station', () => {
self.orderService.storeRadioStationData({ Description: 'Radio Station', MediaId: 'WXYZ' })
self.orderService.storeRadioStationData({ WXYZ: 'Radio Station' })
expect(self.$window.sessionStorage.getItem('radioStationName')).toEqual('Radio Station')
expect(self.$window.sessionStorage.getItem('radioStationCallLetters')).toEqual('WXYZ')
})
Expand Down
6 changes: 3 additions & 3 deletions src/common/services/api/radioStations.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ class RadioStations {
this.$http = $http
}

getRadioStations (radioStationApiUrl, postalCode, radioStationRadius) {
getRadioStations (radioStationApiUrl, postalCode) {
return Observable.from(this.$http({
method: 'GET',
url: radioStationApiUrl + '/' + postalCode + '/' + radioStationRadius,
url: radioStationApiUrl + '/' + postalCode,
withCredentials: true
}))
.map((response) => {
return response.data.GetMediaNearPostalCodeResult
return response.data
})
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/common/services/api/radioStations.service.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ describe('radio station service', () => {

describe('getRadioStations', () => {
it('returns a list of radio stations', (done) => {
const expectedRadioStations = [{ Description: 'Radio Station', MediaId: 'WXYZ' }, { Description: 'Other Station', MediaId: 'ZYXW' }]
self.$httpBackend.expectGET('https://api.domain.com/getStations/33333/100')
.respond(200, { GetMediaNearPostalCodeResult: expectedRadioStations })
self.radioStationsService.getRadioStations('https://api.domain.com/getStations', '33333', '100')
const expectedRadioStations = { WXYZ: 'Radio Station', ZYXW: 'Other Station' }

self.$httpBackend.expectGET('https://api.domain.com/getStations/33333')
.respond(200, expectedRadioStations)
self.radioStationsService.getRadioStations('https://api.domain.com/getStations', '33333')
.subscribe((data) => {
expect(data).toEqual(expectedRadioStations)
done()
Expand Down

0 comments on commit e2a7f3f

Please sign in to comment.