import { afterEach, beforeEach, describe, expect, it } from '@jest/globals';
import { Test, TestingModule } from '@nestjs/testing';
import request = require('supertest');
import { AppModule } from '../src/app.module';
import { INestApplication } from '@nestjs/common';
import { AuthGuard } from '../src/security/guards/auth.guard';
import { RolesGuard } from '../src/security/guards/roles.guard';
import { <%= dtoClass %> } from '../src/service/dto/<%= entityFileName %>.dto';
import { <%= entityClass %>Service } from '../src/service/<%= entityFileName %>.service';

describe('<%= entityClass %> Controller', () => {
    let app: INestApplication;

    const authGuardMock = { canActivate: (): any => true };
    const rolesGuardMock = { canActivate: (): any => true };
    const entityMock: any = {
        id: 'entityId'
    }

    const serviceMock = {
        findById: (): any => entityMock,
        findAndCount: (): any => [entityMock, 0],
        save: (): any => entityMock,
        update: (): any => entityMock,
        deleteById: (): any => entityMock
    };


    beforeEach(async () => {
        const moduleFixture: TestingModule = await Test.createTestingModule({
            imports: [AppModule],
        }).overrideGuard(AuthGuard)
        .useValue(authGuardMock)
        .overrideGuard(RolesGuard)
        .useValue(rolesGuardMock)
        .overrideProvider(<%= entityClass %>Service)
        .useValue(serviceMock)
        .compile();

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

    it('/GET all <%= entityApiUrl %> ', async () => {

        const getEntities: <%= dtoClass %>[] = (await request(app.getHttpServer())
        .get('/api/<%= entityApiUrl %>')
        .expect(200)).body;

        expect(getEntities).toEqual(entityMock);

    }
    );

    it('/GET <%= entityApiUrl %> by id', async () => {


        const getEntity: <%= dtoClass %> = (await request(app.getHttpServer())
            .get('/api/<%= entityApiUrl %>/' + entityMock.id)
            .expect(200)).body;

        expect(getEntity).toEqual(entityMock);

    }
    );

    it('/POST create <%= entityApiUrl %>', async () => {

        const createdEntity: <%= dtoClass %> = (await request(app.getHttpServer())
            .post('/api/<%= entityApiUrl %>')
            .send(entityMock)
            .expect(201)).body;

        expect(createdEntity).toEqual(entityMock);

    }
    );

    it('/PUT update <%= entityApiUrl %>', async () => {


        const updatedEntity: <%= dtoClass %> = (await request(app.getHttpServer())
            .put('/api/<%= entityApiUrl %>')
            .send(entityMock)
            .expect(201)).body;


        expect(updatedEntity).toEqual(entityMock);

    }
    );

    it('/PUT update <%= entityApiUrl %> from id', async () => {


        const updatedEntity: <%= dtoClass %> = (await request(app.getHttpServer())
            .put('/api/<%= entityApiUrl %>/' + entityMock.id)
            .send(entityMock)
            .expect(201)).body;


        expect(updatedEntity).toEqual(entityMock);

    }
    );


    it('/DELETE <%= entityApiUrl %>', async () => {


        const deletedEntity: <%= dtoClass %> = (await request(app.getHttpServer())
            .delete('/api/<%= entityApiUrl %>/' + entityMock.id)
            .expect(204)).body;

            expect(deletedEntity).toEqual({});
    }
    );

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

