Example #1
0
def test_delete_search():
    # Arrange: create a codelist with searches
    owner = UserFactory()
    cl = actions.create_codelist(
        owner=owner, name="Test Codelist", coding_system_id="snomedct"
    )
    s1 = actions.create_search(
        codelist=cl, term="synchronised", codes=["1068181000000106"]
    )
    s2 = actions.create_search(
        codelist=cl, term="swimming", codes=["1067731000000107", "1068181000000106"]
    )

    # Act: delete the search for "swimming"
    actions.delete_search(search=s2)

    # Assert...
    # that the codelist has only 1 search
    assert cl.searches.count() == 1
    # that the codelist has only 1 code
    assert cl.codes.count() == 1

    # Arrange: recreate the search for "swimming"
    actions.create_search(
        codelist=cl, term="swimming", codes=["1067731000000107", "1068181000000106"]
    )

    # Act: delete the search for "synchronised"
    actions.delete_search(search=s1)

    # Assert...
    # that the codelist has only 1 search
    assert cl.searches.count() == 1
    # that the codelist still has both codes
    assert cl.codes.count() == 2
Example #2
0
def test_codelistupdate_with_duplicate_name(rf):
    project = ProjectFactory()

    CodelistFactory(name="Existing Codelist", project=project)
    codelist = CodelistFactory(project=project)

    data = {
        "project": codelist.project.slug,
        "name": "Existing Codelist",
        "coding_system_id": "snomedct",
        "description": "This is a test CHANGED",
        "methodology": "This is how we did it",
        "reference-TOTAL_FORMS": "0",
        "reference-INITIAL_FORMS": "0",
        "reference-MIN_NUM_FORMS": "0",
        "reference-MAX_NUM_FORMS": "1000",
        "signoff-TOTAL_FORMS": "0",
        "signoff-INITIAL_FORMS": "0",
        "signoff-MIN_NUM_FORMS": "0",
        "signoff-MAX_NUM_FORMS": "1000",
    }

    request = rf.post("/", data=data)
    request.user = UserFactory()
    response = CodelistUpdate.as_view()(
        request, project_slug=codelist.project.slug, codelist_slug=codelist.slug
    )

    assert response.status_code == 200

    # confirm we have errors from the codelist form
    assert response.context_data["codelist_form"].errors
Example #3
0
def test_versionupdate_success(rf):
    version = create_draft_version()

    assert version.codelist.versions.count() == 1

    csv_data = "code,description\n1068181000000106, Injury whilst synchronised swimming (disorder)"
    data = {
        "csv_data": csv_builder(csv_data),
    }

    request = rf.post("/", data=data)
    request.user = UserFactory()
    response = VersionUpdate.as_view()(
        request,
        project_slug=version.codelist.project.slug,
        codelist_slug=version.codelist.slug,
        qualified_version_str=version.qualified_version_str,
    )

    assert response.status_code == 302
    assert (
        response.url
        == f"/codelist/{version.codelist.project.slug}/{version.codelist.slug}/2020-07-23-draft/"
    )

    assert version.codelist.versions.count() == 1
Example #4
0
def test_codelistcreate_success(rf):
    project = ProjectFactory()
    signoff_user = UserFactory()

    assert project.codelists.count() == 0

    csv_data = "code,description\n1067731000000107,Injury whilst swimming (disorder)"
    data = {
        "name": "Test Codelist",
        "coding_system_id": "snomedct",
        "description": "This is a test",
        "methodology": "This is how we did it",
        "csv_data": csv_builder(csv_data),
        "reference-TOTAL_FORMS": "1",
        "reference-INITIAL_FORMS": "0",
        "reference-MIN_NUM_FORMS": "0",
        "reference-MAX_NUM_FORMS": "1000",
        "reference-0-text": "foo",
        "reference-0-url": "http://example.com",
        "signoff-TOTAL_FORMS": "1",
        "signoff-INITIAL_FORMS": "0",
        "signoff-MIN_NUM_FORMS": "0",
        "signoff-MAX_NUM_FORMS": "1000",
        "signoff-0-user": signoff_user.username,
        "signoff-0-date": "2020-01-23",
    }

    request = rf.post("/", data=data)
    request.user = UserFactory()
    response = CodelistCreate.as_view()(request, project_slug=project.slug)

    assert response.status_code == 302
    assert response.url == f"/codelist/{project.slug}/test-codelist/"

    assert project.codelists.count() == 1
    codelist = project.codelists.first()
    assert codelist.name == "Test Codelist"

    # we should have one reference to example.com
    assert codelist.references.count() == 1
    ref = codelist.references.first()
    assert ref.url == "http://example.com"

    # we should have one signoff by signoff user
    assert codelist.signoffs.count() == 1
    signoff = codelist.signoffs.first()
    assert signoff.user == signoff_user
