Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/interview timeslots #25

Merged
merged 56 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
5ffb921
add: relations between User, Availabilities
whiitex May 1, 2024
ce9dd19
fix: entity (recsess, user, timeslot, avail)
whiitex May 14, 2024
90ebd95
add: find available time slots functionality, tested
whiitex May 19, 2024
2718207
Merge branch 'dev' of https://github.com/MuNuChapterHKN/HKrecruitment…
whiitex May 19, 2024
59c3f48
fix: previous simplification for dev
whiitex May 19, 2024
74b0d00
format
whiitex May 19, 2024
019f24a
fix: minor
whiitex May 19, 2024
dc04c2f
fix: minor 2
whiitex May 19, 2024
71c66ed
fix: minor 3
whiitex May 19, 2024
2050e01
add: test 2e2
whiitex May 19, 2024
4602a26
format
whiitex May 19, 2024
d034c33
fix: sql errors
whiitex May 19, 2024
127c223
fix: sql error 2
whiitex May 19, 2024
cd72909
format
whiitex May 19, 2024
520a1f4
fix: minor
whiitex May 19, 2024
3a8c0d2
fix: 2
whiitex May 19, 2024
50533c5
fix: 3
whiitex May 19, 2024
682b5b8
fix 4
whiitex May 19, 2024
d7dd6c3
fix: 6
whiitex May 19, 2024
2154316
fix: 5
whiitex May 19, 2024
fc00fc5
fix: 7
whiitex May 19, 2024
5aa5400
fix: 8
whiitex May 19, 2024
23ffd9e
fix: 8
whiitex May 19, 2024
395a321
fix: 9
whiitex May 19, 2024
dd3f63a
format
whiitex May 19, 2024
0c92b3d
fix: 10
whiitex May 19, 2024
aab3bc9
fix: 11
whiitex May 19, 2024
b82b00d
debubg: tests
whiitex May 19, 2024
dff77a4
format
whiitex May 19, 2024
542e5dc
debubg: tests 2
whiitex May 19, 2024
527c65c
debug: test 3
whiitex May 19, 2024
da50afe
format
whiitex May 19, 2024
37729bb
debug: test 4
whiitex May 19, 2024
04656b0
debug: test 5
whiitex May 19, 2024
0596a93
debug: test 6
whiitex May 19, 2024
7351d02
debug: test 7
whiitex May 19, 2024
22522fc
debug: test 8
whiitex May 19, 2024
a4a43ad
debug: test 9
whiitex May 19, 2024
bbb997f
not def
whiitex May 19, 2024
1356a78
not def
whiitex May 19, 2024
4ed9b9d
not def!
whiitex May 19, 2024
7d6690c
fix: pull requested changes
whiitex May 22, 2024
90e0cb5
upd: sonar properties
whiitex May 22, 2024
58dc3f1
test: find available time slotsù
whiitex May 22, 2024
72e2679
fix: format
whiitex May 22, 2024
d8a4b8e
test: improvements
whiitex May 22, 2024
3c82ffa
fix: improve coverage
whiitex May 23, 2024
76bd43c
fix: improve coverage
whiitex May 24, 2024
0e82629
fix: improve coverage
whiitex May 24, 2024
defd47b
fix: improve coverage - format
whiitex May 24, 2024
dad4992
fix: minor
whiitex May 25, 2024
f2f4a4a
fix: formatting comments
whiitex May 25, 2024
87a2eb1
fix: formatting comments
whiitex May 25, 2024
6dd26b6
fix: formatting comments
whiitex May 25, 2024
1afe269
fix: formatting comments
whiitex May 25, 2024
c9c30fb
feat: check ability
whiitex May 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions api/src/availability/availability.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
} from '../../../shared/src/availability';
import { User } from 'src/users/user.entity';
import { TimeSlot } from 'src/timeslots/timeslot.entity';
import { DbAwareColumn } from 'src/utils/db-aware-column';

@Entity()
export class Availability implements AvailabilityInterface {
Expand All @@ -24,13 +23,12 @@ export class Availability implements AvailabilityInterface {
@Column({ name: 'last_modified' })
lastModified: Date;

@DbAwareColumn(() => TimeSlot, { name: 'time_slot' })
@ManyToOne(() => TimeSlot, (timeSlot) => timeSlot.availabilities)
timeSlot: Relation<TimeSlot>;

@ManyToOne(() => User, (user) => user.availabilities)
user: Relation<User>;

// @OneToOne(() => Interview)
// @OneToOne(() => Interview, (interview) => interview.availability)
// interview: Interview;
}
29 changes: 29 additions & 0 deletions api/src/availability/availability.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,28 @@ describe('AvailabilityService', () => {
});
});

describe('updateAvailability', () => {
it('should update the availability with the specified id', async () => {
const mockUpdatedAvailability = {
...mockAvailability,
state: AvailabilityState.Interviewing,
};
jest
.spyOn(mockedRepository, 'save')
.mockResolvedValue(mockUpdatedAvailability);
const result = await service.updateAvailability(
mockAvailability.id,
mockUpdatedAvailability,
);
expect(result).toEqual(mockUpdatedAvailability);
expect(mockedRepository.save).toHaveBeenCalledTimes(1);
expect(mockedRepository.save).toHaveBeenCalledWith({
...mockUpdatedAvailability,
id: mockAvailability.id,
});
});
});

