Skip to content

Commit

Permalink
Update PR to add new logic to User table to pass data from user more …
Browse files Browse the repository at this point in the history
…easily than login table
  • Loading branch information
duncanc19 committed Jan 8, 2025
1 parent 3fc182c commit 679abce
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 20 deletions.
6 changes: 3 additions & 3 deletions backend/migrations/20250106091714-addLastViewedSLVMessage.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
'use strict';

const loginTable = { tableName: 'Login', schema: 'cqc' };
const userTable = { tableName: 'User', schema: 'cqc' };

/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
return queryInterface.addColumn(loginTable, 'LastViewedSLVMessage', {
return queryInterface.addColumn(userTable, 'LastViewedSLVMessage', {
type: Sequelize.DataTypes.DATE,
allowNull: true,
});
},

async down(queryInterface) {
return queryInterface.removeColumn(loginTable, 'LastViewedSLVMessage');
return queryInterface.removeColumn(userTable, 'LastViewedSLVMessage');
},
};
5 changes: 0 additions & 5 deletions backend/server/models/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,6 @@ module.exports = function (sequelize, DataTypes) {
allowNull: false,
field: '"AgreedUpdatedTerms"',
},
lastViewedSLVMessage: {
type: DataTypes.DATE,
allowNull: true,
field: 'LastViewedSLVMessage',
},
},
{
tableName: '"Login"',
Expand Down
16 changes: 16 additions & 0 deletions backend/server/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,11 @@ module.exports = function (sequelize, DataTypes) {
allowNull: true,
field: '"CanManageWdfClaimsChangedBy"',
},
lastViewedSLVMessage: {
type: DataTypes.DATE,
allowNull: true,
field: 'LastViewedSLVMessage',
},
},
{
tableName: '"User"',
Expand Down Expand Up @@ -542,5 +547,16 @@ module.exports = function (sequelize, DataTypes) {
return userFound;
};

User.setDateForLastViewedSLVMessage = async function (userUid) {
return await this.update(
{ lastViewedSLVMessage: new Date() },
{
where: {
uid: userUid,
},
},
);
};

return User;
};
25 changes: 24 additions & 1 deletion backend/server/routes/accounts/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ router.route('/swap/establishment/notification/:nmsdId').get(async (req, res) =>
let notificationArr = [];

const establishmentNotifications = await notifications.selectNotificationByEstablishment(req.establishmentUid);
if(establishmentNotifications) notificationArr.push(establishmentNotifications);
if (establishmentNotifications) notificationArr.push(establishmentNotifications);
return res.status(200).send(notificationArr);
}
} catch (e) {
Expand Down Expand Up @@ -911,6 +911,27 @@ const swapEstablishment = async (req, res) => {
.json(response);
};

const updateLastViewedSLVMessage = async (req, res) => {
try {
const userUid = req.params?.userUid;

if (!isCorrectlyFormattedUid(userUid)) {
return res.status(400).send('User UID invalid');
}

await models.user.setDateForLastViewedSLVMessage(userUid);

return res.status(200);
} catch (error) {
return res.status(500).send('Failed to update last viewed date');
}
};

const isCorrectlyFormattedUid = (userUid) => {
const uuidRegex = /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/;
return uuidRegex.test(userUid.toUpperCase());
};

router.route('/').get(return200);
router.route('/admin').get(Authorization.isAdmin, listAdminUsers);
router.route('/admin/:userId').get(Authorization.isAdmin, getUser);
Expand Down Expand Up @@ -945,6 +966,7 @@ router.route('/my/establishments').get(Authorization.isAuthorised, listEstablish
router.route('/admin/:userId').get(Authorization.isAuthorised, getUser);
router.use('/my/notifications', Authorization.isAuthorised);
router.route('/my/notifications').get(listNotifications);
router.route('/update-last-viewed-slv-message/:userUid').post(Authorization.isAuthorised, updateLastViewedSLVMessage);

router.use('/swap/establishment/:id', authLimiter);
router.route('/swap/establishment/:id').post(Authorization.isAdmin, swapEstablishment);
Expand All @@ -955,3 +977,4 @@ module.exports.partAddUser = partAddUser;

module.exports.listAdminUsers = listAdminUsers;
module.exports.updateUser = updateUser;
module.exports.updateLastViewedSLVMessage = updateLastViewedSLVMessage;
4 changes: 2 additions & 2 deletions backend/server/routes/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ router.post('/', async (req, res) => {
'tribalSalt',
'agreedUpdatedTerms',
'status',
'lastViewedSLVMessage',
],
include: [
{
Expand All @@ -80,6 +79,7 @@ router.post('/', async (req, res) => {
'UserRoleValue',
'registrationSurveyCompleted',
'tribalId',
'lastViewedSLVMessage',
],
include: [
{
Expand Down Expand Up @@ -286,7 +286,7 @@ router.post('/', async (req, res) => {
migratedUser,
},
establishmentUser.user.registrationSurveyCompleted,
establishmentUser.lastViewedSLVMessage,
establishmentUser.user.lastViewedSLVMessage,
);

await models.sequelize.transaction(async (t) => {
Expand Down
48 changes: 47 additions & 1 deletion backend/server/test/unit/routes/accounts/user.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ const expect = chai.expect;
const sinon = require('sinon');
const httpMocks = require('node-mocks-http');

const { meetsMaxUserLimit, partAddUser, listAdminUsers, updateUser } = require('../../../../routes/accounts/user');
const {
meetsMaxUserLimit,
partAddUser,
listAdminUsers,
updateUser,
updateLastViewedSLVMessage,
} = require('../../../../routes/accounts/user');
const User = require('../../../../models/classes/user').User;
const models = require('../../../../models');

describe('user.js', () => {
let req;
Expand Down Expand Up @@ -345,4 +352,43 @@ describe('user.js', () => {
});
});
});

describe('updateLastViewedSLVMessage', () => {
let req;
let res;

beforeEach(() => {
req = httpMocks.createRequest();
res = httpMocks.createResponse();
});

it('should return 200 response if userUid in params is valid and database call successful', async () => {
req.params = { userUid: '6b6885fa-340d-4d59-8720-c03d8845e603' };
sinon.stub(models.user, 'setDateForLastViewedSLVMessage').returns(null);

await updateLastViewedSLVMessage(req, res);

expect(res.statusCode).to.equal(200);
});

it('should return 400 response if userUid in params invalid', async () => {
req.params = { userUid: 'invalid-uid' };
sinon.stub(models.user, 'setDateForLastViewedSLVMessage').returns(null);

await updateLastViewedSLVMessage(req, res);

expect(res.statusCode).to.equal(400);
expect(res._getData()).to.deep.equal('User UID invalid');
});

it('should return 500 response if unexpected error', async () => {
req.params = { userUid: '6b6885fa-340d-4d59-8720-c03d8845e603' };
sinon.stub(models.user, 'setDateForLastViewedSLVMessage').throws();

await updateLastViewedSLVMessage(req, res);

expect(res.statusCode).to.equal(500);
expect(res._getData()).to.deep.equal('Failed to update last viewed date');
});
});
});
1 change: 1 addition & 0 deletions frontend/src/app/core/model/userDetails.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface UserDetails {
updatedBy?: string;
username?: string;
canManageWdfClaims?: boolean;
lastViewedSLVMessage?: Date;
}

export enum UserStatus {
Expand Down
9 changes: 6 additions & 3 deletions frontend/src/app/core/services/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Injectable, isDevMode } from '@angular/core';
import { GetWorkplacesResponse } from '@core/model/my-workplaces.model';
import { URLStructure } from '@core/model/url.model';
import { UserDetails } from '@core/model/userDetails.model';
import { BehaviorSubject, Observable, of } from 'rxjs';
import { BehaviorSubject, Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { environment } from 'src/environments/environment';

Expand Down Expand Up @@ -184,7 +184,10 @@ export class UserService {
.pipe(map((response) => response.users));
}

public updateSLVMessage(userUid: string) {
return of(null);
public updateSLVMessage() {
return this.http.post(
`${environment.appRunnerEndpoint}/api/user/update-last-viewed-slv-message/${this.loggedInUser.uid}`,
{},
);
}
}
6 changes: 4 additions & 2 deletions frontend/src/app/features/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ export class LoginComponent implements OnInit, OnDestroy, AfterViewInit {
this.subscriptions.add(
this.authService.authenticate(username, password).subscribe(
(response) => {
const isPreviousUser = this.authService.isPreviousUser(username);
this.authService.clearPreviousUser();

if (response.body.establishment?.uid) {
this.establishmentService.establishmentId = response.body.establishment.uid;
}
Expand All @@ -177,8 +180,7 @@ export class LoginComponent implements OnInit, OnDestroy, AfterViewInit {
return this.router.navigate(['/registration-survey']);
}

if (this.authService.isPreviousUser(username) && this.authService.redirectLocation) {
this.authService.clearPreviousUser();
if (isPreviousUser && this.authService.redirectLocation) {
return this.router.navigateByUrl(this.authService.redirectLocation);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ export class StartersLeaversVacanciesLoginMessageComponent implements OnDestroy
private subscriptions: Subscription = new Subscription();

constructor(private userService: UserService) {
const userUid = this.userService.loggedInUser.uid;

this.subscriptions.add(
this.userService.updateSLVMessage(userUid).subscribe((res) => {
this.userService.updateSLVMessage().subscribe((res) => {
() => {};
}),
);
Expand Down

0 comments on commit 679abce

Please sign in to comment.