Passed
Push — main ( 3f259d...71e4ad )
by Patrick
02:34
created

tests/lib/Boost.test.ts   A

Complexity

Total Complexity 8
Complexity/F 0

Size

Lines of Code 226
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 202
dl 0
loc 226
rs 10
c 0
b 0
f 0
wmc 8
mnd 8
bc 8
fnc 0
bpm 0
cpm 0
noi 0
1
/* eslint-disable sort-keys */
2
3
import { AppSettings } from '@/index';
4
import { Boost } from '@/lib/Boost';
5
import { CodeBoost } from '@/lib/CodeBoost';
6
import { Repository } from '@/lib/Repository';
7
import { BoostConfiguration } from '@/types/BoostConfiguration';
8
import { FakeHistoryManager } from '@tests/fakes/FakeHistoryManager';
9
10
const createCodeBoost = (appSettings: AppSettings | null = null, historyMgr: any = null) => {
11
    appSettings = appSettings ?? {
12
        github_token: '1234567890',
13
        repository_storage_path: `${__dirname}/../fixtures/temp`,
14
        boosts_path: `${__dirname}/../fixtures`,
15
        use_forks: false,
16
        use_pull_requests: false,
17
        log_target: ['console'],
18
    };
19
    historyMgr = historyMgr ?? new FakeHistoryManager();
20
21
    return new CodeBoost(appSettings, historyMgr);
22
};
23
24
const createBoost = (path, config = {}, historyMgr: any = null, codeboost: any = null) => {
25
    historyMgr = historyMgr ?? new FakeHistoryManager();
26
    codeboost = codeboost ?? createCodeBoost(null, historyMgr);
27
28
    const result = new Boost(codeboost, path);
29
    result.config = Object.assign({}, result.config, config);
30
    result.init(path);
31
32
    result.path = result.path.replace(__dirname, '.');
33
34
    return result;
35
};
36
37
const createBoostMock = methodName => jest.spyOn(Boost.prototype, methodName);
38
39
it('sets the correct properties on create', async () => {
40
    const boostConfig: BoostConfiguration = {
41
        id: 'test-one',
42
        version: '1.0.0',
43
        repository_limits: {
44
            max_runs_per_version: 1,
45
            minutes_between_runs: 60,
46
        },
47
        pull_request: {
48
            title: 'Add Test One',
49
            body: 'This PR is a test',
50
            branch: 'add-test-one',
51
        },
52
        scripts: {
53
            parallel: true,
54
            files: [],
55
        },
56
    };
57
58
    const appSettings: AppSettings = {
59
        github_token: '1234567890',
60
        repository_storage_path: `${__dirname}/../fixtures/temp`,
61
        boosts_path: `${__dirname}/../fixtures`,
62
        use_forks: false,
63
        use_pull_requests: false,
64
        log_target: ['console'],
65
    };
66
67
    const boost = new Boost(new CodeBoost(appSettings, new FakeHistoryManager()), `${__dirname}/../fixtures/test-boost-1`);
68
    boost.config = boostConfig;
69
    boost.init(`${__dirname}/../fixtures/test-boost-1`);
70
71
    const keys = Object.keys(boost);
72
    keys.sort();
73
74
    expect(keys).toMatchSnapshot();
75
});
76
77
it('loads a boost from a path', async () => {
78
    const config = { repository_limits: { max_runs_per_version: 1, minutes_between_runs: 5 } };
79
    const boost = createBoost(`${__dirname}/../fixtures/test-boost-1`, config, new FakeHistoryManager());
80
81
    expect(boost.scripts[0]).toBeInstanceOf(Function);
82
83
    const keys = Object.keys(boost);
84
    keys.sort();
85
86
    expect(keys).toMatchSnapshot();
87
});
88
89
it('respects the max runs per version limit', async () => {
90
    const config = { repository_limits: { max_runs_per_version: 1, minutes_between_runs: 5 } };
91
    const historyMgr = new FakeHistoryManager();
92
    const boost = createBoost(`${__dirname}/../fixtures/test-boost-1`, config, historyMgr);
93
94
    expect(boost.canRunOnRepository('owner1/name1')).toBeTruthy();
95
    historyMgr.addSucceededItem(boost.id, '0.0.0', 'owner1/name1');
96
    expect(boost.canRunOnRepository('owner1/name1')).toBeTruthy();
97
    historyMgr.addSucceededItem(boost.id, boost.version, 'owner1/name1');
98
    expect(boost.canRunOnRepository('owner1/name1')).toBeFalsy();
99
});
100
101
it('respects the min minutes between runs limit', async () => {
102
    const config = { repository_limits: { max_runs_per_version: 999, minutes_between_runs: 5 } };
103
    const historyMgr = new FakeHistoryManager();
104
    const boost = createBoost(`${__dirname}/../fixtures/test-boost-1`, config, historyMgr);
105
106
    expect(boost.canRunOnRepository('owner1/name1')).toBeTruthy();
107
    historyMgr.addSucceededItem(boost.id, boost.version, 'owner1/name1', 10);
108
    expect(boost.canRunOnRepository('owner1/name1')).toBeTruthy();
109
    historyMgr.addSucceededItem(boost.id, boost.version, 'owner1/name1', 3);
110
    expect(boost.canRunOnRepository('owner1/name1')).toBeFalsy();
111
});
112
113
it('does not consider skipped runs when determining if limits apply', async () => {
114
    const config = { repository_limits: { max_runs_per_version: 1, minutes_between_runs: 5 } };
115
    const historyMgr = new FakeHistoryManager();
116
    const boost = createBoost(`${__dirname}/../fixtures/test-boost-1`, config, historyMgr);
117
118
    expect(boost.canRunOnRepository('owner1/name1')).toBeTruthy();
119
    historyMgr.addSkippedItem(boost.id, boost.version, 'owner1/name1', 3);
120
    expect(boost.canRunOnRepository('owner1/name1')).toBeTruthy();
121
    historyMgr.addSucceededItem(boost.id, boost.version, 'owner1/name1', 3);
122
    expect(boost.canRunOnRepository('owner1/name1')).toBeFalsy();
123
});
124
125
it('does not consider runs for other repositories when determining if limits apply', async () => {
126
    const config = { repository_limits: { max_runs_per_version: 1, minutes_between_runs: 5 } };
127
    const historyMgr = new FakeHistoryManager();
128
    const boost = createBoost(`${__dirname}/../fixtures/test-boost-1`, config, historyMgr);
129
130
    expect(boost.canRunOnRepository('owner1/name1')).toBeTruthy();
131
    historyMgr.addSucceededItem(boost.id, boost.version, 'owner2/name2', 3);
132
    expect(boost.canRunOnRepository('owner1/name1')).toBeTruthy();
133
    historyMgr.addSucceededItem(boost.id, boost.version, 'owner1/name1', 3);
134
    expect(boost.canRunOnRepository('owner1/name1')).toBeFalsy();
135
});
136
137
it('mocks a class method', () => {
138
    const runScriptsMock = jest.spyOn(Boost.prototype, 'runScripts').mockImplementation(async () => {});
139
140
    const boost = createBoost(`${__dirname}/../fixtures/test-boost-1`);
141
    boost.runScripts(<any>{});
142
143
    expect(runScriptsMock).toHaveBeenCalledTimes(1);
144
145
    runScriptsMock.mockRestore();
146
});
147
148
it(`runs all of a boost's scripts synchronously`, async () => {
149
    const boost = createBoost(`${__dirname}/../fixtures/test-boost-1`, { scripts: { parallel: false, files: [] } });
150
    boost.scripts = [jest.fn(), jest.fn()];
151
152
    await boost.runScripts(<any>{});
153
154
    boost.scripts.forEach(script => expect(script).toHaveBeenCalledTimes(1));
155
});
156
157
it(`runs all of a boost's scripts asynchronously`, async () => {
158
    const boost = createBoost(`${__dirname}/../fixtures/test-boost-1`, { scripts: { parallel: true, files: [] } });
159
    boost.scripts = [jest.fn(), jest.fn()];
160
161
    await boost.runScripts(<any>{});
162
163
    boost.scripts.forEach(script => expect(script).toHaveBeenCalledTimes(1));
164
});
165
166
it('runs on a repository', async () => {
167
    const checkoutPullBranchMock = createBoostMock('checkoutPullRequestBranch').mockImplementation(async () => {});
168
    const createScriptHandlerParametersMock = createBoostMock('createScriptHandlerParameters').mockImplementation(() => {
169
        return <any>{};
170
    });
171
    const mocks = [checkoutPullBranchMock, createScriptHandlerParametersMock];
172
173
    const codeboost = createCodeBoost(null, new FakeHistoryManager());
174
    codeboost.appSettings = { use_pull_requests: true } as any;
175
176
    const boost = createBoost(`${__dirname}/../fixtures/test-boost-1`, {}, codeboost.historyManager, codeboost);
177
    boost.scripts = [];
178
179
    const repo = new Repository('owner1/name1', `${__dirname}/../fixtures/repos`);
180
181
    await boost.run(repo, []);
182
183
    mocks.forEach(mock => expect(mock).toHaveBeenCalledTimes(1));
184
185
    mocks.forEach(mock => mock.mockRestore());
186
});
187
188
it('runs on a repository and creates a history item', async () => {
189
    const checkoutPullBranchMock = createBoostMock('checkoutPullRequestBranch').mockImplementation(async () => {});
190
    const createScriptHandlerParametersMock = createBoostMock('createScriptHandlerParameters').mockImplementation(() => {
191
        return <any>{};
192
    });
193
    const mocks = [checkoutPullBranchMock, createScriptHandlerParametersMock];
194
195
    const codeboost = createCodeBoost(null, new FakeHistoryManager());
196
    codeboost.appSettings = { use_pull_requests: true } as any;
197
198
    const boost = createBoost(`${__dirname}/../fixtures/test-boost-1`, {}, codeboost.historyManager, codeboost);
199
    const repo = new Repository('owner1/name1', `${__dirname}/../fixtures/repos`);
200
201
    boost.scripts = [];
202
203
    await boost.run(repo, []);
204
205
    expect(codeboost.historyManager.data).toHaveLength(1);
206
    expect(codeboost.historyManager.data[0].state).not.toBe('running');
207
    expect(codeboost.historyManager.data[0].finished_at).not.toBeNull();
208
209
    mocks.forEach(m => m.mockRestore());
210
});
211
212
it('runs on a repository and creates a skipped history item if limits apply', async () => {
213
    const codeboost = createCodeBoost(null, new FakeHistoryManager());
214
    codeboost.appSettings = { use_pull_requests: true } as any;
215
    const config = { repository_limits: { max_runs_per_version: 1, minutes_between_runs: 60 } };
216
    const boost = createBoost(`${__dirname}/../fixtures/test-boost-1`, config, codeboost.historyManager, codeboost);
217
    const repo = new Repository('owner1/name1', `${__dirname}/../fixtures/repos`);
218
219
    (codeboost.historyManager as FakeHistoryManager).addSucceededItem(boost.id, boost.version, repo.fullRepositoryName(), 3);
220
221
    await boost.run(repo, []);
222
223
    expect(codeboost.historyManager.data).toHaveLength(2);
224
    expect(codeboost.historyManager.data[1].state).toBe('skipped');
225
});
226