def test_ro_fields(self, client_bob, user_alice_id, user_bob_id,
                    access_request_ro_attributes, current_datetime):
     response = client_bob.post(self.list_url, {
         **access_request_ro_attributes,
         **{
             'approved': True
         }
     })
     AssertionHelper.HTTP_400(
         response,
         'User does not have access to approve this access request')
     response = client_bob.post(self.list_url, {
         **access_request_ro_attributes,
         **{
             'approved_at': current_datetime
         }
     })
     AssertionHelper.HTTP_201(response, attributes={'approved_at': None})
     response = client_bob.post(self.list_url, {
         **access_request_ro_attributes,
         **{
             'approved_by': user_alice_id
         }
     })
     AssertionHelper.HTTP_201(response, attributes={'approved_by': None})
     response = client_bob.post(self.list_url, {
         **access_request_ro_attributes,
         **{
             'requester_id': user_alice_id
         }
     })
     AssertionHelper.HTTP_201(response,
                              attributes={'requester_id': user_bob_id})
    def test_create_multiple_access_requests(self, shipment_alice, client_bob,
                                             access_request_ro_attributes,
                                             access_request_rw_attributes,
                                             user_bob_id):
        response = client_bob.post(self.list_url, access_request_ro_attributes)
        AssertionHelper.HTTP_201(response,
                                 entity_refs=AssertionHelper.EntityRef(
                                     resource='AccessRequest',
                                     attributes={
                                         **{
                                             'requester_id': user_bob_id
                                         },
                                         **access_request_ro_attributes
                                     }))

        response = client_bob.post(self.list_url, access_request_rw_attributes)
        AssertionHelper.HTTP_201(response,
                                 entity_refs=AssertionHelper.EntityRef(
                                     resource='AccessRequest',
                                     attributes={
                                         **{
                                             'requester_id': user_bob_id
                                         },
                                         **access_request_rw_attributes
                                     }))
    def assert_write_access(self,
                            client,
                            shipment_access=None,
                            tags_access=None,
                            documents_access=None,
                            notes_access=None,
                            all_access=None):
        if all_access is not None:
            shipment_access = all_access
            tags_access = all_access
            documents_access = all_access
            notes_access = all_access

        shipment_data = {'carriers_scac': 'h4x3d'}
        tag_data = {
            'tag_type': 'foo',
            'tag_value': 'bar',
            'owner_id': client.handler._force_user.id,
        }
        document_data = {
            'name': 'Test BOL',
            'file_type': 'PDF',
            'document_type': 'AIR_WAYBILL'
        }
        note_data = {'message': 'hello, world.'}

        if shipment_access is not None:
            response = client.patch(self.endpoint_urls['shipment'],
                                    shipment_data)
            AssertionHelper.HTTP_202(
                response) if shipment_access else AssertionHelper.HTTP_403(
                    response)

        if tags_access is not None:
            response = client.post(self.endpoint_urls['tags'], tag_data)
            AssertionHelper.HTTP_201(
                response) if tags_access else AssertionHelper.HTTP_403(
                    response)

        if documents_access is not None:
            response = client.post(self.endpoint_urls['documents'],
                                   document_data)
            AssertionHelper.HTTP_201(
                response) if documents_access else AssertionHelper.HTTP_403(
                    response)

        if notes_access is not None:
            response = client.post(self.endpoint_urls['notes'], note_data)
            AssertionHelper.HTTP_201(
                response) if notes_access else AssertionHelper.HTTP_403(
                    response)
