Skip to content

Commit

Permalink
[MERGE] sprint 10
Browse files Browse the repository at this point in the history
sprint 10
  • Loading branch information
andre-filho authored May 21, 2018
2 parents 04fcf6f + 49e0ca1 commit 4551bfc
Show file tree
Hide file tree
Showing 17 changed files with 280 additions and 21 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ wheels/
*.egg-info/
.installed.cfg
*.egg
*migrations*

# Python migrations
migrations/
Expand Down
1 change: 1 addition & 0 deletions TropicalHazards_BI/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
'rest_auth',
'dashboards',
'tags',
'django_filters',
'import_data'
]

Expand Down
Binary file added docs/UX/Fluxograma_nav.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/UX/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Fluxograma de Interação/Navegação

<img src="Fluxograma_nav.png" class="responsive-img"/>
27 changes: 25 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,29 @@
</li>
</ul>
</li>
<li class="no-padding collection-item">
<ul class="collapsible collapsible-accordion">
<li>
<a class="collapsible-header">
User Experience
</a>
<div class="collapsible-body">
<ul>
<li>
<a href="https://fga-gpp-mds.github.io/2018.1-TropicalHazards-BI/UX/index" class="waves-effect">
<span class="fa fa-file"></span> Fluxograma de Navegação
</a>
</li>
<li>
<a href="https://fga-gpp-mds.github.io/2018.1-TropicalHazards-BI/project_artefacts/usability_test" class="waves-effect">
<span class="fa fa-file"></span> Planejamento dos testes de Usabilidade
</a>
</li>
</ul>
</div>
</li>
</ul>
</li>
<li class="no-padding collection-item">
<ul class="collapsible collapsible-accordion">
<li>
Expand Down Expand Up @@ -450,7 +473,7 @@ <h4 class="promo-heading">
Projetos
</h4>
<p>
<b>Crie</b> e compartilhe os dados da sua pesquisa. <b>Escolha</b> os dados que deseja disponibilizar,
<b>Crie</b> e compartilhe os dados da sua pesquisa. <b>Escolha</b> os dados que deseja disponibilizar,
interprete as informações, gere indicadores e gráficos, crie e <b>gerencie</b> os seus observatórios.
</p>
</div>
Expand All @@ -460,7 +483,7 @@ <h4 class="promo-heading">
Colaboradores
</h4>
<p>
Trabalhe em <b>equipe</b>, interaja com os dados das pesquisas,
Trabalhe em <b>equipe</b>, interaja com os dados das pesquisas,
gere seus <b>próprios indicadores</b> e contribua com o conhecimento do projeto.
</p>
</div>
Expand Down
158 changes: 158 additions & 0 deletions docs/project_artefacts/usability_test/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# Planejamento dos Testes de Usabilidade

### Objetivo
O principal objetivo do Teste de Usabilidade do sistema Observ é determinar as respostas emocionais, feedback, tempo, passos e número de erros resultantes da interação do usuário com a aplicação. Ao final dos testes a equipe visa encontrar problemas e oportunidades de melhorias.

### Perfil de usuário
* Usuários que tenham experiência no dia a dia com websites.
* Usuários com experiência em aplicações para manipulação de dados.

### Ambiente
* Notebook com a ferramenta SimpleScreenRecorder instalado;

### Regras
Duração de 10 minutos.

## Tópicos de Análise
Para os testes de usabilidade que serão usados no projeto, serão avaliados os seguintes tópicos:

<ul>
<li>
<b>Simplicidade da interface:</b> A facilidade de entendimento da interface por meio do usuário.
</li>
<li>
<b>Desempenho do usuário:</b> tempo e passos necessários para a completude de tarefas.
</li>
<li>
<b>Precisão no uso:</b> Quantidade de erros cometidos pelo usuário na realização da tarefa.
</li>
<li>
<b>Resposta emocional:</b> Como a pessoa se sentiu durante a atividade.
</li>
<li>
<b>Lembrança e reconhecimento:</b> Reconhecimento da aplicação após certo período de tempo.
</li>
</ul>

## Avaliação
<table>
<thead>
<tr>
<th>Tópico</th>
<th>Medida</th>
<th>Fórmula</th>
</tr>
</thead>
<tbody>
<tr>
<th>Simplicidade da Interface</th>
<td></td>
<td></td>
</tr>
<tr>
<th>Desempenho do usuário</th>
<td></td>
<td></td>
</tr>
<tr>
<th>Precisão de Uso</th>
<td></td>
<td></td>
</tr>
<tr>
<th>Resposta emocional</th>
<td></td>
<td></td>
</tr>
<tr>
<th>Lembrança e reconhecimento</th>
<td></td>
<td></td>
</tr>
<tr>
<th>Número de erros cometidos</th>
<td></td>
<td></td>
</tr>
</tbody>
</table>

