Inicio del curso

1

驴Qu茅 vamos a construir en el curso avanzado de Node.js?

Introducci贸n a Node.js

2

Conoce qu茅 es node.js

3

Caracter铆sticas de la plataforma Node.js

4

驴Qu茅 tipo de aplicaciones podemos desarrollar con Node.js?

Preparando el entorno de Desarrollo

5

C贸mo instalar Node.js en macOS

6

C贸mo instalar PostgreSQL y Redis en macOS

7

C贸mo instalar Visual Studio Code en macOS

8

C贸mo instalar Ansible en macOS

Arquitectura del Proyecto (Platziverse)

9

Arquitectura y Componentes del proyecto

Introducci贸n a protocolos y patrones de aplicaciones en tiempo real

10

C贸mo funciona el modelo Pub/Sub en MQTT y Web Sockets

Creando M贸dulo de Base de Datos (platziverse-db)

11

Estructura b谩sica de un m贸dulo de Node.js

12

Definici贸n de entidades de base de datos

13

Implementaci贸n de modelos con sequelize

14

Implementaci贸n de un m贸dulo b谩sico de base de datos

15

Implementaci贸n de script de inicializaci贸n de base de datos

16

Creando una advertencia sobre el borrado de base de datos

17

Introducci贸n a pruebas unitarias con Ava.js

18

Introducci贸n a code coverage con nyc

19

C贸mo hacer Mocks y Stubs con Sinon

20

Creaci贸n de fixtures y definici贸n b谩sica del servicio de Agent

21

Implementaci贸n de findbyId y pruebas en el servicio Agent

22

Implementaci贸n de createOrUpdate

23

Revisi贸n del servicio Agent

24

Implementaci贸n del servicio Metric

25

Realizando un ejemplo con el m贸dulo de base de datos

26

Reto: C贸mo modificar el script de inicializaci贸n de la base de datos

Construyendo un servidor en tiempo real para Internet de las Cosas con Mosca/MQT

27

Definici贸n de un Broker de Mensajer铆a

28

Definici贸n de los tipos de mensajes

29

Implementaci贸n del servidor MQTT

30

C贸mo recibir mensajes

31

C贸mo integrar el servidor MQTT con la base de datos

32

C贸mo almacenar la informaci贸n del agente y reportar el agente conectado

33

C贸mo almacenar la informaci贸n de las m茅tricas

34

Probando el servidor MQTT (Ejemplo con mqtt client)

Construyendo el agente de monitoreo (platziverse-agent)

35

C贸mo implementar un custom EventEmitter usando ES6 classes

36

Definiendo un timer de ejecuci贸n continua (setInterval)

37

Implementaci贸n del cliente MQTT

38

Implementaci贸n de m茅tricas personalizadas

39

Probar agent (ejemplo)

Construyendo una API REST con Express (platziverse-api)

40

Implementaci贸n de un servidor b谩sico con express

41

Definici贸n de rutas del API

42

Implementaci贸n de manejo de errores con express

43

Pruebas b谩sicas de Integraci贸n con Ava y supertest

44

Integraci贸n con el m贸dulo de base de datos

45

Implementaci贸n de ruta del API

46

Pruebas de Integraci贸n con Ava, Supertest y Sinon

Asegurando nuestra API REST con JWT

47

Definici贸n de JWT

48

Asegurando nuestra API con express-jwt

49

Modificando las pruebas de integracion

50

Implementando permisos con express-jwt-permissions

Creando un Dashboard Web en tiempo real con WebSockets (platziverse-web)

51

Implementaci贸n de un servidor web est谩tico con express

52

Integrando socket.io con express

53

Integrando agente de monitoreo con socket.io

54

Implementaci贸n de rutas proxy con la API

55

Presentaci贸n de nuestro cliente frontend en Vue.js

56

Integraci贸n del cliente frontend con API (Metric)

57

Integraci贸n del cliente frontend con socket.io (Metric)

