-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FEATURE] affiche une alerte d'expiration des lots de places (PIX-14008…
…) (#10106)
- Loading branch information
Showing
8 changed files
with
176 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,36 @@ | ||
import PixBanner from '@1024pix/pix-ui/components/pix-banner'; | ||
import dayjs from 'dayjs'; | ||
import { t } from 'ember-intl'; | ||
import { STATUSES } from 'pix-orga/models/organization-places-lot.js'; | ||
|
||
function getLastActivePlacesLot(placesLots) { | ||
return placesLots | ||
.filter((placesLot) => placesLot.status === STATUSES.ACTIVE) | ||
.sort((placesLotA, placesLotB) => placesLotB.expirationDate - placesLotA.expirationDate); | ||
} | ||
|
||
function getCountdDownDays(placesLots) { | ||
const [lastActiveLot] = getLastActivePlacesLot(placesLots); | ||
if (!lastActiveLot) return; | ||
return dayjs(lastActiveLot.expirationDate).diff(dayjs(), 'day'); | ||
} | ||
|
||
function isAlertVisible(placesLots) { | ||
if (!Array.isArray(placesLots)) return false; | ||
|
||
const hasPendingLots = placesLots.some((placesLot) => placesLot.status === STATUSES.PENDING); | ||
|
||
if (hasPendingLots) return false; | ||
|
||
const [lastActiveLot] = getLastActivePlacesLot(placesLots); | ||
if (!lastActiveLot) return false; | ||
return dayjs(lastActiveLot.expirationDate).isBefore(dayjs().add(30, 'days')); | ||
} | ||
|
||
<template> | ||
{{#if (isAlertVisible @placesLots)}} | ||
<PixBanner class="places-lots-alert" @type="warning" @withIcon="true"> | ||
{{t "banners.last-places-lot-available.message" days=(getCountdDownDays @placesLots)}} | ||
</PixBanner> | ||
{{/if}} | ||
</template> |
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 |
---|---|---|
|
@@ -3,3 +3,5 @@ | |
@import 'place-info'; | ||
@import 'capacity-alert'; | ||
@import 'places-lots'; | ||
@import 'places-lots-alert'; | ||
|
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 @@ | ||
.places-lots-alert { | ||
margin-top: var(--pix-spacing-8x); | ||
} |
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
125 changes: 125 additions & 0 deletions
125
orga/tests/integration/components/places/places-lot-alert-test.gjs
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,125 @@ | ||
import { render } from '@1024pix/ember-testing-library'; | ||
import { t } from 'ember-intl/test-support'; | ||
import PlacesLotsAlert from 'pix-orga/components/places/places-lot-alert'; | ||
import { STATUSES } from 'pix-orga/models/organization-places-lot'; | ||
import { module, test } from 'qunit'; | ||
import sinon from 'sinon'; | ||
|
||
import setupIntlRenderingTest from '../../../helpers/setup-intl-rendering'; | ||
|
||
module('Integration | Component | Places | PlacesLotsAlert', function (hooks) { | ||
setupIntlRenderingTest(hooks); | ||
let store, clock; | ||
const now = new Date('2021-11-03'); | ||
|
||
hooks.beforeEach(function () { | ||
store = this.owner.lookup('service:store'); | ||
clock = sinon.useFakeTimers({ now }); | ||
}); | ||
|
||
hooks.afterEach(function () { | ||
clock.restore(); | ||
}); | ||
|
||
test('it should show an alert with remaining days before places lot expires', async function (assert) { | ||
// given | ||
const placesLots = [ | ||
store.createRecord('organization-places-lot', { | ||
count: 123, | ||
activationDate: new Date('2021-11-01'), | ||
expirationDate: new Date('2021-11-30'), | ||
status: STATUSES.ACTIVE, | ||
}), | ||
]; | ||
// when | ||
const screen = await render(<template><PlacesLotsAlert @placesLots={{placesLots}} /></template>); | ||
const banner = screen.getByRole('alert', { value: t('banners.last-places-lot-available.message') }); | ||
// then | ||
assert.strictEqual(banner.outerText, t('banners.last-places-lot-available.message', { days: 27 })); | ||
}); | ||
test('it should not show an alert if there is one active lot that has an expiration date in more than 1 month', async function (assert) { | ||
// given | ||
const placesLots = [ | ||
store.createRecord('organization-places-lot', { | ||
count: 123, | ||
activationDate: new Date('2021-11-01'), | ||
expirationDate: new Date('2021-11-07'), | ||
status: STATUSES.ACTIVE, | ||
}), | ||
store.createRecord('organization-places-lot', { | ||
count: 123, | ||
activationDate: new Date('2021-11-01'), | ||
expirationDate: new Date('2021-12-03'), | ||
status: STATUSES.ACTIVE, | ||
}), | ||
]; | ||
// when | ||
const screen = await render(<template><PlacesLotsAlert @placesLots={{placesLots}} /></template>); | ||
|
||
// then | ||
assert.notOk(screen.queryByRole('alert', { value: t('banners.last-places-lot-available.message') })); | ||
}); | ||
test('it should not show an alert if remaining days before places lot expires in more than 30 days', async function (assert) { | ||
// given | ||
const placesLots = [ | ||
store.createRecord('organization-places-lot', { | ||
count: 123, | ||
activationDate: new Date('2021-11-01'), | ||
expirationDate: new Date('2021-12-03'), | ||
status: STATUSES.ACTIVE, | ||
}), | ||
]; | ||
// when | ||
const screen = await render(<template><PlacesLotsAlert @placesLots={{placesLots}} /></template>); | ||
|
||
// then | ||
assert.notOk(screen.queryByRole('alert', { value: t('banners.last-places-lot-available.message') })); | ||
}); | ||
test('it should not show alert if there is `PENDING` placesLots', async function (assert) { | ||
// given | ||
const placesLots = [ | ||
store.createRecord('organization-places-lot', { | ||
count: 123, | ||
activationDate: new Date('2021-11-01'), | ||
expirationDate: new Date('2021-11-30'), | ||
status: STATUSES.ACTIVE, | ||
}), | ||
store.createRecord('organization-places-lot', { | ||
count: 123, | ||
activationDate: new Date('2021-12-01'), | ||
expirationDate: new Date('2021-12-30'), | ||
status: STATUSES.PENDING, | ||
}), | ||
]; | ||
// when | ||
const screen = await render(<template><PlacesLotsAlert @placesLots={{placesLots}} /></template>); | ||
|
||
// then | ||
assert.notOk(screen.queryByRole('alert', { value: t('banners.last-places-lot-available.message') })); | ||
}); | ||
test('it should not show alert if there is no ACTIVE placesLots', async function (assert) { | ||
// given | ||
const placesLots = [ | ||
store.createRecord('organization-places-lot', { | ||
count: 123, | ||
activationDate: new Date('2020-12-01'), | ||
expirationDate: new Date('2020-12-30'), | ||
status: STATUSES.EXPIRED, | ||
}), | ||
]; | ||
// when | ||
const screen = await render(<template><PlacesLotsAlert @placesLots={{placesLots}} /></template>); | ||
|
||
// then | ||
assert.notOk(screen.queryByRole('alert', { value: t('banners.last-places-lot-available.message') })); | ||
}); | ||
test('it should not show alert if there is no placesLots', async function (assert) { | ||
// given | ||
const placesLots = []; | ||
// when | ||
const screen = await render(<template><PlacesLotsAlert @placesLots={{placesLots}} /></template>); | ||
|
||
// then | ||
assert.notOk(screen.queryByRole('alert', { value: t('banners.last-places-lot-available.message') })); | ||
}); | ||
}); |
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
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
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