## Testes Utilizados
Aqui estão definidos os testes de usabilidade que serão aplicados pela equipe.
É importante resaltar que existem testes que cobrem vários dos tópicos de análise.
Antes de iniciar os testes, deve-se passar algumas informações ao usuário:
* Informar que quem será testado é o sistema e não o usuário.
* Pedir para o usuário falar em voz alta o que ele está pensando.
* Será utilizada a ferramenta de captura de tela "SimpleScreenRecorder" para acompanhar os passos de navegação do usuário pelo sistema Observ.


### Teste 01 - Teste de Workflow

#### Objetivo
Avaliar a implementação da interface do sistema ao ser utilizada pelo usuário.

#### Duração
* Máximo de 5 minutos.

#### Roteiro do Teste

1. O usuário estando na página principal, pesquisa pelo dashboard x.
2. Após receber o resultado da pesquisa, o usuário entra no dashboard escolhido.
3. O usuário confere os dados e baixa os dados do dashboard.
4. O usuário volta para a página principal.
5. O usuário realiza cadastro.
6. O usuário cria um projeto.
7. O usuário faz upload de um set de dados.
8. O usuário cria um dashboard.
9. O usuário entra no dashboard.
11. O usuário baixa os dados do dashboard.

---

### Teste 02 - Teste de Workflow (usuário alterado)

#### Objetivo
Avaliar a navegação da interface, considerando que os usuários estarão sob condições adversas durante o teste.

#### Justificativa
Esse teste foi idealizado baseado na ideia de Richard Littauer, o artigo do mesmo se encontra nas referências do documento.

#### Duração
* Máximo de 5 minutos.

#### Roteiro do Teste

1. O usuário estando na página principal, pesquisa pelo dashboard x.
2. Após receber o resultado da pesquisa, o usuário entra no dashboard escolhido.
3. O usuário confere os dados e baixa os dados do dashboard.
4. O usuário volta para a página principal.
5. O usuário realiza cadastro.
6. O usuário cria um projeto com tags.
7. O usuário faz upload de um set de dados com extensão .csv.
8. O usuário parametriza os dados.
9. O usuário cria um dashboard.
12. O usuário entra no dashboard.
13. O usuário baixa os dados do dashboard.

---
## Teste 03 - Teste de Workflow - Gerar indicadores

#### Duração
* Máximo de 5 minutos.

#### Roteiro do Teste

* Meta da tarefa: Gerar indicadores.

1. O usuário realiza cadastro.
2. O usuário realiza o login.
2. O usuário seleciona um projeto.
3. O usuário seleciona um dataset.
4. O usuário seleciona os dados.
6. O usuário gera um gráfico com indicadores.


## Referências

