Skip to content

Commit

Permalink
Use django URL names in test suite (#730)
Browse files Browse the repository at this point in the history
* namespaces urls by app

* refactor urls patterns and test for wasteline views

* refactor core app tests to use named urls

* refactor rcrasite urls to use named urls

remove 'rcra' from our REST API endpoint URLs

* refactor profile app endpoints to use namespaces and named endpoints

* refactor manifest app to use namespaces and named endpoints

* refactor org app to use namespaces and named endpoints

* refactor site app to use namespaces and named endpoints
  • Loading branch information
dpgraham4401 authored Jun 14, 2024
1 parent e57bb47 commit 174b161
Show file tree
Hide file tree
Showing 29 changed files with 334 additions and 210 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('Manifest Status Field', () => {
}),
});
server.use(
http.get(`${API_BASE_URL}/api/user/profile`, () => {
http.get(`${API_BASE_URL}/api/profile`, () => {
return HttpResponse.json(
{
...createMockProfileResponse({
Expand Down Expand Up @@ -97,7 +97,7 @@ describe('Manifest Status Field', () => {
}),
});
server.use(
http.get(`${API_BASE_URL}/api/user/profile`, () => {
http.get(`${API_BASE_URL}/api/profile`, () => {
return HttpResponse.json(
{
...createMockProfileResponse({
Expand Down Expand Up @@ -131,7 +131,7 @@ describe('Manifest Status Field', () => {
}),
});
server.use(
http.get(`${API_BASE_URL}/api/user/profile`, () => {
http.get(`${API_BASE_URL}/api/profile`, () => {
return HttpResponse.json(
{
...createMockProfileResponse({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,17 @@ const mockRcrainfoSite2 = createMockRcrainfoSite({ epaSiteId: mockRcrainfoSite2I
const mockRcraSite1 = createMockRcrainfoSite({ epaSiteId: mockRcraSite1Id });
const mockRcraSite2 = createMockRcrainfoSite({ epaSiteId: mockRcraSite2Id });
export const mockHandlerSearches = [
http.get(`${API_BASE_URL}/api/rcra/site/search`, () => {
http.get(`${API_BASE_URL}/api/rcrasite/search`, () => {
return HttpResponse.json([mockRcraSite1, mockRcraSite2], { status: 200 });
}),
http.get(`${API_BASE_URL}/api/rcra/handler/search`, () => {
// ToDo: remove this
http.get(`${API_BASE_URL}/api/rcrainfo/rcrasite/search`, () => {
return HttpResponse.json([mockRcrainfoSite1, mockRcrainfoSite2], { status: 200 });
}),
http.get(`${API_BASE_URL}/api/user/profile`, () => {
http.get(`${API_BASE_URL}/api/profile`, () => {
return HttpResponse.json({ ...mockProfile }, { status: 200 });
}),
http.post(`${API_BASE_URL}/api/rcra/handler/search`, () => {
http.post(`${API_BASE_URL}/api/rcrainfo/rcrasite/search`, () => {
return HttpResponse.json([mockRcrainfoSite1, mockRcrainfoSite2], { status: 200 });
}),
];
Expand Down Expand Up @@ -72,7 +73,7 @@ describe('HandlerSearchForm', () => {
});
test('retrieves rcra sites from haztrak if org not rcrainfo integrated', async () => {
server.use(
http.get(`${API_BASE_URL}/api/user/profile`, () => {
http.get(`${API_BASE_URL}/api/profile`, () => {
return HttpResponse.json(
{
...mockProfile,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const testTaskID = 'testTaskId';

const server = setupServer(...mockUserEndpoints);
server.use(
http.post(`${API_BASE_URL}rcra/manifest/emanifest/sync`, () => {
http.post(`${API_BASE_URL}manifest/emanifest/sync`, () => {
// Mock Sync Site Manifests response
return HttpResponse.json(
{
Expand Down
2 changes: 1 addition & 1 deletion client/src/features/NewManifest/NewManifest.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const mockProfile: HaztrakProfileResponse = {

const server = setupServer(...mockUserEndpoints);
server.use(
http.get(`${API_BASE_URL}/api/user/profile`, () => {
http.get(`${API_BASE_URL}/api/profile`, () => {
return HttpResponse.json({ ...mockProfile }, { status: 200 });
})
);
Expand Down
2 changes: 1 addition & 1 deletion client/src/hooks/useUserSiteIds/useUserSiteIds.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('useUserSiteId hook', () => {
}),
});
server.use(
http.get(`${API_BASE_URL}/api/user/profile`, () => {
http.get(`${API_BASE_URL}/api/profile`, () => {
return HttpResponse.json(
{
...createMockProfileResponse({
Expand Down
26 changes: 13 additions & 13 deletions client/src/store/htApi.slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,37 +81,37 @@ export const haztrakApi = createApi({
// Note: build.query<ReturnType, ArgType>
searchRcrainfoSites: build.query<Array<RcraSite>, RcrainfoSiteSearch>({
query: (data: RcrainfoSiteSearch) => ({
url: 'rcra/handler/search',
url: 'rcrainfo/rcrasite/search',
method: 'post',
data: data,
}),
}),
searchRcraSites: build.query<Array<RcraSite>, RcrainfoSiteSearch>({
query: (data: RcrainfoSiteSearch) => ({
url: 'rcra/site/search',
url: 'rcrasite/search',
method: 'get',
params: { epaId: data.siteId, siteType: data.siteType },
}),
}),
getRcrainfoSite: build.query<RcraSite, string | null>({
query: (epaSiteId) => ({
url: `rcra/handler/${epaSiteId}`,
url: `rcrasite/${epaSiteId}`,
method: 'get',
}),
}),
getTaskStatus: build.query<TaskStatus, string>({
query: (taskId) => ({ url: `task/${taskId}`, method: 'get' }),
}),
getFedWasteCodes: build.query<Array<Code>, void>({
query: () => ({ url: 'rcra/waste/code/federal', method: 'get' }),
query: () => ({ url: 'waste/code/federal', method: 'get' }),
providesTags: ['code'],
}),
getStateWasteCodes: build.query<Array<Code>, string>({
query: (state) => ({ url: `rcra/waste/code/state/${state}`, method: 'get' }),
query: (state) => ({ url: `waste/code/state/${state}`, method: 'get' }),
providesTags: ['code'],
}),
getDotIdNumbers: build.query<Array<string>, string>({
query: (id) => ({ url: 'rcra/waste/dot/id', method: 'get', params: { q: id } }),
query: (id) => ({ url: 'waste/dot/id', method: 'get', params: { q: id } }),
providesTags: ['code'],
}),
getOrgSites: build.query<Array<HaztrakSite>, string>({
Expand All @@ -128,50 +128,50 @@ export const haztrakApi = createApi({
}),
getMTN: build.query<Array<MtnDetails>, string | undefined>({
query: (siteId) => ({
url: siteId ? `rcra/manifest/mtn/${siteId}` : 'rcra/manifest/mtn',
url: siteId ? `manifest/mtn/${siteId}` : 'manifest/mtn',
method: 'get',
}),
providesTags: ['manifest'],
}),
getManifest: build.query<Manifest, string>({
query: (mtn) => ({ url: `rcra/manifest/${mtn}`, method: 'get' }),
query: (mtn) => ({ url: `manifest/${mtn}`, method: 'get' }),
providesTags: ['manifest'],
}),
createManifest: build.mutation<Manifest, Manifest>({
query: (data) => ({
url: 'rcra/manifest',
url: 'manifest',
method: 'POST',
data,
}),
invalidatesTags: ['manifest'],
}),
updateManifest: build.mutation<Manifest, { mtn: string; manifest: Manifest }>({
query: ({ mtn, manifest }) => ({
url: `rcra/manifest/${mtn}`,
url: `manifest/${mtn}`,
method: 'PUT',
data: manifest,
}),
invalidatesTags: ['manifest'],
}),
saveEManifest: build.mutation<TaskResponse, Manifest>({
query: (data) => ({
url: 'rcra/manifest/emanifest',
url: 'manifest/emanifest',
method: 'POST',
data,
}),
invalidatesTags: ['manifest'],
}),
syncEManifest: build.mutation<TaskResponse, string>({
query: (siteId) => ({
url: 'rcra/manifest/emanifest/sync',
url: 'manifest/emanifest/sync',
method: 'POST',
data: { siteId: siteId },
}),
invalidatesTags: ['manifest'],
}),
signEManifest: build.mutation<TaskResponse, QuickerSignature>({
query: (signature) => ({
url: 'rcra/manifest/emanifest/sign',
url: 'manifest/emanifest/sign',
method: 'POST',
data: signature,
}),
Expand Down
8 changes: 4 additions & 4 deletions client/src/store/userSlice/user.slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export const userApi = haztrakApi.injectEndpoints({
}),
getProfile: build.query<ProfileSlice, void>({
query: () => ({
url: 'user/profile',
url: 'profile',
method: 'GET',
}),
providesTags: ['profile'],
Expand All @@ -135,7 +135,7 @@ export const userApi = haztrakApi.injectEndpoints({
}),
getRcrainfoProfile: build.query<RcrainfoProfileState, string>({
query: (username) => ({
url: `user/rcrainfo-profile/${username}`,
url: `rcrainfo-profile/${username}`,
method: 'GET',
}),
providesTags: ['rcrainfoProfile'],
Expand All @@ -154,15 +154,15 @@ export const userApi = haztrakApi.injectEndpoints({
}),
updateRcrainfoProfile: build.mutation<any, { username: string; data: any }>({
query: (data) => ({
url: `user/rcrainfo-profile/${data.username}`,
url: `rcrainfo-profile/${data.username}`,
method: 'PUT',
data: data.data,
}),
invalidatesTags: ['rcrainfoProfile'],
}),
syncRcrainfoProfile: build.mutation<TaskResponse, void>({
query: () => ({
url: `user/rcrainfo-profile/sync`,
url: `rcrainfo-profile/sync`,
method: 'POST',
}),
invalidatesTags: ['rcrainfoProfile'],
Expand Down
8 changes: 4 additions & 4 deletions client/src/test-utils/mock/mockManifestEndpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,26 @@ const generateRandomMTN = (): string => {

export const mockManifestEndpoints = [
/** mock GET Manifest*/
http.get(`${API_BASE_URL}/api/rcra/manifest/${mockMTN}`, (info) => {
http.get(`${API_BASE_URL}/api/manifest/${mockMTN}`, (info) => {
return HttpResponse.json(createMockManifest(), { status: 200 });
}),
/** Mock create local Manifests*/
http.post(`${API_BASE_URL}/api/rcra/manifest`, async (info) => {
http.post(`${API_BASE_URL}/api/manifest`, async (info) => {
let bodyManifest = (await info.request.json()) as Manifest;
if (!bodyManifest.manifestTrackingNumber)
bodyManifest.manifestTrackingNumber = `${generateRandomMTN()}DFT`.padEnd(9, '0');
return HttpResponse.json(bodyManifest, { status: 200 });
}),
/** Mock update local Manifests*/
http.put(`${API_BASE_URL}/api/rcra/manifest/:mtn`, async (info) => {
http.put(`${API_BASE_URL}/api/manifest/:mtn`, async (info) => {
const { mtn } = info.params;
let bodyManifest = (await info.request.json()) as Manifest;
if (bodyManifest.manifestTrackingNumber !== mtn)
return HttpResponse.json(null, { status: 400 });
return HttpResponse.json(bodyManifest, { status: 200 });
}),
/** list of manifests ('My Manifests' feature and a site's manifests)*/
http.get(`${API_BASE_URL}/api/rcra/mtn*`, (info) => {
http.get(`${API_BASE_URL}/api/mtn*`, (info) => {
const mockManifestArray = [
createMockManifest(),
createMockManifest({ manifestTrackingNumber: '987654321ELC', status: 'Pending' }),
Expand Down
4 changes: 2 additions & 2 deletions client/src/test-utils/mock/mockUserEndpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const mockUserEndpoints = [
return HttpResponse.json({ ...user, ...info.request.body }, { status: 200 });
}),
/** GET Profile */
http.get(`${API_BASE_URL}/api/user/profile`, () => {
http.get(`${API_BASE_URL}/api/profile`, () => {
return HttpResponse.json({ ...createMockProfileResponse() }, { status: 200 });
}),
/** Login */
Expand All @@ -34,7 +34,7 @@ export const mockUserEndpoints = [
);
}),
/** GET RCRAInfo profile */
http.get(`${API_BASE_URL}/api/user/rcrainfo-profile/:username`, (info) => {
http.get(`${API_BASE_URL}/api/rcrainfo-profile/:username`, (info) => {
const { username } = info.params;
// @ts-ignore
const rcrainfoProfile = createMockRcrainfoProfileResponse({ user: username ?? '' });
Expand Down
4 changes: 2 additions & 2 deletions client/src/test-utils/mock/mockWasteEndpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { mockDotIdNumbers, mockFederalWasteCodes } from 'test-utils/fixtures/moc
const API_BASE_URL = import.meta.env.VITE_HT_API_URL;
export const mockWasteEndpoints = [
/** GET User */
http.get(`${API_BASE_URL}/api/rcra/waste/code/federal`, (info) => {
http.get(`${API_BASE_URL}/api/waste/code/federal`, (info) => {
return HttpResponse.json(mockFederalWasteCodes, { status: 200 });
}),
http.get(`${API_BASE_URL}/api/rcra/waste/dot/id`, (info) => {
http.get(`${API_BASE_URL}/api/waste/dot/id`, (info) => {
const url = new URL(info.request.url);
const query = url.searchParams.get('q');
let filteredIds: Array<string> = [];
Expand Down
6 changes: 4 additions & 2 deletions server/apps/core/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from django.core.exceptions import PermissionDenied
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.core.exceptions import ValidationError as DjangoValidationError
from django.http import Http404
from rest_framework import exceptions
from rest_framework.exceptions import APIException
from rest_framework.exceptions import APIException, NotFound
from rest_framework.serializers import as_serializer_error
from rest_framework.views import exception_handler

Expand Down Expand Up @@ -32,6 +32,8 @@ def haztrak_exception_handler(exc, context):
exc = exceptions.PermissionDenied()
case Http404():
exc = exceptions.NotFound()
case ObjectDoesNotExist():
exc = NotFound()
case KeyError():
exc = exceptions.ParseError()
case ValueError():
Expand Down
64 changes: 64 additions & 0 deletions server/apps/core/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from unittest import mock

import pytest
from django.test.client import Client
from rest_framework import status
from rest_framework.reverse import reverse
from rest_framework.test import APIRequestFactory, force_authenticate

from apps.core.views import LaunchExampleTaskView, TaskStatusView


class TestUserViews:
@pytest.fixture
def factory(self):
return APIRequestFactory()

@pytest.fixture
def user(self, user_factory):
return user_factory()

def test_returns_user_details(self, factory, user):
c = Client()
c.force_login(user)
response = c.get(reverse("core:user:details"))
data: dict = response.json()
assert response.status_code == 200
assert user.username in data.values()
assert user.first_name in data.values()


class TestLaunchExampleTaskView:
@pytest.fixture
def factory(self):
return APIRequestFactory()

def test_successful_launch(self, factory):
with mock.patch("apps.core.views.launch_example_task") as mock_task:
request = factory.get(reverse("core:task:example"))
mock_task.return_value = "123"
response = LaunchExampleTaskView.as_view()(request)
assert response.status_code == status.HTTP_200_OK
assert response.data == {"taskId": "123"}


class TestTaskStatusView:
@pytest.fixture
def factory(self):
return APIRequestFactory()

def test_successful_get_status(self, factory, user_factory):
user = user_factory()
task_id = "123"
request = factory.get(reverse("core:task:status", args=[task_id]))
force_authenticate(request, user)
with mock.patch("apps.core.views.get_task_status") as mock_task:
mock_task.return_value = {
"status": "PENDING",
"name": "task_name",
"result": None,
"taskId": task_id,
}
response = TaskStatusView.as_view()(request, task_id=task_id)
assert response.status_code == status.HTTP_200_OK
assert "PENDING" in response.data.values()
Loading

0 comments on commit 174b161

Please sign in to comment.