瀏覽代碼

Merge branch 'brian_tests' of fyindr/siimee into dev

brian_lifecycle_docs
maeda 2 年之前
父節點
當前提交
2a45594bb7

+ 35
- 28
backend/lib/routes/membership/active.js 查看文件

@@ -81,51 +81,58 @@ module.exports = {
81 81
             const groupingIds = groupings.map(grouping => grouping.grouping_id)
82 82
             const memberships =
83 83
                 await membershipService.findMemberships(groupingIds)
84
-            const profileIds = memberships
85
-                .filter(membership => membership.profile_id != profileId)
84
+            let profileIds = memberships
85
+                .filter(membership => membership.profile_id !== profileId)
86 86
                 .map(membership => membership.profile_id)
87
-
87
+            profileIds =
88
+                !profileIds.length || profileIds[0] === undefined
89
+                    ? []
90
+                    : profileIds
88 91
             /** Assemble complete profiles to reference and pass */
89 92
             const completedProfiles = !profileIds.length
90 93
                 ? []
91 94
                 : await profileService.getProfilesFor(profileIds, 'participant')
92
-
93 95
             /**
94 96
              * Heavily process the result by storing just a profile_id
95 97
              * and attach complete profiles
96 98
              * !: This still assumes only ONE other profile
97 99
              * TODO: should be refactored to many other profiles
98 100
              */
99
-            const reformattedGroupings = groupings.length
100
-                ? groupings.map(grouping => {
101
-                      const otherPid = grouping.profiles.find(
102
-                          p => p.profile_id != profileId,
103
-                      ).profile_id
104
-                      grouping.profile = completedProfiles.find(
105
-                          p => otherPid == p.profile_id,
106
-                      )
107
-                      grouping.is_paired = _activeGroupingIds(
108
-                          memberships,
109
-                      ).includes(grouping.grouping_id)
110
-                      delete grouping.profiles
111
-                      return grouping
112
-                  })
113
-                : []
114
-
101
+            const reformattedGroupings =
102
+                groupings.length && completedProfiles.length
103
+                    ? groupings.map(grouping => {
104
+                          const otherPid = grouping.profiles.find(
105
+                              p => p.profile_id != profileId,
106
+                          ).profile_id
107
+                          grouping.profile = completedProfiles.find(
108
+                              p => otherPid == p.profile_id,
109
+                          )
110
+                          grouping.is_paired = _activeGroupingIds(
111
+                              memberships,
112
+                          ).includes(grouping.grouping_id)
113
+                          delete grouping.profiles
114
+                          return grouping
115
+                      })
116
+                    : []
115 117
             /** Grabs revealTags */
116
-            const revealTags = await profileService.getTagsFor(
117
-                profileIds,
118
-                groupingIds,
119
-                'reveal',
120
-            )
118
+            const revealTags =
119
+                profileIds.length && groupingIds.length
120
+                    ? await profileService.getTagsFor(
121
+                          profileIds,
122
+                          groupingIds,
123
+                          'reveal',
124
+                      )
125
+                    : undefined
121 126
 
122 127
             /** If the revealTags exist, the completedProfile's hidden info is
123 128
              * removed and replaced with the completedProfile's user information
124 129
              * Otherwise the completedProfiles remain unchanged
125 130
              */
126
-            const user = await userService.findById(
127
-                completedProfiles.map(p => p.user_id),
128
-            )
131
+            const user = completedProfiles.length
132
+                ? await userService.findById(
133
+                      completedProfiles.map(p => p.user_id),
134
+                  )
135
+                : undefined
129 136
 
130 137
             // TODO: Refactor this. Is it safe to always use completedProfiles[0]?
131 138
             if (revealTags && user) {

+ 2
- 1
backend/lib/routes/profile/get.js 查看文件

@@ -28,7 +28,8 @@ module.exports = {
28 28
     options: {
29 29
         ...pluginConfig.docs,
30 30
         tags: ['api'],
31
-        auth: 'default_jwt',
31
+        // auth: 'default_jwt',
32
+        auth: false,
32 33
         cors: true,
33 34
         handler: async function (request, h) {
34 35
             const { profile_id } = request.params

+ 1
- 3
backend/lib/routes/profile/score.js 查看文件

@@ -53,9 +53,7 @@ module.exports = {
53 53
             const distanceUnit = request.query.unit
54 54
                 ? request.query.unit
55 55
                 : 'mile'
56
-            const duration = request.query.duration.includes('-')
57
-                ? request.query.duration.split('-')[0]
58
-                : request.query.duration
56
+            const duration = request.query.duration
59 57
             const presence =
60 58
                 request.query.presence === 'in_person'
61 59
                     ? 'onsite'

+ 14
- 1
backend/lib/services/profile/index.js 查看文件

@@ -34,6 +34,16 @@ module.exports = class ProfileService extends Schmervice.Service {
34 34
                 if (!desc.is_active) return
35 35
                 this.tagLookup[desc.tag_id] = desc
36 36
             })
37
+            /* EXAMPLE:
38
+             * this.tagLookup : {
39
+             * '1' : {
40
+             * tag_id: 1,
41
+             * tag_category: 'reveal',
42
+             * tag_description: 'verified',
43
+             * is_active: 1
44
+             * }
45
+             * }
46
+             * */
37 47
         } else return
38 48
     }
39 49
     /**
@@ -368,6 +378,7 @@ module.exports = class ProfileService extends Schmervice.Service {
368 378
         if (!profileId.length || !groupingId.length) {
369 379
             return associations
370 380
         } else {
381
+            // NOTE: all queries do not fire in Swagger API (whereIn clauses??)
371 382
             associations = groupingId
372 383
                 ? await TagAssociation.query()
373 384
                       .where('grouping_id', groupingId)
@@ -376,7 +387,9 @@ module.exports = class ProfileService extends Schmervice.Service {
376 387
             return associations
377 388
                 .map(assoc => ({
378 389
                     ...assoc,
379
-                    tag: this.tagLookup[assoc.tag_id],
390
+                    tag: !this.tagLookup[assoc.tag_id]
391
+                        ? {}
392
+                        : this.tagLookup[assoc.tag_id],
380 393
                 }))
381 394
                 .filter(tagWithAssoc => {
382 395
                     return category

+ 1
- 1
backend/lib/services/user.js 查看文件

@@ -9,7 +9,7 @@ const SecurePassword = require('secure-password')
9 9
 // Configuration for Brevo
10 10
 const Brevo = require('@getbrevo/brevo')
11 11
 const apiInstance = new Brevo.TransactionalEmailsApi()
12
-const apiKey = apiInstance.authentications.apiKey
12
+const apiKey = apiInstance.apiClient.authentications['api-key']
13 13
 apiKey.apiKey = process.env.BREVO_KEY
14 14
 const sendSmtpEmail = new Brevo.SendSmtpEmail()
15 15
 

+ 69
- 4
backend/tests/membership.spec.js 查看文件

@@ -7,13 +7,15 @@ const Hapi = require('@hapi/hapi')
7 7
 const plugin = require('../lib/plugins/membership')
8 8
 
9 9
 const ProfileService = require('../lib/services/profile')
10
+const UserService = require('../lib/services/user')
10 11
 const MembershipService = require('../lib/services/membership')
11 12
 
12 13
 const Profile = require('../lib/models/profile')
13 14
 const Grouping = require('../lib/models/grouping')
14 15
 const Membership = require('../lib/models/membership')
15 16
 const Tag = require('../lib/models/tag')
16
-const ZipCode = require('../lib/models/zip-code')
17
+const TagAssociation = require('../lib/models/tag-association')
18
+const User = require('../lib/models/user')
17 19
 const Aspect = require('../lib/models/aspect')
18 20
 const AspectLabel = require('../lib/models/aspect_label')
19 21
 
@@ -34,7 +36,11 @@ const mockReturn = {
34 36
         responses: [],
35 37
         tags: [],
36 38
     },
37
-    memberships: [{ membership_id: 1, grouping_id: 1 }],
39
+    memberships: [
40
+        { membership_id: 1, grouping_id: 1, profile_id: 99 },
41
+        { membership_id: 1, grouping_id: 1, profile_id: 1 },
42
+        { membership_id: 1, grouping_id: 1, profile_id: 2 },
43
+    ],
38 44
     groupings: [
39 45
         { grouping_id: 1, profiles: [{ profile_id: 1 }, { profile_id: 99 }] },
40 46
     ],
@@ -79,7 +85,36 @@ const mockReturn = {
79 85
             user: { user_name: 'jill' },
80 86
         },
81 87
     ],
82
-    tags: [],
88
+    tag_associations: [
89
+        {
90
+            tag_association_id: 1,
91
+            profile_id: 99,
92
+            grouping_id: 1,
93
+            tag_id: 7,
94
+            is_deleted: 0,
95
+        },
96
+        {
97
+            tag_association_id: 2,
98
+            profile_id: 1,
99
+            grouping_id: 1,
100
+            tag_id: 8,
101
+            is_deleted: 0,
102
+        },
103
+    ],
104
+    tags: [
105
+        {
106
+            tag_id: 7,
107
+            tag_category: 'reveal',
108
+            tag_description: 'user_name',
109
+            is_active: 1,
110
+        },
111
+        {
112
+            tag_id: 8,
113
+            tag_category: 'reveal',
114
+            tag_description: 'user_email',
115
+            is_active: 1,
116
+        },
117
+    ],
83 118
     labels: [
84 119
         { aspect_id: 1, a: 100, b: 100 },
85 120
         { aspect_id: 2, a: 100, b: 200 },
@@ -92,6 +127,16 @@ const mockReturn = {
92 127
         { aspect_id: 3, 1: 111, 2: 112, 3: 113, 4: 114 },
93 128
         { aspect_id: 4, 1: 111, 2: 111, 3: 111, 4: 111 },
94 129
     ],
130
+    user: [
131
+        {
132
+            user_id: 99,
133
+            user_name: 'bob',
134
+            user_email: 'bob@testemail.com',
135
+            is_admin: 0,
136
+            is_poster: 0,
137
+            is_verified: 0,
138
+        },
139
+    ],
95 140
 }
96 141
 const pathToTest = {
97 142
     method: 'GET',
@@ -121,9 +166,10 @@ test('path /<profile_id> should return ok', async t => {
121 166
         Membership,
122 167
         Grouping,
123 168
         Tag,
169
+        TagAssociation,
170
+        User,
124 171
     })
125 172
 
126
-    // server.registerService(ProfileService)
127 173
     /**
128 174
      * Register Routes and Services as usual
129 175
      */
@@ -133,9 +179,21 @@ test('path /<profile_id> should return ok', async t => {
133 179
      * !: Janky - might be better to temp knex sqlite instance
134 180
      */
135 181
     server.services()['profileService'] = new ProfileService(server)
182
+    server.services()['membershipService'] = new MembershipService(server)
183
+    server.services()['userService'] = new UserService(server)
184
+
136 185
     stub(server.models()['Tag'], 'query').returns(mockReturn.tags)
137 186
     stub(server.models()['AspectLabel'], 'query').returns(mockReturn.labels)
138 187
     stub(server.models()['Aspect'], 'query').returns(mockReturn.aspects)
188
+    stub(server.models()['User'], 'query').returns({
189
+        throwIfNotFound: () => ({
190
+            first: () => ({
191
+                where: () => {
192
+                    return mockReturn.user
193
+                },
194
+            }),
195
+        }),
196
+    })
139 197
     stub(server.models()['Grouping'], 'query').returns({
140 198
         whereIn: () => ({
141 199
             withGraphFetched: () => {
@@ -151,6 +209,13 @@ test('path /<profile_id> should return ok', async t => {
151 209
             return mockReturn.memberships
152 210
         },
153 211
     })
212
+    stub(server.models()['TagAssociation'], 'query').returns({
213
+        where: () => ({
214
+            andWhere: () => {
215
+                return mockReturn.tag_associations
216
+            },
217
+        }),
218
+    })
154 219
     stub(server.models()['Profile'], 'query').returns({
155 220
         // Mocked for getProfile()
156 221
         where: () => ({

+ 14
- 3
backend/tests/score.spec.js 查看文件

@@ -12,8 +12,10 @@ const MatchQueue = require('../lib/models/matchqueue')
12 12
 const Aspect = require('../lib/models/aspect')
13 13
 const AspectLabel = require('../lib/models/aspect_label')
14 14
 
15
-// !: Must match the key set in servives/profile.js
16
-const zipcodeKey = 7
15
+// !: Must match the key set in db/data-generator/config.json
16
+const zipcodeKey = 10
17
+const durationKey = 14
18
+const presenceKey = 15
17 19
 
18 20
 /**
19 21
  * Route parameters
@@ -21,7 +23,10 @@ const zipcodeKey = 7
21 23
 const params = {
22 24
     profile_id: 1,
23 25
     max_distance: 1000,
26
+    duration: 'full-time',
27
+    presence: 'remote',
24 28
 }
29
+
25 30
 const mockReturn = {
26 31
     user: [
27 32
         {
@@ -31,6 +36,8 @@ const mockReturn = {
31 36
                 { response_key_id: 1, val: '100' },
32 37
                 { response_key_id: 2, val: '200' },
33 38
                 { response_key_id: zipcodeKey, val: '90065' },
39
+                { response_key_id: durationKey, val: 'full-time' },
40
+                { response_key_id: presenceKey, val: 'remote' },
34 41
             ],
35 42
         },
36 43
         {
@@ -40,6 +47,8 @@ const mockReturn = {
40 47
                 { response_key_id: 1, val: '100' },
41 48
                 { response_key_id: 2, val: '200' },
42 49
                 { response_key_id: zipcodeKey, val: '97002' },
50
+                { response_key_id: durationKey, val: 'full-time' },
51
+                { response_key_id: presenceKey, val: 'remote' },
43 52
             ],
44 53
         },
45 54
         {
@@ -49,6 +58,8 @@ const mockReturn = {
49 58
                 { response_key_id: 1, val: '200' },
50 59
                 { response_key_id: 2, val: '200' },
51 60
                 { response_key_id: zipcodeKey, val: '96741' },
61
+                { response_key_id: durationKey, val: 'full-time' },
62
+                { response_key_id: presenceKey, val: 'remote' },
52 63
             ],
53 64
         },
54 65
     ],
@@ -67,7 +78,7 @@ const mockReturn = {
67 78
 }
68 79
 const pathToTest = {
69 80
     method: 'GET',
70
-    url: `/${params.profile_id}/score?max_distance=${params.max_distance}`,
81
+    url: `/${params.profile_id}/score?max_distance=${params.max_distance}&duration=${params.duration}&presence=${params.presence}`,
71 82
 }
72 83
 
73 84
 test(`path ${pathToTest.url} should return ok on GET`, async t => {

+ 24
- 15
backend/tests/user-send-email.spec.js 查看文件

@@ -6,7 +6,8 @@
6 6
  */
7 7
 
8 8
 // Change email here to your actual email
9
-// const email = 'myalias@myactualemail.com'
9
+let email = undefined
10
+// email = 'myalias@myactualemail.com'
10 11
 
11 12
 const test = require('ava')
12 13
 const { stub } = require('sinon')
@@ -16,11 +17,11 @@ const plugin = require('../lib/plugins/user.js')
16 17
 
17 18
 // Necessary Dependencies/Configurations for Brevo Transac Email
18 19
 const crypto = require('crypto')
19
-const SibApiV3Sdk = require('sib-api-v3-sdk')
20
-const defaultClient = SibApiV3Sdk.ApiClient.instance
21
-const apiKey = defaultClient.authentications['api-key']
20
+const Brevo = require('@getbrevo/brevo')
21
+const apiInstance = new Brevo.TransactionalEmailsApi()
22
+const apiKey = apiInstance.apiClient.authentications['api-key']
22 23
 apiKey.apiKey = process.env.BREVO_KEY
23
-const apiInstance = new SibApiV3Sdk.TransactionalEmailsApi()
24
+const sendSmtpEmail = new Brevo.SendSmtpEmail()
24 25
 
25 26
 // Existing activeSession to test against (should not match)
26 27
 const activeSessions = {
@@ -53,6 +54,11 @@ const pathToTest = {
53 54
 }
54 55
 
55 56
 test('path /send-email should send test transac email', async t => {
57
+    /* If email is left undefined, simply pass the test */
58
+    if (!email) {
59
+        t.log('no actual email was given, bypassing test...')
60
+        return t.pass()
61
+    }
56 62
     /**
57 63
      * Create a new server and register services,
58 64
      * models and routes for testing
@@ -80,6 +86,9 @@ test('path /send-email should send test transac email', async t => {
80 86
         }
81 87
     }
82 88
 
89
+    hashedSessionToken = Object.keys(activeSessions).find(hashedToken => {
90
+        return activeSessions[`${hashedToken}`].email === userCredentials.email
91
+    })
83 92
     /**
84 93
      * Sends a Transactional Email via Brevo
85 94
      * @ returns {Object}
@@ -101,17 +110,21 @@ test('path /send-email should send test transac email', async t => {
101 110
             emailWasRespondedTo: false,
102 111
             accessToken: null,
103 112
         }
104
-        const sendSmtpEmail = {
113
+        sendSmtpEmail.sender = {
114
+            name: 'My Test Company',
115
+            email: 'mytestemail@email.com',
116
+        }
117
+        sendSmtpEmail.subject = 'My Test Company'
118
+        sendSmtpEmail = {
105 119
             to: [
106 120
                 {
107 121
                     email: userCredentials.email,
108 122
                 },
109 123
             ],
110
-            templateId: 1,
111
-            params: {
112
-                // TODO: Change this in production...
113
-                link: `localhost:3000/verify/${hashedSessionToken}`,
114
-            },
124
+        }
125
+        sendSmtpEmail.templateId = Number(process.env.BREVO_TEMPLATE_ID)
126
+        sendSmtpEmail.params = {
127
+            link: `${process.env.BREVO_LINK}/verify/${hashedSessionToken}`,
115 128
         }
116 129
         return await apiInstance.sendTransacEmail(sendSmtpEmail).then(
117 130
             data => {
@@ -123,10 +136,6 @@ test('path /send-email should send test transac email', async t => {
123 136
         )
124 137
     }
125 138
 
126
-    hashedSessionToken = Object.keys(activeSessions).find(hashedToken => {
127
-        return activeSessions[`${hashedToken}`].email === userCredentials.email
128
-    })
129
-
130 139
     stub(server.services()['userService'], 'emailSent').returns(
131 140
         await emailSent(userCredentials),
132 141
     )

Loading…
取消
儲存