Bladeren bron

:pencil: backend | added some jsdoc style comments to start

master
TOJ 5 jaren geleden
bovenliggende
commit
7bb9b5e54a

+ 4
- 1
backend/README.md Bestand weergeven

50
 
50
 
51
 ## :pill: Tests & Code Quality
51
 ## :pill: Tests & Code Quality
52
 
52
 
53
-TBD
53
+Tests are run with AVA with code coverage reporting via nyc. Look at the example test for ideas, as well as the [ava documentation](https://github.com/avajs/ava/blob/main/docs/01-writing-tests.md)
54
+* Run tests with coverage report with `npm test`
54
 
55
 
55
 ## :heart: Built With
56
 ## :heart: Built With
56
 
57
 
58
 * [Objection](https://vincit.github.io/objection.js/) - Light ORM
59
 * [Objection](https://vincit.github.io/objection.js/) - Light ORM
59
 * [Knex.js](https://knexjs.org/) - Query builder
60
 * [Knex.js](https://knexjs.org/) - Query builder
60
 * [Schiwfty](https://hapipal.com/docs/schwifty) - Model layer
61
 * [Schiwfty](https://hapipal.com/docs/schwifty) - Model layer
62
+* [Ava](https://github.com/avajs/ava) - Easy testing
63
+* [Nyc](https://github.com/istanbuljs/nyc) - Test coverage with Istanbul's CLI

+ 17
- 0
backend/lib/index.js Bestand weergeven

2
 const MembershipPlugin = require('./plugins/membership');
2
 const MembershipPlugin = require('./plugins/membership');
3
 const TestPlugin = require('./plugins/example');
3
 const TestPlugin = require('./plugins/example');
4
 
4
 
5
+/**
6
+ * A Hapi server instance
7
+ * @typedef {Object} Server
8
+ */
9
+
10
+/**
11
+ * A plugin for Hapi
12
+ * @typedef {Object} Plugin
13
+ */
14
+
5
 exports.plugin = {
15
 exports.plugin = {
6
     name: 'main-app-plugin',
16
     name: 'main-app-plugin',
17
+
18
+    /**
19
+     * Main Hapi plugin that grabs all our
20
+     * other plugins to create the API app
21
+     * @param {Server} server
22
+     * @param {Object} options
23
+     */
7
     register: async (server, options) => {
24
     register: async (server, options) => {
8
 
25
 
9
         await server.register(TestPlugin, {
26
         await server.register(TestPlugin, {

+ 6
- 0
backend/lib/plugins/example.js Bestand weergeven

3
 module.exports = {
3
 module.exports = {
4
     name: 'myPlugin',
4
     name: 'myPlugin',
5
     version: '1.0.0',
5
     version: '1.0.0',
6
+
7
+    /**
8
+     * Example route registration
9
+     * @param {Server} server
10
+     * @param {Object} options
11
+     */
6
     register: async (server, options) => {
12
     register: async (server, options) => {
7
         // Create a route for example
13
         // Create a route for example
8
         server.route(example)
14
         server.route(example)

+ 15
- 0
backend/lib/routes/example/base.js Bestand weergeven

1
 module.exports = {
1
 module.exports = {
2
     method: 'GET',
2
     method: 'GET',
3
     path: '/',
3
     path: '/',
4
+
5
+    /**
6
+     * Our request hanlder callback
7
+     * @param {*} request
8
+     * @param {*} h
9
+     * @returns {Object}
10
+     */
4
     handler: async function (request, h) {
11
     handler: async function (request, h) {
5
         return { test: 'hello, world' }
12
         return { test: 'hello, world' }
6
     },
13
     },
14
+
15
+    /**
16
+     * Our route options
17
+     * @param {string} description - Title for our swagger docs
18
+     * @param {string} notes - Subtitle for our swagger docs
19
+     * @param {Array} tags - Our tags
20
+     * @param {boolean} auth - The authentication scheme
21
+     */
7
     options: {
22
     options: {
8
         description: 'Test',
23
         description: 'Test',
9
         notes: 'This is an example route',
24
         notes: 'This is an example route',

+ 56
- 1
backend/lib/services/user.js Bestand weergeven

5
 const Schmervice = require('@hapipal/schmervice');
5
 const Schmervice = require('@hapipal/schmervice');
6
 const SecurePassword = require('secure-password');
6
 const SecurePassword = require('secure-password');
7
 
7
 
8
+/** Class for methods used in the User plugin */
8
 module.exports = class UserService extends Schmervice.Service {
9
 module.exports = class UserService extends Schmervice.Service {
10
+    /**
11
+     * Unsure of what our constructor does
12
+     * @param  {...any} args
13
+     */
9
     constructor(...args) {
14
     constructor(...args) {
10
         super(...args)
15
         super(...args)
11
         const pwd = new SecurePassword()
16
         const pwd = new SecurePassword()
14
             verify: Util.promisify(pwd.verify.bind(pwd))
19
             verify: Util.promisify(pwd.verify.bind(pwd))
15
         }
20
         }
16
     }
21
     }
22
+
23
+    /**
24
+     * Use knex to find users with id column
25
+     * @param {number} id
26
+     * @param {*} txn
27
+     * @returns
28
+     */
17
     async findById(id, txn) {
29
     async findById(id, txn) {
18
         const { User } = this.server.models()
30
         const { User } = this.server.models()
19
         return await User.query(txn).throwIfNotFound().findById(id)
31
         return await User.query(txn).throwIfNotFound().findById(id)
20
     }
32
     }
33
+
34
+    /**
35
+     * Use knew to find first user with username
36
+     * @param {*} username
37
+     * @param {*} txn
38
+     * @returns
39
+     */
21
     async findByUsername(username, txn) {
40
     async findByUsername(username, txn) {
22
         const { User } = this.server.models()
41
         const { User } = this.server.models()
23
 
42
 
24
         return await User.query(txn).throwIfNotFound().first().where({ username })
43
         return await User.query(txn).throwIfNotFound().first().where({ username })
25
     }
44
     }
45
+
46
+    /**
47
+     * Signup function
48
+     * @param {*} param0
49
+     * @param {*} txn
50
+     * @returns
51
+     */
26
     async signup({ password, ...userInfo }, txn) {
52
     async signup({ password, ...userInfo }, txn) {
27
         const { User } = this.server.models()
53
         const { User } = this.server.models()
28
         const { id } = await User.query(txn).insert(userInfo)
54
         const { id } = await User.query(txn).insert(userInfo)
29
         await this.changePassword(id, password, txn)
55
         await this.changePassword(id, password, txn)
30
         return id
56
         return id
31
     }
57
     }
58
+
59
+    /**
60
+     * Updates user's info
61
+     * @param {number} id
62
+     * @param {*} param1
63
+     * @param {*} txn
64
+     * @returns
65
+     */
32
     async update(id, { password, ...userInfo }, txn) {
66
     async update(id, { password, ...userInfo }, txn) {
33
         const { User } = this.server.models()
67
         const { User } = this.server.models()
34
 
68
 
42
 
76
 
43
         return id
77
         return id
44
     }
78
     }
79
+
80
+    /**
81
+     * Self explanatory
82
+     * @param {*} param0
83
+     * @param {*} txn
84
+     * @returns
85
+     */
45
     async login({ email, password }, txn) {
86
     async login({ email, password }, txn) {
46
         const { User } = this.server.models()
87
         const { User } = this.server.models()
47
 
88
 
51
             .where({ user_email: email })
92
             .where({ user_email: email })
52
 
93
 
53
 
94
 
54
-        // Uncomment to run password check using SecurePassword
95
+        /** Uncomment to run password check using SecurePassword */
55
         // const passwordCheck = await this.pwd.verify(Buffer.from(password), user.password)
96
         // const passwordCheck = await this.pwd.verify(Buffer.from(password), user.password)
56
         // if (passwordCheck === SecurePassword.VALID_NEEDS_REHASH) {
97
         // if (passwordCheck === SecurePassword.VALID_NEEDS_REHASH) {
57
         //     await this.changePassword(user.id, password, txn)
98
         //     await this.changePassword(user.id, password, txn)
62
 
103
 
63
         return user
104
         return user
64
     }
105
     }
106
+
107
+    /**
108
+     * Create a token to be sent in request headers
109
+     * @param {User} user
110
+     * @returns {Token}
111
+     */
65
     createToken(user) {
112
     createToken(user) {
66
         const key = this.server.registrations['main-app-plugin'].options.jwtKey
113
         const key = this.server.registrations['main-app-plugin'].options.jwtKey
67
 
114
 
77
             ttlSec: 4 * 60 * 60 // 7 days
124
             ttlSec: 4 * 60 * 60 // 7 days
78
         })
125
         })
79
     }
126
     }
127
+
128
+    /**
129
+     * Use knex to try to change password entry
130
+     * @param {number} id
131
+     * @param {string} password
132
+     * @param {*} txn
133
+     * @returns {number}
134
+     */
80
     async changePassword(id, password, txn) {
135
     async changePassword(id, password, txn) {
81
         const { User } = this.server.models()
136
         const { User } = this.server.models()
82
 
137
 

+ 1
- 1
backend/package.json Bestand weergeven

8
     "migrate": "knex migrate:latest",
8
     "migrate": "knex migrate:latest",
9
     "unmigrate": "knex migrate:down",
9
     "unmigrate": "knex migrate:down",
10
     "seed": "knex seed:run",
10
     "seed": "knex seed:run",
11
-    "test": "nyc ava"
11
+    "test": "nyc ava --timeout=3000"
12
   },
12
   },
13
   "author": "TOJ",
13
   "author": "TOJ",
14
   "license": "UNLICENSED",
14
   "license": "UNLICENSED",

+ 11
- 7
backend/server/manifest.js Bestand weergeven

5
 const Schwifty = require('@hapipal/schwifty');
5
 const Schwifty = require('@hapipal/schwifty');
6
 const HapiSwagger = require('hapi-swagger');
6
 const HapiSwagger = require('hapi-swagger');
7
 
7
 
8
-// Pull .env into process.env
8
+/** Pull .env into process.env */
9
 Dotenv.config({ path: `${__dirname}/.env` });
9
 Dotenv.config({ path: `${__dirname}/.env` });
10
 
10
 
11
-// Glue manifest as a confidence store
11
+/** Glue manifest as a confidence store */
12
 module.exports = new Confidence.Store({
12
 module.exports = new Confidence.Store({
13
     server: {
13
     server: {
14
         host: process.env.API_HOST,
14
         host: process.env.API_HOST,
34
     },
34
     },
35
     register: {
35
     register: {
36
         plugins: [
36
         plugins: [
37
+
38
+            /** Main app */
37
             {
39
             {
38
-                plugin: '../lib', // Main plugin
40
+                plugin: '../lib',
39
                 routes: {
41
                 routes: {
40
                     prefix: '/api'
42
                     prefix: '/api'
41
                 },
43
                 },
46
                             $param: 'APP_SECRET',
48
                             $param: 'APP_SECRET',
47
                             $default: 'app-secret'
49
                             $default: 'app-secret'
48
                         },
50
                         },
49
-                        production: { // In production do not default to "app-secret"
51
+                        // Use .env file in production
52
+                        production: {
50
                             $param: 'APP_SECRET'
53
                             $param: 'APP_SECRET'
51
                         }
54
                         }
52
                     }
55
                     }
53
                 }
56
                 }
54
             },
57
             },
55
-            // Documentaion deps
56
-            Inert,
57
-            Vision,
58
+
59
+            /** Documentaion plugins */
60
+            Inert, Vision,
58
             {
61
             {
59
                 plugin: HapiSwagger,
62
                 plugin: HapiSwagger,
60
                 options: {
63
                 options: {
61
                     info: { title: 'Test API Documentation' }
64
                     info: { title: 'Test API Documentation' }
62
                 }
65
                 }
63
             },
66
             },
67
+            /** Model and knex integration */
64
             {
68
             {
65
                 plugin: Schwifty,
69
                 plugin: Schwifty,
66
                 options: {
70
                 options: {

Laden…
Annuleren
Opslaan