Как протестировать V2 onCall Cloud Function с помощью Jest?

Вопрос или проблема

Я пытаюсь написать модульные тесты для функции Cloud Firestore под названием setBrakeModeV2 с использованием Jest. Функция предназначена для установки режима торможения пользователя в true и обновления его пользовательских утверждений в Firebase Authentication. Вот фрагмент теста, который я написал:

 it('должен установить режим торможения для пользователя в true', async () => {
  const result = await setBrakeModeV2();
  expect(result).toBe(true);
 // и пользовательские утверждения должны быть обновлены  
expect(admin.auth().setCustomUserClaims).toHaveBeenCalledWith('testUid', { brakeMode: true });
 });

Однако я не уверен, как правильно смоделировать параметры req (запрос) и res (ответ), которые необходимо передать функции setBrakeModeV2. Поскольку это функция Cloud Firestore, эти параметры важны для правильного тестирования ее поведения.

Как мне замокировать объекты req и res для функции Cloud в Jest? Если это поможет, я могу предоставить детали реализации setBrakeModeV2, но моя текущая проблема заключается в передаче стандартных аргументов.

export const setBrakeModeV2 = onCall(
  {
    // Примечание: ⚙️⚙️⚙️ Дополнительная информация об этом объекте в интерфейсе HttpsOptions. ⚙️⚙️⚙️
    maxInstances: 1,
    memory: '256MiB',
    // enforceAppCheck: true,
  },

  async (request: CallableRequest<null>) => {
    consoleLogFn('setBrakeModeV2');

    // 🪪 Проверка безопасности
    const requestAuth = request?.auth;
    verifyExistingUserPermissions(requestAuth);

    const uid = requestAuth?.uid;
    // Пользовательские утверждения
    const tokenData = requestAuth?.token;
    const userType = tokenData?.userType;
    const stripeRole = tokenData?.stripeRole;

    console.log('uid ===>', uid);
    console.log('tokenData ===>', tokenData);
    console.log('userType из токена ===>', userType);
    console.log('stripeRole из токена ===>', stripeRole);

    /**
     * Эта функция позволяет пользователю, чья подписка на премиум истекла, продлить период истечения удаления аккаунта
     * путем включения "режима торможения". Режим торможения можно включить только в том случае, если роль пользователя в Stripe равна null, что указывает на то, что
     * пользователь больше не является активным премиум-подписчиком.
     *
     * Null-роль в Stripe подразумевает, что у пользователя была как минимум одна премиум-подписка в прошлом, но в настоящее время он не
     * имеет активной премиум-подписки. Для получения дополнительной информации ознакомьтесь с документацией по жизненному циклу ролей Stripe.
     */
    if (uid && userType && tokenData && stripeRole === null) {
      const currentBreakModeValue = tokenData?.brakeMode;

      await Promise.all([
        admin
          .auth()
          /**
           * в качестве альтернативы мы можем использовать .getUserByEmail(tokenData.email)
           */
          .getUser(uid)
          .then((user) => {
            /*
             * Обновить пользовательские утверждения
             */
            const newCustomClaims: CustomClaim = {
              // Скопировать существующие пользовательские утверждения
              ...(user.customClaims as CustomClaim),
              // Изменить режим торможения на противоположный текущему значению
              brakeMode: !currentBreakModeValue,
            };
            admin.auth().setCustomUserClaims(user.uid, newCustomClaims);
          }),
      ]);
      // Вернуть новое значение режима торможения клиенту
      return !currentBreakModeValue;
    }
    return null;
  }
);

Ответ или решение

Как протестировать Cloud Function setBrakeModeV2 с помощью Jest

Проверка функций облачных функций с использованием Jest — это важный шаг для обеспечения их надежности и корректного поведения. В вашем случае, вы хотите протестировать функцию setBrakeModeV2, которая устанавливает режим торможения пользователя и обновляет его индивидуальные полномочия в Firebase Authentication. Давайте пройдемся по каждому шагу, чтобы настроить тестирование правильно.

1. Создание мока для объектов req и res

Объект req

Объект req (request) для облачных функций Firebase часто содержит информацию об аутентификации и дополнительных данных, отправляемых вместе с запросом. Вам нужно смоделировать его так, чтобы он содержал необходимые поля.

const req = {
  auth: {
    uid: 'testUid',
    token: {
      userType: 'testUserType',
      stripeRole: null,
      brakeMode: false,
    },
  },
};

Объект res

Объект res (response) обычно не используется в вызовах onCall, поскольку результат возвращается клиенту напрямую. Однако, если ваша функция использует его, вы можете смоделировать его следующим образом:

const res = {
  send: jest.fn(),
};

2. Написание теста

Теперь, когда вы создали моки для req и res, вы можете написать тест для вашей функции. В тесте вы должны вызывать setBrakeModeV2, передавая ему подготовленный объект req, и ожидать, что функция выполнит обновление служебных полномочий.

import { setBrakeModeV2 } from './yourFunctionFile'; // Импортируйте вашу функцию
import admin from 'firebase-admin'; // Импортируйте admin, чтобы замокировать вызовы

jest.mock('firebase-admin'); // Мокирование firebase-admin

describe('setBrakeModeV2 Tests', () => {
  beforeEach(() => {
    jest.clearAllMocks(); // Очистка всех моков перед каждым тестом
  });

  it('должен установить режим торможения для пользователя в true', async () => {
    const req = {
      auth: {
        uid: 'testUid',
        token: {
          userType: 'testUserType',
          stripeRole: null,
          brakeMode: false,
        },
      },
    };

    // Мокаем admin.auth().getUser
    const mockUser = {
      customClaims: { brakeMode: false },
      uid: 'testUid',
    };
    admin.auth().getUser.mockResolvedValue(mockUser);

    const result = await setBrakeModeV2(req);

    expect(result).toBe(true);
    expect(admin.auth().setCustomUserClaims).toHaveBeenCalledWith('testUid', { brakeMode: true });
  });

  it('должен вернуть null, если uid или userType отсутствуют', async () => {
    const req = {};

    const result = await setBrakeModeV2(req);

    expect(result).toBeNull();
  });
});

3. Объяснение тестов

  • Тест на успешное выполнение: В первом тесте вы передаете корректные данные для аутентификации и мока для admin.auth().getUser. После выполнения функции setBrakeModeV2 ожидается, что режим торможения устанавливается в true, и setCustomUserClaims будет вызван с правильными аргументами.

  • Тест на ошибочные данные: Во втором тесте вы передаете пустой объект req, проверяя, корректно ли функция возвращает null, если у запроса отсутствуют uid или userType.

Заключение

Следуя этим шагам, вы сможете правильно протестировать вашу функцию setBrakeModeV2 с помощью Jest, удостоверившись, что ваша функция будет вести себя корректно в различных сценариях. Эффективное тестирование поможет улучшить качество кода и уменьшить количество ошибок в продакшен среде. Для получения дополнительной информации о Jest и мокировании объектов, ознакомьтесь с документацией Jest.

Оцените материал
Добавить комментарий

Капча загружается...