58

Integraci贸n del cliente frontend con API (Agent)

59

Integraci贸n del cliente frontend con socket.io (Agent)

Creando un Dashboard para la terminal en tiempo real con Blessed (platziverse-cl)

60

Implementaci贸n de un CLI B谩sico con Node

61

Introducci贸n a Blessed / Blessed Contrib

62

Implementaci贸n del layout b谩sico con Blessed Contrib

63

Integraci贸n con el agente de monitoreo 1

64

Integraci贸n con el agente de monitoreo 2

65

Integraci贸n con el agente de monitoreo 3

Depurando Aplicaciones Node.js

66

Utilizando longjohn para mejores stacktraces

67

Depurando en Desarrollo con node --inspect

68

Depurando en Desarrollo con Visual Studio Code

Preparando nuestra aplicaci贸n para producci贸n

69

Preparando Proyecto para Producci贸n 1

70

Preparando Proyecto para Producci贸n 2

71

Creaci贸n de scripts para despliegue con Ansible

72

Probando el database rol con Vagrant

73

Creando scripts del rol de platziverse db y mqtt (script de automatizaci贸n .yml)

74

Terminando los scripts faltantes

75

Creaci贸n de servidores en DigitalOcean

Desplegando nuestra aplicaci贸n a producci贸n

76

Ejecutando los Scripts de Despliegue

77

Utilizando Aplicaci贸n en Producci贸n y cierre del curso

Bonus: Utilizando platziverse-agent en BeagleBone Black y Raspberry PI

78

Implementaci贸n platziverse-agent con Johnny-Five

A煤n no tienes acceso a esta clase

Crea una cuenta y contin煤a viendo este curso

Pruebas de Integraci贸n con Ava, Supertest y Sinon

46/78
Recursos

驴Ves un patr贸n aqu铆? - El m贸dulo de fixtures se reusa del proyecto platziverse-db 驴Puedes volverlo un m贸dulo standalone? 驴C贸mo lo llamar铆as? / 驴Puedes terminar de implementar el resto de pruebas del API?

Aportes 5

Preguntas 0

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

'use strict'

const test = require('ava')
const request = require('supertest')
const sinon = require('sinon')
const proxyquire = require('proxyquire')

const agentFixtures = require('./fixtures/agent')
const metricFixtures = require('./fixtures/metric')

let sandbox = null
let server = null
let dbStub = null
let AgentStub = {}
let MetricStub = {}

const uuid = 'yyy-yyy-yyy'
const wrongUuid = 'xxx-yyy-yyy'
const type = 'CPU'

test.beforeEach(async () => {
    sandbox = sinon.createSandbox()

    dbStub = sandbox.stub()
    dbStub.returns(Promise.resolve({
        Agent: AgentStub,
        Metric: MetricStub
    }))

    AgentStub.findConnected = sandbox.stub()
    AgentStub.findConnected.returns(Promise.resolve(agentFixtures.connected))

    AgentStub.findByUuid = sandbox.stub();
    AgentStub.findByUuid.withArgs(uuid).returns(Promise.resolve(agentFixtures.byUuid(uuid)));
    AgentStub.findByUuid.withArgs(wrongUuid).returns(Promise.resolve(null));

    MetricStub.findByAgentUuid = sandbox.stub();
    MetricStub.findByAgentUuid.withArgs(uuid).returns(Promise.resolve(metricFixtures.findByAgentUuid(uuid)));
    MetricStub.findByAgentUuid.withArgs(wrongUuid).returns(Promise.resolve(null));

    MetricStub.findByTypeAgentUuid = sandbox.stub();
    MetricStub.findByTypeAgentUuid.withArgs(type, uuid).returns(Promise.resolve(metricFixtures.findByTypeAgentUuid(type, uuid)));
    MetricStub.findByTypeAgentUuid.withArgs(type, wrongUuid).returns(Promise.resolve(null));

    const api = proxyquire('../api', {
        'platziverse-db': dbStub
    })

    server = proxyquire('../server', {
        './api': api
    })
})

