Introduce prettier

This commit is contained in:
Takeshi Kimata
2024-05-19 21:04:45 +09:00
parent cbb5993276
commit 75eeebefda
89 changed files with 872 additions and 944 deletions

7
.prettierrc Normal file
View File

@@ -0,0 +1,7 @@
{
"printWidth": 120,
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "es5",
"endOfLine": "auto"
}

7
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"prettier.useEditorConfig": false,
"prettier.useTabs": false,
"prettier.configPath": ".prettierrc"
}

View File

@@ -1,14 +1,14 @@
const express = require("express"); const express = require('express');
const path = require('path'); const path = require('path');
const { Sequelize } = require("sequelize"); const { Sequelize } = require('sequelize');
const app = express(); const app = express();
// enable frontend access // enable frontend access
const cors = require("cors"); const cors = require('cors');
const frontendOrigin = process.env.FRONTEND_ORIGIN || 'http://localhost:3000'; const frontendOrigin = process.env.FRONTEND_ORIGIN || 'http://localhost:3000';
const corsOptions = { const corsOptions = {
origin: frontendOrigin, origin: frontendOrigin,
methods: "GET,HEAD,PUT,PATCH,POST,DELETE", methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
}; };
app.use(cors(corsOptions)); app.use(cors(corsOptions));
@@ -16,103 +16,103 @@ app.use(cors(corsOptions));
app.use(express.json()); app.use(express.json());
// Specify the directory to serve static files // Specify the directory to serve static files
app.use(express.static(path.join(__dirname, "public"))); app.use(express.static(path.join(__dirname, 'public')));
// init sequalize // init sequalize
const sequelize = new Sequelize({ const sequelize = new Sequelize({
dialect: "sqlite", dialect: 'sqlite',
storage: "database.sqlite", storage: 'database.sqlite',
}); });
// "/" // "/"
const indexRoute = require("./routes/index"); const indexRoute = require('./routes/index');
app.use("/", indexRoute); app.use('/', indexRoute);
// "auth" // "auth"
const signUpRoute = require("./routes/auth/signup")(sequelize); const signUpRoute = require('./routes/auth/signup')(sequelize);
const signInRoute = require("./routes/auth/signin")(sequelize); const signInRoute = require('./routes/auth/signin')(sequelize);
app.use("/auth", signUpRoute); app.use('/auth', signUpRoute);
app.use("/auth", signInRoute); app.use('/auth', signInRoute);
// "/projects" // "/projects"
const projectsIndexRoute = require("./routes/projects/index")(sequelize); const projectsIndexRoute = require('./routes/projects/index')(sequelize);
const projectsShowRoute = require("./routes/projects/show")(sequelize); const projectsShowRoute = require('./routes/projects/show')(sequelize);
const projectsNewRoute = require("./routes/projects/new")(sequelize); const projectsNewRoute = require('./routes/projects/new')(sequelize);
const projectsEditRoute = require("./routes/projects/edit")(sequelize); const projectsEditRoute = require('./routes/projects/edit')(sequelize);
const projectsDeleteRoute = require("./routes/projects/delete")(sequelize); const projectsDeleteRoute = require('./routes/projects/delete')(sequelize);
app.use("/projects", projectsIndexRoute); app.use('/projects', projectsIndexRoute);
app.use("/projects", projectsShowRoute); app.use('/projects', projectsShowRoute);
app.use("/projects", projectsNewRoute); app.use('/projects', projectsNewRoute);
app.use("/projects", projectsEditRoute); app.use('/projects', projectsEditRoute);
app.use("/projects", projectsDeleteRoute); app.use('/projects', projectsDeleteRoute);
// "/folders" // "/folders"
const foldersIndexRoute = require("./routes/folders/index")(sequelize); const foldersIndexRoute = require('./routes/folders/index')(sequelize);
const foldersNewRoute = require("./routes/folders/new")(sequelize); const foldersNewRoute = require('./routes/folders/new')(sequelize);
const foldersEditRoute = require("./routes/folders/edit")(sequelize); const foldersEditRoute = require('./routes/folders/edit')(sequelize);
const foldersDeleteRoute = require("./routes/folders/delete")(sequelize); const foldersDeleteRoute = require('./routes/folders/delete')(sequelize);
app.use("/folders", foldersIndexRoute); app.use('/folders', foldersIndexRoute);
app.use("/folders", foldersNewRoute); app.use('/folders', foldersNewRoute);
app.use("/folders", foldersEditRoute); app.use('/folders', foldersEditRoute);
app.use("/folders", foldersDeleteRoute); app.use('/folders', foldersDeleteRoute);
// "/cases" // "/cases"
const casesIndexRoute = require("./routes/cases/index")(sequelize); const casesIndexRoute = require('./routes/cases/index')(sequelize);
const casesShowRoute = require("./routes/cases/show")(sequelize); const casesShowRoute = require('./routes/cases/show')(sequelize);
const casesNewRoute = require("./routes/cases/new")(sequelize); const casesNewRoute = require('./routes/cases/new')(sequelize);
const casesEditRoute = require("./routes/cases/edit")(sequelize); const casesEditRoute = require('./routes/cases/edit')(sequelize);
const casesDeleteRoute = require("./routes/cases/delete")(sequelize); const casesDeleteRoute = require('./routes/cases/delete')(sequelize);
const casesBulkDeleteRoute = require("./routes/cases/bulkDelete")(sequelize); const casesBulkDeleteRoute = require('./routes/cases/bulkDelete')(sequelize);
app.use("/cases", casesIndexRoute); app.use('/cases', casesIndexRoute);
app.use("/cases", casesShowRoute); app.use('/cases', casesShowRoute);
app.use("/cases", casesNewRoute); app.use('/cases', casesNewRoute);
app.use("/cases", casesEditRoute); app.use('/cases', casesEditRoute);
app.use("/cases", casesDeleteRoute); app.use('/cases', casesDeleteRoute);
app.use("/cases", casesBulkDeleteRoute); app.use('/cases', casesBulkDeleteRoute);
// "/steps" // "/steps"
const stepsNewRoute = require("./routes/steps/new")(sequelize); const stepsNewRoute = require('./routes/steps/new')(sequelize);
const stepsDeleteRoute = require("./routes/steps/delete")(sequelize); const stepsDeleteRoute = require('./routes/steps/delete')(sequelize);
app.use("/steps", stepsNewRoute); app.use('/steps', stepsNewRoute);
app.use("/steps", stepsDeleteRoute); app.use('/steps', stepsDeleteRoute);
// "/attachments" // "/attachments"
const attachmentsNewRoute = require("./routes/attachments/new")(sequelize); const attachmentsNewRoute = require('./routes/attachments/new')(sequelize);
const attachmentsDeleteRoute = require("./routes/attachments/delete")(sequelize); const attachmentsDeleteRoute = require('./routes/attachments/delete')(sequelize);
const attachmentsDownloadRoute = require("./routes/attachments/download")(sequelize); const attachmentsDownloadRoute = require('./routes/attachments/download')(sequelize);
app.use("/attachments", attachmentsNewRoute); app.use('/attachments', attachmentsNewRoute);
app.use("/attachments", attachmentsDeleteRoute); app.use('/attachments', attachmentsDeleteRoute);
app.use("/attachments", attachmentsDownloadRoute); app.use('/attachments', attachmentsDownloadRoute);
// "/runs" // "/runs"
const runsIndexRoute = require("./routes/runs/index")(sequelize); const runsIndexRoute = require('./routes/runs/index')(sequelize);
const runsShowRoute = require("./routes/runs/show")(sequelize); const runsShowRoute = require('./routes/runs/show')(sequelize);
const runsNewRoute = require("./routes/runs/new")(sequelize); const runsNewRoute = require('./routes/runs/new')(sequelize);
const runsEditRoute = require("./routes/runs/edit")(sequelize); const runsEditRoute = require('./routes/runs/edit')(sequelize);
const runDeleteRoute = require("./routes/runs/delete")(sequelize); const runDeleteRoute = require('./routes/runs/delete')(sequelize);
app.use("/runs", runsIndexRoute); app.use('/runs', runsIndexRoute);
app.use("/runs", runsShowRoute); app.use('/runs', runsShowRoute);
app.use("/runs", runsNewRoute); app.use('/runs', runsNewRoute);
app.use("/runs", runsEditRoute); app.use('/runs', runsEditRoute);
app.use("/runs", runDeleteRoute); app.use('/runs', runDeleteRoute);
// "/runcases" // "/runcases"
const runCaseIndexRoute = require("./routes/runcases/index")(sequelize); const runCaseIndexRoute = require('./routes/runcases/index')(sequelize);
const runCaseNewRoute = require("./routes/runcases/new")(sequelize); const runCaseNewRoute = require('./routes/runcases/new')(sequelize);
const runCaseEditRoute = require("./routes/runcases/edit")(sequelize); const runCaseEditRoute = require('./routes/runcases/edit')(sequelize);
const runCaseBuldNewRoute = require("./routes/runcases/bulkNew")(sequelize); const runCaseBuldNewRoute = require('./routes/runcases/bulkNew')(sequelize);
const runCaseDeleteRoute = require("./routes/runcases/delete")(sequelize); const runCaseDeleteRoute = require('./routes/runcases/delete')(sequelize);
const runCaseBulkDeleteRoute = require("./routes/runcases/bulkDelete")(sequelize); const runCaseBulkDeleteRoute = require('./routes/runcases/bulkDelete')(sequelize);
app.use("/runcases", runCaseIndexRoute); app.use('/runcases', runCaseIndexRoute);
app.use("/runcases", runCaseNewRoute); app.use('/runcases', runCaseNewRoute);
app.use("/runcases", runCaseEditRoute); app.use('/runcases', runCaseEditRoute);
app.use("/runcases", runCaseBuldNewRoute); app.use('/runcases', runCaseBuldNewRoute);
app.use("/runcases", runCaseDeleteRoute); app.use('/runcases', runCaseDeleteRoute);
app.use("/runcases", runCaseBulkDeleteRoute); app.use('/runcases', runCaseBulkDeleteRoute);
// "/home" // "/home"
const homeIndexRoute = require("./routes/home/index")(sequelize); const homeIndexRoute = require('./routes/home/index')(sequelize);
app.use("/home", homeIndexRoute); app.use('/home', homeIndexRoute);
const PORT = process.env.PORT || 3001; const PORT = process.env.PORT || 3001;
app.listen(PORT, () => { app.listen(PORT, () => {

View File

@@ -44,5 +44,5 @@ module.exports = {
async down(queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.dropTable('folders'); await queryInterface.dropTable('folders');
} },
}; };

View File

@@ -37,16 +37,16 @@ module.exports = {
}, },
createdAt: { createdAt: {
allowNull: false, allowNull: false,
type: Sequelize.DATE type: Sequelize.DATE,
}, },
updatedAt: { updatedAt: {
allowNull: false, allowNull: false,
type: Sequelize.DATE type: Sequelize.DATE,
} },
}); });
}, },
async down(queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.dropTable('runs'); await queryInterface.dropTable('runs');
} },
}; };

View File

@@ -57,16 +57,16 @@ module.exports = {
}, },
createdAt: { createdAt: {
allowNull: false, allowNull: false,
type: Sequelize.DATE type: Sequelize.DATE,
}, },
updatedAt: { updatedAt: {
allowNull: false, allowNull: false,
type: Sequelize.DATE type: Sequelize.DATE,
} },
}); });
}, },
async down(queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.dropTable('cases'); await queryInterface.dropTable('cases');
} },
}; };

View File

@@ -1,9 +1,9 @@
"use strict"; 'use strict';
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.createTable("caseSteps", { await queryInterface.createTable('caseSteps', {
id: { id: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
primaryKey: true, primaryKey: true,
@@ -12,20 +12,20 @@ module.exports = {
caseId: { caseId: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
references: { references: {
model: "cases", model: 'cases',
key: "id", key: 'id',
}, },
onUpdate: "CASCADE", onUpdate: 'CASCADE',
onDelete: "CASCADE", onDelete: 'CASCADE',
}, },
stepId: { stepId: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
references: { references: {
model: "steps", model: 'steps',
key: "id", key: 'id',
}, },
onUpdate: "CASCADE", onUpdate: 'CASCADE',
onDelete: "CASCADE", onDelete: 'CASCADE',
}, },
stepNo: { stepNo: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
@@ -41,12 +41,12 @@ module.exports = {
}, },
}); });
await queryInterface.addIndex("caseSteps", ["caseId", "stepId"], { await queryInterface.addIndex('caseSteps', ['caseId', 'stepId'], {
unique: true, unique: true,
}); });
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable("caseSteps"); await queryInterface.dropTable('caseSteps');
}, },
}; };

View File

@@ -23,16 +23,16 @@ module.exports = {
}, },
createdAt: { createdAt: {
allowNull: false, allowNull: false,
type: Sequelize.DATE type: Sequelize.DATE,
}, },
updatedAt: { updatedAt: {
allowNull: false, allowNull: false,
type: Sequelize.DATE type: Sequelize.DATE,
} },
}); });
}, },
async down(queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.dropTable('attachments'); await queryInterface.dropTable('attachments');
} },
}; };

View File

@@ -1,9 +1,9 @@
"use strict"; 'use strict';
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.createTable("caseAttachments", { await queryInterface.createTable('caseAttachments', {
id: { id: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
primaryKey: true, primaryKey: true,
@@ -12,20 +12,20 @@ module.exports = {
caseId: { caseId: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
references: { references: {
model: "cases", model: 'cases',
key: "id", key: 'id',
}, },
onUpdate: "CASCADE", onUpdate: 'CASCADE',
onDelete: "CASCADE", onDelete: 'CASCADE',
}, },
attachmentId: { attachmentId: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
references: { references: {
model: "attachments", model: 'attachments',
key: "id", key: 'id',
}, },
onUpdate: "CASCADE", onUpdate: 'CASCADE',
onDelete: "CASCADE", onDelete: 'CASCADE',
}, },
createdAt: { createdAt: {
type: Sequelize.DATE, type: Sequelize.DATE,
@@ -37,12 +37,12 @@ module.exports = {
}, },
}); });
await queryInterface.addIndex("caseAttachments", ["caseId", "attachmentId"], { await queryInterface.addIndex('caseAttachments', ['caseId', 'attachmentId'], {
unique: true, unique: true,
}); });
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable("caseAttachments"); await queryInterface.dropTable('caseAttachments');
}, },
}; };

View File

