Skip to content

Commit

Permalink
feat(api): filter on place management feature instead of organization…
Browse files Browse the repository at this point in the history
… places for data statistics
  • Loading branch information
Alexandre-Monney authored Nov 5, 2024
1 parent 9da072f commit 2c0466a
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const getDataOrganizationsPlacesStatistics = withTransaction(async function ({
organizationPlacesLotRepository,
organizationLearnerRepository,
}) {
const organizationWithPlaces = await organizationRepository.getOrganizationsWithPlaces();
const organizationWithPlaces = await organizationRepository.getOrganizationsWithPlacesManagementFeatureEnabled();

const organizationWithPlacesIds = organizationWithPlaces.map((organization) => organization.id);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import _ from 'lodash';
import { knex } from '../../../../db/knex-database-connection.js';
import { Organization } from '../../../organizational-entities/domain/models/Organization.js';
import { Tag } from '../../../organizational-entities/domain/models/Tag.js';
import { ORGANIZATION_FEATURE } from '../../../shared/domain/constants.js';
import { DomainTransaction } from '../../domain/DomainTransaction.js';
import { NotFoundError } from '../../domain/errors.js';
import { fetchPage } from '../utils/knex-utils.js';
Expand Down Expand Up @@ -184,13 +185,26 @@ const findPaginatedFilteredByTargetProfile = async function ({ targetProfileId,
return { models: organizations, pagination };
};

const getOrganizationsWithPlaces = async function () {
const getOrganizationsWithPlacesManagementFeatureEnabled = async function () {
const knexConn = DomainTransaction.getConnection();
const placesManagementFeature = await knexConn('features')
.select('id')
.where('key', ORGANIZATION_FEATURE.PLACES_MANAGEMENT.key)
.first();

if (!placesManagementFeature) {
return [];
}

const organizations = await knexConn('organizations')
.select('organizations.id', 'name', 'type')
.innerJoin('organization-places', 'organizations.id', 'organization-places.organizationId')
.whereNull('archivedAt')
.distinct();
.join('organization-features', function () {
this.on('organization-features.organizationId', 'organizations.id').andOn(
'organization-features.featureId',
placesManagementFeature.id,
);
})
.whereNull('archivedAt');

return organizations.map((organization) => _toDomain(organization));
};
Expand All @@ -204,6 +218,6 @@ export {
findScoOrganizationsByUai,
get,
getIdByCertificationCenterId,
getOrganizationsWithPlaces,
getOrganizationsWithPlacesManagementFeatureEnabled,
update,
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import _ from 'lodash';

import { NON_OIDC_IDENTITY_PROVIDERS } from '../../../../src/identity-access-management/domain/constants/identity-providers.js';
import { ORGANIZATION_FEATURE } from '../../../../src/shared/domain/constants.js';
import { NotFoundError } from '../../../../src/shared/domain/errors.js';
import { Organization } from '../../../../src/shared/domain/models/index.js';
import * as organizationRepository from '../../../../src/shared/infrastructure/repositories/organization-repository.js';
Expand Down Expand Up @@ -1000,173 +1001,173 @@ describe('Integration | Repository | Organization', function () {
});
});

describe('#getOrganizationsWithPlaces', function () {
it('should only return organizations not archived', async function () {
// given
const superAdminUserId = databaseBuilder.factory.buildUser().id;

const firstOrganization = databaseBuilder.factory.buildOrganization({
type: 'SCO',
name: 'Organization of the dark side',
archivedAt: null,
isArchived: false,
});
describe('#getOrganizationsWithPlacesManagementFeatureEnabled', function () {
describe('When organization have places management feature enabled', function () {
let firstOrganization;

databaseBuilder.factory.buildOrganizationPlace({
count: 3,
organizationId: firstOrganization.id,
activationDate: new Date(),
expirationDate: new Date(),
createdBy: superAdminUserId,
createdAt: new Date(),
deletedAt: null,
deletedBy: null,
});

const secondOrganization = databaseBuilder.factory.buildOrganization({
type: 'SCO',
name: 'Organization of the BRIGHT side',
archivedAt: new Date(),
isArchived: true,
});
beforeEach(async function () {
firstOrganization = databaseBuilder.factory.buildOrganization({
type: 'SCO',
name: 'Organization of the dark side',
archivedAt: null,
isArchived: false,
});
const placesManagementFeatureId = databaseBuilder.factory.buildFeature({
key: ORGANIZATION_FEATURE.PLACES_MANAGEMENT.key,
}).id;
databaseBuilder.factory.buildOrganizationFeature({
organizationId: firstOrganization.id,
featureId: placesManagementFeatureId,
});

databaseBuilder.factory.buildOrganizationPlace({
count: 3,
organizationId: secondOrganization.id,
activationDate: new Date(),
expirationDate: new Date(),
createdBy: superAdminUserId,
createdAt: new Date(),
deletedAt: null,
deletedBy: null,
await databaseBuilder.commit();
});

await databaseBuilder.commit();
it('should only return organizations not archived', async function () {
// given
const superAdminUserId = databaseBuilder.factory.buildUser().id;

// when
const organizationsWithPlaces = await organizationRepository.getOrganizationsWithPlaces();
databaseBuilder.factory.buildOrganizationPlace({
count: 3,
organizationId: firstOrganization.id,
activationDate: new Date(),
expirationDate: new Date(),
createdBy: superAdminUserId,
createdAt: new Date(),
deletedAt: null,
deletedBy: null,
});

// then
expect(organizationsWithPlaces.length).to.equal(1);
expect(organizationsWithPlaces[0]).to.be.instanceOf(Organization);
expect(organizationsWithPlaces[0].id).to.equal(firstOrganization.id);
expect(organizationsWithPlaces[0].name).to.equal(firstOrganization.name);
expect(organizationsWithPlaces[0].type).to.equal(firstOrganization.type);
});
const secondOrganization = databaseBuilder.factory.buildOrganization({
type: 'SCO',
name: 'Organization of the BRIGHT side',
archivedAt: new Date(),
isArchived: true,
});

it('should only return organizations with places', async function () {
// given
const superAdminUserId = databaseBuilder.factory.buildUser().id;
databaseBuilder.factory.buildOrganizationPlace({
count: 3,
organizationId: secondOrganization.id,
activationDate: new Date(),
expirationDate: new Date(),
createdBy: superAdminUserId,
createdAt: new Date(),
deletedAt: null,
deletedBy: null,
});

const firstOrganization = databaseBuilder.factory.buildOrganization({
type: 'SCO',
name: 'Organization of the dark side',
archivedAt: null,
isArchived: false,
});
await databaseBuilder.commit();

databaseBuilder.factory.buildOrganizationPlace({
count: 3,
organizationId: firstOrganization.id,
activationDate: new Date(),
expirationDate: new Date(),
createdBy: superAdminUserId,
createdAt: new Date(),
deletedAt: null,
deletedBy: null,
});
// when
const organizationsWithPlaces =
await organizationRepository.getOrganizationsWithPlacesManagementFeatureEnabled();

databaseBuilder.factory.buildOrganization({
type: 'SCO',
name: 'Organization of the rainbow side',
archivedAt: null,
isArchived: false,
// then
expect(organizationsWithPlaces.length).to.equal(1);
expect(organizationsWithPlaces[0]).to.be.instanceOf(Organization);
expect(organizationsWithPlaces[0].id).to.equal(firstOrganization.id);
expect(organizationsWithPlaces[0].name).to.equal(firstOrganization.name);
expect(organizationsWithPlaces[0].type).to.equal(firstOrganization.type);
});

await databaseBuilder.commit();
it('should return only once an organization with many placesLots', async function () {
// given
const superAdminUserId = databaseBuilder.factory.buildUser().id;

// when
const organizationsWithPlaces = await organizationRepository.getOrganizationsWithPlaces();
databaseBuilder.factory.buildOrganizationPlace({
count: 3,
organizationId: firstOrganization.id,
activationDate: new Date(),
expirationDate: new Date(),
createdBy: superAdminUserId,
createdAt: new Date(),
deletedAt: null,
deletedBy: null,
});

// then
expect(organizationsWithPlaces.length).to.equal(1);
expect(organizationsWithPlaces[0]).to.be.instanceOf(Organization);
expect(organizationsWithPlaces[0].id).to.equal(firstOrganization.id);
expect(organizationsWithPlaces[0].name).to.equal(firstOrganization.name);
expect(organizationsWithPlaces[0].type).to.equal(firstOrganization.type);
});
databaseBuilder.factory.buildOrganizationPlace({
count: 25,
organizationId: firstOrganization.id,
activationDate: new Date(),
expirationDate: new Date(),
createdBy: superAdminUserId,
createdAt: new Date(),
deletedAt: null,
deletedBy: null,
});

it('should return only once an organization with many placesLots', async function () {
// given
const superAdminUserId = databaseBuilder.factory.buildUser().id;
await databaseBuilder.commit();

const firstOrganization = databaseBuilder.factory.buildOrganization({
type: 'SCO',
name: 'Organization of the dark side',
archivedAt: null,
isArchived: false,
});
// when
const organizationsWithPlaces =
await organizationRepository.getOrganizationsWithPlacesManagementFeatureEnabled();

databaseBuilder.factory.buildOrganizationPlace({
count: 3,
organizationId: firstOrganization.id,
activationDate: new Date(),
expirationDate: new Date(),
createdBy: superAdminUserId,
createdAt: new Date(),
deletedAt: null,
deletedBy: null,
// then
expect(organizationsWithPlaces.length).to.equal(1);
});

databaseBuilder.factory.buildOrganizationPlace({
count: 25,
organizationId: firstOrganization.id,
activationDate: new Date(),
expirationDate: new Date(),
createdBy: superAdminUserId,
createdAt: new Date(),
deletedAt: null,
deletedBy: null,
});
it('should return organization instead if they have unlimited places', async function () {
// given
const superAdminUserId = databaseBuilder.factory.buildUser().id;

await databaseBuilder.commit();
const organizationId = databaseBuilder.factory.buildOrganization({
type: 'SCO',
name: 'Organization du sud de la France avec le plus beau stade de France',
archivedAt: null,
isArchived: false,
}).id;

// when
const organizationsWithPlaces = await organizationRepository.getOrganizationsWithPlaces();
databaseBuilder.factory.buildOrganizationPlace({
count: null,
organizationId,
activationDate: new Date('2024-01-01'),
expirationDate: new Date('2025-12-31'),
createdBy: superAdminUserId,
createdAt: new Date(),
deletedAt: null,
deletedBy: null,
});

// then
expect(organizationsWithPlaces.length).to.equal(1);
});
await databaseBuilder.commit();

it('should return organization instead if they have unlimited places', async function () {
// given
const superAdminUserId = databaseBuilder.factory.buildUser().id;
// when
const organizationsWithPlaces =
await organizationRepository.getOrganizationsWithPlacesManagementFeatureEnabled();

const organizationId = databaseBuilder.factory.buildOrganization({
type: 'SCO',
name: 'Organization du sud de la France avec le plus beau stade de France',
archivedAt: null,
isArchived: false,
}).id;

databaseBuilder.factory.buildOrganizationPlace({
count: null,
organizationId,
activationDate: new Date('2024-01-01'),
expirationDate: new Date('2025-12-31'),
createdBy: superAdminUserId,
createdAt: new Date(),
deletedAt: null,
deletedBy: null,
// then
expect(organizationsWithPlaces.length).to.equal(1);
});
});

await databaseBuilder.commit();
describe('When organization have places management feature not enabled', function () {
it('should not return organization', async function () {
// given
const userId = databaseBuilder.factory.buildUser().id;
const organizationId = databaseBuilder.factory.buildOrganization({
type: 'PRO',
name: 'Organization without places feature',
isArchived: false,
}).id;
databaseBuilder.factory.buildOrganizationPlace({
count: 3,
organizationId,
activationDate: new Date(),
expirationDate: new Date(),
createdBy: userId,
createdAt: new Date(),
deletedAt: null,
deletedBy: null,
});

// when
const organizationsWithPlaces = await organizationRepository.getOrganizationsWithPlaces();
await databaseBuilder.commit();

// then
expect(organizationsWithPlaces.length).to.equal(1);
// when
const organizationsWithPlaces =
await organizationRepository.getOrganizationsWithPlacesManagementFeatureEnabled();

// then
expect(organizationsWithPlaces).to.have.lengthOf(0);
});
});
});
});
Loading

0 comments on commit 2c0466a

Please sign in to comment.