Skip to content

Commit f414e18

Browse files
author
ChadKluck
committed
updating validator, transform, and test examples
1 parent 99d549e commit f414e18

File tree

6 files changed

+106
-40
lines changed

6 files changed

+106
-40
lines changed

application-infrastructure/src/config/validations.js

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,26 @@ const statusCodePathParameter = (code) => {
2929
return statusCodes.some((statusCode) => statusCode.code === code);
3030
};
3131

32+
/**
33+
* Ensure id is in 'G-<8-char-hex>' format
34+
* @param {string} id - The id to validate
35+
* @returns {boolean} - True if the id is valid, false otherwise
36+
*/
3237
const idPathParameter = (id) => {
3338
if (!id) return false;
34-
if (!isString(id)) return false;
35-
// separate id by -
36-
const [char, gid] = id.split("-");
37-
if (!char || !gid) return false;
38-
if (!isStringOfNumbers(gid)) return false;
39-
// check if char is a letter
40-
if (!char.match(/[A-Z]/)) return false;
41-
// check if number is a number within range
42-
const idNumber = parseInt(gid, 10);
43-
if (isNaN(idNumber)) return false; // not a number
44-
if (idNumber < 1 || idNumber > 15) return false;
39+
if (!char.match(/^G\-[a-f0-9]{8}$/)) return false;
40+
return true;
41+
};
42+
43+
/**
44+
* Ensure players is a number between 1 and 10
45+
* @param {string} players - The players to validate
46+
* @returns {boolean} - True if the players is valid, false otherwise
47+
*/
48+
const playersQueryParameter = (players) => {
49+
if (!players) return false;
50+
if (!isStringOfNumbers(players)) return false;
51+
if (players < 1 || players > 10) return false;
4552
return true;
4653
};
4754

@@ -55,11 +62,13 @@ module.exports = {
5562
parameters: {
5663
pathParameters: {
5764
code: statusCodePathParameter,
58-
id: idPathParameter
59-
}
60-
//, queryParameter: {}
61-
//, headerParameter: {}
62-
//, cookieParameter: {}
63-
//, bodyParameter: {}
65+
id: idPathParameter,
66+
},
67+
queryParameters: {
68+
players: playersQueryParameter,
69+
},
70+
// headerParameters: {},
71+
// cookieParameters: {},
72+
// bodyParameters: {},
6473
}
6574
};
Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
{
22
"count": 15,
33
"items": [
4-
{ "game_id": "G-1", "display_name": "Falken's Maze" },
5-
{ "game_id": "G-2", "display_name": "Black Jack" },
6-
{ "game_id": "G-3", "display_name": "Gin Rummy" },
7-
{ "game_id": "G-4", "display_name": "Hearts" },
8-
{ "game_id": "G-5", "display_name": "Bridge" },
9-
{ "game_id": "G-6", "display_name": "Checkers" },
10-
{ "game_id": "G-7", "display_name": "Chess" },
11-
{ "game_id": "G-8", "display_name": "Poker" },
12-
{ "game_id": "G-9", "display_name": "Fighter Combat" },
13-
{ "game_id": "G-10", "display_name": "Guerrilla Engagement" },
14-
{ "game_id": "G-11", "display_name": "Desert Warfare" },
15-
{ "game_id": "G-12", "display_name": "Air-To-Ground Actions" },
16-
{ "game_id": "G-13", "display_name": "Theaterwide Tactical Warfare" },
4+
{ "id": "G-cea73c4b", "display_name": "Falken's Maze" },
5+
{ "id": "G-8f494e5b", "display_name": "Black Jack" },
6+
{ "id": "G-4a09ad1c", "display_name": "Gin Rummy" },
7+
{ "id": "G-73b8058c", "display_name": "Hearts" },
8+
{ "id": "G-f1cf6201", "display_name": "Bridge" },
9+
{ "id": "G-fd325ad0", "display_name": "Checkers" },
10+
{ "id": "G-c170b666", "display_name": "Chess" },
11+
{ "id": "G-0ac0647a", "display_name": "Poker" },
12+
{ "id": "G-c12ac225", "display_name": "Fighter Combat" },
13+
{ "id": "G-7fb4f254", "display_name": "Guerrilla Engagement" },
14+
{ "id": "G-f07993c7", "display_name": "Desert Warfare" },
15+
{ "id": "G-03cbb530", "display_name": "Air-To-Ground Actions" },
16+
{ "id": "G-603f6cd0", "display_name": "Theaterwide Tactical Warfare" },
1717
{
18-
"game_id": "G-14",
18+
"id": "G-2e22e975",
1919
"display_name": "Theaterwide Biotoxic and Chemical Warfare"
2020
},
21-
{ "game_id": "G-15", "display_name": "Global Thermonuclear War" }
21+
{ "id": "G-dd2ea1b3", "display_name": "Global Thermonuclear War" }
2222
]
2323
}