Example #5
0
def test_versioncreate_unknown_codelist(rf):
    codelist = CodelistFactory()

    request = rf.get("/")
    request.user = UserFactory()

    with pytest.raises(Http404):
        VersionCreate.as_view()(
            request, project_slug=codelist.project.slug, codelist_slug="test"
        )
Example #6
0
def test_versionupdate_unknown_version(rf):
    codelist = CodelistFactory()

    request = rf.get("/")
    request.user = UserFactory()
    with pytest.raises(Http404):
        VersionUpdate.as_view()(
            request,
            project_slug=codelist.project.slug,
            codelist_slug=codelist.slug,
            qualified_version_str="test",
        )
Example #7
0
def test_versionpublish_unknown_version(rf):
    codelist = CodelistFactory()

    request = rf.post("/")
    request.user = UserFactory()
    with pytest.raises(Http404):
        version_publish(
            request,
            project_slug=codelist.project.slug,
            codelist_slug=codelist.slug,
            qualified_version_str="test",
        )
Example #8
0
def test_versioncreate_missing_field(rf):
    codelist = create_published_version().codelist

    request = rf.post("/", data={})
    request.user = UserFactory()
    response = VersionCreate.as_view()(
        request, project_slug=codelist.project.slug, codelist_slug=codelist.slug
    )

    assert response.status_code == 200
    assert "form" in response.context_data
    assert len(response.context_data["form"].errors) == 1
    assert "csv_data" in response.context_data["form"].errors
Example #9
0
def test_codelistcreate_invalid_post(rf):
    project = ProjectFactory()
    signoff_user = UserFactory()

    assert project.codelists.count() == 0

    csv_data = "code,description\n1067731000000107,Injury whilst swimming (disorder)"

    # missing signoff-0-date
    data = {
        "name": "Test Codelist",
        "coding_system_id": "snomedct",
        "description": "This is a test",
        "methodology": "This is how we did it",
        "csv_data": csv_builder(csv_data),
        "reference-TOTAL_FORMS": "1",
        "reference-INITIAL_FORMS": "0",
        "reference-MIN_NUM_FORMS": "0",
        "reference-MAX_NUM_FORMS": "1000",
        "reference-0-text": "foo",
        "reference-0-url": "http://example.com",
        "signoff-TOTAL_FORMS": "1",
        "signoff-INITIAL_FORMS": "0",
        "signoff-MIN_NUM_FORMS": "0",
        "signoff-MAX_NUM_FORMS": "1000",
        "signoff-0-user": signoff_user.username,
    }

    request = rf.post("/", data=data)
    request.user = UserFactory()
    response = CodelistCreate.as_view()(request, project_slug=project.slug)

    # we're returning an HTML response when there are errors so check we don't
    # receive a redirect code
    assert response.status_code == 200

    # confirm we have errors from the signoff formset
    assert response.context_data["signoff_formset"].errors
Example #10
0
def test_codelist(client, tennis_elbow_codelist):
    owner = UserFactory()
    cl = actions.create_codelist(
        owner=owner, name="Elbows", coding_system_id="snomedct"
    )
    search_results = do_search(cl.coding_system, "elbow")
    actions.create_search(codelist=cl, term="elbow", codes=search_results["all_codes"])

    client.force_login(owner)

    rsp = client.get(f"/builder/{owner.username}/{cl.slug}/")

    assert rsp.status_code == 200
    assert b"Elbows" in rsp.content
Example #11
0
def test_create_codelist():
    # Arrange: create a user
    owner = UserFactory()

    # Act: create a codelist
    cl = actions.create_codelist(
        owner=owner, name="Test Codelist", coding_system_id="snomedct"
    )

    # Assert...
    # that a codelist's attributes have been set
    assert cl.owner == owner
    assert cl.name == "Test Codelist"
    assert cl.slug == "test-codelist"
    assert cl.coding_system_id == "snomedct"
