Skip to content

Commit 4d2c968

Browse files
authored
Merge pull request #56 from PengfeiLi0218/master
Add API Test
2 parents 2bae114 + 24f1bd1 commit 4d2c968

File tree

6 files changed

+154
-11
lines changed

6 files changed

+154
-11
lines changed

.idea/encodings.xml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apitester/runtests/static/runtests/js/runtests.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,19 @@ $(function() {
2121
var alertType = 'success';
2222
var msg = '';
2323
var collapse = '';
24-
var text = `<pre>${escapeHTML(data['text'])}</pre>`;
24+
var text = "<pre>${escapeHTML(data['text'])}</pre>";
2525
if (!data['success']) {
2626
alertType = 'danger';
2727
msg = '<ul>';
2828
for (var i=0; i < data['messages'].length; i++) {
29-
msg += `<li>${data['messages'][i]}</li>`;
29+
msg += "<li>${data['messages'][i]}</li>";
3030
}
3131
msg += '</ul>';
3232
} else {
33-
collapse = `<button type="button" class="btn btn-xs btn-success pull-right" data-toggle="collapse" data-target="#${data['config']['operation_id']}" aria-expanded="false"><span class="glyphicon glyphicon-chevron-right"></span><span class="glyphicon glyphicon-chevron-down"></span></button>`;
34-
text = `<div id="${data['config']['operation_id']}" class="collapse">${text}</div>`;
33+
collapse = "<button type='button' class='btn btn-xs btn-success pull-right' data-toggle='collapse' data-target='#${data['config']['operation_id']}' aria-expanded='false'><span class='glyphicon glyphicon-chevron-right'></span><span class='glyphicon glyphicon-chevron-down'></span></button>";
34+
text = "<div id='${data['config']['operation_id']}' class='collapse'>${text}</div>";
3535
}
36-
var result = `<div class="alert alert-${alertType}"><div class="row"><div class="col-xs-10 col-sm-11">${data['config']['summary']}<br />${data['config']['urlpath']}<br />Took ${data['execution_time']} ms<br />${msg}</div><div class="col-xs-2 col-sm-1">${collapse}</div></div>${text}</div>`;
36+
var result ="<div class='alert alert-${alertType}'><div class='row'><div class='col-xs-10 col-sm-11'>${data['config']['summary']}<br />${data['config']['urlpath']}<br />Took ${data['execution_time']} ms<br />${msg}</div><div class='col-xs-2 col-sm-1'>${collapse}</div></div>${text}</div>";
3737
$(runner.find('.result')).append(result);
3838
});
3939
}
@@ -82,7 +82,7 @@ $(function() {
8282
});
8383

