/// <reference types="jest" />
import request from "supertest";
import type { INestApplication } from "@nestjs/common";
import { Test } from "@nestjs/testing";
import type { Server } from "node:http";

import { AppModule } from "../src/app.module";
import {
  parseInternetCatalog,
  internetCatalogResponseSchema,
} from "@customer-portal/domain/catalog";
import { apiSuccessResponseSchema } from "@customer-portal/domain/common/schema";

const internetCatalogApiResponseSchema = apiSuccessResponseSchema(internetCatalogResponseSchema);

const isRecord = (value: unknown): value is Record<string, unknown> =>
  typeof value === "object" && value !== null;

const isHttpServer = (value: unknown): value is Server =>
  isRecord(value) && typeof value.listen === "function" && typeof value.close === "function";

describe("Catalog contract", () => {
  let app: INestApplication;

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  afterAll(async () => {
    await app.close();
  });

  it("should return internet catalog matching domain schema", async () => {
    const serverCandidate: unknown = app.getHttpServer();
    if (!isHttpServer(serverCandidate)) {
      throw new Error("Expected Nest application to expose an HTTP server");
    }

    const response = await request(serverCandidate).get("/api/catalog/internet/plans");

    expect(response.status).toBe(200);
    const payload = internetCatalogApiResponseSchema.parse(response.body);
    expect(() => parseInternetCatalog(payload.data)).not.toThrow();
  });
});