Example #12
0
def test_versionupdate_form_error(rf):
    version = create_published_version()

    request = rf.post("/", data={})
    request.user = UserFactory()
    response = VersionUpdate.as_view()(
        request,
        project_slug=version.codelist.project.slug,
        codelist_slug=version.codelist.slug,
        qualified_version_str=version.qualified_version_str,
    )

    assert response.status_code == 200
    assert "form" in response.context_data
    assert "csv_data" in response.context_data["form"].errors
Example #13
0
def test_versionpublish_success(rf):
    version = create_draft_version()

    request = rf.post("/")
    request.user = UserFactory()
    response = version_publish(
        request,
        project_slug=version.codelist.project.slug,
        codelist_slug=version.codelist.slug,
        qualified_version_str=version.qualified_version_str,
    )

    assert response.status_code == 302

    version.refresh_from_db()

    assert response.url == version.get_absolute_url()
    assert not version.is_draft
Example #14
0
def test_versionupdate_draft_mismatch(rf):
    version = create_published_version()

    # set the version string to that of a draft
    qualified_version_str = f"{version.qualified_version_str}-draft"

    request = rf.get("/")
    request.user = UserFactory()
    response = VersionUpdate.as_view()(
        request,
        project_slug=version.codelist.project.slug,
        codelist_slug=version.codelist.slug,
        qualified_version_str=qualified_version_str,
    )

    # we should get redirected to the Version page
    assert response.status_code == 302
    assert response.url == version.get_absolute_url()
Example #15
0
def test_codelistcreate_with_duplicate_name(rf):
    project = ProjectFactory()

    create_codelist(
        project=project,
        name="Test",
        coding_system_id="snomedct",
        description="This is a test",
        methodology="This is how we did it",
        csv_data="code,description\n1067731000000107,Injury whilst swimming (disorder)",
    )

    assert project.codelists.count() == 1

    csv_data = "code,description\n1067731000000107,Injury whilst swimming (disorder)"
    data = {
        "name": "Test",
        "coding_system_id": "snomedct",
        "description": "This is a test",
        "methodology": "This is how we did it",
        "csv_data": csv_builder(csv_data),
        "reference-TOTAL_FORMS": "0",
        "reference-INITIAL_FORMS": "0",
        "reference-MIN_NUM_FORMS": "0",
        "reference-MAX_NUM_FORMS": "1000",
        "signoff-TOTAL_FORMS": "0",
        "signoff-INITIAL_FORMS": "0",
        "signoff-MIN_NUM_FORMS": "0",
        "signoff-MAX_NUM_FORMS": "1000",
    }

    request = rf.post("/", data=data)
    request.user = UserFactory()
    response = CodelistCreate.as_view()(request, project_slug=project.slug)

    assert project.codelists.count() == 1

    # we're returning an HTML response when there are errors so check we don't
    # receive a redirect code
    assert response.status_code == 200

    # confirm we have errors from the codelist form
    assert response.context_data["codelist_form"].errors
    def handle(self, path, **kwargs):
        if Concept.objects.count() > 0:
            raise CommandError("Must be run against empty database")

        fixtures_path = Path(settings.BASE_DIR, "coding_systems", "snomedct",
                             "fixtures")
        call_command("loaddata", fixtures_path / "core-model-components.json")
        call_command("loaddata", fixtures_path / "tennis-elbow.json")

        owner = UserFactory()
        cl = actions.create_codelist(owner=owner,
                                     name="Elbows",
                                     coding_system_id="snomedct")
        search_results = do_search(cl.coding_system, "elbow")
        actions.create_search(codelist=cl,
                              term="elbow",
                              codes=search_results["all_codes"])

        client = Client()
        client.force_login(owner)

        rsp = client.get(f"/builder/{owner.username}/{cl.slug}/")
        data = {
            k: rsp.context[k]
            for k in [
                "searches",
                "filter",
                "tables",
                "included_codes",
                "excluded_codes",
                "displayed_codes",
                "parent_map",
                "child_map",
                "is_editable",
                "update_url",
                "search_url",
            ]
        }

        with open(path, "w") as f:
            json.dump(data, f, indent=2)