8484
$('.runner button.forSave').click(function() {
85-
var t = $(this)
85+
var t = $(this);
8686
var runner = $(this).parent().parent().parent();
8787
jsonBody = $(runner).find('textarea[name="params"]').val();
8888
operationId = $(runner).find('input[type="hidden"]').val();
@@ -106,7 +106,7 @@ $(function() {
106106
});
107107

108108
$('.runner button.forCopy').click(function() {
109-
var t = $(this)
109+
var t = $(this);
110110
var runner = $(this).parent().parent().parent();
111111
var item_list = $(runner).parent();
112112
jsonBody = $(runner).find('textarea[name="params"]').val();
@@ -154,14 +154,25 @@ $(function() {
154154
}
155155
});
156156

157+
$('#api-add').click(function () {
158+
var selected = $('#select-api').val();
159+
$.post('/runtests/add/api', {
160+
'operation_id': selected,
161+
'profile_id' : window.CURRENT_PROFILE_ID,
162+
'csrfmiddlewaretoken': window.CSRF
163+
}, function (response) {
164+
location.reload();
165+
});
166+
});
167+
157168
$('#select-testconfig').change(function() {
158169
var configPk = $(this).val();
159170
if (configPk) {
160-
location.href = `${URL_RUNTESTS_INDEX}${configPk}`;
171+
location.href = URL_RUNTESTS_INDEX+configPk;
161172
} else {
162173
location.href = URL_RUNTESTS_INDEX;
163174
}
164-
})
175+
});
165176

166177
var configPk = location.href.substr(location.href.lastIndexOf('/') + 1);
167178
if (configPk) {

apitester/runtests/templates/runtests/index.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,20 @@ <h2>{{ config.name }}</h2>
136136
<label>runs num: </label><input type="text" id="numRun" size="1" value=1 />
137137
</div>
138138
</div>
139+
140+
<div class="row">
141+
<div class="col-xs-12 col-sm-10">
142+
<select id="select-api" class="form-control">
143+
<option value="">Select test api ...</option>
144+
{% for swagger in swaggers %}
145+
<option value="{{ swagger }}">{{ swagger }}</option>
146+
{% endfor %}
147+
</select>
148+
</div>
149+
<div class="col-xs-12 col-sm-2">
150+
<a id="api-add" class="btn btn-success form-control">Add API</a>
151+
</div>
152+
</div>
139153
</div>
140154

141155
<ul class="hide" id="test-list">

apitester/runtests/urls.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
TestConfigurationCreateView,
1212
TestConfigurationUpdateView,
1313
TestConfigurationDeleteView,
14-
saveJsonBody,
14+
saveJsonBody, addAPI,
1515
copyJsonBody, deleteJsonBody)
1616

1717

@@ -28,6 +28,11 @@
2828
url(r'testconfig/add/$',
2929
TestConfigurationCreateView.as_view(),
3030
name='runtests-testconfig-add'),
31+
32+
url(r'add/api',
33+
addAPI,
34+
name='runtests-api-add'),
35+
3136
url(r'testconfig/(?P<pk>[0-9]+)/$',
3237
TestConfigurationUpdateView.as_view(),
3338
name='runtests-testconfig-update'),

apitester/runtests/views.py

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ def get_context_data(self, **kwargs):
160160
testconfigs = self.get_testconfigs(testconfig_pk)
161161
api = API(self.request.session.get('obp'))
162162

163+
swaggers = []
163164
if 'selected' in testconfigs and testconfigs['selected']:
164165
api_version = testconfigs['selected'].api_version
165-
166166
if re.match("^[1-3]\.[0-9]\.[0-9]$", api_version) is None:
167167
api_version = settings.API_VERSION
168168

@@ -174,22 +174,27 @@ def get_context_data(self, **kwargs):
174174
for path, data in swagger['paths'].items():
175175
if 'get' in data:
176176
call = self.get_post_or_update('get', testconfigs, testconfig_pk, path, data, swagger)
177+
swaggers.append(data['get']['operationId'])
177178
calls = calls+call
178179
if 'post' in data:
179180
call = self.get_post_or_update('post', testconfigs, testconfig_pk, path, data, swagger)
181+
swaggers.append(data['post']['operationId'])
180182
calls = calls + call
181183

182184
if 'put' in data:
183185
call = self.get_post_or_update('put', testconfigs, testconfig_pk, path, data, swagger)
186+
swaggers.append(data['put']['operationId'])
184187
calls = calls + call
185188

186189
if 'delete' in data:
187190
call = self.get_post_or_update('delete', testconfigs, testconfig_pk, path, data, swagger)
191+
swaggers.append(data['delete']['operationId'])
188192
calls = calls + call
189193

190194
calls = sorted(calls, key=lambda item: item['order'], reverse=False)
191195

192196
context.update({
197+
'swaggers':swaggers,
193198
'calls': calls,
194199
'testconfigs': testconfigs,
195200
'testconfig_pk': testconfig_pk,
@@ -473,3 +478,101 @@ def deleteJsonBody(request):
473478
profile.save()
474479

475480
return JsonResponse({'state': True})
481+
482+
def api_replace(string, match, value):
483+
"""Helper to replace format strings from the API"""
484+
# API sometimes uses '{match}' or 'match' to denote variables
485+
return string. \
486+
replace('{{{}}}'.format(match), value). \
487+
replace(match, value)
488+
489+
def get_urlpath(testconfig, path):
490+
"""
491+
Gets a URL path
492+
where placeholders in given path are replaced by values from testconfig
493+
"""
494+
urlpath = path
495+
for (index, match) in enumerate(URLPATH_REPLACABLES):
496+
value = getattr(testconfig, match.lower())
497+
if value:
498+
urlpath = api_replace(urlpath, match, value)
499+
else:
500+
urlpath = api_replace(urlpath, match, URLPATH_DEFAULT[index])
501+
502+
return urlpath
503+
504+
def addAPI(request):
505+
operation_id = request.POST.get('operation_id')
506+
profile_id = request.POST.get('profile_id')
507+
508+
testconfig = TestConfiguration.objects.get(
509+
owner=request.user,
510+
pk=profile_id,
511+
)
512+
513+
api = API(request.session.get('obp'))
514+
api_version = settings.API_VERSION
515+
swagger = api.get_swagger(api_version)
516+
517+
request_body = {}
518+
urlpath = ''
519+
params = ''
520+
remark = ''
521+
522+
for path, data in swagger['paths'].items():
523+
if 'get' in data:
524+
method = 'get'
525+
if 'post' in data:
526+
method = 'post'
527+
if 'put' in data:
528+
method = 'put'
529+
if 'delete' in data:
530+
method = 'delete'
531+
532+
if data[method]['operationId']==operation_id:
533+
urlpath = get_urlpath(testconfig, path)
534+
remark = data[method]['summary']
535+
if method == 'post' or method == 'put':
536+
request_body = {}
537+
definition = data[method]['parameters'][0] if len(data[method]['parameters']) > 0 else None
538+
definition = definition['schema']['$ref'][14:]
539+
params = swagger['definitions'][definition]
540+
if len(params["required"]) > 0:
541+
for field in params["required"]:
542+
# Match Profile variables
543+
field_names = [ f.name for f in TestConfiguration._meta.fields]
544+
if field in field_names:
545+
request_body[field] = getattr(testconfig, field)
546+
else:
547+
try:
548+
request_body[field] = params["properties"][field].get("example", "")
549+
except:
550+
request_body[field] = None
551+
params = json.dumps(request_body, indent=4)
552+
553+
#if not re.match("^{.*}$", json_body):
554+
# json_body = "{{{}}}".format(json_body)
555+
556+
profile_list = ProfileOperation.objects.filter(
557+
operation_id=operation_id,
558+
profile_id=profile_id
559+
)
560+
561+
if profile_list is None or len(profile_list)==0:
562+
replica_id = 1
563+
else:
564+
replica_id = max([profile.replica_id for profile in profile_list])+1
565+
566+
ProfileOperation.objects.create(profile_id = profile_id, operation_id = operation_id, json_body = params, order = 100, urlpath = urlpath, remark=remark, replica_id = replica_id, is_deleted=0)
567+
568+
return JsonResponse({
569+
'state': True,
570+
'profile_id': profile_id,
571+
'operation_id': operation_id,
572+
'json_body': params,
573+
'order': 100,
574+
'urlpath': urlpath,
575+
'remark': remark,
576+
'replica_id': replica_id,
577+
'is_deleted': 0
578+
})

0 commit comments

Comments
 (0)