def test_create_shipment_note(user_alice, shipper_user, api_client, shipper_api_client, client_alice,
                              shipment, mocked_is_shipper, successful_wallet_owner_calls_assertions):

    url = reverse('shipment-notes-list', kwargs={'version': 'v1', 'shipment_pk': shipment.id})
    create_note_data, content_type = create_form_content({'message': MESSAGE_1})

    # An unauthenticated user cannot create a shipment note
    response = api_client.post(url, {'message': MESSAGE_1})
    AssertionHelper.HTTP_403(response, error='You do not have permission to perform this action.')

    # An authenticated request with a empty message should fail
    response = client_alice.post(url, {'message': ''})
    AssertionHelper.HTTP_400(response, error='This field may not be blank.', pointer='message')

    # An authenticated request with a message with more than 500 characters should fail
    response = client_alice.post(url, {'message': MESSAGE_2})
    AssertionHelper.HTTP_400(response,
                             error='Ensure this value has at most 500 characters (it has 632).',
                             pointer='message')

    # An authenticated user can create a shipment note
    response = client_alice.post(url, create_note_data, content_type=content_type)

    AssertionHelper.HTTP_201(response,
                             entity_refs=AssertionHelper.EntityRef(resource='ShipmentNote',
                                                                   attributes={
                                                                       'message': MESSAGE_1,
                                                                       'user_id': user_alice.id,
                                                                       'username': get_username(user_alice),
                                                                       'organization_name': get_user_org_name(
                                                                           user_alice)},
                                                                   relationships={'shipment': AssertionHelper.EntityRef(
                                                                       resource='Shipment', pk=shipment.id)})
                             )

    # A shipper also valid for moderator and carrier can add a shipment note
    response = shipper_api_client.post(url, {'message': MESSAGE_1})

    AssertionHelper.HTTP_201(response,
                             entity_refs=AssertionHelper.EntityRef(resource='ShipmentNote',
                                                                   attributes={
                                                                       'message': MESSAGE_1,
                                                                       'user_id': shipper_user.id,
                                                                       'username': get_username(shipper_user)},
                                                                   relationships={
                                                                       'shipment': AssertionHelper.EntityRef(
                                                                           resource='Shipment', pk=shipment.id)})
                             )
    mocked_is_shipper.assert_calls(successful_wallet_owner_calls_assertions)
Esempio n. 5
0
    def test_file_types(self, client_alice, entity_ref_shipment_alice):
        attributes = {
            'name': 'Test BOL',
            'file_type': 'NOT A FILE TYPE',
            'document_type': 'BOL',
        }
        response = client_alice.post(self.shipment_alice_url, attributes)
        AssertionHelper.HTTP_400(response, error=f'"{attributes["file_type"]}" is not a valid choice.',
                                 pointer='file_type')

        attributes['file_type'] = FileType.PDF.name
        response = client_alice.post(self.shipment_alice_url, attributes)
        AssertionHelper.HTTP_201(response,
                                 entity_refs=AssertionHelper.EntityRef(
                                     resource='Document',
                                     attributes={
                                        'upload_status': UploadStatus.PENDING.name, **attributes
                                     },
                                     relationships=[{
                                         'shipment': entity_ref_shipment_alice
                                     }],
                                     meta={
                                         'presigned_s3_thumbnail': None
                                     }
                                 ))
        assert isinstance(response.json()['data']['meta']['presigned_s3'], dict)
Esempio n. 6
0
def test_profiles_disabled_shipment_tag_creation(
        api_client, shipment, shipment_tag_creation_data,
        shipment_tag_creation_missing_owner_id, entity_shipment_relationship):

    url = reverse('shipment-tags-list',
                  kwargs={
                      'version': 'v1',
                      'shipment_pk': shipment.id
                  })

    # A request without user_id should fail
    response = api_client.post(url, shipment_tag_creation_missing_owner_id)
    AssertionHelper.HTTP_400(response, error='This field is required.')

    response = api_client.post(url, shipment_tag_creation_data)
    AssertionHelper.HTTP_201(
        response,
        entity_refs=AssertionHelper.EntityRef(
            resource='ShipmentTag',
            attributes={
                'tag_type': shipment_tag_creation_data['tag_type'],
                'tag_value': shipment_tag_creation_data['tag_value'],
                'owner_id': USER_ID
            },
            relationships={'shipment': entity_shipment_relationship}))
Esempio n. 7
0
    def test_with_unassociated_device(self, client_alice, route_attributes, device):
        route_attributes['device_id'] = device.id

        with mock.patch('apps.shipments.models.Device.get_or_create_with_permission') as mock_device:
            mock_device.return_value = device

            response = client_alice.post(self.url, route_attributes)
            AssertionHelper.HTTP_201(
                response,
                entity_refs=AssertionHelper.EntityRef(
                    resource='Route',
                    attributes={
                        'name': route_attributes['name'],
                        'driver_id': route_attributes['driver_id'],
                    },
                    relationships={
                        'device': AssertionHelper.EntityRef(
                            resource='Device',
                            pk=route_attributes['device_id']
                        ),
                    }
                ),
                included=AssertionHelper.EntityRef(
                    resource='Device',
                    pk=route_attributes['device_id']
                ),
            )
