summaryrefslogtreecommitdiffstats
path: root/pift.pages.inc
blob: 177656de65ddf2f92b1a3f186098343fdddfa813 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
<?php

/**
 * @file
 * Provide general pages and UI functions.
 *
 * @author Jimmy Berry ("boombatower", http://drupal.org/user/214218)
 */

/**
 * Add additional description to file attachment form on issues.
 */
function pift_pages_description_add(&$form, $form_state, $form_id) {
  global $user;
  // Add description on field_issue_files if it is set.
  if (PIFT_DESCRIPTION) {
    // Detect project issue node ID.
    $nid = NULL;
    // TODO: This is drupal.org specific, as any node type can be marked as an
    // issue after the Project* D7 changes.  This code assumes a single node
    // type of 'project_issue'.
    if ($form_id == 'project_issue_node_form') {
      $nid = $form['#node']->field_project['und'][0]['target_id'];
      if (isset($form['field_issue_files'][LANGUAGE_NONE]['#file_upload_description']) && $nid && pift_project_enabled($nid)) {
        $description = filter_xss_admin(PIFT_DESCRIPTION);
        $form['field_issue_files'][LANGUAGE_NONE]['#file_upload_description'] .= " " . $description;
      }
    }
  }
}

/**
 * Add testing setting.
 */
function pift_pages_project_issue_settings($form, &$form_state, $node) {
  $form = array();
  $form['testing'] = array(
    '#type' => 'fieldset',
    '#title' => t('Testing'),
    '#collapsible' => TRUE,
    '#weight' => -9,
    '#access' => user_access('pift enable project testing'),
  );

  // Build an array of core capatible version strings (ie 6.x, 7.x, etc).
  $api_versions = pift_core_api_versions();
  $versions = array();
  foreach ($api_versions as $api_version) {
    $term = taxonomy_term_load($api_version);
    $versions[] = $term->name;
  }
  $form['testing']['pift_enable'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable automated testing'),
    '#description' => t('Enable automated testing of @versions compatible branches and patches.',
      array('@versions' => implode(', ', $versions))),
    '#default_value' => pift_project_enabled($node->nid),
  );
  $form['testing']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save Settings'),
  );
  return $form;
}

/**
 * Store project testing preferences.
 */
function pift_pages_project_issue_settings_submit($form, &$form_state) {
  $enabled = pift_project_enabled($form_state['values']['nid']);
  if ($form_state['values']['pift_enable'] && !$enabled) {
    db_query('INSERT INTO {pift_project} VALUES (:nid)', array(':nid' => $form_state['values']['nid']));
  }
  else if (!$form_state['values']['pift_enable'] && $enabled) {
    db_delete('pift_project')
      ->condition('pid', $form_state['values']['nid'])
      ->execute();
  }
}

/**
 * Confirm re-test.
 *
 * @param integer Test ID to re-test.
 */
function pift_pages_retest_confirm_form($form, &$form_state, $test_id) {
  $test = pift_test_get($test_id);

  if ($test) {
    $form = array();
    // Key off type to determine if this is a file retest or branch retest
    if ($test['type'] == PIFT_TYPE_FILE) {
      // File test
      $form['test'] = array(
        '#type' => 'value',
        '#value' => array(
          'test_id' => $test_id,
          'fid' => $test['fid'],
          'nid' => ($test['fid'] ? $test['nid'] : $test['rid']),
          'cid' => ($test['cid'] ? $test['cid'] : 0),
          'status' => $test['status'],
          'title' => ($test['fid'] ? $test['filename'] : project_release_get_version((object) $test)),
          'type' => PIFT_TYPE_FILE,
        ),
      );
      $form_state['#redirect'] = 'node/' . $form['test']['#value']['nid'];
    }
    elseif ($test['type'] == PIFT_TYPE_RELEASE) {
      // Branch test
      $form['test'] = array(
        '#type' => 'value',
        '#value' => array(
          'test_id' => $test_id,
          'status' => $test['status'],
          'title' => "Test " . $test['test_id'],
          'type' => PIFT_TYPE_RELEASE,
        ),
      );
      // Get the project id
      $pid = db_query_range("SELECT project_nid from {versioncontrol_release_labels} where release_nid = %d", $test['id'])->fetchField();
      $form_state['#redirect'] = 'node/' . $pid . '/testing-status';
    }
    return confirm_form(
      $form,
      t('Are you sure you want to request that %title be re-tested?', array('%title' => $form['test']['#value']['title'])),
      $form_state['#redirect'],
      t('Once requested the test will be re-queued and results will be updated once the re-test has finished.'),
      t('Re-test'),
      t('Cancel')
    );
  }
  else {
    drupal_set_message(t('Invalid test.'), 'error');
  }
}

/**
 * Re-queue test if it still meets are criteria.
 */