application-infrastructure/src/tests/index.mjs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { readFile } from 'fs/promises';
88
import { expect } from "chai";
99

1010
import validations from '../config/validations.js';
11+
import utils from '../utils/index.js';
1112
import { view as exampleView } from '../views/example.view.js';
1213

1314

@@ -53,7 +54,7 @@ describe('Test validations from config/validations.js', () => {
5354
});
5455
});
5556

56-
it('should reject invalid org codes', () => {
57+
it('should reject invalid status codes', () => {
5758
const invalidCodes = ['', '123', 'ABCD', 'A1', '1A', 'AAA'];
5859
invalidCodes.forEach(code => {
5960
expect(validations.parameters.pathParameters.code(code), `Status code ${code} should be invalid`).to.be.false;
@@ -112,6 +113,41 @@ describe('Test validations from config/validations.js', () => {
112113
})
113114
});
114115

116+
/* ****************************************************************************
117+
* Utils
118+
*/
119+
120+
describe('Test utils', () => {
121+
describe('utils.hash.hashLast8', () => {
122+
it('should return a string of length 8', () => {
123+
const input = 'example';
124+
const result = utils.hash.hashLast8(input);
125+
expect(result).to.be.a('string');
126+
expect(result).to.have.lengthOf(8);
127+
});
128+
129+
it('should return a different string for different inputs', () => {
130+
const input1 = 'example1';
131+
const input2 = 'example2';
132+
const result1 = utils.hash.hashLast8(input1);
133+
const result2 = utils.hash.hashLast8(input2);
134+
expect(result1).to.not.equal(result2);
135+
});
136+
137+
it('should return the same string for the same input', () => {
138+
const input = 'example';
139+
const result1 = utils.hash.hashLast8(input);
140+
const result2 = utils.hash.hashLast8(input);
141+
expect(result1).to.equal(result2);
142+
});
143+
144+
it('should return a string containing only valid characters', () => {
145+
const input = 'example';
146+
const result = utils.hash.hashLast8(input);
147+
expect(result).to.match(/^[a-f0-9]+$/);
148+
});
149+
});
150+
});
115151

116152
/* ****************************************************************************
117153
* Views
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const crypto = require('crypto');
2+
3+
/**
4+
* Hash a string using SHA256 and return the last 8 characters
5+
* @param {string} input - The string to hash
6+
* @returns {string} The last 8 characters of the SHA256 hash
7+
*/
8+
const hashLast8 = (input) => {
9+
return crypto.createHash('sha256').update(input).digest('hex').slice(-8);
10+
};
11+
12+
module.exports = { hashLast8 };
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
const func = require('./helper-functions.js');
3+
const hash = require('./hash.js');
34

45
module.exports = {
5-
func
6+
func,
7+
hash
68
};

application-infrastructure/src/views/example.view.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
A view should be called from the controller, or if the view is cached, from the service.
33
*/
44

5-
const { tools: {Timer} } = require("@63klabs/cache-data");
6-
const { DebugAndLog } = require("@63klabs/cache-data/src/lib/tools");
5+
const {
6+
tools: {
7+
Timer
8+
}
9+
} = require("@63klabs/cache-data");
10+
11+
const utils = require('../utils');
712

813
const logIdentifier = "Example View";
914

@@ -18,18 +23,20 @@ const filter = (dataItem = null) => {
1823
return include;
1924
}
2025

21-
// For this data we want to assign an index to each item in the view, so we can track it
22-
let index = 0;
23-
2426
/**
2527
* Generic transformer
2628
* @param {object} data
2729
* @returns {object} data
2830
*/
2931
const transform = (data) => {
3032

33+
// take data and create an 8 character hash
34+
// since we only expect a list of <20 games this is okay for an example
35+
// using sha256, create a hash and retain the last 8 characters
36+
const hashId = utils.hash.hashLast8(data);
37+
3138
const returnData = {
32-
game_id: `G-${++index}`,
39+
game_id: `G-${hashId}`,
3340
display_name: data
3441
};
3542

0 commit comments

Comments
 (0)