- [The User Has Sobered Up - Littauer, Richard](https://medium.com/@richlitt/the-user-has-sobered-up-df0b411997ea)
- [Testes de Usabilidade](https://www.caelum.com.br/apostila-ux-usabilidade-mobile-web/usabilidade/#o-que--medido)
4 changes: 3 additions & 1 deletion import_data/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@
app_name = 'import_data'

urlpatterns = [
path('', views.FileUploadView.as_view(), name='import_data')
path('', views.FileUploadView.as_view(), name='import_data'),
path('<int:pk>/', views.FileUploadViewDetail.as_view(),
name='import_data_detail'),
]
50 changes: 48 additions & 2 deletions import_data/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ class FileUploadView(APIView):
def post(self, request, format=None):
file_obj = request.data['file']
project_id = request.data['project']
# Fix temporária por probelmas com forma append
to_remove_list_fields = json.loads(request.data['headers'])
to_define_list_fields = json.loads(request.data['define'])
type_list_fields = json.loads(request.data['types'])

serializer = ImportDataSerializer(data=request.data)
if serializer.is_valid():
file_path = '/code/tmp/' + file_obj.name
Expand All @@ -32,17 +37,58 @@ def post(self, request, format=None):
for chunk in file_obj.chunks():
dest.write(chunk)

dataframe = pandas.read_csv(file_path)
dataframe = pandas.read_csv(file_path, header=0)

dataframe = dataframe.drop(to_remove_list_fields, axis=1)

for dfield, type in zip(to_define_list_fields,
type_list_fields):
try:
dataframe[dfield] = dataframe[dfield].astype(type)
break
except ValueError:
return Response(serializer.errors,
status=status.
HTTP_400_BAD_REQUEST)
json_data = json.loads(dataframe.to_json(orient="records"))

mongo_client = pymongo.MongoClient('mongo', 27017)
mongo_db = mongo_client['main_db']
collection = mongo_db['collection_' + project_id]

collection.insert(json_data)
serializer.save()
os.remove(file_path)

return Response(serializer.data,
status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@permission_classes((permissions.AllowAny,))
class FileUploadViewDetail(APIView):

def get(self, request, pk, format=None):
mongo_client = pymongo.MongoClient('mongo', 27017)
mongo_db = mongo_client['main_db']
collection = mongo_db['collection_' + str(pk)]
if collection.count() == 0:
return Response(status=status.HTTP_404_NOT_FOUND)
else:
elements = collection.find({})
json_docs = []
for doc in elements:
# Remove o campo _id do elemento, pois ele não é serializável
del(doc['_id'])
json_docs.append(doc)
# O campo json_docs já está no formato JSON
return Response(json_docs, status=status.HTTP_200_OK)

def put(self, request, pk, format=None):
remove_field = request.data['remove_field']
mongo_client = pymongo.MongoClient('mongo', 27017)
mongo_db = mongo_client['main_db']
collection = mongo_db['collection_' + str(pk)]
if collection.count() == 0:
return Response(status=status.HTTP_404_NOT_FOUND)
else:
collection.update({}, {'$unset': {remove_field: 1}}, multi=True)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"devDependencies": {
"release-it": "^4.2.0"
},
"version": "1.2.0"
"version": "1.3.0"
}
10 changes: 10 additions & 0 deletions projects/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import django_filters
from .models import Project


class ProjectFilter(django_filters.FilterSet):
tag_name = django_filters.CharFilter(lookup_expr='icontains')

class Meta:
model = Project
fields = ['tags__name']
2 changes: 1 addition & 1 deletion projects/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from tags.models import Tag


class Project(models.Model): # Herdando da model
class Project(models.Model):

name = models.CharField(max_length=80, validators=[MinLengthValidator(5)],
blank=False, verbose_name="Nome")
Expand Down
10 changes: 5 additions & 5 deletions projects/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def test_get_project_detail_return_200(client):
user.save()
client.login(username='username', password='password')
project = mommy.make('Project', user=user)
url = reverse('projects:projects-detail', kwargs={'pk': project.id})
url = reverse('projects:project-detail', kwargs={'pk': project.id})
response = client.get(url)

assert response.status_code == 200
Expand All @@ -94,7 +94,7 @@ def test_get_project_detail_return_404(client):
user.save()
client.login(username='username', password='password')

url = reverse('projects:projects-detail', kwargs={'pk': 1})
url = reverse('projects:project-detail', kwargs={'pk': 1})
response = client.get(url)

assert response.status_code == 404
Expand All @@ -107,7 +107,7 @@ def test_put_project_detail_return_200(client):
user.save()
client.login(username='username', password='password')
project = mommy.make('Project', user=user)
url = reverse('projects:projects-detail', kwargs={'pk': project.id})
url = reverse('projects:project-detail', kwargs={'pk': project.id})
data = {'name': "nameproject", 'description': "description",
'user': user.id}
json_data = json.dumps(data)
Expand All @@ -122,7 +122,7 @@ def test_put_project_detail_return400(client):
user.save()
client.login(username='username', password='password')
project = mommy.make('Project', user=user)
url = reverse('projects:projects-detail', kwargs={'pk': project.id})
url = reverse('projects:project-detail', kwargs={'pk': project.id})
data = {'name': "", 'description': "description", 'user': user.id}
json_data = json.dumps(data)
response = client.put(url, data=json_data, content_type='application/json')
Expand All @@ -137,7 +137,7 @@ def test_delete_project_detail_return_204(client):
user.save()
client.login(username='username', password='password')
project = mommy.make('Project', user=user)
url = reverse('projects:projects-detail', kwargs={'pk': project.id})
url = reverse('projects:project-detail', kwargs={'pk': project.id})
response = client.delete(url, content_type='application/json')

assert response.status_code == 204
2 changes: 1 addition & 1 deletion projects/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@

urlpatterns = [
path('', views.ProjectList.as_view(), name='projects'),
path('<int:pk>/', views.ProjectDetail.as_view(), name='projects-detail'),
path('<int:pk>/', views.ProjectDetail.as_view(), name='project-detail'),
]
Loading

0 comments on commit 4551bfc

Please sign in to comment.