Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
87 changes: 87 additions & 0 deletions cypress/e2e/requirement-set.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
describe('Requirement Set Management', () => {
beforeEach(() => {
// Login and navigate to the requirement management page
cy.login('admin', 'password');
cy.visit('/admin/requirement-sets');
});

it('should list all requirement sets', () => {
cy.intercept('GET', '/api/requirementset', {
fixture: 'requirementSets.json'
}).as('getRequirementSets');

cy.wait('@getRequirementSets');
cy.get('[data-testid=requirement-set-list]').should('be.visible');
cy.get('[data-testid=requirement-set-item]').should('have.length.at.least', 1);
});

it('should create a new requirement set', () => {
const newRequirementSet = {
requirementSetGroupId: 1,
name: 'Test Requirement Set',
description: 'Test Description',
unitId: '1',
requirementId: 1
};

cy.intercept('POST', '/api/requirementset', {
statusCode: 201,
body: { id: '123', ...newRequirementSet }
}).as('createRequirementSet');

cy.get('[data-testid=add-requirement-set-btn]').click();
cy.get('[data-testid=requirement-set-name-input]').type(newRequirementSet.name);
cy.get('[data-testid=requirement-set-description-input]').type(newRequirementSet.description);
cy.get('[data-testid=requirement-set-group-select]').select(newRequirementSet.requirementSetGroupId.toString());
cy.get('[data-testid=requirement-set-unit-select]').select(newRequirementSet.unitId);
cy.get('[data-testid=requirement-set-requirement-select]').select(newRequirementSet.requirementId.toString());
cy.get('[data-testid=save-requirement-set-btn]').click();

cy.wait('@createRequirementSet');
cy.get('[data-testid=requirement-set-item]').should('contain', newRequirementSet.name);
});

it('should update an existing requirement set', () => {
const updatedDescription = 'Updated Description';

cy.intercept('PUT', '/api/requirementset', {
statusCode: 200,
body: { description: updatedDescription }
}).as('updateRequirementSet');

cy.get('[data-testid=requirement-set-item]').first().click();
cy.get('[data-testid=edit-requirement-set-btn]').click();
cy.get('[data-testid=requirement-set-description-input]').clear().type(updatedDescription);
cy.get('[data-testid=save-requirement-set-btn]').click();

cy.wait('@updateRequirementSet');
cy.get('[data-testid=requirement-set-item]').first().should('contain', updatedDescription);
});

it('should handle error cases gracefully', () => {
// Test server error
cy.intercept('GET', '/api/requirementset', {
statusCode: 500,
body: { error: 'Internal Server Error' }
}).as('getRequirementSetsError');

cy.wait('@getRequirementSetsError');
cy.get('[data-testid=error-message]').should('be.visible');
cy.get('[data-testid=error-message]').should('contain', 'Error loading requirement sets');

// Test validation error
const invalidRequirementSet = {
requirementSetGroupId: 1,
name: '', // Invalid - empty name
description: 'Test Description',
unitId: '1',
requirementId: 1
};

cy.get('[data-testid=add-requirement-set-btn]').click();
cy.get('[data-testid=requirement-set-name-input]').type(invalidRequirementSet.name);
cy.get('[data-testid=save-requirement-set-btn]').click();
cy.get('[data-testid=validation-error]').should('be.visible');
cy.get('[data-testid=validation-error]').should('contain', 'Name is required');
});
});
156 changes: 156 additions & 0 deletions cypress/e2e/unit.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
describe('Unit Management', () => {
const mockUnits = [
{
code: 'COS10001',
id: 1,
name: 'Introduction to Programming',
my_role: 'Admin',
main_convenor_user_id: 2
},
{
code: 'COS20007',
id: 2,
name: 'Object Oriented Programming',
my_role: 'Admin',
main_convenor_user_id: 2
},
{
code: 'COS30046',
id: 3,
name: 'Artificial Intelligence for Games',
my_role: 'Admin',
main_convenor_user_id: 4
},
{
code: 'COS30243',
id: 4,
name: 'Game Programming',
my_role: 'Admin',
main_convenor_user_id: 4
}
];

beforeEach(() => {
// Setup and login
cy.login('admin', 'password');

// Intercept API calls
cy.intercept('GET', '/api/units', {
statusCode: 200,
body: mockUnits
}).as('getUnits');
});

describe('Unit Listing', () => {
it('should display all units', () => {
cy.visit('/admin/units');
cy.wait('@getUnits');

// Check if all units are displayed
mockUnits.forEach(unit => {
cy.get('[data-testid=unit-list]')
.should('contain', unit.code)
.and('contain', unit.name);
});
});

it('should filter units by search term', () => {
cy.visit('/admin/units');
cy.wait('@getUnits');

// Search for "Programming"
cy.get('[data-testid=unit-search-input]').type('Programming');

// Should show 3 units
cy.get('[data-testid=unit-list-item]').should('have.length', 3);
cy.get('[data-testid=unit-list]')
.should('contain', 'COS10001')
.and('contain', 'COS20007')
.and('contain', 'COS30243');
});

it('should filter units by level', () => {
cy.visit('/admin/units');
cy.wait('@getUnits');

// Select level 3 units
cy.get('[data-testid=unit-level-select]').select('3');

// Should show 2 level 3 units
cy.get('[data-testid=unit-list-item]').should('have.length', 2);
cy.get('[data-testid=unit-list]')
.should('contain', 'COS30046')
.and('contain', 'COS30243');
});
});

describe('Unit Details', () => {
it('should display unit details correctly', () => {
const testUnit = mockUnits[0];

// Intercept specific unit request
cy.intercept('GET', `/api/units/${testUnit.id}`, {
statusCode: 200,
body: testUnit
}).as('getUnit');

cy.visit(`/admin/units/${testUnit.id}`);
cy.wait('@getUnit');

// Check unit details
cy.get('[data-testid=unit-code]').should('contain', testUnit.code);
cy.get('[data-testid=unit-name]').should('contain', testUnit.name);
cy.get('[data-testid=unit-convenor]').should('contain', testUnit.main_convenor_user_id);
});
});

describe('Unit Navigation', () => {
it('should navigate between unit pages', () => {
cy.visit('/admin/units');
cy.wait('@getUnits');

// Click first unit
cy.get('[data-testid=unit-list-item]').first().click();

// Should be on unit details page
cy.url().should('include', '/admin/units/1');

// Go back to list
cy.get('[data-testid=back-to-list]').click();
cy.url().should('include', '/admin/units');
});
});

describe('Error Handling', () => {
it('should handle API errors gracefully', () => {
// Mock API error
cy.intercept('GET', '/api/units', {
statusCode: 500,
body: { error: 'Server Error' }
}).as('getUnitsError');

cy.visit('/admin/units');
cy.wait('@getUnitsError');

// Should show error message
cy.get('[data-testid=error-message]')
.should('be.visible')
.and('contain', 'Error loading units');
});

it('should handle non-existent unit', () => {
cy.intercept('GET', '/api/units/999', {
statusCode: 404,
body: { error: 'Unit not found' }
}).as('getNonExistentUnit');

cy.visit('/admin/units/999');
cy.wait('@getNonExistentUnit');

// Should show not found message
cy.get('[data-testid=not-found-message]')
.should('be.visible')
.and('contain', 'Unit not found');
});
});
});
25 changes: 25 additions & 0 deletions cypress/fixtures/requirementSets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"requirement_sets": [
{
"id": "1",
"requirement_set_group_id": 1,
"description": "Core programming skills",
"unit_id": 1,
"requirement_id": 1
},
{
"id": "2",
"requirement_set_group_id": 1,
"description": "Advanced programming concepts",
"unit_id": 1,
"requirement_id": 2
},
{
"id": "3",
"requirement_set_group_id": 2,
"description": "Database fundamentals",
"unit_id": 2,
"requirement_id": 3
}
]
}
32 changes: 32 additions & 0 deletions cypress/fixtures/units.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"units": [
{
"code": "COS10001",
"id": 1,
"name": "Introduction to Programming",
"my_role": "Admin",
"main_convenor_user_id": 2
},
{
"code": "COS20007",
"id": 2,
"name": "Object Oriented Programming",
"my_role": "Admin",
"main_convenor_user_id": 2
},
{
"code": "COS30046",
"id": 3,
"name": "Artificial Intelligence for Games",
"my_role": "Admin",
"main_convenor_user_id": 4
},
{
"code": "COS30243",
"id": 4,
"name": "Game Programming",
"my_role": "Admin",
"main_convenor_user_id": 4
}
]
}
Loading