Esempio n. 8
0
    def test_permission_link_email_send_multiform(self, client_alice,
                                                  mock_aws_success,
                                                  user_alice):
        multi_form_data, content_type = create_form_content({
            'name':
            'Permission Link Name',
            'emails': ['*****@*****.**', '*****@*****.**']
        })
        response = client_alice.post(self.url_permission_link_create,
                                     multi_form_data,
                                     content_type=content_type)
        AssertionHelper.HTTP_201(
            response,
            entity_refs=AssertionHelper.EntityRef(
                resource='PermissionLink',
                attributes={'name': 'Permission Link Name'},
                relationships=self.shipment_alice_relationships))

        assert len(mail.outbox) == 1
        assert 'The ShipChain team' in str(mail.outbox[0].body)
        assert user_alice.username in str(mail.outbox[0].body)
        assert user_alice.username in str(mail.outbox[0].subject)

        pm_id = response.json()['data']['id']
        mock_aws_success.assert_calls([{
            'path': '/test/',
            'query': None,
            'body': {
                'long_url':
                f'http://localhost:3000/shipments/{self.shipment_alice.id}/?permission_link={pm_id}',
                'expiration_date': None
            },
            'host': settings.URL_SHORTENER_HOST
        }])
Esempio n. 9
0
 def test_owner_can_create(self, client_alice):
     response = client_alice.post(self.url_permission_link_create,
                                  {'name': 'Permission Link Name'})
     AssertionHelper.HTTP_201(
         response,
         entity_refs=AssertionHelper.EntityRef(
             resource='PermissionLink',
             attributes={'name': 'Permission Link Name'},
             relationships=self.shipment_alice_relationships))
Esempio n. 10
0
 def test_can_create_with_permission(self, client_bob,
                                     mock_successful_wallet_owner_calls):
     response = client_bob.post(self.url_permission_link_create,
                                {'name': 'Permission Link Name'})
     AssertionHelper.HTTP_201(
         response,
         entity_refs=AssertionHelper.EntityRef(
             resource='PermissionLink',
             attributes={'name': 'Permission Link Name'},
             relationships=self.shipment_alice_relationships))
     mock_successful_wallet_owner_calls.assert_calls(
         self.successful_wallet_owner_calls_assertions)
Esempio n. 11
0
 def test_with_attributes(self, client_alice, route_attributes):
     response = client_alice.post(self.url, route_attributes)
     AssertionHelper.HTTP_201(
         response,
         entity_refs=AssertionHelper.EntityRef(
             resource='Route',
             attributes={
                 'name': route_attributes['name'],
                 'driver_id': route_attributes['driver_id'],
             },
         ),
     )
Esempio n. 12
0
    def test_org_shipment(self, client_alice, leg_attributes, second_shipment):
        leg_attributes['shipment_id'] = second_shipment.pk

        response = client_alice.post(self.url_route, data=leg_attributes)
        AssertionHelper.HTTP_201(
            response,
            entity_refs=AssertionHelper.EntityRef(
                resource='RouteLeg',
                attributes={
                    'shipment_id': second_shipment.pk,
                },
            )
        )
    def test_with_permission_links(self, shipment_alice, client_bob,
                                   new_rw_access_request_bob,
                                   permission_link_shipment_alice):
        shipment_data = {'carriers_scac': 'h4x3d'}
        tag_data = {
            'tag_type': 'foo',
            'tag_value': 'bar',
            'owner_id': client_bob.handler._force_user.id,
        }

        # Documents/notes are not accessible via permission link, tracking/telemetry is RO
        response = client_bob.get(
            f'{self.endpoint_urls["shipment"]}?permission_link={permission_link_shipment_alice.id}'
        )
        AssertionHelper.HTTP_200(
            response,
            entity_refs=AssertionHelper.EntityRef(
                resource='Shipment',
                relationships={
                    'tags':
                    AssertionHelper.EntityRef(resource='ShipmentTag',
                                              pk=self.tag.id)
                }),
            included=AssertionHelper.EntityRef(resource='ShipmentTag'),
        )

        response = client_bob.patch(
            f'{self.endpoint_urls["shipment"]}?permission_link={permission_link_shipment_alice.id}',
            shipment_data)
        AssertionHelper.HTTP_403(response)

        response = client_bob.post(
            f'{self.endpoint_urls["tags"]}?permission_link={permission_link_shipment_alice.id}',
            tag_data)
        AssertionHelper.HTTP_403(response)

        new_rw_access_request_bob.approved = True
        new_rw_access_request_bob.save()

        response = client_bob.patch(
            f'{self.endpoint_urls["shipment"]}?permission_link={permission_link_shipment_alice.id}',
            shipment_data)
        AssertionHelper.HTTP_202(response)

        response = client_bob.post(
            f'{self.endpoint_urls["tags"]}?permission_link={permission_link_shipment_alice.id}',
            tag_data)
        AssertionHelper.HTTP_201(response)