test.afterEach(() => {
    sandbox && sinon.restore()
})

test.serial.cb('/api/agents', t => {
    request(server)
        .get('/api/agents')
        .expect(200)
        .expect('Content-Type', /json/)
        .end((err, res) => {
            t.falsy(err, 'should not return an error')
            let body = JSON.stringify(res.body)
            let expected = JSON.stringify(agentFixtures.connected)
            t.deepEqual(body, expected, 'response body should be the expected')
            t.end()
        })
})

test.serial.cb('/api/agent/:uuid', t => {
    request(server)
        .get(`/api/agent/${uuid}`)
        .expect(200)
        .expect('Content-Type', /json/)
        .end((err, res) => {
            t.falsy(err, 'should not return an error');
            let body = JSON.stringify(res.body);
            let expected = JSON.stringify(agentFixtures.byUuid(uuid));
            t.deepEqual(body, expected, 'response body should be the expected');
            t.end();
        });
});

test.serial.cb('/api/agent/:uuid - not found', t => {
    request(server)
        .get(`/api/agent/${wrongUuid}`)
        .expect(404)
        .expect('Content-Type', /json/)
        .end((err, res) => {
            if (err) {
                console.log(err);
            }
            t.truthy(res.body.error, 'should return an error');
            t.regex(res.body.error, /not found/, 'Error should contains not found');
            t.end();
        });
});

test.serial.cb('/api/metrics/:uuid', t => {
    request(server)
        .get(`/api/metrics/${uuid}`)
        .expect(200)
        .expect('Content-Type', /json/)
        .end((err, res) => {
            t.falsy(err, 'should not return an error');
            let body = JSON.stringify(res.body);
            let expected = JSON.stringify(metricFixtures.findByAgentUuid(uuid));
            t.deepEqual(body, expected, 'response body should be the expected');
            t.end();
        });
});

test.serial.cb('/api/metrics/:uuid - not found', t => {
    request(server)
        .get(`/api/metrics/${wrongUuid}`)
        .expect(404)
        .expect('Content-Type', /json/)
        .end((err, res) => {
            if (err) {
                console.log(err);
            }
            t.truthy(res.body.error, 'should return an error');
            t.regex(res.body.error, /not found/, 'Error should contains not found');
            t.end();
        });
});

test.serial.cb('/api/metrics/:uuid/:type', t => {
    request(server)
        .get(`/api/metrics/${uuid}/${type}`)
        .expect(200)
        .expect('Content-Type', /json/)
        .end((err, res) => {
            t.falsy(err, 'should not return an error');
            let body = JSON.stringify(res.body);
            let expected = JSON.stringify(metricFixtures.findByTypeAgentUuid(type, uuid));
            t.deepEqual(body, expected, 'response body should be the expected');
            t.end();
        });
});

