Skip to content

Commit c9718ad

Browse files
committed
Add mechanism to create a Session
1 parent f56b427 commit c9718ad

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

code_submitter/server.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,20 @@ async def upload(request: Request) -> Response:
122122
)
123123

124124

125+
@requires(['authenticated', BLUESHIRT_SCOPE])
126+
async def create_session(request: Request) -> Response:
127+
user: User = request.user
128+
form = await request.form()
129+
130+
await utils.create_session(database, form['name'], by_username=user.username)
131+
132+
return RedirectResponse(
133+
request.url_for('homepage'),
134+
# 302 so that the browser switches to GET
135+
status_code=302,
136+
)
137+
138+
125139
@requires(['authenticated', BLUESHIRT_SCOPE])
126140
async def download_submissions(request: Request) -> Response:
127141
buffer = io.BytesIO()
@@ -142,6 +156,7 @@ async def download_submissions(request: Request) -> Response:
142156
routes = [
143157
Route('/', endpoint=homepage, methods=['GET']),
144158
Route('/upload', endpoint=upload, methods=['POST']),
159+
Route('/create-session', endpoint=create_session, methods=['POST']),
145160
Route('/download-submissions', endpoint=download_submissions, methods=['GET']),
146161
]
147162

templates/index.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,22 @@ <h1>Virtual Competition Code Submission</h1>
3939
</a>
4040
</div>
4141
</div>
42+
<div class="row">
43+
<div class="col-sm-6">
44+
<form
45+
action="{{ url_for('create_session') }}"
46+
enctype="multipart/form-data"
47+
method="POST"
48+
>
49+
<h4>Create a new session</h4>
50+
<div class="form-group row">
51+
<label class="col-sm-2 col-form-label" for="name">Name</label>
52+
<input class="col-sm-6" type="text" name="name" required />
53+
</div>
54+
<button class="btn btn-primary" type="submit">Create</button>
55+
</form>
56+
</div>
57+
</div>
4258
{% endif %}
4359
<div class="row">
4460
{% if request.user.team %}

tests/tests_app.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
from unittest import mock
55

66
import test_utils
7+
from sqlalchemy.sql import select
78
from starlette.testclient import TestClient
89

9-
from code_submitter.tables import Archive, ChoiceHistory
10+
from code_submitter.tables import Archive, Session, ChoiceHistory
1011

1112

1213
class AppTests(test_utils.DatabaseTestCase):
@@ -277,6 +278,42 @@ def test_upload_archive_without_robot_py(self) -> None:
277278
)
278279
self.assertEqual([], choices, "Should not have created a choice")
279280

281+
def test_create_session_requires_blueshirt(self) -> None:
282+
response = self.session.post(
283+
self.url_for('create_session'),
284+
data={'name': "Test session"},
285+
)
286+
self.assertEqual(403, response.status_code)
287+
288+
def test_create_session(self) -> None:
289+
self.session.auth = ('blueshirt', 'blueshirt')
290+
291+
response = self.session.post(
292+
self.url_for('create_session'),
293+
data={'name': "Test session"},
294+
)
295+
self.assertEqual(302, response.status_code)
296+
self.assertEqual(
297+
self.url_for('homepage'),
298+
response.headers['location'],
299+
)
300+
301+
session, = self.await_(
302+
self.database.fetch_all(select([
303+
Session.c.name,
304+
Session.c.username,
305+
])),
306+
)
307+
308+
self.assertEqual(
309+
{
310+
'name': 'Test session',
311+
'username': 'blueshirt',
312+
},
313+
dict(session),
314+
"Should have created a session",
315+
)
316+
280317
def test_no_download_link_for_non_blueshirt(self) -> None:
281318
download_url = self.url_for('download_submissions')
282319

0 commit comments

Comments
 (0)