"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const test_helper_1 = require("../../helpers/test-helper");
const database_init_1 = __importDefault(require("../../helpers/database-init"));
const no_logger_1 = __importDefault(require("../../../fixtures/no-logger"));
const constants_1 = require("../../../../lib/util/constants");
const types_1 = require("../../../../lib/types");
let app;
let db;
const testUser = { name: 'test', id: -9999 };
beforeAll(async () => {
    db = await (0, database_init_1.default)('feature_api_client', no_logger_1.default);
    app = await (0, test_helper_1.setupAppWithCustomConfig)(db.stores, {
        experimental: {
            flags: {
                strictSchemaValidation: true,
            },
        },
    }, db.rawDatabase);
    await app.services.featureToggleServiceV2.createFeatureToggle('default', {
        name: 'featureX',
        description: 'the #1 feature',
        impressionData: true,
    }, types_1.TEST_AUDIT_USER);
    await app.services.featureToggleServiceV2.createFeatureToggle('default', {
        name: 'featureY',
        description: 'soon to be the #1 feature',
    }, types_1.TEST_AUDIT_USER);
    await app.services.featureToggleServiceV2.createFeatureToggle('default', {
        name: 'featureZ',
        description: 'terrible feature',
    }, types_1.TEST_AUDIT_USER);
    await app.services.featureToggleServiceV2.createFeatureToggle('default', {
        name: 'featureArchivedX',
        description: 'the #1 feature',
    }, types_1.TEST_AUDIT_USER);
    // depend on enabled feature with variant
    await app.services.dependentFeaturesService.unprotectedUpsertFeatureDependency({ child: 'featureY', projectId: 'default' }, { feature: 'featureX', variants: ['featureXVariant'] }, types_1.TEST_AUDIT_USER);
    await app.services.featureToggleServiceV2.archiveToggle('featureArchivedX', testUser, types_1.TEST_AUDIT_USER);
    await app.services.featureToggleServiceV2.createFeatureToggle('default', {
        name: 'featureArchivedY',
        description: 'soon to be the #1 feature',
    }, types_1.TEST_AUDIT_USER);
    await app.services.featureToggleServiceV2.archiveToggle('featureArchivedY', testUser, types_1.TEST_AUDIT_USER);
    await app.services.featureToggleServiceV2.createFeatureToggle('default', {
        name: 'featureArchivedZ',
        description: 'terrible feature',
    }, types_1.TEST_AUDIT_USER);
    await app.services.featureToggleServiceV2.archiveToggle('featureArchivedZ', testUser, types_1.TEST_AUDIT_USER);
    await app.services.featureToggleServiceV2.createFeatureToggle('default', {
        name: 'feature.with.variants',
        description: 'A feature toggle with variants',
    }, types_1.TEST_AUDIT_USER);
    await app.services.featureToggleServiceV2.saveVariants('feature.with.variants', 'default', [
        {
            name: 'control',
            weight: 50,
            weightType: 'fix',
            stickiness: 'default',
        },
        {
            name: 'new',
            weight: 50,
            weightType: 'variable',
            stickiness: 'default',
        },
    ], types_1.TEST_AUDIT_USER);
});
afterAll(async () => {
    await app.destroy();
    await db.destroy();
});
test('returns four feature toggles', async () => {
    return app.request
        .get('/api/client/features')
        .expect('Content-Type', /json/)
        .expect(200)
        .expect((res) => {
        expect(res.body.features).toHaveLength(4);
    });
});
test('returns dependencies', async () => {
    return app.request
        .get('/api/client/features')
        .expect('Content-Type', /json/)
        .expect(200)
        .expect((res) => {
        expect(res.body.features[0]).toMatchObject({
            name: 'featureY',
            dependencies: [
                {
                    feature: 'featureX',
                    enabled: true,
                    variants: ['featureXVariant'],
                },
            ],
        });
        expect(res.body.features[1].dependencies).toBe(undefined);
    });
});
test('returns four feature toggles without createdAt', async () => {
    return app.request
        .get('/api/client/features')
        .expect('Content-Type', /json/)
        .expect(200)
        .expect((res) => {
        expect(res.body.features).toHaveLength(4);
        expect(res.body.features[0].createdAt).toBeFalsy();
    });
});
test('gets a feature by name', async () => {
    return app.request
        .get('/api/client/features/featureX')
        .expect('Content-Type', /json/)
        .expect(200);
});
test('returns a feature toggles impression data', async () => {
    return app.request
        .get('/api/client/features/featureX')
        .expect('Content-Type', /json/)
        .expect((res) => {
        expect(res.body.impressionData).toBe(true);
    });
});
test('returns a false for impression data when not specified', async () => {
    return app.request
        .get('/api/client/features/featureZ')
        .expect('Content-Type', /json/)
        .expect((res) => {
        expect(res.body.impressionData).toBe(false);
    });
});
test('cant get feature that does not exist', async () => {
    return app.request
        .get('/api/client/features/myfeature')
        .expect('Content-Type', /json/)
        .expect(404);
});
test('Can filter features by namePrefix', async () => {
    return app.request
        .get('/api/client/features?namePrefix=feature.')
        .expect('Content-Type', /json/)
        .expect(200)
        .expect((res) => {
        expect(res.body.features).toHaveLength(1);
        expect(res.body.features[0].name).toBe('feature.with.variants');
    });
});
test('Can get strategies for specific environment', async () => {
    const featureName = 'test.feature.with.env';
    const env = constants_1.DEFAULT_ENV;
    // Create feature toggle
    await app.request.post('/api/admin/projects/default/features').send({
        name: featureName,
        type: 'killswitch',
    });
    // Add global strategy
    await app.request
        .post(`/api/admin/projects/default/features/${featureName}/environments/${env}/strategies`)
        .send({
        name: 'default',
    })
        .expect(200);
    // create new env
    await db.stores.environmentStore.create({
        name: 'testing',
        type: 'test',
    });
    await app.services.environmentService.addEnvironmentToProject('testing', 'default', types_1.SYSTEM_USER_AUDIT);
    await app.request
        .post(`/api/admin/projects/default/features/${featureName}/environments/testing/strategies`)
        .send({
        name: 'default',
    })
        .expect(200);
    await app.request
        .get(`/api/client/features/${featureName}?environment=testing`)
        .expect('Content-Type', /json/)
        .expect(200)
        .expect((res) => {
        expect(res.body.name).toBe(featureName);
        expect(res.body.strategies).toHaveLength(1);
        expect(res.body.strategies.find((s) => s.name === 'default')).toBeDefined();
    });
});
test('Can use multiple filters', async () => {
    expect.assertions(3);
    await app.request.post('/api/admin/projects/default/features').send({
        name: 'test.feature',
        type: 'killswitch',
        enabled: true,
        strategies: [{ name: 'default' }],
    });
    await app.request.post('/api/admin/projects/default/features').send({
        name: 'test.feature2',
        type: 'killswitch',
        enabled: true,
        strategies: [{ name: 'default' }],
    });
    await app.request.post('/api/admin/projects/default/features').send({
        name: 'notestprefix.feature3',
        type: 'release',
        enabled: true,
        strategies: [{ name: 'default' }],
    });
    const tag = { value: 'Crazy', type: 'simple' };
    const tag2 = { value: 'tagb', type: 'simple' };
    await app.request
        .post('/api/admin/features/test.feature/tags')
        .send(tag)
        .expect(201);
    await app.request
        .post('/api/admin/features/test.feature2/tags')
        .send(tag2)
        .expect(201);
    await app.request
        .post('/api/admin/features/notestprefix.feature3/tags')
        .send(tag)
        .expect(201);
    await app.request
        .get('/api/client/features?tag=simple:Crazy')
        .expect('Content-Type', /json/)
        .expect(200)
        .expect((res) => expect(res.body.features).toHaveLength(2));
    await app.request
        .get('/api/client/features?namePrefix=test&tag=simple:Crazy')
        .expect('Content-Type', /json/)
        .expect(200)
        .expect((res) => {
        expect(res.body.features).toHaveLength(1);
        expect(res.body.features[0].name).toBe('test.feature');
    });
});
test('returns a feature toggles impression data for a different project', async () => {
    const project = {
        id: 'impression-data-client',
        name: 'ImpressionData',
        description: '',
        mode: 'open',
    };
    await db.stores.projectStore.create(project);
    const toggle = {
        name: 'project-client.impression.data',
        impressionData: true,
    };
    await app.request
        .post('/api/admin/projects/impression-data-client/features')
        .send(toggle)
        .expect(201)
        .expect((res) => {
        expect(res.body.impressionData).toBe(true);
    });
    return app.request
        .get('/api/client/features')
        .expect('Content-Type', /json/)
        .expect((res) => {
        const projectToggle = res.body.features.find((resToggle) => resToggle.project === project.id);
        expect(projectToggle.name).toBe(toggle.name);
        expect(projectToggle.project).toBe(project.id);
        expect(projectToggle.impressionData).toBe(true);
    });
});
//# sourceMappingURL=feature.e2e.test.js.map