14 | Service Hooks are the means by which gitlab notifies strider of new
15 | commits and pull requests to your repository.
16 |
17 |
18 | We already registered the requisite hooks when you added this project, but
19 | if you want to remove them or add them back, you can do so here.
20 |
21 |
28 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/config/config.js:
--------------------------------------------------------------------------------
1 | app.controller('GitLabCtrl', [
2 | '$scope',
3 | function ($scope) {
4 | $scope.config = $scope.providerConfig();
5 | $scope.config.cache = $scope.config.cache || false;
6 |
7 | $scope.addWebhooks = function () {
8 | $scope.loadingWebhooks = true;
9 | $.ajax($scope.api_root + 'gitlab/hook', {
10 | type: 'POST',
11 | success: function () {
12 | $scope.loadingWebhooks = false;
13 | $scope.success('Set gitlab webhooks', true);
14 | },
15 | error: function () {
16 | $scope.loadingWebhooks = false;
17 | $scope.error('Failed to set gitlab webhooks', true);
18 | },
19 | });
20 | };
21 |
22 | $scope.deleteWebhooks = function () {
23 | $scope.loadingWebhooks = true;
24 | $.ajax($scope.api_root + 'gitlab/hook', {
25 | type: 'DELETE',
26 | success: function (data) {
27 | $scope.loadingWebhooks = false;
28 | $scope.success(data, true);
29 | },
30 | error: function () {
31 | $scope.loadingWebhooks = false;
32 | $scope.error('Failed to remove gitlab webhooks', true);
33 | },
34 | });
35 | };
36 |
37 | $scope.save = function () {
38 | this.providerConfig(this.config);
39 | };
40 | },
41 | ]);
42 |
--------------------------------------------------------------------------------
/lib/api.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const async = require('async');
4 | const superagent = require('superagent');
5 | const debug = require('debug')('strider-gitlab:api');
6 | const util = require('util');
7 | const parseLinkHeader = require('parse-link-header');
8 |
9 | module.exports = {
10 | get: get,
11 | parseRepo: parseRepo,
12 | createHooks: createHooks,
13 | deleteHooks: deleteHooks,
14 | addDeployKey: addDeployKey,
15 | removeDeployKey: removeDeployKey,
16 | };
17 |
18 | /**
19 | * Retrieve a file from a GitLab repository, using the GitLab API.
20 | * @param {Object} config The configuration of the GitLab provider plugin.
21 | * @param {String} uri The URI of the file to retrieve.
22 | * @param {Function} done A function to call, once a result is available.
23 | */
24 | function get(config, uri, done) {
25 | // If the configuration has no GitLab API URL, bail.
26 | if (!config.api_url) {
27 | return done(
28 | new Error('API URL missing from GitLab provider configuration!')
29 | );
30 | }
31 | // Append a slash to the URL if there isn't one.
32 | let apiBase = config.api_url;
33 | if (!/\/$/.test(apiBase)) {
34 | apiBase += '/';
35 | }
36 | // Construct the complete request URL
37 | const url = apiBase + uri;
38 | superagent
39 | .get(url)
40 | .query({
41 | private_token: config.api_key,
42 | per_page: 100,
43 | membership: config.membership,
44 | })
45 | .set('User-Agent', 'StriderCD (http://stridercd.com)')
46 | .end((error, res) => {
47 | res = res || {};
48 |
49 | if (error) {
50 | return done(error, null, null);
51 | }
52 |
53 | debug(`Response body type: ${typeof res.body}`);
54 | debug(
55 | `Response body received: ${util.inspect(res.body, false, 10, true)}`
56 | );
57 | if (res.text) {
58 | debug(
59 | `Response text received: ${util.inspect(res.text, false, 10, true)}`
60 | );
61 | }
62 | if (res.error) {
63 | return done(res.error, null, res);
64 | }
65 | if (!res.body) {
66 | return done(undefined, res.body, res);
67 | }
68 |
69 | let results = res.body;
70 |
71 | if (res.headers.link) {
72 | const linkHeader = parseLinkHeader(res.headers.link);
73 | const numberOfPages =
74 | linkHeader && linkHeader.last ? linkHeader.last.page : 1;
75 | let i = 1;
76 |
77 | async.whilst(
78 | () => {
79 | return i < numberOfPages;
80 | },
81 | (callback) => {
82 | i++;
83 | superagent
84 | .get(url)
85 | .query({
86 | private_token: config.api_key,
87 | per_page: 100,
88 | page: i,
89 | })
90 | .set('User-Agent', 'StriderCD (http://stridercd.com)')
91 | .end((err1, res) => {
92 | if (err1) return callback(err1);
93 |
94 | results = results.concat(res.body);
95 | callback(null, i);
96 | });
97 | },
98 | (err) => {
99 | if (err) return done(err);
100 |
101 | return done(null, results, res);
102 | }
103 | );
104 | } else {
105 | return done(null, results, res);
106 | }
107 | });
108 | }
109 |
110 | function parseRepo(repo) {
111 | return {
112 | id: repo.id,
113 | name: repo.path_with_namespace,
114 | display_name: repo.path_with_namespace,
115 | display_url: repo.web_url,
116 | group: repo.namespace.path,
117 | private: !repo.public,
118 | config: {
119 | auth: { type: 'ssh' },
120 | scm: 'git',
121 | url: repo.ssh_url_to_repo,
122 | owner: repo.owner,
123 | repo: repo.web_url,
124 | pull_requests: 'none',
125 | whitelist: [],
126 | },
127 | };
128 | }
129 |
130 | function createHooks(config, repo_id, url, callback) {
131 | const endpoint_url = `${config.api_url}/projects/${repo_id}/hooks`;
132 |
133 | superagent
134 | .post(endpoint_url)
135 | .send({
136 | url: url,
137 | push_events: true,
138 | })
139 | .set('PRIVATE-TOKEN', config.api_key)
140 | .set('User-Agent', 'StriderCD (http://stridercd.com)')
141 | .end((err, res) => {
142 | if (err) return callback(err);
143 | if (res.status === 200) {
144 | debug(
145 | 'API request succeeded, but resource was not created. User possibly has insufficient access rights or GitLab API URL was not configured with correct prefix.'
146 | );
147 | }
148 | if (res && res.status !== 201) return callback(res);
149 |
150 | return callback(null, true);
151 | });
152 | }
153 |
154 | function deleteHooks(config, repo_id, url, callback) {
155 | const endpoint_url = `${config.api_url}/projects/${repo_id}/hooks`;
156 |
157 | // Fetch all webhooks from Gitlab
158 | superagent
159 | .get(endpoint_url)
160 | .set('PRIVATE-TOKEN', config.api_key)
161 | .set('User-Agent', 'StriderCD (http://stridercd.com)')
162 | .end((err, res) => {
163 | let deleted = false;
164 |
165 | if (err) {
166 | return callback(err);
167 | }
168 |
169 | if (!res) {
170 | return callback(new Error('Empty response.'));
171 | }
172 |
173 | async.each(
174 | res.body,
175 | (hook, cb) => {
176 | // Remove all webhooks matching url
177 | if (hook.url === url) {
178 | const hook_url = `${endpoint_url}/${hook.id}`;
179 |
180 | superagent
181 | .del(hook_url)
182 | .set('PRIVATE-TOKEN', config.api_key)
183 | .end((err) => {
184 | deleted = true;
185 | cb(err);
186 | });
187 | } else cb();
188 | },
189 | (err) => {
190 | callback(err, deleted);
191 | }
192 | );
193 | });
194 | }
195 |
196 | function addDeployKey(config, repo_id, title, key, callback) {
197 | const endpoint_url = `${config.api_url}/projects/${encodeURIComponent(
198 | repo_id
199 | )}/deploy_keys`;
200 |
201 | superagent
202 | .post(endpoint_url)
203 | .send({
204 | title: title,
205 | key: key,
206 | })
207 | .set('User-Agent', 'StriderCD (http://stridercd.com)')
208 | .set('PRIVATE-TOKEN', config.api_key)
209 | .end((err, res) => {
210 | if (err) return callback(err);
211 | if (res.status === 200) {
212 | debug(
213 | 'API request succeeded, but resource was not created. User possibly has insufficient access rights or GitLab API URL was not configured with correct prefix.'
214 | );
215 | }
216 | if (res && res.status !== 201) return callback(res);
217 |
218 | return callback(null, true);
219 | });
220 | }
221 |
222 | function removeDeployKey(config, repo_id, title, callback) {
223 | const endpoint_url = `${config.api_url}/projects/${repo_id}/deploy_keys`;
224 |
225 | // Fetch all deploy keys from Gitlab
226 | superagent
227 | .get(endpoint_url)
228 | .set('PRIVATE-TOKEN', config.api_key)
229 | .set('User-Agent', 'StriderCD (http://stridercd.com)')
230 | .end((err, res) => {
231 | if (err) {
232 | return callback(err);
233 | }
234 |
235 | let deleted = false;
236 |
237 | if (!res) {
238 | return callback(new Error('Empty response.'));
239 | }
240 |
241 | async.each(
242 | res.body,
243 | (key, cb) => {
244 | // Remove all webhooks matching url
245 | if (key.title === title) {
246 | const deploy_key_url = `${endpoint_url}/${key.id}`;
247 |
248 | superagent
249 | .del(deploy_key_url)
250 | .set('PRIVATE-TOKEN', config.api_key)
251 | .end((err) => {
252 | deleted = true;
253 | cb(err);
254 | });
255 | } else cb();
256 | },
257 | (err) => callback(err, deleted)
258 | );
259 | });
260 | }
261 |
--------------------------------------------------------------------------------
/lib/webapp.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const _ = require('lodash');
4 | const api = require('./api');
5 | const async = require('async');
6 | const debug = require('debug')('strider-gitlab:webapp');
7 | const hostname = process.env.strider_server_name || 'http://localhost:3000';
8 | const util = require('util');
9 | const webhooks = require('./webhooks');
10 |
11 | module.exports = {
12 | // this is the project-level config
13 | // project.provider.config
14 | config: {
15 | url: String,
16 | owner: String,
17 | repo: String,
18 | cache: Boolean,
19 | pull_requests: { type: String, enum: ['all', 'none', 'whitelist'] },
20 | whitelist: [
21 | {
22 | name: String,
23 | level: { type: String, enum: ['tester', 'admin'] },
24 | },
25 | ],
26 | // used for the webhook
27 | secret: String,
28 | // type: https || ssh
29 | auth: {},
30 | },
31 |
32 | listRepos: (config, done) => {
33 | api.get(config, 'projects', (err, repos) => {
34 | if (err) return done(err);
35 |
36 | if (!repos) {
37 | return done(
38 | new Error(
39 | 'Could not get a list of projects from the GitLab repository. Please check the configuration in Account->GitLab.'
40 | )
41 | );
42 | }
43 |
44 | // Parse and filter only git repos
45 | done(
46 | null,
47 | repos.map(api.parseRepo).filter((repo) => {
48 | return repo.config.scm === 'git';
49 | })
50 | );
51 | });
52 | },
53 |
54 | getFile: (filename, ref, account, config, project, done) => {
55 | const repoId = project.provider.repo_id;
56 | const branch = encodeURIComponent(ref.branch);
57 | const encodedFileName = encodeURIComponent(filename);
58 | const uri = util.format(
59 | 'projects/%d/repository/blobs/%s?filepath=%s',
60 | repoId,
61 | branch,
62 | encodedFileName
63 | );
64 |
65 | api.get(account, uri, (err, data, res) => {
66 | if (err) {
67 | return done(err, null);
68 | } else {
69 | done(err, res.text);
70 | }
71 | });
72 | },
73 |
74 | getBranches: (account, config, project, done) => {
75 | const repoId = project.provider.repo_id;
76 | const uri = util.format('projects/%d/repository/branches', repoId);
77 |
78 | debug(`Getting URI ${uri}`);
79 | api.get(account, uri, (err, branches) => {
80 | debug(
81 | `We get the following as branches: ${util.inspect(
82 | branches,
83 | false,
84 | 10,
85 | true
86 | )}`
87 | );
88 |
89 | done(
90 | err,
91 | _.map(branches || [], (branch) => {
92 | return branch.name;
93 | })
94 | );
95 | });
96 | },
97 |
98 | // will be namespaced under /:org/:repo/api/gitlab
99 | routes: (app, context) => {
100 | app.post('/hook', (req, res) => {
101 | const url = `${hostname}/${req.project.name}/api/gitlab/webhook`;
102 | const config = req.accountConfig();
103 |
104 | if (!config.api_key)
105 | return res.status(400).send('Gitlab account not configured');
106 |
107 | return api.createHooks(
108 | config,
109 | req.project.provider.repo_id,
110 | url,
111 | (err) => {
112 | if (err) return res.status(500).send(err.message);
113 |
114 | return res.status(200).send('Webhook registered');
115 | }
116 | );
117 | });
118 |
119 | app.delete('/hook', (req, res) => {
120 | const url = `${hostname}/${req.project.name}/api/gitlab/webhook`;
121 | const config = req.accountConfig();
122 |
123 | if (!config.api_key)
124 | return res.status(400).send('Gitlab account not configured');
125 |
126 | return api.deleteHooks(
127 | config,
128 | req.project.provider.repo_id,
129 | url,
130 | (err, deleted) => {
131 | if (err) return res.status(500).send(err.message);
132 |
133 | return res
134 | .status(200)
135 | .send(deleted ? 'Webhook removed' : 'No webhook to delete');
136 | }
137 | );
138 | });
139 |
140 | // gitlab should hit this endpoint
141 | app.anon.post('/webhook', function (req, res) {
142 | webhooks.receiveWebhook(context.emitter, req, res);
143 | });
144 | },
145 |
146 | setupRepo: (account, config, project, done) => {
147 | const url = `${hostname}/${project.name}/api/gitlab/webhook`;
148 | const deploy_key_title = util.format('strider-%s', project.name);
149 |
150 | if (!account.api_key)
151 | return done(new Error('Gitlab account not configured'));
152 |
153 | // Create webhooks and add deploykey
154 | return async.parallel(
155 | [
156 | (callback) => {
157 | debug('Creating webhooks...');
158 | api.createHooks(account, project.provider.repo_id, url, callback);
159 | },
160 | (callback) => {
161 | debug('Adding deployment keys...');
162 | api.addDeployKey(
163 | account,
164 | project.provider.repo_id,
165 | deploy_key_title,
166 | project.branches[0].pubkey,
167 | callback
168 | );
169 | },
170 | ],
171 | (err) => {
172 | done(err, config);
173 | }
174 | );
175 | },
176 |
177 | teardownRepo: (account, config, project, done) => {
178 | const url = `${hostname}/${project.name}/api/gitlab/webhook`;
179 | const deploy_key_title = util.format('strider-%s', project.name);
180 |
181 | if (!account.api_key)
182 | return done(new Error('Gitlab account not configured'));
183 |
184 | // Remove webhooks and deploykey
185 | return async.parallel(
186 | [
187 | (callback) => {
188 | api.deleteHooks(account, project.provider.repo_id, url, callback);
189 | },
190 | (callback) => {
191 | api.removeDeployKey(
192 | account,
193 | project.provider.repo_id,
194 | deploy_key_title,
195 | callback
196 | );
197 | },
198 | ],
199 | done
200 | );
201 | },
202 | };
203 |
--------------------------------------------------------------------------------
/lib/webhooks.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const debug = require('debug')('strider-gitlab:webhooks');
4 | const gravatar = require('gravatar');
5 | const util = require('util');
6 |
7 | module.exports = {
8 | receiveWebhook: receiveWebhook,
9 | pushJob: pushJob,
10 | };
11 |
12 | function makeJob(project, config) {
13 | var deploy = false;
14 | var branch = project.branch(config.branch) || {
15 | active: true,
16 | mirror_master: true,
17 | deploy_on_green: false,
18 | };
19 |
20 | if (!branch.active) return false;
21 |
22 | if (config.branch !== 'master' && branch.mirror_master) {
23 | // mirror_master branches don't deploy
24 | deploy = false;
25 | } else {
26 | deploy = config.deploy && branch.deploy_on_green;
27 | }
28 |
29 | return {
30 | type: deploy ? 'TEST_AND_DEPLOY' : 'TEST_ONLY',
31 | trigger: config.trigger,
32 | project: project.name,
33 | ref: config.ref,
34 | plugin_data: config.plugin_data || {},
35 | user_id: project.creator._id,
36 | created: new Date(),
37 | };
38 | }
39 |
40 | function startFromCommit(project, payload, send) {
41 | const config = pushJob(payload);
42 | if (payload.commits) {
43 | const lastCommit = payload.commits[payload.commits.length - 1];
44 |
45 | if (lastCommit.message.indexOf('[skip ci]') > -1) {
46 | return { skipCi: true };
47 | }
48 | } else if (payload.after && /^0+$/.test(payload.after)) {
49 | // Tag push event reaction from tags added or removed
50 | // When reaction from `remove`, `payload.after` hash is all 0
51 | return { deleteTag: true };
52 | }
53 |
54 | var branch = project.branch(config.branch);
55 | var job;
56 |
57 | if (branch) {
58 | job = makeJob(project, config);
59 | if (job) return send(job);
60 | }
61 |
62 | return false;
63 | }
64 |
65 | // returns : {trigger, branch, deploy}
66 | function pushJob(payload) {
67 | let branchname;
68 | let commit;
69 | if (payload.commits) {
70 | commit = payload.commits[payload.commits.length - 1];
71 |
72 | if (!commit || !commit.author) {
73 | debug(
74 | "Unable to determine author from provided commit (may it's a merge commit?). Skipping"
75 | );
76 | debug(`Commit data extracted from payload:${util.inspect(commit)}`);
77 | return null;
78 | }
79 | } else if (payload.after) {
80 | // If data haven't commits array but basic information to start ci exist
81 | commit = {
82 | url: `${payload.repository.homepage}/commit/${payload.after}`,
83 | message: 'tag push',
84 | timestamp: new Date().toISOString(),
85 | author: {
86 | name: payload.user_name || '',
87 | email: undefined,
88 | image: '',
89 | },
90 | };
91 | } else {
92 | return null;
93 | }
94 |
95 | let trigger;
96 | let ref;
97 | var isTagPush = false;
98 |
99 | if (payload.ref.indexOf('refs/heads/') === 0) {
100 | branchname = payload.ref.substring('refs/heads/'.length);
101 | ref = {
102 | branch: branchname,
103 | id: payload.after,
104 | };
105 | } else if (payload.ref.indexOf('refs/tags/') === 0) {
106 | // `tag` ref is start with refs/tags/
107 | // Git clone options can set `--branch tag-name` to clone `tag` same as clone `branch`
108 | isTagPush = true;
109 | branchname = payload.ref.substring('refs/tags/'.length);
110 | ref = {
111 | branch: branchname,
112 | id: payload.after,
113 | };
114 | } else {
115 | ref = {
116 | fetch: payload.ref,
117 | };
118 | }
119 |
120 | trigger = {
121 | type: isTagPush ? 'tag push' : 'commit',
122 | author: {
123 | name: commit.author.name,
124 | username: commit.author.username,
125 | email: commit.author.email,
126 | image: gravatar.url(commit.author.email, {}, true),
127 | },
128 | url: commit.url,
129 | message: commit.message,
130 | timestamp: commit.timestamp,
131 | source: {
132 | type: 'plugin',
133 | plugin: 'gitlab',
134 | },
135 | };
136 |
137 | return {
138 | branch: branchname,
139 | trigger: trigger,
140 | deploy: true,
141 | ref: ref,
142 | };
143 | }
144 |
145 | function receiveWebhook(emitter, req, res) {
146 | var payload = req.body;
147 |
148 | res.sendStatus(204);
149 |
150 | var result = startFromCommit(req.project, payload, sendJob);
151 |
152 | if (result && result.skipCi) {
153 | debug('Skipping commit due to [skip ci] tag');
154 | } else if (result && result.deleteTag) {
155 | debug('Skipping push due to delete tag event');
156 | } else if (!result) {
157 | debug('webhook received, but no branches matched or branch is not active');
158 | }
159 |
160 | function sendJob(job) {
161 | emitter.emit('job.prepare', job);
162 | return true;
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/lib/worker.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const git = require('strider-git/worker');
4 |
5 | module.exports = {
6 | init: (dirs, account, config, job, done) => {
7 | return done(null, {
8 | config: config,
9 | account: account,
10 | fetch: (context, done) => {
11 | module.exports.fetch(dirs.data, account, config, job, context, done);
12 | },
13 | });
14 | },
15 | fetch: (dest, account, config, job, context, done) => {
16 | if (config.auth.type === 'https' && !config.auth.username) {
17 | config.auth.username = account.accessToken;
18 | config.auth.password = '';
19 | }
20 |
21 | git.fetch(dest, config, job, context, done);
22 | },
23 | };
24 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "strider-gitlab",
3 | "version": "2.0.0",
4 | "description": "A gitlab provider for strider",
5 | "scripts": {
6 | "test": "npm run lint && npm run tests",
7 | "lint": "eslint lib",
8 | "tests": "mocha -R spec test/",
9 | "release": "standard-version"
10 | },
11 | "engines": {
12 | "node": ">=4.2"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/Strider-CD/strider-gitlab.git"
17 | },
18 | "keywords": [
19 | "git",
20 | "gitlab",
21 | "strider"
22 | ],
23 | "author": {
24 | "name": "Martin Ericson "
25 | },
26 | "license": "MIT",
27 | "readmeFilename": "README.md",
28 | "strider": {
29 | "id": "gitlab",
30 | "title": "GitLab",
31 | "type": "provider",
32 | "hosted": true,
33 | "config": {
34 | "controller": "GitLabCtrl"
35 | },
36 | "accountConfig": {
37 | "setupLink": "/account/#provider-gitlab",
38 | "template": "config/accountConfig.html"
39 | },
40 | "webapp": "lib/webapp.js",
41 | "worker": "lib/worker.js",
42 | "inline_icon": "git-square"
43 | },
44 | "devDependencies": {
45 | "eslint": "4.13.0",
46 | "expect.js": "~0.3.1",
47 | "mocha": "~3.5.3",
48 | "nock": "^10.0.0",
49 | "standard-version": "^7.1.0"
50 | },
51 | "dependencies": {
52 | "async": "~2.6.0",
53 | "debug": "~2.6.0",
54 | "gravatar": "^1.6.0",
55 | "lodash": "~4.17.0",
56 | "parse-link-header": "^0.4.1",
57 | "proxyquire": "^1.7.11",
58 | "strider-git": "^1.0.0",
59 | "superagent": "~3.6.0"
60 | },
61 | "bugs": {
62 | "url": "https://github.com/Strider-CD/strider-gitlab/issues"
63 | },
64 | "homepage": "https://github.com/Strider-CD/strider-gitlab"
65 | }
66 |
--------------------------------------------------------------------------------
/test/README.md:
--------------------------------------------------------------------------------
1 | strider-gitlab tests
2 | ====================
3 |
4 | The tests use mocha for testing and [nock](https://github.com/pgte/nock) for mocking responses from a gitlab server.
5 |
6 | Start out by writing an outline of what you want to test by adding pending tests to a .js file in the test directory,
7 | (inside the appropriate describe blocks)
8 |
9 | like:
10 |
11 | ```
12 | it('should do xyz when abc happens');
13 | it('should do lmn when opq happens');
14 | ... as many as necessary
15 | ```
16 |
17 | Now running npm test will show your tests as "pending" and marked with a "-".
18 |
19 | Next, observe the "happy path", the existing behavior of the code by using util.inspect to log the parameters passed to
20 | the function to be tested when the codepath is run (ensure that the codepath is run by using the Strider web gui if needed),
21 | in order to understand what needs to be passed to the function you want to test in the test file.
22 |
23 | In order to sniff and record the http traffic so that you can create a nock mock of the gitlab server,
24 | use code similar to the following inside the codepath that you want to test:
25 |
26 | ```
27 | In file lib/api.js ...
28 |
29 | var nock = require('nock');
30 | ...
31 |
32 | //for example, inside the removeDeployKey function in lib/api.js
33 | var appendLogToFile = function(content) {
34 | fs.appendFile('/noderoot/gitlab_remove_deploykey.txt', content);
35 | };
36 |
37 | nock.recorder.rec({
38 | logging: appendLogToFile,
39 | });
40 | ```
41 |
42 | In the above example, the file gitlab_remove_deploykey.txt file will contain the statements generated by nock.
43 |
44 | Next write out the body of the pending tests, one at a time.
45 | After writing out the body of a test, do an 'npm test' run, with nock still recording.
46 | Before doing the npm test run, ensure that only the current describe() block is active by adding the .only suffix.
47 | Like so,
48 | ```
49 | describe.only('parseRepo', function(){
50 | it('should correctly parse repo information as received from gitlab server into a repo object');
51 | it('should throw an error if it gets an empty parameter as repo ?');
52 | ...
53 |
54 | ```
55 | This will ensure that only the tests for functionality currently under consideration will be run.
56 | Also, mark all tests other than the current one to be inactive by changing the "it('should ..." to "xit('should ...".
57 | Else, you can ensure that only the current test is run by changing 'it(' to 'it.only('
58 |
59 | Before the run, you must also comment out any code that asks nock to intercept calls - the usual place for which is in
60 | the before, after or beforeEach/afterEach blocks. For example, comment out all the lines inside the following blocks
61 | ```
62 | before('Setup the mock gitlab server', function setupNock() {
63 | nock.cleanAll(); //remove all interceptors
64 | require('./mocks/gitlab_add_key.js')(); //pull in the mock code to simulate the server for this block
65 | });
66 |
67 | after('Tear down mock Gitlab server', function tearDownNock() {
68 | nock.cleanAll(); //remove all interceptors
69 | });
70 | ```
71 | This will ensure that the actual interaction between our code and the gitlab server will be recorded by nock.
72 | Copy out the code generated by nock into a .js file in the mocks subdirectory (see existing files in mocks/ for example)
73 |
74 | Before moving on to writing the next test, empty out the file used by nock for recording, and mark the test already
75 | written with a "xit(" or a "it.skip("
76 |
77 | After you are done with writing the tests, remove or comment out the nock.recorder.rec code so that nock stops recording.
78 | Then, enable all the tests in the block and enable/de-comment out the code that asks nock to
79 | disableNetConnect and mock, and re-run "npm test" to see all your tests run with the gitlab server mocked out of the picture.
80 |
--------------------------------------------------------------------------------
/test/mocha.opts:
--------------------------------------------------------------------------------
1 | --timeout 5000
2 |
--------------------------------------------------------------------------------
/test/mocks/gitlab_add_key.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Simulation of responses from server when we
5 | request the addition of a deploy key.
6 |
7 | nock will simulate a gitlab server running at
8 | localhost:80, where Strider Tester, a user is
9 | registered with the name "stridertester", and
10 | has been registered with api token - zRtVsmeznn7ySatTrnrp
11 | stridertester is an "owner" of a group named "testunion"
12 | and has admin access to three projects -
13 | testunion / unionproject1
14 | Strider Tester / pubproject1
15 | Strider Tester / privproject1
16 | */
17 |
18 | const nock = require('nock');
19 |
20 | module.exports = function() {
21 | //--------------------------------------------------------------------------------------
22 | //simulate a Created 201 response when we try to deploy ssh keys for a project
23 | nock('http://localhost:80')
24 | .post('/api/v3/projects/5/deploy_keys', {
25 | "title": "strider-stridertester/privproject1",
26 | "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAMoSHhKfeE3/oXanAQEZO0Sq20SMjvjmJlTy+CaGz/1uk+glLXi9u2RKtfPRZDceAgyEtRUpqya9Uo1v9bjkIckGLhQwXdSo2G6O3QuzpE3gc6AXTDPQ0ZkkXbSdU9VGL1Zzr+maBnvfwK6IlsNz3fLa4lNV7vz1LaGCg9D1jP+nufZjuDiCAno7D607oG1iHQ3x/BqzphUATav3DFQFT2FBmmittQT0l0mMJ4XsQCQXkwNbDjkLYNon8FYPm9U3AOlzicOGteebt5mhsQtfl9+lL99B8+fk8b24pEEbOxZ4l0HcwMI1R5OLoTzPwSvVw+bp3YPhH2IzfFwK5NUk7 stridertester/privproject1-stridertester@gmail.com\n"
27 | })
28 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
29 | .reply(201, {
30 | "id": 12,
31 | "title": "strider-stridertester/privproject1",
32 | "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAMoSHhKfeE3/oXanAQEZO0Sq20SMjvjmJlTy+CaGz/1uk+glLXi9u2RKtfPRZDceAgyEtRUpqya9Uo1v9bjkIckGLhQwXdSo2G6O3QuzpE3gc6AXTDPQ0ZkkXbSdU9VGL1Zzr+maBnvfwK6IlsNz3fLa4lNV7vz1LaGCg9D1jP+nufZjuDiCAno7D607oG1iHQ3x/BqzphUATav3DFQFT2FBmmittQT0l0mMJ4XsQCQXkwNbDjkLYNon8FYPm9U3AOlzicOGteebt5mhsQtfl9+lL99B8+fk8b24pEEbOxZ4l0HcwMI1R5OLoTzPwSvVw+bp3YPhH2IzfFwK5NUk7 stridertester/privproject1-stridertester@gmail.com",
33 | "created_at": "2015-08-19T03:35:01.863Z"
34 | }, {
35 | server: 'nginx',
36 | date: 'Wed, 19 Aug 2015 03:35:01 GMT',
37 | 'content-type': 'application/json',
38 | 'content-length': '534',
39 | connection: 'close',
40 | status: '201 Created',
41 | etag: '"5a11f9a2bf20878df6e3de77364e297c"',
42 | 'cache-control': 'max-age=0, private, must-revalidate',
43 | 'x-request-id': '565d54e9-f03b-4077-8cf4-a93503060889',
44 | 'x-runtime': '0.099917'
45 | });
46 |
47 | //--------------------------------------------------------------------------------------
48 | //simulate a 400 Bad Request response when an invalid key is sent
49 | nock('http://localhost:80')
50 | .post('/api/v3/projects/5/deploy_keys', {"title": "strider-stridertester/privproject1", "key": "invalid-key"})
51 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
52 | .reply(400, {"message": {"key": ["is invalid"], "fingerprint": ["cannot be generated"]}}, {
53 | server: 'nginx',
54 | date: 'Wed, 19 Aug 2015 04:35:26 GMT',
55 | 'content-type': 'application/json',
56 | 'content-length': '72',
57 | connection: 'close',
58 | status: '400 Bad Request',
59 | 'cache-control': 'no-cache',
60 | 'x-request-id': '907e7139-cb13-407a-864f-a91ce108e419',
61 | 'x-runtime': '0.054109'
62 | });
63 |
64 | //--------------------------------------------------------------------------------------
65 | //simulate a 401 Unauthorized response when invalid credentials are used
66 | nock('http://localhost:80')
67 | .post('/api/v3/projects/5/deploy_keys', {
68 | "title": "strider-stridertester/privproject1",
69 | "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAMoSHhKfeE3/oXanAQEZO0Sq20SMjvjmJlTy+CaGz/1uk+glLXi9u2RKtfPRZDceAgyEtRUpqya9Uo1v9bjkIckGLhQwXdSo2G6O3QuzpE3gc6AXTDPQ0ZkkXbSdU9VGL1Zzr+maBnvfwK6IlsNz3fLa4lNV7vz1LaGCg9D1jP+nufZjuDiCAno7D607oG1iHQ3x/BqzphUATav3DFQFT2FBmmittQT0l0mMJ4XsQCQXkwNbDjkLYNon8FYPm9U3AOlzicOGteebt5mhsQtfl9+lL99B8+fk8b24pEEbOxZ4l0HcwMI1R5OLoTzPwSvVw+bp3YPhH2IzfFwK5NUk7 stridertester/privproject1-stridertester@gmail.com\n"
70 | })
71 | .query({"private_token": "zRtVsmeznn7ySatTrnra"})
72 | .reply(401, {"message": "401 Unauthorized"}, {
73 | server: 'nginx',
74 | date: 'Wed, 19 Aug 2015 05:03:45 GMT',
75 | 'content-type': 'application/json',
76 | 'content-length': '30',
77 | connection: 'close',
78 | status: '401 Unauthorized',
79 | 'cache-control': 'no-cache',
80 | 'x-request-id': '282a2411-dd11-4026-90b3-8a36560c0512',
81 | 'x-runtime': '0.004726'
82 | });
83 |
84 | //--------------------------------------------------------------------------------------
85 | //simulate a 404 response when project could not be found
86 | nock('http://localhost:80')
87 | .post('/api/v3/projects/wrong%20repo%20id/deploy_keys', {
88 | "title": "strider-stridertester/privproject1",
89 | "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAMoSHhKfeE3/oXanAQEZO0Sq20SMjvjmJlTy+CaGz/1uk+glLXi9u2RKtfPRZDceAgyEtRUpqya9Uo1v9bjkIckGLhQwXdSo2G6O3QuzpE3gc6AXTDPQ0ZkkXbSdU9VGL1Zzr+maBnvfwK6IlsNz3fLa4lNV7vz1LaGCg9D1jP+nufZjuDiCAno7D607oG1iHQ3x/BqzphUATav3DFQFT2FBmmittQT0l0mMJ4XsQCQXkwNbDjkLYNon8FYPm9U3AOlzicOGteebt5mhsQtfl9+lL99B8+fk8b24pEEbOxZ4l0HcwMI1R5OLoTzPwSvVw+bp3YPhH2IzfFwK5NUk7 stridertester/privproject1-stridertester@gmail.com\n"
90 | })
91 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
92 | .reply(404, ["1f8b0800000000000003ab56ca4d2d2e4e4c4f55b252323130510828cacf4a4d2e51f0cb2f5170cb2fcd4b51aa050037095a2823000000"], {
93 | server: 'nginx',
94 | date: 'Wed, 19 Aug 2015 05:25:00 GMT',
95 | 'content-type': 'application/json',
96 | 'transfer-encoding': 'chunked',
97 | connection: 'close',
98 | status: '404 Not Found',
99 | 'cache-control': 'no-cache',
100 | 'x-request-id': '2c64ae26-d7b1-4caf-8efd-300893dedf37',
101 | 'x-runtime': '0.005714',
102 | 'content-encoding': 'gzip'
103 | });
104 | }
105 |
--------------------------------------------------------------------------------
/test/mocks/gitlab_create_hooks.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Simulation of responses from a server when we
5 | request the creation of hooks.
6 |
7 | nock will simulate a gitlab server running at
8 | localhost:80, where Strider Tester, a user is
9 | registered with the name "stridertester", and
10 | has been registered with api token - zRtVsmeznn7ySatTrnrp
11 | stridertester is an "owner" of a group named "testunion"
12 | and has admin access to three projects -
13 | testunion / unionproject1
14 | Strider Tester / pubproject1
15 | Strider Tester / privproject1
16 | */
17 | const nock = require('nock');
18 |
19 | module.exports = function() {
20 |
21 | //--------------------------------------------------------------------------------------
22 | //Simulate a 401 reply if api key is not sent
23 | nock('http://localhost:80')
24 | .post('/api/v3/projects/5/hooks', {
25 | "url": "http://localhost:3000/stridertester/privproject1/api/gitlab/webhook",
26 | "push_events": true
27 | })
28 | .reply(401, {"message": "401 Unauthorized"}, {
29 | server: 'nginx',
30 | date: 'Fri, 21 Aug 2015 14:42:46 GMT',
31 | 'content-type': 'application/json',
32 | 'content-length': '30',
33 | connection: 'close',
34 | status: '401 Unauthorized',
35 | 'cache-control': 'no-cache',
36 | 'x-request-id': '052eafeb-0028-4e69-b951-95925efdc232',
37 | 'x-runtime': '0.004600'
38 | });
39 |
40 | //--------------------------------------------------------------------------------------
41 | //Simulate 201 replies when we request the addition of a new project
42 | //(adding hooks and keys)
43 | nock('http://localhost:80')
44 | .post('/api/v3/projects/5/hooks', {
45 | "url": "http://localhost:3000/stridertester/privproject1/api/gitlab/webhook",
46 | "push_events": true
47 | })
48 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
49 | .reply(201, {
50 | "id": 18,
51 | "url": "http://localhost:3000/stridertester/privproject1/api/gitlab/webhook",
52 | "created_at": "2015-08-21T14:11:54.922Z",
53 | "project_id": 5,
54 | "push_events": true,
55 | "issues_events": false,
56 | "merge_requests_events": false,
57 | "tag_push_events": false
58 | }, {
59 | server: 'nginx',
60 | date: 'Fri, 21 Aug 2015 14:11:54 GMT',
61 | 'content-type': 'application/json',
62 | 'content-length': '235',
63 | connection: 'close',
64 | status: '201 Created',
65 | etag: '"3b0821c3d2fa5d74684be993bfba7805"',
66 | 'cache-control': 'max-age=0, private, must-revalidate',
67 | 'x-request-id': '0f470a71-564f-4dcc-ae1f-743b73c98473',
68 | 'x-runtime': '0.021008'
69 | });
70 |
71 | nock('http://localhost:80')
72 | .post('/api/v3/projects/5/deploy_keys', {
73 | "title": "strider-stridertester/privproject1",
74 | "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5CS04M9YZAoOkl9suZuKdBR643lB9Kv2AigyqcCfljhnFK3tWPLEnlsLE7ZnunTC3VcPPesdC8MeWC95EvQgNGH6Y5oXrGcaxZKiVDunk4xxKpJQjzMbp753B4R7i28NyZVShCyYG0+wkqAYlJ4NFWn6PMEOouinY8Z3/JD/e9luq4QgyyrI9s+e7VWKBBof9f6FtaGWXwpaWt7Peud3/AWKkhPELQmDDBEcZ5jxFneLsO0KEQ3qqGlEhQbtYLblgjWvuekd0CAReyUNjyJQG+rfDyVVadAQNHiri7c8cj6Y766FdfRskCKiA7E5IPfnysUcRx8657u6DG4PC6guV stridertester/privproject1-stridertester@gmail.com\n"
75 | })
76 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
77 | .reply(201, {
78 | "id": 22,
79 | "title": "strider-stridertester/privproject1",
80 | "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5CS04M9YZAoOkl9suZuKdBR643lB9Kv2AigyqcCfljhnFK3tWPLEnlsLE7ZnunTC3VcPPesdC8MeWC95EvQgNGH6Y5oXrGcaxZKiVDunk4xxKpJQjzMbp753B4R7i28NyZVShCyYG0+wkqAYlJ4NFWn6PMEOouinY8Z3/JD/e9luq4QgyyrI9s+e7VWKBBof9f6FtaGWXwpaWt7Peud3/AWKkhPELQmDDBEcZ5jxFneLsO0KEQ3qqGlEhQbtYLblgjWvuekd0CAReyUNjyJQG+rfDyVVadAQNHiri7c8cj6Y766FdfRskCKiA7E5IPfnysUcRx8657u6DG4PC6guV stridertester/privproject1-stridertester@gmail.com",
81 | "created_at": "2015-08-21T14:11:54.986Z"
82 | }, {
83 | server: 'nginx',
84 | date: 'Fri, 21 Aug 2015 14:11:55 GMT',
85 | 'content-type': 'application/json',
86 | 'content-length': '534',
87 | connection: 'close',
88 | status: '201 Created',
89 | etag: '"13f3437db289c9c485011a1201db884f"',
90 | 'cache-control': 'max-age=0, private, must-revalidate',
91 | 'x-request-id': '0e829475-9fda-458e-8b34-08c7e8c4c0f5',
92 | 'x-runtime': '0.099567'
93 | });
94 |
95 | //--------------------------------------------------------------------------------------
96 | //Simulate a 404 if we passed an incorrect repo id
97 | nock('http://localhost:80')
98 | .post('/api/v3/projects/invalid-repo/hooks', {
99 | "url": "http://localhost:3000/stridertester/privproject1/api/gitlab/webhook",
100 | "push_events": true
101 | })
102 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
103 | .reply(404, ["1f8b0800000000000003ab56ca4d2d2e4e4c4f55b252323130510828cacf4a4d2e51f0cb2f5170cb2fcd4b51aa050037095a2823000000"], {
104 | server: 'nginx',
105 | date: 'Fri, 21 Aug 2015 14:47:42 GMT',
106 | 'content-type': 'application/json',
107 | 'transfer-encoding': 'chunked',
108 | connection: 'close',
109 | status: '404 Not Found',
110 | 'cache-control': 'no-cache',
111 | 'x-request-id': 'b35510b5-8f3b-434c-bc63-e77ed6a5dc74',
112 | 'x-runtime': '0.006681',
113 | 'content-encoding': 'gzip'
114 | });
115 |
116 | //--------------------------------------------------------------------------------------
117 | //Simulate a 400 if we passed a bad URL
118 | nock('http://localhost:80')
119 | .post('/api/v3/projects/5/hooks', {"url": false, "push_events": true})
120 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
121 | .reply(400, {"message": "400 (Bad request) \"url\" not given"}, {
122 | server: 'nginx',
123 | date: 'Fri, 21 Aug 2015 14:52:41 GMT',
124 | 'content-type': 'application/json',
125 | 'content-length': '49',
126 | connection: 'close',
127 | status: '400 Bad Request',
128 | 'cache-control': 'no-cache',
129 | 'x-request-id': '823fd96a-3829-4dbe-b7ff-75ab89b50455',
130 | 'x-runtime': '0.010701'
131 | });
132 |
133 | //--------------------------------------------------------------------------------------
134 | //Simulate a 401 if wrong credentials were sent
135 | nock('http://localhost:80')
136 | .post('/api/v3/projects/5/hooks', {
137 | "url": "http://localhost:3000/stridertester/privproject1/api/gitlab/webhook",
138 | "push_events": true
139 | })
140 | .query({"private_token": "zRtVsmeznn7ySatTrnra"})
141 | .reply(401, {"message": "401 Unauthorized"}, {
142 | server: 'nginx',
143 | date: 'Fri, 21 Aug 2015 16:38:40 GMT',
144 | 'content-type': 'application/json',
145 | 'content-length': '30',
146 | connection: 'close',
147 | status: '401 Unauthorized',
148 | 'cache-control': 'no-cache',
149 | 'x-request-id': '0f3180af-8f43-495f-91fb-8455313eff9a',
150 | 'x-runtime': '0.004978'
151 | });
152 | };
153 |
--------------------------------------------------------------------------------
/test/mocks/gitlab_delete_hooks_when_absent.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Simulation of responses from server when we
5 | ask for deleting hooks when no hooks are present
6 |
7 | nock will simulate a gitlab server running at
8 | localhost:80, where Strider Tester, a user is
9 | registered with the name "stridertester", and
10 | has been registered with api token - zRtVsmeznn7ySatTrnrp
11 | stridertester is an "owner" of a group named "testunion"
12 | and has admin access to three projects -
13 | testunion / unionproject1
14 | Strider Tester / pubproject1
15 | Strider Tester / privproject1
16 | */
17 | const nock = require('nock');
18 |
19 | module.exports = function() {
20 | //--------------------------------------------------------------------------------------
21 | //Empty array as list of hooks in response
22 | nock('http://localhost:80')
23 | .get('/api/v3/projects/5/hooks')
24 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
25 | .reply(200, [], {
26 | server: 'nginx',
27 | date: 'Fri, 21 Aug 2015 16:08:18 GMT',
28 | 'content-type': 'application/json',
29 | 'content-length': '2',
30 | connection: 'close',
31 | status: '200 OK',
32 | link: '; rel="first", ; rel="last"',
33 | etag: '"d751713988987e9331980363e24189ce"',
34 | 'cache-control': 'max-age=0, private, must-revalidate',
35 | 'x-request-id': 'de64f599-b582-4bcb-b68d-552c2441028e',
36 | 'x-runtime': '0.019459'
37 | });
38 | };
39 |
--------------------------------------------------------------------------------
/test/mocks/gitlab_delete_hooks_when_present.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 |
5 | These scenarios are mock responses from the server
6 | when we request the deletion of hooks, when registered
7 | hooks are present.
8 |
9 | nock will simulate a gitlab server running at
10 | localhost:80, where Strider Tester, a user is
11 | registered with the name "stridertester", and
12 | has been registered with api token - zRtVsmeznn7ySatTrnrp
13 | stridertester is an "owner" of a group named "testunion"
14 | and has admin access to three projects -
15 | testunion / unionproject1
16 | Strider Tester / pubproject1
17 | Strider Tester / privproject1
18 |
19 | */
20 | const nock = require('nock');
21 | module.exports = function() {
22 |
23 | /*--------------------------------------------------------------------------------------
24 | Simulate responses from gitlab server when deleting multiple hooks associated with a
25 | repo - here, there are four hooks with IDs 18, 19, 20 and 21. NOTE: what if other
26 | software has registered hooks with the same repo? Perhaps what we should be doing is,
27 | keeping track of which hooks were registered by Strider, and delete only those.
28 | --------------------------------------------------------------------------------------
29 | */
30 | nock('http://localhost:80')
31 | .persist()
32 | .get('/api/v3/projects/5/hooks')
33 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
34 | .reply(200, ["1f8b0800000000000003c592c14ec4300c44ff25e76e13274db5cd777002a128db9a369025c5719703e2df09688584b8778f9e198ffc243f7c883809a7a1111b25e1c4c2bc3a29531e435a7261679452b230c50989b130925c295e56cacf3832c8b04639474ee124dff1b4e4fc221a311206c6c907ae955a813da8e341c31d74ce80b37d6b8dbaafb96b8bffbec1d6712b8bc70bbe72118e69c346c452362cbfe25348a5aa67a4193de15bf5f89fcb61f67faa7eb63e9b2babda8d55f74e776d6fccad5861d88fb57356b783829bb11e776385fac35d3b68bd3bebe317b6d31703b1030000"], {
35 | server: 'nginx',
36 | date: 'Fri, 21 Aug 2015 15:17:53 GMT',
37 | 'content-type': 'application/json',
38 | 'transfer-encoding': 'chunked',
39 | connection: 'close',
40 | status: '200 OK',
41 | link: '; rel="first", ; rel="last"',
42 | etag: 'W/"66dde97b2afc21eb28d09cea6cd938b5"',
43 | 'cache-control': 'max-age=0, private, must-revalidate',
44 | 'x-request-id': '6dadbbb0-79d7-440f-9cb7-e68ce8a29554',
45 | 'x-runtime': '0.519726',
46 | 'content-encoding': 'gzip'
47 | });
48 |
49 | nock('http://localhost:80')
50 | .delete('/api/v3/projects/5/hooks/20')
51 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
52 | .reply(200, ["1f8b08000000000000038d8dc16ec2301044ff65cfa1761c4095bf83532f96932c89a989dddd757aa8faef1884901017aef366defc4118c11add40a1081666916c958a69f0714e2cb6d35a2b160a2392200b92ca14d64ce98483b4cae7a0a620d1f7ea17fb39a56f68e04eddd5bd6b6020f482a3f3521f8c6e771bfdb931eda1dd5ab3b766fbb1efbaaf3a2b797cabc7486b18f0a65f4a8cf5b0f0ec70c54518ac50c1060273417e84471fb9a667a4091de14f65f242c54fee49755f2d49f0d9f47f014f6dcfe639010000"], {
53 | server: 'nginx',
54 | date: 'Fri, 21 Aug 2015 15:17:53 GMT',
55 | 'content-type': 'application/json',
56 | 'transfer-encoding': 'chunked',
57 | connection: 'close',
58 | status: '200 OK',
59 | etag: 'W/"441a3588cef9fb94b7d512ef5e950ea7"',
60 | 'cache-control': 'max-age=0, private, must-revalidate',
61 | 'x-request-id': 'b694345c-e83b-4b65-ae85-08d4464f3c07',
62 | 'x-runtime': '0.025442',
63 | 'content-encoding': 'gzip'
64 | });
65 |
66 | nock('http://localhost:80')
67 | .delete('/api/v3/projects/5/hooks/19')
68 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
69 | .reply(200, ["1f8b08000000000000038d8dc16ec2301044ff65cfa1b603918abf831317cb244b6230b1d95da787aaff8e41080971e975decc9b5f080358b36da050040b9348b64ac5d4fb382516bbd65a2b160a0392200b92ca14964ce984bd18e573506390e80fea070f534a6768e049dddddd35d0137ac1c179a90fad36dd4a7faf5ab3331bdb6e6cd77e6db5d9d759c9c3bf7a8cb4841e1ffab9c4580f0b4f0e179c85c10a156c203017e45778f4916b7a411ad1115e2b930f2a7e746faae76a4e82efa6bf1b8989ea2039010000"], {
70 | server: 'nginx',
71 | date: 'Fri, 21 Aug 2015 15:17:53 GMT',
72 | 'content-type': 'application/json',
73 | 'transfer-encoding': 'chunked',
74 | connection: 'close',
75 | status: '200 OK',
76 | etag: 'W/"a589536875f3986c7a8dbb852470a6b9"',
77 | 'cache-control': 'max-age=0, private, must-revalidate',
78 | 'x-request-id': 'f7ae7e88-4d88-4410-8fe3-e5f9e571d46c',
79 | 'x-runtime': '0.014732',
80 | 'content-encoding': 'gzip'
81 | });
82 |
83 | nock('http://localhost:80')
84 | .delete('/api/v3/projects/5/hooks/18')
85 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
86 | .reply(200, ["1f8b08000000000000038d8dc16ec2301044ff65cfa1b60391c0dfd11317cb244b627063b3bb4e0f55ff1d831012e2c275decc9b3f080358b36da050040b9348b64ac5d4fb382516bbd65a2b160a0392200b92ca14964ce984bd18e573506390e80fea170f534a6768e041ddcddd35d0137ac1c179a90fad36dd4a6f57adf9361b6b8ced365fbbb6ddd759c9c3473d465a428f77fd5c62ac878527870bcec260850a3610980bf2333cfac835fd411ad1115e2a93372a7e742faac76a4e82afa6ff2bc45c0bae39010000"], {
87 | server: 'nginx',
88 | date: 'Fri, 21 Aug 2015 15:17:53 GMT',
89 | 'content-type': 'application/json',
90 | 'transfer-encoding': 'chunked',
91 | connection: 'close',
92 | status: '200 OK',
93 | etag: 'W/"833cfcd8b12696291ad963463ea5ec47"',
94 | 'cache-control': 'max-age=0, private, must-revalidate',
95 | 'x-request-id': 'f36e3cd5-2f64-4859-93b1-dde3d6c4863e',
96 | 'x-runtime': '0.014471',
97 | 'content-encoding': 'gzip'
98 | });
99 |
100 | nock('http://localhost:80')
101 | .delete('/api/v3/projects/5/hooks/21')
102 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
103 | .reply(200, ["1f8b08000000000000038d8dc16ec2301044ff65cfa1b6138290bfa3272e964996c4d48dcdee3a3d54fd770c4248a817aef366defc4218c1b6a68142112ccc22d92a15d3e0e39c586ca7b5562c1446244116249529ac99d2190731cae7a0a620d11fd50f1ee794bea08107753777dfc040e80547e7a53eb4daf41bbddfb4e6d36c6d676cbffbe83b7da8b392c7b77a8cb48601effaa5c4580f0bcf0e575c84c10a156c203017e46778f2916bfa8d34a123bc5426ffa8f8c9bda81eab2509be9afeae07c9ee7a39010000"], {
104 | server: 'nginx',
105 | date: 'Fri, 21 Aug 2015 15:17:53 GMT',
106 | 'content-type': 'application/json',
107 | 'transfer-encoding': 'chunked',
108 | connection: 'close',
109 | status: '200 OK',
110 | etag: 'W/"3586f6e4865bead39cdd672bd35adf9a"',
111 | 'cache-control': 'max-age=0, private, must-revalidate',
112 | 'x-request-id': 'b73a0d0d-7cab-4c25-a364-237699b677c9',
113 | 'x-runtime': '0.519791',
114 | 'content-encoding': 'gzip'
115 | });
116 |
117 | //--------------------------------------------------------------------------------------
118 | //Simulate case when api_key is not provided
119 | nock('http://localhost:80')
120 | .get('/api/v3/projects/5/hooks')
121 | .reply(401, {"message": "401 Unauthorized"}, {
122 | server: 'nginx',
123 | date: 'Fri, 21 Aug 2015 16:02:41 GMT',
124 | 'content-type': 'application/json',
125 | 'content-length': '30',
126 | connection: 'close',
127 | status: '401 Unauthorized',
128 | 'cache-control': 'no-cache',
129 | 'x-request-id': '343536d3-1830-45de-a609-78d98844599c',
130 | 'x-runtime': '0.003969'
131 | });
132 |
133 | //--------------------------------------------------------------------------------------
134 | //Simulate case when invalid repo id is sent
135 | nock('http://localhost:80')
136 | .get('/api/v3/projects/invalid-repo/hooks')
137 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
138 | .reply(404, ["1f8b0800000000000003ab56ca4d2d2e4e4c4f55b252323130510828cacf4a4d2e51f0cb2f5170cb2fcd4b51aa050037095a2823000000"], {
139 | server: 'nginx',
140 | date: 'Fri, 21 Aug 2015 16:05:38 GMT',
141 | 'content-type': 'application/json',
142 | 'transfer-encoding': 'chunked',
143 | connection: 'close',
144 | status: '404 Not Found',
145 | 'cache-control': 'no-cache',
146 | 'x-request-id': '3b41f707-85d9-49cd-a052-bcdcd0180b20',
147 | 'x-runtime': '0.005461',
148 | 'content-encoding': 'gzip'
149 | });
150 |
151 | //--------------------------------------------------------------------------------------
152 | //Case when invalid credentials are sent
153 | nock('http://localhost:80')
154 | .get('/api/v3/projects/5/hooks')
155 | .query({"private_token": "zRtVsmeznn7ySatTrnra"})
156 | .reply(401, {"message": "401 Unauthorized"}, {
157 | server: 'nginx',
158 | date: 'Fri, 21 Aug 2015 16:33:39 GMT',
159 | 'content-type': 'application/json',
160 | 'content-length': '30',
161 | connection: 'close',
162 | status: '401 Unauthorized',
163 | 'cache-control': 'no-cache',
164 | 'x-request-id': 'bbf03f1f-8c62-4b7c-9bb1-e1fbb3856411',
165 | 'x-runtime': '0.004745'
166 | });
167 | };
168 |
--------------------------------------------------------------------------------
/test/mocks/gitlab_delete_key_when_absent.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Here we simulate the response of the server when there
5 | no deploy keys registered in the project.
6 |
7 | nock will simulate a gitlab server running at
8 | localhost:80, where Strider Tester, a user is
9 | registered with the name "stridertester", and
10 | has been registered with api token - zRtVsmeznn7ySatTrnrp
11 | stridertester is an "owner" of a group named "testunion"
12 | and has admin access to three projects -
13 | testunion / unionproject1
14 | Strider Tester / pubproject1
15 | Strider Tester / privproject1
16 |
17 | */
18 | const nock = require('nock');
19 |
20 | module.exports = function() {
21 |
22 | nock('http://localhost:80')
23 | .get('/api/v3/projects/5/deploy_keys')
24 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
25 | .reply(200, [], {
26 | server: 'nginx',
27 | date: 'Wed, 19 Aug 2015 07:44:07 GMT',
28 | 'content-type': 'application/json',
29 | 'content-length': '2',
30 | connection: 'close',
31 | status: '200 OK',
32 | etag: '"d751713988987e9331980363e24189ce"',
33 | 'cache-control': 'max-age=0, private, must-revalidate',
34 | 'x-request-id': '6335ed65-d224-42e7-bf6d-948559539f88',
35 | 'x-runtime': '0.015344'
36 | });
37 | };
38 |
--------------------------------------------------------------------------------
/test/mocks/gitlab_delete_project.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Simulate responses from server when we try to
5 | delete a project.
6 |
7 | nock will simulate a gitlab server running at
8 | localhost:80, where Strider Tester, a user is
9 | registered with the name "stridertester", and
10 | has been registered with api token - zRtVsmeznn7ySatTrnrp
11 | stridertester is an "owner" of a group named "testunion"
12 | and has admin access to three projects -
13 | testunion / unionproject1
14 | Strider Tester / pubproject1
15 | Strider Tester / privproject1
16 | */
17 |
18 | const nock = require('nock');
19 |
20 | module.exports = function() {
21 |
22 | //--------------------------------------------------------------------------------------
23 | //Simulate responses during a successful delete operation
24 | nock('http://localhost:80')
25 | .get('/api/v3/projects/5/deploy_keys')
26 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
27 | .reply(200, ["1f8b080000000000000375914b8fa2400084ffca84abe3740302e26991a73c544659d4cd66836d232d0fb1bb5570b2ff7d35d9cb1eb62e95aad4a192efc797400ec244d4de054e78858589c03825074c877f9d63c631052d25b7969e4f18715178174adcbfa6ac185296bd194f4de5f92333c51e49f62b5a466c4c5fb5115b374ac2540d41752a734c2173a792a6b68d28ad34b52f2278d1a2dd6e7d2cf9d8c52d2b46b96dccf083fbdab987eea0408113b941ea2f7d5d424a536c1534b6ad4cf2b05dcddcf69458ae978f5cffd2a669ba6ff00eceafcbade55da7614b48c969b35191db5f947902d2b06ee60b51be2730ec5a45d2a3c1c1ebf69e6f6138ebd9f95672ad32ecf9f5d69f10f556eb8ad58613c04e078cdf8e5a4e06f4ae3a6c7395b6345e786668aa7982880b2ea4b3133da795fcd8630f01d6a8b06ac896811a8278162c8ad5b5e8ca1105a1cd833275827e2d6bb9f368bb1a24b934c3aae5c42650f2689f176c1f2f756edf53bd3625ff1c9b9b512546d1e7f7e7e3f2d347e0f0f67f3effa2fb76ac33527da073fde48628ce383efccaf8139f04456508c743515f436d22cb1359f9186b7027fcfef90733edcd2b18020000"], {
28 | server: 'nginx',
29 | date: 'Wed, 19 Aug 2015 07:34:26 GMT',
30 | 'content-type': 'application/json',
31 | 'transfer-encoding': 'chunked',
32 | connection: 'close',
33 | status: '200 OK',
34 | etag: 'W/"6b396edfec74bfbd19e6db1f696be410"',
35 | 'cache-control': 'max-age=0, private, must-revalidate',
36 | 'x-request-id': 'd7010f79-a813-4e88-8b23-4b8adac5bc43',
37 | 'x-runtime': '0.026638',
38 | 'content-encoding': 'gzip'
39 | });
40 |
41 | nock('http://localhost:80')
42 | .delete('/api/v3/projects/5/hooks/14')
43 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
44 | .reply(200, ["1f8b08000000000000038d8db14ec4301044ff65eb1c76081177fe0e2a1acb970c89c1c466771d0ac4bf63d009e944433b6fe6cd07c5995c7fd751e5448e56d5e28c49790a69cda26eb0d61a518e3358210a3685e35e383f63d2de8412cd123585b379c779cdf9853aba50ffed1e3b9a184131fba0ede1d6f6e3c11e0ffde9c1debb6170c37873b4a7c736ab65fe574fc07b9cf0a3df6a4aedb0caeab1635321a75cd15114a990dff0292469e92b788167bc35a67fa886c55fa92eab2d2bae4d9f5f95e44d6c39010000"], {
45 | server: 'nginx',
46 | date: 'Wed, 19 Aug 2015 07:34:26 GMT',
47 | 'content-type': 'application/json',
48 | 'transfer-encoding': 'chunked',
49 | connection: 'close',
50 | status: '200 OK',
51 | etag: 'W/"48100b28764f2de3fffabb9de2e5c741"',
52 | 'cache-control': 'max-age=0, private, must-revalidate',
53 | 'x-request-id': 'f3623d3d-af5f-4673-a0c8-568a3f5829cb',
54 | 'x-runtime': '0.019863',
55 | 'content-encoding': 'gzip'
56 | });
57 |
58 | nock('http://localhost:80')
59 | .delete('/api/v3/projects/5/deploy_keys/17')
60 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
61 | .reply(200, ["1f8b08000000000000038c52c992a24014fc950eaeb65dc5be9c06651341a5d541bd74201652b288558582f3f38331276ff36ef95e664646e4fbc3e11367f0ea27d752447e5ea06ecbf2934b094a183afd248c333801f2f2186a635edf40d510454394bf34151eb841d69cfe8b57a07e30a2341f139a7c98c34cc4c53399f27d2ad82f6899913979adcdc8ba131cc44a00ca4b912102a93b1154a5a97961ad2a7d1ec29b1a1e0e9b73c1341735349732db9ca127f3d56b0fdd519ece9dd09dc7fecad78554aef3bd9c6ab695081eb2cb99db5cb696eb6592ebdf9a388e8f353ac045bbda5b5e3b091a8c0b46ea9d92bafd4d5e6c411c54f562c98b8f2d0cba4616f47074f2baa3e75b08ce7a7abd174c2d4d7bd1defb4b4abcf5a6a495e9cc61a703caee6735c323f2501cba6b853d8996de34982ad936c52eb8e1cedeea1929c5e7117929a0b502cb1aef29a8208866f365be6ef3ae9008086c362f6267de6f4435739e4d57816d26cc906239d114c85978cc727a8c563ab31fb15e4d05ff1a4d7752c987e1f7ef2171f1eda7e0f44119c1274418a20c11d0107c6fc8f58252c68fdf4ebfce5582cbaff45a0dfd32cc4af46aee9ff89df9663290335c9f11199cebd7d748a2a123031e0d2d3124edefac4c4dacd252acd28cacd24cac9281a9c8cc2a35cdcac4c0ca32cdcad2d0ca3211a8bfa03429273359c92a2d31a738b5160053bf1cd39c020000"], {
62 | server: 'nginx',
63 | date: 'Wed, 19 Aug 2015 07:34:26 GMT',
64 | 'content-type': 'application/json',
65 | 'transfer-encoding': 'chunked',
66 | connection: 'close',
67 | status: '200 OK',
68 | etag: 'W/"73e7baa6dacd78d9a403fb0391b6e4bb"',
69 | 'cache-control': 'max-age=0, private, must-revalidate',
70 | 'x-request-id': 'f60ad59d-8088-40d4-9358-37ff188ec374',
71 | 'x-runtime': '0.033622',
72 | 'content-encoding': 'gzip'
73 | });
74 |
75 | //--------------------------------------------------------------------------------------
76 | //simulate trying to delete a project when an incorrect repo id is specified
77 | nock('http://localhost:80')
78 | .get('/api/v3/projects/wrong%20repo%20id/deploy_keys')
79 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
80 | .reply(404, ["1f8b0800000000000003ab56ca4d2d2e4e4c4f55b252323130510828cacf4a4d2e51f0cb2f5170cb2fcd4b51aa050037095a2823000000"], {
81 | server: 'nginx',
82 | date: 'Wed, 19 Aug 2015 08:35:42 GMT',
83 | 'content-type': 'application/json',
84 | 'transfer-encoding': 'chunked',
85 | connection: 'close',
86 | status: '404 Not Found',
87 | 'cache-control': 'no-cache',
88 | 'x-request-id': '234fcd84-6d78-44fb-921f-0c613414671a',
89 | 'x-runtime': '0.005932',
90 | 'content-encoding': 'gzip'
91 | });
92 |
93 | //--------------------------------------------------------------------------------------
94 | //simulate 401 when wrong credentials are specified
95 | nock('http://localhost:80')
96 | .get('/api/v3/projects/5/deploy_keys')
97 | .query({"private_token": "zRtVsmeznn7ySatTrnra"})
98 | .reply(401, {"message": "401 Unauthorized"}, {
99 | server: 'nginx',
100 | date: 'Sat, 22 Aug 2015 04:43:22 GMT',
101 | 'content-type': 'application/json',
102 | 'content-length': '30',
103 | connection: 'close',
104 | status: '401 Unauthorized',
105 | 'cache-control': 'no-cache',
106 | 'x-request-id': '404162fd-f217-4d03-a429-d08edd893921',
107 | 'x-runtime': '0.460579'
108 | });
109 | };
110 |
--------------------------------------------------------------------------------
/test/mocks/gitlab_get.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | This file sets up mock responses as received from gitlab for each request fired
5 | during get operations.
6 |
7 | nock will simulate a gitlab server running at
8 | localhost:80, where Strider Tester, a user is
9 | registered with the name "stridertester", and
10 | has been registered with api token - zRtVsmeznn7ySatTrnrp
11 | stridertester is an "owner" of a group named "testunion"
12 | and has admin access to three projects -
13 | testunion / unionproject1
14 | Strider Tester / pubproject1
15 | Strider Tester / privproject1
16 | */
17 |
18 | const nock = require('nock');
19 |
20 | module.exports = function() {
21 | nock('http://localhost:80')
22 | .get('/api/v3/projects')
23 | .query({"private_token": "zRtVsmeznn7ySatTrnrp", "per_page": "100"})
24 | .reply(200, ["1f8b0800000000000003e5966d6f9b3010c7bf0af2eb94674862a9dabec3fa6a5d850c5c823702cc36a0aaea77df199c2c84e6a1daa44a9b9444e87c773eff7df7238f2f84e7842e1724079909de285e57849287824b0b3fcc6a44fd1d3265ed18af147e21b7d2674b15607d5182e720ac07900a84b4da4ac7ea4c1bd6962a4905abb20293ed9876c015c5b649c9a522f4f169419a362d7946e8869512168489ace01d6035c6d071c9535e72f59c94d04149a8bb205216492bca44d58980a6c6ec5bae3e57750e1d5558c8508433fc9aca3d1b3d70f342a9e624549ba8e30cd1cee5e81e521d8cfbdd1284db556c07e83da9c498939eab22d10eb26199f63aec6d39a38cfbda31a2614a8b789a489b2f249a4a8069b8942dc8042a96965a64255a147d07620ba8e44f5c53b3d59effe0a711b2e24d03c7bee6ba32014c419e30bc5ee2bb5e74e7aeeebcd5831b537f4923d7f6d7abaf584889dd90b04cf14edfec5bde6b1a2e6ddff7b5f790b51689ee526f54d58836766e7050faa0e16fcd8e4d755fc198a66acbd2247ebb5cac38f2ed78e9e902da263f77ac89dfb9f9d135585b51b78db5a985d540dd9460692bafb6961c67c8c68d58c7141384be90a1cf7495afaf7bf3d87b836d311e3cbe30b2c360ed271753bf7722c7deb86120fd2b13698ea74f0bc2c1817fe74c5e8b3f339567c3508ba10fb4ca6640a714d3172e4198b5491e5cd24d880d2715760436f9d0c470b8ba291ffabeb7b762bc543bab77cef8e8041b6c2cc85731e441eee35310876eb664ae17a7ee7abdfc24ef43f75bebba7e9cdf235f2bc533c42a768229ea4845dc5a1be718981e0aa1320d3248991be7992e49f9a148096918d9ebd58d48896810da61384cf431520c3e2648090f529fdebfd1edd4fc1b2d98ee02063d9706911dae822b5c99f84db972c4891106061b733e44333e6810eddfe69e26ce7bb1f0d75ed4274d2578f7675c9827b80d0c4771ff0419a6e7b9150dd3a83d1be6d6ab7098867c241dbc80466b7be9c5b7fde1086888effb20fc0fe8f0f40bfc3991d8f20b0000"], {
25 | server: 'nginx',
26 | date: 'Tue, 18 Aug 2015 14:32:30 GMT',
27 | 'content-type': 'application/json',
28 | 'transfer-encoding': 'chunked',
29 | connection: 'close',
30 | status: '200 OK',
31 | link: '; rel="first", ; rel="last"',
32 | etag: 'W/"29dc98e2063c4571f4a98da2b681bb60"',
33 | 'cache-control': 'max-age=0, private, must-revalidate',
34 | 'x-request-id': '374db4c9-de67-4408-b9e8-49651bf8a7f3',
35 | 'x-runtime': '0.616995',
36 | 'content-encoding': 'gzip'
37 | });
38 |
39 | nock('http://localhost:80')
40 | .get('/api/v3/projects')
41 | .query({"private_token": "zRtVsmeznn7ySatTrnrp", "per_page": "100", "page": "1"})
42 | .reply(200, ["1f8b0800000000000003e5966d6f9b3010c7bf0af2eb94674862a9dabec3fa6a5d850c5c823702cc36a0aaea77df199c2c84e6a1daa44a9b9444e87c773eff7df7238f2f84e7842e1724079909de285e57849287824b0b3fcc6a44fd1d3265ed18af147e21b7d2674b15607d5182e720ac07900a84b4da4ac7ea4c1bd6962a4905abb20293ed9876c015c5b649c9a522f4f169419a362d7946e8869512168489ace01d6035c6d071c9535e72f59c94d04149a8bb205216492bca44d58980a6c6ec5bae3e57750e1d5558c8508433fc9aca3d1b3d70f342a9e624549ba8e30cd1cee5e81e521d8cfbdd1284db556c07e83da9c498939eab22d10eb26199f63aec6d39a38cfbda31a2614a8b789a489b2f249a4a8069b8942dc8042a96965a64255a147d07620ba8e44f5c53b3d59effe0a711b2e24d03c7bee6ba32014c419e30bc5ee2bb5e74e7aeeebcd5831b537f4923d7f6d7abaf584889dd90b04cf14edfec5bde6b1a2e6ddff7b5f790b51689ee526f54d58836766e7050faa0e16fcd8e4d755fc198a66acbd2247ebb5cac38f2ed78e9e902da263f77ac89dfb9f9d135585b51b78db5a985d540dd9460692bafb6961c67c8c68d58c7141384be90a1cf7495afaf7bf3d87b836d311e3cbe30b2c360ed271753bf7722c7deb86120fd2b13698ea74f0bc2c1817fe74c5e8b3f339567c3508ba10fb4ca6640a714d3172e4198b5491e5cd24d880d2715760436f9d0c470b8ba291ffabeb7b762bc543bab77cef8e8041b6c2cc85731e441eee35310876eb664ae17a7ee7abdfc24ef43f75bebba7e9cdf235f2bc533c42a768229ea4845dc5a1be718981e0aa1320d3248991be7992e49f9a148096918d9ebd58d48896810da61384cf431520c3e2648090f529fdebfd1edd4fc1b2d98ee02063d9706911dae822b5c99f84db972c4891106061b733e44333e6810eddfe69e26ce7bb1f0d75ed4274d2578f7675c9827b80d0c4771ff0419a6e7b9150dd3a83d1be6d6ab7098867c241dbc80466b7be9c5b7fde1086888effb20fc0fe8f0f40bfc3991d8f20b0000"], {
43 | server: 'nginx',
44 | date: 'Tue, 18 Aug 2015 14:32:30 GMT',
45 | 'content-type': 'application/json',
46 | 'transfer-encoding': 'chunked',
47 | connection: 'close',
48 | status: '200 OK',
49 | link: '; rel="first", ; rel="last"',
50 | etag: 'W/"29dc98e2063c4571f4a98da2b681bb60"',
51 | 'cache-control': 'max-age=0, private, must-revalidate',
52 | 'x-request-id': '374db4c9-de67-4408-b9e8-49651bf8a7f3',
53 | 'x-runtime': '0.616995',
54 | 'content-encoding': 'gzip'
55 | });
56 |
57 | //mocks a response when incorrect credentials are specified
58 | nock('http://localhost:80')
59 | .get('/api/v3/projects')
60 | .query({"private_token": "zRtVsmeznn7ySatTrnra", "per_page": "100"})
61 | .reply(401, {"message": "401 Unauthorized"}, {
62 | server: 'nginx',
63 | date: 'Wed, 19 Aug 2015 01:09:38 GMT',
64 | 'content-type': 'application/json',
65 | 'content-length': '30',
66 | connection: 'close',
67 | status: '401 Unauthorized',
68 | 'cache-control': 'no-cache',
69 | 'x-request-id': '4eb8c9f8-3a0c-4b70-aa9a-cfd61ea15b87',
70 | 'x-runtime': '0.444739'
71 | });
72 |
73 | //mocks a response when an incorrect path is specified
74 | nock('http://localhost:80')
75 | .get('/api/v3/nonexistentpath')
76 | .query({"private_token": "zRtVsmeznn7ySatTrnrp", "per_page": "100"})
77 | .reply(404, ["1f8b08000000000000039551b152c3300cddf315c24b61a9e9b5639a053816383a74615462a5f6c5b173b6c291bf4771e00358ec93a5f7f4de737df7fcf174fdbcbc80e5d13755fd77119aa602a8d9b1a7e66a0926bc112c71de25021fe3e0c20dfa98a08bb3371022434bf2300703f7a7c7d343ad37eccae25d18c026eacf4a674676ddbecb59c148c6e159e52e11050589bc14bc78ca968815f032d159317db32ef35a146a5bb455751bcd5234da43230ba571d8cae33ff5ee057adca0493608e3d4bce3409067f1cae21d8d499433b82c7653a28e01c5275be4d22fd958cc61c730c62f324239fd325d3c6126c10546c14982095e1dbf612bb4a30b2e734296205dbf36856f0d4bceb20e61940111b331d67a732d8acb7ffd000988a5bfc0010000"], {
78 | server: 'nginx',
79 | date: 'Wed, 19 Aug 2015 01:21:43 GMT',
80 | 'content-type': 'text/html; charset=utf-8',
81 | 'transfer-encoding': 'chunked',
82 | connection: 'close',
83 | status: '404 Not Found',
84 | 'x-frame-options': 'DENY',
85 | 'x-xss-protection': '1; mode=block',
86 | 'x-content-type-options': 'nosniff',
87 | 'x-ua-compatible': 'IE=edge',
88 | 'cache-control': 'no-cache',
89 | 'x-request-id': '78eec92b-b96f-49bb-a46f-3b9ed7d8ff71',
90 | 'x-runtime': '0.077683',
91 | 'content-encoding': 'gzip'
92 | });
93 | };
94 |
--------------------------------------------------------------------------------
/test/mocks/gitlab_webapp_getbranches.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Here we simulate the response of the server when asked
5 | to get a list of branches from the privproject1 repo
6 |
7 | nock will simulate a gitlab server running at
8 | localhost:80, where Strider Tester, a user is
9 | registered with the name "stridertester", and
10 | has been registered with api token - zRtVsmeznn7ySatTrnrp
11 | stridertester is an "owner" of a group named "testunion"
12 | and has admin access to three projects -
13 | testunion / unionproject1
14 | Strider Tester / pubproject1
15 | Strider Tester / privproject1
16 |
17 | privproject has two branches firstbranch and master
18 | */
19 |
20 | const nock = require('nock');
21 |
22 | module.exports = function() {
23 |
24 | //--------------------------------------------------------------------------------------
25 | //Simulate a good response that sends the correct branches
26 | nock('http://localhost:80')
27 | .get('/api/v3/projects/5/repository/branches')
28 | .query({"private_token": "zRtVsmeznn7ySatTrnrp", "per_page": "100"})
29 | .reply(200, ["1f8b0800000000000003bd914f4f023110c5bf0ae95520fdb74bdb9346397a516e48c8b49d42137631dd723084ef6e1102c68872d1ebbc99f732ef37dd92161a24868498ba6c13b46e49fac4ad9b266662b624fa22faa0400826a5422aaa5a680ca09c730a3c30e625b35450a145b96cb0eb60b177bc5f42bb40df7b1adf3d3c8e878d7f698bfe0a09db3c8fbe23664a24ad9d05ad99b3b606ea18adb50e0e2d528e4e0b1194ac2b2fc9ac4f609397eb847eee21effd3965d580aa01e71356994a19560d29a537541b4a4bd2617f7efcef39a7e831f526d8654c67191b88abe2d61df4fc21df2ef6d36169e1d445be3ef8505eb1b9987ddef82d7e571a4beb8caee4131360d5e1ae7f82d6c0f1992fbcaeaef5332ff0bed0b2b185f4d60b7185dff01a8112bc70d1b5171c582d1843096847ca8f2cd5238bdc0685f8132fa6275c18ce8c90ffcbeb52f0dff1ca6983bbd93b8b937b0e65030000"], {
30 | server: 'nginx',
31 | date: 'Sat, 22 Aug 2015 07:32:10 GMT',
32 | 'content-type': 'application/json',
33 | 'transfer-encoding': 'chunked',
34 | connection: 'close',
35 | status: '200 OK',
36 | etag: 'W/"a5766ebd98e6dcefebb0256942be9cf1"',
37 | 'cache-control': 'max-age=0, private, must-revalidate',
38 | 'x-request-id': '6166a894-b650-4e17-9057-6c23bc4e959f',
39 | 'x-runtime': '0.019611',
40 | 'content-encoding': 'gzip'
41 | });
42 |
43 | //--------------------------------------------------------------------------------------
44 | //Simulate a 401 when bad credentials are sent
45 | nock('http://localhost:80')
46 | .get('/api/v3/projects/5/repository/branches')
47 | .query({"private_token": "badkey", "per_page": "100"})
48 | .reply(401, {"message": "401 Unauthorized"}, {
49 | server: 'nginx',
50 | date: 'Sat, 22 Aug 2015 07:45:55 GMT',
51 | 'content-type': 'application/json',
52 | 'content-length': '30',
53 | connection: 'close',
54 | status: '401 Unauthorized',
55 | 'cache-control': 'no-cache',
56 | 'x-request-id': 'c487af2c-3a4f-45ff-938e-9ee196429b65',
57 | 'x-runtime': '0.003879'
58 | });
59 |
60 | //--------------------------------------------------------------------------------------
61 | //Simulate a 404 when an invalid repo id of "invalidrepo" is sent
62 | //Heaven forbid that there actually is a project with repo ID "NaN"
63 | nock('http://localhost:80')
64 | .get('/api/v3/projects/NaN/repository/branches')
65 | .query({"private_token": "zRtVsmeznn7ySatTrnrp", "per_page": "100"})
66 | .reply(404, ["1f8b0800000000000003ab56ca4d2d2e4e4c4f55b252323130510828cacf4a4d2e51f0cb2f5170cb2fcd4b51aa050037095a2823000000"], {
67 | server: 'nginx',
68 | date: 'Sat, 22 Aug 2015 07:56:44 GMT',
69 | 'content-type': 'application/json',
70 | 'transfer-encoding': 'chunked',
71 | connection: 'close',
72 | status: '404 Not Found',
73 | 'cache-control': 'no-cache',
74 | 'x-request-id': '60c9a1ef-0dbf-4533-8f6e-0aded176d319',
75 | 'x-runtime': '0.006694',
76 | 'content-encoding': 'gzip'
77 | });
78 | };
79 |
--------------------------------------------------------------------------------
/test/mocks/gitlab_webapp_getfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Here we simulate the response of the server when asked
5 | to get the strider.json file from the privproject1 repo
6 |
7 | nock will simulate a gitlab server running at
8 | localhost:80, where Strider Tester, a user is
9 | registered with the name "stridertester", and
10 | has been registered with api token - zRtVsmeznn7ySatTrnrp
11 | stridertester is an "owner" of a group named "testunion"
12 | and has admin access to three projects -
13 | testunion / unionproject1
14 | Strider Tester / pubproject1
15 | Strider Tester / privproject1
16 | */
17 |
18 | const nock = require('nock');
19 |
20 | module.exports = function() {
21 |
22 | nock('http://localhost:80')
23 | .get('/api/v3/projects/5/repository/blobs/master')
24 | .query({"private_token": "zRtVsmeznn7ySatTrnrp", "per_page": "100", "filepath": "strider.json"})
25 | .reply(200, ["1f8b0800000000000003abe6525050ca4bcc4d55b25250cacd2c294a54d2010915a726e7e7a580048b12cb3221622519994560a1e2d2a24aa8bab4fcd2a2920c90605246625ea912572d170048d47f8653000000"], {
26 | server: 'nginx',
27 | date: 'Wed, 19 Aug 2015 14:12:21 GMT',
28 | 'content-type': 'text/plain',
29 | 'transfer-encoding': 'chunked',
30 | connection: 'close',
31 | status: '200 OK',
32 | etag: 'W/"079e2a69978805f09ba55d6f6b3705f2"',
33 | 'cache-control': 'max-age=0, private, must-revalidate',
34 | 'x-request-id': 'daffad5d-cdff-4f23-bd2d-aec209109619',
35 | 'x-runtime': '0.013665',
36 | 'content-encoding': 'gzip'
37 | });
38 |
39 | //--------------------------------------------------------------------------------------
40 | //Simulate a scenario where the project does not contain a strider.json
41 | //For this purpose we have added another project named priproject2 with id 8
42 | nock('http://localhost:80')
43 | .get('/api/v3/projects/8/repository/blobs/master')
44 | .query({"private_token": "zRtVsmeznn7ySatTrnrp", "per_page": "100", "filepath": "strider.json"})
45 | .reply(404, ["1f8b0800000000000003ab56ca4d2d2e4e4c4f55b2523231305170cbcc4955f0cb2f5170cb2fcd4b51aa0500db72e71020000000"], {
46 | server: 'nginx',
47 | date: 'Mon, 24 Aug 2015 06:28:17 GMT',
48 | 'content-type': 'application/json',
49 | 'transfer-encoding': 'chunked',
50 | connection: 'close',
51 | status: '404 Not Found',
52 | 'cache-control': 'no-cache',
53 | 'x-request-id': '9e221d4c-9109-4291-929b-2e7cb1e4f057',
54 | 'x-runtime': '0.022119',
55 | 'content-encoding': 'gzip'
56 | });
57 | };
58 |
--------------------------------------------------------------------------------
/test/mocks/gitlab_webapp_listrepos.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Here we simulate the response of the server when asked
5 | to get a list of repositories from the gitlab server
6 |
7 | nock will simulate a gitlab server running at
8 | localhost:80, where Strider Tester, a user is
9 | registered with the name "stridertester", and
10 | has been registered with api token - zRtVsmeznn7ySatTrnrp
11 | stridertester is an "owner" of a group named "testunion"
12 | and has admin access to three projects -
13 | testunion / unionproject1
14 | Strider Tester / pubproject1
15 | Strider Tester / privproject1
16 |
17 | */
18 |
19 | const nock = require('nock');
20 |
21 | module.exports = function() {
22 |
23 | //--------------------------------------------------------------------------------------
24 | //Simulate a good response that sends the three correct repos
25 | nock('http://localhost:80')
26 | .get('/api/v3/projects')
27 | .query({"private_token": "zRtVsmeznn7ySatTrnrp", "per_page": "100"})
28 | .reply(200, ["1f8b0800000000000003e5966d6f9b3010c7bf8ac5eb94e7474bd5f61dd657eb2ae4c0257823c06c03aaaa7ef79d816421340fd52655daa4248ace77e7f3df773f787c31786ed06865e42033c11bc5ebcaa0c643c125c10f238da8bf43a6c88ef14ae11772b27e26aa00f245099e83200f20150849da4ac7ea4c1bd6962a5d0b56650526db31ed802b8a6dd3924b65d0c7a795d1b4eb926706ddb052c2ca60222b780758cd64e8b8e46b5e72f59c96d04169507b654859a4ad285355a7029a1ab36fb9fa5cd539745461214311d6f03b55ee98e8819b174a3527a1da442d6b88b62e47f7b0d6c1b8df2d41b85dc57680deb34a2673da7355a4da41362cd35e87bd8935cab8af1d231aa6b488a789b4f942a2b90498864bd9824ca162eb528bac448ba2ef406c0195fc896b6ab1daf31ffc344256bc69e0d877baae4c005390a70cafd7706d27b8b3e33b277eb043ea4634b04d3789bf6221257643ca32c53b7db36f7927d48f4cd775b5f790b516a9ee52675475126dec5cefa0f441c3df9a1d9beabe82314dd596e594f8ed72b1e2c035c3c8d105b44d7eee5833bf73f3a36b205b51b70dd9d48234503725106de5d596c871864cdc88754c3161d01763e8335de5ebebde3cf6de605b8d070f2f8cec3058fbc9c5d4ef9dc8b1376e1848f7ca444ec7d3a70561e1c0bf7326afc59f99cab361a8c5d0075ae56940e714d3172e414c6bb33cb8a49b101b4e2aec086cf2a189e17075733ef47d6f6ec578a96656efacf1afe56db0b1208f43c8bddcc57f5ee8db59c46c275cdb49127d92f7befdadb56d37ccef91af95e21962153b612aea4845dc5a1b9718981f0aa1320f9a90b2342e335d92f24391e2533f3093f846a404d4f34ddf1f26fa1829133e6648f10f529fdeffa4dba9f9375a30dd050c3a36f502d38fbd2b5c99f9cdb972c48911061336967c08167cd020da3fcd1d4d9cf762e1af3da84f9a4af0eecfb8b04c701b188ee2fe0932cccf732b1ae6517b362cad57e1300ff9483a381e0d123372c22b2f1caeab5f4f8298baaee925d17f4087a75f735e9d4af20b0000"], {
29 | server: 'nginx',
30 | date: 'Sat, 22 Aug 2015 08:21:19 GMT',
31 | 'content-type': 'application/json',
32 | 'transfer-encoding': 'chunked',
33 | connection: 'close',
34 | status: '200 OK',
35 | link: '; rel="first", ; rel="last"',
36 | etag: 'W/"4568d3770abe645a4a67a538d64ae3d3"',
37 | 'cache-control': 'max-age=0, private, must-revalidate',
38 | 'x-request-id': '1f82c7d6-2948-487a-bbcd-9e2a485b4fb0',
39 | 'x-runtime': '0.089518',
40 | 'content-encoding': 'gzip'
41 | });
42 |
43 | nock('http://localhost:80')
44 | .get('/api/v3/projects')
45 | .query({"private_token": "zRtVsmeznn7ySatTrnrp", "per_page": "100", "page": "1"})
46 | .reply(200, ["1f8b0800000000000003e5966d6f9b3010c7bf8ac5eb94e7474bd5f61dd657eb2ae4c0257823c06c03aaaa7ef79d816421340fd52655daa4248ace77e7f3df773f787c31786ed06865e42033c11bc5ebcaa0c643c125c10f238da8bf43a6c88ef14ae11772b27e26aa00f245099e83200f20150849da4ac7ea4c1bd6962a5d0b56650526db31ed802b8a6dd3924b65d0c7a795d1b4eb926706ddb052c2ca60222b780758cd64e8b8e46b5e72f59c96d04169507b654859a4ad285355a7029a1ab36fb9fa5cd539745461214311d6f03b55ee98e8819b174a3527a1da442d6b88b62e47f7b0d6c1b8df2d41b85dc57680deb34a2673da7355a4da41362cd35e87bd8935cab8af1d231aa6b488a789b4f942a2b90498864bd9824ca162eb528bac448ba2ef406c0195fc896b6ab1daf31ffc344256bc69e0d877baae4c005390a70cafd7706d27b8b3e33b277eb043ea4634b04d3789bf6221257643ca32c53b7db36f7927d48f4cd775b5f790b516a9ee52675475126dec5cefa0f441c3df9a1d9beabe82314dd596e594f8ed72b1e2c035c3c8d105b44d7eee5833bf73f3a36b205b51b70dd9d48234503725106de5d596c871864cdc88754c3161d01763e8335de5ebebde3cf6de605b8d070f2f8cec3058fbc9c5d4ef9dc8b1376e1848f7ca444ec7d3a70561e1c0bf7326afc59f99cab361a8c5d0075ae56940e714d3172e414c6bb33cb8a49b101b4e2aec086cf2a189e17075733ef47d6f6ec578a96656efacf1afe56db0b1208f43c8bddcc57f5ee8db59c46c275cdb49127d92f7befdadb56d37ccef91af95e21962153b612aea4845dc5a1b9718981f0aa1320f9a90b2342e335d92f24391e2533f3093f846a404d4f34ddf1f26fa1829133e6648f10f529fdeffa4dba9f9375a30dd050c3a36f502d38fbd2b5c99f9cdb972c48911061336967c08167cd020da3fcd1d4d9cf762e1af3da84f9a4af0eecfb8b04c701b188ee2fe0932cccf732b1ae6517b362cad57e1300ff9483a381e0d123372c22b2f1caeab5f4f8298baaee925d17f4087a75f735e9d4af20b0000"], {
47 | server: 'nginx',
48 | date: 'Sat, 22 Aug 2015 08:21:19 GMT',
49 | 'content-type': 'application/json',
50 | 'transfer-encoding': 'chunked',
51 | connection: 'close',
52 | status: '200 OK',
53 | link: '; rel="first", ; rel="last"',
54 | etag: 'W/"4568d3770abe645a4a67a538d64ae3d3"',
55 | 'cache-control': 'max-age=0, private, must-revalidate',
56 | 'x-request-id': '1f82c7d6-2948-487a-bbcd-9e2a485b4fb0',
57 | 'x-runtime': '0.089518',
58 | 'content-encoding': 'gzip'
59 | });
60 |
61 | //--------------------------------------------------------------------------------------
62 | //Simulate a 401 on bad credentials being sent
63 | nock('http://localhost:80')
64 | .get('/api/v3/projects')
65 | .query({"private_token": "badkey", "per_page": "100"})
66 | .reply(401, {"message": "401 Unauthorized"}, {
67 | server: 'nginx',
68 | date: 'Sat, 22 Aug 2015 08:32:44 GMT',
69 | 'content-type': 'application/json',
70 | 'content-length': '30',
71 | connection: 'close',
72 | status: '401 Unauthorized',
73 | 'cache-control': 'no-cache',
74 | 'x-request-id': '82e3262d-3a37-4a00-93c0-116b1886faf2',
75 | 'x-runtime': '0.004822'
76 | });
77 | };
78 |
--------------------------------------------------------------------------------
/test/mocks/gitlab_webapp_setuprepo.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Here we simulate the response of the server when asked
5 | to setup the repo for privproject1
6 |
7 | nock will simulate a gitlab server running at
8 | localhost:80, where Strider Tester, a user is
9 | registered with the name "stridertester", and
10 | has been registered with api token - zRtVsmeznn7ySatTrnrp
11 | stridertester is an "owner" of a group named "testunion"
12 | and has admin access to three projects -
13 | testunion / unionproject1
14 | Strider Tester / pubproject1
15 | Strider Tester / privproject1
16 |
17 | */
18 |
19 | const nock = require('nock');
20 |
21 | module.exports = function() {
22 |
23 | //--------------------------------------------------------------------------------------
24 | //Simulate good response that are sent when the repo is set up correctly
25 |
26 | nock('http://localhost:80')
27 | .post('/api/v3/projects/5/hooks', {
28 | "url": "http://localhost:3000/stridertester/privproject1/api/gitlab/webhook",
29 | "push_events": true
30 | })
31 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
32 | .reply(201, {
33 | "id": 23,
34 | "url": "http://localhost:3000/stridertester/privproject1/api/gitlab/webhook",
35 | "created_at": "2015-08-22T08:55:50.345Z",
36 | "project_id": 5,
37 | "push_events": true,
38 | "issues_events": false,
39 | "merge_requests_events": false,
40 | "tag_push_events": false
41 | }, {
42 | server: 'nginx',
43 | date: 'Sat, 22 Aug 2015 08:55:50 GMT',
44 | 'content-type': 'application/json',
45 | 'content-length': '235',
46 | connection: 'close',
47 | status: '201 Created',
48 | etag: '"3e1074f02f37c23c355cd1a33eecfb4b"',
49 | 'cache-control': 'max-age=0, private, must-revalidate',
50 | 'x-request-id': '3ccf26db-b72c-4b62-9b7b-42b307a85381',
51 | 'x-runtime': '0.031542'
52 | });
53 |
54 |
55 | nock('http://localhost:80')
56 | .post('/api/v3/projects/5/deploy_keys', {
57 | "title": "strider-stridertester/privproject1",
58 | "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1j1c3wNyUwFzIhU5ELZb6tH1K+TkQgV0CrYjRvWmeZZr5aNKehSo5ntCoPtjZOddD2qYOUNyqe0EkdsSa7JeuD0blk5T9V8EADxqSmfYE8qD3Ch1JN0T4gbxoH20N45gqfpzug04FNwaDvCoxJgKvJXNj141SRLVVsa3DlByqC1Il+6TS7LqsQQMnSahgdx6fOUSLzSRG5NmbHGnS4CA1W4zyqQKzznh/Qj9WLxQKxugly3PPWtlcCDoaFBBQSOIgGVs00Bd3X8DJW/3gNPfydtUAdm/BcDZHOLyBUNOQCjR/fGyLS8D4ufYt6vr72No9O0dyKyI+FpOb+jPDG631 stridertester/privproject1-stridertester@gmail.com\n"
59 | })
60 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
61 | .reply(201, {
62 | "id": 24,
63 | "title": "strider-stridertester/privproject1",
64 | "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1j1c3wNyUwFzIhU5ELZb6tH1K+TkQgV0CrYjRvWmeZZr5aNKehSo5ntCoPtjZOddD2qYOUNyqe0EkdsSa7JeuD0blk5T9V8EADxqSmfYE8qD3Ch1JN0T4gbxoH20N45gqfpzug04FNwaDvCoxJgKvJXNj141SRLVVsa3DlByqC1Il+6TS7LqsQQMnSahgdx6fOUSLzSRG5NmbHGnS4CA1W4zyqQKzznh/Qj9WLxQKxugly3PPWtlcCDoaFBBQSOIgGVs00Bd3X8DJW/3gNPfydtUAdm/BcDZHOLyBUNOQCjR/fGyLS8D4ufYt6vr72No9O0dyKyI+FpOb+jPDG631 stridertester/privproject1-stridertester@gmail.com",
65 | "created_at": "2015-08-22T08:55:50.403Z"
66 | }, {
67 | server: 'nginx',
68 | date: 'Sat, 22 Aug 2015 08:55:50 GMT',
69 | 'content-type': 'application/json',
70 | 'content-length': '534',
71 | connection: 'close',
72 | status: '201 Created',
73 | etag: '"f5843bd3736577d1059f9390612e8f81"',
74 | 'cache-control': 'max-age=0, private, must-revalidate',
75 | 'x-request-id': '667866c3-47bb-408c-9569-f049ab7a21e6',
76 | 'x-runtime': '0.103697'
77 | });
78 |
79 | //--------------------------------------------------------------------------------------
80 | //Simulate 401 unauthorized responses on sending incorrect api key
81 |
82 | nock('http://localhost:80')
83 | .post('/api/v3/projects/5/hooks', {
84 | "url": "http://localhost:3000/stridertester/privproject1/api/gitlab/webhook",
85 | "push_events": true
86 | })
87 | .query({"private_token": "badkey"})
88 | .reply(401, {"message": "401 Unauthorized"}, {
89 | server: 'nginx',
90 | date: 'Sat, 22 Aug 2015 09:47:00 GMT',
91 | 'content-type': 'application/json',
92 | 'content-length': '30',
93 | connection: 'close',
94 | status: '401 Unauthorized',
95 | 'cache-control': 'no-cache',
96 | 'x-request-id': 'f31bd5f2-36cf-4cd6-9199-7ca70831da4d',
97 | 'x-runtime': '0.004801'
98 | });
99 |
100 | nock('http://localhost:80')
101 | .post('/api/v3/projects/5/deploy_keys', {
102 | "title": "strider-stridertester/privproject1",
103 | "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1j1c3wNyUwFzIhU5ELZb6tH1K+TkQgV0CrYjRvWmeZZr5aNKehSo5ntCoPtjZOddD2qYOUNyqe0EkdsSa7JeuD0blk5T9V8EADxqSmfYE8qD3Ch1JN0T4gbxoH20N45gqfpzug04FNwaDvCoxJgKvJXNj141SRLVVsa3DlByqC1Il+6TS7LqsQQMnSahgdx6fOUSLzSRG5NmbHGnS4CA1W4zyqQKzznh/Qj9WLxQKxugly3PPWtlcCDoaFBBQSOIgGVs00Bd3X8DJW/3gNPfydtUAdm/BcDZHOLyBUNOQCjR/fGyLS8D4ufYt6vr72No9O0dyKyI+FpOb+jPDG631 stridertester/privproject1-stridertester@gmail.com\n"
104 | })
105 | .query({"private_token": "badkey"})
106 | .reply(401, {"message": "401 Unauthorized"}, {
107 | server: 'nginx',
108 | date: 'Sat, 22 Aug 2015 09:47:00 GMT',
109 | 'content-type': 'application/json',
110 | 'content-length': '30',
111 | connection: 'close',
112 | status: '401 Unauthorized',
113 | 'cache-control': 'no-cache',
114 | 'x-request-id': '000fffa7-8aa6-46ed-a34a-7689f88d331f',
115 | 'x-runtime': '0.006122'
116 | });
117 |
118 | //--------------------------------------------------------------------------------------
119 | //Simulate 404 when invalid repo is specified
120 | nock('http://localhost:80')
121 | .post('/api/v3/projects/invalidrepo/hooks', {
122 | "url": "http://localhost:3000/stridertester/privproject1/api/gitlab/webhook",
123 | "push_events": true
124 | })
125 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
126 | .reply(404, ["1f8b0800000000000003ab56ca4d2d2e4e4c4f55b252323130510828cacf4a4d2e51f0cb2f5170cb2fcd4b51aa050037095a2823000000"], {
127 | server: 'nginx',
128 | date: 'Sat, 22 Aug 2015 11:29:30 GMT',
129 | 'content-type': 'application/json',
130 | 'transfer-encoding': 'chunked',
131 | connection: 'close',
132 | status: '404 Not Found',
133 | 'cache-control': 'no-cache',
134 | 'x-request-id': '9d44eb7e-8a4d-4714-bd0a-5b4de958ed24',
135 | 'x-runtime': '0.005929',
136 | 'content-encoding': 'gzip'
137 | });
138 |
139 |
140 | nock('http://localhost:80')
141 | .post('/api/v3/projects/invalidrepo/deploy_keys', {
142 | "title": "strider-stridertester/privproject1",
143 | "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1j1c3wNyUwFzIhU5ELZb6tH1K+TkQgV0CrYjRvWmeZZr5aNKehSo5ntCoPtjZOddD2qYOUNyqe0EkdsSa7JeuD0blk5T9V8EADxqSmfYE8qD3Ch1JN0T4gbxoH20N45gqfpzug04FNwaDvCoxJgKvJXNj141SRLVVsa3DlByqC1Il+6TS7LqsQQMnSahgdx6fOUSLzSRG5NmbHGnS4CA1W4zyqQKzznh/Qj9WLxQKxugly3PPWtlcCDoaFBBQSOIgGVs00Bd3X8DJW/3gNPfydtUAdm/BcDZHOLyBUNOQCjR/fGyLS8D4ufYt6vr72No9O0dyKyI+FpOb+jPDG631 stridertester/privproject1-stridertester@gmail.com\n"
144 | })
145 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
146 | .reply(404, ["1f8b0800000000000003ab56ca4d2d2e4e4c4f55b252323130510828cacf4a4d2e51f0cb2f5170cb2fcd4b51aa050037095a2823000000"], {
147 | server: 'nginx',
148 | date: 'Sat, 22 Aug 2015 11:29:30 GMT',
149 | 'content-type': 'application/json',
150 | 'transfer-encoding': 'chunked',
151 | connection: 'close',
152 | status: '404 Not Found',
153 | 'cache-control': 'no-cache',
154 | 'x-request-id': 'f78f974c-207b-4d85-b42a-3c38dea668e7',
155 | 'x-runtime': '0.006760',
156 | 'content-encoding': 'gzip'
157 | });
158 |
159 |
160 | //--------------------------------------------------------------------------------------
161 | //Simulate a situation where an invalid ssh key is provided
162 | //the hook ends up getting created, but we get a 400 Bad Request when trying to add the key
163 | nock('http://localhost:80')
164 | .post('/api/v3/projects/5/hooks', {
165 | "url": "http://localhost:3000/stridertester/privproject1/api/gitlab/webhook",
166 | "push_events": true
167 | })
168 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
169 | .reply(201, {
170 | "id": 27,
171 | "url": "http://localhost:3000/stridertester/privproject1/api/gitlab/webhook",
172 | "created_at": "2015-08-22T11:31:48.159Z",
173 | "project_id": 5,
174 | "push_events": true,
175 | "issues_events": false,
176 | "merge_requests_events": false,
177 | "tag_push_events": false
178 | }, {
179 | server: 'nginx',
180 | date: 'Sat, 22 Aug 2015 11:31:48 GMT',
181 | 'content-type': 'application/json',
182 | 'content-length': '235',
183 | connection: 'close',
184 | status: '201 Created',
185 | etag: '"ae205f292720e19ab273c3bea2ba66b0"',
186 | 'cache-control': 'max-age=0, private, must-revalidate',
187 | 'x-request-id': '4562483b-5c3d-4f19-bf63-bb3968c39815',
188 | 'x-runtime': '0.023564'
189 | });
190 |
191 | nock('http://localhost:80')
192 | .post('/api/v3/projects/5/deploy_keys', {"title": "strider-stridertester/privproject1", "key": "invalid key"})
193 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
194 | .reply(400, {"message": {"key": ["is invalid"], "fingerprint": ["cannot be generated"]}}, {
195 | server: 'nginx',
196 | date: 'Sat, 22 Aug 2015 11:31:48 GMT',
197 | 'content-type': 'application/json',
198 | 'content-length': '72',
199 | connection: 'close',
200 | status: '400 Bad Request',
201 | 'cache-control': 'no-cache',
202 | 'x-request-id': 'be0ac084-2fae-4589-b4a7-13a65cc0f055',
203 | 'x-runtime': '0.074954'
204 | });
205 | };
206 |
--------------------------------------------------------------------------------
/test/mocks/gitlab_webapp_teardownrepos.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Here we simulate the response of the server when asked
5 | to tear down the repo for privproject1
6 |
7 | nock will simulate a gitlab server running at
8 | localhost:80, where Strider Tester, a user is
9 | registered with the name "stridertester", and
10 | has been registered with api token - zRtVsmeznn7ySatTrnrp
11 | stridertester is an "owner" of a group named "testunion"
12 | and has admin access to three projects -
13 | testunion / unionproject1
14 | Strider Tester / pubproject1
15 | Strider Tester / privproject1
16 |
17 | */
18 |
19 | const nock = require('nock');
20 |
21 | module.exports = function() {
22 |
23 | //--------------------------------------------------------------------------------------
24 | //Simulate good responses that are sent when the repo is torn down correctly
25 |
26 | //get the list of ssh keys
27 | nock('http://localhost:80')
28 | .get('/api/v3/projects/5/deploy_keys')
29 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
30 | .reply(200, ["1f8b080000000000000375d14b8fa2401405e0bfd2614bdb4d953c5d0dcf26a2342f5b743299005542c94ba1046132ff7d3499cd2ce66e4eeec9d97ddf7f3104312b28bf3294d00a332ba6a71d41b85bfc4d8a7b8abbf74b47864bd79e714601f3ca94787a4efb62d1f5c98bfa386de9ce890ea60c9acfd7507d557bd6aaafd7ad939243efb53c053a98871d6756e7b477e429908b6242a6531feffa1859cb61107bc9abc7234621f59325f24814f6b3a7de2732d159b69348637349fa5aebb91b39bb6b3542f409e5ecd816bc1d8c72a1d73011344d833a1902a7d95a8dc8d9c04a63bfea14f3e6a54225dd907f4ed61f87d2deab8622679b496a8da54da3681b833054aa3db89bb9e5df3c944690cab59e69bb2c9725cb364ba4909087065b8fe6d05e9c2bab3a87c22c21328c4d75312d716d5b6c5e9ea6c93fef02a4ab2d7f307a711b70db36d8eecf208958019fc8e912eedf95358d2d213646a7ac9bf2ab41d7d80199a8ba568c58d4229bf65699ba3cdb7d2e371f6aa301bc9edd61d41af7e5ff3effd27dcbeb84546f595b3fdcb20e2714a39f097df0410e080b4e5e401801b0e2c51514de38513932bf7ffc014101a3c118020000"], {
31 | server: 'nginx',
32 | date: 'Sat, 22 Aug 2015 11:47:06 GMT',
33 | 'content-type': 'application/json',
34 | 'transfer-encoding': 'chunked',
35 | connection: 'close',
36 | status: '200 OK',
37 | etag: 'W/"690cd0366b746f11420cf4cd41447505"',
38 | 'cache-control': 'max-age=0, private, must-revalidate',
39 | 'x-request-id': '61269e5f-cfc1-422e-b74f-eca5a5171203',
40 | 'x-runtime': '0.019441',
41 | 'content-encoding': 'gzip'
42 | });
43 |
44 | //get the list of hooks
45 | nock('http://localhost:80')
46 | .get('/api/v3/projects/5/hooks')
47 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
48 | .reply(200, ["1f8b0800000000000003658e4b0ec2300c44efe275216928bf9c83150845a1356d209062bbb040dc9d8010126239f3eca7d9dc21346027ba80812258e8447aab544cb58f5d62c9486bc542a141126441523d856b4fe980b594caf741b541a2dfa91beeba948e50404de8051be7252b8d2ea723bd1819b32a4b5bcdaca9c6cbb959e7bb8fc5bd364c731cb87378c5b33058a1010b08cc03f2b7dcfbc8b93d21b5e8082f99c91f15dfba1fd5fbebb17d0262c84f93ed000000"], {
49 | server: 'nginx',
50 | date: 'Sat, 22 Aug 2015 11:47:06 GMT',
51 | 'content-type': 'application/json',
52 | 'transfer-encoding': 'chunked',
53 | connection: 'close',
54 | status: '200 OK',
55 | link: '; rel="first", ; rel="last"',
56 | etag: 'W/"e7cde71ed4b2e2f010cc02aa14c300e5"',
57 | 'cache-control': 'max-age=0, private, must-revalidate',
58 | 'x-request-id': '27681ba4-9cea-4b26-8306-0ec64c76bfec',
59 | 'x-runtime': '0.022184',
60 | 'content-encoding': 'gzip'
61 | });
62 |
63 | //delete the key associated with the project
64 | nock('http://localhost:80')
65 | .delete('/api/v3/projects/5/deploy_keys/28')
66 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
67 | .reply(200, ["1f8b08000000000000038c52c976a24014fd951cb6c4842a9957cd188e286132a29b1ca04a40c64009627ebef1f4ca5dbfdd7d77d8dcfb4b158892a1f84a5d07dc7f3f4073adaa572aed714c30fa8e0925539001dc8a1157108600c82c2f43ee8de1a513b5d83af45fba12cf4bd030e4ab7e885f94e5d4b5738f3530a7d078405df114f5f1563cad6eeda4380e6ecb12a081fbb8678cea920cb638fb629ecfc8b0ebd34d9b42733d8efc20b8f574c228205ebc466e1106c3dd556e733193bb68c5a14a6782f0b5d13227b4f73fd504d12714d3539bb3963f89b956c3985355156ac5e8dbcdce6c78c602661279552f195737e12ae18abc4bbcf93896d641d12531ddce42abaf2d1286bb080481541dc0cdc84cefeaa2248444acb554dda7992898965122a90858a8d3f5648c6d67ffd08a7dcc8d12225ddf569d61f21bcba4b3f23ccfde65ef234d69d9a33ef03b9fd9b5feee7001714873f85c9cbbe0f02e6d486472913ed965dd945f0dfa896c90f28a634688462db2c8609689c3d2fde77afba1342ac09bbb334e6ae3bc0ca42f10ee091e08eedfbbbe18bbbebde09480d513f527abe3a27a4bdb7ae99714a4c28fe6fe999f954f218bf85c3419ee97e4e6b19a98971920f3922c2c83817f6795966265996c65666a95626165666c656a62659c6695960452936461659a08d45f509a949399ac64959698539c5a0b00837af5d39c020000"], {
68 | server: 'nginx',
69 | date: 'Sat, 22 Aug 2015 11:47:06 GMT',
70 | 'content-type': 'application/json',
71 | 'transfer-encoding': 'chunked',
72 | connection: 'close',
73 | status: '200 OK',
74 | etag: 'W/"b4902d64c484b3f0e011862ecaa556eb"',
75 | 'cache-control': 'max-age=0, private, must-revalidate',
76 | 'x-request-id': '3e5e9625-a43c-4f32-a6a5-477e05b0ed3b',
77 | 'x-runtime': '0.023933',
78 | 'content-encoding': 'gzip'
79 | });
80 |
81 | //delete the hook associated with the project
82 | nock('http://localhost:80')
83 | .delete('/api/v3/projects/5/hooks/30')
84 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
85 | .reply(200, ["1f8b08000000000000038d8dcd6ec2301084df65cf013be6aff573f4c4c532c93671ebc666771d0e8877c720540971e13adfcc3767083dd8956ea050040ba348b64ac5d4f93826968ab4562c147a244116249529cc99d20f76d22a9f831a82447f50273c8c29fd42030fea6eee4d031da117ec9d97fa6074bb59e88f85315f6d6bd75b6bd6cbcf9dd9d759c9fd5b3d469a438777fd5462ac87854787334ec260850a3610980bf27ff8ed23d7f40f69404778ac4c5ea8f8c13da91eab29093e9b2e57ff64dcac39010000"], {
86 | server: 'nginx',
87 | date: 'Sat, 22 Aug 2015 11:47:06 GMT',
88 | 'content-type': 'application/json',
89 | 'transfer-encoding': 'chunked',
90 | connection: 'close',
91 | status: '200 OK',
92 | etag: 'W/"cf8c92b71d0b72f1e754948cc93b78f1"',
93 | 'cache-control': 'max-age=0, private, must-revalidate',
94 | 'x-request-id': '55957387-e9bb-4b80-8172-2990bffbf2e0',
95 | 'x-runtime': '0.024064',
96 | 'content-encoding': 'gzip'
97 | });
98 |
99 | //--------------------------------------------------------------------------------------
100 | //Simulate 401 Unauthorized responses when invalid credentials are supplied
101 |
102 | nock('http://localhost:80')
103 | .get('/api/v3/projects/5/hooks')
104 | .query({"private_token": "badkey"})
105 | .reply(401, {"message": "401 Unauthorized"}, {
106 | server: 'nginx',
107 | date: 'Sat, 22 Aug 2015 11:57:57 GMT',
108 | 'content-type': 'application/json',
109 | 'content-length': '30',
110 | connection: 'close',
111 | status: '401 Unauthorized',
112 | 'cache-control': 'no-cache',
113 | 'x-request-id': '8a4a34a5-f522-4f13-b7a5-534505e0a9c4',
114 | 'x-runtime': '0.004208'
115 | });
116 |
117 |
118 | nock('http://localhost:80')
119 | .get('/api/v3/projects/5/deploy_keys')
120 | .query({"private_token": "badkey"})
121 | .reply(401, {"message": "401 Unauthorized"}, {
122 | server: 'nginx',
123 | date: 'Sat, 22 Aug 2015 11:57:57 GMT',
124 | 'content-type': 'application/json',
125 | 'content-length': '30',
126 | connection: 'close',
127 | status: '401 Unauthorized',
128 | 'cache-control': 'no-cache',
129 | 'x-request-id': '1ebb7394-25f2-4279-abce-ea4845d458d5',
130 | 'x-runtime': '0.006446'
131 | });
132 |
133 | //--------------------------------------------------------------------------------------
134 | //Simulate a 404 when an invalid repo id is passed
135 | nock('http://localhost:80')
136 | .get('/api/v3/projects/invalidrepo/hooks')
137 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
138 | .reply(404, ["1f8b0800000000000003ab56ca4d2d2e4e4c4f55b252323130510828cacf4a4d2e51f0cb2f5170cb2fcd4b51aa050037095a2823000000"], {
139 | server: 'nginx',
140 | date: 'Sat, 22 Aug 2015 12:02:54 GMT',
141 | 'content-type': 'application/json',
142 | 'transfer-encoding': 'chunked',
143 | connection: 'close',
144 | status: '404 Not Found',
145 | 'cache-control': 'no-cache',
146 | 'x-request-id': '3af42422-6659-4deb-a356-857cc209dbe9',
147 | 'x-runtime': '0.005849',
148 | 'content-encoding': 'gzip'
149 | });
150 |
151 |
152 | nock('http://localhost:80')
153 | .get('/api/v3/projects/invalidrepo/deploy_keys')
154 | .query({"private_token": "zRtVsmeznn7ySatTrnrp"})
155 | .reply(404, ["1f8b0800000000000003ab56ca4d2d2e4e4c4f55b252323130510828cacf4a4d2e51f0cb2f5170cb2fcd4b51aa050037095a2823000000"], {
156 | server: 'nginx',
157 | date: 'Sat, 22 Aug 2015 12:02:54 GMT',
158 | 'content-type': 'application/json',
159 | 'transfer-encoding': 'chunked',
160 | connection: 'close',
161 | status: '404 Not Found',
162 | 'cache-control': 'no-cache',
163 | 'x-request-id': '6a09637f-d80f-404b-a11c-80677a62a979',
164 | 'x-runtime': '0.006442',
165 | 'content-encoding': 'gzip'
166 | });
167 | };
168 |
--------------------------------------------------------------------------------
/test/mocks/receive_webhooks_req.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | //This is a mock for a request passed in to the receiveWebhooks function
4 | //It contains the payload received from the gitlab server in
5 | //body and project information from strider
6 |
7 | module.exports = {
8 | body: {
9 | object_kind: 'push',
10 | before: 'e85d185fdd17ebb379495f5ec14426134ce02837',
11 | after: '6a00c57e69bd4e269496ca27973191ecafcf8b20',
12 | ref: 'refs/heads/master',
13 | checkout_sha: '6a00c57e69bd4e269496ca27973191ecafcf8b20',
14 | message: null,
15 | user_id: 3,
16 | user_name: 'Strider Tester',
17 | user_email: 'stridertester@gmail.com',
18 | project_id: 5,
19 | repository: {
20 | name: 'privproject1',
21 | url: 'git@nodev:stridertester/privproject1.git',
22 | description: 'Test project 1.',
23 | homepage: 'http://nodev/stridertester/privproject1',
24 | git_http_url: 'http://nodev/stridertester/privproject1.git',
25 | git_ssh_url: 'git@nodev:stridertester/privproject1.git',
26 | visibility_level: 0
27 | },
28 | commits: [{
29 | id: '6a00c57e69bd4e269496ca27973191ecafcf8b20',
30 | message: 'testing webhook receiving\n',
31 | timestamp: '2015-08-26T21:25:22+09:00',
32 | url: 'http://nodev/stridertester/privproject1/commit/6a00c57e69bd4e269496ca27973191ecafcf8b20',
33 | author: {name: 'Strider Tester', email: 'stridertester@gmail.com'}
34 | }],
35 | total_commits_count: 1
36 | }
37 | ,
38 | project: {
39 | name: "stridertester/privproject1",
40 | creator: {
41 | _id: "55d2ecb5edb0d634165eac37"
42 | },
43 | branch: function(branchname) {
44 | //mocked to only return the master branch
45 | return {
46 | name: 'master',
47 | pubkey: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWHmPMdv+QDoR/vaPcu4yk/sn23B4wNQe3bGTtrIUjMj/7Ih3gy7XWGDUxCpVjTgq3LOfIK3Uu9cnHHV8KUQF7edF16MBMvZT2IsDgErXMEeWLYL7Or7yi6Oa9JGYSSxJXoKh8tMSqFooXFnppK9MtKCuuj2F537s9v/0fbL9WdIja5xMX0tDm7jGCSzMJhG7WYdzJ+GoX7Y9w+6JuWwTHIFavX8xVxJ59InxQ+GiHszibRcgnDUam3/QG9v/z9aeLNB7tngXX8NaszwAj1OA1sZnotmGrO0byH2zhcG7QPWYJkk94ZAz9TZMzEOqGze0Guh/A8VZOPRZjaWKKhx6B stridertester/privproject1-stridertester@gmail.com\n',
48 | privkey: '-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEA1h5jzHb/kA6Ef72j3LuMpP7J9tweMDUHt2xk7ayFIzI/+yId\n4Mu11hg1MQqVY04KtyznyCt1LvXJxx1fClEBe3nRdejATL2U9iLA4BK1zBHli2C+\nzq+8oujmvSRmEksSV6CofLTEqhaKFxZ6aSvTLSgrro9hed+7Pb/9H2y/VnSI2ucT\nF9LQ5u4xgkszCYRu1mHcyfhqF+2PcPuiblsExyBWr1/MVcSefSJ8UPhoh7M4m0XI\nJw1Gpt/0Bvb/8/WnizQe7Z4F1/DWrM8AI9TgNbGZ6LZhqztG8h9s4XBu0D1mCZJP\neGQM/U2TMxDqhs3tBrofwPFWTj0WY2liiocegQIDAQABAoIBAE4yHwRG2SJFCwKT\nwUoVfFGtcxiiXqwAUeccwOdDwAOQkGkolnzIKIodoR9d3By+HY+z6JnjtRIHVT9Q\nbKsZ1k6/uE01STU9by9Mld+/NYFnb8ss88ILz/o20D13E4fOvs4dsCqK4d+0B45S\n+TV7ec3eA8XmOxUFLh5pBQn67w2lKmmslmQVdHovPifQLDrRLnmJs5WdS5FYFgGj\nVY4N1unyJ1a42YpcxDQgYYJilCrWtQ58L5FY2zE87y9p3uljxnBiFULuWdPIlWMq\nJ0cjp6IWlkl1lR7zfAIGK989VgNchcStZGRz3yGMnQYT7S20zEWX4MBkmQYUrbVf\nZ4xd9KECgYEA7JOJB1TEhRJPXPFW6uIWxz0INSHoDp4ue7TGvGhWouC7o7Ed+cdc\nbZL+Naqf34ZB9ZpPFxI9t2CDc3Xzb9jRlAja/kVAksojaJCXMqDuDtaCeUjpD5hh\ndQq3ZDF/B5aC67/1fOm++rv/ZusQt8yeo/RRYJSajb9AR5N9n8sHLnUCgYEA57LU\ntSNNAxRkucAkTooo0oEGg1GLae4JsyyFxQAkCE/YZUmZKfOhpPUhiqst9XhaI08o\n++/9hpE2DlQe2xfsvIxgIGlZDlEZCfRu9+sM0s7OWGSh+U/VXDAowczJwAnN48Js\nUKTuwBgQYuNXKk19y37omqHq0sxScWRe4izyhl0CgYAH0o0KYAQrfkJ/iT9dfuJP\n7jWyRA+/Q/23e2/C1RRgSFwL+pRKKQxmVyDut1iX9IGD1HlfAuxlftx52eGVxi6P\n3YcYN0P+Vo67K2TEeMvGU9N2nTGPoXM/gn4z4usXXiOwFeXRHo2BDuxQA9/GpA5u\nz2pNbjx6CWPfugHCYd037QKBgE3MuKvSHKvqDyBoKkjND4QPmxZBLWT2bv9g9dH+\niBraZLkuC2YQzrhLL2YWsKn6LZopnINsRF8JJ3OMP4gl8nIlWKnJdgPeq1+yWgiZ\nPocStirsL489hVEdQrJAh4YaRK4zvJcfqqOJ8Qaje8NSnejUxloWAHmj7hLxNwMP\nQKhpAoGAEt5A8mlohNoJAEJyoO0dH2m2oyBhxSGOhNdwE0GPMdOeDlLhkkn0JB+8\n+y9j+jCpjEpOfHkPZ7gVOkWgZUZwhbzYkDmfy8OXFuVUtUtDHvF7MoHGCXBsVpCq\nCuBauEVw5orSfYJXFwoFYwLbiXSVBdNVvNMsC6bDwi1J701SsOU=\n-----END RSA PRIVATE KEY-----\n',
49 | _id: "55dac66a7946e3a309c92f68",
50 | runner: {id: 'simple-runner', config: {pty: false}},
51 | plugins: [{
52 | id: 'node',
53 | enabled: true,
54 | config: {},
55 | _id: "55dac66a7946e3a309c92f69",
56 | showStatus: true
57 | }],
58 | deploy_on_green: true,
59 | mirror_master: false,
60 | active: true
61 | }
62 | }
63 | }
64 | };
65 |
--------------------------------------------------------------------------------
/test/mocks/sample_payload.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | object_kind: 'push',
5 | before: '9be0948373aedbbed7ac6ce1da708061fac072d7',
6 | after: '352e6fe2ea42d394a21dc7995df2116e86bb0684',
7 | ref: 'refs/heads/master',
8 | checkout_sha: '352e6fe2ea42d394a21dc7995df2116e86bb0684',
9 | message: null,
10 | user_id: 3,
11 | user_name: 'Strider Tester',
12 | user_email: 'stridertester@gmail.com',
13 | project_id: 5,
14 | repository: {
15 | name: 'privproject1',
16 | url: 'git@nodev:stridertester/privproject1.git',
17 | description: 'Test project 1.',
18 | homepage: 'http://nodev/stridertester/privproject1',
19 | git_http_url: 'http://nodev/stridertester/privproject1.git',
20 | git_ssh_url: 'git@nodev:stridertester/privproject1.git',
21 | visibility_level: 0
22 | },
23 | commits: [{
24 | id: '378105b72465107d6ca8e6c70d88cb9b9b7fcbac',
25 | message: 'first commit\n',
26 | timestamp: '2015-08-26T20:01:10+09:00',
27 | url: 'http://nodev/stridertester/privproject1/commit/378105b72465107d6ca8e6c70d88cb9b9b7fcbac',
28 | author: {name: 'Strider Tester', email: 'stridertester@gmail.com'}
29 | },
30 | {
31 | id: '352e6fe2ea42d394a21dc7995df2116e86bb0684',
32 | message: 'updated strider.json\n',
33 | timestamp: '2015-08-26T20:02:07+09:00',
34 | url: 'http://nodev/stridertester/privproject1/commit/352e6fe2ea42d394a21dc7995df2116e86bb0684',
35 | author: {name: 'Strider Tester', email: 'stridertester@gmail.com'}
36 | }],
37 | total_commits_count: 2
38 | };
39 |
--------------------------------------------------------------------------------
/test/mocks/sample_payload_tag_push_with_v7.x.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | ref: 'refs/tags/tag-1.1.2',
5 | before: '9be0948373aedbbed7ac6ce1da708061fac072d7',
6 | after: '352e6fe2ea42d394a21dc7995df2116e86bb0684',
7 | user_id: 3,
8 | user_name: 'Strider Tester',
9 | project_id: 1,
10 | repository: {
11 | name: 'privproject1',
12 | url: 'git@nodev:stridertester/privproject1.git',
13 | description: 'Test project 1.',
14 | homepage: 'http://nodev/stridertester/privproject1'
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/test/test_api.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 |
5 | Used to test the gitlab API wrapper
6 |
7 | nock will simulate a gitlab server running at
8 | localhost:80, where Strider Tester, a user is
9 | registered with the name "stridertester", and
10 | has been registered with api token - zRtVsmeznn7ySatTrnrp
11 | stridertester is an "owner" of a group named "testunion"
12 | and has admin access to three projects -
13 | testunion / unionproject1
14 | Strider Tester / pubproject1
15 | Strider Tester / privproject1
16 | */
17 |
18 |
19 | const expect = require('expect.js');
20 | const api = require('../lib/api');
21 | let util = require('util');
22 | let debug = require('debug')('strider-gitlab:test:api');
23 | const nock = require('nock');
24 |
25 | const correctConfig = {
26 | api_key: 'zRtVsmeznn7ySatTrnrp',
27 | api_url: 'http://localhost:80/api/v3'
28 | };
29 |
30 | const wrongCredentialsConfig = {
31 | api_key: 'zRtVsmeznn7ySatTrnra',
32 | api_url: 'http://localhost:80/api/v3'
33 | };
34 |
35 | const invalidServerNameConfig = {
36 | api_key: 'zRtVsmeznn7ySatTrnrp',
37 | api_url: 'http://localghost:80/api/v3'
38 | };
39 |
40 | const configWithoutApiUrl = {api_key: 'zRtVsmeznn7ySatTrnrp'};
41 |
42 | const configWithoutApiKey = {
43 | api_url: 'http://localhost:80/api/v3'
44 | };
45 |
46 | const correctDeployKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAMoSHhKfeE3/oXanAQEZO0Sq20SMjvjmJlTy+CaGz/1uk+glLXi9u2RKtfPRZDceAgyEtRUpqya9Uo1v9bjkIckGLhQwXdSo2G6O3QuzpE3gc6AXTDPQ0ZkkXbSdU9VGL1Zzr+maBnvfwK6IlsNz3fLa4lNV7vz1LaGCg9D1jP+nufZjuDiCAno7D607oG1iHQ3x/BqzphUATav3DFQFT2FBmmittQT0l0mMJ4XsQCQXkwNbDjkLYNon8FYPm9U3AOlzicOGteebt5mhsQtfl9+lL99B8+fk8b24pEEbOxZ4l0HcwMI1R5OLoTzPwSvVw+bp3YPhH2IzfFwK5NUk7 stridertester/privproject1-stridertester@gmail.com\n";
47 |
48 | describe('gitlab api', function() {
49 | before('Setup the mock gitlab server', function setupNock() {
50 | nock.cleanAll();
51 | require('./mocks/gitlab_get.js')();
52 | require('./mocks/gitlab_add_key.js')();
53 | });
54 |
55 | after('Tear down mock Gitlab server', function tearDownNock() {
56 | nock.cleanAll();
57 | });
58 |
59 | //--------------------------------------------------------------------------------------
60 | describe('get', function() {
61 | it('should get a list of projects', function(done) {
62 | api.get(correctConfig, 'projects', function(err, body, res) {
63 | expect(err).to.not.be.ok();
64 | expect(body).to.be.an(Array);
65 | done();
66 | });
67 | });
68 |
69 | it('should return an error if a non existent path is asked for', function(done) {
70 |
71 | const wrongPath = 'nonexistentpath';
72 |
73 | api.get(correctConfig, wrongPath, function(err, body, res) {
74 | expect(err).to.be.ok();
75 | expect(err).to.be.an(Error);
76 | expect(err.status).to.eql('404');
77 | done();
78 | });
79 | });
80 |
81 | it('should return a 401 error if incorrect credentials are specified', function(done) {
82 | api.get(wrongCredentialsConfig, 'projects', function(err, body, res) {
83 | expect(err).to.be.ok();
84 | expect(err).to.be.an(Error);
85 | expect(err.status).to.eql('401');
86 | done();
87 | });
88 | });
89 |
90 | it('should return an error if the specified gitlab server IP cannot be resolved from the name', function(done) {
91 | api.get(invalidServerNameConfig, 'projects', function(err, body, res) {
92 | expect(err).to.be.ok();
93 | expect(err).to.be.an(Error);
94 | done();
95 | });
96 | });
97 |
98 | it('should return an error if the config passed in to it does not have a Gitlab API url', function(done) {
99 | const config = {api_key: 'zRtVsmeznn7ySatTrnrp'};
100 | api.get(config, 'projects', function(err, body, res) {
101 | expect(err).to.be.ok();
102 | expect(err).to.be.an(Error);
103 | done();
104 | });
105 | });
106 |
107 | it('should invoke our callback with the first parameter as undefined if the Gitlab server responds with a falsy value for res.body');
108 | });
109 |
110 | //--------------------------------------------------------------------------------------
111 | describe('parseRepo', function() {
112 | it('should correctly parse repo information as received from gitlab server into a repo object');
113 | it('should throw an error if it gets an empty parameter as repo ?');
114 | it('should throw an error if repo.id is absent ?');
115 | it('should throw an error if repo.path_with_namespace is absent ?');
116 | it('should throw an error if repo.web_url is absent ?');
117 | it('should throw an error if repo.public is absent ?');
118 | it('should throw an error if repo.ssh_url_to_repo is absent ?');
119 | it('should throw an error if repo.owner is absent ?');
120 | it('should throw an error if repo.web_url is absent ?');
121 |
122 | /*
123 | return {
124 | 83 id: repo.id,
125 | 84 name: repo.path_with_namespace,
126 | 85 display_name: repo.path_with_namespace,
127 | 86 display_url: repo.web_url,
128 | 87 group: repo.namespace.path,
129 | 88 private: !repo.public,
130 | 89 config: {
131 | 90 auth: {type: 'ssh'},
132 | 91 scm: 'git',
133 | 92 url: repo.ssh_url_to_repo,
134 | 93 owner: repo.owner,
135 | 94 repo: repo.web_url,
136 | 95 pull_requests: 'none',
137 | 96 whitelist: []
138 | 97 }
139 | */
140 | });
141 |
142 | //--------------------------------------------------------------------------------------
143 | describe('addDeployKey', function() {
144 | it('should return an error if any of its expected arguments are absent');
145 |
146 | it('should invoke our callback with err as null and the second parameter as true, when given correct parameters', function(done) {
147 | api.addDeployKey(correctConfig, 5, 'strider-stridertester/privproject1', correctDeployKey, function(err, secondParam) {
148 | expect(err).to.not.be.ok();
149 | expect(secondParam).to.be.ok();
150 | done();
151 | });
152 | });
153 |
154 | it('should give an error if invalid data is sent as an ssh key', function(done) {
155 | api.addDeployKey(correctConfig, 5, 'strider-stridertester/privproject1', "invalid-key", function(err, secondParam) {
156 | //debug("Err is: " + util.inspect(err, false, 10, true));
157 | expect(err).to.be.ok();
158 | done();
159 | });
160 | });
161 |
162 | it('should give an error if incorrect credentials are passed to it', function(done) {
163 | api.addDeployKey(wrongCredentialsConfig, 5, 'strider-stridertester/privproject1', correctDeployKey, function(err, secondParam) {
164 | //debug("Err is: " + util.inspect(err, false, 10, true));
165 | expect(err).to.be.ok();
166 | done();
167 | });
168 | });
169 |
170 | it('should return an error if the specified gitlab server IP cannot be resolved from the name', function(done) {
171 | api.addDeployKey(invalidServerNameConfig, 5, 'strider-stridertester/privproject1', correctDeployKey, function(err, secondParam) {
172 | expect(err).to.be.ok();
173 | expect(err).to.be.an(Error);
174 | done();
175 | });
176 | });
177 |
178 | it('should return an error if the config passed in to it does not have a Gitlab API url', function(done) {
179 | const config = {api_key: 'zRtVsmeznn7ySatTrnrp'};
180 | api.addDeployKey(config, 5, 'strider-stridertester/privproject1', correctDeployKey, function(err, secondParam) {
181 | expect(err).to.be.ok();
182 | expect(err).to.be.an(Error);
183 | done();
184 | });
185 | });
186 |
187 | it('should give an error if invalid repo id is passed to it', function(done) {
188 | api.addDeployKey(correctConfig, "wrong repo id", 'strider-stridertester/privproject1', correctDeployKey, function(err, secondParam) {
189 | //debug("Err is: " + util.inspect(err, false, 10, true));
190 | expect(err).to.be.ok();
191 | done();
192 | });
193 | });
194 | });
195 |
196 | //--------------------------------------------------------------------------------------
197 | describe('removeDeployKey - when key is registered with the server', function() {
198 | before('Setup the mock gitlab server', function setupNock() {
199 | nock.cleanAll();
200 | require('./mocks/gitlab_delete_project.js')();
201 | });
202 |
203 | after('Tear down mock Gitlab server', function tearDownNock() {
204 | nock.cleanAll();
205 | });
206 |
207 | it('should return an error if any of its expected arguments are absent');
208 |
209 | it('should delete a key and invoke our callback with err as null and wasDeleted as true when given correct parameters', function(done) {
210 | api.removeDeployKey(correctConfig, 5, 'strider-stridertester/privproject1', function(err, wasDeleted) {
211 | //debug("Err is: " + util.inspect(err, false, 10, true));
212 | //debug("Err is: " + err);
213 | //debug("wasDeleted is: " + wasDeleted);
214 | expect(err).to.not.be.ok();
215 | expect(wasDeleted).to.be.ok();
216 | done();
217 | });
218 | });
219 |
220 | it('should return an error if wrong credentials are given', function(done) {
221 | api.removeDeployKey(wrongCredentialsConfig, 5, 'strider-stridertester/privproject1', function(err, wasDeleted) {
222 | //debug("Err is: " + util.inspect(err, false, 10, true));
223 | //debug("Err is: " + err);
224 | expect(err).to.be.ok();
225 | expect(err).to.be.an(Error);
226 | done();
227 | });
228 | });
229 |
230 | it('should return an error if the config passed in to it does not have a Gitlab API url', function(done) {
231 | api.removeDeployKey(configWithoutApiUrl, 5, 'strider-stridertester/privproject1', function(err, wasDeleted) {
232 | //debug("Err is: " + util.inspect(err, false, 10, true));
233 | //debug("Err is: " + err);
234 | expect(err).to.be.ok();
235 | expect(err).to.be.an(Error);
236 | done();
237 | });
238 | });
239 |
240 | it('should return an error if the specified gitlab server IP cannot be resolved from the name', function(done) {
241 | api.removeDeployKey(invalidServerNameConfig, 5, 'strider-stridertester/privproject1', function(err, wasDeleted) {
242 | //Currently due to an issue with nock/superagent interaction we get a TypeError thrown instead of ENOTFOUND
243 | //https://github.com/pgte/nock/issues/211#issuecomment-133636234
244 | //debug("Err is: " + util.inspect(err, false, 10, true));
245 | //debug("Err is: " + err.stack);
246 | expect(err).to.be.ok();
247 | expect(err).to.be.an(Error);
248 | done();
249 | });
250 | });
251 |
252 | it('should give an error if invalid repo id is passed to it', function(done) {
253 | api.removeDeployKey(correctConfig, "wrong repo id", 'strider-stridertester/privproject1', function(err, secondParam) {
254 | //debug("Err is: " + err);
255 | //debug("Err is: " + util.inspect(err, false, 10, true));
256 | expect(err).to.be.ok();
257 | done();
258 | });
259 | });
260 | });
261 |
262 | describe('removeDeployKey - when key is not registered in the gitlab server', function() {
263 | before('Setup the mock gitlab server', function setupNock() {
264 | nock.cleanAll();
265 | require('./mocks/gitlab_delete_key_when_absent.js')();
266 | });
267 |
268 | after('Tear down mock Gitlab server', function tearDownNock() {
269 | nock.cleanAll();
270 | });
271 |
272 | it('should callback with err as null and wasDeleted as false', function(done) {
273 | api.removeDeployKey(correctConfig, 5, 'strider-stridertester/privproject1', function(err, wasDeleted) {
274 | //debug("Err is: " + util.inspect(err, false, 10, true));
275 | //debug("wasDeleted is: " + wasDeleted);
276 | expect(err).to.not.be.ok();
277 | expect(wasDeleted).to.not.be.ok();
278 | done();
279 | });
280 | });
281 | });
282 |
283 | //--------------------------------------------------------------------------------------
284 | describe('createHooks', function() {
285 | //takes parameters config, repo_id, url and callback
286 |
287 | beforeEach('Setup the mock gitlab server for creating hooks', function setupNock() {
288 | nock.cleanAll();
289 | require('./mocks/gitlab_create_hooks.js')();
290 | });
291 |
292 | afterEach('Tear down mock Gitlab server', function tearDownNock() {
293 | nock.cleanAll();
294 | });
295 |
296 |
297 | it('should return true as the second parameter and err as false if hooks were created successfully', function(done) {
298 | api.createHooks(correctConfig, '5', 'http://localhost:3000/stridertester/privproject1/api/gitlab/webhook', function(err, couldCreateHooks) {
299 | //debug("error: " + err + " couldCreateHooks: " + couldCreateHooks);
300 | expect(err).to.not.be.ok();
301 | expect(couldCreateHooks).to.be.ok();
302 | done();
303 | });
304 | });//NOTE: if the webhook has already been created, gitlab creates a new one with an incremented ID
305 |
306 | it('should callback with an error if config does not have an api_url', function(done) {
307 | api.createHooks(configWithoutApiUrl, '5', 'http://localhost:3000/stridertester/privproject1/api/gitlab/webhook', function(err, couldCreateHooks) {
308 | expect(err).to.be.ok();
309 | done();
310 | });
311 | });
312 |
313 | it('should callback with an error if config does not have an api_key', function(done) {
314 | api.createHooks(configWithoutApiKey, '5', 'http://localhost:3000/stridertester/privproject1/api/gitlab/webhook', function(err, couldCreateHooks) {
315 | expect(err).to.be.ok();
316 | done();
317 | });
318 | });
319 |
320 | it('should callback with an error if invalid credentials were specified', function(done) {
321 | api.createHooks(wrongCredentialsConfig, '5', 'http://localhost:3000/stridertester/privproject1/api/gitlab/webhook', function(err, couldCreateHooks) {
322 | expect(err).to.be.ok();
323 | done();
324 | });
325 | });
326 |
327 |
328 | it('should callback with an error if an invalid repo_id was specified', function(done) {
329 | api.createHooks(correctConfig, 'invalid-repo', 'http://localhost:3000/stridertester/privproject1/api/gitlab/webhook', function(err, couldCreateHooks) {
330 | expect(err).to.be.ok();
331 | done();
332 | });
333 | });
334 |
335 | it('should callback with a 400 error if the URL parameter is not a string', function(done) {
336 | api.createHooks(correctConfig, '5', false, function(err, couldCreateHooks) {
337 | expect(err).to.be.ok();
338 | done();
339 | });
340 | });
341 |
342 | it('should callback with an error if the gitlab server cannot be reached or resolved', function(done) {
343 | api.createHooks(invalidServerNameConfig, '5', false, function(err, couldCreateHooks) {
344 | expect(err).to.be.ok();
345 | done();
346 | });
347 | });
348 | });
349 |
350 | //--------------------------------------------------------------------------------------
351 | describe('deleteHooks - when hook has been registered', function() {
352 | before('Setup the mock gitlab server', function setupNock() {
353 | nock.cleanAll();
354 | require('./mocks/gitlab_delete_hooks_when_present.js')();
355 | });
356 |
357 | after('Tear down mock Gitlab server', function tearDownNock() {
358 | nock.cleanAll();
359 | });
360 |
361 |
362 | it('should call our callback with second param as true and err as null if hooks were successfully deleted', function(done) {
363 | api.deleteHooks(correctConfig, '5', 'http://localhost:3000/stridertester/privproject1/api/gitlab/webhook', function(err, wasDeleted) {
364 | expect(err).to.not.be.ok();
365 | expect(wasDeleted).to.be.ok();
366 | done();
367 | });
368 | });
369 |
370 | it('should callback with an error if config does not have an api_url', function(done) {
371 | api.deleteHooks(configWithoutApiUrl, '5', 'http://localhost:3000/stridertester/privproject1/api/gitlab/webhook', function(err, wasDeleted) {
372 | //debug('Error is ' + util.inspect(err, false, null, true));
373 | expect(err).to.be.ok();
374 | done();
375 | });
376 | });
377 |
378 | it('should callback with an error if config does not have an api_key', function(done) {
379 | api.deleteHooks(configWithoutApiKey, '5', 'http://localhost:3000/stridertester/privproject1/api/gitlab/webhook', function(err, wasDeleted) {
380 | expect(err).to.be.ok();
381 | done();
382 | });
383 | });
384 |
385 | it('should callback with an error if invalid credentials were specified', function(done) {
386 | api.deleteHooks(wrongCredentialsConfig, '5', 'http://localhost:3000/stridertester/privproject1/api/gitlab/webhook', function(err, wasDeleted) {
387 | expect(err).to.be.ok();
388 | done();
389 | });
390 | });
391 |
392 |
393 | it('should callback with an error if an invalid repo_id was specified', function(done) {
394 | api.deleteHooks(correctConfig, 'invalid-repo', 'http://localhost:3000/stridertester/privproject1/api/gitlab/webhook', function(err, wasDeleted) {
395 | expect(err).to.be.ok();
396 | done();
397 | });
398 | });
399 |
400 |
401 | it('should callback with an error if the gitlab server cannot be reached', function(done) {
402 | api.deleteHooks(invalidServerNameConfig, '5', 'http://localhost:3000/stridertester/privproject1/api/gitlab/webhook', function(err, wasDeleted) {
403 | expect(err).to.be.ok();
404 | done();
405 | });
406 | });
407 | });
408 |
409 | //--------------------------------------------------------------------------------------
410 | describe('deleteHooks - when hook has not been registered', function() {
411 | before('Setup the mock gitlab server', function setupNock() {
412 | nock.cleanAll();
413 | require('./mocks/gitlab_delete_hooks_when_absent.js')();
414 | });
415 |
416 | after('Tear down mock Gitlab server', function tearDownNock() {
417 | nock.cleanAll();
418 | });
419 |
420 | it('should callback with err as null and wasDeleted as false', function(done) {
421 | api.deleteHooks(correctConfig, 5, 'strider-stridertester/privproject1', function(err, wasDeleted) {
422 | //debug("Err is: " + util.inspect(err, false, 10, true));
423 | //debug("wasDeleted is: " + wasDeleted);
424 | expect(err).to.not.be.ok();
425 | expect(wasDeleted).to.not.be.ok();
426 | done();
427 | });
428 | });
429 | });
430 | });
431 |
--------------------------------------------------------------------------------
/test/test_webapp.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Used to test the gitlab webapp
5 |
6 | nock will simulate a gitlab server running at
7 | localhost:80, where Strider Tester, a user is
8 | registered with the name "stridertester", and
9 | has been registered with api token - zRtVsmeznn7ySatTrnrp
10 | stridertester is an "owner" of a group named "testunion"
11 | and has admin access to three projects -
12 | testunion / unionproject1
13 | Strider Tester / pubproject1
14 | Strider Tester / privproject1
15 | */
16 |
17 | const expect = require('expect.js');
18 | const webapp = require('../lib/webapp');
19 | const util = require('util');
20 | const nock = require('nock');
21 |
22 | function deepClone(sourceObject) {
23 | return JSON.parse(JSON.stringify(sourceObject));
24 | }
25 |
26 | const wrongCredentialsConfig = {
27 | api_url: 'http://localhost:80/api/v3',
28 | api_key: 'badkey'
29 | };
30 |
31 | const providerConfig = {
32 | whitelist: [],
33 | pull_requests: 'none',
34 | repo: 'http://nodev/stridertester/privproject1',
35 | owner: {
36 | avatar_url: 'http://www.gravatar.com/avatar/3f671ed86ed3d21ed3640c7a016b0997?s=40&d=identicon',
37 | state: 'active',
38 | id: 3,
39 | username: 'stridertester',
40 | name: 'Strider Tester'
41 | },
42 | url: 'git@nodev:stridertester/privproject1.git',
43 | scm: 'git',
44 | auth: {type: 'ssh'}
45 | };
46 |
47 | const providerConfigForProjectWithMissingStriderJson =
48 | {
49 | whitelist: [],
50 | pull_requests: 'none',
51 | repo: 'http://nodev/stridertester/priproject2',
52 | owner: {
53 | avatar_url: 'http://www.gravatar.com/avatar/3f671ed86ed3d21ed3640c7a016b0997?s=40&d=identicon',
54 | state: 'active',
55 | id: 3,
56 | username: 'stridertester',
57 | name: 'Strider Tester'
58 | },
59 | url: 'git@nodev:stridertester/priproject2.git',
60 | scm: 'git',
61 | auth: {type: 'ssh'}
62 | };
63 |
64 | const repoProject = {
65 | name: 'stridertester/privproject1',
66 | display_name: 'stridertester/privproject1',
67 | display_url: 'http://nodev/stridertester/privproject1',
68 | public: false,
69 | prefetch_config: true,
70 | creator: "55d2ecb5edb0d634165eac37",
71 | provider: {
72 | id: 'gitlab',
73 | account: '0',
74 | repo_id: '5',
75 | config: {
76 | auth: {type: 'ssh'},
77 | scm: 'git',
78 | url: 'git@nodev:stridertester/privproject1.git',
79 | owner: {
80 | name: 'Strider Tester',
81 | username: 'stridertester',
82 | id: 3,
83 | state: 'active',
84 | avatar_url: 'http://www.gravatar.com/avatar/3f671ed86ed3d21ed3640c7a016b0997?s=40&d=identicon'
85 | },
86 | repo: 'http://nodev/stridertester/privproject1',
87 | pull_requests: 'none',
88 | whitelist: []
89 | }
90 | },
91 | branches: [{
92 | name: 'master',
93 | active: true,
94 | mirror_master: false,
95 | deploy_on_green: true,
96 | pubkey: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1j1c3wNyUwFzIhU5ELZb6tH1K+TkQgV0CrYjRvWmeZZr5aNKehSo5ntCoPtjZOddD2qYOUNyqe0EkdsSa7JeuD0blk5T9V8EADxqSmfYE8qD3Ch1JN0T4gbxoH20N45gqfpzug04FNwaDvCoxJgKvJXNj141SRLVVsa3DlByqC1Il+6TS7LqsQQMnSahgdx6fOUSLzSRG5NmbHGnS4CA1W4zyqQKzznh/Qj9WLxQKxugly3PPWtlcCDoaFBBQSOIgGVs00Bd3X8DJW/3gNPfydtUAdm/BcDZHOLyBUNOQCjR/fGyLS8D4ufYt6vr72No9O0dyKyI+FpOb+jPDG631 stridertester/privproject1-stridertester@gmail.com\n',
97 | privkey: '-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAtY9XN8DclMBcyIVORC2W+rR9Svk5EIFdAq2I0b1pnmWa+WjS\nnoUqOZ7QqD7Y2TnXQ9qmDlDcqntBJHbEmuyXrg9G5ZOU/VfBAA8akpn2BPKg9wod\nSTdE+IG8aB9tDeOYKn6c7oNOBTcGg7wqMSYCryVzY9eNUkS1VbGtw5QcqgtSJfuk\n0uy6rEEDJ0moYHcenzlEi80kRuTZmxxp0uAgNVuM8qkCs854f0I/Vi8UCsboJctz\nz1rZXAg6GhQQUEjiIBlbNNAXd1/AyVv94DT38nbVAHZvwXA2Rzi8gVDTkAo0f3xs\ni0vA+Ln2Ler6+9jaPTtHcisiPhaTm/ozwxut9QIDAQABAoIBAGbtMPOheSs29iKT\nN/B8q+fKpHD5YnlR7QmUmUjWCWdLkJSt8SD+uxZZS07l+gcDvF5yOMtK2h4nq6Fh\nV0nAsKhzbqy9gqwwsHA5H8ZWU9swNUJ3UGzuUUJUQhwBHNDP4rbMemjYtUVNkXrj\nFEQymTjzkTvbufkWjHpdNPX4JFvdBGKJID9Orfq53TV/tKWQ4cuk9y6L3WcHojPo\nTx6iKc7n6GEH3OYaUeuF0LfbZGGrSO04EB0gsq/kjtjPzmTH5kVG8haVZBhbjETW\nrFQPTWfshSx6za3ecMGfvlC7Jb5JBZ7BknTHHytAGuPK0W08K9yBfkrTmhMUiEyD\nMDO7oU0CgYEA4ofELHIt7/V/YKFyCU4v7DkrCJdOcTnLHpOlMm2e3NZInGZdDp8+\n6XFKRKlk/Vv7NZg5m/liPhBRGZalWTT5x20VyTNxVN0WudjPTGbl/Q6l9nG1cu5V\nNtxX5G3o8eOcSQaiTY8IVEN96ApuYhnh2u+463WSaWc5U53Oh+0V4kcCgYEAzS3n\n9o1qmkc+KLmjYI19M5gN3sW1ZyIYa3f0i9FCqnAaKKoBrNVjSaQ5Hp/jyAc1hDtq\nS/HwztUDJNvVB5/IRacpMklrh8ReF/2kTHgM1ChCTkdsoIQOw04Sp8VJLK4ECswn\n7R+17Ff4hW0nffYfQeMeXCZd99HrbYgH564PL+MCgYBzNLzuJbt7GA2J5VGLrfnt\nVz2thtXb+5pzmH8hYGK0yT3wXJbjAtYJ/xXYSZYUzBy8KwjRbEksazvzmYvKDIkj\nhTTZOJJgqHgQWFVE8+fvhO2eokG3i8JGvlTs1YDs0+b9tKQCccW4pQJ5aiStO6CD\nqfsPtKGbfWXIQq9wrYC9rQKBgGUx5f0pJFGxH4wwes7NGdoPfY/JDT4vh8HBaQBo\nliu/nHc/2hGnMRAKCg37p/lo7NEqCLQqQK2SS7mrHrdi7ADGgEAIDBvrEslcVONO\nNm2Q6Zr4CTBl0W4sHHFYkU2TCfVVWb/O6wgFH1KXUmoCsMnrPXcPiTsH8siT1epD\nY8QnAoGAYhPbK1k6sH8bTdU6hI3TtaSZ1MOMDO2eeB0u2dpQSOiQ5a33vLM9AN2s\nHQfwA6yNn9oPf3BnJBOGxpX6W/L3ntYOVp4T/18LCZOX8f9GFwUrAAtbH52YgP/3\njveYyVbjAOkSohdCd2UhiJWoQVHcGGHrkX/bKFfyVYUlKrKpVag=\n-----END RSA PRIVATE KEY-----\n',
98 | plugins: [
99 | {
100 | id: 'node',
101 | enabled: true,
102 | config: {
103 | fork: 'Node.js',
104 | runtime: 'whatever',
105 | caching: 'none',
106 | test: 'npm test',
107 | globals: []
108 | }
109 | }],
110 | runner: {
111 | id: 'simple-runner',
112 | config: {pty: false}
113 | }
114 | },
115 | {name: '*', mirror_master: true}
116 | ]
117 | };
118 |
119 | const projectWithInvalidRepoID = deepClone(repoProject);
120 | projectWithInvalidRepoID.provider.repo_id = "invalidrepo";
121 |
122 | const projectWithInvalidSSHKey = deepClone(repoProject);
123 | projectWithInvalidSSHKey.branches[0].pubkey = "invalid key";
124 |
125 | const projectWithInvalidName = deepClone(repoProject);
126 | projectWithInvalidName.name = "nonexistentproject";
127 |
128 | describe('gitlab webapp', function() {
129 | //--------------------------------------------------------------------------------------
130 | //Test getting a json file
131 | describe('getFile', function() {
132 | before('Setup the mock gitlab server', function setupNock() {
133 | nock.cleanAll();
134 | require('./mocks/gitlab_webapp_getfile.js')();
135 | });
136 |
137 | after('Tear down mock Gitlab server', function tearDownNock() {
138 | nock.cleanAll();
139 | });
140 |
141 | const filename = "strider.json";
142 |
143 | const ref = {
144 | branch: 'master',
145 | };
146 |
147 | //getFile only uses account.config
148 | const account = {
149 | api_key: 'zRtVsmeznn7ySatTrnrp',
150 | api_url: 'http://localhost:80/api/v3'
151 | };
152 |
153 |
154 | //getFile only uses project.provider.repo_id
155 | const project = {
156 | provider: {
157 | repo_id: '5'
158 | }
159 | };
160 |
161 | //project with strider.json missing
162 | const projectWithMissingStriderJson = {
163 | provider: {
164 | repo_id: '8'
165 | }
166 | };
167 |
168 |
169 | it('should get a json file correctly', function(done) {
170 | webapp.getFile(filename, ref, account, providerConfig, project, function(err, text) {
171 | expect(text).to.be.a('string');
172 | done();
173 | });
174 | });
175 |
176 | //created a project priproject2 of type node.js, but not having a strider.json for this test
177 | it('should not crash, but return an error if the file could not be found', function(done) {
178 | webapp.getFile(filename, ref, account, providerConfigForProjectWithMissingStriderJson, projectWithMissingStriderJson, function(err, text) {
179 | expect(err).to.be.ok();
180 | expect(text).to.not.be.ok();
181 | done();
182 | });
183 | });
184 | });
185 |
186 | //--------------------------------------------------------------------------------------
187 | //Test getting branches from a repository
188 | describe('getBranches', function() {
189 | //takes parameters - account, config, project
190 |
191 | /*
192 | NOTE: the account argument in this function is DIFFERENT from
193 | the account argument passed in to webapp.getFile. Here we get passed what is
194 | known elsewhere (in the api tests) to be a config object (i.e. one with
195 | two properties - api_url and api_key. Also note that in the webapp file, config
196 | is used to refer to an object of type project.provider.config
197 | */
198 | const account = {
199 | api_url: 'http://localhost:80/api/v3',
200 | api_key: 'zRtVsmeznn7ySatTrnrp'
201 | };
202 |
203 |
204 | const invalidAccount = {
205 | api_url: 'http://localhost:80/api/v3',
206 | api_key: 'badkey'
207 | };
208 |
209 | //getBranches only uses project.provider.repo_id
210 | const project = {
211 | provider: {
212 | repo_id: '5',
213 | }
214 | };
215 |
216 | const invalidProject = {
217 | provider: {
218 | repo_id: 'invalidrepo',
219 | }
220 | };
221 |
222 | before('Setup the mock gitlab server', function setupNock() {
223 | nock.cleanAll();
224 | require('./mocks/gitlab_webapp_getbranches.js')();
225 | });
226 |
227 | after('Tear down mock Gitlab server', function tearDownNock() {
228 | nock.cleanAll();
229 | });
230 |
231 | it('should get a correct list of branches in the project', function(done) {
232 | webapp.getBranches(account, providerConfig, project, function(err, branches) {
233 | //debug("Branches we get are: " + Object.prototype.toString.call(branches) + "Inspected: " + util.inspect(branches, false, null, true));
234 | expect(branches).to.be.an('array');
235 | expect(branches).to.eql(['firstbranch', 'master']);
236 | done();
237 | });
238 | });
239 |
240 | it('should complain suitably if account data is empty', function(done) {
241 | webapp.getBranches({}, providerConfig, project, function(err, branches) {
242 | //debug("Branches we get are: " + Object.prototype.toString.call(branches) + "Inspected: " + util.inspect(branches, false, null, true));
243 | //debug("We get ERR as: " + util.inspect(err, false, null, true));
244 | expect(err).to.be.ok();
245 | done();
246 | });
247 | });
248 |
249 | it('should complain suitably if account data is invalid', function(done) {
250 | webapp.getBranches(invalidAccount, providerConfig, project, function(err, branches) {
251 | //debug("We get ERR as: " + err);
252 | expect(err).to.be.ok();
253 | done();
254 | });
255 | });
256 |
257 | it('should complain suitably if project.provider.repo_id is invalid', function(done) {
258 | webapp.getBranches(account, providerConfig, invalidProject, function(err, branches) {
259 | //debug("We get ERR as: " + util.inspect(err, false, null, true));
260 | expect(err).to.be.ok();
261 | done();
262 | });
263 | });
264 | });
265 |
266 | //--------------------------------------------------------------------------------------
267 | describe('listRepos', function() {
268 | //takes parameters - config, callback
269 |
270 | //NOTE: what listRepos expects as config, is called account elsewhere in webapp.js
271 | const config = {
272 | api_url: 'http://localhost:80/api/v3',
273 | api_key: 'zRtVsmeznn7ySatTrnrp'
274 | };
275 |
276 |
277 | before('Setup the mock gitlab server', function setupNock() {
278 | nock.cleanAll();
279 | require('./mocks/gitlab_webapp_listrepos.js')();
280 | });
281 |
282 | after('Tear down mock Gitlab server', function tearDownNock() {
283 | nock.cleanAll();
284 | });
285 |
286 | it('should get a list of repositories accessible to the user correctly', function(done) {
287 | webapp.listRepos(config, function(err, repos) {
288 | expect(err).to.not.be.ok();
289 | expect(repos).to.be.an('array');
290 | expect(repos.length).to.eql(3);
291 | done();
292 | });
293 | });
294 |
295 | it('should complain if an invalid config is passed - invalid api_url', function(done) {
296 | webapp.listRepos({api_url: 'invalidurl', api_key: 'zRtVsmeznn7ySatTrnrp'}, function(err, repos) {
297 | expect(err).to.be.ok();
298 | done();
299 | });
300 | });
301 |
302 | it('should complain if invalid credentials are passed - wrong api_key', function(done) {
303 | webapp.listRepos(wrongCredentialsConfig, function(err, repos) {
304 | expect(err).to.be.ok();
305 | done();
306 | });
307 | });
308 | });
309 |
310 | //--------------------------------------------------------------------------------------
311 | describe('setupRepo', function() {
312 | //takes parameters - account, project, config, callback
313 | const account = {
314 | api_url: 'http://localhost:80/api/v3',
315 | api_key: 'zRtVsmeznn7ySatTrnrp'
316 | };
317 |
318 | before('Setup the mock gitlab server', function setupNock() {
319 | nock.cleanAll();
320 | require('./mocks/gitlab_webapp_setuprepo.js')();
321 | });
322 |
323 | after('Tear down mock Gitlab server', function tearDownNock() {
324 | nock.cleanAll();
325 | });
326 |
327 | it('should callback with the same config object that we passed in as the second parameter if repo was set up successfully', function(done) {
328 | webapp.setupRepo(account, providerConfig, repoProject, function(err, receivedConf) {
329 | expect(err).to.not.be.ok();
330 | expect(receivedConf).to.eql(providerConfig);
331 | done();
332 | });
333 | });
334 |
335 | it('should callback with an error if invalid credentials are supplied', function(done) {
336 | webapp.setupRepo(wrongCredentialsConfig, providerConfig, repoProject, function(err, receivedConf) {
337 | expect(err).to.be.ok();
338 | done();
339 | });
340 | });
341 |
342 | it('should callback with an error if project.provider.repo_id is invalid', function(done) {
343 | webapp.setupRepo(account, providerConfig, projectWithInvalidRepoID, function(err, receivedConf) {
344 | expect(err).to.be.ok();
345 | done();
346 | });
347 | });
348 |
349 | it('should callback with an error if project.branches[0].pubkey is not a valid ssh public key', function(done) {
350 | webapp.setupRepo(account, providerConfig, projectWithInvalidSSHKey, function(err, receivedConf) {
351 | expect(err).to.be.ok();
352 | done();
353 | });
354 | });
355 | });
356 |
357 | //--------------------------------------------------------------------------------------
358 | describe('tearDownRepo', function() {
359 | //takes parameters - account, project, config, callback
360 | const account = {
361 | api_url: 'http://localhost:80/api/v3',
362 | api_key: 'zRtVsmeznn7ySatTrnrp'
363 | };
364 |
365 | before('Setup the mock gitlab server', function setupNock() {
366 | nock.cleanAll();
367 | require('./mocks/gitlab_webapp_teardownrepos.js')();
368 | });
369 |
370 | after('Tear down mock Gitlab server', function tearDownNock() {
371 | nock.cleanAll();
372 | });
373 |
374 | it('should callback on success with no parameters if the repo was destroyed successfully', function(done) {
375 | webapp.teardownRepo(account, providerConfig, repoProject, function(err) {
376 | expect(err).to.not.be.ok();
377 | done();
378 | });
379 | });
380 |
381 | it('should callback with an error if invalid credentials are supplied', function(done) {
382 | webapp.teardownRepo(wrongCredentialsConfig, providerConfig, repoProject, function(err) {
383 | expect(err).to.be.ok();
384 | done();
385 | });
386 | });
387 |
388 | it('should callback with an error if project.provider.repo_id is invalid', function(done) {
389 | webapp.teardownRepo(account, providerConfig, projectWithInvalidRepoID, function(err) {
390 | expect(err).to.be.ok();
391 | done();
392 | });
393 | });
394 |
395 | it.skip('should callback with an error if an invalid project name is given', function(done) {
396 | webapp.teardownRepo(account, providerConfig, projectWithInvalidName, function(err) {
397 | //TODO: what happens here is that the title does not match that of the key and
398 | //the key is not deleted. In that case, we are silently ignoring the was_deleted flag
399 | //and directly calling done with a null error
400 | expect(err).to.be.ok();
401 | done();
402 | });
403 | });
404 | });
405 | });
406 |
--------------------------------------------------------------------------------
/test/test_webhooks.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Used to test the gitlab webhooks
5 | */
6 |
7 | const expect = require('expect.js');
8 | const webhooks = require('../lib/webhooks');
9 | let util = require('util');
10 | let debug = require('debug')('strider-gitlab:test:webhooks');
11 |
12 | describe('receiving webhooks from the gitlab server', function() {
13 | //--------------------------------------------------------------------------------------
14 | describe('receiveWebhook', function() {
15 | //It takes three parameters, emitter, req and res
16 |
17 | it('should emit a job.prepare event on emitter AND return a 204 response if the payload was parsed successfully and a job could be created', function(done) {
18 | let expected_successes_remaining = 2;
19 |
20 | //the test should pass only when mockRes.sendStatus gets called with 204 AND when
21 | //emitter receives this signal with the jobObject, doing assertion counting to
22 | //ensure both conditions are successful. TODO: Is there a better way to do this with Mocha?
23 |
24 | function checkDone() {
25 | expected_successes_remaining--;
26 | if(expected_successes_remaining === 0) {
27 | done();
28 | }
29 | }
30 |
31 | //This will get the job.prepare event when the job is successfully created
32 | const emitter = new (require('events').EventEmitter);
33 |
34 | //This contains the payload received from the gitlab server in
35 | //body and project information from strider
36 | const mockReq = require('./mocks/receive_webhooks_req.js');
37 |
38 | //On receiving the payload we are expected to send a 204 immediately (?)
39 | //perhaps we should send a 400 if we could not parse the payload
40 | const mockRes = {
41 | sendStatus: function(code) {
42 | expect(code).to.eql(204);
43 | checkDone();
44 | }
45 | };
46 |
47 | emitter.on('job.prepare', function(jobObject) {
48 | expect(jobObject.type).to.eql("TEST_AND_DEPLOY");
49 | expect(jobObject.trigger.type).to.eql("commit");
50 | expect(jobObject.ref.branch).to.eql("master");
51 | expect(jobObject.ref.id).to.eql("6a00c57e69bd4e269496ca27973191ecafcf8b20");
52 | checkDone();
53 | });
54 |
55 | webhooks.receiveWebhook(emitter, mockReq, mockRes);
56 |
57 | });
58 |
59 | it('should send a 400 error in the res if the payload cannot be parsed');
60 |
61 | });
62 |
63 | //--------------------------------------------------------------------------------------
64 | describe('pushJob', function() {
65 | //pushJob takes one parameter - a payload object
66 |
67 | it('should be able to parse the payload and return an object with branch, trigger, deploy and ref', function() {
68 | const samplePayload = require('./mocks/sample_payload.js');
69 | const config = webhooks.pushJob(samplePayload);
70 | expect(config).to.eql({
71 | branch: 'master',
72 | trigger: {
73 | type: 'commit',
74 | author: {
75 | name: 'Strider Tester',
76 | username: undefined,
77 | email: 'stridertester@gmail.com',
78 | image: 'https://s.gravatar.com/avatar/3f671ed86ed3d21ed3640c7a016b0997'
79 | },
80 | url: 'http://nodev/stridertester/privproject1/commit/352e6fe2ea42d394a21dc7995df2116e86bb0684',
81 | message: 'updated strider.json\n',
82 | timestamp: '2015-08-26T20:02:07+09:00',
83 | source: {type: 'plugin', plugin: 'gitlab'}
84 | },
85 | deploy: true,
86 | ref: {
87 | branch: 'master',
88 | id: '352e6fe2ea42d394a21dc7995df2116e86bb0684'
89 | }
90 | });
91 | });
92 | });
93 |
94 |
95 | //--------------------------------------------------------------------------------------
96 | describe('pushJob', function() {
97 | //pushJob takes one parameter - a payload object
98 |
99 | it('should be able to parse the payload and return an object with branch, trigger, deploy and ref by gitlab v7', function() {
100 | const samplePayload = require('./mocks/sample_payload_tag_push_with_v7.x.js');
101 | const config = webhooks.pushJob(samplePayload);
102 | expect(config).to.eql({
103 | branch: 'tag-1.1.2',
104 | trigger: {
105 | type: 'tag push',
106 | author: {
107 | name: 'Strider Tester',
108 | username: undefined,
109 | email: undefined,
110 | image: 'https://s.gravatar.com/avatar/d415f0e30c471dfdd9bc4f827329ef48'
111 | },
112 | url: 'http://nodev/stridertester/privproject1/commit/352e6fe2ea42d394a21dc7995df2116e86bb0684',
113 | message: 'tag push',
114 | timestamp: config.trigger.timestamp,
115 | source: { type: 'plugin', plugin: 'gitlab' }
116 | },
117 | deploy: true,
118 | ref: {
119 | branch: 'tag-1.1.2',
120 | id: '352e6fe2ea42d394a21dc7995df2116e86bb0684'
121 | }
122 | });
123 | });
124 | });
125 |
126 | });
127 |
--------------------------------------------------------------------------------
/test/test_worker.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Used to test the gitlab worker
5 | */
6 |
7 | const proxyquire = require('proxyquire');
8 | const expect = require('expect.js');
9 | let util = require('util');
10 | let debug = require('debug')('strider-gitlab:test:webapp');
11 |
12 | const gitStub = {};
13 |
14 | gitStub.fetch = function(dest, config, job, context, done) {
15 | done();
16 | };
17 |
18 | const worker = proxyquire('../lib/worker', {'strider-git/worker': gitStub});
19 |
20 | describe('gitlab worker', function() {
21 | //--------------------------------------------------------------------------------------
22 | describe('init', function() {
23 | const dirs = {
24 | base: '/home/dev/.strider',
25 | data: '/home/dev/.strider/data/stridertester-privproject1-55de9a6c1cfc0d872d309dbb',
26 | cache: '/home/dev/.strider/cache/stridertester/privproject1'
27 | };
28 |
29 | const account = {
30 | api_url: 'http://localhost:80/api/v3',
31 | api_key: 'zRtVsmeznn7ySatTrnrp'
32 | };
33 |
34 | const config = {
35 | whitelist: [],
36 | pull_requests: 'none',
37 | repo: 'http://nodev/stridertester/privproject1',
38 | owner: {
39 | avatar_url: 'http://www.gravatar.com/avatar/3f671ed86ed3d21ed3640c7a016b0997?s=40&d=identicon',
40 | state: 'active',
41 | id: 3,
42 | username: 'stridertester',
43 | name: 'Strider Tester'
44 | },
45 | url: 'git@nodev:stridertester/privproject1.git',
46 | scm: 'git',
47 | auth: {type: 'ssh'}
48 | };
49 |
50 | const job = {};
51 |
52 | it('should call back with err as null and the second param as an object with three properties, config, account and a fetch function', function(done) {
53 | worker.init(dirs, account, config, job, function(err, object) {
54 | expect(err).to.not.be.ok();
55 | expect(object.config).to.eql(config);
56 | expect(object.account).to.eql(account);
57 | expect(object.fetch).to.be.a('function');
58 | done();
59 | });
60 | });
61 |
62 | it('should check for invalid arguments and operational errors ?');
63 | });
64 |
65 | //--------------------------------------------------------------------------------------
66 | describe('fetch', function() {
67 |
68 | it('should call our callback after strider-git/worker fetch is done with its task', function(done) {
69 | const dest = "";
70 | const account = {
71 | accessToken: "abcd"
72 | };
73 | const config = {
74 | auth: {
75 | type: "https",
76 | username: "strider"
77 | }
78 | };
79 | const job = {};
80 | const context = {};
81 |
82 | worker.fetch(dest, account, config, job, context, done);
83 | });
84 |
85 | it('should check for invalid arguments and operational errors ?');
86 | });
87 |
88 | });
89 |
--------------------------------------------------------------------------------