Esempio n. 14
0
    def test_valid_expiration_date(self, client_alice):
        attributes = {
            'name': 'Permission Link Name',
            'expiration_date': datetime.utcnow() + timedelta(days=1)
        }
        response = client_alice.post(self.url_permission_link_create,
                                     attributes)

        attributes['expiration_date'] = attributes[
            'expiration_date'].isoformat() + 'Z'
        AssertionHelper.HTTP_201(
            response,
            entity_refs=AssertionHelper.EntityRef(
                resource='PermissionLink',
                attributes=attributes,
                relationships=self.shipment_alice_relationships))
def test_create_shipment_note(api_client, shipment):
    url = reverse('shipment-notes-list',
                  kwargs={
                      'version': 'v1',
                      'shipment_pk': shipment.id
                  })
    bad_shipment_url = reverse('shipment-notes-list',
                               kwargs={
                                   'version': 'v1',
                                   'shipment_pk': random_id()
                               })

    create_note_data, content_type = create_form_content({
        'message': MESSAGE,
        'user_id': USER_ID
    })

    # An unauthenticated user cannot create a shipment note without specifying the user
    response = api_client.post(url, {'message': MESSAGE})
    AssertionHelper.HTTP_400(response,
                             error='This field is required.',
                             pointer='user_id')

    # A shipment note cannot be created for a non existing shipment
    response = api_client.post(bad_shipment_url,
                               create_note_data,
                               content_type=content_type)
    AssertionHelper.HTTP_403(
        response, error='You do not have permission to perform this action.')

    # An authenticated user with a specified user can create a shipment note
    response = api_client.post(url,
                               create_note_data,
                               content_type=content_type)
    AssertionHelper.HTTP_201(response,
                             entity_refs=AssertionHelper.EntityRef(
                                 resource='ShipmentNote',
                                 attributes={
                                     'message': MESSAGE,
                                     'user_id': USER_ID,
                                     'username': None
                                 },
                                 relationships={
                                     'shipment':
                                     AssertionHelper.EntityRef(
                                         resource='Shipment', pk=shipment.id)
                                 }))
Esempio n. 16
0
    def test_permission_link_email_wallet_owner(
        self,
        client_bob,
        mock_aws_success,
        user_bob,
    ):
        response = client_bob.post(
            self.url_permission_link_create, {
                'name': 'Permission Link Name',
                'emails': ['*****@*****.**', '*****@*****.**'],
                'expiration_date': datetime.utcnow() + timedelta(days=1)
            })
        AssertionHelper.HTTP_201(
            response,
            entity_refs=AssertionHelper.EntityRef(
                resource='PermissionLink',
                attributes={
                    'name':
                    'Permission Link Name',
                    'expiration_date':
                    (datetime.utcnow() + timedelta(days=1)).isoformat() + 'Z'
                },
                relationships=self.shipment_alice_relationships))
        pm_id = response.json()['data']['id']
        self.successful_wallet_owner_calls_assertions.append({
            'path':
            '/test/',
            'query':
            None,
            'body': {
                'long_url':
                f'http://localhost:3000/shipments/{self.shipment_alice.id}/?permission_link={pm_id}',
                'expiration_date':
                (datetime.utcnow() + timedelta(days=1)).isoformat() + '+00:00'
            },
            'host':
            settings.URL_SHORTENER_HOST
        })
        mock_aws_success.assert_calls(
            self.successful_wallet_owner_calls_assertions)

        assert len(mail.outbox) == 1
        assert 'The ShipChain team' in str(mail.outbox[0].body)
        assert user_bob.username in str(mail.outbox[0].body)
        assert user_bob.username in str(mail.outbox[0].subject)
