Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add username table #347

Merged
merged 7 commits into from
Dec 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions migrations/20221216122421_username_table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
exports.up = async function (knex) {
await knex.schema.createTable('osm_users', (table) => {
table.integer('id').primary()
table.text('name')
table.text('image')
table.datetime('updated_at').defaultTo(knex.fn.now())
})
}

exports.down = async function (knex) {
await knex.schema.dropTable('osm_users')
}
4 changes: 2 additions & 2 deletions src/components/profile-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ export default function ProfileModal({
<article className='modal__body'>
<div className='modal__header'>
<div className='user__item'>
{user.img ? (
{user.image ? (
<figure>
<img src={user.img} />
<img src={user.image} />
</figure>
) : (
<figure>
Expand Down
4 changes: 2 additions & 2 deletions src/lib/logger.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Pino from 'pino'
const Pino = require('pino')

/**
* Create logger instance. Level is set to 'silent' when testing.
Expand All @@ -8,4 +8,4 @@ const logger = Pino({
level: process.env.LOG_LEVEL || 'info',
})

export default logger
module.exports = logger
95 changes: 56 additions & 39 deletions src/models/team.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
const db = require('../lib/db')
const logger = require('../lib/logger')
const knexPostgis = require('knex-postgis')
const join = require('url-join')
const xml2js = require('xml2js')
const { unpack } = require('../../app/lib/utils')
const { prop, isEmpty } = require('ramda')
const { prop, isEmpty, difference, concat, assoc } = require('ramda')
const request = require('request-promise-native')

const { serverRuntimeConfig } = require('../../next.config')
Expand Down Expand Up @@ -64,48 +65,64 @@ const teamAttributes = [
*
*/
async function resolveMemberNames(ids) {
// The following avoids hitting OSM API when testing. We use TESTING variable
// instead of NODE_EN because the server run in development mode while
// executing E2E tests.
if (process.env.TESTING === 'true') {
return ids.map((id) => ({
id,
name: `User ${id}`,
image: `https://via.placeholder.com/150`,
}))
}

try {
const resp = await request(
join(serverRuntimeConfig.OSM_API, `/api/0.6/users?users=${ids.join(',')}`)
)
var parser = new xml2js.Parser()

return new Promise((resolve, reject) => {
parser.parseString(resp, (err, xml) => {
if (err) {
reject(err)
}

let users = xml.osm.user.map((user) => {
let img = prop('img', user)
if (img) {
img = img[0]['$'].href
}
return {
id: user['$'].id,
name: user['$'].display_name,
img,
}
// get the display names from the database table first
vgeorge marked this conversation as resolved.
Show resolved Hide resolved
const foundUsers = await db('osm_users').whereIn('id', ids)
const foundUserIds = foundUsers.map(prop('id'))
const notFound = difference(ids, foundUserIds)

let usersFromOSM = []
if (notFound.length > 0) {
try {
// The following avoids hitting OSM API when testing. We use TESTING variable
// instead of NODE_EN because the server run in development mode while
// executing E2E tests.
if (process.env.TESTING === 'true') {
usersFromOSM = notFound.map((id) => ({
id,
name: `User ${id}`,
image: `https://via.placeholder.com/150`,
}))
} else {
const resp = await request(
join(
serverRuntimeConfig.OSM_API,
`/api/0.6/users?users=${notFound.join(',')}`
)
)
var parser = new xml2js.Parser()

usersFromOSM = await new Promise((resolve, reject) => {
parser.parseString(resp, (err, xml) => {
if (err) {
reject(err)
}

let users = xml.osm.user.map((user) => {
let img = prop('img', user)
if (img) {
img = img[0]['$'].href
}
return {
id: user['$'].id,
name: user['$'].display_name,
image: img,
}
})
resolve(users)
})
})
}

resolve(users)
let usersToInsert = usersFromOSM.map((u) => {
return assoc('updated_at', db.fn.now(), u)
})
})
} catch (e) {
console.error(e)
throw new Error('Could not resolve usernames')
await db('osm_users').insert(usersToInsert)
} catch (e) {
logger.error(e)
throw new Error('Could not resolve user names from OSM')
}
}
return concat(usersFromOSM, foundUsers)
}

/**
Expand Down
27 changes: 27 additions & 0 deletions tests/api/cache.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const test = require('ava')
const db = require('../../src/lib/db')
const createAgent = require('../utils/create-agent')
const { resetDb, disconnectDb } = require('../utils/db-helpers')

let user1Agent
test.before(async () => {
await resetDb()
user1Agent = await createAgent({ id: 1 })
})

test.after.always(disconnectDb)

test('cache is filled when requesting team members', async (t) => {
let team1 = await user1Agent
.post('/api/teams')
.send({ name: 'cache team 1' })
.expect(200)

const team1Id = team1.body.id

// Make a request to getMembers
await user1Agent.get(`/api/teams/${team1Id}/members`).expect(200)

const usernames = await db('osm_users').select()
t.true(usernames.length > 0)
})