@@ -1,9 +1,9 @@
"use strict"; 'use strict';
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.createTable("runCases", { await queryInterface.createTable('runCases', {
id: { id: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
primaryKey: true, primaryKey: true,
@@ -12,20 +12,20 @@ module.exports = {
runId: { runId: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
references: { references: {
model: "runs", model: 'runs',
key: "id", key: 'id',
}, },
onUpdate: "CASCADE", onUpdate: 'CASCADE',
onDelete: "CASCADE", onDelete: 'CASCADE',
}, },
caseId: { caseId: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
references: { references: {
model: "cases", model: 'cases',
key: "id", key: 'id',
}, },
onUpdate: "CASCADE", onUpdate: 'CASCADE',
onDelete: "CASCADE", onDelete: 'CASCADE',
}, },
status: { status: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
@@ -41,12 +41,12 @@ module.exports = {
}, },
}); });
await queryInterface.addIndex("runCases", ["runId", "caseId"], { await queryInterface.addIndex('runCases', ['runId', 'caseId'], {
unique: true, unique: true,
}); });
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable("runCases"); await queryInterface.dropTable('runCases');
}, },
}; };

View File

@@ -1,9 +1,9 @@
"use strict"; 'use strict';
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.createTable("users", { await queryInterface.createTable('users', {
id: { id: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
primaryKey: true, primaryKey: true,
@@ -12,7 +12,7 @@ module.exports = {
email: { email: {
type: Sequelize.STRING, type: Sequelize.STRING,
allowNull: false, allowNull: false,
unique: true unique: true,
}, },
password: { password: {
type: Sequelize.STRING, type: Sequelize.STRING,
@@ -41,6 +41,6 @@ module.exports = {
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable("users"); await queryInterface.dropTable('users');
}, },
}; };

View File

@@ -1,5 +1,5 @@
function defineAttachment(sequelize, DataTypes) { function defineAttachment(sequelize, DataTypes) {
const Attachment = sequelize.define("Attachment", { const Attachment = sequelize.define('Attachment', {
title: { title: {
type: DataTypes.STRING, type: DataTypes.STRING,
allowNull: false, allowNull: false,
@@ -16,7 +16,7 @@ function defineAttachment(sequelize, DataTypes) {
Attachment.associate = (models) => { Attachment.associate = (models) => {
Attachment.belongsToMany(models.Case, { Attachment.belongsToMany(models.Case, {
through: "caseAttachments" through: 'caseAttachments',
}); });
}; };

View File

@@ -1,5 +1,5 @@
function defineCaseAttachment(sequelize, DataTypes) { function defineCaseAttachment(sequelize, DataTypes) {
const CaseAttachment = sequelize.define("CaseAttachment", { const CaseAttachment = sequelize.define('CaseAttachment', {
caseId: { caseId: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
allowNull: false, allowNull: false,
@@ -12,12 +12,12 @@ function defineCaseAttachment(sequelize, DataTypes) {
CaseAttachment.associate = (models) => { CaseAttachment.associate = (models) => {
CaseAttachment.belongsTo(models.Case, { CaseAttachment.belongsTo(models.Case, {
foreignKey: "caseId", foreignKey: 'caseId',
onDelete: "CASCADE", onDelete: 'CASCADE',
}); });
CaseAttachment.belongsTo(models.Attachment, { CaseAttachment.belongsTo(models.Attachment, {
foreignKey: "attachmentId", foreignKey: 'attachmentId',
onDelete: "CASCADE", onDelete: 'CASCADE',
}); });
}; };

View File

@@ -1,5 +1,5 @@
function defineCaseStep(sequelize, DataTypes) { function defineCaseStep(sequelize, DataTypes) {
const CaseStep = sequelize.define("CaseStep", { const CaseStep = sequelize.define('CaseStep', {
caseId: { caseId: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
allowNull: false, allowNull: false,
@@ -16,12 +16,12 @@ function defineCaseStep(sequelize, DataTypes) {
CaseStep.associate = (models) => { CaseStep.associate = (models) => {
CaseStep.belongsTo(models.Case, { CaseStep.belongsTo(models.Case, {
foreignKey: "caseId", foreignKey: 'caseId',
onDelete: "CASCADE", onDelete: 'CASCADE',
}); });
CaseStep.belongsTo(models.Step, { CaseStep.belongsTo(models.Step, {
foreignKey: "stepId", foreignKey: 'stepId',
onDelete: "CASCADE", onDelete: 'CASCADE',
}); });
}; };

View File

@@ -1,5 +1,5 @@
function defineCase(sequelize, DataTypes) { function defineCase(sequelize, DataTypes) {
const Case = sequelize.define("Case", { const Case = sequelize.define('Case', {
title: { title: {
type: DataTypes.STRING, type: DataTypes.STRING,
allowNull: false, allowNull: false,
@@ -40,20 +40,20 @@ function defineCase(sequelize, DataTypes) {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
allowNull: false, allowNull: false,
references: { references: {
model: "folder", model: 'folder',
key: "id", key: 'id',
}, },
onDelete: "CASCADE", onDelete: 'CASCADE',
}, },
}); });
Case.associate = (models) => { Case.associate = (models) => {
Case.belongsTo(models.Folder, { Case.belongsTo(models.Folder, {
foreignKey: "folderId", foreignKey: 'folderId',
onDelete: "CASCADE", onDelete: 'CASCADE',
}); });
Case.belongsToMany(models.Step, { Case.belongsToMany(models.Step, {
through: "caseSteps" through: 'caseSteps',
}); });
}; };

View File

@@ -1,5 +1,5 @@
function defineFolder(sequelize, DataTypes) { function defineFolder(sequelize, DataTypes) {
const Folder = sequelize.define("Folder", { const Folder = sequelize.define('Folder', {
name: { name: {
type: DataTypes.STRING, type: DataTypes.STRING,
allowNull: false, allowNull: false,
@@ -17,10 +17,10 @@ function defineFolder(sequelize, DataTypes) {
allowNull: false, allowNull: false,
references: { references: {
model: 'project', model: 'project',
key: 'id' key: 'id',
},
onDelete: 'CASCADE',
}, },
onDelete: 'CASCADE'
}
}); });
Folder.associate = (models) => { Folder.associate = (models) => {

View File

@@ -1,40 +1,27 @@
"use strict"; 'use strict';
const fs = require("fs"); const fs = require('fs');
const path = require("path"); const path = require('path');
const Sequelize = require("sequelize"); const Sequelize = require('sequelize');
const process = require("process"); const process = require('process');
const basename = path.basename(__filename); const basename = path.basename(__filename);
const env = process.env.NODE_ENV || "development"; const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + "/../config/config.json")[env]; const config = require(__dirname + '/../config/config.json')[env];
const db = {}; const db = {};
let sequelize; let sequelize;
if (config.use_env_variable) { if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable], config); sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else { } else {
sequelize = new Sequelize( sequelize = new Sequelize(config.database, config.username, config.password, config);
config.database,
config.username,
config.password,
config
);
} }
fs.readdirSync(__dirname) fs.readdirSync(__dirname)
.filter((file) => { .filter((file) => {
return ( return file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js' && file.indexOf('.test.js') === -1;
file.indexOf(".") !== 0 &&
file !== basename &&
file.slice(-3) === ".js" &&
file.indexOf(".test.js") === -1
);
}) })
.forEach((file) => { .forEach((file) => {
const model = require(path.join(__dirname, file))( const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
sequelize,
Sequelize.DataTypes
);
db[model.name] = model; db[model.name] = model;
}); });

View File

@@ -1,5 +1,5 @@
function defineProject(sequelize, DataTypes) { function defineProject(sequelize, DataTypes) {
const Project = sequelize.define("Project", { const Project = sequelize.define('Project', {
name: { name: {
type: DataTypes.STRING, type: DataTypes.STRING,
allowNull: false, allowNull: false,
@@ -11,7 +11,7 @@ function defineProject(sequelize, DataTypes) {
}); });
Project.associate = (models) => { Project.associate = (models) => {
Project.hasMany(models.Folder, { foreignKey: "projectId" }); Project.hasMany(models.Folder, { foreignKey: 'projectId' });
}; };
return Project; return Project;

View File

@@ -1,5 +1,5 @@
function defineRunCase(sequelize, DataTypes) { function defineRunCase(sequelize, DataTypes) {
const RunCase = sequelize.define("RunCase", { const RunCase = sequelize.define('RunCase', {
runId: { runId: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
allowNull: false, allowNull: false,
@@ -16,12 +16,12 @@ function defineRunCase(sequelize, DataTypes) {
RunCase.associate = (models) => { RunCase.associate = (models) => {
RunCase.belongsTo(models.Run, { RunCase.belongsTo(models.Run, {
foreignKey: "runId", foreignKey: 'runId',
onDelete: "CASCADE", onDelete: 'CASCADE',
}); });
RunCase.belongsTo(models.Case, { RunCase.belongsTo(models.Case, {
foreignKey: "caseId", foreignKey: 'caseId',
onDelete: "CASCADE", onDelete: 'CASCADE',
}); });
}; };

View File

@@ -21,10 +21,10 @@ function defineRun(sequelize, DataTypes) {
allowNull: false, allowNull: false,
references: { references: {
model: 'project', model: 'project',
key: 'id' key: 'id',
},
onDelete: 'CASCADE',
}, },
onDelete: 'CASCADE'
}
}); });
Run.associate = (models) => { Run.associate = (models) => {

View File

@@ -1,5 +1,5 @@
function defineStep(sequelize, DataTypes) { function defineStep(sequelize, DataTypes) {
const Step = sequelize.define("Step", { const Step = sequelize.define('Step', {
step: { step: {
type: DataTypes.STRING, type: DataTypes.STRING,
allowNull: false, allowNull: false,
@@ -12,7 +12,7 @@ function defineStep(sequelize, DataTypes) {
Step.associate = (models) => { Step.associate = (models) => {
Step.belongsToMany(models.Case, { Step.belongsToMany(models.Case, {
through: "caseSteps" through: 'caseSteps',
}); });
}; };

View File

@@ -1,5 +1,5 @@
function defineUser(sequelize, DataTypes) { function defineUser(sequelize, DataTypes) {
const User = sequelize.define("User", { const User = sequelize.define('User', {
email: { email: {
type: DataTypes.STRING, type: DataTypes.STRING,
allowNull: false, allowNull: false,

View File

@@ -1,14 +1,14 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const path = require("path"); const path = require('path');
const fs = require("fs"); const fs = require('fs');
const defineAttachment = require("../../models/attachments"); const defineAttachment = require('../../models/attachments');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Attachment = defineAttachment(sequelize, DataTypes); const Attachment = defineAttachment(sequelize, DataTypes);
router.delete("/:attachmentId", async (req, res) => { router.delete('/:attachmentId', async (req, res) => {
const attachmentId = req.params.attachmentId; const attachmentId = req.params.attachmentId;
const t = await sequelize.transaction(); const t = await sequelize.transaction();
@@ -16,19 +16,19 @@ module.exports = function (sequelize) {
const attachment = await Attachment.findByPk(attachmentId); const attachment = await Attachment.findByPk(attachmentId);
if (!attachment) { if (!attachment) {
await t.rollback(); await t.rollback();
return res.status(404).send("Attachment not found"); return res.status(404).send('Attachment not found');
} }
// delete file from folder // delete file from folder
const uploadDir = path.join(__dirname, "../../public/uploads"); const uploadDir = path.join(__dirname, '../../public/uploads');
const url = attachment.path; const url = attachment.path;
const fileName = url.substring(url.lastIndexOf("/") + 1); const fileName = url.substring(url.lastIndexOf('/') + 1);
const filePath = path.join(uploadDir, fileName); const filePath = path.join(uploadDir, fileName);
fs.unlink(filePath, (err) => { fs.unlink(filePath, (err) => {
if (err) { if (err) {
console.error('Error deleting file:', err); console.error('Error deleting file:', err);
t.rollback(); t.rollback();
return res.status(404).send("Attachment not found"); return res.status(404).send('Attachment not found');
} }
}); });
@@ -38,7 +38,7 @@ module.exports = function (sequelize) {
} catch (error) { } catch (error) {
console.error(error); console.error(error);
await t.rollback(); await t.rollback();
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,32 +1,32 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const path = require("path"); const path = require('path');
const fs = require("fs"); const fs = require('fs');
const defineAttachment = require("../../models/attachments"); const defineAttachment = require('../../models/attachments');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Attachment = defineAttachment(sequelize, DataTypes); const Attachment = defineAttachment(sequelize, DataTypes);
router.get("/download/:attachmentId", async (req, res) => { router.get('/download/:attachmentId', async (req, res) => {
const attachmentId = req.params.attachmentId; const attachmentId = req.params.attachmentId;
try { try {
const attachment = await Attachment.findByPk(attachmentId); const attachment = await Attachment.findByPk(attachmentId);
if (!attachment) { if (!attachment) {
return res.status(404).send("Attachment not found"); return res.status(404).send('Attachment not found');
} }
const filename = attachment.path.split("/").pop(); const filename = attachment.path.split('/').pop();
const filePath = path.join(__dirname, `../../public/uploads/${filename}`); const filePath = path.join(__dirname, `../../public/uploads/${filename}`);
if (!fs.existsSync(filePath)) { if (!fs.existsSync(filePath)) {
return res.status(404).json({ error: "File not found" }); return res.status(404).json({ error: 'File not found' });
} }
res.download(filePath); res.download(filePath);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,18 +1,18 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const path = require("path"); const path = require('path');
const fs = require("fs"); const fs = require('fs');
const multer = require("multer"); const multer = require('multer');
const defineAttachment = require("../../models/attachments"); const defineAttachment = require('../../models/attachments');
const defineCaseAttachment = require("../../models/caseAttachments"); const defineCaseAttachment = require('../../models/caseAttachments');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Attachment = defineAttachment(sequelize, DataTypes); const Attachment = defineAttachment(sequelize, DataTypes);
const CaseAttachment = defineCaseAttachment(sequelize, DataTypes); const CaseAttachment = defineCaseAttachment(sequelize, DataTypes);
// Create uploads folder if it does not exist // Create uploads folder if it does not exist
const uploadDir = path.join(__dirname, "../../public/uploads"); const uploadDir = path.join(__dirname, '../../public/uploads');
if (!fs.existsSync(uploadDir)) { if (!fs.existsSync(uploadDir)) {
fs.mkdirSync(uploadDir, { recursive: true }); fs.mkdirSync(uploadDir, { recursive: true });
} }
@@ -46,16 +46,16 @@ module.exports = function (sequelize) {
const upload = multer({ storage }); const upload = multer({ storage });
router.post("/", upload.array("files", 10), async (req, res) => { router.post('/', upload.array('files', 10), async (req, res) => {
const t = await sequelize.transaction(); const t = await sequelize.transaction();
try { try {
const caseId = req.query.parentCaseId; const caseId = req.query.parentCaseId;
const files = req.files; const files = req.files;
if (files.length === 0) { if (files.length === 0) {
return res.status(400).json({ error: "No files uploaded" }); return res.status(400).json({ error: 'No files uploaded' });
} }
const host = req.get("host"); const host = req.get('host');
const protocol = req.protocol; const protocol = req.protocol;
const attachmentsData = files.map((file) => ({ const attachmentsData = files.map((file) => ({
title: file.originalname, title: file.originalname,
@@ -75,7 +75,7 @@ module.exports = function (sequelize) {
res.json(newAttachments); res.json(newAttachments);
} catch (error) { } catch (error) {
await t.rollback(); await t.rollback();
res.status(500).json({ error: "Internal server error" }); res.status(500).json({ error: 'Internal server error' });
} }
}); });

View File

@@ -1,2 +1,2 @@
const roles = [{ uid: "admin" }, { uid: "moderator" }, { uid: "user" }]; const roles = [{ uid: 'admin' }, { uid: 'moderator' }, { uid: 'user' }];
module.exports = roles; module.exports = roles;

View File

@@ -1,14 +1,14 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineUser = require("../../models/users"); const defineUser = require('../../models/users');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
const bcrypt = require('bcrypt'); const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const User = defineUser(sequelize, DataTypes); const User = defineUser(sequelize, DataTypes);
router.post("/signin", async (req, res) => { router.post('/signin', async (req, res) => {
try { try {
const { email, password } = req.body; const { email, password } = req.body;
const user = await User.findOne({ const user = await User.findOne({
@@ -17,20 +17,20 @@ module.exports = function (sequelize) {
}, },
}); });
if (!user) { if (!user) {
return res.status(401).json({ error: "Authentication failed" }); return res.status(401).json({ error: 'Authentication failed' });
} }
const passwordMatch = await bcrypt.compare(password, user.password); const passwordMatch = await bcrypt.compare(password, user.password);
if (!passwordMatch) { if (!passwordMatch) {
return res.status(401).json({ error: "Authentication failed" }); return res.status(401).json({ error: 'Authentication failed' });
} }
const accessToken = jwt.sign({ userId: user.id }, "your-secret-key", { const accessToken = jwt.sign({ userId: user.id }, 'your-secret-key', {
expiresIn: "1h", expiresIn: '1h',
}); });
res.status(200).json({ access_token: accessToken, user }); res.status(200).json({ access_token: accessToken, user });
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Sign up failed"); res.status(500).send('Sign up failed');
} }
}); });

View File

@@ -1,15 +1,15 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineUser = require("../../models/users"); const defineUser = require('../../models/users');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
const roles = require("./roles"); const roles = require('./roles');
const bcrypt = require("bcrypt"); const bcrypt = require('bcrypt');
const jwt = require("jsonwebtoken"); const jwt = require('jsonwebtoken');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const User = defineUser(sequelize, DataTypes); const User = defineUser(sequelize, DataTypes);
router.post("/signup", async (req, res) => { router.post('/signup', async (req, res) => {
try { try {
const { email, password, username, avatarPath } = req.body; const { email, password, username, avatarPath } = req.body;
const hashedPassword = await bcrypt.hash(password, 10); const hashedPassword = await bcrypt.hash(password, 10);
@@ -17,8 +17,8 @@ module.exports = function (sequelize) {
const userCount = await User.count(); const userCount = await User.count();
const initialRole = const initialRole =
userCount > 0 userCount > 0
? roles.findIndex((entry) => entry.uid === "user") ? roles.findIndex((entry) => entry.uid === 'user')
: roles.findIndex((entry) => entry.uid === "admin"); : roles.findIndex((entry) => entry.uid === 'admin');
const user = await User.create({ const user = await User.create({
email, email,
@@ -28,15 +28,15 @@ module.exports = function (sequelize) {
avatarPath: avatarPath, avatarPath: avatarPath,
}); });
const accessToken = jwt.sign({ userId: user.id }, "your-secret-key", { const accessToken = jwt.sign({ userId: user.id }, 'your-secret-key', {
expiresIn: "1h", expiresIn: '1h',
}); });
user.password = undefined; user.password = undefined;
res.status(200).json({ access_token: accessToken, user }); res.status(200).json({ access_token: accessToken, user });
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Sign up failed"); res.status(500).send('Sign up failed');
} }
}); });

View File

@@ -1,15 +1,15 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineCase = require("../../models/cases"); const defineCase = require('../../models/cases');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Case = defineCase(sequelize, DataTypes); const Case = defineCase(sequelize, DataTypes);
router.post("/bulkdelete", async (req, res) => { router.post('/bulkdelete', async (req, res) => {
const { caseIds } = req.body; const { caseIds } = req.body;
if (!caseIds || !Array.isArray(caseIds)) { if (!caseIds || !Array.isArray(caseIds)) {
return res.status(400).send("Invalid caseIds array"); return res.status(400).send('Invalid caseIds array');
} }
try { try {
@@ -17,7 +17,7 @@ module.exports = function (sequelize) {
res.status(204).send(); res.status(204).send();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,23 +1,23 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineCase = require("../../models/cases"); const defineCase = require('../../models/cases');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Case = defineCase(sequelize, DataTypes); const Case = defineCase(sequelize, DataTypes);
router.delete("/:caseId", async (req, res) => { router.delete('/:caseId', async (req, res) => {
const caseId = req.params.caseId; const caseId = req.params.caseId;
try { try {
const testcase = await Case.findByPk(caseId); const testcase = await Case.findByPk(caseId);
if (!testcase) { if (!testcase) {
return res.status(404).send("Case not found"); return res.status(404).send('Case not found');
} }
await testcase.destroy(); await testcase.destroy();
res.status(204).send(); res.status(204).send();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,20 +1,20 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineCase = require("../../models/cases"); const defineCase = require('../../models/cases');
const defineStep = require("../../models/steps"); const defineStep = require('../../models/steps');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Case = defineCase(sequelize, DataTypes); const Case = defineCase(sequelize, DataTypes);
const Step = defineStep(sequelize, DataTypes); const Step = defineStep(sequelize, DataTypes);
router.put("/:caseId", async (req, res) => { router.put('/:caseId', async (req, res) => {
const caseId = req.params.caseId; const caseId = req.params.caseId;
const updateCase = req.body; const updateCase = req.body;
try { try {
const testcase = await Case.findByPk(caseId); const testcase = await Case.findByPk(caseId);
if (!testcase) { if (!testcase) {
return res.status(404).send("Case not found"); return res.status(404).send('Case not found');
} }
// if Case has Steps, update Steps as well // if Case has Steps, update Steps as well
@@ -36,7 +36,7 @@ module.exports = function (sequelize) {
res.json(testcase); res.json(testcase);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,16 +1,16 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineCase = require("../../models/cases"); const defineCase = require('../../models/cases');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Case = defineCase(sequelize, DataTypes); const Case = defineCase(sequelize, DataTypes);
router.get("/", async (req, res) => { router.get('/', async (req, res) => {
const { folderId } = req.query; const { folderId } = req.query;
if (!folderId) { if (!folderId) {
return res.status(400).json({ error: "folderId is required" }); return res.status(400).json({ error: 'folderId is required' });
} }
try { try {
@@ -22,7 +22,7 @@ module.exports = function (sequelize) {
res.json(cases); res.json(cases);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,17 +1,9 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineCase = require("../../models/cases"); const defineCase = require('../../models/cases');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
const requiredFields = [ const requiredFields = ['title', 'state', 'priority', 'type', 'automationStatus', 'template', 'folderId'];
"title",
"state",
"priority",
"type",
"automationStatus",
"template",
"folderId",
];
function isEmpty(value) { function isEmpty(value) {
if (value === null || value === undefined) { if (value === null || value === undefined) {
@@ -24,7 +16,7 @@ function isEmpty(value) {
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Case = defineCase(sequelize, DataTypes); const Case = defineCase(sequelize, DataTypes);
router.post("/", async (req, res) => { router.post('/', async (req, res) => {
try { try {
if ( if (
requiredFields.some((field) => { requiredFields.some((field) => {
@@ -32,8 +24,7 @@ module.exports = function (sequelize) {
}) })
) { ) {
return res.status(400).json({ return res.status(400).json({
error: error: 'Title, state, priority, type, automationStatus, template, and folderId are required',
"Title, state, priority, type, automationStatus, template, and folderId are required",
}); });
} }
@@ -65,7 +56,7 @@ module.exports = function (sequelize) {
res.json(newCase); res.json(newCase);
} catch (error) { } catch (error) {
res.status(500).json({ error: "Internal server error" }); res.status(500).json({ error: 'Internal server error' });
} }
}); });

View File

@@ -1,24 +1,24 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineCase = require("../../models/cases"); const defineCase = require('../../models/cases');
const defineStep = require("../../models/steps"); const defineStep = require('../../models/steps');
const defineAttachment = require("../../models/attachments"); const defineAttachment = require('../../models/attachments');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Case = defineCase(sequelize, DataTypes); const Case = defineCase(sequelize, DataTypes);
const Step = defineStep(sequelize, DataTypes); const Step = defineStep(sequelize, DataTypes);
const Attachment = defineAttachment(sequelize, DataTypes); const Attachment = defineAttachment(sequelize, DataTypes);
Case.belongsToMany(Step, { through: "caseSteps" }); Case.belongsToMany(Step, { through: 'caseSteps' });
Step.belongsToMany(Case, { through: "caseSteps" }); Step.belongsToMany(Case, { through: 'caseSteps' });
Case.belongsToMany(Attachment, { through: "caseAttachments" }); Case.belongsToMany(Attachment, { through: 'caseAttachments' });
Attachment.belongsToMany(Case, { through: "caseAttachments" }); Attachment.belongsToMany(Case, { through: 'caseAttachments' });
router.get("/:caseId", async (req, res) => { router.get('/:caseId', async (req, res) => {
const caseId = req.params.caseId; const caseId = req.params.caseId;
if (!caseId) { if (!caseId) {
return res.status(400).json({ error: "caseId is required" }); return res.status(400).json({ error: 'caseId is required' });
} }
try { try {
@@ -26,7 +26,7 @@ module.exports = function (sequelize) {
include: [ include: [
{ {
model: Step, model: Step,
through: { attributes: ["stepNo"] }, through: { attributes: ['stepNo'] },
}, },
{ {
model: Attachment, model: Attachment,
@@ -36,7 +36,7 @@ module.exports = function (sequelize) {
return res.json(testcase); return res.json(testcase);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,23 +1,23 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineFolder = require("../../models/folders"); const defineFolder = require('../../models/folders');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Folder = defineFolder(sequelize, DataTypes); const Folder = defineFolder(sequelize, DataTypes);
router.delete("/:folderId", async (req, res) => { router.delete('/:folderId', async (req, res) => {
const folderId = req.params.folderId; const folderId = req.params.folderId;
try { try {
const folder = await Folder.findByPk(folderId); const folder = await Folder.findByPk(folderId);
if (!folder) { if (!folder) {
return res.status(404).send("Folder not found"); return res.status(404).send('Folder not found');
} }
await folder.destroy(); await folder.destroy();
res.status(204).send(); res.status(204).send();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,18 +1,18 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineFolder = require("../../models/folders"); const defineFolder = require('../../models/folders');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Folder = defineFolder(sequelize, DataTypes); const Folder = defineFolder(sequelize, DataTypes);
router.put("/:folderId", async (req, res) => { router.put('/:folderId', async (req, res) => {
const folderId = req.params.folderId; const folderId = req.params.folderId;
const { name, detail, projectId, parentFolderId } = req.body; const { name, detail, projectId, parentFolderId } = req.body;
try { try {
const folder = await Folder.findByPk(folderId); const folder = await Folder.findByPk(folderId);
if (!folder) { if (!folder) {
return res.status(404).send("Folder not found"); return res.status(404).send('Folder not found');
} }
await folder.update({ await folder.update({
name, name,
@@ -23,7 +23,7 @@ module.exports = function (sequelize) {
res.json(folder); res.json(folder);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,12 +1,12 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineFolder = require('../../models/folders'); const defineFolder = require('../../models/folders');
const { DataTypes } = require('sequelize'); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Folder = defineFolder(sequelize, DataTypes) const Folder = defineFolder(sequelize, DataTypes);
router.get("/", async (req, res) => { router.get('/', async (req, res) => {
const { projectId } = req.query; const { projectId } = req.query;
if (!projectId) { if (!projectId) {
@@ -16,13 +16,13 @@ module.exports = function(sequelize) {
try { try {
const folders = await Folder.findAll({ const folders = await Folder.findAll({
where: { where: {
projectId: projectId projectId: projectId,
} },
}); });
res.json(folders); res.json(folders);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,18 +1,16 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineFolder = require("../../models/folders"); const defineFolder = require('../../models/folders');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Folder = defineFolder(sequelize, DataTypes); const Folder = defineFolder(sequelize, DataTypes);
router.post("/", async (req, res) => { router.post('/', async (req, res) => {
try { try {
const { name, detail, projectId, parentFolderId } = req.body; const { name, detail, projectId, parentFolderId } = req.body;
if (!name || !projectId) { if (!name || !projectId) {
return res return res.status(400).json({ error: 'Name and projectId are required' });
.status(400)
.json({ error: "Name and projectId are required" });
} }
const newFolder = await Folder.create({ const newFolder = await Folder.create({
@@ -24,7 +22,7 @@ module.exports = function (sequelize) {
res.json(newFolder); res.json(newFolder);
} catch (error) { } catch (error) {
res.status(500).json({ error: "Internal server error" }); res.status(500).json({ error: 'Internal server error' });
} }
}); });

View File

@@ -1,11 +1,11 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineProject = require("../../models/projects"); const defineProject = require('../../models/projects');
const defineFolder = require("../../models/folders"); const defineFolder = require('../../models/folders');
const defineCase = require("../../models/cases"); const defineCase = require('../../models/cases');
const defineRun = require("../../models/runs"); const defineRun = require('../../models/runs');
const defineRunCase = require("../../models/runCases"); const defineRunCase = require('../../models/runCases');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Project = defineProject(sequelize, DataTypes); const Project = defineProject(sequelize, DataTypes);
@@ -13,16 +13,16 @@ module.exports = function (sequelize) {
const Case = defineCase(sequelize, DataTypes); const Case = defineCase(sequelize, DataTypes);
const Run = defineRun(sequelize, DataTypes); const Run = defineRun(sequelize, DataTypes);
const RunCase = defineRunCase(sequelize, DataTypes); const RunCase = defineRunCase(sequelize, DataTypes);
Project.hasMany(Folder, { foreignKey: "projectId" }); Project.hasMany(Folder, { foreignKey: 'projectId' });
Folder.hasMany(Case, { foreignKey: "folderId" }); Folder.hasMany(Case, { foreignKey: 'folderId' });
Project.hasMany(Run, { foreignKey: "projectId" }); Project.hasMany(Run, { foreignKey: 'projectId' });
Run.hasMany(RunCase, { foreignKey: "runId" }); Run.hasMany(RunCase, { foreignKey: 'runId' });
router.get("/:projectId", async (req, res) => { router.get('/:projectId', async (req, res) => {
const projectId = req.params.projectId; const projectId = req.params.projectId;
if (!projectId) { if (!projectId) {
return res.status(400).json({ error: "projectId is required" }); return res.status(400).json({ error: 'projectId is required' });
} }
try { try {
@@ -36,12 +36,12 @@ module.exports = function (sequelize) {
], ],
}); });
if (!project) { if (!project) {
return res.status(404).send("Project not found"); return res.status(404).send('Project not found');
} }
res.json(project); res.json(project);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,23 +1,23 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineProject = require("../../models/projects"); const defineProject = require('../../models/projects');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Project = defineProject(sequelize, DataTypes); const Project = defineProject(sequelize, DataTypes);
router.delete("/:projectId", async (req, res) => { router.delete('/:projectId', async (req, res) => {
const projectId = req.params.projectId; const projectId = req.params.projectId;
try { try {
const project = await Project.findByPk(projectId); const project = await Project.findByPk(projectId);
if (!project) { if (!project) {
return res.status(404).send("Project not found"); return res.status(404).send('Project not found');
} }
await project.destroy(); await project.destroy();
res.status(204).send(); res.status(204).send();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,18 +1,18 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineProject = require("../../models/projects"); const defineProject = require('../../models/projects');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Project = defineProject(sequelize, DataTypes); const Project = defineProject(sequelize, DataTypes);
router.put("/:projectId", async (req, res) => { router.put('/:projectId', async (req, res) => {
const projectId = req.params.projectId; const projectId = req.params.projectId;
const { name, detail } = req.body; const { name, detail } = req.body;
try { try {
const project = await Project.findByPk(projectId); const project = await Project.findByPk(projectId);
if (!project) { if (!project) {
return res.status(404).send("Project not found"); return res.status(404).send('Project not found');
} }
await project.update({ await project.update({
name, name,
@@ -21,7 +21,7 @@ module.exports = function (sequelize) {
res.json(project); res.json(project);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,18 +1,18 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineProject = require('../../models/projects'); const defineProject = require('../../models/projects');
const { DataTypes } = require('sequelize'); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Project = defineProject(sequelize, DataTypes) const Project = defineProject(sequelize, DataTypes);
router.get("/", async (req, res) => { router.get('/', async (req, res) => {
try { try {
const projects = await Project.findAll(); const projects = await Project.findAll();
res.json(projects); res.json(projects);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,12 +1,12 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineProject = require("../../models/projects"); const defineProject = require('../../models/projects');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Project = defineProject(sequelize, DataTypes) const Project = defineProject(sequelize, DataTypes);
router.post("/", async (req, res) => { router.post('/', async (req, res) => {
try { try {
const { name, detail } = req.body; const { name, detail } = req.body;
const newProject = await Project.create({ const newProject = await Project.create({
@@ -16,7 +16,7 @@ module.exports = function (sequelize) {
res.json(newProject); res.json(newProject);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,19 +1,19 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineProject = require("../../models/projects"); const defineProject = require('../../models/projects');
const defineFolder = require("../../models/folders"); const defineFolder = require('../../models/folders');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Project = defineProject(sequelize, DataTypes); const Project = defineProject(sequelize, DataTypes);
const Folder = defineFolder(sequelize, DataTypes); const Folder = defineFolder(sequelize, DataTypes);
Project.hasMany(Folder, { foreignKey: "projectId" }); Project.hasMany(Folder, { foreignKey: 'projectId' });
router.get("/:projectId", async (req, res) => { router.get('/:projectId', async (req, res) => {
const projectId = req.params.projectId; const projectId = req.params.projectId;
if (!projectId) { if (!projectId) {
return res.status(400).json({ error: "projectId is required" }); return res.status(400).json({ error: 'projectId is required' });
} }
try { try {
@@ -25,12 +25,12 @@ module.exports = function (sequelize) {
], ],
}); });
if (!project) { if (!project) {
return res.status(404).send("Project not found"); return res.status(404).send('Project not found');
} }
res.json(project); res.json(project);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,12 +1,12 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineRunCase = require("../../models/runCases"); const defineRunCase = require('../../models/runCases');
const { DataTypes, Op } = require("sequelize"); const { DataTypes, Op } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const RunCase = defineRunCase(sequelize, DataTypes); const RunCase = defineRunCase(sequelize, DataTypes);
router.post("/bulkdelete", async (req, res) => { router.post('/bulkdelete', async (req, res) => {
const recordsToDelete = req.body; const recordsToDelete = req.body;
try { try {
@@ -20,7 +20,7 @@ module.exports = function (sequelize) {
}); });
if (existingRunCases.length === 0) { if (existingRunCases.length === 0) {
return res.status(200).send("No records found to delete"); return res.status(200).send('No records found to delete');
} }
await RunCase.destroy({ await RunCase.destroy({
@@ -32,10 +32,10 @@ module.exports = function (sequelize) {
}, },
}); });
res.status(200).send("Records deleted successfully"); res.status(200).send('Records deleted successfully');
} catch (error) { } catch (error) {
console.error("Error deleting run cases:", error); console.error('Error deleting run cases:', error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,12 +1,12 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineRunCase = require("../../models/runCases"); const defineRunCase = require('../../models/runCases');
const { DataTypes, Op } = require("sequelize"); const { DataTypes, Op } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const RunCase = defineRunCase(sequelize, DataTypes); const RunCase = defineRunCase(sequelize, DataTypes);
router.post("/bulknew", async (req, res) => { router.post('/bulknew', async (req, res) => {
const recordsToCreate = req.body; const recordsToCreate = req.body;
try { try {
@@ -22,9 +22,7 @@ module.exports = function (sequelize) {
// Filter out records that already exist // Filter out records that already exist
const recordsToCreateFiltered = recordsToCreate.filter((record) => { const recordsToCreateFiltered = recordsToCreate.filter((record) => {
return !existingRunCases.some( return !existingRunCases.some(
(existingRecord) => (existingRecord) => existingRecord.runId == record.runId && existingRecord.caseId == record.caseId
existingRecord.runId == record.runId &&
existingRecord.caseId == record.caseId
); );
}); });
@@ -39,7 +37,7 @@ module.exports = function (sequelize) {
res.json(newRunCases); res.json(newRunCases);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,12 +1,12 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineRunCase = require("../../models/runCases"); const defineRunCase = require('../../models/runCases');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const RunCase = defineRunCase(sequelize, DataTypes); const RunCase = defineRunCase(sequelize, DataTypes);
router.delete("/", async (req, res) => { router.delete('/', async (req, res) => {
const runId = req.query.runId; const runId = req.query.runId;
const caseId = req.query.caseId; const caseId = req.query.caseId;
@@ -20,14 +20,14 @@ module.exports = function (sequelize) {
}); });
if (!deletingRunCase) { if (!deletingRunCase) {
return res.status(404).send("RunCase not found"); return res.status(404).send('RunCase not found');
} }
await deletingRunCase.destroy(); await deletingRunCase.destroy();
res.status(204).send(); res.status(204).send();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,12 +1,12 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineRunCase = require("../../models/runCases"); const defineRunCase = require('../../models/runCases');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const RunCase = defineRunCase(sequelize, DataTypes); const RunCase = defineRunCase(sequelize, DataTypes);
router.put("/", async (req, res) => { router.put('/', async (req, res) => {
const runId = req.query.runId; const runId = req.query.runId;
const caseId = req.query.caseId; const caseId = req.query.caseId;
const status = req.query.status; const status = req.query.status;
@@ -20,7 +20,7 @@ module.exports = function (sequelize) {
}); });
if (!runCase) { if (!runCase) {
return res.status(404).send("Runcase not found"); return res.status(404).send('Runcase not found');
} }
await runCase.update({ await runCase.update({
@@ -31,7 +31,7 @@ module.exports = function (sequelize) {
res.json(runCase); res.json(runCase);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,12 +1,12 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineRunCase = require("../../models/runCases"); const defineRunCase = require('../../models/runCases');
const { DataTypes } = require('sequelize'); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const RunCase = defineRunCase(sequelize, DataTypes) const RunCase = defineRunCase(sequelize, DataTypes);
router.get("/", async (req, res) => { router.get('/', async (req, res) => {
const { runId } = req.query; const { runId } = req.query;
if (!runId) { if (!runId) {
@@ -16,13 +16,13 @@ module.exports = function(sequelize) {
try { try {
const runCases = await RunCase.findAll({ const runCases = await RunCase.findAll({
where: { where: {
runId: runId runId: runId,
} },
}); });
res.json(runCases); res.json(runCases);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,12 +1,12 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineRunCase = require("../../models/runCases"); const defineRunCase = require('../../models/runCases');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const RunCase = defineRunCase(sequelize, DataTypes); const RunCase = defineRunCase(sequelize, DataTypes);
router.post("/", async (req, res) => { router.post('/', async (req, res) => {
const runId = req.query.runId; const runId = req.query.runId;
const caseId = req.query.caseId; const caseId = req.query.caseId;
@@ -15,26 +15,24 @@ module.exports = function (sequelize) {
const existingRunCase = await RunCase.findOne({ const existingRunCase = await RunCase.findOne({
where: { where: {
runId: runId, runId: runId,
caseId: caseId caseId: caseId,
} },
}); });
if (existingRunCase) { if (existingRunCase) {
return res.status(400).send("Record already exists"); return res.status(400).send('Record already exists');
} }
const newRunCase = await RunCase.create( const newRunCase = await RunCase.create({
{
runId: runId, runId: runId,
caseId: caseId, caseId: caseId,
status: 0, status: 0,
}, });
);
res.json(newRunCase); res.json(newRunCase);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,23 +1,23 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineRun = require("../../models/runs"); const defineRun = require('../../models/runs');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Run = defineRun(sequelize, DataTypes); const Run = defineRun(sequelize, DataTypes);
router.delete("/:runId", async (req, res) => { router.delete('/:runId', async (req, res) => {
const runId = req.params.runId; const runId = req.params.runId;
try { try {
const testrun = await Run.findByPk(runId); const testrun = await Run.findByPk(runId);
if (!testrun) { if (!testrun) {
return res.status(404).send("Run not found"); return res.status(404).send('Run not found');
} }
await testrun.destroy(); await testrun.destroy();
res.status(204).send(); res.status(204).send();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,18 +1,18 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineRun = require("../../models/runs"); const defineRun = require('../../models/runs');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Run = defineRun(sequelize, DataTypes); const Run = defineRun(sequelize, DataTypes);
router.put("/:runId", async (req, res) => { router.put('/:runId', async (req, res) => {
const runId = req.params.runId; const runId = req.params.runId;
const updateRun = req.body; const updateRun = req.body;
try { try {
const testrun = await Run.findByPk(runId); const testrun = await Run.findByPk(runId);
if (!testrun) { if (!testrun) {
return res.status(404).send("Run not found"); return res.status(404).send('Run not found');
} }
delete updateRun.Steps; delete updateRun.Steps;
@@ -20,7 +20,7 @@ module.exports = function (sequelize) {
res.json(testrun); res.json(testrun);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,12 +1,12 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineRun = require("../../models/runs"); const defineRun = require('../../models/runs');
const { DataTypes } = require('sequelize'); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Run = defineRun(sequelize, DataTypes) const Run = defineRun(sequelize, DataTypes);
router.get("/", async (req, res) => { router.get('/', async (req, res) => {
const { projectId } = req.query; const { projectId } = req.query;
if (!projectId) { if (!projectId) {
@@ -16,13 +16,13 @@ module.exports = function(sequelize) {
try { try {
const runs = await Run.findAll({ const runs = await Run.findAll({
where: { where: {
projectId: projectId projectId: projectId,
} },
}); });
res.json(runs); res.json(runs);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,18 +1,16 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineRun = require("../../models/runs"); const defineRun = require('../../models/runs');
const { DataTypes } = require("sequelize"); const { DataTypes } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Run = defineRun(sequelize, DataTypes); const Run = defineRun(sequelize, DataTypes);
router.post("/", async (req, res) => { router.post('/', async (req, res) => {
try { try {
const { name, configurations, description, state, projectId } = req.body; const { name, configurations, description, state, projectId } = req.body;
if (!name || !projectId) { if (!name || !projectId) {
return res return res.status(400).json({ error: 'Name and projectId are required' });
.status(400)
.json({ error: "Name and projectId are required" });
} }
const newRun = await Run.create({ const newRun = await Run.create({
@@ -25,7 +23,7 @@ module.exports = function (sequelize) {
res.json(newRun); res.json(newRun);
} catch (error) { } catch (error) {
res.status(500).json({ error: "Internal server error" }); res.status(500).json({ error: 'Internal server error' });
} }
}); });

View File

@@ -1,39 +1,39 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineRun = require("../../models/runs"); const defineRun = require('../../models/runs');
const defineRunCase = require("../../models/runCases"); const defineRunCase = require('../../models/runCases');
const { DataTypes, literal } = require("sequelize"); const { DataTypes, literal } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Run = defineRun(sequelize, DataTypes); const Run = defineRun(sequelize, DataTypes);
const RunCase = defineRunCase(sequelize, DataTypes); const RunCase = defineRunCase(sequelize, DataTypes);
router.get("/:runId", async (req, res) => { router.get('/:runId', async (req, res) => {
const runId = req.params.runId; const runId = req.params.runId;
if (!runId) { if (!runId) {
return res.status(400).json({ error: "runId is required" }); return res.status(400).json({ error: 'runId is required' });
} }
try { try {
const run = await Run.findByPk(runId); const run = await Run.findByPk(runId);
if (!run) { if (!run) {
return res.status(404).send("Run not found"); return res.status(404).send('Run not found');
} }
// Counts test case status belonging to the run // Counts test case status belonging to the run
const statusCounts = await RunCase.findAll({ const statusCounts = await RunCase.findAll({
attributes: ["status", [literal("COUNT(*)"), "count"]], attributes: ['status', [literal('COUNT(*)'), 'count']],
where: { where: {
runId: run.id, runId: run.id,
}, },
group: ["status"], group: ['status'],
}); });
res.json({ run, statusCounts }); res.json({ run, statusCounts });
} catch (error) { } catch (error) {
console.error(error); console.error(error);
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,14 +1,14 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineStep = require("../../models/steps"); const defineStep = require('../../models/steps');
const defineCaseStep = require("../../models/caseSteps"); const defineCaseStep = require('../../models/caseSteps');
const { DataTypes, Op } = require("sequelize"); const { DataTypes, Op } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Step = defineStep(sequelize, DataTypes); const Step = defineStep(sequelize, DataTypes);
const CaseStep = defineCaseStep(sequelize, DataTypes); const CaseStep = defineCaseStep(sequelize, DataTypes);
router.delete("/:stepId", async (req, res) => { router.delete('/:stepId', async (req, res) => {
const stepId = req.params.stepId; const stepId = req.params.stepId;
// TODO The caseId should not be specified from the front end, but should be traced from stepId by association. // TODO The caseId should not be specified from the front end, but should be traced from stepId by association.
const caseId = req.query.parentCaseId; const caseId = req.query.parentCaseId;
@@ -19,7 +19,7 @@ module.exports = function (sequelize) {
const step = await Step.findByPk(stepId); const step = await Step.findByPk(stepId);
if (!step) { if (!step) {
await t.rollback(); await t.rollback();
return res.status(404).send("Step not found"); return res.status(404).send('Step not found');
} }
// Get caseStep to be deleted. // Get caseStep to be deleted.
@@ -32,7 +32,7 @@ module.exports = function (sequelize) {
// Decrease stepNo for all caseSteps with greater than the caseStep to be deleted. // Decrease stepNo for all caseSteps with greater than the caseStep to be deleted.
await CaseStep.update( await CaseStep.update(
{ stepNo: sequelize.literal("stepNo - 1") }, { stepNo: sequelize.literal('stepNo - 1') },
{ {
where: { where: {
CaseId: caseId, CaseId: caseId,
@@ -51,7 +51,7 @@ module.exports = function (sequelize) {
} catch (error) { } catch (error) {
console.error(error); console.error(error);
await t.rollback(); await t.rollback();
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,14 +1,14 @@
const express = require("express"); const express = require('express');
const router = express.Router(); const router = express.Router();
const defineStep = require("../../models/steps"); const defineStep = require('../../models/steps');
const defineCaseStep = require("../../models/caseSteps"); const defineCaseStep = require('../../models/caseSteps');
const { DataTypes, Op } = require("sequelize"); const { DataTypes, Op } = require('sequelize');
module.exports = function (sequelize) { module.exports = function (sequelize) {
const Step = defineStep(sequelize, DataTypes); const Step = defineStep(sequelize, DataTypes);
const CaseStep = defineCaseStep(sequelize, DataTypes); const CaseStep = defineCaseStep(sequelize, DataTypes);
router.post("/", async (req, res) => { router.post('/', async (req, res) => {
const newStepNo = req.query.newStepNo; const newStepNo = req.query.newStepNo;
const caseId = req.query.parentCaseId; const caseId = req.query.parentCaseId;
@@ -16,13 +16,13 @@ module.exports = function (sequelize) {
try { try {
// Update existing stepNo for steps with stepNo greater than or equal to newStepNo // Update existing stepNo for steps with stepNo greater than or equal to newStepNo
const maxStepNo = await CaseStep.max("stepNo", { const maxStepNo = await CaseStep.max('stepNo', {
where: { caseId: caseId }, where: { caseId: caseId },
transaction: t, transaction: t,
}); });
if (maxStepNo >= newStepNo) { if (maxStepNo >= newStepNo) {
await CaseStep.update( await CaseStep.update(
{ stepNo: sequelize.literal("stepNo + 1") }, { stepNo: sequelize.literal('stepNo + 1') },
{ {
where: { where: {
caseId: caseId, caseId: caseId,
@@ -35,8 +35,8 @@ module.exports = function (sequelize) {
const newStep = await Step.create( const newStep = await Step.create(
{ {
step: "", step: '',
result: "", result: '',
}, },
{ transaction: t } { transaction: t }
); );
@@ -55,7 +55,7 @@ module.exports = function (sequelize) {
} catch (error) { } catch (error) {
console.error(error); console.error(error);
await t.rollback(); await t.rollback();
res.status(500).send("Internal Server Error"); res.status(500).send('Internal Server Error');
} }
}); });

View File

@@ -1,58 +1,58 @@
"use strict"; 'use strict';
const path = require("path"); const path = require('path');
const fs = require("fs"); const fs = require('fs');
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
// Add projects table records // Add projects table records
await queryInterface.bulkInsert("Projects", [ await queryInterface.bulkInsert('Projects', [
{ {
name: "TestPlat Test", name: 'TestPlat Test',
detail: "Test Plat's Manual test", detail: "Test Plat's Manual test",
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
name: "Iron Muscle App(筋トレアプリ)", name: 'Iron Muscle App(筋トレアプリ)',
detail: "リリース前総合評価", detail: 'リリース前総合評価',
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
]); ]);
// Add folders table records // Add folders table records
await queryInterface.bulkInsert("folders", [ await queryInterface.bulkInsert('folders', [
{ {
name: "Account", name: 'Account',
detail: "", detail: '',
projectId: 1, projectId: 1,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
name: "Contact", name: 'Contact',
detail: "", detail: '',
projectId: 1, projectId: 1,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
name: "アカウント", name: 'アカウント',
detail: "", detail: '',
projectId: 2, projectId: 2,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
name: "トレーニング記録", name: 'トレーニング記録',
detail: "", detail: '',
projectId: 2, projectId: 2,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
name: "タイムライン", name: 'タイムライン',
detail: "", detail: '',
projectId: 2, projectId: 2,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
@@ -60,30 +60,30 @@ module.exports = {
]); ]);
// Add runs table records // Add runs table records
await queryInterface.bulkInsert("runs", [ await queryInterface.bulkInsert('runs', [
{ {
name: "First Test Run", name: 'First Test Run',
projectId: 1, projectId: 1,
configurations: 1, configurations: 1,
description: "5/14 - 5/31", description: '5/14 - 5/31',
state: 4, state: 4,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
name: "総合評価第一回", name: '総合評価第一回',
projectId: 2, projectId: 2,
configurations: 1, configurations: 1,
description: "5/14 - 5/31", description: '5/14 - 5/31',
state: 4, state: 4,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
name: "総合評価第二回", name: '総合評価第二回',
projectId: 2, projectId: 2,
configurations: 1, configurations: 1,
description: "6/1 - 6/12", description: '6/1 - 6/12',
state: 1, state: 1,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
@@ -91,171 +91,171 @@ module.exports = {
]); ]);
// Add cases table records // Add cases table records
await queryInterface.bulkInsert("cases", [ await queryInterface.bulkInsert('cases', [
{ {
title: "Signup", title: 'Signup',
state: 1, state: 1,
priority: 1, priority: 1,
type: 4, type: 4,
automationStatus: 1, automationStatus: 1,
description: "User can signup from signup form.", description: 'User can signup from signup form.',
template: 1, template: 1,
preConditions: "Not signed in", preConditions: 'Not signed in',
expectedResults: "", expectedResults: '',
folderId: 1, folderId: 1,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
title: "Signin", title: 'Signin',
state: 1, state: 1,
priority: 1, priority: 1,
type: 4, type: 4,
automationStatus: 1, automationStatus: 1,
description: "User can signin from signin form.", description: 'User can signin from signin form.',
template: 1, template: 1,
preConditions: "Not signed in", preConditions: 'Not signed in',
expectedResults: "", expectedResults: '',
folderId: 1, folderId: 1,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
title: "Contact", title: 'Contact',
state: 1, state: 1,
priority: 1, priority: 1,
type: 4, type: 4,
automationStatus: 1, automationStatus: 1,
description: "User can send inquiry from 'contact us' form.", description: "User can send inquiry from 'contact us' form.",
template: 0, template: 0,
preConditions: "", preConditions: '',
expectedResults: "", expectedResults: '',
folderId: 2, folderId: 2,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
title: "メールアドレスでのアカウント登録", title: 'メールアドレスでのアカウント登録',
state: 1, state: 1,
priority: 2, priority: 2,
type: 4, type: 4,
automationStatus: 1, automationStatus: 1,
description: "メールアドレス、パスワードをフォームに入力してサインアップボタンを押す", description: 'メールアドレス、パスワードをフォームに入力してサインアップボタンを押す',
template: 0, template: 0,
preConditions: "未サインイン状態であること。アカウントがないこと。", preConditions: '未サインイン状態であること。アカウントがないこと。',
expectedResults: "サインアップができ、自動でアカウントページに遷移する", expectedResults: 'サインアップができ、自動でアカウントページに遷移する',
folderId: 3, folderId: 3,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
title: "メールアドレスでのサインイン", title: 'メールアドレスでのサインイン',
state: 1, state: 1,
priority: 2, priority: 2,
type: 4, type: 4,
automationStatus: 1, automationStatus: 1,
description: "メールアドレス、パスワードをフォームに入力してサインインボタンを押す", description: 'メールアドレス、パスワードをフォームに入力してサインインボタンを押す',
template: 0, template: 0,
preConditions: "未サインイン状態であること", preConditions: '未サインイン状態であること',
expectedResults: "サインインができ、自動でアカウントページに遷移する", expectedResults: 'サインインができ、自動でアカウントページに遷移する',
folderId: 3, folderId: 3,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
title: "ソーシャルアカウントサインイン", title: 'ソーシャルアカウントサインイン',
state: 1, state: 1,
priority: 1, priority: 1,
type: 4, type: 4,
automationStatus: 1, automationStatus: 1,
description: "Googleアカウントで筋トレアプリにサインインできること", description: 'Googleアカウントで筋トレアプリにサインインできること',
template: 0, template: 0,
preConditions: "未サインイン状態であること", preConditions: '未サインイン状態であること',
expectedResults: "サインインでき、自動でアカウントページに遷移する", expectedResults: 'サインインでき、自動でアカウントページに遷移する',
folderId: 3, folderId: 3,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
title: "アカウント情報編集", title: 'アカウント情報編集',
state: 1, state: 1,
priority: 3, priority: 3,
type: 4, type: 4,
automationStatus: 1, automationStatus: 1,
description: "ユーザー名、アバター画像を変更できること", description: 'ユーザー名、アバター画像を変更できること',
template: 0, template: 0,
preConditions: "アバター画像(.png, .svg, .jpg)を用意する", preConditions: 'アバター画像(.png, .svg, .jpg)を用意する',
expectedResults: "アバター画像を登録できること", expectedResults: 'アバター画像を登録できること',
folderId: 3, folderId: 3,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
title: "アカウント閲覧", title: 'アカウント閲覧',
state: 1, state: 1,
priority: 0, priority: 0,
type: 1, type: 1,
automationStatus: 1, automationStatus: 1,
description: "ほかの人のアカウント情報は見れないこと", description: 'ほかの人のアカウント情報は見れないこと',
template: 1, template: 1,
preConditions: "特になし", preConditions: '特になし',
expectedResults: "", expectedResults: '',
folderId: 3, folderId: 3,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
title: "筋トレ記録(部位選択)", title: '筋トレ記録(部位選択)',
state: 1, state: 1,
priority: 2, priority: 2,
type: 1, type: 1,
automationStatus: 1, automationStatus: 1,
description: "部位選択", description: '部位選択',
template: 1, template: 1,
preConditions: "特になし", preConditions: '特になし',
expectedResults: "筋トレ部位を選択できること", expectedResults: '筋トレ部位を選択できること',
folderId: 4, folderId: 4,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
title: "筋トレ記録(回数選択)", title: '筋トレ記録(回数選択)',
state: 1, state: 1,
priority: 2, priority: 2,
type: 1, type: 1,
automationStatus: 1, automationStatus: 1,
description: "回数選択", description: '回数選択',
template: 1, template: 1,
preConditions: "特になし", preConditions: '特になし',
expectedResults: "筋トレ回数を選択できること", expectedResults: '筋トレ回数を選択できること',
folderId: 4, folderId: 4,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
title: "筋トレ記録 ダイアログのクローズ", title: '筋トレ記録 ダイアログのクローズ',
state: 1, state: 1,
priority: 3, priority: 3,
type: 3, type: 3,
automationStatus: 1, automationStatus: 1,
description: "選択ダイアログの機能性確認", description: '選択ダイアログの機能性確認',
template: 1, template: 1,
preConditions: "ダイアログを開く", preConditions: 'ダイアログを開く',
expectedResults: "ダイアログの「×」ボタンを押して閉じれること", expectedResults: 'ダイアログの「×」ボタンを押して閉じれること',
folderId: 4, folderId: 4,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
title: "筋トレ記録 選択ダイアログ", title: '筋トレ記録 選択ダイアログ',
state: 1, state: 1,
priority: 3, priority: 3,
type: 3, type: 3,
automationStatus: 1, automationStatus: 1,
description: "選択ダイアログのレスポンシブ確認", description: '選択ダイアログのレスポンシブ確認',
template: 1, template: 1,
preConditions: "スマホでウェブサイトにアクセスする", preConditions: 'スマホでウェブサイトにアクセスする',
expectedResults: "ダイアログの表示がおかしくないこと", expectedResults: 'ダイアログの表示がおかしくないこと',
folderId: 4, folderId: 4,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
@@ -263,47 +263,47 @@ module.exports = {
]); ]);
// Add steps table records // Add steps table records
await queryInterface.bulkInsert("steps", [ await queryInterface.bulkInsert('steps', [
{ {
step: "Check accout status", step: 'Check accout status',
result: "Never have account", result: 'Never have account',
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
step: "Enter signup form and then, click 'signup' button.", step: "Enter signup form and then, click 'signup' button.",
result: "Automatically redirect to the account page", result: 'Automatically redirect to the account page',
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
step: "Check signin status", step: 'Check signin status',
result: "Not signed in", result: 'Not signed in',
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
step: "Enter signin form and then, click 'signin button.'", step: "Enter signin form and then, click 'signin button.'",
result: "Automatically redirect to the account page", result: 'Automatically redirect to the account page',
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
step: "ブラウザのシークレットモードに入る", step: 'ブラウザのシークレットモードに入る',
result: "開発者モードのLocal Storageを開き、sessionがないことを確認する。", result: '開発者モードのLocal Storageを開き、sessionがないことを確認する。',
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
step: "'account/userinfo?userid=xxx'に遷移する", step: "'account/userinfo?userid=xxx'に遷移する",
result: "エラーページにリダイレクトされ、403エラーなこと。", result: 'エラーページにリダイレクトされ、403エラーなこと。',
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
]); ]);
// Add case-step join table // Add case-step join table
await queryInterface.bulkInsert("caseSteps", [ await queryInterface.bulkInsert('caseSteps', [
{ {
caseId: 1, caseId: 1,
stepId: 1, stepId: 1,
@@ -338,7 +338,8 @@ module.exports = {
stepNo: 1, stepNo: 1,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, { },
{
caseId: 8, caseId: 8,
stepId: 6, stepId: 6,
stepNo: 2, stepNo: 2,
@@ -347,28 +348,28 @@ module.exports = {
}, },
]); ]);
await queryInterface.bulkInsert("attachments", [ await queryInterface.bulkInsert('attachments', [
{ {
title: "Selenium logo", title: 'Selenium logo',
detail: "", detail: '',
path: "http://localhost:3001/uploads/861px-Selenium_Logo.png", path: 'http://localhost:3001/uploads/861px-Selenium_Logo.png',
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
{ {
title: "vitest logo", title: 'vitest logo',
detail: "", detail: '',
path: "http://localhost:3001/uploads/logo-shadow.svg", path: 'http://localhost:3001/uploads/logo-shadow.svg',
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}, },
]); ]);
// copy sample files to uploads folder // copy sample files to uploads folder
const sampleFolderPath = "public/sample"; const sampleFolderPath = 'public/sample';
const uploadsFolderPath = "public/uploads"; const uploadsFolderPath = 'public/uploads';
const SeleniumLogoFileName = "861px-Selenium_Logo.png"; const SeleniumLogoFileName = '861px-Selenium_Logo.png';
const vitestLogoFileName = "logo-shadow.svg"; const vitestLogoFileName = 'logo-shadow.svg';
if (!fs.existsSync(uploadsFolderPath)) { if (!fs.existsSync(uploadsFolderPath)) {
fs.mkdirSync(uploadsFolderPath, { recursive: true }); fs.mkdirSync(uploadsFolderPath, { recursive: true });
} }
@@ -381,17 +382,13 @@ module.exports = {
} }
} }
); );
fs.copyFile( fs.copyFile(`${sampleFolderPath}/${vitestLogoFileName}`, `${uploadsFolderPath}/${vitestLogoFileName}`, (err) => {
`${sampleFolderPath}/${vitestLogoFileName}`,
`${uploadsFolderPath}/${vitestLogoFileName}`,
(err) => {
if (err) { if (err) {
console.log(err); console.log(err);
} }
} });
);
await queryInterface.bulkInsert("caseAttachments", [ await queryInterface.bulkInsert('caseAttachments', [
{ {
caseId: 1, caseId: 1,
attachmentId: 1, attachmentId: 1,
@@ -406,7 +403,7 @@ module.exports = {
}, },
]); ]);
await queryInterface.bulkInsert("runCases", [ await queryInterface.bulkInsert('runCases', [
{ {
runId: 1, runId: 1,
caseId: 1, caseId: 1,

View File

@@ -1,50 +1,42 @@
import { tv } from "tailwind-variants"; import { tv } from 'tailwind-variants';
export const title = tv({ export const title = tv({
base: "tracking-tight inline font-semibold", base: 'tracking-tight inline font-semibold',
variants: { variants: {
color: { color: {
violet: "from-[#FF1CF7] to-[#b249f8]", violet: 'from-[#FF1CF7] to-[#b249f8]',
yellow: "from-[#FF705B] to-[#FFB457]", yellow: 'from-[#FF705B] to-[#FFB457]',
blue: "from-[#5EA2EF] to-[#0072F5]", blue: 'from-[#5EA2EF] to-[#0072F5]',
cyan: "from-[#00b7fa] to-[#01cfea]", cyan: 'from-[#00b7fa] to-[#01cfea]',
green: "from-[#6FEE8D] to-[#17c964]", green: 'from-[#6FEE8D] to-[#17c964]',
pink: "from-[#FF72E1] to-[#F54C7A]", pink: 'from-[#FF72E1] to-[#F54C7A]',
foreground: "dark:from-[#FFFFFF] dark:to-[#4B4B4B]", foreground: 'dark:from-[#FFFFFF] dark:to-[#4B4B4B]',
}, },
size: { size: {
sm: "text-3xl lg:text-4xl", sm: 'text-3xl lg:text-4xl',
md: "text-[2.3rem] lg:text-5xl leading-9", md: 'text-[2.3rem] lg:text-5xl leading-9',
lg: "text-4xl lg:text-6xl", lg: 'text-4xl lg:text-6xl',
}, },
fullWidth: { fullWidth: {
true: "w-full block", true: 'w-full block',
}, },
}, },
defaultVariants: { defaultVariants: {
size: "md", size: 'md',
}, },
compoundVariants: [ compoundVariants: [
{ {
color: [ color: ['violet', 'yellow', 'blue', 'cyan', 'green', 'pink', 'foreground'],
"violet", class: 'bg-clip-text text-transparent bg-gradient-to-b',
"yellow",
"blue",
"cyan",
"green",
"pink",
"foreground",
],
class: "bg-clip-text text-transparent bg-gradient-to-b",
}, },
], ],
}); });
export const subtitle = tv({ export const subtitle = tv({
base: "w-full md:w-1/2 my-2 text-lg lg:text-xl text-default-600 block max-w-full", base: 'w-full md:w-1/2 my-2 text-lg lg:text-xl text-default-600 block max-w-full',
variants: { variants: {
fullWidth: { fullWidth: {
true: "!w-full", true: '!w-full',
}, },
}, },
defaultVariants: { defaultVariants: {

View File

@@ -1,11 +1,11 @@
import { Fira_Code as FontMono, Inter as FontSans } from "next/font/google"; import { Fira_Code as FontMono, Inter as FontSans } from 'next/font/google';
export const fontSans = FontSans({ export const fontSans = FontSans({
subsets: ["latin"], subsets: ['latin'],
variable: "--font-sans", variable: '--font-sans',
}); });
export const fontMono = FontMono({ export const fontMono = FontMono({
subsets: ["latin"], subsets: ['latin'],
variable: "--font-mono", variable: '--font-mono',
}); });

View File

@@ -1,92 +1,74 @@
const roles = [{ uid: "admin" }, { uid: "moderator" }, { uid: "user" }]; const roles = [{ uid: 'admin' }, { uid: 'moderator' }, { uid: 'user' }];
const categoricalPalette = [ const categoricalPalette = ['#fba91e', '#6ea56c', '#3ac6e1', '#feda2f', '#f15f47', '#244470', '#9c80bb', '#f595a6'];
"#fba91e",
"#6ea56c",
"#3ac6e1",
"#feda2f",
"#f15f47",
"#244470",
"#9c80bb",
"#f595a6",
];
const priorities = [ const priorities = [
{ uid: "critical", color: "#bb3e03", chartColor: "#bb3e03" }, { uid: 'critical', color: '#bb3e03', chartColor: '#bb3e03' },
{ uid: "high", color: "#ca6702", chartColor: "#ca6702" }, { uid: 'high', color: '#ca6702', chartColor: '#ca6702' },
{ uid: "medium", color: "#ee9b00", chartColor: "#ee9b00" }, { uid: 'medium', color: '#ee9b00', chartColor: '#ee9b00' },
{ uid: "low", color: "#94d2bd", chartColor: "#94d2bd" }, { uid: 'low', color: '#94d2bd', chartColor: '#94d2bd' },
]; ];
const testTypes = [ const testTypes = [
{ uid: "other", chartColor: categoricalPalette[0] }, { uid: 'other', chartColor: categoricalPalette[0] },
{ uid: "security", chartColor: categoricalPalette[1] }, { uid: 'security', chartColor: categoricalPalette[1] },
{ uid: "performance", chartColor: categoricalPalette[2] }, { uid: 'performance', chartColor: categoricalPalette[2] },
{ uid: "accessibility", chartColor: categoricalPalette[3] }, { uid: 'accessibility', chartColor: categoricalPalette[3] },
{ uid: "functional", chartColor: categoricalPalette[4] }, { uid: 'functional', chartColor: categoricalPalette[4] },
{ uid: "acceptance", chartColor: categoricalPalette[5] }, { uid: 'acceptance', chartColor: categoricalPalette[5] },
{ uid: "usability", chartColor: categoricalPalette[6] }, { uid: 'usability', chartColor: categoricalPalette[6] },
{ uid: "smokeSanity", chartColor: categoricalPalette[7] }, { uid: 'smokeSanity', chartColor: categoricalPalette[7] },
{ uid: "compatibility", chartColor: categoricalPalette[0] }, { uid: 'compatibility', chartColor: categoricalPalette[0] },
{ uid: "destructive", chartColor: categoricalPalette[1] }, { uid: 'destructive', chartColor: categoricalPalette[1] },
{ uid: "regression", chartColor: categoricalPalette[2] }, { uid: 'regression', chartColor: categoricalPalette[2] },
{ uid: "automated", chartColor: categoricalPalette[3] }, { uid: 'automated', chartColor: categoricalPalette[3] },
{ uid: "manual", chartColor: categoricalPalette[4] }, { uid: 'manual', chartColor: categoricalPalette[4] },
]; ];
const automationStatus = [ const automationStatus = [
{ name: "Automated", uid: "automated" }, { name: 'Automated', uid: 'automated' },
{ name: "Automation Not Required", uid: "automation-not-required" }, { name: 'Automation Not Required', uid: 'automation-not-required' },
{ name: "Cannot Be Automated", uid: "cannot-be-automated" }, { name: 'Cannot Be Automated', uid: 'cannot-be-automated' },
{ name: "Obsolete", uid: "obsolete" }, { name: 'Obsolete', uid: 'obsolete' },
]; ];
const templates = [{ uid: "text" }, { uid: "step" }]; const templates = [{ uid: 'text' }, { uid: 'step' }];
const testRunStatus = [ const testRunStatus = [
{ uid: "new" }, { uid: 'new' },
{ uid: "inProgress" }, { uid: 'inProgress' },
{ uid: "underReview" }, { uid: 'underReview' },
{ uid: "rejected" }, { uid: 'rejected' },
{ uid: "done" }, { uid: 'done' },
{ uid: "closed" }, { uid: 'closed' },
]; ];
const testRunCaseStatus = [ const testRunCaseStatus = [
{ {
uid: "untested", uid: 'untested',
color: "primary", color: 'primary',
chartColor: "#3ac6e1", chartColor: '#3ac6e1',
}, },
{ uid: "passed", color: "success", chartColor: "#6ea56c" }, { uid: 'passed', color: 'success', chartColor: '#6ea56c' },
{ uid: "failed", color: "danger", chartColor: "#f15f47" }, { uid: 'failed', color: 'danger', chartColor: '#f15f47' },
{ uid: "retest", color: "warning", chartColor: "#fba91e" }, { uid: 'retest', color: 'warning', chartColor: '#fba91e' },
{ uid: "skipped", color: "primary", chartColor: "#805aab" }, { uid: 'skipped', color: 'primary', chartColor: '#805aab' },
]; ];
const avatars = [ const avatars = [
"/avatar/bear.png", '/avatar/bear.png',
"/avatar/cat.png", '/avatar/cat.png',
"/avatar/cow.png", '/avatar/cow.png',
"/avatar/dog.png", '/avatar/dog.png',
"/avatar/giraffe.png", '/avatar/giraffe.png',
"/avatar/koala.png", '/avatar/koala.png',
"/avatar/lion.png", '/avatar/lion.png',
"/avatar/owl.png", '/avatar/owl.png',
"/avatar/panda.png", '/avatar/panda.png',
"/avatar/penguin.png", '/avatar/penguin.png',
"/avatar/rhinoceros.png", '/avatar/rhinoceros.png',
"/avatar/shark.png", '/avatar/shark.png',
"/avatar/sloth.png", '/avatar/sloth.png',
]; ];
export { export { roles, priorities, testTypes, automationStatus, templates, testRunStatus, testRunCaseStatus, avatars };
roles,
priorities,
testTypes,
automationStatus,
templates,
testRunStatus,
testRunCaseStatus,
avatars,
};

View File

@@ -1,4 +1,4 @@
const createNextIntlPlugin = require("next-intl/plugin"); const createNextIntlPlugin = require('next-intl/plugin');
const withNextIntl = createNextIntlPlugin(); const withNextIntl = createNextIntlPlugin();
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */

View File

@@ -3,4 +3,4 @@ module.exports = {
tailwindcss: {}, tailwindcss: {},
autoprefixer: {}, autoprefixer: {},
}, },
} };

View File

@@ -1,13 +1,13 @@
import { UserType } from "@/types/user"; import { UserType } from '@/types/user';
import { avatars } from "@/config/selection"; import { avatars } from '@/config/selection';
import Config from "@/config/config"; import Config from '@/config/config';
const apiServer = Config.apiServer; const apiServer = Config.apiServer;
async function signUp(newUser: UserType) { async function signUp(newUser: UserType) {
const fetchOptions = { const fetchOptions = {
method: "POST", method: 'POST',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
body: JSON.stringify(newUser), body: JSON.stringify(newUser),
}; };
@@ -22,16 +22,16 @@ async function signUp(newUser: UserType) {
const token = await response.json(); const token = await response.json();
return token; return token;
} catch (error: any) { } catch (error: any) {
console.error("Error sign up:", error); console.error('Error sign up:', error);
throw error; throw error;
} }
} }
async function signIn(signInUser: UserType) { async function signIn(signInUser: UserType) {
const fetchOptions = { const fetchOptions = {
method: "POST", method: 'POST',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
body: JSON.stringify(signInUser), body: JSON.stringify(signInUser),
}; };
@@ -46,7 +46,7 @@ async function signIn(signInUser: UserType) {
const token = await response.json(); const token = await response.json();
return token; return token;
} catch (error: any) { } catch (error: any) {
console.error("Error sign in:", error); console.error('Error sign in:', error);
throw error; throw error;
} }
} }

View File

@@ -1,24 +1,24 @@
import { expect, test } from "vitest"; import { expect, test } from 'vitest';
import { isValidEmail, isValidPassword } from "./validate"; import { isValidEmail, isValidPassword } from './validate';
test("validate email", () => { test('validate email', () => {
const email1 = "aaa@gmail.com"; const email1 = 'aaa@gmail.com';
expect(isValidEmail(email1)).toBe(true); expect(isValidEmail(email1)).toBe(true);
const email2 = "gmail.com"; const email2 = 'gmail.com';
expect(isValidEmail(email2)).toBe(false); expect(isValidEmail(email2)).toBe(false);
const email23 = ""; const email23 = '';
expect(isValidEmail(email23)).toBe(false); expect(isValidEmail(email23)).toBe(false);
}); });
test("validate password", () => { test('validate password', () => {
const pass1 = "aaaaaaaa"; const pass1 = 'aaaaaaaa';
expect(isValidPassword(pass1)).toBe(true); expect(isValidPassword(pass1)).toBe(true);
const pass2 = "abcdefg"; const pass2 = 'abcdefg';
expect(isValidPassword(pass2)).toBe(false); expect(isValidPassword(pass2)).toBe(false);
const pass3 = ""; const pass3 = '';
expect(isValidPassword(pass3)).toBe(false); expect(isValidPassword(pass3)).toBe(false);
}); });

View File

@@ -1,6 +1,5 @@
function isValidEmail(email: string) { function isValidEmail(email: string) {
const validRegex = const validRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
if (email.match(validRegex)) { if (email.match(validRegex)) {
return true; return true;
} else { } else {

View File

@@ -1,8 +1,8 @@
import { expect, test } from "vitest"; import { expect, test } from 'vitest';
import { isImage } from "./isImage"; import { isImage } from './isImage';
import { AttachmentType } from "@/types/case"; import { AttachmentType } from '@/types/case';
test("isImage", () => { test('isImage', () => {
type CaseAttachmentType = { type CaseAttachmentType = {
createdAt: Date; createdAt: Date;
updatedAt: Date; updatedAt: Date;
@@ -19,17 +19,17 @@ test("isImage", () => {
const sampleAttachment: AttachmentType = { const sampleAttachment: AttachmentType = {
id: 1, id: 1,
title: "", title: '',
detail: "", detail: '',
path: "", path: '',
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
caseAttachments: sampleCaseAttachment, caseAttachments: sampleCaseAttachment,
}; };
sampleAttachment.path = "public/uploads/abc.png"; sampleAttachment.path = 'public/uploads/abc.png';
expect(isImage(sampleAttachment)).toBe(true); expect(isImage(sampleAttachment)).toBe(true);
sampleAttachment.path = "public/uploads/abc.mp3"; sampleAttachment.path = 'public/uploads/abc.mp3';
expect(isImage(sampleAttachment)).toBe(false); expect(isImage(sampleAttachment)).toBe(false);
}); });

View File

@@ -1,14 +1,11 @@
import Config from "@/config/config"; import Config from '@/config/config';
const apiServer = Config.apiServer; const apiServer = Config.apiServer;
async function fetchDownloadAttachment( async function fetchDownloadAttachment(attachmentId: number, downloadFileName: string) {
attachmentId: number,
downloadFileName: string
) {
const fetchOptions = { const fetchOptions = {
method: "GET", method: 'GET',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}; };
@@ -23,14 +20,14 @@ async function fetchDownloadAttachment(
const blob = await response.blob(); const blob = await response.blob();
const downloadUrl = window.URL.createObjectURL(blob); const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement("a"); const link = document.createElement('a');
link.href = downloadUrl; link.href = downloadUrl;
link.download = downloadFileName; link.download = downloadFileName;
document.body.appendChild(link); document.body.appendChild(link);
link.click(); link.click();
document.body.removeChild(link); document.body.removeChild(link);
} catch (error: any) { } catch (error: any) {
console.error("Error downloading file:", error); console.error('Error downloading file:', error);
throw error; throw error;
} }
} }
@@ -39,31 +36,31 @@ async function fetchCreateAttachments(caseId: number, files: File[]) {
try { try {
const formData = new FormData(); const formData = new FormData();
for (let i = 0; i < files.length; i++) { for (let i = 0; i < files.length; i++) {
formData.append("files", files[i]); formData.append('files', files[i]);
} }
const url = `${apiServer}/attachments?parentCaseId=${caseId}`; const url = `${apiServer}/attachments?parentCaseId=${caseId}`;
const response = await fetch(url, { const response = await fetch(url, {
method: "POST", method: 'POST',
body: formData, body: formData,
}); });
if (!response.ok) { if (!response.ok) {
throw new Error("Network response was not ok"); throw new Error('Network response was not ok');
} }
const responseData = await response.json(); const responseData = await response.json();
return responseData; return responseData;
} catch (error: any) { } catch (error: any) {
console.error("Error uploading files:", error); console.error('Error uploading files:', error);
} }
} }
async function fetchDeleteAttachment(attachmentId: number) { async function fetchDeleteAttachment(attachmentId: number) {
const fetchOptions = { const fetchOptions = {
method: "DELETE", method: 'DELETE',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}; };
@@ -75,13 +72,9 @@ async function fetchDeleteAttachment(attachmentId: number) {
throw new Error(`HTTP error! Status: ${response.status}`); throw new Error(`HTTP error! Status: ${response.status}`);
} }
} catch (error: any) { } catch (error: any) {
console.error("Error deleting file:", error); console.error('Error deleting file:', error);
throw error; throw error;
} }
} }
export { export { fetchDownloadAttachment, fetchCreateAttachments, fetchDeleteAttachment };
fetchDownloadAttachment,
fetchCreateAttachments,
fetchDeleteAttachment,
};

View File

@@ -1,15 +1,15 @@
import { AttachmentType } from "@/types/case"; import { AttachmentType } from '@/types/case';
function isImage(attachmentFile: AttachmentType) { function isImage(attachmentFile: AttachmentType) {
let path = attachmentFile.path; let path = attachmentFile.path;
let extension = path.substring(path.lastIndexOf(".") + 1).toLowerCase(); let extension = path.substring(path.lastIndexOf('.') + 1).toLowerCase();
if ( if (
extension === "png" || extension === 'png' ||
extension === "jpg" || extension === 'jpg' ||
extension === "jpeg" || extension === 'jpeg' ||
extension === "gif" || extension === 'gif' ||
extension === "bmp" || extension === 'bmp' ||
extension === "svg" extension === 'svg'
) { ) {
return true; return true;
} else { } else {

View File

@@ -1,11 +1,11 @@
import Config from "@/config/config"; import Config from '@/config/config';
const apiServer = Config.apiServer; const apiServer = Config.apiServer;
async function fetchCreateStep(newStepNo: number, parentCaseId: number) { async function fetchCreateStep(newStepNo: number, parentCaseId: number) {
const fetchOptions = { const fetchOptions = {
method: "POST", method: 'POST',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}; };
@@ -18,16 +18,16 @@ async function fetchCreateStep(newStepNo: number, parentCaseId: number) {
} }
return await response.json(); return await response.json();
} catch (error: any) { } catch (error: any) {
console.error("Error deleting project:", error); console.error('Error deleting project:', error);
throw error; throw error;
} }
} }
async function fetchDeleteStep(stepId: number, parentCaseId: number) { async function fetchDeleteStep(stepId: number, parentCaseId: number) {
const fetchOptions = { const fetchOptions = {
method: "DELETE", method: 'DELETE',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}; };
@@ -39,12 +39,9 @@ async function fetchDeleteStep(stepId: number, parentCaseId: number) {
throw new Error(`HTTP error! Status: ${response.status}`); throw new Error(`HTTP error! Status: ${response.status}`);
} }
} catch (error: any) { } catch (error: any) {
console.error("Error deleting project:", error); console.error('Error deleting project:', error);
throw error; throw error;
} }
} }
export { export { fetchCreateStep, fetchDeleteStep };
fetchCreateStep,
fetchDeleteStep,
};

View File

@@ -1,15 +1,15 @@
import Config from "@/config/config"; import Config from '@/config/config';
const apiServer = Config.apiServer; const apiServer = Config.apiServer;
import { CaseType } from "@/types/case"; import { CaseType } from '@/types/case';
async function fetchCase(caseId: number) { async function fetchCase(caseId: number) {
const url = `${apiServer}/cases/${caseId}`; const url = `${apiServer}/cases/${caseId}`;
try { try {
const response = await fetch(url, { const response = await fetch(url, {
method: "GET", method: 'GET',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}); });
@@ -20,7 +20,7 @@ async function fetchCase(caseId: number) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error fetching data:", error.message); console.error('Error fetching data:', error.message);
} }
} }
@@ -29,9 +29,9 @@ async function fetchCases(folderId: string) {
try { try {
const response = await fetch(url, { const response = await fetch(url, {
method: "GET", method: 'GET',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}); });
@@ -42,28 +42,28 @@ async function fetchCases(folderId: string) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error fetching data:", error.message); console.error('Error fetching data:', error.message);
} }
} }
async function createCase(folderId: string) { async function createCase(folderId: string) {
const newCase = { const newCase = {
title: "untitled case", title: 'untitled case',
state: 0, state: 0,
priority: 2, priority: 2,
type: 0, type: 0,
automationStatus: 0, automationStatus: 0,
description: "", description: '',
template: 0, template: 0,
preConditions: "", preConditions: '',
expectedResults: "", expectedResults: '',
folderId: folderId, folderId: folderId,
}; };
const fetchOptions = { const fetchOptions = {
method: "POST", method: 'POST',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
body: JSON.stringify(newCase), body: JSON.stringify(newCase),
}; };
@@ -78,16 +78,16 @@ async function createCase(folderId: string) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error creating case:", error); console.error('Error creating case:', error);
throw error; throw error;
} }
} }
async function updateCase(updateCaseData: CaseType) { async function updateCase(updateCaseData: CaseType) {
const fetchOptions = { const fetchOptions = {
method: "PUT", method: 'PUT',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
body: JSON.stringify(updateCaseData), body: JSON.stringify(updateCaseData),
}; };
@@ -102,16 +102,16 @@ async function updateCase(updateCaseData: CaseType) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error updating project:", error); console.error('Error updating project:', error);
throw error; throw error;
} }
} }
async function deleteCase(caseId: number) { async function deleteCase(caseId: number) {
const fetchOptions = { const fetchOptions = {
method: "DELETE", method: 'DELETE',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}; };
@@ -123,16 +123,16 @@ async function deleteCase(caseId: number) {
throw new Error(`HTTP error! Status: ${response.status}`); throw new Error(`HTTP error! Status: ${response.status}`);
} }
} catch (error: any) { } catch (error: any) {
console.error("Error deleting case:", error); console.error('Error deleting case:', error);
throw error; throw error;
} }
} }
async function deleteCases(deleteCases: string[]) { async function deleteCases(deleteCases: string[]) {
const fetchOptions = { const fetchOptions = {
method: "POST", method: 'POST',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
body: JSON.stringify({ caseIds: deleteCases }), body: JSON.stringify({ caseIds: deleteCases }),
}; };
@@ -145,16 +145,9 @@ async function deleteCases(deleteCases: string[]) {
throw new Error(`HTTP error! Status: ${response.status}`); throw new Error(`HTTP error! Status: ${response.status}`);
} }
} catch (error: any) { } catch (error: any) {
console.error("Error deleting cases:", error); console.error('Error deleting cases:', error);
throw error; throw error;
} }
} }
export { export { fetchCase, fetchCases, updateCase, createCase, deleteCase, deleteCases };
fetchCase,
fetchCases,
updateCase,
createCase,
deleteCase,
deleteCases,
};

View File

@@ -1,4 +1,4 @@
import Config from "@/config/config"; import Config from '@/config/config';
const apiServer = Config.apiServer; const apiServer = Config.apiServer;
/** /**
@@ -8,9 +8,9 @@ async function fetchFolders(projectId: string) {
try { try {
const url = `${apiServer}/folders?projectId=${projectId}`; const url = `${apiServer}/folders?projectId=${projectId}`;
const response = await fetch(url, { const response = await fetch(url, {
method: "GET", method: 'GET',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}); });
@@ -21,19 +21,14 @@ async function fetchFolders(projectId: string) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error fetching data:", error.message); console.error('Error fetching data:', error.message);
} }
} }
/** /**
* Create project * Create project
*/ */
async function createFolder( async function createFolder(name: string, detail: string, projectId: strting, parentFolderId: number) {
name: string,
detail: string,
projectId: strting,
parentFolderId: number
) {
const newFolderData = { const newFolderData = {
name: name, name: name,
detail: detail, detail: detail,
@@ -42,9 +37,9 @@ async function createFolder(
}; };
const fetchOptions = { const fetchOptions = {
method: "POST", method: 'POST',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
body: JSON.stringify(newFolderData), body: JSON.stringify(newFolderData),
}; };
@@ -59,7 +54,7 @@ async function createFolder(
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error creating new project:", error); console.error('Error creating new project:', error);
throw error; throw error;
} }
} }
@@ -67,13 +62,7 @@ async function createFolder(
/** /**
* Update folder * Update folder
*/ */
async function updateFolder( async function updateFolder(folderId: number, name: string, detail: string, projectId: string, parentFolderId: number) {
folderId: number,
name: string,
detail: string,
projectId: string,
parentFolderId: number
) {
const updateFolderData = { const updateFolderData = {
name: name, name: name,
detail: detail, detail: detail,
@@ -82,9 +71,9 @@ async function updateFolder(
}; };
const fetchOptions = { const fetchOptions = {
method: "PUT", method: 'PUT',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
body: JSON.stringify(updateFolderData), body: JSON.stringify(updateFolderData),
}; };
@@ -99,7 +88,7 @@ async function updateFolder(
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error updating project:", error); console.error('Error updating project:', error);
throw error; throw error;
} }
} }
@@ -109,9 +98,9 @@ async function updateFolder(
*/ */
async function deleteFolder(folderId: number) { async function deleteFolder(folderId: number) {
const fetchOptions = { const fetchOptions = {
method: "DELETE", method: 'DELETE',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}; };
@@ -123,7 +112,7 @@ async function deleteFolder(folderId: number) {
throw new Error(`HTTP error! Status: ${response.status}`); throw new Error(`HTTP error! Status: ${response.status}`);
} }
} catch (error: any) { } catch (error: any) {
console.error("Error deleting project:", error); console.error('Error deleting project:', error);
throw error; throw error;
} }
} }

View File

@@ -1,6 +1,6 @@
import { ProjectType } from "@/types/project"; import { ProjectType } from '@/types/project';
import { testTypes, priorities, testRunCaseStatus } from "@/config/selection"; import { testTypes, priorities, testRunCaseStatus } from '@/config/selection';
import { HomeMessages } from "./page"; import { HomeMessages } from './page';
// aggregate folder, case, run mum // aggregate folder, case, run mum
function aggregateBasicInfo(project: ProjectType) { function aggregateBasicInfo(project: ProjectType) {
@@ -85,9 +85,4 @@ function aggregateProgress(project: ProjectType, messages: HomeMessages) {
return { series, categories }; return { series, categories };
} }
export { export { aggregateBasicInfo, aggregateTestType, aggregateTestPriority, aggregateProgress };
aggregateBasicInfo,
aggregateTestType,
aggregateTestPriority,
aggregateProgress,
};

View File

@@ -1,15 +1,15 @@
import Config from "@/config/config"; import Config from '@/config/config';
const apiServer = Config.apiServer; const apiServer = Config.apiServer;
import { RunType, RunCaseInfoType } from "@/types/run"; import { RunType, RunCaseInfoType } from '@/types/run';
async function fetchRun(runId: string) { async function fetchRun(runId: string) {
const url = `${apiServer}/runs/${runId}`; const url = `${apiServer}/runs/${runId}`;
try { try {
const response = await fetch(url, { const response = await fetch(url, {
method: "GET", method: 'GET',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}); });
@@ -20,7 +20,7 @@ async function fetchRun(runId: string) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error fetching data:", error.message); console.error('Error fetching data:', error.message);
} }
} }
@@ -29,9 +29,9 @@ async function fetchRuns(projectId: string) {
try { try {
const response = await fetch(url, { const response = await fetch(url, {
method: "GET", method: 'GET',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}); });
@@ -42,23 +42,23 @@ async function fetchRuns(projectId: string) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error fetching data:", error.message); console.error('Error fetching data:', error.message);
} }
} }
async function createRun(projectId: string) { async function createRun(projectId: string) {
const newTestRun = { const newTestRun = {
name: "untitled run", name: 'untitled run',
configurations: 0, configurations: 0,
description: "", description: '',
state: 0, state: 0,
projectId: projectId, projectId: projectId,
}; };
const fetchOptions = { const fetchOptions = {
method: "POST", method: 'POST',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
body: JSON.stringify(newTestRun), body: JSON.stringify(newTestRun),
}; };
@@ -73,16 +73,16 @@ async function createRun(projectId: string) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error creating new test run:", error); console.error('Error creating new test run:', error);
throw error; throw error;
} }
} }
async function updateRun(updateTestRun: RunType) { async function updateRun(updateTestRun: RunType) {
const fetchOptions = { const fetchOptions = {
method: "PUT", method: 'PUT',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
body: JSON.stringify(updateTestRun), body: JSON.stringify(updateTestRun),
}; };
@@ -97,16 +97,16 @@ async function updateRun(updateTestRun: RunType) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error updating run:", error); console.error('Error updating run:', error);
throw error; throw error;
} }
} }
async function deleteRun(runId: number) { async function deleteRun(runId: number) {
const fetchOptions = { const fetchOptions = {
method: "DELETE", method: 'DELETE',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}; };
@@ -118,7 +118,7 @@ async function deleteRun(runId: number) {
throw new Error(`HTTP error! Status: ${response.status}`); throw new Error(`HTTP error! Status: ${response.status}`);
} }
} catch (error: any) { } catch (error: any) {
console.error("Error deleting run:", error); console.error('Error deleting run:', error);
throw error; throw error;
} }
} }
@@ -128,9 +128,9 @@ async function fetchRunCases(runId: string) {
try { try {
const response = await fetch(url, { const response = await fetch(url, {
method: "GET", method: 'GET',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}); });
@@ -141,15 +141,15 @@ async function fetchRunCases(runId: string) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error fetching data:", error.message); console.error('Error fetching data:', error.message);
} }
} }
async function createRunCase(runId: string, caseId: number) { async function createRunCase(runId: string, caseId: number) {
const fetchOptions = { const fetchOptions = {
method: "POST", method: 'POST',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}; };
@@ -163,16 +163,16 @@ async function createRunCase(runId: string, caseId: number) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error creating new runcase:", error); console.error('Error creating new runcase:', error);
throw error; throw error;
} }
} }
async function updateRunCase(runId: string, caseId: number, status: number) { async function updateRunCase(runId: string, caseId: number, status: number) {
const fetchOptions = { const fetchOptions = {
method: "PUT", method: 'PUT',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}; };
@@ -186,16 +186,16 @@ async function updateRunCase(runId: string, caseId: number, status: number) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error updating runcase:", error); console.error('Error updating runcase:', error);
throw error; throw error;
} }
} }
async function bulkCreateRunCases(runCaseInfo: RunCaseInfoType[]) { async function bulkCreateRunCases(runCaseInfo: RunCaseInfoType[]) {
const fetchOptions = { const fetchOptions = {
method: "POST", method: 'POST',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
body: JSON.stringify(runCaseInfo), body: JSON.stringify(runCaseInfo),
}; };
@@ -210,16 +210,16 @@ async function bulkCreateRunCases(runCaseInfo: RunCaseInfoType[]) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error creating new runcase:", error); console.error('Error creating new runcase:', error);
throw error; throw error;
} }
} }
async function deleteRunCase(runId: string, caseId: number) { async function deleteRunCase(runId: string, caseId: number) {
const fetchOptions = { const fetchOptions = {
method: "DELETE", method: 'DELETE',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}; };
@@ -231,16 +231,16 @@ async function deleteRunCase(runId: string, caseId: number) {
throw new Error(`HTTP error! Status: ${response.status}`); throw new Error(`HTTP error! Status: ${response.status}`);
} }
} catch (error: any) { } catch (error: any) {
console.error("Error deleting runcase:", error); console.error('Error deleting runcase:', error);
throw error; throw error;
} }
} }
async function bulkDeleteRunCases(runCaseInfo: RunCaseInfoType[]) { async function bulkDeleteRunCases(runCaseInfo: RunCaseInfoType[]) {
const fetchOptions = { const fetchOptions = {
method: "POST", method: 'POST',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
body: JSON.stringify(runCaseInfo), body: JSON.stringify(runCaseInfo),
}; };
@@ -253,7 +253,7 @@ async function bulkDeleteRunCases(runCaseInfo: RunCaseInfoType[]) {
throw new Error(`HTTP error! Status: ${response.status}`); throw new Error(`HTTP error! Status: ${response.status}`);
} }
} catch (error: any) { } catch (error: any) {
console.error("Error deleting runcase:", error); console.error('Error deleting runcase:', error);
throw error; throw error;
} }
} }

View File

@@ -1,4 +1,4 @@
import Config from "@/config/config"; import Config from '@/config/config';
const apiServer = Config.apiServer; const apiServer = Config.apiServer;
/** /**
@@ -9,9 +9,9 @@ async function fetchProjects() {
try { try {
const response = await fetch(url, { const response = await fetch(url, {
method: "GET", method: 'GET',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}); });
@@ -22,7 +22,7 @@ async function fetchProjects() {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error fetching data:", error.message); console.error('Error fetching data:', error.message);
} }
} }
@@ -36,9 +36,9 @@ async function createProject(name: string, detail: string) {
}; };
const fetchOptions = { const fetchOptions = {
method: "POST", method: 'POST',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
body: JSON.stringify(newProjectData), body: JSON.stringify(newProjectData),
}; };
@@ -53,7 +53,7 @@ async function createProject(name: string, detail: string) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error creating new project:", error); console.error('Error creating new project:', error);
throw error; throw error;
} }
} }
@@ -68,9 +68,9 @@ async function updateProject(projectId: number, name: string, detail: string) {
}; };
const fetchOptions = { const fetchOptions = {
method: "PUT", method: 'PUT',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
body: JSON.stringify(updatedProjectData), body: JSON.stringify(updatedProjectData),
}; };
@@ -85,7 +85,7 @@ async function updateProject(projectId: number, name: string, detail: string) {
const data = await response.json(); const data = await response.json();
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error updating project:", error); console.error('Error updating project:', error);
throw error; throw error;
} }
} }
@@ -95,9 +95,9 @@ async function updateProject(projectId: number, name: string, detail: string) {
*/ */
async function deleteProject(projectId: number) { async function deleteProject(projectId: number) {
const fetchOptions = { const fetchOptions = {
method: "DELETE", method: 'DELETE',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}; };
@@ -109,7 +109,7 @@ async function deleteProject(projectId: number) {
throw new Error(`HTTP error! Status: ${response.status}`); throw new Error(`HTTP error! Status: ${response.status}`);
} }
} catch (error: any) { } catch (error: any) {
console.error("Error deleting project:", error); console.error('Error deleting project:', error);
throw error; throw error;
} }
} }

View File

@@ -1,7 +1,7 @@
import { notFound } from "next/navigation"; import { notFound } from 'next/navigation';
import { getRequestConfig } from "next-intl/server"; import { getRequestConfig } from 'next-intl/server';
const locales = ["en", "ja"]; const locales = ['en', 'ja'];
export default getRequestConfig(async ({ locale }) => { export default getRequestConfig(async ({ locale }) => {
if (!locales.includes(locale as any)) notFound(); if (!locales.includes(locale as any)) notFound();

View File

@@ -1,12 +1,12 @@
import createMiddleware from "next-intl/middleware"; import createMiddleware from 'next-intl/middleware';
import { locales, localePrefix } from "./navigation"; import { locales, localePrefix } from './navigation';
export default createMiddleware({ export default createMiddleware({
defaultLocale: "en", defaultLocale: 'en',
localePrefix, localePrefix,
locales, locales,
}); });
export const config = { export const config = {
matcher: ["/", "/(ja|en)/:path*"], matcher: ['/', '/(ja|en)/:path*'],
}; };

View File

@@ -1,10 +1,9 @@
import { createSharedPathnamesNavigation } from "next-intl/navigation"; import { createSharedPathnamesNavigation } from 'next-intl/navigation';
export const locales = ["en", "ja"] as const; export const locales = ['en', 'ja'] as const;
export const localePrefix = "always"; export const localePrefix = 'always';
export const { Link, redirect, usePathname, useRouter } = export const { Link, redirect, usePathname, useRouter } = createSharedPathnamesNavigation({ locales, localePrefix });
createSharedPathnamesNavigation({ locales, localePrefix });
export const NextUiLinkClasses = export const NextUiLinkClasses =
"data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 text-medium text-primary hover:underline hover:opacity-80 active:opacity-disabled transition-opacity underline-offset-4 dark:text-white"; 'data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 text-medium text-primary hover:underline hover:opacity-80 active:opacity-disabled transition-opacity underline-offset-4 dark:text-white';

View File

@@ -1,37 +1,37 @@
import { nextui } from "@nextui-org/theme"; import { nextui } from '@nextui-org/theme';
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
module.exports = { module.exports = {
content: [ content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}", './pages/**/*.{js,ts,jsx,tsx,mdx}',
"./components/**/*.{js,ts,jsx,tsx,mdx}", './components/**/*.{js,ts,jsx,tsx,mdx}',
"./app/**/*.{js,ts,jsx,tsx,mdx}", './app/**/*.{js,ts,jsx,tsx,mdx}',
"./src/app/**/*.{js,ts,jsx,tsx,mdx}", './src/app/**/*.{js,ts,jsx,tsx,mdx}',
"./node_modules/@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}", './node_modules/@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}',
], ],
theme: { theme: {
extend: {}, extend: {},
}, },
darkMode: "class", darkMode: 'class',
plugins: [ plugins: [
nextui({ nextui({
themes: { themes: {
light: { light: {
colors: { colors: {
primary: { primary: {
DEFAULT: "#030712", DEFAULT: '#030712',
foreground: "#FFFFFF", foreground: '#FFFFFF',
}, },
focus: "#030712", focus: '#030712',
}, },
}, },
dark: { dark: {
colors: { colors: {
primary: { primary: {
DEFAULT: "#1F883D", DEFAULT: '#1F883D',
foreground: "#FFFFFF", foreground: '#FFFFFF',
}, },
focus: "#1F883D", focus: '#1F883D',
}, },
}, },
}, },

View File

@@ -1,4 +1,4 @@
import { CaseType } from "./case"; import { CaseType } from './case';
export type FolderType = { export type FolderType = {
id: number; id: number;

View File

@@ -1,4 +1,4 @@
import {SVGProps} from "react"; import { SVGProps } from 'react';
export type IconSvgProps = SVGProps<SVGSVGElement> & { export type IconSvgProps = SVGProps<SVGSVGElement> & {
size?: number; size?: number;

View File

@@ -1,5 +1,5 @@
import { FolderType } from "./folder"; import { FolderType } from './folder';
import { RunType } from "./run"; import { RunType } from './run';
export type ProjectType = { export type ProjectType = {
id: number; id: number;

View File

@@ -29,10 +29,10 @@ type RunStatusCountType = {
type ProgressSeriesType = { type ProgressSeriesType = {
name: string; name: string;
data: number[]; data: number[];
} };
type RunsMessages = { type RunsMessages = {
runList: string, runList: string;
id: string; id: string;
name: string; name: string;
description: string; description: string;
@@ -44,11 +44,11 @@ type RunsMessages = {
}; };
type RunMessages = { type RunMessages = {
backToRuns: string, backToRuns: string;
updating: string; updating: string;
update: string; update: string;
progress: string, progress: string;
refresh: string, refresh: string;
id: string; id: string;
title: string; title: string;
pleaseEnter: string; pleaseEnter: string;
@@ -78,12 +78,4 @@ type RunMessages = {
noCasesFound: string; noCasesFound: string;
}; };
export { export { RunType, RunCaseType, RunCaseInfoType, RunStatusCountType, ProgressSeriesType, RunsMessages, RunMessages };
RunType,
RunCaseType,
RunCaseInfoType,
RunStatusCountType,
ProgressSeriesType,
RunsMessages,
RunMessages,
};

View File

@@ -1,6 +1,6 @@
'use client' 'use client';
import { usePathname } from 'next/navigation' import { usePathname } from 'next/navigation';
import { useState, useEffect } from "react"; import { useState, useEffect } from 'react';
type ProjectFolderIds = { type ProjectFolderIds = {
projectId: number | null; projectId: number | null;
@@ -12,21 +12,19 @@ type ProjectFolderIds = {
* Example: For the path '/projects/1/folders/3/cases', projectId would be 1 and folderId would be 3. * Example: For the path '/projects/1/folders/3/cases', projectId would be 1 and folderId would be 3.
*/ */
const useGetCurrentIds = (): ProjectFolderIds => { const useGetCurrentIds = (): ProjectFolderIds => {
const pathname = usePathname() const pathname = usePathname();
const [projectId, setProjectId] = useState<number | null>(null); const [projectId, setProjectId] = useState<number | null>(null);
const [folderId, setFolderId] = useState<number | null>(null); const [folderId, setFolderId] = useState<number | null>(null);
useEffect(() => { useEffect(() => {
const currentPath = pathname; const currentPath = pathname;
const pathSegments = currentPath.split("/").filter(Boolean); const pathSegments = currentPath.split('/').filter(Boolean);
const projectIdIndex = pathSegments.indexOf("projects") + 1; const projectIdIndex = pathSegments.indexOf('projects') + 1;
const folderIdIndex = pathSegments.indexOf("folders") + 1; const folderIdIndex = pathSegments.indexOf('folders') + 1;
const newProjectId = const newProjectId = projectIdIndex !== -1 ? parseInt(pathSegments[projectIdIndex], 10) : null;
projectIdIndex !== -1 ? parseInt(pathSegments[projectIdIndex], 10) : null; const newFolderId = folderIdIndex !== -1 ? parseInt(pathSegments[folderIdIndex], 10) : null;
const newFolderId =
folderIdIndex !== -1 ? parseInt(pathSegments[folderIdIndex], 10) : null;
setProjectId(newProjectId); setProjectId(newProjectId);
setFolderId(newFolderId); setFolderId(newFolderId);

16
package-lock.json generated
View File

@@ -9,6 +9,7 @@
"version": "1.0.0", "version": "1.0.0",
"devDependencies": { "devDependencies": {
"@vitest/coverage-v8": "^1.6.0", "@vitest/coverage-v8": "^1.6.0",
"prettier": "^3.2.5",
"vitest": "^1.6.0" "vitest": "^1.6.0"
} }
}, },
@@ -1504,6 +1505,21 @@
"node": "^10 || ^12 || >=14" "node": "^10 || ^12 || >=14"
} }
}, },
"node_modules/prettier": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
"integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/pretty-format": { "node_modules/pretty-format": {
"version": "29.7.0", "version": "29.7.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",

View File

@@ -3,11 +3,13 @@
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"scripts": { "scripts": {
"format": "prettier --write frontend/**/*.{js,ts,json} backend/**/*.{js,ts,json}",
"test": "vitest", "test": "vitest",
"coverage": "vitest run --coverage" "coverage": "vitest run --coverage"
}, },
"devDependencies": { "devDependencies": {
"@vitest/coverage-v8": "^1.6.0", "@vitest/coverage-v8": "^1.6.0",
"prettier": "^3.2.5",
"vitest": "^1.6.0" "vitest": "^1.6.0"
} }
} }