diff --git a/.github/pre-commit b/.github/pre-commit old mode 100755 new mode 100644 index 19ae29f1..e69de29b --- a/.github/pre-commit +++ b/.github/pre-commit @@ -1,3 +0,0 @@ -#!/bin/sh - -make fmt test-all diff --git a/console/atest-ui/gen.sh b/console/atest-ui/gen.sh old mode 100755 new mode 100644 diff --git a/e2e/entrypoint.sh b/e2e/entrypoint.sh old mode 100755 new mode 100644 diff --git a/e2e/start.sh b/e2e/start.sh old mode 100755 new mode 100644 diff --git a/pkg/generator/code_generator_test.go b/pkg/generator/code_generator_test.go index e06653ac..ab0bf89b 100644 --- a/pkg/generator/code_generator_test.go +++ b/pkg/generator/code_generator_test.go @@ -1,5 +1,5 @@ /* -Copyright 2023 API Testing Authors. +Copyright 2024 API Testing Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -63,6 +63,12 @@ func TestGenerators(t *testing.T) { assert.Equal(t, expectedJavaCode, result) }) + t.Run("python", func(t *testing.T) { + result, err := generator.GetCodeGenerator("python").Generate(nil, testcase) + assert.NoError(t, err) + assert.Equal(t, expectedPythonCode, result) + }) + formRequest := &atest.TestCase{Request: testcase.Request} formRequest.Request.Form = map[string]string{ "key": "value", @@ -79,6 +85,12 @@ func TestGenerators(t *testing.T) { assert.Equal(t, expectedFormRequestJavaCode, result, result) }) + t.Run("python form HTTP request", func(t *testing.T) { + result, err := generator.GetCodeGenerator("python").Generate(nil, formRequest) + assert.NoError(t, err) + assert.Equal(t, expectedFormRequestPythonCode, result, result) + }) + cookieRequest := &atest.TestCase{Request: formRequest.Request} cookieRequest.Request.Cookie = map[string]string{ "name": "value", @@ -95,6 +107,12 @@ func TestGenerators(t *testing.T) { assert.Equal(t, expectedCookieRequestJavaCode, result, result) }) + t.Run("python cookie HTTP request", func(t *testing.T) { + result, err := generator.GetCodeGenerator("python").Generate(nil, cookieRequest) + assert.NoError(t, err) + assert.Equal(t, expectedCookieRequestPythonCode, result, result) + }) + bodyRequest := &atest.TestCase{Request: testcase.Request} bodyRequest.Request.Body.Value = `{"key": "value"}` @@ -125,3 +143,12 @@ var expectedCookieRequestJavaCode string //go:embed testdata/expected_go_body_request_code.txt var expectedBodyRequestGoCode string + +//go:embed testdata/expected_python_code.txt +var expectedPythonCode string + +//go:embed testdata/expected_python_form_request_code.txt +var expectedFormRequestPythonCode string + +//go:embed testdata/expected_python_cookie_request_code.txt +var expectedCookieRequestPythonCode string diff --git a/pkg/generator/data/main.python.tpl b/pkg/generator/data/main.python.tpl new file mode 100644 index 00000000..1259f42e --- /dev/null +++ b/pkg/generator/data/main.python.tpl @@ -0,0 +1,56 @@ +/* +Copyright 2024 API Testing Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import io +import requests +from urllib.parse import urlencode + +def main(): + {{- if gt (len .Request.Form) 0 }} + data = {} + {{- range $key, $val := .Request.Form}} + data["{{$key}}"] = "{{$val}}" + encoded_data = urlencode(data) + {{- end}} + body = io.BytesIO(encoded_data.encode("utf-8")) + {{- else}} + body = io.BytesIO(b"{{.Request.Body.String}}") + {{- end}} + {{- range $key, $val := .Request.Header}} + headers = {"{{$key}}": "{{$val}}"} + {{- end}} + {{- if gt (len .Request.Cookie) 0 }} + {{- range $key, $val := .Request.Cookie}} + cookies = {"{{$key}}": "{{$val}}"} + {{- end}} + {{- end}} + {{- if gt (len .Request.Cookie) 0 }} + try: + req = requests.Request("{{.Request.Method}}", "{{.Request.API}}", headers=headers, cookies=cookies, data=body) + except requests.RequestException as e: + raise e + {{- else}} + try: + req = requests.Request("{{.Request.Method}}", "{{.Request.API}}", headers=headers, data=body) + except requests.RequestException as e: + raise e + {{- end}} + + resp = requests.Session().send(req.prepare()) + if resp.status_code != 200: + raise Exception("status code is not 200") + + data = resp.content + print(data.decode("utf-8")) + +if __name__ == "__main__": + main() diff --git a/pkg/generator/python_generator.go b/pkg/generator/python_generator.go new file mode 100644 index 00000000..9ed3180e --- /dev/null +++ b/pkg/generator/python_generator.go @@ -0,0 +1,54 @@ +/* +Copyright 2024 API Testing Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package generator + +import ( + "bytes" + "html/template" + "net/http" + + _ "embed" + + "github.com/linuxsuren/api-testing/pkg/testing" +) + +type pythonGenerator struct { +} + +func NewPythonGenerator() CodeGenerator { + return &pythonGenerator{} +} + +func (g *pythonGenerator) Generate(testSuite *testing.TestSuite, testcase *testing.TestCase) (result string, err error) { + if testcase.Request.Method == "" { + testcase.Request.Method = http.MethodGet + } + var tpl *template.Template + if tpl, err = template.New("python template").Parse(pythonTemplate); err == nil { + buf := new(bytes.Buffer) + if err = tpl.Execute(buf, testcase); err == nil { + result = buf.String() + } + } + return +} + +func init() { + RegisterCodeGenerator("python", NewPythonGenerator()) +} + +//go:embed data/main.python.tpl +var pythonTemplate string diff --git a/pkg/generator/testdata/expected_python_code.txt b/pkg/generator/testdata/expected_python_code.txt new file mode 100644 index 00000000..0e532874 --- /dev/null +++ b/pkg/generator/testdata/expected_python_code.txt @@ -0,0 +1,33 @@ +/* +Copyright 2024 API Testing Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import io +import requests +from urllib.parse import urlencode + +def main(): + body = io.BytesIO(b"") + headers = {"User-Agent": "atest"} + try: + req = requests.Request("GET", "https://www.baidu.com", headers=headers, data=body) + except requests.RequestException as e: + raise e + + resp = requests.Session().send(req.prepare()) + if resp.status_code != 200: + raise Exception("status code is not 200") + + data = resp.content + print(data.decode("utf-8")) + +if __name__ == "__main__": + main() diff --git a/pkg/generator/testdata/expected_python_cookie_request_code.txt b/pkg/generator/testdata/expected_python_cookie_request_code.txt new file mode 100644 index 00000000..d05f3f5d --- /dev/null +++ b/pkg/generator/testdata/expected_python_cookie_request_code.txt @@ -0,0 +1,37 @@ +/* +Copyright 2024 API Testing Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import io +import requests +from urllib.parse import urlencode + +def main(): + data = {} + data["key"] = "value" + encoded_data = urlencode(data) + body = io.BytesIO(encoded_data.encode("utf-8")) + headers = {"User-Agent": "atest"} + cookies = {"name": "value"} + try: + req = requests.Request("GET", "https://www.baidu.com", headers=headers, cookies=cookies, data=body) + except requests.RequestException as e: + raise e + + resp = requests.Session().send(req.prepare()) + if resp.status_code != 200: + raise Exception("status code is not 200") + + data = resp.content + print(data.decode("utf-8")) + +if __name__ == "__main__": + main() diff --git a/pkg/generator/testdata/expected_python_form_request_code.txt b/pkg/generator/testdata/expected_python_form_request_code.txt new file mode 100644 index 00000000..2180c44a --- /dev/null +++ b/pkg/generator/testdata/expected_python_form_request_code.txt @@ -0,0 +1,36 @@ +/* +Copyright 2024 API Testing Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import io +import requests +from urllib.parse import urlencode + +def main(): + data = {} + data["key"] = "value" + encoded_data = urlencode(data) + body = io.BytesIO(encoded_data.encode("utf-8")) + headers = {"User-Agent": "atest"} + try: + req = requests.Request("GET", "https://www.baidu.com", headers=headers, data=body) + except requests.RequestException as e: + raise e + + resp = requests.Session().send(req.prepare()) + if resp.status_code != 200: + raise Exception("status code is not 200") + + data = resp.content + print(data.decode("utf-8")) + +if __name__ == "__main__": + main() diff --git a/pkg/server/remote_server_test.go b/pkg/server/remote_server_test.go index 04242b71..c329dd27 100644 --- a/pkg/server/remote_server_test.go +++ b/pkg/server/remote_server_test.go @@ -1,5 +1,5 @@ /* -Copyright 2023 API Testing Authors. +Copyright 2024 API Testing Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -593,7 +593,7 @@ func TestCodeGenerator(t *testing.T) { t.Run("ListCodeGenerator", func(t *testing.T) { generators, err := server.ListCodeGenerator(ctx, &Empty{}) assert.NoError(t, err) - assert.Equal(t, 4, len(generators.Data)) + assert.Equal(t, 5, len(generators.Data)) }) t.Run("GenerateCode, no generator found", func(t *testing.T) {