diff --git a/api/src/shared/domain/models/UserOrgaSettings.js b/api/src/shared/domain/models/UserOrgaSettings.js index 3ee81c274df..37a60a56a3d 100644 --- a/api/src/shared/domain/models/UserOrgaSettings.js +++ b/api/src/shared/domain/models/UserOrgaSettings.js @@ -1,8 +1,10 @@ class UserOrgaSettings { - constructor({ id, currentOrganization, user } = {}) { + constructor({ id, currentOrganization, user, createdAt, updatedAt } = {}) { this.id = id; this.currentOrganization = currentOrganization; this.user = user; + this.createdAt = createdAt; + this.updatedAt = updatedAt; } } diff --git a/api/src/team/infrastructure/repositories/user-orga-settings-repository.js b/api/src/team/infrastructure/repositories/user-orga-settings-repository.js index b67f4539b89..d2ab45b6e06 100644 --- a/api/src/team/infrastructure/repositories/user-orga-settings-repository.js +++ b/api/src/team/infrastructure/repositories/user-orga-settings-repository.js @@ -64,7 +64,13 @@ const update = async function (userId, organizationId) { const currentOrganization = await knex('organizations') .where('id', userOrgaSettingsUpdated.currentOrganizationId) .first(); - return new UserOrgaSettings({ id: userOrgaSettingsUpdated.id, user, currentOrganization }); + return new UserOrgaSettings({ + id: userOrgaSettingsUpdated.id, + createdAt: userOrgaSettingsUpdated.createdAt, + updatedAt: userOrgaSettingsUpdated.updatedAt, + user, + currentOrganization, + }); }; /** diff --git a/api/tests/identity-access-management/integration/infrastructure/repositories/user.repository.test.js b/api/tests/identity-access-management/integration/infrastructure/repositories/user.repository.test.js index d550b6eb64e..4f690905749 100644 --- a/api/tests/identity-access-management/integration/infrastructure/repositories/user.repository.test.js +++ b/api/tests/identity-access-management/integration/infrastructure/repositories/user.repository.test.js @@ -54,6 +54,17 @@ describe('Integration | Identity Access Management | Infrastructure | Repository let membershipInDB; let certificationCenterInDB; + let clock; + const now = new Date('2022-12-24'); + + beforeEach(function () { + clock = sinon.useFakeTimers({ now, toFake: ['Date'] }); + }); + + afterEach(function () { + clock.restore(); + }); + function _insertUserWithOrganizationsAndCertificationCenterAccesses() { organizationInDB = databaseBuilder.factory.buildOrganization({ type: 'PRO', @@ -797,7 +808,6 @@ describe('Integration | Identity Access Management | Infrastructure | Repository it('should only return actives certification center membership associated to the user', async function () { // given - const now = new Date(); const email = 'lilou@example.net'; const user = databaseBuilder.factory.buildUser({ email }); const certificationCenter = databaseBuilder.factory.buildCertificationCenter(); @@ -1076,11 +1086,11 @@ describe('Integration | Identity Access Management | Infrastructure | Repository describe('#getUserDetailsForAdmin', function () { it('should return the found user', async function () { // given + const createdAt = new Date('2021-01-01'); const emailConfirmedAt = new Date('2022-01-01'); const lastTermsOfServiceValidatedAt = new Date('2022-01-02'); const lastPixOrgaTermsOfServiceValidatedAt = new Date('2022-01-03'); const lastLoggedAt = new Date('2022-01-04'); - const now = new Date(); const userInDB = databaseBuilder.factory.buildUser({ firstName: 'Henri', lastName: 'Cochet', @@ -1088,8 +1098,8 @@ describe('Integration | Identity Access Management | Infrastructure | Repository cgu: true, lang: 'en', locale: 'en', - createdAt: now, - updatedAt: now, + createdAt, + updatedAt: createdAt, lastTermsOfServiceValidatedAt, lastPixOrgaTermsOfServiceValidatedAt, lastPixCertifTermsOfServiceValidatedAt: lastLoggedAt, @@ -1108,8 +1118,8 @@ describe('Integration | Identity Access Management | Infrastructure | Repository expect(userDetailsForAdmin.lastName).to.equal('Cochet'); expect(userDetailsForAdmin.email).to.equal('henri-cochet@example.net'); expect(userDetailsForAdmin.cgu).to.be.true; - expect(userDetailsForAdmin.createdAt).to.deep.equal(now); - expect(userDetailsForAdmin.updatedAt).to.deep.equal(now); + expect(userDetailsForAdmin.createdAt).to.deep.equal(createdAt); + expect(userDetailsForAdmin.updatedAt).to.deep.equal(createdAt); expect(userDetailsForAdmin.lang).to.equal('en'); expect(userDetailsForAdmin.locale).to.equal('en'); expect(userDetailsForAdmin.lastTermsOfServiceValidatedAt).to.deep.equal(lastTermsOfServiceValidatedAt); @@ -1315,17 +1325,6 @@ describe('Integration | Identity Access Management | Infrastructure | Repository }); context('when user has login details', function () { - let clock; - const now = new Date('2022-02-02'); - - beforeEach(function () { - clock = sinon.useFakeTimers({ now, toFake: ['Date'] }); - }); - - afterEach(function () { - clock.restore(); - }); - it('should return the user with his login details', async function () { // given const userInDB = databaseBuilder.factory.buildUser(userToInsert); @@ -1372,17 +1371,6 @@ describe('Integration | Identity Access Management | Infrastructure | Repository describe('update user', function () { describe('#update', function () { - let clock; - const now = new Date('2021-01-02'); - - beforeEach(function () { - clock = sinon.useFakeTimers({ now, toFake: ['Date'] }); - }); - - afterEach(function () { - clock.restore(); - }); - it('updates the given properties', async function () { // given const user = databaseBuilder.factory.buildUser(); @@ -1393,7 +1381,7 @@ describe('Integration | Identity Access Management | Infrastructure | Repository const fetchedUser = await knex.from('users').where({ id: user.id }).first(); // then - expect(fetchedUser.updatedAt).to.deep.equal(new Date('2021-01-02')); + expect(fetchedUser.updatedAt).to.deep.equal(now); expect(fetchedUser.email).to.equal('chronos@example.net'); expect(fetchedUser.locale).to.equal('fr-BE'); }); @@ -1412,21 +1400,11 @@ describe('Integration | Identity Access Management | Infrastructure | Repository // then expect(updatedUser).to.be.an.instanceOf(User); expect(updatedUser.email).to.equal(newEmail); + expect(updatedUser.updatedAt).to.deep.equal(now); }); }); describe('#updateEmailConfirmed', function () { - let clock; - const now = new Date('2022-02-02'); - - beforeEach(function () { - clock = sinon.useFakeTimers({ now, toFake: ['Date'] }); - }); - - afterEach(function () { - clock.restore(); - }); - it('marks the users’ email as confirmed by updating "emailConfirmedAt" to current date', async function () { // given const userId = databaseBuilder.factory.buildUser({ @@ -1443,6 +1421,7 @@ describe('Integration | Identity Access Management | Infrastructure | Repository // then const user1 = await knex('users').where({ id: userId }).first(); expect(user1.emailConfirmedAt).to.deep.equal(now); + expect(user1.updatedAt).to.deep.equal(now); const user2 = await knex('users').where({ id: user2Id }).first(); expect(user2.emailConfirmedAt).to.be.null; @@ -1474,6 +1453,7 @@ describe('Integration | Identity Access Management | Infrastructure | Repository expect(updatedUser.emailConfirmedAt.toString()).to.equal(userAttributes.emailConfirmedAt.toString()); expect(updatedUser.email).to.equal(userAttributes.email); expect(updatedUser.cgu).to.equal(userAttributes.cgu); + expect(updatedUser.updatedAt).to.deep.equal(now); }); it('should rollback the user email in case of error in transaction', async function () { @@ -1502,17 +1482,6 @@ describe('Integration | Identity Access Management | Infrastructure | Repository }); describe('#updateUserDetailsForAdministration', function () { - let clock; - const now = new Date('2022-11-24'); - - beforeEach(async function () { - clock = sinon.useFakeTimers({ now, toFake: ['Date'] }); - }); - - afterEach(function () { - clock.restore(); - }); - it('updates firstName, lastName, email, username and locale of the user', async function () { // given const userInDb = databaseBuilder.factory.buildUser(userToInsert); @@ -1542,7 +1511,7 @@ describe('Integration | Identity Access Management | Infrastructure | Repository expect(updatedUser.email).to.equal('email_123@example.net'); expect(updatedUser.username).to.equal('username_123'); expect(updatedUser.locale).to.equal('fr-FR'); - expect(updatedUser.updatedAt).to.deep.equal(new Date('2022-11-24')); + expect(updatedUser.updatedAt).to.deep.equal(now); }); describe('when the preventUpdatedAt option is true', function () { @@ -1627,6 +1596,7 @@ describe('Integration | Identity Access Management | Infrastructure | Repository // then expect(updatedUser).to.be.an.instanceOf(User); expect(updatedUser.username).to.equal(username); + expect(updatedUser.updatedAt).to.deep.equal(now); }); it('should throw UserNotFoundError when user id not found', async function () { @@ -1646,17 +1616,6 @@ describe('Integration | Identity Access Management | Infrastructure | Repository }); describe('#updatePixOrgaTermsOfServiceAcceptedToTrue', function () { - let clock; - const now = new Date('2021-01-02'); - - beforeEach(function () { - clock = sinon.useFakeTimers({ now, toFake: ['Date'] }); - }); - - afterEach(function () { - clock.restore(); - }); - it('should return the model with pixOrgaTermsOfServiceAccepted flag updated to true', async function () { // given const userId = databaseBuilder.factory.buildUser({ pixOrgaTermsOfServiceAccepted: false }).id; @@ -1683,21 +1642,11 @@ describe('Integration | Identity Access Management | Infrastructure | Repository // then expect(result.lastPixOrgaTermsOfServiceValidatedAt).to.deep.equal(now); + expect(result.updatedAt).to.deep.equal(now); }); }); describe('#updatePixCertifTermsOfServiceAcceptedToTrue', function () { - let clock; - const now = new Date('2021-01-02'); - - beforeEach(function () { - clock = sinon.useFakeTimers({ now, toFake: ['Date'] }); - }); - - afterEach(function () { - clock.restore(); - }); - it('should return the model with pixCertifTermsOfServiceAccepted flag updated to true', async function () { // given const userId = databaseBuilder.factory.buildUser({ pixCertifTermsOfServiceAccepted: false }).id; @@ -1724,6 +1673,7 @@ describe('Integration | Identity Access Management | Infrastructure | Repository // then expect(actualUser.lastPixCertifTermsOfServiceValidatedAt).to.deep.equal(now); + expect(actualUser.updatedAt).to.deep.equal(now); }); }); @@ -1738,6 +1688,7 @@ describe('Integration | Identity Access Management | Infrastructure | Repository // then expect(actualUser.hasSeenAssessmentInstructions).to.be.true; + expect(actualUser.updatedAt).to.deep.equal(now); }); }); @@ -1752,6 +1703,7 @@ describe('Integration | Identity Access Management | Infrastructure | Repository // then expect(actualUser.hasSeenNewDashboardInfo).to.be.true; + expect(actualUser.updatedAt).to.deep.equal(now); }); }); @@ -1773,6 +1725,7 @@ describe('Integration | Identity Access Management | Infrastructure | Repository // then expect(actualUser.hasSeenFocusedChallengeTooltip).to.be.true; + expect(actualUser.updatedAt).to.deep.equal(now); }); it('should return the model with hasSeenOtherChallengesTooltip flag updated to true', async function () { @@ -1782,6 +1735,7 @@ describe('Integration | Identity Access Management | Infrastructure | Repository // then expect(actualUser.hasSeenOtherChallengesTooltip).to.be.true; + expect(actualUser.updatedAt).to.deep.equal(now); }); }); }); @@ -1869,6 +1823,7 @@ describe('Integration | Identity Access Management | Infrastructure | Repository expect(actualUser.lastTermsOfServiceValidatedAt).to.be.exist; expect(actualUser.lastTermsOfServiceValidatedAt).to.be.a('Date'); expect(actualUser.mustValidateTermsOfService).to.be.false; + expect(actualUser.updatedAt).to.deep.equal(now); }); }); @@ -1899,17 +1854,6 @@ describe('Integration | Identity Access Management | Infrastructure | Repository }); describe('#updateLastDataProtectionPolicySeenAt', function () { - let clock; - const now = new Date('2022-12-24'); - - beforeEach(function () { - clock = sinon.useFakeTimers({ now, toFake: ['Date'] }); - }); - - afterEach(function () { - clock.restore(); - }); - it('should update the last data protection policy to now', async function () { // given const user = databaseBuilder.factory.buildUser(); @@ -1922,6 +1866,7 @@ describe('Integration | Identity Access Management | Infrastructure | Repository // then expect(result).to.be.an.instanceOf(User); expect(result.lastDataProtectionPolicySeenAt).to.deep.equal(now); + expect(result.updatedAt).to.deep.equal(now); }); }); }); diff --git a/api/tests/team/integration/infrastructure/repositories/organization-invitation.repository.test.js b/api/tests/team/integration/infrastructure/repositories/organization-invitation.repository.test.js index b2c656b2024..54fc6356b03 100644 --- a/api/tests/team/integration/infrastructure/repositories/organization-invitation.repository.test.js +++ b/api/tests/team/integration/infrastructure/repositories/organization-invitation.repository.test.js @@ -7,6 +7,17 @@ import { organizationInvitationRepository } from '../../../../../src/team/infras import { catchErr, databaseBuilder, expect, knex, sinon } from '../../../../test-helper.js'; describe('Integration | Team | Infrastructure | Repository | organization-invitation', function () { + let clock; + const now = new Date('2021-01-02'); + + beforeEach(function () { + clock = sinon.useFakeTimers({ now, toFake: ['Date'] }); + }); + + afterEach(function () { + clock.restore(); + }); + describe('#create', function () { let organizationId; @@ -114,7 +125,7 @@ describe('Integration | Team | Infrastructure | Repository | organization-invita await databaseBuilder.commit(); }); - it('should return an Organization-invitation domain object', async function () { + it('accepts and returns the accepted organization invitation', async function () { // when const organizationInvitationSaved = await organizationInvitationRepository.markAsAccepted( organizationInvitation.id, @@ -122,6 +133,12 @@ describe('Integration | Team | Infrastructure | Repository | organization-invita // then expect(organizationInvitationSaved).to.be.an.instanceof(OrganizationInvitation); + expect(organizationInvitationSaved.id).to.equal(organizationInvitation.id); + expect(organizationInvitationSaved.organizationId).to.equal(organizationInvitation.organizationId); + expect(organizationInvitationSaved.email).to.equal(organizationInvitation.email); + expect(organizationInvitationSaved.status).to.equal(OrganizationInvitation.StatusType.ACCEPTED); + expect(organizationInvitationSaved.code).to.equal(organizationInvitation.code); + expect(organizationInvitationSaved.updatedAt).to.be.deep.equal(now); }); it('should not add row in table organization-invitations', async function () { @@ -135,30 +152,11 @@ describe('Integration | Team | Infrastructure | Repository | organization-invita const { count: nbOrganizationInvitationsAfterUpdate } = await knex('organization-invitations').count().first(); expect(nbOrganizationInvitationsAfterUpdate).to.equal(nbOrganizationInvitationsBeforeUpdate); }); - - it('should update model in database', async function () { - // given - const statusAccepted = OrganizationInvitation.StatusType.ACCEPTED; - - // when - const organizationInvitationSaved = await organizationInvitationRepository.markAsAccepted( - organizationInvitation.id, - ); - - // then - expect(organizationInvitationSaved.id).to.equal(organizationInvitation.id); - expect(organizationInvitationSaved.organizationId).to.equal(organizationInvitation.organizationId); - expect(organizationInvitationSaved.email).to.equal(organizationInvitation.email); - expect(organizationInvitationSaved.status).to.equal(statusAccepted); - expect(organizationInvitationSaved.code).to.equal(organizationInvitation.code); - }); }); describe('#markAsCancelled', function () { it('should return the cancelled organization invitation', async function () { // given - const now = new Date('2021-01-02'); - const clock = sinon.useFakeTimers({ now, toFake: ['Date'] }); const organizationInvitation = databaseBuilder.factory.buildOrganizationInvitation({ updatedAt: new Date('2020-01-01T00:00:00Z'), status: OrganizationInvitation.StatusType.PENDING, @@ -178,7 +176,6 @@ describe('Integration | Team | Infrastructure | Repository | organization-invita expect(organizationInvitationSaved.status).to.equal(OrganizationInvitation.StatusType.CANCELLED); expect(organizationInvitationSaved.code).to.equal(organizationInvitation.code); expect(organizationInvitationSaved.updatedAt).to.be.deep.equal(now); - clock.restore(); }); it('should throw a not found error', async function () { @@ -308,17 +305,6 @@ describe('Integration | Team | Infrastructure | Repository | organization-invita }); describe('#updateModificationDate', function () { - let clock; - const now = new Date('2021-01-02'); - - beforeEach(function () { - clock = sinon.useFakeTimers({ now, toFake: ['Date'] }); - }); - - afterEach(function () { - clock.restore(); - }); - it('should update the modification date', async function () { // given const organizationId = 2323; diff --git a/api/tests/team/integration/infrastructure/repositories/user-orga-settings-repository_test.js b/api/tests/team/integration/infrastructure/repositories/user-orga-settings-repository_test.js index cf2a25bf9e6..e3ca927038c 100644 --- a/api/tests/team/integration/infrastructure/repositories/user-orga-settings-repository_test.js +++ b/api/tests/team/integration/infrastructure/repositories/user-orga-settings-repository_test.js @@ -3,7 +3,7 @@ import _ from 'lodash'; import { UserOrgaSettingsCreationError } from '../../../../../src/shared/domain/errors.js'; import { UserOrgaSettings } from '../../../../../src/shared/domain/models/UserOrgaSettings.js'; import { userOrgaSettingsRepository } from '../../../../../src/team/infrastructure/repositories/user-orga-settings-repository.js'; -import { catchErr, databaseBuilder, expect, knex } from '../../../../test-helper.js'; +import { catchErr, databaseBuilder, expect, knex, sinon } from '../../../../test-helper.js'; describe('Integration | Team | Infrastructure | Repository | UserOrgaSettings', function () { const USER_PICKED_PROPERTIES = [ @@ -35,15 +35,24 @@ describe('Integration | Team | Infrastructure | Repository | UserOrgaSettings', 'sessionExpirationDate', ]; + let clock; + const now = new Date('2022-12-01'); + let user; let organization; beforeEach(async function () { + clock = sinon.useFakeTimers({ now, toFake: ['Date'] }); + user = databaseBuilder.factory.buildUser(); organization = databaseBuilder.factory.buildOrganization(); await databaseBuilder.commit(); }); + afterEach(function () { + clock.restore(); + }); + describe('#create', function () { it('should return an UserOrgaSettings domain object', async function () { // when @@ -93,30 +102,22 @@ describe('Integration | Team | Infrastructure | Repository | UserOrgaSettings', }); describe('#update', function () { - let userOrgaSettingsId; - let expectedOrganization; - - beforeEach(async function () { - userOrgaSettingsId = databaseBuilder.factory.buildUserOrgaSettings({ + it('updates the userOrgaSettings and returns it', async function () { + // given + const userOrgaSettings = databaseBuilder.factory.buildUserOrgaSettings({ userId: user.id, - currentOrganizationId: organization.id, - }).id; - expectedOrganization = databaseBuilder.factory.buildOrganization(); + }); + const newOrganization = databaseBuilder.factory.buildOrganization(); await databaseBuilder.commit(); - }); - it('should return the updated userOrgaSettings', async function () { // when - const updatedUserOrgaSettings = await userOrgaSettingsRepository.update(user.id, expectedOrganization.id); + const updatedUserOrgaSettings = await userOrgaSettingsRepository.update(user.id, newOrganization.id); // then - expect(updatedUserOrgaSettings.id).to.deep.equal(userOrgaSettingsId); - expect(_.pick(updatedUserOrgaSettings.user, USER_PICKED_PROPERTIES)).to.deep.equal( - _.pick(user, USER_PICKED_PROPERTIES), - ); - expect(_.omit(updatedUserOrgaSettings.currentOrganization, ORGANIZATION_OMITTED_PROPERTIES)).to.deep.equal( - _.omit(expectedOrganization, ORGANIZATION_OMITTED_PROPERTIES), - ); + expect(updatedUserOrgaSettings.id).to.equal(userOrgaSettings.id); + expect(updatedUserOrgaSettings.updatedAt).to.deep.equal(now); + expect(updatedUserOrgaSettings.user).to.deep.equal(user); + expect(updatedUserOrgaSettings.currentOrganization).to.deep.equal(newOrganization); }); });