Example #17
0
def test_create_search():
    # Arrange: create a codelist
    owner = UserFactory()
    cl = actions.create_codelist(
        owner=owner, name="Test Codelist", coding_system_id="snomedct"
    )

    # Act: create a first search
    s = actions.create_search(
        codelist=cl, term="swimming", codes=["1067731000000107", "1068181000000106"]
    )

    # Assert...
    # that the search's attributes have been set
    assert s.codelist == cl
    assert s.term == "swimming"
    assert s.slug == "swimming"

    # that the newly created search has 2 results
    assert s.results.count() == 2
    # that the codelist has 1 search
    assert cl.searches.count() == 1
    # that the codelist has 2 codes
    assert cl.codes.count() == 2

    # Act: create another search
    s = actions.create_search(
        codelist=cl, term="synchronised", codes=["1068181000000106"]
    )

    # Assert...
    # that the newly created search has 1 result
    assert s.results.count() == 1
    # that the codelist has 2 searches
    assert cl.searches.count() == 2
    # that the codelist still has 2 codes
    assert cl.codes.count() == 2
Example #18
0
def test_codelistupdate_invalid_post(rf):
    codelist = CodelistFactory()
    signoff_1 = SignOffFactory(codelist=codelist)
    reference_1 = ReferenceFactory(codelist=codelist)

    # missing signoff-0-date
    data = {
        "project": codelist.project.slug,
        "name": "Test Codelist",
        "coding_system_id": "snomedct",
        "description": "This is a test",
        "methodology": "This is how we did it",
        "reference-TOTAL_FORMS": "1",
        "reference-INITIAL_FORMS": "0",
        "reference-MIN_NUM_FORMS": "0",
        "reference-MAX_NUM_FORMS": "1000",
        "reference-0-text": reference_1.text,
        "reference-0-url": reference_1.url,
        "signoff-TOTAL_FORMS": "1",
        "signoff-INITIAL_FORMS": "0",
        "signoff-MIN_NUM_FORMS": "0",
        "signoff-MAX_NUM_FORMS": "1000",
        "signoff-0-user": signoff_1.user.username,
    }

    request = rf.post("/", data=data)
    request.user = UserFactory()
    response = CodelistUpdate.as_view()(
        request, project_slug=codelist.project.slug, codelist_slug=codelist.slug
    )

    # we're returning an HTML response when there are errors so check we don't
    # receive a redirect code
    assert response.status_code == 200

    # confirm we have errors from the signoff formset
    assert response.context_data["signoff_formset"].errors
Example #19
0
def test_update_code_statuses(tennis_elbow):
    # Arrange: load fixtures and create a codelist with a search
    owner = UserFactory()
    cl = actions.create_codelist(
        owner=owner, name="Test Codelist", coding_system_id="snomedct"
    )

    # Search results have this structure in hierarchy
    #
    # 116309007 Finding of elbow region
    #     128133004 Disorder of elbow
    #         239964003 Soft tissue lesion of elbow region
    #         35185008 Enthesopathy of elbow region
    #             73583000 Epicondylitis
    #                 202855006 Lateral epicondylitis
    #         429554009 Arthropathy of elbow
    #             439656005 Arthritis of elbow
    #                 202855006 Lateral epicondylitis
    #     298869002 Finding of elbow joint
    #         298163003 Elbow joint inflamed
    #             439656005 Arthritis of elbow
    #                 202855006 Lateral epicondylitis
    #         429554009 Arthropathy of elbow
    #             439656005 Arthritis of elbow
    #                 202855006 Lateral epicondylitis
    actions.create_search(
        codelist=cl,
        term="elbow",
        codes=[
            "116309007",  # Finding of elbow region
            "128133004",  # Disorder of elbow
            "239964003",  # Soft tissue lesion of elbow region
            "35185008",  # Enthesopathy of elbow region
            "73583000",  # Epicondylitis
            "202855006",  # Lateral epicondylitis
            "429554009",  # Arthropathy of elbow
            "439656005",  # Arthritis of elbow
            "298869002",  # Finding of elbow joint
            "298163003",  # Elbow joint inflamed
        ],
    )

    # Act: process single update from the client
    actions.update_code_statuses(codelist=cl, updates=[("35185008", "+")])

    # Assert that results have the expected status
    assert dict(cl.codes.values_list("code", "status")) == {
        "116309007": "?",  # Finding of elbow region
        "128133004": "?",  # Disorder of elbow
        "239964003": "?",  # Soft tissue lesion of elbow region
        "35185008": "+",  # Enthesopathy of elbow region
        "73583000": "(+)",  # Epicondylitis
        "202855006": "(+)",  # Lateral epicondylitis
        "429554009": "?",  # Arthropathy of elbow
        "439656005": "?",  # Arthritis of elbow
        "298869002": "?",  # Finding of elbow joint
        "298163003": "?",  # Elbow joint inflamed
    }

    # Act: process multiple updates from the client
    actions.update_code_statuses(
        codelist=cl, updates=[("35185008", "-"), ("116309007", "+"), ("35185008", "?")]
    )

    # Assert that results have the expected status
    assert dict(cl.codes.values_list("code", "status")) == {
        "116309007": "+",  # Finding of elbow region
        "128133004": "(+)",  # Disorder of elbow
        "239964003": "(+)",  # Soft tissue lesion of elbow region
        "35185008": "(+)",  # Enthesopathy of elbow region
        "73583000": "(+)",  # Epicondylitis
        "202855006": "(+)",  # Lateral epicondylitis
        "429554009": "(+)",  # Arthropathy of elbow
        "439656005": "(+)",  # Arthritis of elbow
        "298869002": "(+)",  # Finding of elbow joint
        "298163003": "(+)",  # Elbow joint inflamed
    }