test.serial.cb('/api/metrics/:uuid/:type - not found', t => {
    request(server)
        .get(`/api/metrics/${wrongUuid}/${type}`)
        .expect(404)
        .expect('Content-Type', /json/)
        .end((err, res) => {
            if (err) {
                console.log(err);
            }
            t.truthy(res.body.error, 'should return an error');
            t.regex(res.body.error, /not found/, 'Error should contains not found');
            t.end();
        });
});```

Reto resuelto aqu铆 el c贸digo

sabran como hacer esto mismo pero usando los Mock Functions de }jest ???

RETO #1 (reutilizar los fixtures)
podemos bajo una carpeta llamada platziverse-tools en un m贸dulo llamado fixtures.js exportar para el agente y m茅tricas el siguiente c贸digo:

'use strict';


const agent = {
  "id":3,
  "uuid":"mm-xx-vv-nn",
  "username":"Pepe",
  "name":"Derek",
  "hostname":"host",
  "pid":1,
  "connected":true,
  "createdAt":"2020-07-05T21:51:15.964Z",
  "updatedAt":"2020-07-05T21:51:15.964Z"
}

const agents = [
  agent,
  extendedLazzy(agent, { id: 2, uuid: 'mm-xx-vv', name: 'Suesck', username: 'Testeador2', pid: 2, connected: false }),
  extendedLazzy(agent, { "id":5,"uuid":"yyy-tt-zz","username":"desadaal","name":"Milena","hostname":"host","pid":13210,"connected":true,"createdAt":"2020-07-05T22:12:56.460Z","updatedAt":"2020-07-05T22:12:56.460Z" }),
  extendedLazzy(agent, { id: 4, uuid: 'jj-zz-aa', name: 'Suesck4', username: 'Testeador4', pid: 4, connected: false })
];

function extendedLazzy(object, value) {
  const clone = Object.assign({}, object);// primer valor es el objeto al que le quiere copiar propiedades y el segundo valores que quiero copiar
  return Object.assign(clone, value);
}

//**/////***//**//*/****/***/**/**-*/ */ */ */ */ */ */ */

const metric = {
  id: 1,
  type: 'callbackMetric',
  value: '1234Kokorick',
  agentId: '73c61e52-2d0b-4811-936e-da6e5518d134',
  createdAt: new Date(),
  updatedAt: new Date()
};

const metrics = [
  metric,
  extendedMetric(metric, { id: 2, type: 'mobile', value: '456脩lp', agentId: 'c71d80db-d16c-4d25-bb91-5d2ab4f422d4' }),
  extendedMetric(metric, { id: 3, type: 'mobile', value: '123987', agentId: '6b7a6dde-551d-410b-b297-e94b8b637556' }),
  extendedMetric(metric, { id: 4, type: 'cpu', value: '5642' }),
];

function extendedMetric (obj, value) {
  const clone = Object.assign({}, obj);
  return Object.assign(clone, value);
};

module.exports = {
  agent: {
    singleAgent: agent,
    all: agents,
      allConnected: agents.filter((items) => items.connected === true),
      allDisconnected: agents.filter((items) => items.connected === false),
      allSuesck: agents.filter((items) => items.name === 'Testeador2'),
      byUuid: (uuid) => agents.filter((items) => items.uuid === uuid).shift(),
      byId: (id) => agents.find((items) => items.id === id)
  },
  metric: {
      singleMetric: metric,
      all: metrics,
      findById: (id) => metrics.find((item) => item.id === id),
      allTypes: () => metrics.forEach((item) => {
        console.log(item.type);
        return item.type;
      }),
      TypeSelected: (selected) => metrics.filter((item) => item.type === selected),
      allValues: () => metrics.forEach((item) => {
        console.log(item.value);
        return item.value;
      }),
      orderByTheSelected: (orderBy, limit) => {
        const filteredOrder = metrics.filter((items) => items.type);
        if (orderBy === 'DESC') {
          return filteredOrder.reverse().slice(0, limit);
        }
        if (orderBy === 'ASCE'){
          return filteredOrder.slice(0, limit);
        }
        return null;
      },
      findAgentById: (uuid) => metrics.filter((items) => {
        return items.agentId === uuid;
      }).shift()
  }
}

RETO#2 (Implementaci贸n del resto de los tests)

test.serial.todo('/api/agent/:uuid');

test.serial.cb('/api/agent/:uuid - FIND AGENT BY UUID', (t) => {
  const uuid = 'yyy-tt-zz';

  request(serverApi)
    .get(`/api/agent/${uuid}`)
    .expect(200)
    .expect('Content-Type', /json/)
    .expect('Content-Length', '190')
    .end((err, res) => {
      t.falsy(err, 'Error should be false');
      let Agent = res.body;
      let AgentFixture = agent.byUuid(uuid);
      t.truthy(Agent, 'Should be exist agent');
      t.deepEqual(Agent, AgentFixture, 'response.body should be the expected agent find by uuid');
      t.end();
    });
});

test.serial.todo('/api/agent/:uuid - not found')

test.serial.cb('/api/agent/:uuid - FIND AGENT BY UUID (NOT FOUND)', (t) => {
  const uuid = 'yyy-tt-zzAS4415465a646asas3a';

  request(serverApi)
    .get(`/api/agent/${uuid}`)
    .expect(404)
    .expect('Content-Type', /text/)
    .expect('Content-Length', '9')
    .end((err, res) => {
      t.truthy(err, 'Error should be true');
      let AgentFixture = agent.byUuid(uuid);
      let ResponseNotFound = JSON.stringify(res.body);
      t.deepEqual(ResponseNotFound, '{}', 'Response on body should be {}');
      t.notDeepEqual(uuid, AgentFixture, 'response.body should not be the expected agent found by uuid');
      t.end();
    });
});

test.serial.todo('/api/metrics/:uuid')

test.serial.cb('/api/metrics/:uuid - FIND UUID OF AGENT WITH METRICS', (t) => {
  const uuid = '73c61e52-2d0b-4811-936e-da6e5518d134';

  request(serverApi)
    .get(`/api/metrics/${uuid}`)
    .expect('Content-Type', /json/)
    .expect('Content-Length', '67')
    .end((err, res) => {
      t.falsy(err, 'Error should be false');
      let MetricBody = res.body;
      let MetricFixture = [
        {
          type: 'callbackMetric',
        },
        {
          type: 'promiseKetric',
        },
        {
          type: 'rss',
        },
      ];
      t.truthy(MetricBody, 'res.body should be exist');
      t.deepEqual(MetricBody, MetricFixture, 'MetricBody should be equal to MetricFixture');
      t.end();
    });
});

test.serial.todo('/api/metrics/:uuid - not found')

test.serial.cb('/api/metrics/:uuid - FIND UUID OF AGENT WITH METRICS (NOT FOUND)', (t) => {
  const uuid = 'cualquierCosa';
  request(serverApi)
    .get(`/api/metrics/${uuid}`)
    .expect(404)
    .expect('Content-Type', /text/)
    .expect('Content-Length', '9')
    .end((err, res) => {
      t.truthy(err, 'Error should be true');
      let MetricFixture = agent.byUuid(uuid);
      let ResponseNotFound = JSON.stringify(res.body);
      t.deepEqual(ResponseNotFound, '{}', 'Response on body should be {}');
      t.notDeepEqual(uuid, MetricFixture, 'response.body should not be the expected agent found by uuid');
      t.end();
    });
});

test.serial.todo('/api/metrics/:uuid/:type')

test.serial.cb('/api/metrics/:uuid/:type - FIND UUID OF AGENT AND TYPE OF METRICS WITH METRICS', (t) => {
  const uuid = '6b7a6dde-551d-410b-b297-e94b8b637556';
  const type = 'callbackMetric';

  request(serverApi)
    .get(`/api/metrics/${uuid}/${type}`)
    .expect('Content-Type', /json/)
    .expect('Content-Length', '309')
    .end((err, res) => {
      t.falsy(err, 'Error should be false');
      let MetricTypeFixture = [
        {
          createdAt: '2020-07-05T22:24:04.870Z',
          id: 47,
          type: 'callbackMetric',
          value: '0.05874242582302891',
        },
        {
          createdAt: '2020-07-05T22:24:02.886Z',
          id: 44,
          type: 'callbackMetric',
          value: '0.2968601413510581',
        },
        {
          createdAt: '2020-07-05T22:24:00.922Z',
          id: 41,
          type: 'callbackMetric',
          value: '0.06692634490428051',
        },
      ];
      let Response = res.body;
      t.deepEqual(Response, MetricTypeFixture, 'Response.body should be equal to MetricTypeFixture');
      t.end();
    });
});

test.serial.todo('/api/metrics/:uuid/:type - not found')

test.serial.cb('/api/metrics/:uuid/:type - FIND UUID OF AGENT AND TYPE OF METRICS WITH METRICS (NOT FOUND)', (t) => {
  const uuid = 'cualquierCosa';
  const type = 'cualquierTipo'
  request(serverApi)
    .get(`/api/metrics/${uuid}/${type}`)
    .expect(404)
    .expect('Content-Type', /text/)
    .expect('Content-Length', '9')
    .end((err, res) => {
      t.truthy(err, 'Error should be true');
      let ResponseNotFound = JSON.stringify(res.body);
      t.deepEqual(ResponseNotFound, '{}', 'Response on body should be {}');
      t.end();
    });
});

Despu茅s de toda una ma帽ana de domingo al fin pude realizar los test justo antes del almuerzo

requer铆 boom para generar los errores

api-test.js

"use strict";

const test = require("ava");
const request = require("supertest");
const sinon = require("sinon");
const proxyquire = require("proxyquire");
const debug = require('debug')

const agentFixtures = require("./fixtures/agents");
const metricFixture = require('./fixtures/metrics')

let sandbox = null;
let server = null;
let dbStub = null;
let AgentStub = {};
let MetricStub = {};
const uuid = "yyy-yyy-yyy";
const uuidNotFound= "yyydd";
const metricType= 'temp'
const metricTypeNotFound= 'now'

test.beforeEach(async () => {
  sandbox = sinon.createSandbox();

  dbStub = sandbox.stub();
  dbStub.returns(
    Promise.resolve({
      Agent: AgentStub,
      Metric: MetricStub,
    })
  );

  AgentStub.findConnected = sandbox.stub();
  AgentStub.findConnected.returns(Promise.resolve(agentFixtures.connected));
  AgentStub.findByUuid = sandbox.stub();
  AgentStub.findByUuid.withArgs(uuid).returns(Promise.resolve(agentFixtures.byUuid(uuid)));
  AgentStub.findByUuid.withArgs(uuidNotFound).returns(Promise.resolve(agentFixtures.byUuid(uuidNotFound)));

  MetricStub.findByAgentUuid = sandbox.stub()
  MetricStub.findByAgentUuid.withArgs(uuid).returns(Promise.resolve(metricFixture.findByAgentUuid(uuid)))
  MetricStub.findByAgentUuid.withArgs(uuidNotFound).returns(Promise.resolve(metricFixture.findByAgentUuid(uuidNotFound)))

  MetricStub.findByTypeAgentUuid = sandbox.stub()
  MetricStub.findByTypeAgentUuid.withArgs(metricType, uuid).returns(Promise.resolve(metricFixture.findByTypeAgentUuid( metricType,uuid)))
  MetricStub.findByTypeAgentUuid.withArgs(metricTypeNotFound, uuidNotFound).returns(Promise.resolve(metricFixture.findByTypeAgentUuid( metricTypeNotFound, uuidNotFound)))

 const api = proxyquire("../api", {
    "platziverse-db": dbStub,
  });

  server = proxyquire("../server", {
    "./api": api,
  });
});

test.afterEach(() => {
  sandbox && sinon.restore();
});

test.serial.cb("/api/agents", (t) => {
  request(server)
    .get("/api/agents")
    .expect(200)
    .expect("Content-Type", /json/)
    .end((err, res) => {
      t.falsy(err, "should not return an error");
      let body = JSON.stringify(res.body);
      let expected = JSON.stringify(agentFixtures.connected);
      t.deepEqual(body, expected, "response body should be the expected");
      t.end();
    });
});

test.serial.cb('/api/agent/:uuid', t => {
  request(server)
    .get(`/api/agent/${uuid}`)
    .expect(200)
    .expect('Content-Type', /json/)
    .end((err, res) => {
      t.falsy(err, 'should not return an error');
      let body = JSON.stringify(res.body);
      let expected = JSON.stringify(agentFixtures.byUuid(uuid));
      t.deepEqual(body, expected, 'response body should be the expected');
      t.end();
    });
});

test.serial.cb("/api/agent/:uuid - not found", (t) => {
  request(server)
    .get(`/api/agent/${uuidNotFound}`)
    .expect(404)
    .expect('Content-Type', /json/)
    .end((err, res) => {
      t.truthy(err, 'should not return an error');
      let body = JSON.stringify(res.body);
      let expected = JSON.stringify(agentFixtures.byUuid(uuidNotFound));
      t.deepEqual(body, expected, 'response body should be the expected');
      t.end();
    });
});

test.serial.cb("/api/metrics/:uuid", (t) => {
  request(server)
    .get(`/api/metrics/${uuid}`)
    .expect(200)
    .expect('Content-Type', /json/)
    .end((err, res) => {
      t.falsy(err, 'should not return an error');
      let body = JSON.stringify(res.body);
      let expected = JSON.stringify(metricFixture.findByAgentUuid(uuid));
      t.deepEqual(body, expected, 'response body should be the expected');
      t.end();
    });
});

test.serial.cb("/api/metrics/:uuid - not found", (t)=> {
  request(server)
    .get(`/api/metrics/${uuidNotFound}`)
    .expect(404)
    .expect('Content-Type', /json/)
    .end((err, res) => {
      t.truthy(err, 'should not return an error');
      let body = JSON.stringify(res.body);
      let expected = JSON.stringify(metricFixture.findByAgentUuid(uuidNotFound));
      t.deepEqual(body, expected, 'response body should be the expected');
      t.end();
    });
});

test.serial.cb("/api/metrics/:uuid/:type", (t) => {
  request(server)
  .get(`/api/metrics/${uuid}/${metricType}`)
  .expect(200)
  .expect('Content-Type', /json/)
  .end((err, res) => {
    t.falsy(err, 'should not return an error');
    let body = JSON.stringify(res.body);
    let expected = JSON.stringify(metricFixture.findByTypeAgentUuid(metricType, uuid));
    t.deepEqual(body, expected, 'response body should be the expected');
    t.end();
  });
});
test.serial.cb("/api/metrics/:uuid/:type - not found", (t) =>{
  request(server)
  .get(`/api/metrics/${uuidNotFound}/${metricTypeNotFound}`)
  .expect(404)
  .expect('Content-Type', /json/)
  .end((err, res) => {
    t.truthy(err, 'should not return an error');
    let body = JSON.stringify(res.body);
    let expected = JSON.stringify(metricFixture.findByTypeAgentUuid(metricTypeNotFound, uuidNotFound));
    t.deepEqual(body, expected, 'response body should be the expected');
    t.end();
  });
});

metrics.js

'use strict'

const boom = require('@hapi/boom')

const metric =  {

  id: 1,
  type: 'temp',
  value: 44,
  createdAt: null,
  updateAt: null,
  uuid: 'yyy-yyy-yyy'
}

const metrics = [
  metric,
  {...metric, id: 2, value: 33},
  {...metric, id:3, value:500, type:'memory'},
  {...metric, id:4, value:550, type:'memory'}

]

function findByAgentUuid(uuid){

  let findMetric = metrics.filter((a) => a.uuid === uuid)
  
  if (findMetric.length===0){
    findMetric = boom.notFound(`Metrics not found for agent with uuid ${uuid}`)
  }

  return findMetric
}

function findByTypeAgentUuid(type,uuid){
  let findMetric = metrics.filter((a) => a.type === type && a.uuid === uuid )
  
    if (findMetric.length===0){
    findMetric = boom.notFound('Metrics not found for agent with uuid yyyd')
  }

  return findMetric

}

module.exports = {
  findByAgentUuid,
  findByTypeAgentUuid
}