def test_org_user_shipment_tag(org_id_alice, api_client, client_alice, shipment, shipment_tag_creation_data,
                               missing_tag_type_creation_data, missing_tag_value_creation_data,
                               space_in_tag_type_creation_data, space_in_tag_value_creation_data):

    url = reverse('shipment-tags-list', kwargs={'version': 'v1', 'shipment_pk': shipment.id})

    # An unauthenticated user cannot tag a shipment
    response = api_client.post(url, shipment_tag_creation_data)
    AssertionHelper.HTTP_403(response, error='You do not have permission to perform this action.')

    # An org user cannot tag a shipment with missing tag_type in creation data
    response = client_alice.post(url, missing_tag_type_creation_data)
    AssertionHelper.HTTP_400(response, error='This field is required.')

    # An org user cannot tag a shipment with missing tag_value in creation data
    response = client_alice.post(url, missing_tag_value_creation_data)
    AssertionHelper.HTTP_400(response, error='This field is required.')

    # An org user cannot tag a shipment with space in tag_value field creation data
    response = client_alice.post(url, space_in_tag_value_creation_data)
    AssertionHelper.HTTP_400(response, error='Space(s) not allowed in this field')

    # An org user cannot tag a shipment with space in tag_type field creation data
    response = client_alice.post(url, space_in_tag_type_creation_data)
    AssertionHelper.HTTP_400(response, error='Space(s) not allowed in this field')

    # An org user with proper tag data definition, should tag a shipment
    response = client_alice.post(url, shipment_tag_creation_data)
    AssertionHelper.HTTP_201(response,
                           entity_refs=AssertionHelper.EntityRef(
                               resource='ShipmentTag',
                               attributes={'tag_type': shipment_tag_creation_data['tag_type'],
                                           'tag_value': shipment_tag_creation_data['tag_value'],
                                           'owner_id': org_id_alice},
                               relationships={
                                   'shipment': AssertionHelper.EntityRef(resource='Shipment', pk=shipment.id)
                               })
                           )

    # Trying to tag a shipment with an existing (tag_type, tag_value) pair should fail
    response = client_alice.post(url, shipment_tag_creation_data)
    AssertionHelper.HTTP_400(response, error='This shipment already has a tag with the provided [tag_type] and [tag_value].')
Esempio n. 18
0
    def test_shipment_wallet_permission(self, client_bob, mock_successful_wallet_owner_calls,
                                        entity_ref_shipment_alice, successful_wallet_owner_calls_assertions):
        attributes = {
            'name': 'Test BOL',
            'file_type': FileType.PDF.name,
            'document_type': DocumentType.AIR_WAYBILL.name
        }

        response = client_bob.post(self.shipment_alice_url, attributes)
        AssertionHelper.HTTP_201(response,
                                 entity_refs=AssertionHelper.EntityRef(
                                     resource='Document',
                                     attributes={
                                        'upload_status': UploadStatus.PENDING.name, **attributes
                                     },
                                     relationships=[{
                                         'shipment': entity_ref_shipment_alice
                                     }],
                                     meta={
                                         'presigned_s3_thumbnail': None
                                     }
                                 ))
        mock_successful_wallet_owner_calls.assert_calls(successful_wallet_owner_calls_assertions)
Esempio n. 19
0
 def test_no_attributes(self, client_alice, user_alice):
     response = client_alice.post(self.url)
     AssertionHelper.HTTP_201(response, entity_refs=AssertionHelper.EntityRef(
         resource='Route',
     ))
 def test_shipment_not_included(self, shipment_alice, client_bob,
                                access_request_ro_attributes):
     response = client_bob.post(self.list_url,
                                {**access_request_ro_attributes})
     AssertionHelper.HTTP_201(response)
     assert 'included' not in response.json()
Esempio n. 21
0
 def test_owner_is_caller_org(self, client_alice, org_id_alice):
     response = client_alice.post(self.url)
     AssertionHelper.HTTP_201(response, entity_refs=AssertionHelper.EntityRef(
         resource='Route',
         attributes={'owner_id': org_id_alice}
     ))
Esempio n. 22
0
 def test_owner_is_caller_no_org(self, client_lionel, user_lionel_id):
     response = client_lionel.post(self.url)
     AssertionHelper.HTTP_201(response, entity_refs=AssertionHelper.EntityRef(
         resource='Route',
         attributes={'owner_id': user_lionel_id}
     ))