describe('deleteAvailability', () => {
it('should remove the specified availability from the database', async () => {
const mockAvailabilityRepository = {
Expand Down Expand Up @@ -142,6 +164,13 @@ describe('AvailabilityService', () => {
expect(result).toEqual(mockAvailability);
expect(mockedRepository.findBy).toHaveBeenCalledTimes(1);
});

it('should return null if no availability is found', async () => {
jest.spyOn(mockedRepository, 'findBy').mockResolvedValue([]);
const result = await service.findById(mockAvailability.id);
expect(result).toBeNull();
expect(mockedRepository.findBy).toHaveBeenCalledTimes(1);
});
});

describe('findByUserAndTimeSlot', () => {
Expand Down
35 changes: 33 additions & 2 deletions api/src/availability/availability.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,54 @@ export class AvailabilityService {
private dataSource: DataSource,
) {}

/**
* List all availabilities
* @returns {Promise<Availability[]>} - List of availabilities
*/
async listAvailabilities(): Promise<Availability[]> {
return await this.availabilityRepository.find();
}

/**
* Find all availabilities for a given user
* @param user - User to find availabilities for
* @returns {Promise<Availability[]>} - List of availabilities for the user
*/
async findById(id: number): Promise<Availability> {
const matches = await this.availabilityRepository.findBy({
id: id,
});
return matches.length > 0 ? matches[0] : null;
}

/**
* Find all availabilities for a given user
* @param user - User to find availabilities for
* @returns {Promise<Availability[]>} - List of availabilities for the user
*/
async findByUserAndTimeSlot(user: User, timeSlot: TimeSlot) {
const matches = await this.availabilityRepository.findBy({
user: user,
timeSlot: timeSlot,
user: user as any,
timeSlot: timeSlot as any,
});
return matches.length > 0 ? matches[0] : null;
}

/**
* Create an availability
* @param availability - Availability to create
* @returns {Promise<Availability>} - Created availability
*/
async createAvailability(availability: Availability): Promise<Availability> {
return await this.availabilityRepository.save(availability);
}

/**
* Update an availability
* @param oldAvailabilityId - ID of the
* @param newAvailability - New availability
* @returns {Promise<Availability>} - Updated availability
*/
async updateAvailability(
oldAvailabilityId: number,
newAvailability: Availability,
Expand All @@ -49,6 +74,12 @@ export class AvailabilityService {
});
}

/**
* Delete an availability
* @param availabilityId - ID of the availability to delete
* @returns {Promise<Availability>} - Deleted availability
* @throws {ConflictException} - If availability is in use
*/
async deleteAvailability(availabilityId: number): Promise<Availability> {
return await transaction(
this.dataSource,
Expand Down
90 changes: 83 additions & 7 deletions api/src/mocks/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,6 @@ export const testDateTime1Hour = new Date(2023, 0, 1, 11, 30, 0);
export const testDateTime3Hours = new Date(2023, 0, 1, 13, 30, 0);
export const testDateTimeEnd = new Date(2023, 0, 1, 11, 30, 0);

export const mockTimeSlot = {
start: testDateTimeStart,
end: testDateTimeEnd,
id: 1,
availabilities: [],
} as TimeSlot & { availabilities: any[] };

export const testInterviewStart = '11:55' as unknown as Date;
export const testInterviewEnd = '20:35' as unknown as Date;
export const testDay1 = '2024-10-20' as unknown as Date;
Expand All @@ -54,6 +47,14 @@ export const mockRecruitmentSession = {
lastModified: testDateLastModified,
};

export const mockTimeSlot = {
recruitmentSession: mockRecruitmentSession,
start: testDateTimeStart,
end: testDateTimeEnd,
id: 1,
availabilities: [],
} as TimeSlot & { availabilities: any[] };

export const mockCreateRecruitmentSessionDto = {
slotDuration: 50,
interviewStart: testInterviewStart,
Expand Down Expand Up @@ -228,3 +229,78 @@ export const mockAvailability = {
export const mockCreateAvailabilityDto = {
timeSlotId: mockTimeSlot.id,
} as CreateAvailabilityDto;

export const mockTimeSlotsJoined = [
{
start: new Date('2022-01-01T09:00:00'),
end: new Date('2022-01-01T10:00:00'),
id: 1,
recruitmentSession: 3,
availabilities: [
{
state: AvailabilityState.Interviewing,
user: {
role: Role.None,
is_board: false,
is_expert: true,
},
},
{
state: AvailabilityState.Free,
user: {
role: Role.Member,
is_board: true,
is_expert: false,
},
},
{
state: AvailabilityState.Free,
user: {
role: Role.Applicant,
is_board: false,
is_expert: false,
},
},
{
state: AvailabilityState.Free,
user: {
role: Role.Member,
is_board: false,
is_expert: true,
},
},
{
state: AvailabilityState.Interviewing,
user: {
role: Role.Member,
is_board: false,
is_expert: true,
},
},
{
state: AvailabilityState.Interviewing,
user: {
role: Role.Admin,
is_board: false,
is_expert: true,
},
},
],
},
{
start: new Date('2022-01-01T9:00:00'),
end: new Date('2022-01-01T20:00:00'),
id: 2,
recruitmentSession: 3,
availabilities: [
{
state: AvailabilityState.Free,
user: {
role: Role.Member,
is_board: true,
is_expert: true,
},
},
],
},
];
Loading