function pift_pages_retest_confirm_form_submit($form, &$form_state) {
  global $user;
  $test = $form_state['values']['test'];
  if ($test['status'] > PIFT_STATUS_SENT) {
    if ($test['type'] == PIFT_TYPE_FILE) {
      // Base changes to be made in followup comment.
      $node = node_load($test['nid']);
      $node->nodechanges_uid = $user->uid;
      $node->nodechanges_comment_body['value'] = theme('pift_auto_followup', array('type' => 'retest', 'nid' => $test['nid'], 'cid' => $test['cid'], 'filename' => $test['title']));
      // If node issue status is not already a valid status then set to default
      // retest status, otherwise leave status alone.
      if (!in_array($node->field_issue_status[LANGUAGE_NONE][0]['value'], variable_get('pift_status', array()))) {
        $node->field_issue_status[LANGUAGE_NONE][0]['value'] = PIFT_FOLLOWUP_RETEST;
      }
      // Add followup to issue.
      node_save($node);
    }

    // Update test record to reflect change.
    db_update('pift_test')
      ->fields(array(
        'status' => PIFT_STATUS_QUEUE,
      ))
      ->condition('test_id', $test['test_id'])
      ->execute();

    if (db_affected_rows()) {
      drupal_set_message(t('%title has been submitted for re-testing. Please be patient while you wait for results.',
                           array('%title' => $test['title'])));
    }
    else {
      drupal_set_message(t('Invalid test.'), 'error');
    }
  }
  else {
    drupal_set_message(t('%title is not currently eligible for re-testing.',
                         array('%title' => $test['title'])), 'error');
  }
}

/**
 * Confirm "delete test".
 *
 * @param integer Test ID to delete.
 */
function pift_pages_delete_test_confirm_form($form, &$form_state, $test_id) {
  $test = pift_test_get($test_id);

  if ($test) {
    $form = array();
    $form['test'] = array(
      '#type' => 'value',
      '#value' => array(
        'test_id' => $test_id,
        'title' => "Test " . $test['test_id'],
      ),
    );
    // Get the project id
    $pid = db_query_range("SELECT project_nid from {versioncontrol_release_labels} where release_nid = :rid", 0, 1, array(':rid' => $test['id']))->fetchField();
    $form_state['#redirect'] = 'node/' . $pid . '/testing-status';
    return confirm_form(
      $form,
      t('Are you sure you want to delete %title?', array('%title' => $form['test']['#value']['title'])),
      $form_state['#redirect'],
      t('This will remove any existing results from the site, and reset the test status.') . '<br />' . t('This can help free up a branch test which is stuck in a "sent" state for long periods of time.'),
      t('Delete Test'),
      t('Cancel')
    );
  }
  else {
    drupal_set_message(t('Invalid test.'), 'error');
  }
}

/**
 * Delete test
 */
function pift_pages_delete_test_confirm_form_submit($form, &$form_state) {
  $test_id = $form_state['values']['test']['test_id'];
  if (!empty($test_id)) {
    db_delete('pift_test')
      ->condition('test_id', $test_id)
      ->execute();
  }
}

/**
 * Theme attachments into a table with test results.
 *
 * @param array $files List of file attachments.
 * @param boolean $status Issue status.
 * @return string HTML output.
 */
function theme_pift_attachments($variables) {
  // TODO: Validate whether these variables are still valid after the project*
  // changes introduced with the D7 port.
  $files = $variables['files'];
  $status = $variables['status'];
  $header = array(t('Attachment'), t('Size'), t('Status'), t('Test result'), t('Operations'));
  $rows = array();
  foreach ($files as $file) {
    $row = array();

    $row[] = l($file['filename'], file_create_url($file['filepath']));
    $row[] = format_size($file['filesize']);

    if ($file['test_id'] !== NULL) {
      list($row[], $class) = pift_attachment_process($file['status'], (bool) $file['message']);
      $message = $file['message'] ? check_plain($file['message']) : '<em>' . t('None') . '</em>';

      // If file is being re-tested then prefix the previous result message.
      if ($file['message'] && $file['status'] == PIFT_STATUS_QUEUE) {
        $message = t('Previous result: ') . $message;
      }

      $row[] = $message;
    }
    else {
      // Check if ignored due to issue status
      if (!in_array($status, variable_get('pift_status', array()))) {
        $row[] = '<em>' . t('Ignored:  Check issue status.');
      }
      else {
        $row[] = '<em>' . t('Ignored') . '</em>';
      }
      $row[] = '<em>' . t('None') . '</em>';
      $class = '';
    }

    // Add valid operations.
    $operations = array();
    if (($file['status'] > PIFT_STATUS_QUEUE || $file['message']) && !empty($file['test_id'])) {
      $operations[] = l(t('View details'), PIFT_SERVER . 'pifr/test/' . $file['test_id']);
    }
    if ($file['status'] > PIFT_STATUS_SENT && !($status == PROJECT_ISSUE_STATE_CLOSED) && !empty($file['test_id'])) {
      $operations[] = l(t('Re-test'), 'pift/retest/' . $file['test_id']);
    }
    $row[] = ($operations ? implode(' | ', $operations) : '<em>' . t('None') . '</em>');

    $rows[] = array(
      'class' => $class,
      'data' => $row,
    );
  }
  return theme('table', array('header' => $header, 'rows' => $rows));
}

/**
 * Process the specified attachment information and return the valid status
 * message and and row CSS class.
 *
 * @param integer $status Test status, PIFT_STATUS_*.
 * @param boolean $has_message Attachment has a message.
 * @return array Cell value and CSS class.
 */
function pift_attachment_process($status, $has_message) {
  $class = '';
  if ($status == PIFT_STATUS_QUEUE && $has_message) {
    $cell = t('Queued for re-testing');
    $class = 'pift-retest';
  }
  else if ($status == PIFT_STATUS_QUEUE) {
    $cell = t('Queued for testing');
  }
  elseif ($status == PIFT_STATUS_SENT) {
    $cell = t('Test request sent');
    $class = 'pift-retest';
  }
  elseif ($status > PIFT_STATUS_SENT) {
    $cell = t('Idle');
    $class = $status == PIFT_STATUS_PASS ? 'pift-pass' : 'pift-fail';
  }
  return array($cell, $class);
}