Example #20
0
def test_codelistupdate_success(rf):
    codelist = CodelistFactory()
    signoff_1 = SignOffFactory(codelist=codelist)
    signoff_2 = SignOffFactory(codelist=codelist)
    reference_1 = ReferenceFactory(codelist=codelist)
    reference_2 = ReferenceFactory(codelist=codelist)

    assert codelist.references.count() == 2
    assert codelist.signoffs.count() == 2

    new_signoff_user = UserFactory()

    data = {
        "project": codelist.project.slug,
        "name": "Test Codelist",
        "coding_system_id": "snomedct",
        "description": "This is a test CHANGED",
        "methodology": "This is how we did it",
        "reference-TOTAL_FORMS": "3",
        "reference-INITIAL_FORMS": "2",
        "reference-MIN_NUM_FORMS": "0",
        "reference-MAX_NUM_FORMS": "1000",
        "reference-0-text": reference_1.text,
        "reference-0-url": reference_1.url,
        "reference-0-id": reference_1.id,
        "reference-0-DELETE": "on",
        "reference-1-text": reference_2.text + " CHANGED",
        "reference-1-url": reference_2.url,
        "reference-1-id": reference_2.id,
        "reference-2-text": "This is a new reference",
        "reference-2-url": "http://example.com",
        "signoff-TOTAL_FORMS": "3",
        "signoff-INITIAL_FORMS": "2",
        "signoff-MIN_NUM_FORMS": "0",
        "signoff-MAX_NUM_FORMS": "1000",
        "signoff-0-user": signoff_1.user.username,
        "signoff-0-date": signoff_1.date,
        "signoff-0-id": signoff_1.id,
        "signoff-0-DELETE": "on",
        "signoff-1-user": signoff_2.user.username,
        "signoff-1-date": signoff_2.date + datetime.timedelta(days=2),
        "signoff-1-id": signoff_2.id,
        "signoff-2-user": new_signoff_user.username,
        "signoff-2-date": "2000-01-01",
    }

    request = rf.post("/", data=data)
    request.user = UserFactory()
    response = CodelistUpdate.as_view()(
        request, project_slug=codelist.project.slug, codelist_slug=codelist.slug
    )

    assert response.status_code == 302
    assert response.url == f"/codelist/{codelist.project.slug}/{codelist.slug}/"

    # we should have still have 2 references but the first should be changed
    # while the second is new.
    assert codelist.references.count() == 2
    assert codelist.references.first().text == reference_2.text + " CHANGED"
    assert codelist.references.last().text == "This is a new reference"

    # we should have still have 2 signoffs but the first should be changed
    # while the second is new.
    assert codelist.signoffs.count() == 2
    assert codelist.signoffs.first().date == signoff_2.date + datetime.timedelta(days=2)
    assert codelist.signoffs.last().user == new_signoff_user